diff --git a/.gitignore b/.gitignore index e43b0f9..af56f61 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .DS_Store +.idea/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..cf0c89c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/mLib"] + path = external/mLib + url = https://github.com/niessner/mLib diff --git a/Alignment/README.md b/Alignment/README.md new file mode 100644 index 0000000..01c3245 --- /dev/null +++ b/Alignment/README.md @@ -0,0 +1,15 @@ +## Aligner for scanned .sens, .ply files +========================================= + +Transforms scans to z-up alignment for scans and tries to align walls to x-y planes. + +### Installation. +This code was developed under VS2013. + +Requirements: +- our research library mLib, a git submodule in ../external/mLib +- mLib external libraries can be downloaded [here](https://www.dropbox.com/s/fve3uen5mzonidx/mLibExternal.zip?dl=0) + + +To run: +`alignment.exe [path to directory of scan to align]` \ No newline at end of file diff --git a/Alignment/alignment.sln b/Alignment/alignment.sln new file mode 100644 index 0000000..ef6367d --- /dev/null +++ b/Alignment/alignment.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "alignment", "alignment.vcxproj", "{EB0D04B5-579C-4BF9-8FC3-58DFB235231F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EB0D04B5-579C-4BF9-8FC3-58DFB235231F}.Debug|x64.ActiveCfg = Debug|x64 + {EB0D04B5-579C-4BF9-8FC3-58DFB235231F}.Debug|x64.Build.0 = Debug|x64 + {EB0D04B5-579C-4BF9-8FC3-58DFB235231F}.Release|x64.ActiveCfg = Release|x64 + {EB0D04B5-579C-4BF9-8FC3-58DFB235231F}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Alignment/alignment.vcxproj b/Alignment/alignment.vcxproj new file mode 100644 index 0000000..02c79cc --- /dev/null +++ b/Alignment/alignment.vcxproj @@ -0,0 +1,105 @@ + + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + true + true + + + Create + Create + + + + {EB0D04B5-579C-4BF9-8FC3-58DFB235231F} + alignment + + + + Application + true + v120 + MultiByte + + + Application + false + v120 + true + MultiByte + + + + + + + + + + + + + ../external/mLib/include;../external/mLibExternal/include/;./src/;$(IncludePath) + ..\external\mLibExternal\libsWindows\lib64;$(LibraryPath) + + + ../external/mLib/include;../external/mLibExternal/include/;./src/;$(IncludePath) + ..\external\mLibExternal\libsWindows\lib64;$(LibraryPath) + + + + Level3 + Disabled + true + _CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + Use + -Zm400 %(AdditionalOptions) + + + true + freeimage.lib;%(AdditionalDependencies) + + + + + Level2 + MaxSpeed + true + true + true + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + Use + -Zm400 %(AdditionalOptions) + + + true + true + true + freeimage.lib;%(AdditionalDependencies) + + + + + + \ No newline at end of file diff --git a/Alignment/alignment.vcxproj.filters b/Alignment/alignment.vcxproj.filters new file mode 100644 index 0000000..2c9c538 --- /dev/null +++ b/Alignment/alignment.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Alignment/src/alignment.h b/Alignment/src/alignment.h new file mode 100644 index 0000000..588c020 --- /dev/null +++ b/Alignment/src/alignment.h @@ -0,0 +1,366 @@ + +#pragma once + +#include "stdafx.h" + +#include "processedFile.h" +#include "planeExtract.h" + +class Alignment { +public: + + static MeshDataf makeNormalMesh(const vec3f& p0, const vec3f& p1, const vec4f& color = vec4f(0.8f, 0.2f, 0.2f, 1.0f)) + { + TriMeshf normalMesh0 = Shapesf::sphere(0.05f, p0, 10, 10, color); + TriMeshf normalMesh1 = Shapesf::cylinder(p0, p1, 0.025f, 10, 10, color); + MeshDataf nMesh = normalMesh0.computeMeshData(); + nMesh.merge(normalMesh1.computeMeshData()); + return nMesh; + } + + + + static vec3f upVectorFromViews(const SensorData& sd) { + vec3f v(0.0f, 0.0f, 0.0f); + for (size_t i = 0; i < sd.m_frames.size(); i++) { + const mat4f& t = sd.m_frames[i].getCameraToWorld(); + if (sd.m_frames[i].getCameraToWorld()(0, 0) == -std::numeric_limits::infinity()) continue; + + const vec3f cameraUp(0.0f, -1.0f, 0.0f); + const vec3f worldUp = (t.getRotation() * cameraUp).getNormalized(); + v += worldUp; + } + v /= (float)sd.m_frames.size(); + return v.getNormalized(); + } + + static bool hasAccel(const SensorData& sd, unsigned int numThresh = 10) { + unsigned int numValidAccel = 0; + for (const SensorData::IMUFrame& f : sd.m_IMUFrames) { + if (f.acceleration != vec3d(0.0)) numValidAccel++; + } + + if (numValidAccel > numThresh) return true; + else return false; + } + + static vec3f upVectorFromAccel(const SensorData& sd) + { + if (sd.m_IMUFrames.size() == 0) throw MLIB_EXCEPTION("no imu data found"); + + vec3f v(0.0f, 0.0f, 0.0f); + for (size_t i = 0; i < sd.m_frames.size(); i++) { + const SensorData::IMUFrame& f = sd.findClosestIMUFrame(i); + + if (sd.m_frames[i].getCameraToWorld()(0, 0) == -std::numeric_limits::infinity()) continue; + + if (f.acceleration == vec3d::origin) { + std::cout << "invalid IMU acceleration data entry at " << i << "-th frame" << std::endl; + continue; + } + + vec3f cameraUp = -vec3f((float)f.acceleration.x, (float)f.acceleration.y, (float)f.acceleration.z).getNormalized(); + const mat4f& t = sd.m_frames[i].getCameraToWorld(); + const vec3f worldUp = (t.getRotation() * cameraUp).getNormalized(); + v += worldUp; + } + + return v.getNormalized(); + } + + static bool hasGravity(const SensorData& sd, unsigned int numThresh = 10) + { + unsigned int numValidGravity = 0; + for (const SensorData::IMUFrame& f : sd.m_IMUFrames) { + if (f.gravity != vec3d(0.0)) numValidGravity++; + } + + if (numValidGravity > numThresh) return true; + else return false; + } + + static vec3f upVectorFromGravity(const SensorData& sd) + { + if (sd.m_IMUFrames.size() == 0) throw MLIB_EXCEPTION("no imu data found"); + + vec3f v(0.0f, 0.0f, 0.0f); + for (size_t i = 0; i < sd.m_frames.size(); i++) { + const SensorData::IMUFrame& f = sd.findClosestIMUFrame(i); + if (sd.m_frames[i].getCameraToWorld()(0, 0) == -std::numeric_limits::infinity()) continue; + + if (f.gravity == vec3d::origin) { + std::cout << "invalid IMU gravity data entry at " << i << "-th frame" << std::endl; + continue; + } + + vec3f cameraUp = vec3f((float)f.gravity.x, (float)f.gravity.y, (float)f.gravity.z).getNormalized(); + + cameraUp = vec3f(cameraUp.y, cameraUp.x, cameraUp.z); + + const mat4f& t = sd.m_frames[i].getCameraToWorld(); + const vec3f worldUp = (t.getRotation() * cameraUp).getNormalized(); + v += worldUp; + } + v /= (float)sd.m_frames.size(); + + return v.getNormalized(); + } + + static void writeTrajectoryFile(const std::string& outFile, const SensorData& sd) { + + std::vector trajecotry; + for (size_t i = 0; i < sd.m_frames.size(); i++) { + trajecotry.push_back(sd.m_frames[i].getCameraToWorld()); + } + + BinaryDataStreamFile outStream(outFile, true); + outStream << trajecotry; + outStream.close(); + } + + static std::vector readTrajectoryFile(const std::string& inFile) { + BinaryDataStreamFile in(inFile, false); + std::vector trajectory; + in >> trajectory; + return trajectory; + } + + static void removeInvalidIMUFrames(SensorData& sd) { + const bool checkTimeStamp = true; //at the moment only remove invalid time frames + const bool checkGravity = false; + const bool checkAccel = false; + + unsigned int removedInvalidFrames = 0; + for (std::vector::iterator iter = sd.m_IMUFrames.begin(); iter != sd.m_IMUFrames.end();) { + bool rem = false; + if (checkTimeStamp && iter->timeStamp == 0) rem = true; + if (checkGravity && iter->gravity == vec3d::origin) rem = true; + if (checkAccel && iter->gravity == vec3d::origin) rem = true; + + if (rem == true) { + iter = sd.m_IMUFrames.erase(iter); + removedInvalidFrames++; + } + else { + iter++; + } + } + + if (removedInvalidFrames > 0) { + std::cout << "removed " << removedInvalidFrames << " invalid IMUFrames" << std::endl; + } + } + + static void alignScan(const std::string& path, bool forceRealign = false) { + + const std::string processedFile(path + "/" + "processed.txt"); + if (!util::fileExists(processedFile)) { + std::cout << "no reconstruction available for " << path << "\n\t -> skipping folder" << std::endl; + return; + } + ParameterFile parameterFile(processedFile); + ProcessedFile pf; pf.readMembers(parameterFile); + if (!pf.valid) { + std::cout << "reconstruction was invalid for " << path << "\n\t -> skipping folder" << std::endl; + return; + } + if (pf.aligned && !forceRealign) { + std::cout << "reconstruction is already aligned " << path << "\n\t -> skipping folder" << std::endl; + return; + } + + Directory dir(path); + const std::vector tmp = ml::util::split(util::replace(path, "\\", "/"), "/"); //we assume forward slashes + const std::string base = tmp.back(); + const std::string baseFile = path + "/" + base; + + const std::string sensFile = path + "/" + base + ".sens"; + const std::string plyFile = path + "/" + base + ".ply"; + const std::string trajFile = util::replace(sensFile, ".sens", ".traj"); + + + mat4f transform = mat4f::identity(); + + SensorData sd(sensFile); + removeInvalidIMUFrames(sd); + + if (sd.m_frames.size() == 0) throw MLIB_EXCEPTION("no frames found in the sensor file"); + + if (sd.m_frames[0].getCameraToWorld() != mat4f::identity()) { + std::cout << "already found a previous alignment -> reverting to original" << std::endl; + + if (sd.m_frames[0].getCameraToWorld()(0, 0) == -std::numeric_limits::infinity()) { + std::cout << "error can't revert due to an invalid transform in the first frame" << std::endl; + std::cout << "\tskipping folder " << std::endl; + return; + } + mat4f inverse = sd.m_frames[0].getCameraToWorld().getInverse(); + sd.applyTransform(inverse); + + //if we have a multiple ply files (e.g., if VH was already run): + Directory dir(path); + std::vector plyFiles = dir.getFilesWithSuffix(".ply"); + for (const std::string& plyFile : plyFiles) { + MeshDataf md = MeshIOf::loadFromFile(dir.getPath() + "/" + plyFile); + md.applyTransform(inverse); + MeshIOf::saveToFile(dir.getPath() + "/" + plyFile, md); + } + } + + MeshDataf md = MeshIOf::loadFromFile(plyFile); + md.mergeCloseVertices(0.0005f, true); + md.removeIsolatedPieces(5000); + + //compute approx up vector from camera views or gravity (if available) + if (true) { + vec3f upEstimateView = upVectorFromViews(sd); + vec3f upEstimate = upEstimateView; + if (hasGravity(sd)) { //try to use gravity if possible + vec3f upEstimateGrav = upVectorFromGravity(sd); + upEstimate = upEstimateGrav; + } + + vec3f x = upEstimate ^ vec3f(upEstimate.y, -upEstimate.z, upEstimate.x); x.normalize(); + vec3f y = upEstimate ^ x; y.normalize(); + vec3f z = upEstimate; + mat4f mat = mat4f(x, y, z); + md.applyTransform(mat); + transform = mat * transform; + } + + md.computeVertexNormals(); + + //attempting to find a ground plane (and align to it) + if (true) { + PlaneExtract pe(md); + pe.cluster(); + pe.removeSmallClusters(); + pe.removeNonBoundingClusters(0.1f, 100); //the + const auto& clusters = pe.getClusters(); + + bool foundHorizontalPlane = false; + const size_t maxClusters = clusters.size(); + size_t i = 0; + for (const Cluster& c : clusters) { + if ((c.m_rep.plane.getNormal() | vec3f(0.0f, 0.0f, 1.0f)) > 0.8f) { + mat4f mat = c.reComputeNormalAlignment(); + md.applyTransform(mat); + transform = mat * transform; + foundHorizontalPlane = true; + break; + } + i++; + if (i >= maxClusters) break; + } + if (!foundHorizontalPlane) std::cout << "could not find a horizontal plane" << std::endl; + + //final alignment with xy plane (translation) + if (true) { + BoundingBox3f bb = md.computeBoundingBox(); + mat4f mat = mat4f::translation(-bb.getMinZ()); + transform = mat * transform; + md.applyTransform(mat); + + bb = md.computeBoundingBox(); + mat = mat4f::translation(-vec3f(bb.getCenter().x, bb.getCenter().y, 0.0f)); + md.applyTransform(mat); + transform = mat * transform; + } + + //attempting to find a vertical plane to align with the x and y axis + if (true) { + if (true) { + //first find the bounding box using cgal + OrientedBoundingBox3f obb = CGALWrapperf::computeOrientedBoundingBox(md.m_Vertices, CGALWrapperf::CONSTRAIN_Z); + mat4f mat = mat4f(obb.getAxisX().getNormalized(), obb.getAxisY().getNormalized(), obb.getAxisZ().getNormalized()); + md.applyTransform(mat); + transform = mat * transform; + } + + //make sure x and y are in the positive quadrant + if (true) { + BoundingBox3f bb = md.computeBoundingBox(); + mat4f mat = mat4f::translation(-vec3f(bb.getMin().x, bb.getMin().y, 0.0f)); + md.applyTransform(mat); + transform = mat * transform; + } + } + } + + md.m_Normals.clear(); + + { + //if we have a multiple ply files (e.g., if VH was already run): + Directory dir(path); + std::vector plyFiles = dir.getFilesWithSuffix(".ply"); + for (const std::string& plyFile : plyFiles) { + MeshDataf mesh = MeshIOf::loadFromFile(dir.getPath() + "/" + plyFile); + mesh.applyTransform(transform); + MeshIOf::saveToFile(dir.getPath() + "/" + plyFile, mesh); + } + + + sd.applyTransform(transform); + sd.saveToFile(sensFile); + pf.aligned = true; //it's now aligned + pf.saveToFile(processedFile); + } + } + + static mat4f readTransformFromAln(const std::string& filename) + { + std::ifstream s(filename); + if (!s.is_open()) throw MLIB_EXCEPTION("failed to open file " + filename + " for read"); + std::string tmp; + std::getline(s, tmp); std::getline(s, tmp); std::getline(s, tmp);//ignore header lines + mat4f m; + for (unsigned int i = 0; i < 16; i++) s >> m[i]; + s.close(); + return m; + } + + static void alignScanFromAlnFile(const std::string& path) { + + const std::string processedFile(path + "/" + "processed.txt"); + if (!util::fileExists(processedFile)) { + std::cout << "no reconstruction available for " << path << "\n\t -> skipping folder" << std::endl; + return; + } + ParameterFile parameterFile(processedFile); + ProcessedFile pf; pf.readMembers(parameterFile); + if (!pf.valid) { + std::cout << "reconstruction was invalid for " << path << "\n\t -> skipping folder" << std::endl; + return; + } + + Directory dir(path); + const std::vector tmp = ml::util::split(util::replace(path, "\\", "/"), "/"); //we assume forward slashes + const std::string base = tmp.back(); + const std::string baseFile = path + "/" + base; + + const std::string alnFile = path + "/alignment.aln"; + const std::string sensFile = path + "/" + base + ".sens"; + std::vector plyFiles = dir.getFilesWithSuffix(".ply"); + + const mat4f transform = readTransformFromAln(alnFile); + + SensorData sd(sensFile); + if (sd.m_frames.size() == 0) throw MLIB_EXCEPTION("no frames found in the sensor file"); + sd.applyTransform(transform); + + { //save out transformed + for (const std::string& plyFile : plyFiles) { + MeshDataf mesh = MeshIOf::loadFromFile(dir.getPath() + "/" + plyFile); + mesh.applyTransform(transform); + MeshIOf::saveToFile(dir.getPath() + "/" + plyFile, mesh); + } + sd.applyTransform(transform); + sd.saveToFile(sensFile); + pf.aligned = true; //it's now aligned + pf.saveToFile(processedFile); + } + } + + +private: +}; \ No newline at end of file diff --git a/Alignment/src/globalAppState.h b/Alignment/src/globalAppState.h new file mode 100644 index 0000000..1ff697b --- /dev/null +++ b/Alignment/src/globalAppState.h @@ -0,0 +1,72 @@ +#pragma once + +#ifndef _GLOBAL_APP_STATE_H_ +#define _GLOBAL_APP_STATE_H_ + +#include "mLibInclude.h" + +#define X_GLOBAL_APP_STATE_FIELDS \ + X(std::string, s_inputTestFile) \ + X(std::string, s_sourceDirectory) \ + X(std::vector, s_methods) + + +#ifndef VAR_NAME +#define VAR_NAME(x) #x +#endif + +#define checkSizeArray(a, d)( (((sizeof a)/(sizeof a[0])) >= d)) + +class GlobalAppState +{ +public: + +#define X(type, name) type name; + X_GLOBAL_APP_STATE_FIELDS +#undef X + + //! sets the parameter file and reads + void readMembers(const ParameterFile& parameterFile) { + m_ParameterFile = parameterFile; + readMembers(); + } + + //! reads all the members from the given parameter file (could be called for reloading) + void readMembers() { +#define X(type, name) \ + if (!m_ParameterFile.readParameter(std::string(#name), name)) {MLIB_WARNING(std::string(#name).append(" ").append("uninitialized")); name = type();} + X_GLOBAL_APP_STATE_FIELDS +#undef X + m_bIsInitialized = true; + } + + void print() const { +#define X(type, name) \ + std::cout << #name " = " << name << std::endl; + X_GLOBAL_APP_STATE_FIELDS +#undef X + } + + static GlobalAppState& get() { + static GlobalAppState s; + return s; + } + + + //! constructor + GlobalAppState() { + m_bIsInitialized = false; + } + + //! destructor + ~GlobalAppState() { + } + + + +private: + bool m_bIsInitialized; + ParameterFile m_ParameterFile; +}; + +#endif \ No newline at end of file diff --git a/Alignment/src/mLibInclude.h b/Alignment/src/mLibInclude.h new file mode 100644 index 0000000..4ea883d --- /dev/null +++ b/Alignment/src/mLibInclude.h @@ -0,0 +1,16 @@ +#ifndef _MLIB_INCLUDE_H_ +#define _MLIB_INCLUDE_H_ + +#ifdef _DEBUG +#define MLIB_ERROR_CHECK +#endif + +#include +#include +#include +#include +#include + +using namespace ml; + +#endif \ No newline at end of file diff --git a/Alignment/src/mLibSource.cpp b/Alignment/src/mLibSource.cpp new file mode 100644 index 0000000..f836f68 --- /dev/null +++ b/Alignment/src/mLibSource.cpp @@ -0,0 +1,7 @@ + +#include "main.h" + +#include "mLibCore.cpp" +#include "mLibLodePNG.cpp" +#include "mLibDepthCamera.cpp" +//#include "mLibZLib.cpp" \ No newline at end of file diff --git a/Alignment/src/main.cpp b/Alignment/src/main.cpp new file mode 100644 index 0000000..fdbe6f8 --- /dev/null +++ b/Alignment/src/main.cpp @@ -0,0 +1,62 @@ + +#include "stdafx.h" + +#include "main.h" +#include "alignment.h" + +void alignScan(const std::string& sceneFolder, bool forceRealign = false) +{ + std::cout << "aligning: " << sceneFolder << std::endl; + Alignment::alignScan(sceneFolder, forceRealign); +} + +void alignScanFromAlnFile(const std::string& sceneFolder) +{ + std::cout << "aligning: " << sceneFolder << std::endl; + Alignment::alignScanFromAlnFile(sceneFolder); +} + + + +void alignDirectory(const std::string& path, bool forceRealign = false) { + Directory dir(path); + std::vector scenes = dir.getDirectories(); + std::sort(scenes.begin(), scenes.end()); + for (size_t i = 0; i < scenes.size(); i++) { + const std::string& scene = scenes[i]; + const std::string sceneFolder = path + scene; + alignScan(sceneFolder); + //break; + //if (i >= 20) break; + } +} + +int main(int argc, char* argv[]) +{ + try { + if (argc == 2) { //converts a specific scan given by the command line argument + std::string stagingFolder(argv[1]); + alignScan(stagingFolder); + } + else { + throw MLIB_EXCEPTION("requires the path as a command line argument"); + } + } + catch (const std::exception& e) + { + MessageBoxA(NULL, e.what(), "Exception caught", MB_ICONERROR); + exit(EXIT_FAILURE); + } + catch (...) + { + MessageBoxA(NULL, "UNKNOWN EXCEPTION", "Exception caught", MB_ICONERROR); + exit(EXIT_FAILURE); + } + + //std::cout << "" << std::endl; + //getchar(); + + return 0; +} + + diff --git a/Alignment/src/main.h b/Alignment/src/main.h new file mode 100644 index 0000000..9e593e5 --- /dev/null +++ b/Alignment/src/main.h @@ -0,0 +1,9 @@ + +#include +#include +#include +#include +#include +#include + +#include "stdafx.h" diff --git a/Alignment/src/planeExtract.h b/Alignment/src/planeExtract.h new file mode 100644 index 0000000..3db2dbb --- /dev/null +++ b/Alignment/src/planeExtract.h @@ -0,0 +1,203 @@ + +#pragma once + +#include "stdafx.h" + + +struct Point { + Planef plane; + vec3f point; + size_t urIdx; +}; + +struct Cluster { + Cluster(const Point* init) { + m_points.push_back(init); + m_rep = *m_points.front(); + + sumNormal = init->plane.getNormal(); + sumPoint = init->point; + } + void addPoint(const Point* p) { + + m_points.push_back(p); + + sumNormal += p->plane.getNormal(); + sumPoint += p->point; + + m_rep.plane = Planef(sumNormal.getNormalized(), sumPoint / (float)m_points.size()); + } + + bool check(const Point& p, float normalThresh, float distThresh) { + float d_norm = p.plane.getNormal() | m_rep.plane.getNormal(); + float d_dist = m_rep.plane.distanceToPointAbs(p.point); + + return (d_norm > normalThresh) && (d_dist < distThresh); + } + + mat4f reComputeNormalAlignment() const { + std::vector points; + for (const Point* p : m_points) { + if (m_rep.plane.distanceToPointAbs(p->point) < 0.05f) { + points.push_back(p->point); + } + } + auto res = math::pointSetPCA(points); + mat4f m(res[0].first.getNormalized(), res[1].first.getNormalized(), res[2].first.getNormalized()); + return m.getTranspose(); + } + + vec3f reComputeNormal() const { + std::vector points; + for (const Point* p : m_points) { + if (m_rep.plane.distanceToPointAbs(p->point) < 0.05f) { + points.push_back(p->point); + } + } + auto res = math::pointSetPCA(points); + mat3f m(res[0].first.getNormalized(), res[1].first.getNormalized(), res[2].first.getNormalized()); + return m.zcol().getNormalized(); + } + + bool operator<(const Cluster& other) const { + return m_points.size() > other.m_points.size(); + } + + Point m_rep; + std::list m_points; + + vec3f sumNormal; + vec3f sumPoint; +}; + +class PlaneExtract { +public: + PlaneExtract(const MeshDataf& md) { + if (!md.hasNormals()) throw MLIB_EXCEPTION("need to compute normals first"); + + m_points.resize(md.m_Vertices.size()); + for (size_t i = 0; i < md.m_Vertices.size(); i++) { + Point& p = m_points[i]; + p.plane = Planef(md.m_Normals[i], md.m_Vertices[i]); + p.point = md.m_Vertices[i]; + p.urIdx = i; + m_pointsRef.push_back(&m_points[i]); + } + } + + void cluster(float normalThresh = 0.90f, float distThresh = 0.05f) { + for (const Point* p : m_pointsRef) { + bool foundCluster = false; + for (Cluster& c : m_clusters) { + if (c.check(*p, normalThresh, distThresh)) { + c.addPoint(p); + foundCluster = true; + break; + } + } + if (!foundCluster) { + m_clusters.push_back(Cluster(p)); + } + } + + m_clusters.sort(); + } + + void print(unsigned int topN = 10) const { + std::cout << m_points.size() << " points " << std::endl; + std::cout << m_clusters.size() << " clusters " << std::endl; + unsigned int i = 0; + for (const Cluster& c : m_clusters) { + if (i >= topN) break; + std::cout << "\t" << c.m_points.size() << std::endl; + i++; + } + } + + + const std::list getClusters() const { + return m_clusters; + } + + void removeSmallClusters(size_t minSize = 500) { + for (std::list::iterator iter = m_clusters.begin(); iter != m_clusters.end();) { + if (iter->m_points.size() < minSize) { + iter = m_clusters.erase(iter); + } + else { + iter++; + } + } + } + + //threshold is 10cm by default + void removeNonBoundingClusters(float distThresh, unsigned int numthresh) { + for (std::list::iterator iter = m_clusters.begin(); iter != m_clusters.end();) { + if (!isBoundingCluster(*iter, distThresh, numthresh)) { + iter = m_clusters.erase(iter); + } + else { + iter++; + } + } + } + + //check whether there are points behind the plane -- if so then return false + bool isBoundingCluster(const Cluster& c, float distThresh, unsigned int numThresh) const { + unsigned int countBehind = 0; + for (size_t i = 0; i < m_points.size(); i++) { + const float d = c.m_rep.plane.distanceToPoint(m_points[i].point); + if (d < -distThresh) countBehind++; + } + if (countBehind > numThresh) return false; + else return true; + } + + void saveColoredPlanes(const std::string& filename, const MeshDataf& md, unsigned int topN = 0) { + topN = (unsigned int)std::min(topN, m_clusters.size()); + + MeshDataf mesh = md; + + if (mesh.m_Colors.size() != mesh.m_Vertices.size()) { + mesh.m_Colors.resize(mesh.m_Vertices.size()); + } + + size_t i = 0; + for (const Cluster& c : m_clusters) { + RGBColor color = RGBColor::randomColor(); + for (const Point* p : c.m_points) { + mesh.m_Colors[p->urIdx] = color; + } + + i++; + if (topN != 0 && i >= topN) { + break; + } + } + + MeshIOf::saveToFile(filename, mesh); + } + + + void saveColoredPlane(const std::string& filename, const Cluster& c, const MeshDataf& md, const RGBColor& color = RGBColor::randomColor()) { + + MeshDataf mesh = md; + + if (mesh.m_Colors.size() != mesh.m_Vertices.size()) { + mesh.m_Colors.resize(mesh.m_Vertices.size()); + } + + for (const Point* p : c.m_points) { + mesh.m_Colors[p->urIdx] = color; + } + + MeshIOf::saveToFile(filename, mesh); + } + +private: + + + std::vector m_points; + std::list m_pointsRef; + std::list m_clusters; +}; diff --git a/Alignment/src/processedFile.h b/Alignment/src/processedFile.h new file mode 100644 index 0000000..3930691 --- /dev/null +++ b/Alignment/src/processedFile.h @@ -0,0 +1,87 @@ +#pragma once + + +#include "mLibInclude.h" + +#define X_PROCESSED_FILE_STATE_FIELDS \ + X(bool, valid) \ + X(unsigned int, heapFreeCount) \ + X(unsigned int, numValidOptTransforms) \ + X(unsigned int, numTransforms) \ + X(bool, aligned) + + +#ifndef VAR_NAME +#define VAR_NAME(x) #x +#endif + +#define checkSizeArray(a, d)( (((sizeof a)/(sizeof a[0])) >= d)) + +class ProcessedFile +{ +public: + +#define X(type, name) type name; + X_PROCESSED_FILE_STATE_FIELDS +#undef X + + //! sets the parameter file and reads + void readMembers(const ParameterFile& parameterFile) { + m_ParameterFile = parameterFile; + readMembers(); + } + + //! reads all the members from the given parameter file (could be called for reloading) + void readMembers() { + aligned = false; + +#define X(type, name) \ + if (!m_ParameterFile.readParameter(std::string(#name), name) && std::string(#name) != "aligned") {MLIB_WARNING(std::string(#name).append(" ").append("uninitialized")); name = type();} + X_PROCESSED_FILE_STATE_FIELDS +#undef X + + m_bIsInitialized = true; + } + + template + std::string makeString(const T& in) { + std::string ret = std::to_string(in); + return ret; + } + template <> + std::string makeString(const bool& in) { + if (in == true) return "true"; + else return "false"; + } + + void saveToFile(const std::string& outFile) { + std::ofstream out(outFile); +#define X(type, name) \ + { out << #name << " = " << makeString(name) << std::endl; } + X_PROCESSED_FILE_STATE_FIELDS +#undef X + } + + void print() const { +#define X(type, name) \ + std::cout << #name " = " << name << std::endl; + X_PROCESSED_FILE_STATE_FIELDS +#undef X + } + + + //! constructor + ProcessedFile() { + m_bIsInitialized = false; + } + + //! destructor + ~ProcessedFile() { + } + + +private: + bool m_bIsInitialized; + ParameterFile m_ParameterFile; +}; + diff --git a/Alignment/src/stdafx.cpp b/Alignment/src/stdafx.cpp new file mode 100644 index 0000000..3f38672 --- /dev/null +++ b/Alignment/src/stdafx.cpp @@ -0,0 +1,11 @@ +// stdafx.cpp : source file that includes just the standard includes +// VirtualScan.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#pragma warning (disable : 4996) + +#include "stdafx.h" + +#include "mLibSource.cpp" +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/Alignment/src/stdafx.h b/Alignment/src/stdafx.h new file mode 100644 index 0000000..c695e5c --- /dev/null +++ b/Alignment/src/stdafx.h @@ -0,0 +1,13 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include +#include + +// TODO: reference additional headers your program requires here + +#include "mLibInclude.h" \ No newline at end of file diff --git a/AnnotationTools/Filter2dAnnotations/Filter2dAnnotations.cpp b/AnnotationTools/Filter2dAnnotations/Filter2dAnnotations.cpp new file mode 100644 index 0000000..0f69b2b --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/Filter2dAnnotations.cpp @@ -0,0 +1,440 @@ +// EvaluateAnnotations.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include +#include "GlobalDefines.h" +#include "MatrixConversion.h" +#include "../common/json.h" +#include "../common/Segmentation.h" +#include "../common/Aggregation.h" +#include "LabelUtil.h" + +extern "C" void convertDepthFloatToCameraSpaceFloat4(float4* d_output, float* d_input, float4x4 intrinsicsInv, unsigned int width, unsigned int height); +extern "C" void computeNormals(float4* d_output, float4* d_input, unsigned int width, unsigned int height); +extern "C" void resampleFloatMap(float* d_colorMapResampledFloat, unsigned int outputWidth, unsigned int outputHeight, + float* d_colorMapFloat, unsigned int inputWidth, unsigned int inputHeight); +extern "C" void resampleUCharMap(unsigned char* d_MapResampled, unsigned int outputWidth, unsigned int outputHeight, + unsigned char* d_Map, unsigned int inputWidth, unsigned int inputHeight); +extern "C" void gaussFilterFloat4Map(float4* d_output, float4* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height); +extern "C" void bilateralFilterFloatMap(float* d_output, float* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height); +extern "C" void bilateralFilterFloat4Map(float4* d_output, float4* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height); +extern "C" void filterAnnotations(unsigned char* d_outputInstance, const unsigned char* d_inputInstance, + const float* d_depth, const float* d_intensity, const unsigned char* d_instanceToIdx, + const unsigned char* d_idxToInstance, float* d_vote, + int structureSize, int width, int height, float sigmaD, float sigmaR, float intensityScale); +extern "C" void convertInstanceToLabel(unsigned short* d_outputLabel, const unsigned char* d_inputInstance, + const unsigned short* d_instanceToLabel, unsigned int width, unsigned int height); + +struct FilterData { + FilterData() { + d_instanceToIdx = NULL; + d_idxToInstance = NULL; + d_vote = NULL; + d_instanceToLabel = NULL; + d_depth = NULL; + d_intensity = NULL; + d_instance = NULL; + d_instanceHelper = NULL; + d_label = NULL; + d_depthHelper = NULL; + d_intensityHelper = NULL; + } + void alloc(unsigned int width, unsigned int height) { + MLIB_CUDA_SAFE_CALL(cudaMalloc(&d_instanceToIdx, sizeof(unsigned char)*MAX_NUM_LABELS_PER_SCENE)); + MLIB_CUDA_SAFE_CALL(cudaMalloc(&d_idxToInstance, sizeof(unsigned char)*MAX_NUM_LABELS_PER_SCENE)); + MLIB_CUDA_SAFE_CALL(cudaMalloc(&d_instanceToLabel, sizeof(unsigned short)*MAX_NUM_LABELS_PER_SCENE)); + MLIB_CUDA_SAFE_CALL(cudaMalloc(&d_vote, sizeof(float)*width*height*MAX_NUM_LABELS_PER_SCENE)); + MLIB_CUDA_SAFE_CALL(cudaMalloc(&d_depth, sizeof(float)*width*height)); + MLIB_CUDA_SAFE_CALL(cudaMalloc(&d_intensity, sizeof(float)*width*height)); + MLIB_CUDA_SAFE_CALL(cudaMalloc(&d_depthHelper, sizeof(float)*width*height)); + MLIB_CUDA_SAFE_CALL(cudaMalloc(&d_intensityHelper, sizeof(float)*width*height)); + MLIB_CUDA_SAFE_CALL(cudaMalloc(&d_instance, sizeof(unsigned char)*width*height)); + MLIB_CUDA_SAFE_CALL(cudaMalloc(&d_instanceHelper, sizeof(unsigned char)*width*height)); + MLIB_CUDA_SAFE_CALL(cudaMalloc(&d_label, sizeof(unsigned short)*width*height)); + } + void init(const std::vector& objectIdsToIdx, const std::vector& idxToObjectIds, const std::vector& objectIdsToLabel) { + //initialize + MLIB_CUDA_SAFE_CALL(cudaMemcpy(d_instanceToIdx, objectIdsToIdx.data(), sizeof(unsigned char)*MAX_NUM_LABELS_PER_SCENE, cudaMemcpyHostToDevice)); + MLIB_CUDA_SAFE_CALL(cudaMemcpy(d_idxToInstance, idxToObjectIds.data(), sizeof(unsigned char)*MAX_NUM_LABELS_PER_SCENE, cudaMemcpyHostToDevice)); + MLIB_CUDA_SAFE_CALL(cudaMemcpy(d_instanceToLabel, objectIdsToLabel.data(), sizeof(unsigned short)*MAX_NUM_LABELS_PER_SCENE, cudaMemcpyHostToDevice)); + } + void free() { + MLIB_CUDA_SAFE_FREE(d_instanceToIdx); + MLIB_CUDA_SAFE_FREE(d_idxToInstance); + MLIB_CUDA_SAFE_FREE(d_instanceToLabel); + MLIB_CUDA_SAFE_FREE(d_vote); + MLIB_CUDA_SAFE_FREE(d_depth); + MLIB_CUDA_SAFE_FREE(d_intensity); + MLIB_CUDA_SAFE_FREE(d_depthHelper); + MLIB_CUDA_SAFE_FREE(d_intensityHelper); + MLIB_CUDA_SAFE_FREE(d_instance); + MLIB_CUDA_SAFE_FREE(d_instanceHelper); + MLIB_CUDA_SAFE_FREE(d_label); + } + + unsigned char* d_instanceToIdx, *d_idxToInstance; float* d_vote; unsigned short* d_instanceToLabel; + float* d_depth, *d_intensity; unsigned char* d_instance, *d_instanceHelper; unsigned short* d_label; + float* d_depthHelper, *d_intensityHelper; +}; + +std::vector readScenesFromFile(const std::string& filename); +void process(FilterData& filterData, std::string path, std::string scanNetPath, std::string outputPath, const std::string& name, bool printDebugOutput); +void processSegs(std::string path, std::string scanNetPath, std::string outputPath, const std::string& name); + +void debugVis(const std::string& rawPath, const std::string& filtPath, const std::string& scene, const std::string& scanNetPath, const std::string& outDir); + +int _tmain(int argc, _TCHAR* argv[]) +{ + try { + //-------Fill in the paths accordingly here + const bool bPrintDebugOutput = false; + const std::string scanNetDir = "../../data/scans/"; + const std::string dataPath = "../annotations-2d/"; + const std::string outputPath = "../annotations-2d-filtered/"; + const std::string sceneListFile = "../../Tasks/Benchmark/scannet_train.txt"; + LabelUtil::get().init("../../data/tasks/scannet-labels.combined.tsv"); + //------- + + if (!util::directoryExists(scanNetDir) || !util::directoryExists(dataPath)) + throw MLIB_EXCEPTION("input data dir(s) do not exist"); + if (!sceneListFile.empty() && !util::fileExists(sceneListFile)) + throw MLIB_EXCEPTION("scene list file (" + sceneListFile + ") does not exist"); + + if (!util::directoryExists(outputPath)) util::makeDirectory(outputPath); + + Directory annotationDir(dataPath); + std::vector scenes; + if (sceneListFile.empty()) + scenes = annotationDir.getDirectories(); + else + scenes = readScenesFromFile(sceneListFile); + + std::cout << "found " << scenes.size() << " scenes" << std::endl; + unsigned int counter = 0; + FilterData filterData; filterData.alloc(1296, 968); //max width/height + for (const std::string& scene : scenes) { + if (!util::directoryExists(dataPath + scene)) continue; + Timer t; + process(filterData, dataPath + scene, scanNetDir, outputPath + scene, scene, bPrintDebugOutput); + t.stop(); std::cout << "[" << counter << " | " << scenes.size() << "] time for scene: " << t.getElapsedTime() << " s" << std::endl; + counter++; + } + filterData.free(); + std::cout << std::endl << "processed " << counter << " scenes" << std::endl; + } + catch (MLibException& e) + { + std::stringstream ss; + ss << "exception caught:" << e.what() << std::endl; + std::cout << ss.str() << std::endl; + } + std::cout << "done done done" << std::endl; + //getchar(); + return 0; +} + +std::vector readScenesFromFile(const std::string& filename) +{ + std::vector scenes; + std::ifstream s(filename); std::string line; + while (std::getline(s, line)) + scenes.push_back(line); + return scenes; +} + +void visualizeAnnotations(const std::string& prefix, const BaseImage& instanceImage, const BaseImage& labelImage = BaseImage(), + bool printLegend = false, const Aggregation& agg = Aggregation()) +{ + static std::unordered_map colormap; + for (const auto& p : instanceImage) { + if (p.value != 0 && colormap.find(p.value) == colormap.end()) { + RGBColor c = RGBColor::randomColor(); + while (vec3f(c).length() < 0.05f) + c = RGBColor::randomColor(); + colormap[p.value] = vec3uc(c.x, c.y, c.z); + } + } + if (labelImage.getNumPixels() > 0) { + for (const auto& p : labelImage) { + if (p.value != 0 && colormap.find(p.value) == colormap.end()) { + RGBColor c = RGBColor::randomColor(); + while (vec3f(c).length() < 0.05f) + c = RGBColor::randomColor(); + colormap[p.value] = vec3uc(c.x, c.y, c.z); + } + } + } + ColorImageR8G8B8 visInstance(instanceImage.getDimensions()), visLabel(labelImage.getDimensions()); + for (unsigned int y = 0; y < instanceImage.getHeight(); y++) { + for (unsigned int x = 0; x < instanceImage.getWidth(); x++) { + const auto instance = instanceImage(x, y); + if (instance == 0) visInstance(x, y) = vec3uc(0, 0, 0); + else visInstance(x, y) = colormap[instance]; + if (labelImage.getNumPixels() > 0) { + const auto label = labelImage(x, y); + if (label == 0) visLabel(x, y) = vec3uc(0, 0, 0); + else visLabel(x, y) = colormap[label]; + } + } + } + FreeImageWrapper::saveImage(prefix + "-instance.png", visInstance); + if (labelImage.getNumPixels() > 0) FreeImageWrapper::saveImage(prefix + "-label.png", visLabel); + + if (printLegend) { + std::unordered_map> instanceColors; + std::unordered_map> labelColors; + const auto& objectIdToLabels = agg.getObjectIdsToLabels(); + bool bRaw = util::endsWith(prefix, "raw"); + for (const auto& p : instanceImage) { + if (p.value != 0) { + const unsigned char inst = p.value - 1; + const auto it = instanceColors.find(inst); + if (it == instanceColors.end()) { + const auto it2 = objectIdToLabels.find(inst); + instanceColors[inst] = std::make_pair(it2->second, colormap[inst+1]); + if (labelImage(p.x, p.y) > 0) { + std::string labelName; + bool valid = LabelUtil::get().getLabelForId(labelImage(p.x, p.y), labelName); + MLIB_ASSERT(valid); + labelColors[labelImage(p.x, p.y)] = std::make_pair(labelName, colormap[labelImage(p.x, p.y)]); + + if (bRaw && labelName != it2->second) + std::cout << "ERROR: inconsistent instance/label" << std::endl; + } + } + } + } + const std::string legendPrefix = prefix + "_legend-"; + for (const auto& c : instanceColors) { + ColorImageR8G8B8 image(100, 100); + image.setPixels(c.second.second); + FreeImageWrapper::saveImage(legendPrefix + "instance_" + c.second.first + ".png", image); + } + for (const auto& c : labelColors) { + ColorImageR8G8B8 image(100, 100); + image.setPixels(c.second.second); + FreeImageWrapper::saveImage(legendPrefix + "label_" + c.second.first + ".png", image); + } + } +} + +ColorImageR32 convertToGrayscale(const ColorImageR8G8B8& color) +{ + ColorImageR32 res(color.getDimensions()); + for (const auto& p : color) { + float v = (0.299f*p.value.x + 0.587f*p.value.y + 0.114f*p.value.z) / 255.0f; + res(p.x, p.y) = v; + } + return res; +} + +void convertToGrayscale(const vec3uc* color, unsigned int width, unsigned int height, ColorImageR32& intensity) +{ + intensity.allocate(width, height); + const float inv = 1.0f / 255.0f; + for (unsigned int y = 0; y < height; y++) { + for (unsigned int x = 0; x < width; x++) { + const vec3uc& c = color[y * width + x]; + float v = (0.299f*c.x + 0.587f*c.y + 0.114f*c.z) * inv; + intensity(x, y) = v; + } + } +} + +void convertToFloat(const unsigned short* depth, unsigned int width, unsigned int height, DepthImage32& depthImage) +{ + depthImage.allocate(width, height); + const float inv = 1.0f / 255.0f; + for (unsigned int y = 0; y < height; y++) { + for (unsigned int x = 0; x < width; x++) { + const unsigned short d = depth[y*width + x]; + if (d == 0) depthImage(x, y) = -std::numeric_limits::infinity(); + else depthImage(x, y) = (float)d * 0.001f; + } + } +} + +void process(FilterData& filterData, std::string path, std::string scanNetPath, std::string outputPath, const std::string& name, bool printDebugOutput) +{ + if (!(path.back() == '\\' || path.back() == '/')) path.push_back('/'); + if (!(scanNetPath.back() == '\\' || scanNetPath.back() == '/')) scanNetPath.push_back('/'); + if (!(outputPath.back() == '\\' || outputPath.back() == '/')) outputPath.push_back('/'); + const std::string instancePath = path + "instance/"; + const std::string labelPath = path + "label/"; + if (!util::directoryExists(labelPath) || !util::directoryExists(instancePath)) + throw MLIB_EXCEPTION("instance/label dir does not exist for " + path); + const std::string outputInstancePath = outputPath + "instance/"; + const std::string outputLabelPath = outputPath + "label/"; + std::cout << path << std::endl; + SensorData sd(scanNetPath + name + "/" + name + ".sens"); + if (util::directoryExists(outputInstancePath) && util::directoryExists(outputLabelPath)) { + Directory outInst(outputInstancePath); + Directory outLabel(outputLabelPath); + if (outInst.getFiles().size() == sd.m_frames.size() && outLabel.getFiles().size() == sd.m_frames.size()) { + std::cout << " ==> skipping, already exists" << std::endl; + return; + } + } + Aggregation agg; agg.loadFromJSONFile(scanNetPath + name + "/" + name + ".aggregation.json"); + const auto& objecIdsToLabelNames = agg.getObjectIdsToLabels(); + + if (!util::directoryExists(outputPath)) util::makeDirectory(outputPath); + if (!util::directoryExists(outputInstancePath)) util::makeDirectory(outputInstancePath); + if (!util::directoryExists(outputLabelPath)) util::makeDirectory(outputLabelPath); + const std::string outDebugPath = "debug/" + name + "/"; + if (printDebugOutput && !util::directoryExists(outDebugPath)) util::makeDirectory(outDebugPath); + + const std::vector filterWidths = { 320, sd.m_colorWidth }; + const std::vector filterHeights = { 240, sd.m_colorHeight }; + const std::vector filterRadii = { 12, 10 }; + const std::vector intensityScales = { 10.0f, 4.0f }; //higher respects edges better but edges are rough and sometimes ends up cutting things that overreach too far + MLIB_ASSERT(filterWidths.size() == filterHeights.size() && filterWidths.size() == intensityScales.size()); + const unsigned int numFiltIters = (unsigned int)filterWidths.size(); + + std::vector objectIdsToIdx(MAX_NUM_LABELS_PER_SCENE, 255), idxToObjectIds(MAX_NUM_LABELS_PER_SCENE, 255); + std::vector objectIdsToLabel(MAX_NUM_LABELS_PER_SCENE, 65535); + unsigned char idx = 1; + objectIdsToIdx[0] = 0; idxToObjectIds[0] = 0; objectIdsToLabel[0] = 0; + for (const auto& a : objecIdsToLabelNames) { //object ids are 0-indexed so add 1 + unsigned short label; + bool bValid = LabelUtil::get().getIdForLabel(a.second, label); + if (!bValid) { + //std::cout << "warning: no label id for " << a.second << std::endl; + label = 0; + } + objectIdsToLabel[a.first + 1] = label; + objectIdsToIdx[a.first + 1] = idx; + idxToObjectIds[idx] = a.first + 1; + idx++; + } + filterData.init(objectIdsToIdx, idxToObjectIds, objectIdsToLabel); + + Directory dir(labelPath); + const auto& files = dir.getFiles(); unsigned int _idx = 0; + for (const auto& f : files) { + const unsigned int frameIdx = util::convertTo(util::removeExtensions(f)); + if (sd.m_frames[frameIdx].getCameraToWorld()[0] == -std::numeric_limits::infinity()) { + BaseImage labelImage(sd.m_colorWidth, sd.m_colorHeight); BaseImage instanceImage(sd.m_colorWidth, sd.m_colorHeight); + labelImage.setPixels(0); instanceImage.setPixels(0); + FreeImageWrapper::saveImage(outputInstancePath + f, instanceImage); + FreeImageWrapper::saveImage(outputLabelPath + f, labelImage); + continue; + } + DepthImage32 depth; ColorImageR32 intensity; + { + unsigned short* depthData = sd.decompressDepthAlloc(frameIdx); + vec3uc* colorData = sd.decompressColorAlloc(frameIdx); + convertToFloat(depthData, sd.m_depthWidth, sd.m_depthHeight, depth); + convertToGrayscale(colorData, sd.m_colorWidth, sd.m_colorHeight, intensity); //could also move to gpu + std::free(depthData); std::free(colorData); + } + MLIB_CUDA_SAFE_CALL(cudaMemcpy(filterData.d_depth, depth.getData(), sizeof(float)*depth.getNumPixels(), cudaMemcpyHostToDevice)); + MLIB_CUDA_SAFE_CALL(cudaMemcpy(filterData.d_intensity, intensity.getData(), sizeof(float)*intensity.getNumPixels(), cudaMemcpyHostToDevice)); + bilateralFilterFloatMap(filterData.d_intensityHelper, filterData.d_intensity, 6.0f, 0.1f, intensity.getWidth(), intensity.getHeight()); + bilateralFilterFloatMap(filterData.d_depthHelper, filterData.d_depth, 2.0f, 0.1f, depth.getWidth(), depth.getHeight()); + + const std::string instanceFile = instancePath + f; + const std::string labelFile = labelPath + f; + BaseImage labelImage; BaseImage instanceImage; + FreeImageWrapper::loadImage(instanceFile, instanceImage); + FreeImageWrapper::loadImage(labelFile, labelImage); + MLIB_CUDA_SAFE_CALL(cudaMemcpy(filterData.d_instanceHelper, instanceImage.getData(), sizeof(unsigned char)*instanceImage.getNumPixels(), cudaMemcpyHostToDevice)); + + if (printDebugOutput && frameIdx % 100 == 0) {//debug vis + FreeImageWrapper::saveImage(outDebugPath + std::to_string(frameIdx) + "_depth.png", ColorImageR32G32B32(depth)); + FreeImageWrapper::saveImage(outDebugPath + std::to_string(frameIdx) + "_intensity.png", intensity); + MLIB_CUDA_SAFE_CALL(cudaMemcpy(intensity.getData(), filterData.d_intensityHelper, sizeof(float)*intensity.getNumPixels(), cudaMemcpyDeviceToHost)); + FreeImageWrapper::saveImage(outDebugPath + std::to_string(frameIdx) + "_intensity-filt.png", intensity); + visualizeAnnotations(outDebugPath + std::to_string(frameIdx) + "_orig", instanceImage, labelImage); + }//debug vis + + //t.start(); + unsigned int curDepthWidth = depth.getWidth(), curDepthHeight = depth.getHeight(); + unsigned int curColorWidth = intensity.getWidth(), curColorHeight = intensity.getHeight(); + if (filterWidths.front() != instanceImage.getWidth()) + resampleUCharMap(filterData.d_instance, filterWidths.front(), filterHeights.front(), filterData.d_instanceHelper, instanceImage.getWidth(), instanceImage.getHeight()); + for (unsigned int iter = 0; iter < numFiltIters; iter++) { + //resample depth + if (curDepthWidth != filterWidths[iter]) { + if (filterWidths[iter] == sd.m_depthWidth) { + if (iter + 1 == numFiltIters) + std::swap(filterData.d_depth, filterData.d_depthHelper); + else + MLIB_CUDA_SAFE_CALL(cudaMemcpy(filterData.d_depth, depth.getData(), sizeof(float)*depth.getNumPixels(), cudaMemcpyHostToDevice)); + } + else { + resampleFloatMap(filterData.d_depth, filterWidths[iter], filterHeights[iter], filterData.d_depthHelper, depth.getWidth(), depth.getHeight()); + } + curDepthWidth = filterWidths[iter]; + curDepthHeight = filterHeights[iter]; + } + //resample color + if (curColorWidth != filterWidths[iter]) { + if (filterWidths[iter] == sd.m_colorWidth) { + if (iter + 1 == numFiltIters) + std::swap(filterData.d_intensity, filterData.d_intensityHelper); + else + MLIB_CUDA_SAFE_CALL(cudaMemcpy(filterData.d_intensity, intensity.getData(), sizeof(float)*intensity.getNumPixels(), cudaMemcpyHostToDevice)); + } + else { + resampleFloatMap(filterData.d_intensity, filterWidths[iter], filterHeights[iter], filterData.d_intensityHelper, intensity.getWidth(), intensity.getHeight()); + } + curColorWidth = filterWidths[iter]; + curColorHeight = filterHeights[iter]; + } + filterAnnotations(filterData.d_instanceHelper, filterData.d_instance, filterData.d_depth, filterData.d_intensity, + filterData.d_instanceToIdx, filterData.d_idxToInstance, filterData.d_vote, + filterRadii[iter], filterWidths[iter], filterHeights[iter], 5.0f, 0.1f, intensityScales[iter]); + + if (iter + 1 == numFiltIters) + std::swap(filterData.d_instanceHelper, filterData.d_instance); //result is in instance + else + resampleUCharMap(filterData.d_instance, filterWidths[iter + 1], filterHeights[iter + 1], filterData.d_instanceHelper, filterWidths[iter], filterHeights[iter]); + } + convertInstanceToLabel(filterData.d_label, filterData.d_instance, filterData.d_instanceToLabel, filterWidths.back(), filterHeights.back()); + MLIB_CUDA_SAFE_CALL(cudaMemcpy(instanceImage.getData(), filterData.d_instance, sizeof(unsigned char)*instanceImage.getNumPixels(), cudaMemcpyDeviceToHost)); + MLIB_CUDA_SAFE_CALL(cudaMemcpy(labelImage.getData(), filterData.d_label, sizeof(unsigned short)*labelImage.getNumPixels(), cudaMemcpyDeviceToHost)); + + //save out + FreeImageWrapper::saveImage(outputInstancePath + f, instanceImage); + FreeImageWrapper::saveImage(outputLabelPath + f, labelImage); + + if (printDebugOutput && frameIdx % 100 == 0) {//debug vis + visualizeAnnotations(outDebugPath + std::to_string(frameIdx) + "_filt", instanceImage, labelImage); + std::cout << "waiting..." << std::endl; + getchar(); + } + if (_idx % 10 == 0 || _idx + 1 == files.size()) + std::cout << "\r[ " << _idx << " | " << files.size() << " ]"; + ++_idx; + } + std::cout << std::endl; +} + +void debugVis(const std::string& rawPath, const std::string& filtPath, const std::string& scene, const std::string& scanNetPath, const std::string& outDir) +{ + const unsigned int frameIdx = 400;//0; + const std::string rawInstanceFile = rawPath + scene + "/instance/" + std::to_string(frameIdx) + ".png"; + const std::string rawLabelFile = rawPath + scene + "/label/" + std::to_string(frameIdx) + ".png"; + const std::string filtInstanceFile = filtPath + scene + "/instance/" + std::to_string(frameIdx) + ".png"; + const std::string filtLabelFile = filtPath + scene + "/label/" + std::to_string(frameIdx) + ".png"; + + Aggregation agg; agg.loadFromJSONFile(scanNetPath + scene + "/" + scene + ".aggregation.json"); + SensorData sd(scanNetPath + scene + "/" + scene + ".sens"); + DepthImage32 depth = sd.computeDepthImage(frameIdx); + ColorImageR8G8B8 color = sd.computeColorImage(frameIdx); + + BaseImage rawInstance, filtInstance; + BaseImage rawLabel, filtLabel; + FreeImageWrapper::loadImage(rawInstanceFile, rawInstance); + FreeImageWrapper::loadImage(filtInstanceFile, filtInstance); + FreeImageWrapper::loadImage(rawLabelFile, rawLabel); + FreeImageWrapper::loadImage(filtLabelFile, filtLabel); + + visualizeAnnotations(outDir + "raw", rawInstance, rawLabel, true, agg); + visualizeAnnotations(outDir + "filt", filtInstance, filtLabel); + FreeImageWrapper::saveImage(outDir + "depth.png", ColorImageR32G32B32(depth)); + FreeImageWrapper::saveImage(outDir + "color.png", color); +} + diff --git a/AnnotationTools/Filter2dAnnotations/Filter2dAnnotations.sln b/AnnotationTools/Filter2dAnnotations/Filter2dAnnotations.sln new file mode 100644 index 0000000..f48e399 --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/Filter2dAnnotations.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Filter2dAnnotations", "Filter2dAnnotations.vcxproj", "{5427D3D9-F7E5-4625-A73D-9CF84E22FF06}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5427D3D9-F7E5-4625-A73D-9CF84E22FF06}.Debug|x64.ActiveCfg = Debug|x64 + {5427D3D9-F7E5-4625-A73D-9CF84E22FF06}.Debug|x64.Build.0 = Debug|x64 + {5427D3D9-F7E5-4625-A73D-9CF84E22FF06}.Release|x64.ActiveCfg = Release|x64 + {5427D3D9-F7E5-4625-A73D-9CF84E22FF06}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/AnnotationTools/Filter2dAnnotations/Filter2dAnnotations.vcxproj b/AnnotationTools/Filter2dAnnotations/Filter2dAnnotations.vcxproj new file mode 100644 index 0000000..abfce9e --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/Filter2dAnnotations.vcxproj @@ -0,0 +1,127 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {5427D3D9-F7E5-4625-A73D-9CF84E22FF06} + Win32Proj + Filter2dAnnotations + + + + Application + true + v120 + Unicode + + + Application + false + v120 + true + Unicode + + + + + + + + + + + + + + true + ../../external/mLib/include;../../../mLibExternal/include;../../external/cutil/inc;$(IncludePath) + ../../../mLibExternal/libsWindows/lib64;$(LibraryPath) + + + false + ../../external/mLib/include;../../../mLibExternal/include;../../external/cutil/inc;$(IncludePath) + ../../../mLibExternal/libsWindows/lib64;$(LibraryPath) + + + + Use + Level3 + Disabled + WIN32;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + FreeImage.lib;cudart.lib;cublas.lib;%(AdditionalDependencies) + + + compute_35,sm_35 + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;_CRT_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + + + Console + true + true + true + FreeImage.lib;cudart.lib;cublas.lib;%(AdditionalDependencies) + + + compute_35,sm_35 + + + + + + + + + + + + + + + + + + + + + + + + true + true + + + Create + Create + + + + + + + + + + \ No newline at end of file diff --git a/AnnotationTools/Filter2dAnnotations/Filter2dAnnotations.vcxproj.filters b/AnnotationTools/Filter2dAnnotations/Filter2dAnnotations.vcxproj.filters new file mode 100644 index 0000000..d26326d --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/Filter2dAnnotations.vcxproj.filters @@ -0,0 +1,75 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + + \ No newline at end of file diff --git a/AnnotationTools/Filter2dAnnotations/GlobalDefines.h b/AnnotationTools/Filter2dAnnotations/GlobalDefines.h new file mode 100644 index 0000000..7c8a2e4 --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/GlobalDefines.h @@ -0,0 +1,14 @@ +#ifndef GLOBAL_DEFINES_H +#define GLOBAL_DEFINES_H + + +#define MLIB_CUDA_SAFE_CALL(b) { if(b != cudaSuccess) throw MLIB_EXCEPTION(std::string(cudaGetErrorString(b)) + ":" + std::string(__FUNCTION__)); } +#define MLIB_CUDA_SAFE_FREE(b) { if(!b) { MLIB_CUDA_SAFE_CALL(cudaFree(b)); b = NULL; } } +#define MLIB_CUDA_CHECK_ERR(msg) { cudaError_t err = cudaGetLastError(); if (err != cudaSuccess) { throw MLIB_EXCEPTION(cudaGetErrorString( err )); } } + + + + +#define MAX_NUM_LABELS_PER_SCENE 80 //current max = 76 + +#endif //GLOBAL_DEFINES_H \ No newline at end of file diff --git a/AnnotationTools/Filter2dAnnotations/LabelUtil.h b/AnnotationTools/Filter2dAnnotations/LabelUtil.h new file mode 100644 index 0000000..1f9d9c3 --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/LabelUtil.h @@ -0,0 +1,89 @@ +#pragma once + +class LabelUtil +{ +public: + LabelUtil() {} + void init(const std::string& labelMapFile, const std::string& labelName = "category", const std::string& idName = "") { + if (!util::fileExists(labelMapFile)) throw MLIB_EXCEPTION(labelMapFile + " does not exist!"); + m_maxLabel = 65535;//255; + + getLabelMappingFromFile(labelMapFile, labelName, idName); + + m_bIsInitialized = true; + } + + static LabelUtil& getInstance() { + static LabelUtil s; + return s; + } + static LabelUtil& get() { + return getInstance(); + } + + bool getIdForLabel(const std::string& label, unsigned short& id) const { + const auto it = s_labelsToIds.find(label); + if (it == s_labelsToIds.end()) return false; + id = it->second; + return true; + } + + bool getLabelForId(unsigned short id, std::string& label) const { + const auto it = s_idsToLabels.find(id); + if (it == s_idsToLabels.end()) return false; + label = it->second; + return true; + } + +private: + + void getLabelMappingFromFile(const std::string& filename, const std::string& labelName, const std::string& idName) + { + if (!util::fileExists(filename)) throw MLIB_EXCEPTION("label mapping files does not exist!"); + const char splitter = '\t'; + + s_labelsToIds.clear(); + s_idsToLabels.clear(); + + std::ifstream s(filename); std::string line; + //read header + std::unordered_map header; + if (!std::getline(s, line)) throw MLIB_EXCEPTION("error reading label mapping file"); + auto parts = util::split(line, splitter); + const unsigned int numElems = (unsigned int)parts.size(); + for (unsigned int i = 0; i < parts.size(); i++) header[parts[i]] = i; + + auto it = header.find(labelName); + if (it == header.end()) throw MLIB_EXCEPTION("could not find value " + labelName + " in label mapping file"); + unsigned int labelIdx = it->second; + bool bUseExistingLabel = !idName.empty(); unsigned int idIdx = (unsigned int)-1; + if (bUseExistingLabel) { + it = header.find(idName); + if (it == header.end()) throw MLIB_EXCEPTION("could not find value " + idName + " in label mapping file"); + idIdx = it->second; + } + //read elements + unsigned int lineCount = 1; + while (std::getline(s, line)) { + parts = util::split(line, splitter, true); + if (!parts[labelIdx].empty() && (!bUseExistingLabel || !parts[idIdx].empty())) { + unsigned int id = bUseExistingLabel ? util::convertTo(parts[idIdx]) : lineCount; + if (id > m_maxLabel) //skip + continue; + s_labelsToIds[parts[labelIdx]] = (unsigned short)id; + s_idsToLabels[(unsigned short)id] = parts[labelIdx]; + } + ++lineCount; + } + s.close(); + + std::cout << "read " << s_labelsToIds.size() << " labels" << std::endl; + } + + bool m_bIsInitialized; + unsigned short m_maxLabel; + + std::unordered_map s_labelsToIds; + std::unordered_map s_idsToLabels; + +}; \ No newline at end of file diff --git a/AnnotationTools/Filter2dAnnotations/MatrixConversion.h b/AnnotationTools/Filter2dAnnotations/MatrixConversion.h new file mode 100644 index 0000000..bbf73ef --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/MatrixConversion.h @@ -0,0 +1,40 @@ +#pragma once + +#include "cuda_SimpleMatrixUtil.h" + +namespace MatrixConversion +{ + static mat4f toMlib(const float4x4& m) { + return mat4f(m.ptr()); + } + static vec4f toMlib(const float4& v) { + return vec4f(v.x, v.y, v.z, v.w); + } + static vec3f toMlib(const float3& v) { + return vec3f(v.x, v.y, v.z); + } + static vec4i toMlib(const int4& v) { + return vec4i(v.x, v.y, v.z, v.w); + } + static vec3i toMlib(const int3& v) { + return vec3i(v.x, v.y, v.z); + } + static float4x4 toCUDA(const mat4f& m) { + return float4x4(m.getData()); + } + + static float4 toCUDA(const vec4f& v) { + return make_float4(v.x, v.y, v.z, v.w); + } + static float3 toCUDA(const vec3f& v) { + return make_float3(v.x, v.y, v.z); + } + static int4 toCUDA(const vec4i& v) { + return make_int4(v.x, v.y, v.z, v.w); + } + static int3 toCUDA(const vec3i& v) { + return make_int3(v.x, v.y, v.z); + } + + +} diff --git a/AnnotationTools/Filter2dAnnotations/cudaUtil.h b/AnnotationTools/Filter2dAnnotations/cudaUtil.h new file mode 100644 index 0000000..9c5d4b8 --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/cudaUtil.h @@ -0,0 +1,22 @@ +#pragma once + +#ifndef _CUDA_UTIL_ +#define _CUDA_UTIL_ + +#undef max +#undef min + +#include +#include + +// Enable run time assertion checking in kernel code +#define cudaAssert(condition) if (!(condition)) { printf("ASSERT: %s %s\n", #condition, __FILE__); } +//#define cudaAssert(condition) + +#if defined(__CUDA_ARCH__) +#define __CONDITIONAL_UNROLL__ #pragma unroll +#else +#define __CONDITIONAL_UNROLL__ +#endif + +#endif diff --git a/AnnotationTools/Filter2dAnnotations/cuda_SimpleMatrixUtil.h b/AnnotationTools/Filter2dAnnotations/cuda_SimpleMatrixUtil.h new file mode 100644 index 0000000..eeb6a4c --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/cuda_SimpleMatrixUtil.h @@ -0,0 +1,1755 @@ +#pragma once + +#ifndef _CUDA_SIMPLE_MATRIX_UTIL_ +#define _CUDA_SIMPLE_MATRIX_UTIL_ + +#define MINF __int_as_float(0xff800000) +#define INF __int_as_float(0x7f800000) + +#include +#include "cudaUtil.h" + +////////////////////////////// +// float2x2 +////////////////////////////// + +class float2x2 +{ +public: + + inline __device__ __host__ float2x2() + { + } + + inline __device__ __host__ float2x2(const float values[4]) + { + m11 = values[0]; m12 = values[1]; + m21 = values[2]; m22 = values[3]; + } + + inline __device__ __host__ float2x2(const float2x2& other) + { + m11 = other.m11; m12 = other.m12; + m21 = other.m21; m22 = other.m22; + } + + inline __device__ __host__ void setZero() + { + m11 = 0.0f; m12 = 0.0f; + m21 = 0.0f; m22 = 0.0f; + } + + static inline __device__ __host__ float2x2 getIdentity() + { + float2x2 res; + res.setZero(); + res.m11 = res.m22 = 1.0f; + return res; + } + + inline __device__ __host__ float2x2& operator=(const float2x2 &other) + { + m11 = other.m11; m12 = other.m12; + m21 = other.m21; m22 = other.m22; + return *this; + } + + inline __device__ __host__ float2x2 getInverse() + { + float2x2 res; + res.m11 = m22; res.m12 = -m12; + res.m21 = -m21; res.m22 = m11; + + return res*(1.0f/det()); + } + + inline __device__ __host__ float det() + { + return m11*m22-m21*m12; + } + + inline __device__ __host__ float2 operator*(const float2& v) const + { + return make_float2(m11*v.x + m12*v.y, m21*v.x + m22*v.y); + } + + //! matrix scalar multiplication + inline __device__ __host__ float2x2 operator*(const float t) const + { + float2x2 res; + res.m11 = m11 * t; res.m12 = m12 * t; + res.m21 = m21 * t; res.m22 = m22 * t; + return res; + } + + //! matrix matrix multiplication + inline __device__ __host__ float2x2 operator*(const float2x2& other) const + { + float2x2 res; + res.m11 = m11 * other.m11 + m12 * other.m21; + res.m12 = m11 * other.m12 + m12 * other.m22; + res.m21 = m21 * other.m11 + m22 * other.m21; + res.m22 = m21 * other.m12 + m22 * other.m22; + return res; + } + + //! matrix matrix addition + inline __device__ __host__ float2x2 operator+(const float2x2& other) const + { + float2x2 res; + res.m11 = m11 + other.m11; + res.m12 = m12 + other.m12; + res.m21 = m21 + other.m21; + res.m22 = m22 + other.m22; + return res; + } + + inline __device__ __host__ float& operator()(int i, int j) + { + return entries2[i][j]; + } + + inline __device__ __host__ float operator()(int i, int j) const + { + return entries2[i][j]; + } + + inline __device__ __host__ const float* ptr() const { + return entries; + } + inline __device__ __host__ float* ptr() { + return entries; + } + + union + { + struct + { + float m11; float m12; + float m21; float m22; + }; + + float entries[4]; + float entries2[2][2]; + }; +}; + +////////////////////////////// +// float2x3 +////////////////////////////// + +class float2x3 +{ +public: + + inline __device__ __host__ float2x3() + { + } + + inline __device__ __host__ float2x3(const float values[6]) + { + m11 = values[0]; m12 = values[1]; m13 = values[2]; + m21 = values[3]; m22 = values[4]; m23 = values[5]; + } + + inline __device__ __host__ float2x3(const float2x3& other) + { + m11 = other.m11; m12 = other.m12; m13 = other.m13; + m21 = other.m21; m22 = other.m22; m23 = other.m23; + } + + inline __device__ __host__ float2x3& operator=(const float2x3 &other) + { + m11 = other.m11; m12 = other.m12; m13 = other.m13; + m21 = other.m21; m22 = other.m22; m23 = other.m23; + return *this; + } + + inline __device__ __host__ float2 operator*(const float3 &v) const + { + return make_float2(m11*v.x + m12*v.y + m13*v.z, m21*v.x + m22*v.y + m23*v.z); + } + + //! matrix scalar multiplication + inline __device__ __host__ float2x3 operator*(const float t) const + { + float2x3 res; + res.m11 = m11 * t; res.m12 = m12 * t; res.m13 = m13 * t; + res.m21 = m21 * t; res.m22 = m22 * t; res.m23 = m23 * t; + return res; + } + + //! matrix scalar division + inline __device__ __host__ float2x3 operator/(const float t) const + { + float2x3 res; + res.m11 = m11 / t; res.m12 = m12 / t; res.m13 = m13 / t; + res.m21 = m21 / t; res.m22 = m22 / t; res.m23 = m23 / t; + return res; + } + + inline __device__ __host__ float& operator()(int i, int j) + { + return entries2[i][j]; + } + + inline __device__ __host__ float operator()(int i, int j) const + { + return entries2[i][j]; + } + + inline __device__ __host__ const float* ptr() const { + return entries; + } + inline __device__ __host__ float* ptr() { + return entries; + } + + union + { + struct + { + float m11; float m12; float m13; + float m21; float m22; float m23; + }; + + float entries[6]; + float entries2[3][2]; + }; +}; + +////////////////////////////// +// float3x2 +////////////////////////////// + +class float3x2 +{ +public: + + inline __device__ __host__ float3x2() + { + } + + inline __device__ __host__ float3x2(const float values[6]) + { + m11 = values[0]; m12 = values[1]; + m21 = values[2]; m22 = values[3]; + m31 = values[4]; m32 = values[5]; + } + + inline __device__ __host__ float3x2& operator=(const float3x2& other) + { + m11 = other.m11; m12 = other.m12; + m21 = other.m21; m22 = other.m22; + m31 = other.m31; m32 = other.m32; + return *this; + } + + inline __device__ __host__ float3 operator*(const float2& v) const + { + return make_float3(m11*v.x + m12*v.y, m21*v.x + m22*v.y, m31*v.x + m32*v.y); + } + + inline __device__ __host__ float3x2 operator*(const float t) const + { + float3x2 res; + res.m11 = m11 * t; res.m12 = m12 * t; + res.m21 = m21 * t; res.m22 = m22 * t; + res.m31 = m31 * t; res.m32 = m32 * t; + return res; + } + + inline __device__ __host__ float& operator()(int i, int j) + { + return entries2[i][j]; + } + + inline __device__ __host__ float operator()(int i, int j) const + { + return entries2[i][j]; + } + + inline __device__ __host__ float2x3 getTranspose() + { + float2x3 res; + res.m11 = m11; res.m12 = m21; res.m13 = m31; + res.m21 = m12; res.m22 = m22; res.m23 = m32; + return res; + } + + inline __device__ __host__ const float* ptr() const { + return entries; + } + inline __device__ __host__ float* ptr() { + return entries; + } + + union + { + struct + { + float m11; float m12; + float m21; float m22; + float m31; float m32; + }; + + float entries[6]; + float entries2[3][2]; + }; +}; + +inline __device__ __host__ float2x2 matMul(const float2x3& m0, const float3x2& m1) +{ + float2x2 res; + res.m11 = m0.m11*m1.m11+m0.m12*m1.m21+m0.m13*m1.m31; + res.m12 = m0.m11*m1.m12+m0.m12*m1.m22+m0.m13*m1.m32; + res.m21 = m0.m21*m1.m11+m0.m22*m1.m21+m0.m23*m1.m31; + res.m22 = m0.m21*m1.m12+m0.m22*m1.m22+m0.m23*m1.m32; + return res; +} + +class float3x3 { +public: + inline __device__ __host__ float3x3() { + + } + inline __device__ __host__ float3x3(const float values[9]) { + m11 = values[0]; m12 = values[1]; m13 = values[2]; + m21 = values[3]; m22 = values[4]; m23 = values[5]; + m31 = values[6]; m32 = values[7]; m33 = values[8]; + } + + inline __device__ __host__ float3x3(const float3x3& other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; + m21 = other.m21; m22 = other.m22; m23 = other.m23; + m31 = other.m31; m32 = other.m32; m33 = other.m33; + } + + explicit inline __device__ __host__ float3x3(const float2x2& other) { + m11 = other.m11; m12 = other.m12; m13 = 0.0; + m21 = other.m21; m22 = other.m22; m23 = 0.0; + m31 = 0.0; m32 = 0.0; m33 = 0.0; + } + + inline __device__ __host__ float3x3& operator=(const float3x3 &other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; + m21 = other.m21; m22 = other.m22; m23 = other.m23; + m31 = other.m31; m32 = other.m32; m33 = other.m33; + return *this; + } + + inline __device__ __host__ float& operator()(int i, int j) { + return entries2[i][j]; + } + + inline __device__ __host__ float operator()(int i, int j) const { + return entries2[i][j]; + } + + + static inline __device__ __host__ void swap(float& v0, float& v1) { + float tmp = v0; + v0 = v1; + v1 = tmp; + } + + inline __device__ __host__ void transpose() { + swap(m12, m21); + swap(m13, m31); + swap(m23, m32); + } + inline __device__ __host__ float3x3 getTranspose() const { + float3x3 ret = *this; + ret.transpose(); + return ret; + } + + //! inverts the matrix + inline __device__ __host__ void invert() { + *this = getInverse(); + } + + //! computes the inverse of the matrix; the result is returned + inline __device__ __host__ float3x3 getInverse() const { + float3x3 res; + res.entries[0] = entries[4]*entries[8] - entries[5]*entries[7]; + res.entries[1] = -entries[1]*entries[8] + entries[2]*entries[7]; + res.entries[2] = entries[1]*entries[5] - entries[2]*entries[4]; + + res.entries[3] = -entries[3]*entries[8] + entries[5]*entries[6]; + res.entries[4] = entries[0]*entries[8] - entries[2]*entries[6]; + res.entries[5] = -entries[0]*entries[5] + entries[2]*entries[3]; + + res.entries[6] = entries[3]*entries[7] - entries[4]*entries[6]; + res.entries[7] = -entries[0]*entries[7] + entries[1]*entries[6]; + res.entries[8] = entries[0]*entries[4] - entries[1]*entries[3]; + float nom = 1.0f/det(); + return res * nom; + } + + inline __device__ __host__ void setZero(float value = 0.0f) { + m11 = m12 = m13 = value; + m21 = m22 = m23 = value; + m31 = m32 = m33 = value; + } + + inline __device__ __host__ float det() const { + return + + m11*m22*m33 + + m12*m23*m31 + + m13*m21*m32 + - m31*m22*m13 + - m32*m23*m11 + - m33*m21*m12; + } + + inline __device__ __host__ float3 getRow(unsigned int i) { + return make_float3(entries[3*i+0], entries[3*i+1], entries[3*i+2]); + } + + inline __device__ __host__ void setRow(unsigned int i, float3& r) { + entries[3*i+0] = r.x; + entries[3*i+1] = r.y; + entries[3*i+2] = r.z; + } + + inline __device__ __host__ void normalizeRows() + { + //#pragma unroll 3 + for(unsigned int i = 0; i<3; i++) + { + float3 r = getRow(i); + r/=length(r); + setRow(i, r); + } + } + + //! computes the product of two matrices (result stored in this) + inline __device__ __host__ void mult(const float3x3 &other) { + float3x3 res; + res.m11 = m11 * other.m11 + m12 * other.m21 + m13 * other.m31; + res.m12 = m11 * other.m12 + m12 * other.m22 + m13 * other.m32; + res.m13 = m11 * other.m13 + m12 * other.m23 + m13 * other.m33; + + res.m21 = m21 * other.m11 + m22 * other.m21 + m23 * other.m31; + res.m22 = m21 * other.m12 + m22 * other.m22 + m23 * other.m32; + res.m23 = m21 * other.m13 + m22 * other.m23 + m23 * other.m33; + + res.m31 = m21 * other.m11 + m32 * other.m21 + m33 * other.m31; + res.m32 = m21 * other.m12 + m32 * other.m22 + m33 * other.m32; + res.m33 = m21 * other.m13 + m32 * other.m23 + m33 * other.m33; + *this = res; + } + + //! computes the sum of two matrices (result stored in this) + inline __device__ __host__ void add(const float3x3 &other) { + m11 += other.m11; m12 += other.m12; m13 += other.m13; + m21 += other.m21; m22 += other.m22; m23 += other.m23; + m31 += other.m31; m32 += other.m32; m33 += other.m33; + } + + //! standard matrix matrix multiplication + inline __device__ __host__ float3x3 operator*(const float3x3 &other) const { + float3x3 res; + res.m11 = m11 * other.m11 + m12 * other.m21 + m13 * other.m31; + res.m12 = m11 * other.m12 + m12 * other.m22 + m13 * other.m32; + res.m13 = m11 * other.m13 + m12 * other.m23 + m13 * other.m33; + + res.m21 = m21 * other.m11 + m22 * other.m21 + m23 * other.m31; + res.m22 = m21 * other.m12 + m22 * other.m22 + m23 * other.m32; + res.m23 = m21 * other.m13 + m22 * other.m23 + m23 * other.m33; + + res.m31 = m31 * other.m11 + m32 * other.m21 + m33 * other.m31; + res.m32 = m31 * other.m12 + m32 * other.m22 + m33 * other.m32; + res.m33 = m31 * other.m13 + m32 * other.m23 + m33 * other.m33; + return res; + } + + //! standard matrix matrix multiplication + inline __device__ __host__ float3x2 operator*(const float3x2 &other) const { + float3x2 res; + res.m11 = m11 * other.m11 + m12 * other.m21 + m13 * other.m31; + res.m12 = m11 * other.m12 + m12 * other.m22 + m13 * other.m32; + + res.m21 = m21 * other.m11 + m22 * other.m21 + m23 * other.m31; + res.m22 = m21 * other.m12 + m22 * other.m22 + m23 * other.m32; + + res.m31 = m31 * other.m11 + m32 * other.m21 + m33 * other.m31; + res.m32 = m31 * other.m12 + m32 * other.m22 + m33 * other.m32; + return res; + } + + inline __device__ __host__ float3 operator*(const float3 &v) const { + return make_float3( + m11*v.x + m12*v.y + m13*v.z, + m21*v.x + m22*v.y + m23*v.z, + m31*v.x + m32*v.y + m33*v.z + ); + } + + inline __device__ __host__ float3x3 operator*(const float t) const { + float3x3 res; + res.m11 = m11 * t; res.m12 = m12 * t; res.m13 = m13 * t; + res.m21 = m21 * t; res.m22 = m22 * t; res.m23 = m23 * t; + res.m31 = m31 * t; res.m32 = m32 * t; res.m33 = m33 * t; + return res; + } + + + inline __device__ __host__ float3x3 operator+(const float3x3 &other) const { + float3x3 res; + res.m11 = m11 + other.m11; res.m12 = m12 + other.m12; res.m13 = m13 + other.m13; + res.m21 = m21 + other.m21; res.m22 = m22 + other.m22; res.m23 = m23 + other.m23; + res.m31 = m31 + other.m31; res.m32 = m32 + other.m32; res.m33 = m33 + other.m33; + return res; + } + + inline __device__ __host__ float3x3 operator-(const float3x3 &other) const { + float3x3 res; + res.m11 = m11 - other.m11; res.m12 = m12 - other.m12; res.m13 = m13 - other.m13; + res.m21 = m21 - other.m21; res.m22 = m22 - other.m22; res.m23 = m23 - other.m23; + res.m31 = m31 - other.m31; res.m32 = m32 - other.m32; res.m33 = m33 - other.m33; + return res; + } + + static inline __device__ __host__ float3x3 getIdentity() { + float3x3 res; + res.setZero(); + res.m11 = res.m22 = res.m33 = 1.0f; + return res; + } + + static inline __device__ __host__ float3x3 getZeroMatrix() { + float3x3 res; + res.setZero(); + return res; + } + + static inline __device__ __host__ float3x3 getDiagonalMatrix(float diag = 1.0f) { + float3x3 res; + res.m11 = diag; res.m12 = 0.0f; res.m13 = 0.0f; + res.m21 = 0.0f; res.m22 = diag; res.m23 = 0.0f; + res.m31 = 0.0f; res.m32 = 0.0f; res.m33 = diag; + return res; + } + + static inline __device__ __host__ float3x3 tensorProduct(const float3 &v, const float3 &vt) { + float3x3 res; + res.m11 = v.x * vt.x; res.m12 = v.x * vt.y; res.m13 = v.x * vt.z; + res.m21 = v.y * vt.x; res.m22 = v.y * vt.y; res.m23 = v.y * vt.z; + res.m31 = v.z * vt.x; res.m32 = v.z * vt.y; res.m33 = v.z * vt.z; + return res; + } + + inline __device__ __host__ const float* ptr() const { + return entries; + } + inline __device__ __host__ float* ptr() { + return entries; + } + + union { + struct { + float m11; float m12; float m13; + float m21; float m22; float m23; + float m31; float m32; float m33; + }; + float entries[9]; + float entries2[3][3]; + }; +}; + + +inline __device__ __host__ float2x3 matMul(const float2x3& m0, const float3x3& m1) +{ + float2x3 res; + res.m11 = m0.m11*m1.m11+m0.m12*m1.m21+m0.m13*m1.m31; + res.m12 = m0.m11*m1.m12+m0.m12*m1.m22+m0.m13*m1.m32; + res.m13 = m0.m11*m1.m13+m0.m12*m1.m23+m0.m13*m1.m33; + + res.m21 = m0.m21*m1.m11+m0.m22*m1.m21+m0.m23*m1.m31; + res.m22 = m0.m21*m1.m12+m0.m22*m1.m22+m0.m23*m1.m32; + res.m23 = m0.m21*m1.m13+m0.m22*m1.m23+m0.m23*m1.m33; + return res; +} + +// (1x2) row matrix as float2 +inline __device__ __host__ float3 matMul(const float2& m0, const float2x3& m1) +{ + float3 res; + res.x = m0.x*m1.m11+m0.y*m1.m21; + res.y = m0.x*m1.m12+m0.y*m1.m22; + res.z = m0.x*m1.m13+m0.y*m1.m23; + + return res; +} + + +class float3x4 { +public: + inline __device__ __host__ float3x4() { + + } + inline __device__ __host__ float3x4(const float values[12]) { + m11 = values[0]; m12 = values[1]; m13 = values[2]; m14 = values[3]; + m21 = values[4]; m22 = values[5]; m23 = values[6]; m24 = values[7]; + m31 = values[8]; m32 = values[9]; m33 = values[10]; m34 = values[11]; + } + + inline __device__ __host__ float3x4(const float3x4& other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; m14 = other.m14; + m21 = other.m21; m22 = other.m22; m23 = other.m23; m24 = other.m24; + m31 = other.m31; m32 = other.m32; m33 = other.m33; m34 = other.m34; + } + + inline __device__ __host__ float3x4(const float3x3& other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; m14 = 0.0f; + m21 = other.m21; m22 = other.m22; m23 = other.m23; m24 = 0.0f; + m31 = other.m31; m32 = other.m32; m33 = other.m33; m34 = 0.0f; + } + + inline __device__ __host__ float3x4 operator=(const float3x4 &other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; m14 = other.m14; + m21 = other.m21; m22 = other.m22; m23 = other.m23; m24 = other.m24; + m31 = other.m31; m32 = other.m32; m33 = other.m33; m34 = other.m34; + return *this; + } + + inline __device__ __host__ float3x4& operator=(const float3x3 &other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; m14 = 0.0f; + m21 = other.m21; m22 = other.m22; m23 = other.m23; m24 = 0.0f; + m31 = other.m31; m32 = other.m32; m33 = other.m33; m34 = 0.0f; + return *this; + } + + //! assumes the last line of the matrix implicitly to be (0,0,0,1) + inline __device__ __host__ float4 operator*(const float4 &v) const { + return make_float4( + m11*v.x + m12*v.y + m13*v.z + m14*v.w, + m21*v.x + m22*v.y + m23*v.z + m24*v.w, + m31*v.x + m32*v.y + m33*v.z + m34*v.w, + v.w + ); + } + + //! assumes an implicit 1 in w component of the input vector + inline __device__ __host__ float3 operator*(const float3 &v) const { + return make_float3( + m11*v.x + m12*v.y + m13*v.z + m14, + m21*v.x + m22*v.y + m23*v.z + m24, + m31*v.x + m32*v.y + m33*v.z + m34 + ); + } + + //! matrix scalar multiplication + inline __device__ __host__ float3x4 operator*(const float t) const { + float3x4 res; + res.m11 = m11 * t; res.m12 = m12 * t; res.m13 = m13 * t; res.m14 = m14 * t; + res.m21 = m21 * t; res.m22 = m22 * t; res.m23 = m23 * t; res.m24 = m24 * t; + res.m31 = m31 * t; res.m32 = m32 * t; res.m33 = m33 * t; res.m34 = m34 * t; + return res; + } + inline __device__ __host__ float3x4& operator*=(const float t) { + *this = *this * t; + return *this; + } + + //! matrix scalar division + inline __device__ __host__ float3x4 operator/(const float t) const { + float3x4 res; + res.m11 = m11 / t; res.m12 = m12 / t; res.m13 = m13 / t; res.m14 = m14 / t; + res.m21 = m21 / t; res.m22 = m22 / t; res.m23 = m23 / t; res.m24 = m24 / t; + res.m31 = m31 / t; res.m32 = m32 / t; res.m33 = m33 / t; res.m34 = m34 / t; + return res; + } + inline __device__ __host__ float3x4& operator/=(const float t) { + *this = *this / t; + return *this; + } + + //! assumes the last line of the matrix implicitly to be (0,0,0,1) + inline __device__ __host__ float3x4 operator*(const float3x4 &other) const { + float3x4 res; + res.m11 = m11*other.m11 + m12*other.m21 + m13*other.m31; + res.m12 = m11*other.m12 + m12*other.m22 + m13*other.m32; + res.m13 = m11*other.m13 + m12*other.m23 + m13*other.m33; + res.m14 = m11*other.m14 + m12*other.m24 + m13*other.m34 + m14; + + res.m21 = m21*other.m11 + m22*other.m21 + m23*other.m31; + res.m22 = m21*other.m12 + m22*other.m22 + m23*other.m32; + res.m23 = m21*other.m13 + m22*other.m23 + m23*other.m33; + res.m24 = m21*other.m14 + m22*other.m24 + m23*other.m34 + m24; + + res.m31 = m31*other.m11 + m32*other.m21 + m33*other.m31; + res.m32 = m31*other.m12 + m32*other.m22 + m33*other.m32; + res.m33 = m31*other.m13 + m32*other.m23 + m33*other.m33; + res.m34 = m31*other.m14 + m32*other.m24 + m33*other.m34 + m34; + + //res.m41 = m41*other.m11 + m42*other.m21 + m43*other.m31 + m44*other.m41; + //res.m42 = m41*other.m12 + m42*other.m22 + m43*other.m32 + m44*other.m42; + //res.m43 = m41*other.m13 + m42*other.m23 + m43*other.m33 + m44*other.m43; + //res.m44 = m41*other.m14 + m42*other.m24 + m43*other.m34 + m44*other.m44; + + return res; + } + + //! assumes the last line of the matrix implicitly to be (0,0,0,1); and a (0,0,0) translation of other + inline __device__ __host__ float3x4 operator*(const float3x3 &other) const { + float3x4 res; + res.m11 = m11*other.m11 + m12*other.m21 + m13*other.m31; + res.m12 = m11*other.m12 + m12*other.m22 + m13*other.m32; + res.m13 = m11*other.m13 + m12*other.m23 + m13*other.m33; + res.m14 = m14; + + res.m21 = m21*other.m11 + m22*other.m21 + m23*other.m31; + res.m22 = m21*other.m12 + m22*other.m22 + m23*other.m32; + res.m23 = m21*other.m13 + m22*other.m23 + m23*other.m33; + res.m24 = m24; + + res.m31 = m31*other.m11 + m32*other.m21 + m33*other.m31; + res.m32 = m31*other.m12 + m32*other.m22 + m33*other.m32; + res.m33 = m31*other.m13 + m32*other.m23 + m33*other.m33; + res.m34 = m34; + + return res; + } + + + + inline __device__ __host__ float& operator()(int i, int j) { + return entries2[i][j]; + } + + inline __device__ __host__ float operator()(int i, int j) const { + return entries2[i][j]; + } + + //! returns the translation part of the matrix + inline __device__ __host__ float3 getTranslation() { + return make_float3(m14, m24, m34); + } + + //! sets only the translation part of the matrix (other values remain unchanged) + inline __device__ __host__ void setTranslation(const float3 &t) { + m14 = t.x; + m24 = t.y; + m34 = t.z; + } + + //! returns the 3x3 part of the matrix + inline __device__ __host__ float3x3 getFloat3x3() { + float3x3 ret; + ret.m11 = m11; ret.m12 = m12; ret.m13 = m13; + ret.m21 = m21; ret.m22 = m22; ret.m23 = m23; + ret.m31 = m31; ret.m32 = m32; ret.m33 = m33; + return ret; + } + + //! sets the 3x3 part of the matrix (other values remain unchanged) + inline __device__ __host__ void setFloat3x3(const float3x3 &other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; + m21 = other.m21; m22 = other.m22; m23 = other.m23; + m31 = other.m31; m32 = other.m32; m33 = other.m33; + } + + //! inverts the matrix + inline __device__ __host__ void inverse() { + *this = getInverse(); + } + + //! computes the inverse of the matrix + inline __device__ __host__ float3x4 getInverse() { + float3x3 A = getFloat3x3(); + A.invert(); + float3 t = getTranslation(); + t = A*t; + + float3x4 ret; + ret.setFloat3x3(A); + ret.setTranslation(make_float3(-t.x, -t.y, -t.z)); //float3 doesn't have unary '-'... thank you cuda + return ret; + } + + //! prints the matrix; only host + __host__ void print() { + std::cout << + m11 << " " << m12 << " " << m13 << " " << m14 << std::endl << + m21 << " " << m22 << " " << m23 << " " << m24 << std::endl << + m31 << " " << m32 << " " << m33 << " " << m34 << std::endl << + std::endl; + } + + inline __device__ __host__ const float* ptr() const { + return entries; + } + inline __device__ __host__ float* ptr() { + return entries; + } + + union { + struct { + float m11; float m12; float m13; float m14; + float m21; float m22; float m23; float m24; + float m31; float m32; float m33; float m34; + }; + float entries[9]; + float entries2[3][4]; + }; +}; + + + +class float4x4 { +public: + inline __device__ __host__ float4x4() { + + } + inline __device__ __host__ float4x4(const float values[16]) { + m11 = values[0]; m12 = values[1]; m13 = values[2]; m14 = values[3]; + m21 = values[4]; m22 = values[5]; m23 = values[6]; m24 = values[7]; + m31 = values[8]; m32 = values[9]; m33 = values[10]; m34 = values[11]; + m41 = values[12]; m42 = values[13]; m43 = values[14]; m44 = values[15]; + } + + inline __device__ __host__ float4x4(const float4x4& other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; m14 = other.m14; + m21 = other.m21; m22 = other.m22; m23 = other.m23; m24 = other.m24; + m31 = other.m31; m32 = other.m32; m33 = other.m33; m34 = other.m34; + m41 = other.m41; m42 = other.m42; m43 = other.m43; m44 = other.m44; + } + + //implicitly assumes last line to (0,0,0,1) + inline __device__ __host__ float4x4(const float3x4& other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; m14 = other.m14; + m21 = other.m21; m22 = other.m22; m23 = other.m23; m24 = other.m24; + m31 = other.m31; m32 = other.m32; m33 = other.m33; m34 = other.m34; + m41 = 0.0f; m42 = 0.0f; m43 = 0.0f; m44 = 1.0f; + } + + inline __device__ __host__ float4x4(const float3x3& other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; m14 = 0.0f; + m21 = other.m21; m22 = other.m22; m23 = other.m23; m24 = 0.0f; + m31 = other.m31; m32 = other.m32; m33 = other.m33; m34 = 0.0f; + m41 = 0.0f; m42 = 0.0f; m43 = 0.0f; m44 = 1.0f; + } + + inline __device__ __host__ float4x4 operator=(const float4x4 &other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; m14 = other.m14; + m21 = other.m21; m22 = other.m22; m23 = other.m23; m24 = other.m24; + m31 = other.m31; m32 = other.m32; m33 = other.m33; m34 = other.m34; + m41 = other.m41; m42 = other.m42; m43 = other.m43; m44 = other.m44; + return *this; + } + + inline __device__ __host__ float4x4 operator=(const float3x4 &other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; m14 = other.m14; + m21 = other.m21; m22 = other.m22; m23 = other.m23; m24 = other.m24; + m31 = other.m31; m32 = other.m32; m33 = other.m33; m34 = other.m34; + m41 = 0.0f; m42 = 0.0f; m43 = 0.0f; m44 = 1.0f; + return *this; + } + + inline __device__ __host__ float4x4& operator=(const float3x3 &other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; m14 = 0.0f; + m21 = other.m21; m22 = other.m22; m23 = other.m23; m24 = 0.0f; + m31 = other.m31; m32 = other.m32; m33 = other.m33; m34 = 0.0f; + m41 = 0.0f; m42 = 0.0f; m43 = 0.0f; m44 = 1.0f; + return *this; + } + + + //! not tested + inline __device__ __host__ float4x4 operator*(const float4x4 &other) const { + float4x4 res; + res.m11 = m11*other.m11 + m12*other.m21 + m13*other.m31 + m14*other.m41; + res.m12 = m11*other.m12 + m12*other.m22 + m13*other.m32 + m14*other.m42; + res.m13 = m11*other.m13 + m12*other.m23 + m13*other.m33 + m14*other.m43; + res.m14 = m11*other.m14 + m12*other.m24 + m13*other.m34 + m14*other.m44; + + res.m21 = m21*other.m11 + m22*other.m21 + m23*other.m31 + m24*other.m41; + res.m22 = m21*other.m12 + m22*other.m22 + m23*other.m32 + m24*other.m42; + res.m23 = m21*other.m13 + m22*other.m23 + m23*other.m33 + m24*other.m43; + res.m24 = m21*other.m14 + m22*other.m24 + m23*other.m34 + m24*other.m44; + + res.m31 = m31*other.m11 + m32*other.m21 + m33*other.m31 + m34*other.m41; + res.m32 = m31*other.m12 + m32*other.m22 + m33*other.m32 + m34*other.m42; + res.m33 = m31*other.m13 + m32*other.m23 + m33*other.m33 + m34*other.m43; + res.m34 = m31*other.m14 + m32*other.m24 + m33*other.m34 + m34*other.m44; + + res.m41 = m41*other.m11 + m42*other.m21 + m43*other.m31 + m44*other.m41; + res.m42 = m41*other.m12 + m42*other.m22 + m43*other.m32 + m44*other.m42; + res.m43 = m41*other.m13 + m42*other.m23 + m43*other.m33 + m44*other.m43; + res.m44 = m41*other.m14 + m42*other.m24 + m43*other.m34 + m44*other.m44; + + return res; + } + + // untested + inline __device__ __host__ float4 operator*(const float4& v) const + { + return make_float4( + m11*v.x + m12*v.y + m13*v.z + m14*v.w, + m21*v.x + m22*v.y + m23*v.z + m24*v.w, + m31*v.x + m32*v.y + m33*v.z + m34*v.w, + m41*v.x + m42*v.y + m43*v.z + m44*v.w + ); + } + + // untested + //implicitly assumes w to be 1 + inline __device__ __host__ float3 operator*(const float3& v) const + { + return make_float3( + m11*v.x + m12*v.y + m13*v.z + m14*1.0f, + m21*v.x + m22*v.y + m23*v.z + m24*1.0f, + m31*v.x + m32*v.y + m33*v.z + m34*1.0f + ); + } + + inline __device__ __host__ float& operator()(int i, int j) { + return entries2[i][j]; + } + + inline __device__ __host__ float operator()(int i, int j) const { + return entries2[i][j]; + } + + + static inline __device__ __host__ void swap(float& v0, float& v1) { + float tmp = v0; + v0 = v1; + v1 = tmp; + } + + inline __device__ __host__ void transpose() { + swap(m12, m21); + swap(m13, m31); + swap(m23, m32); + swap(m41, m14); + swap(m42, m24); + swap(m43, m34); + } + inline __device__ __host__ float4x4 getTranspose() const { + float4x4 ret = *this; + ret.transpose(); + return ret; + } + + + inline __device__ __host__ void invert() { + *this = getInverse(); + } + + //! return the inverse matrix; but does not change the current matrix + inline __device__ __host__ float4x4 getInverse() const { + float inv[16]; + + inv[0] = entries[5] * entries[10] * entries[15] - + entries[5] * entries[11] * entries[14] - + entries[9] * entries[6] * entries[15] + + entries[9] * entries[7] * entries[14] + + entries[13] * entries[6] * entries[11] - + entries[13] * entries[7] * entries[10]; + + inv[4] = -entries[4] * entries[10] * entries[15] + + entries[4] * entries[11] * entries[14] + + entries[8] * entries[6] * entries[15] - + entries[8] * entries[7] * entries[14] - + entries[12] * entries[6] * entries[11] + + entries[12] * entries[7] * entries[10]; + + inv[8] = entries[4] * entries[9] * entries[15] - + entries[4] * entries[11] * entries[13] - + entries[8] * entries[5] * entries[15] + + entries[8] * entries[7] * entries[13] + + entries[12] * entries[5] * entries[11] - + entries[12] * entries[7] * entries[9]; + + inv[12] = -entries[4] * entries[9] * entries[14] + + entries[4] * entries[10] * entries[13] + + entries[8] * entries[5] * entries[14] - + entries[8] * entries[6] * entries[13] - + entries[12] * entries[5] * entries[10] + + entries[12] * entries[6] * entries[9]; + + inv[1] = -entries[1] * entries[10] * entries[15] + + entries[1] * entries[11] * entries[14] + + entries[9] * entries[2] * entries[15] - + entries[9] * entries[3] * entries[14] - + entries[13] * entries[2] * entries[11] + + entries[13] * entries[3] * entries[10]; + + inv[5] = entries[0] * entries[10] * entries[15] - + entries[0] * entries[11] * entries[14] - + entries[8] * entries[2] * entries[15] + + entries[8] * entries[3] * entries[14] + + entries[12] * entries[2] * entries[11] - + entries[12] * entries[3] * entries[10]; + + inv[9] = -entries[0] * entries[9] * entries[15] + + entries[0] * entries[11] * entries[13] + + entries[8] * entries[1] * entries[15] - + entries[8] * entries[3] * entries[13] - + entries[12] * entries[1] * entries[11] + + entries[12] * entries[3] * entries[9]; + + inv[13] = entries[0] * entries[9] * entries[14] - + entries[0] * entries[10] * entries[13] - + entries[8] * entries[1] * entries[14] + + entries[8] * entries[2] * entries[13] + + entries[12] * entries[1] * entries[10] - + entries[12] * entries[2] * entries[9]; + + inv[2] = entries[1] * entries[6] * entries[15] - + entries[1] * entries[7] * entries[14] - + entries[5] * entries[2] * entries[15] + + entries[5] * entries[3] * entries[14] + + entries[13] * entries[2] * entries[7] - + entries[13] * entries[3] * entries[6]; + + inv[6] = -entries[0] * entries[6] * entries[15] + + entries[0] * entries[7] * entries[14] + + entries[4] * entries[2] * entries[15] - + entries[4] * entries[3] * entries[14] - + entries[12] * entries[2] * entries[7] + + entries[12] * entries[3] * entries[6]; + + inv[10] = entries[0] * entries[5] * entries[15] - + entries[0] * entries[7] * entries[13] - + entries[4] * entries[1] * entries[15] + + entries[4] * entries[3] * entries[13] + + entries[12] * entries[1] * entries[7] - + entries[12] * entries[3] * entries[5]; + + inv[14] = -entries[0] * entries[5] * entries[14] + + entries[0] * entries[6] * entries[13] + + entries[4] * entries[1] * entries[14] - + entries[4] * entries[2] * entries[13] - + entries[12] * entries[1] * entries[6] + + entries[12] * entries[2] * entries[5]; + + inv[3] = -entries[1] * entries[6] * entries[11] + + entries[1] * entries[7] * entries[10] + + entries[5] * entries[2] * entries[11] - + entries[5] * entries[3] * entries[10] - + entries[9] * entries[2] * entries[7] + + entries[9] * entries[3] * entries[6]; + + inv[7] = entries[0] * entries[6] * entries[11] - + entries[0] * entries[7] * entries[10] - + entries[4] * entries[2] * entries[11] + + entries[4] * entries[3] * entries[10] + + entries[8] * entries[2] * entries[7] - + entries[8] * entries[3] * entries[6]; + + inv[11] = -entries[0] * entries[5] * entries[11] + + entries[0] * entries[7] * entries[9] + + entries[4] * entries[1] * entries[11] - + entries[4] * entries[3] * entries[9] - + entries[8] * entries[1] * entries[7] + + entries[8] * entries[3] * entries[5]; + + inv[15] = entries[0] * entries[5] * entries[10] - + entries[0] * entries[6] * entries[9] - + entries[4] * entries[1] * entries[10] + + entries[4] * entries[2] * entries[9] + + entries[8] * entries[1] * entries[6] - + entries[8] * entries[2] * entries[5]; + + float matrixDet = entries[0] * inv[0] + entries[1] * inv[4] + entries[2] * inv[8] + entries[3] * inv[12]; + + float matrixDetr = 1.0f / matrixDet; + + float4x4 res; + for (unsigned int i = 0; i < 16; i++) { + res.entries[i] = inv[i] * matrixDetr; + } + return res; + + } + + + + + + //! returns the 3x3 part of the matrix + inline __device__ __host__ float3x3 getFloat3x3() { + float3x3 ret; + ret.m11 = m11; ret.m12 = m12; ret.m13 = m13; + ret.m21 = m21; ret.m22 = m22; ret.m23 = m23; + ret.m31 = m31; ret.m32 = m32; ret.m33 = m33; + return ret; + } + + //! sets the 3x3 part of the matrix (other values remain unchanged) + inline __device__ __host__ void setFloat3x3(const float3x3 &other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; + m21 = other.m21; m22 = other.m22; m23 = other.m23; + m31 = other.m31; m32 = other.m32; m33 = other.m33; + } + + //! sets the 4x4 part of the matrix to identity + inline __device__ __host__ void setIdentity() + { + m11 = 1.0f; m12 = 0.0f; m13 = 0.0f; m14 = 0.0f; + m21 = 0.0f; m22 = 1.0f; m23 = 0.0f; m24 = 0.0f; + m31 = 0.0f; m32 = 0.0f; m33 = 1.0f; m34 = 0.0f; + m41 = 0.0f; m42 = 0.0f; m43 = 0.0f; m44 = 1.0f; + } + + //! sets the 4x4 part of the matrix to identity + inline __device__ __host__ void setValue(float v) + { + m11 = v; m12 = v; m13 = v; m14 = v; + m21 = v; m22 = v; m23 = v; m24 = v; + m31 = v; m32 = v; m33 = v; m34 = v; + m41 = v; m42 = v; m43 = v; m44 = v; + } + + //! returns the 3x4 part of the matrix + inline __device__ __host__ float3x4 getFloat3x4() { + float3x4 ret; + ret.m11 = m11; ret.m12 = m12; ret.m13 = m13; ret.m14 = m14; + ret.m21 = m21; ret.m22 = m22; ret.m23 = m23; ret.m24 = m24; + ret.m31 = m31; ret.m32 = m32; ret.m33 = m33; ret.m34 = m34; + return ret; + } + + //! sets the 3x4 part of the matrix (other values remain unchanged) + inline __device__ __host__ void setFloat3x4(const float3x4 &other) { + m11 = other.m11; m12 = other.m12; m13 = other.m13; m14 = other.m14; + m21 = other.m21; m22 = other.m22; m23 = other.m23; m24 = other.m24; + m31 = other.m31; m32 = other.m32; m33 = other.m33; m34 = other.m34; + } + + + + + inline __device__ __host__ const float* ptr() const { + return entries; + } + inline __device__ __host__ float* ptr() { + return entries; + } + + union { + struct { + float m11; float m12; float m13; float m14; + float m21; float m22; float m23; float m24; + float m31; float m32; float m33; float m34; + float m41; float m42; float m43; float m44; + }; + float entries[16]; + float entries2[4][4]; + }; +}; + + + +////////////////////////////// +// matNxM +////////////////////////////// + +template +class matNxM +{ + public: + + ////////////////////////////// + // Initialization + ////////////////////////////// + inline __device__ __host__ matNxM() + { + } + + inline __device__ __host__ matNxM(float* values) + { + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i& operator=(const matNxM& other) + { + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i getIdentity() + { + matNxM R; R.setIdentity(); + return R; + } + + ////////////////////////////// + // Conversion + ////////////////////////////// + + // declare generic constructors for compile time checking of matrix size + template + explicit inline __device__ __host__ matNxM(const B& other); + + template + explicit inline __device__ __host__ matNxM(const B& other0, const B& other1); + + // declare generic casts for compile time checking of matrix size + inline __device__ __host__ operator float(); + inline __device__ __host__ operator float2(); + inline __device__ __host__ operator float3(); + inline __device__ __host__ operator float4(); + + inline __device__ __host__ operator float2x2(); + inline __device__ __host__ operator float3x3(); + inline __device__ __host__ operator float4x4(); + + ////////////////////////////// + // Matrix - Matrix Multiplication + ////////////////////////////// + template + inline __device__ __host__ matNxM operator*(const matNxM& other) const + { + cudaAssert(M == NOther); + matNxM res; + + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i getInverse() const; + + ////////////////////////////// + // Matrix - Transpose + ////////////////////////////// + inline __device__ __host__ matNxM getTranspose() const + { + matNxM res; + + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i operator+(const matNxM& other) const + { + matNxM res = (*this); + res+=other; + return res; + } + + inline __device__ __host__ matNxM& operator+=(const matNxM& other) + { + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i operator-() const + { + matNxM res = (*this)*(-1.0f); + return res; + } + + ////////////////////////////// + // Matrix - Matrix Subtraction + ////////////////////////////// + inline __device__ __host__ matNxM operator-(const matNxM& other) const + { + matNxM res = (*this); + res-=other; + return res; + } + + inline __device__ __host__ matNxM& operator-=(const matNxM& other) + { + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i operator*(const float t) const + { + matNxM res = (*this); + res*=t; + return res; + } + + inline __device__ __host__ matNxM& operator*=(const float t) + { + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i operator/(const float t) const + { + matNxM res = (*this); + res/=t; + return res; + } + + inline __device__ __host__ matNxM& operator/=(const float t) + { + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i + inline __device__ __host__ void getBlock(unsigned int xStart, unsigned int yStart, matNxM& res) const + { + cudaAssert(xStart+NOther <= N && yStart+MOther <= M); + + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i + inline __device__ __host__ void setBlock(matNxM& input, unsigned int xStart, unsigned int yStart) + { + cudaAssert(xStart+NOther <= N && yStart+MOther <= M); + + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i +inline __device__ __host__ matNxM operator*(const float t, const matNxM& mat) +{ + matNxM res = mat; + res*=t; + return res; +} + +////////////////////////////// +// Matrix Inversion +////////////////////////////// + +template<> +inline __device__ __host__ float matNxM<3, 3>::det() const +{ + const float& m11 = entries2D[0][0]; + const float& m12 = entries2D[0][1]; + const float& m13 = entries2D[0][2]; + + const float& m21 = entries2D[1][0]; + const float& m22 = entries2D[1][1]; + const float& m23 = entries2D[1][2]; + + const float& m31 = entries2D[2][0]; + const float& m32 = entries2D[2][1]; + const float& m33 = entries2D[2][2]; + + return m11*m22*m33 + m12*m23*m31 + m13*m21*m32 - m31*m22*m13 - m32*m23*m11 - m33*m21*m12; +} + +template<> +inline __device__ __host__ matNxM<3, 3> matNxM<3, 3>::getInverse() const +{ + matNxM<3, 3> res; + res.entries[0] = entries[4]*entries[8] - entries[5]*entries[7]; + res.entries[1] = -entries[1]*entries[8] + entries[2]*entries[7]; + res.entries[2] = entries[1]*entries[5] - entries[2]*entries[4]; + + res.entries[3] = -entries[3]*entries[8] + entries[5]*entries[6]; + res.entries[4] = entries[0]*entries[8] - entries[2]*entries[6]; + res.entries[5] = -entries[0]*entries[5] + entries[2]*entries[3]; + + res.entries[6] = entries[3]*entries[7] - entries[4]*entries[6]; + res.entries[7] = -entries[0]*entries[7] + entries[1]*entries[6]; + res.entries[8] = entries[0]*entries[4] - entries[1]*entries[3]; + return res*(1.0f/det()); +} + +template<> +inline __device__ __host__ float matNxM<2, 2>::det() const +{ + return (*this)(0, 0)*(*this)(1, 1)-(*this)(1, 0)*(*this)(0, 1); +} + +template<> +inline __device__ __host__ matNxM<2, 2> matNxM<2, 2>::getInverse() const +{ + matNxM<2, 2> res; + res(0, 0) = (*this)(1, 1); res(0, 1) = -(*this)(0, 1); + res(1, 0) = -(*this)(1, 0); res(1, 1) = (*this)(0, 0); + + return res*(1.0f/det()); +} + +////////////////////////////// +// Conversion +////////////////////////////// + +// To Matrix from floatNxN +template<> +template<> +inline __device__ __host__ matNxM<1, 1>::matNxM(const float& other) +{ + entries[0] = other; +} + +// To Matrix from floatNxN +template<> +template<> +inline __device__ __host__ matNxM<2, 2>::matNxM(const float2x2& other) +{ + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i<4; i++) entries[i] = other.entries[i]; +} + +template<> +template<> +inline __device__ __host__ matNxM<3, 3>::matNxM(const float3x3& other) +{ + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i<9; i++) entries[i] = other.entries[i]; +} + +template<> +template<> +inline __device__ __host__ matNxM<4, 4>::matNxM(const float4x4& other) +{ + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i<16; i++) entries[i] = other.entries[i]; +} + +template<> +template<> +inline __device__ __host__ matNxM<3, 2>::matNxM(const float3& col0, const float3& col1) +{ + entries2D[0][0] = col0.x; entries2D[0][1] = col1.x; + entries2D[1][0] = col0.y; entries2D[1][1] = col1.y; + entries2D[2][0] = col0.z; entries2D[2][1] = col1.z; +} + +// To floatNxM from Matrix +template<> +inline __device__ __host__ matNxM<4, 4>::operator float4x4() +{ + float4x4 res; + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i<16; i++) res.entries[i] = entries[i]; + return res; +} + +template<> +inline __device__ __host__ matNxM<3, 3>::operator float3x3() +{ + float3x3 res; + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i<9; i++) res.entries[i] = entries[i]; + return res; +} + +template<> +inline __device__ __host__ matNxM<2, 2>::operator float2x2() +{ + float2x2 res; + __CONDITIONAL_UNROLL__ + for(unsigned int i = 0; i<4; i++) res.entries[i] = entries[i]; + return res; +} + +// To Matrix from floatN +template<> +template<> +inline __device__ __host__ matNxM<2, 1>::matNxM(const float2& other) +{ + entries[0] = other.x; + entries[1] = other.y; +} + +template<> +template<> +inline __device__ __host__ matNxM<3, 1>::matNxM(const float3& other) +{ + entries[0] = other.x; + entries[1] = other.y; + entries[2] = other.z; +} + +template<> +template<> +inline __device__ __host__ matNxM<4, 1>::matNxM(const float4& other) +{ + entries[0] = other.x; + entries[1] = other.y; + entries[2] = other.z; + entries[3] = other.w; +} + +// To floatN from Matrix +template<> +inline __device__ __host__ matNxM<1, 1>::operator float() +{ + return entries[0]; +} + +template<> +inline __device__ __host__ matNxM<2, 1>::operator float2() +{ + return make_float2(entries[0], entries[1]); +} + +template<> +inline __device__ __host__ matNxM<3, 1>::operator float3() +{ + return make_float3(entries[0], entries[1], entries[2]); +} + +inline __device__ __host__ matNxM<4, 1>::operator float4() +{ + return make_float4(entries[0], entries[1], entries[2], entries[3]); +} + +////////////////////////////// +// Typedefs +////////////////////////////// + +typedef matNxM<9, 3> mat9x3; +typedef matNxM<3, 9> mat3x9; + +typedef matNxM<9, 1> mat9x1; +typedef matNxM<1, 9> mat1x9; + +typedef matNxM<6, 6> mat6x6; + +typedef matNxM<6, 1> mat6x1; +typedef matNxM<1, 6> mat1x6; + +typedef matNxM<3, 6> mat3x6; +typedef matNxM<6, 3> mat6x3; + +typedef matNxM<4, 4> mat4x4; + +typedef matNxM<4, 1> mat4x1; +typedef matNxM<1, 4> mat1x4; + +typedef matNxM<3, 3> mat3x3; + +typedef matNxM<2, 3> mat2x3; +typedef matNxM<3, 2> mat3x2; + +typedef matNxM<2, 2> mat2x2; + +typedef matNxM<1, 2> mat1x2; +typedef matNxM<2, 1> mat2x1; + +typedef matNxM<1, 3> mat1x3; +typedef matNxM<3, 1> mat3x1; + +typedef matNxM<1, 1> mat1x1; + + +#endif diff --git a/AnnotationTools/Filter2dAnnotations/filter.cu b/AnnotationTools/Filter2dAnnotations/filter.cu new file mode 100644 index 0000000..cff8af4 --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/filter.cu @@ -0,0 +1,1109 @@ +#ifndef _FILTER_ +#define _FILTER_ + +#include +#include +#include "GlobalDefines.h" +#include "cuda_SimpleMatrixUtil.h" + + +#define T_PER_BLOCK 16 +#define MINF __int_as_float(0xff800000) + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Convert Float4 Color to UCHAR4 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void convertColorFloat4ToUCHAR4Device(uchar4* d_output, float4* d_input, unsigned int width, unsigned int height) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x >= width || y >= height) return; + + float4 color = d_input[y*width + x]; + d_output[y*width + x] = make_uchar4(color.x*255.0f, color.y*255.0f, color.z*255.0f, color.w*255.0f); +} + +extern "C" void convertColorFloat4ToUCHAR4(uchar4* d_output, float4* d_input, unsigned int width, unsigned int height) +{ + const dim3 blockSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 gridSize(T_PER_BLOCK, T_PER_BLOCK); + + convertColorFloat4ToUCHAR4Device << > >(d_output, d_input, width, height); + +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Convert Color to Intensity +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void convertColorToIntensityFloatDevice(float* d_output, float4* d_input, unsigned int width, unsigned int height) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x >= width || y >= height) return; + + const float4 color = d_input[y*width + x]; + d_output[y*width + x] = 0.299f*color.x + 0.587f*color.y + 0.114f*color.z; +} + +extern "C" void convertColorToIntensityFloat(float* d_output, float4* d_input, unsigned int width, unsigned int height) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + convertColorToIntensityFloatDevice << > >(d_output, d_input, width, height); + +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Convert Depth to Camera Space Positions +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void convertDepthFloatToCameraSpaceFloat4Device(float4* d_output, float* d_input, float4x4 intrinsicsInv, + unsigned int width, unsigned int height) +{ + const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x; + const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x < width && y < height) { + d_output[y*width+x] = make_float4(MINF, MINF, MINF, MINF); + + float depth = d_input[y*width+x]; + + if(depth != MINF) + { + float4 cameraSpace(intrinsicsInv*make_float4((float)x*depth, (float)y*depth, depth, depth)); + d_output[y*width+x] = make_float4(cameraSpace.x, cameraSpace.y, cameraSpace.w, 1.0f); + } + } +} + +extern "C" void convertDepthFloatToCameraSpaceFloat4(float4* d_output, float* d_input, float4x4 intrinsicsInv, unsigned int width, unsigned int height) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + convertDepthFloatToCameraSpaceFloat4Device<<>>(d_output, d_input, intrinsicsInv, width, height); + +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Compute Normal Map +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void computeNormalsDevice(float4* d_output, float4* d_input, unsigned int width, unsigned int height) +{ + const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x; + const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y; + + if(x >= width || y >= height) return; + + d_output[y*width+x] = make_float4(MINF, MINF, MINF, MINF); + + if(x > 0 && x < width-1 && y > 0 && y < height-1) + { + const float4 CC = d_input[(y+0)*width+(x+0)]; + const float4 PC = d_input[(y+1)*width+(x+0)]; + const float4 CP = d_input[(y+0)*width+(x+1)]; + const float4 MC = d_input[(y-1)*width+(x+0)]; + const float4 CM = d_input[(y+0)*width+(x-1)]; + + if(CC.x != MINF && PC.x != MINF && CP.x != MINF && MC.x != MINF && CM.x != MINF) + { + const float3 n = cross(make_float3(PC)-make_float3(MC), make_float3(CP)-make_float3(CM)); + const float l = length(n); + + if(l > 0.0f) + { + d_output[y*width+x] = make_float4(n/-l, 1.0f); + } + } + } +} + +extern "C" void computeNormals(float4* d_output, float4* d_input, unsigned int width, unsigned int height) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + computeNormalsDevice<<>>(d_output, d_input, width, height); + +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +///////////////////////////////////////////// +// Transform +///////////////////////////////////////////// + +__global__ void transformNormalMapDevice(float4* d_normals, unsigned int imageWidth, unsigned int imageHeight, float4x4 transform) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + const int index = y*imageWidth+x; + + if(x >= 0 && x < imageWidth && y >= 0 && y < imageHeight) + { + if(d_normals[index].x != MINF) + { + float3 n = transform.getFloat3x3() * make_float3(d_normals[index].x,d_normals[index].y,d_normals[index].z); + d_normals[index] = make_float4(n, 0.0f); + } + } +} + +extern "C" void transformNormalMap(float4* d_normals, unsigned int imageWidth, unsigned int imageHeight, float4x4 transform) +{ + const dim3 gridSize((imageWidth + T_PER_BLOCK - 1)/T_PER_BLOCK, (imageHeight + T_PER_BLOCK - 1)/T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + transformNormalMapDevice<<>>(d_normals, imageWidth, imageHeight, transform); + #ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); + #endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Bilateral Filter Float Map +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +inline __device__ float gaussR(float sigma, float dist) +{ + return exp(-(dist*dist) / (2.0*sigma*sigma)); +} + +inline __device__ float linearR(float sigma, float dist) +{ + return max(1.0f, min(0.0f, 1.0f - (dist*dist) / (2.0*sigma*sigma))); +} + +inline __device__ float gaussD(float sigma, int x, int y) +{ + return exp(-((x*x + y*y) / (2.0f*sigma*sigma))); +} + +inline __device__ float gaussD(float sigma, int x) +{ + return exp(-((x*x) / (2.0f*sigma*sigma))); +} + +__global__ void bilateralFilterFloatMapDevice(float* d_output, float* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x >= width || y >= height) return; + + const int kernelRadius = (int)ceil(2.0*sigmaD); + + d_output[y*width + x] = MINF; + + float sum = 0.0f; + float sumWeight = 0.0f; + + const float depthCenter = d_input[y*width + x]; + if (depthCenter != MINF) + { + for (int m = x - kernelRadius; m <= x + kernelRadius; m++) + { + for (int n = y - kernelRadius; n <= y + kernelRadius; n++) + { + if (m >= 0 && n >= 0 && m < width && n < height) + { + const float currentDepth = d_input[n*width + m]; + + if (currentDepth != MINF) { + const float weight = gaussD(sigmaD, m - x, n - y)*gaussR(sigmaR, currentDepth - depthCenter); + + sumWeight += weight; + sum += weight*currentDepth; + } + } + } + } + + if (sumWeight > 0.0f) d_output[y*width + x] = sum / sumWeight; + } +} + +extern "C" void bilateralFilterFloatMap(float* d_output, float* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + bilateralFilterFloatMapDevice << > >(d_output, d_input, sigmaD, sigmaR, width, height); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Bilateral Filter Float4 Map +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void bilateralFilterFloat4MapDevice(float4* d_output, float4* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x >= width || y >= height) return; + + const int kernelRadius = (int)ceil(2.0*sigmaD); + + //d_output[y*width+x] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + d_output[y*width + x] = make_float4(MINF, MINF, MINF, MINF); + + float4 sum = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + float sumWeight = 0.0f; + + const float4 depthCenter = d_input[y*width + x]; + if (depthCenter.x != MINF) { + for (int m = x - kernelRadius; m <= x + kernelRadius; m++) + { + for (int n = y - kernelRadius; n <= y + kernelRadius; n++) + { + if (m >= 0 && n >= 0 && m < width && n < height) + { + const float4 currentDepth = d_input[n*width + m]; + + if (currentDepth.x != MINF) { + const float weight = gaussD(sigmaD, m - x, n - y)*gaussR(sigmaR, length(currentDepth - depthCenter)); + + sum += weight*currentDepth; + sumWeight += weight; + } + } + } + } + } + if (sumWeight > 0.0f) d_output[y*width + x] = sum / sumWeight; +} + +extern "C" void bilateralFilterFloat4Map(float4* d_output, float4* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + bilateralFilterFloat4MapDevice << > >(d_output, d_input, sigmaD, sigmaR, width, height); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Gauss Filter Float Map +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void gaussFilterFloatMapDevice(float* d_output, float* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x >= width || y >= height) return; + + const int kernelRadius = (int)ceil(2.0*sigmaD); + + d_output[y*width + x] = MINF; + + float sum = 0.0f; + float sumWeight = 0.0f; + + const float depthCenter = d_input[y*width + x]; + if (depthCenter != MINF) + { + for (int m = x - kernelRadius; m <= x + kernelRadius; m++) + { + for (int n = y - kernelRadius; n <= y + kernelRadius; n++) + { + if (m >= 0 && n >= 0 && m < width && n < height) + { + const float currentDepth = d_input[n*width + m]; + + if (currentDepth != MINF && fabs(depthCenter - currentDepth) < sigmaR) + { + const float weight = gaussD(sigmaD, m - x, n - y); + + sumWeight += weight; + sum += weight*currentDepth; + } + } + } + } + } + + if (sumWeight > 0.0f) d_output[y*width + x] = sum / sumWeight; +} + +extern "C" void gaussFilterFloatMap(float* d_output, float* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + gaussFilterFloatMapDevice << > >(d_output, d_input, sigmaD, sigmaR, width, height); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Gauss Filter Float4 Map +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void gaussFilterFloat4MapDevice(float4* d_output, float4* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x >= width || y >= height) return; + + const int kernelRadius = (int)ceil(2.0*sigmaD); + + //d_output[y*width+x] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + d_output[y*width + x] = make_float4(MINF, MINF, MINF, MINF); + + float4 sum = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + float sumWeight = 0.0f; + + const float4 center = d_input[y*width + x]; + if (center.x != MINF) { + for (int m = x - kernelRadius; m <= x + kernelRadius; m++) + { + for (int n = y - kernelRadius; n <= y + kernelRadius; n++) + { + if (m >= 0 && n >= 0 && m < width && n < height) + { + const float4 current = d_input[n*width + m]; + + if (current.x != MINF) { + if (length(center - current) < sigmaR) + { + const float weight = gaussD(sigmaD, m - x, n - y); + + sumWeight += weight; + sum += weight*current; + } + } + } + } + } + } + + if (sumWeight > 0.0f) d_output[y*width + x] = sum / sumWeight; +} + +extern "C" void gaussFilterFloat4Map(float4* d_output, float4* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + gaussFilterFloat4MapDevice << > >(d_output, d_input, sigmaD, sigmaR, width, height); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Compute Edge Mask +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void computeMaskEdgeMapFloat4Device(unsigned char* d_output, float4* d_input, float* d_indepth, float threshold, unsigned int width, unsigned int height) +{ + const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x; + const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x >= width || y >= height) return; + + d_output[y*width + x] = 1; + d_output[width*height + y*width + x] = 1; + + const float thre = threshold *threshold *3.0f; + if (x > 0 && y > 0 && x < width - 1 && y < height - 1) + { + if (d_indepth[y*width + x] == MINF) + { + d_output[y*width + x] = 0; + d_output[y*width + x - 1] = 0; + d_output[width*height + y*width + x] = 0; + d_output[width*height + (y - 1)*width + x] = 0; + + return; + } + + const float4& p0 = d_input[(y + 0)*width + (x + 0)]; + const float4& p1 = d_input[(y + 0)*width + (x + 1)]; + const float4& p2 = d_input[(y + 1)*width + (x + 0)]; + + float dU = sqrt(((p1.x - p0.x)*(p1.x - p0.x) + (p1.y - p0.y) * (p1.y - p0.y) + (p1.z - p0.z)*(p1.z - p0.z)) / 3.0f); + float dV = sqrt(((p2.x - p0.x)*(p2.x - p0.x) + (p2.y - p0.y) * (p2.y - p0.y) + (p2.z - p0.z)*(p2.z - p0.z)) / 3.0f); + + //float dgradx = abs(d_indepth[y*width+x-1] + d_indepth[y*width+x+1] - 2.0f * d_indepth[y*width+x]); + //float dgrady = abs(d_indepth[y*width+x-width] + d_indepth[y*width+x+width] - 2.0f * d_indepth[y*width+x]); + + + if (dU > thre) d_output[y*width + x] = 0; + if (dV > thre) d_output[width*height + y*width + x] = 0; + + //remove depth discontinuities + const int r = 1; + const float thres = 0.01f; + + const float pCC = d_indepth[y*width + x]; + for (int i = -r; i <= r; i++) + { + for (int j = -r; j <= r; j++) + { + int currentX = x + j; + int currentY = y + i; + + if (currentX >= 0 && currentX < width && currentY >= 0 && currentY < height) + { + float d = d_indepth[currentY*width + currentX]; + + if (d != MINF && abs(pCC - d) > thres) + { + d_output[y*width + x] = 0; + d_output[width*height + y*width + x] = 0; + return; + } + } + } + } + } +} + +extern "C" void computeMaskEdgeMapFloat4(unsigned char* d_output, float4* d_input, float* d_indepth, float threshold, unsigned int width, unsigned int height) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + computeMaskEdgeMapFloat4Device << > >(d_output, d_input, d_indepth, threshold, width, height); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Resample Float Map +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +inline __device__ float bilinearInterpolationFloat(float x, float y, float* d_input, unsigned int imageWidth, unsigned int imageHeight) +{ + const int2 p00 = make_int2(floor(x), floor(y)); + const int2 p01 = p00 + make_int2(0.0f, 1.0f); + const int2 p10 = p00 + make_int2(1.0f, 0.0f); + const int2 p11 = p00 + make_int2(1.0f, 1.0f); + + const float alpha = x - p00.x; + const float beta = y - p00.y; + + float s0 = 0.0f; float w0 = 0.0f; + if (p00.x < imageWidth && p00.y < imageHeight) { float v00 = d_input[p00.y*imageWidth + p00.x]; if (v00 != MINF) { s0 += (1.0f - alpha)*v00; w0 += (1.0f - alpha); } } + if (p10.x < imageWidth && p10.y < imageHeight) { float v10 = d_input[p10.y*imageWidth + p10.x]; if (v10 != MINF) { s0 += alpha *v10; w0 += alpha; } } + + float s1 = 0.0f; float w1 = 0.0f; + if (p01.x < imageWidth && p01.y < imageHeight) { float v01 = d_input[p01.y*imageWidth + p01.x]; if (v01 != MINF) { s1 += (1.0f - alpha)*v01; w1 += (1.0f - alpha); } } + if (p11.x < imageWidth && p11.y < imageHeight) { float v11 = d_input[p11.y*imageWidth + p11.x]; if (v11 != MINF) { s1 += alpha *v11; w1 += alpha; } } + + const float p0 = s0 / w0; + const float p1 = s1 / w1; + + float ss = 0.0f; float ww = 0.0f; + if (w0 > 0.0f) { ss += (1.0f - beta)*p0; ww += (1.0f - beta); } + if (w1 > 0.0f) { ss += beta *p1; ww += beta; } + + if (ww > 0.0f) return ss / ww; + else return MINF; +} + +__global__ void resampleFloatMapDevice(float* d_colorMapResampledFloat, float* d_colorMapFloat, unsigned int inputWidth, unsigned int inputHeight, unsigned int outputWidth, unsigned int outputHeight) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x < outputWidth && y < outputHeight) + { + const float scaleWidth = (float)(inputWidth - 1) / (float)(outputWidth - 1); + const float scaleHeight = (float)(inputHeight - 1) / (float)(outputHeight - 1); + + const unsigned int xInput = (unsigned int)(x*scaleWidth + 0.5f); + const unsigned int yInput = (unsigned int)(y*scaleHeight + 0.5f); + + if (xInput < inputWidth && yInput < inputHeight) + { + d_colorMapResampledFloat[y*outputWidth + x] = bilinearInterpolationFloat((float)x*scaleWidth, (float)y*scaleHeight, d_colorMapFloat, inputWidth, inputHeight); + } + } +} + +extern "C" void resampleFloatMap(float* d_colorMapResampledFloat, unsigned int outputWidth, unsigned int outputHeight, float* d_colorMapFloat, unsigned int inputWidth, unsigned int inputHeight) +{ + const dim3 gridSize((outputWidth + T_PER_BLOCK - 1) / T_PER_BLOCK, (outputHeight + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + resampleFloatMapDevice << > >(d_colorMapResampledFloat, d_colorMapFloat, inputWidth, inputHeight, outputWidth, outputHeight); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Resample Float4 Map +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +inline __device__ float4 bilinearInterpolationFloat4(float x, float y, float4* d_input, unsigned int imageWidth, unsigned int imageHeight) +{ + const int2 p00 = make_int2(floor(x), floor(y)); + const int2 p01 = p00 + make_int2(0.0f, 1.0f); + const int2 p10 = p00 + make_int2(1.0f, 0.0f); + const int2 p11 = p00 + make_int2(1.0f, 1.0f); + + const float alpha = x - p00.x; + const float beta = y - p00.y; + + //const float INVALID = 0.0f; + const float INVALID = MINF; + + float4 s0 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float w0 = 0.0f; + if (p00.x < imageWidth && p00.y < imageHeight) { float4 v00 = d_input[p00.y*imageWidth + p00.x]; if (v00.x != INVALID && v00.y != INVALID && v00.z != INVALID) { s0 += (1.0f - alpha)*v00; w0 += (1.0f - alpha); } } + if (p10.x < imageWidth && p10.y < imageHeight) { float4 v10 = d_input[p10.y*imageWidth + p10.x]; if (v10.x != INVALID && v10.y != INVALID && v10.z != INVALID) { s0 += alpha *v10; w0 += alpha; } } + + float4 s1 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float w1 = 0.0f; + if (p01.x < imageWidth && p01.y < imageHeight) { float4 v01 = d_input[p01.y*imageWidth + p01.x]; if (v01.x != INVALID && v01.y != INVALID && v01.z != INVALID) { s1 += (1.0f - alpha)*v01; w1 += (1.0f - alpha); } } + if (p11.x < imageWidth && p11.y < imageHeight) { float4 v11 = d_input[p11.y*imageWidth + p11.x]; if (v11.x != INVALID && v11.y != INVALID && v11.z != INVALID) { s1 += alpha *v11; w1 += alpha; } } + + const float4 p0 = s0 / w0; + const float4 p1 = s1 / w1; + + float4 ss = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float ww = 0.0f; + if (w0 > 0.0f) { ss += (1.0f - beta)*p0; ww += (1.0f - beta); } + if (w1 > 0.0f) { ss += beta *p1; ww += beta; } + + if (ww > 0.0f) return ss / ww; + else return make_float4(MINF, MINF, MINF, MINF); +} + +__global__ void resampleFloat4MapDevice(float4* d_colorMapResampledFloat4, float4* d_colorMapFloat4, unsigned int inputWidth, unsigned int inputHeight, unsigned int outputWidth, unsigned int outputHeight) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x < outputWidth && y < outputHeight) + { + const float scaleWidth = (float)(inputWidth - 1) / (float)(outputWidth - 1); + const float scaleHeight = (float)(inputHeight - 1) / (float)(outputHeight - 1); + + const unsigned int xInput = (unsigned int)(x*scaleWidth + 0.5f); + const unsigned int yInput = (unsigned int)(y*scaleHeight + 0.5f); + + if (xInput < inputWidth && yInput < inputHeight) + { + d_colorMapResampledFloat4[y*outputWidth + x] = bilinearInterpolationFloat4(x*scaleWidth, y*scaleHeight, d_colorMapFloat4, inputWidth, inputHeight); + } + } +} + +extern "C" void resampleFloat4Map(float4* d_colorMapResampledFloat4, unsigned int outputWidth, unsigned int outputHeight, float4* d_colorMapFloat4, unsigned int inputWidth, unsigned int inputHeight) +{ + const dim3 gridSize((outputWidth + T_PER_BLOCK - 1) / T_PER_BLOCK, (outputHeight + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + resampleFloat4MapDevice << > >(d_colorMapResampledFloat4, d_colorMapFloat4, inputWidth, inputHeight, outputWidth, outputHeight); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Resample Unsigned Char Map +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void resampleUCharMapDevice(unsigned char* d_MapResampled, unsigned int outputWidth, unsigned int outputHeight, + unsigned char* d_Map, unsigned int inputWidth, unsigned int inputHeight) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x < outputWidth && y < outputHeight) + { + const float scaleWidth = (float)(inputWidth - 1) / (float)(outputWidth - 1); + const float scaleHeight = (float)(inputHeight - 1) / (float)(outputHeight - 1); + + const unsigned int xInput = (unsigned int)(x*scaleWidth + 0.5f); + const unsigned int yInput = (unsigned int)(y*scaleHeight + 0.5f); + + if (xInput < inputWidth && yInput < inputHeight) + { + d_MapResampled[y*outputWidth + x] = d_Map[yInput*inputWidth + xInput]; + } + } +} + +extern "C" void resampleUCharMap(unsigned char* d_MapResampled, unsigned int outputWidth, unsigned int outputHeight, + unsigned char* d_Map, unsigned int inputWidth, unsigned int inputHeight) +{ + const dim3 gridSize((outputWidth + T_PER_BLOCK - 1) / T_PER_BLOCK, (outputHeight + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + resampleUCharMapDevice << > >(d_MapResampled, outputWidth, outputHeight, d_Map, inputWidth, inputHeight); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Convert Edge Mask to Float Map +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void convertEdgeMaskToFloatDevice(float* d_output, unsigned char* d_input, unsigned int width, unsigned int height) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x >= width || y >= height) return; + + d_output[y*width + x] = min(d_input[y*width + x], d_input[width*height + y*width + x]); +} + +extern "C" void convertEdgeMaskToFloat(float* d_output, unsigned char* d_input, unsigned int width, unsigned int height) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + convertEdgeMaskToFloatDevice << > >(d_output, d_input, width, height); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Dilate Depth Map +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void dilateDepthMapDevice(float* d_output, float* d_input, float* d_inputOrig, int structureSize, int width, int height) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x >= 0 && x < width && y >= 0 && y < height) + { + float sum = 0.0f; + float count = 0.0f; + float oldDepth = d_inputOrig[y*width + x]; + if (oldDepth != MINF && oldDepth != 0) + { + for (int i = -structureSize; i <= structureSize; i++) + { + for (int j = -structureSize; j <= structureSize; j++) + { + if (x + j >= 0 && x + j < width && y + i >= 0 && y + i < height) + { + const float d = d_input[(y + i)*width + (x + j)]; + + if (d != MINF && d != 0.0f && fabs(d - oldDepth) < 0.05f) + { + sum += d; + count += 1.0f; + } + } + } + } + } + + if (count > ((2 * structureSize + 1)*(2 * structureSize + 1)) / 36) d_output[y*width + x] = 1.0f; + else d_output[y*width + x] = MINF; + } +} + +extern "C" void dilateDepthMapMask(float* d_output, float* d_input, float* d_inputOrig, int structureSize, int width, int height) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + dilateDepthMapDevice << > >(d_output, d_input, d_inputOrig, structureSize, width, height); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Mean Filter Depth Map +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void removeDevMeanMapMaskDevice(float* d_output, float* d_input, int structureSize, int width, int height) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + d_output[y*width + x] = d_input[y*width + x]; + + if (x >= 0 && x < width && y >= 0 && y < height) + { + float oldDepth = d_input[y*width + x]; + + float mean = 0.0f; + float meanSquared = 0.0f; + float count = 0.0f; + for (int i = -structureSize; i <= structureSize; i++) + { + for (int j = -structureSize; j <= structureSize; j++) + { + if (x + j >= 0 && x + j < width && y + i >= 0 && y + i < height) + { + float depth = d_input[(y + i)*width + (x + j)]; + if (depth == MINF) + { + depth = 8.0f; + } + + if (depth > 0.0f) + { + mean += depth; + meanSquared += depth*depth; + count += 1.0f; + } + } + } + } + + mean /= count; + meanSquared /= count; + + float stdDev = sqrt(meanSquared - mean*mean); + + if (fabs(oldDepth - mean) > 0.5f*stdDev)// || stdDev> 0.005f) + { + d_output[y*width + x] = MINF; + } + } +} + +extern "C" void removeDevMeanMapMask(float* d_output, float* d_input, int structureSize, unsigned int width, unsigned int height) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + removeDevMeanMapMaskDevice << > >(d_output, d_input, structureSize, width, height); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + + + + +// Nearest neighbour +inline __device__ bool getValueNearestNeighbourNoCheck(const float2& p, const float4* inputMap, unsigned int imageWidth, unsigned int imageHeight, float4* outValue) +{ + const int u = (int)(p.x + 0.5f); + const int v = (int)(p.y + 0.5f); + + if (u < 0 || u > imageWidth || v < 0 || v > imageHeight) return false; + + *outValue = inputMap[v*imageWidth + u]; + + return true; +} + +inline __device__ bool getValueNearestNeighbour(const float2& p, const float4* inputMap, unsigned int imageWidth, unsigned int imageHeight, float4* outValue) +{ + bool valid = getValueNearestNeighbourNoCheck(p, inputMap, imageWidth, imageHeight, outValue); + return valid && (outValue->x != MINF && outValue->y != MINF && outValue->z != MINF); +} + +// Nearest neighbour +inline __device__ bool getValueNearestNeighbourFloatNoCheck(const float2& p, const float* inputMap, unsigned int imageWidth, unsigned int imageHeight, float* outValue) +{ + const int u = (int)(p.x + 0.5f); + const int v = (int)(p.y + 0.5f); + + if (u < 0 || u > imageWidth || v < 0 || v > imageHeight) return false; + + *outValue = inputMap[v*imageWidth + u]; + + return true; +} + +inline __device__ bool getValueNearestNeighbourFloat(const float2& p, const float* inputMap, unsigned int imageWidth, unsigned int imageHeight, float* outValue) +{ + bool valid = getValueNearestNeighbourFloatNoCheck(p, inputMap, imageWidth, imageHeight, outValue); + return valid && (*outValue != MINF); +} + +///////////////////////////////////////////// +// Compute Intensity and Derivatives +///////////////////////////////////////////// + +__global__ void computeIntensityAndDerivativesDevice(float* d_intensity, unsigned int imageWidth, unsigned int imageHeight, float4* d_intensityAndDerivatives) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + const int index = y*imageWidth + x; + + if (x >= 0 && x < imageWidth && y >= 0 && y < imageHeight) + { + d_intensityAndDerivatives[index] = make_float4(MINF, MINF, MINF, MINF); + + if (x > 0 && x < imageWidth - 1 && y > 0 && y < imageHeight - 1) + { + float pos00; bool valid00 = getValueNearestNeighbourFloat(make_float2(x - 1, y - 1), d_intensity, imageWidth, imageHeight, &pos00); if (!valid00) return; + float pos01; bool valid01 = getValueNearestNeighbourFloat(make_float2(x - 1, y - 0), d_intensity, imageWidth, imageHeight, &pos01); if (!valid01) return; + float pos02; bool valid02 = getValueNearestNeighbourFloat(make_float2(x - 1, y + 1), d_intensity, imageWidth, imageHeight, &pos02); if (!valid02) return; + + float pos10; bool valid10 = getValueNearestNeighbourFloat(make_float2(x - 0, y - 1), d_intensity, imageWidth, imageHeight, &pos10); if (!valid10) return; + float pos11; bool valid11 = getValueNearestNeighbourFloat(make_float2(x - 0, y - 0), d_intensity, imageWidth, imageHeight, &pos11); if (!valid11) return; + float pos12; bool valid12 = getValueNearestNeighbourFloat(make_float2(x - 0, y + 1), d_intensity, imageWidth, imageHeight, &pos12); if (!valid12) return; + + float pos20; bool valid20 = getValueNearestNeighbourFloat(make_float2(x + 1, y - 1), d_intensity, imageWidth, imageHeight, &pos20); if (!valid20) return; + float pos21; bool valid21 = getValueNearestNeighbourFloat(make_float2(x + 1, y - 0), d_intensity, imageWidth, imageHeight, &pos21); if (!valid21) return; + float pos22; bool valid22 = getValueNearestNeighbourFloat(make_float2(x + 1, y + 1), d_intensity, imageWidth, imageHeight, &pos22); if (!valid22) return; + + float resU = (-1.0f)*pos00 + (1.0f)*pos20 + + (-2.0f)*pos01 + (2.0f)*pos21 + + (-1.0f)*pos02 + (1.0f)*pos22; + resU /= 8.0f; + + float resV = (-1.0f)*pos00 + (-2.0f)*pos10 + (-1.0f)*pos20 + + (1.0f)*pos02 + (2.0f)*pos12 + (1.0f)*pos22; + resV /= 8.0f; + + d_intensityAndDerivatives[index] = make_float4(pos11, resU, resV, 1.0f); + } + } +} + +extern "C" void computeIntensityAndDerivatives(float* d_intensity, unsigned int imageWidth, unsigned int imageHeight, float4* d_intensityAndDerivatives) +{ + const dim3 gridSize((imageWidth + T_PER_BLOCK - 1) / T_PER_BLOCK, (imageHeight + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + computeIntensityAndDerivativesDevice << > >(d_intensity, imageWidth, imageHeight, d_intensityAndDerivatives); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + + +///////////////////////////////////////////// +// Compute grdient intensity magnitude +///////////////////////////////////////////// + +__global__ void computeGradientIntensityMagnitudeDevice(float4* d_inputDU, float4* d_inputDV, unsigned int imageWidth, unsigned int imageHeight, float4* d_ouput) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + const int index = y*imageWidth + x; + + d_ouput[index] = make_float4(MINF, MINF, MINF, MINF); + + float4 DU = d_inputDU[index]; + float4 DV = d_inputDV[index]; + + if (DU.x != MINF && DV.x != MINF) + { + float m = sqrtf(DU.x*DU.x + DV.x*DV.x); + + if (m > 0.005f) + { + d_ouput[index] = make_float4(m, m, m, 1.0f); + } + } +} + +extern "C" void computeGradientIntensityMagnitude(float4* d_inputDU, float4* d_inputDV, unsigned int imageWidth, unsigned int imageHeight, float4* d_ouput) +{ + const dim3 gridSize((imageWidth + T_PER_BLOCK - 1) / T_PER_BLOCK, (imageHeight + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + computeGradientIntensityMagnitudeDevice << > >(d_inputDU, d_inputDV, imageWidth, imageHeight, d_ouput); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Erode Depth Map +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void erodeDepthMapDevice(float* d_output, float* d_input, int structureSize, int width, int height, float dThresh, float fracReq) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + + if (x >= 0 && x < width && y >= 0 && y < height) + { + + + unsigned int count = 0; + + float oldDepth = d_input[y*width + x]; + for (int i = -structureSize; i <= structureSize; i++) + { + for (int j = -structureSize; j <= structureSize; j++) + { + if (x + j >= 0 && x + j < width && y + i >= 0 && y + i < height) + { + float depth = d_input[(y + i)*width + (x + j)]; + if (depth == MINF || depth == 0.0f || fabs(depth - oldDepth) > dThresh) + { + count++; + //d_output[y*width+x] = MINF; + //return; + } + } + } + } + + unsigned int sum = (2 * structureSize + 1)*(2 * structureSize + 1); + if ((float)count / (float)sum >= fracReq) { + d_output[y*width + x] = MINF; + } + else { + d_output[y*width + x] = d_input[y*width + x]; + } + } +} + +extern "C" void erodeDepthMap(float* d_output, float* d_input, int structureSize, unsigned int width, unsigned int height, float dThresh, float fracReq) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + erodeDepthMapDevice << > >(d_output, d_input, structureSize, width, height, dThresh, fracReq); +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// filter annotations +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +__global__ void filterAnnotations_Kernel(unsigned char* d_outputInstance, const unsigned char* d_inputInstance, + const float* d_depth, const float* d_intensity, const unsigned char* d_instanceToIdx, + const unsigned char* d_idxToInstance, float* d_vote, + int structureSize, int width, int height, float sigmaD, float sigmaR, float intensityScale) +{ + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + const int voteoffset = (y*width + x) * MAX_NUM_LABELS_PER_SCENE; + + if (x >= 0 && x < width && y >= 0 && y < height) { + d_outputInstance[y*width + x] = d_inputInstance[y*width + x]; + float depthCenter = d_depth[y*width + x]; + float intensityCenter = d_intensity[y*width + x]; + for (int i = -structureSize; i <= structureSize; i++) { + for (int j = -structureSize; j <= structureSize; j++) { + if (x + j >= 0 && x + j < width && y + i >= 0 && y + i < height) + { + float depth = d_depth[(y + i)*width + (x + j)]; + float intensity = d_intensity[(y + i)*width + (x + j)]; + float intensityOffset = std::abs(intensityCenter - intensity) * intensityScale; //bring intensity to approx scale of depth + float depthOffset = 0.0f; + if (depthCenter != MINF && depth != MINF) + depthOffset = std::abs(depthCenter - depth); + const float weight = gaussD(sigmaD, j, i)*gaussR(sigmaR, depthOffset)*gaussR(sigmaR, intensityOffset); + unsigned char val = d_inputInstance[(y + i)*width + (x + j)]; + unsigned char idx = d_instanceToIdx[val]; + d_vote[voteoffset + idx] += weight; + } + } //j + } //i + float maxWeight = 0.0f; unsigned char bestVal = 0; //TODO fix this part... + for (int i = 0; i < MAX_NUM_LABELS_PER_SCENE; i++) { + if (d_vote[voteoffset + i] > maxWeight) { + maxWeight = d_vote[voteoffset + i]; + bestVal = d_idxToInstance[i]; + } + } + d_outputInstance[y*width + x] = bestVal; + } //in bounds of image +} + +extern "C" void filterAnnotations(unsigned char* d_outputInstance, const unsigned char* d_inputInstance, + const float* d_depth, const float* d_intensity, const unsigned char* d_instanceToIdx, + const unsigned char* d_idxToInstance, float* d_vote, + int structureSize, int width, int height, float sigmaD, float sigmaR, float intensityScale) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + cutilSafeCall(cudaMemset(d_vote, 0, sizeof(float)*width*height*MAX_NUM_LABELS_PER_SCENE)); + + filterAnnotations_Kernel << > >(d_outputInstance, d_inputInstance, + d_depth, d_intensity, d_instanceToIdx, d_idxToInstance, d_vote, + structureSize, width, height, sigmaD, sigmaR, intensityScale); + +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + + +__global__ void convertInstanceToLabel_Kernel(unsigned short* d_outputLabel, const unsigned char* d_inputInstance, + const unsigned short* d_instanceToLabel, unsigned int width, unsigned int height) +{ + const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x; + const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x < width && y < height) { + d_outputLabel[y*width + x] = d_instanceToLabel[d_inputInstance[y*width + x]]; + } //in bounds of image +} + +extern "C" void convertInstanceToLabel(unsigned short* d_outputLabel, const unsigned char* d_inputInstance, + const unsigned short* d_instanceToLabel, unsigned int width, unsigned int height) +{ + const dim3 gridSize((width + T_PER_BLOCK - 1) / T_PER_BLOCK, (height + T_PER_BLOCK - 1) / T_PER_BLOCK); + const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); + + convertInstanceToLabel_Kernel << > >(d_outputLabel, d_inputInstance, + d_instanceToLabel, width, height); + + //TODO convert instance to label +#ifdef _DEBUG + cutilSafeCall(cudaDeviceSynchronize()); + cutilCheckMsg(__FUNCTION__); +#endif +} + +#endif // _FILTER_ diff --git a/AnnotationTools/Filter2dAnnotations/mLibInclude.h b/AnnotationTools/Filter2dAnnotations/mLibInclude.h new file mode 100644 index 0000000..e3925b2 --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/mLibInclude.h @@ -0,0 +1,24 @@ + +#ifndef MLIB_INCLUDE_H +#define MLIB_INCLUDE_H + +// +// mLib config options +// +#define MLIB_ERROR_CHECK +#define MLIB_BOUNDS_CHECK + +// +// mLib includes +// + +#include "mLibCore.h" +#include "mLibDepthCamera.h" +//#include "mLibD3D11.h" +//#include "mLibD3D11Font.h" +//#include "mLibOpenMesh.h" +#include "mLibFreeImage.h" + +using namespace ml; + +#endif diff --git a/AnnotationTools/Filter2dAnnotations/mLibSource.cpp b/AnnotationTools/Filter2dAnnotations/mLibSource.cpp new file mode 100644 index 0000000..4ae8cf3 --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/mLibSource.cpp @@ -0,0 +1,6 @@ + +//#include "stdafx.h" + +#include "mLibCore.cpp" +//#include "mLibD3D11.cpp" +#include "mLibDepthCamera.cpp" \ No newline at end of file diff --git a/AnnotationTools/Filter2dAnnotations/stdafx.cpp b/AnnotationTools/Filter2dAnnotations/stdafx.cpp new file mode 100644 index 0000000..ba318e9 --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/stdafx.cpp @@ -0,0 +1,9 @@ +// stdafx.cpp : source file that includes just the standard includes +// EvaluateAnnotations.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file +#include "mLibSource.cpp" \ No newline at end of file diff --git a/AnnotationTools/Filter2dAnnotations/stdafx.h b/AnnotationTools/Filter2dAnnotations/stdafx.h new file mode 100644 index 0000000..988b708 --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/stdafx.h @@ -0,0 +1,16 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include +#include + + + +// TODO: reference additional headers your program requires here +#include "mLibInclude.h" \ No newline at end of file diff --git a/AnnotationTools/Filter2dAnnotations/targetver.h b/AnnotationTools/Filter2dAnnotations/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/AnnotationTools/Filter2dAnnotations/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/AnnotationTools/ProjectAnnotations/GlobalAppState.h b/AnnotationTools/ProjectAnnotations/GlobalAppState.h new file mode 100644 index 0000000..52c6c15 --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/GlobalAppState.h @@ -0,0 +1,86 @@ +#pragma once + +#include "stdafx.h" + +#include +#include +#include + + + +#define X_GLOBAL_APP_STATE_FIELDS \ + X(std::string, s_scanDir) \ + X(float, s_depthMin) \ + X(float, s_depthMax) \ + X(std::string, s_labelMappingFile) \ + X(std::string, s_outDir) \ + X(float, s_depthDistThresh) \ + X(bool, s_useHiResMesh) \ + X(float, s_propagateNormalThresh) \ + X(unsigned int, s_frameSkip) \ + X(bool, s_outputDebugImages) \ + X(bool, s_filterUsingOrigialDepthImage) + + +#ifndef VAR_NAME +#define VAR_NAME(x) #x +#endif + +#define checkSizeArray(a, d)( (((sizeof a)/(sizeof a[0])) >= d)) + +class GlobalAppState +{ +public: + +#define X(type, name) type name; + X_GLOBAL_APP_STATE_FIELDS +#undef X + + //! sets the parameter file and reads + void readMembers(const ParameterFile& parameterFile) { + m_ParameterFile = parameterFile; + readMembers(); + } + + //! reads all the members from the given parameter file (could be called for reloading) + void readMembers() { +#define X(type, name) \ + if (!m_ParameterFile.readParameter(std::string(#name), name)) {MLIB_WARNING(std::string(#name).append(" ").append("uninitialized")); name = type();} + X_GLOBAL_APP_STATE_FIELDS +#undef X + + + m_bIsInitialized = true; + } + + void print() const { +#define X(type, name) \ + std::cout << #name " = " << name << std::endl; + X_GLOBAL_APP_STATE_FIELDS +#undef X + } + + static GlobalAppState& getInstance() { + static GlobalAppState s; + return s; + } + static GlobalAppState& get() { + return getInstance(); + } + + + //! constructor + GlobalAppState() { + m_bIsInitialized = false; + } + + //! destructor + ~GlobalAppState() { + } + + Timer s_Timer; + +private: + bool m_bIsInitialized; + ParameterFile m_ParameterFile; +}; diff --git a/AnnotationTools/ProjectAnnotations/LabelUtil.h b/AnnotationTools/ProjectAnnotations/LabelUtil.h new file mode 100644 index 0000000..1f9d9c3 --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/LabelUtil.h @@ -0,0 +1,89 @@ +#pragma once + +class LabelUtil +{ +public: + LabelUtil() {} + void init(const std::string& labelMapFile, const std::string& labelName = "category", const std::string& idName = "") { + if (!util::fileExists(labelMapFile)) throw MLIB_EXCEPTION(labelMapFile + " does not exist!"); + m_maxLabel = 65535;//255; + + getLabelMappingFromFile(labelMapFile, labelName, idName); + + m_bIsInitialized = true; + } + + static LabelUtil& getInstance() { + static LabelUtil s; + return s; + } + static LabelUtil& get() { + return getInstance(); + } + + bool getIdForLabel(const std::string& label, unsigned short& id) const { + const auto it = s_labelsToIds.find(label); + if (it == s_labelsToIds.end()) return false; + id = it->second; + return true; + } + + bool getLabelForId(unsigned short id, std::string& label) const { + const auto it = s_idsToLabels.find(id); + if (it == s_idsToLabels.end()) return false; + label = it->second; + return true; + } + +private: + + void getLabelMappingFromFile(const std::string& filename, const std::string& labelName, const std::string& idName) + { + if (!util::fileExists(filename)) throw MLIB_EXCEPTION("label mapping files does not exist!"); + const char splitter = '\t'; + + s_labelsToIds.clear(); + s_idsToLabels.clear(); + + std::ifstream s(filename); std::string line; + //read header + std::unordered_map header; + if (!std::getline(s, line)) throw MLIB_EXCEPTION("error reading label mapping file"); + auto parts = util::split(line, splitter); + const unsigned int numElems = (unsigned int)parts.size(); + for (unsigned int i = 0; i < parts.size(); i++) header[parts[i]] = i; + + auto it = header.find(labelName); + if (it == header.end()) throw MLIB_EXCEPTION("could not find value " + labelName + " in label mapping file"); + unsigned int labelIdx = it->second; + bool bUseExistingLabel = !idName.empty(); unsigned int idIdx = (unsigned int)-1; + if (bUseExistingLabel) { + it = header.find(idName); + if (it == header.end()) throw MLIB_EXCEPTION("could not find value " + idName + " in label mapping file"); + idIdx = it->second; + } + //read elements + unsigned int lineCount = 1; + while (std::getline(s, line)) { + parts = util::split(line, splitter, true); + if (!parts[labelIdx].empty() && (!bUseExistingLabel || !parts[idIdx].empty())) { + unsigned int id = bUseExistingLabel ? util::convertTo(parts[idIdx]) : lineCount; + if (id > m_maxLabel) //skip + continue; + s_labelsToIds[parts[labelIdx]] = (unsigned short)id; + s_idsToLabels[(unsigned short)id] = parts[labelIdx]; + } + ++lineCount; + } + s.close(); + + std::cout << "read " << s_labelsToIds.size() << " labels" << std::endl; + } + + bool m_bIsInitialized; + unsigned short m_maxLabel; + + std::unordered_map s_labelsToIds; + std::unordered_map s_idsToLabels; + +}; \ No newline at end of file diff --git a/AnnotationTools/ProjectAnnotations/ProjectAnnotations.sln b/AnnotationTools/ProjectAnnotations/ProjectAnnotations.sln new file mode 100644 index 0000000..a00469b --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/ProjectAnnotations.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProjectAnnotations", "ProjectAnnotations.vcxproj", "{B7522A83-8AE0-4351-BE91-71C5989A6519}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B7522A83-8AE0-4351-BE91-71C5989A6519}.Debug|x64.ActiveCfg = Debug|x64 + {B7522A83-8AE0-4351-BE91-71C5989A6519}.Debug|x64.Build.0 = Debug|x64 + {B7522A83-8AE0-4351-BE91-71C5989A6519}.Release|x64.ActiveCfg = Release|x64 + {B7522A83-8AE0-4351-BE91-71C5989A6519}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/AnnotationTools/ProjectAnnotations/ProjectAnnotations.vcxproj b/AnnotationTools/ProjectAnnotations/ProjectAnnotations.vcxproj new file mode 100644 index 0000000..bbc3ef9 --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/ProjectAnnotations.vcxproj @@ -0,0 +1,129 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {B7522A83-8AE0-4351-BE91-71C5989A6519} + Win32Proj + ProjectAnnotations + + + + Application + true + v120 + Unicode + + + Application + false + v120 + true + Unicode + + + + + + + + + + + + + true + ../../external/mLib/include;../../../mLibExternal/include;C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include;$(IncludePath) + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;../../../mLibExternal/libsWindows/lib64;$(LibraryPath) + + + false + ../../external/mLib/include;../../../mLibExternal/include;C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include;$(IncludePath) + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;../../../mLibExternal/libsWindows/lib64;$(LibraryPath) + + + + Use + Level3 + Disabled + WIN32;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + false + -Zm110 %(AdditionalOptions) + + + Console + true + FW1FontWrapper.lib;d3d11.lib;d3dx11.lib;D3DCompiler.lib;FreeImage.lib;zlib64.lib;%(AdditionalDependencies) + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;_CRT_SECURE_NO_WARNINGS;NOMINMAX;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + $(IncludePath);$(DXSDK_DIR)Include;..\..\mLibextern\include + true + -Zm110 %(AdditionalOptions) + + + Console + true + true + true + FW1FontWrapper.lib;d3d11.lib;d3dx11.lib;D3DCompiler.lib;FreeImage.lib;zlib64.lib;%(AdditionalDependencies) + $(LibraryPath);$(DXSDK_DIR)Lib\x64; ..\..\mLibextern\libsWindows\lib64 + + + + + + + + + + + + + + + + + + + + true + true + + + Create + Create + + + + + + + + + true + Document + true + + + + + + \ No newline at end of file diff --git a/AnnotationTools/ProjectAnnotations/ProjectAnnotations.vcxproj.filters b/AnnotationTools/ProjectAnnotations/ProjectAnnotations.vcxproj.filters new file mode 100644 index 0000000..02589a5 --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/ProjectAnnotations.vcxproj.filters @@ -0,0 +1,82 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {8e0e7543-8329-42d8-a2e5-c872d029edc0} + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + + + Shader + + + \ No newline at end of file diff --git a/AnnotationTools/ProjectAnnotations/Visualizer.cpp b/AnnotationTools/ProjectAnnotations/Visualizer.cpp new file mode 100644 index 0000000..8495f37 --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/Visualizer.cpp @@ -0,0 +1,378 @@ + +#include "stdafx.h" +#include "Visualizer.h" +#include "GlobalAppState.h" +#include "LabelUtil.h" +#include "omp.h" +#include + +void Visualizer::init(ApplicationData &app) +{ + std::string scanDir = GlobalAppState::get().s_scanDir; + scanDir = util::replace(scanDir, '\\', '/'); + if (scanDir.back() != '/') scanDir.push_back('/'); + std::cout << "[ProjectAnnotations] " << scanDir << std::endl; + const std::string scanName = util::split(scanDir, "/").back(); + const std::string sensFile = scanDir + scanName + ".sens"; + const std::string meshFile = scanDir + scanName + "_vh_clean_2.ply"; + const std::string segsFile = scanDir + scanName + "_vh_clean_2.0.010000.segs.json"; + const std::string aggregationFile = scanDir + scanName + ".aggregation.json"; + const std::string meshHiFile = scanDir + scanName + "_vh_clean.ply"; + const bool bUseHiResMesh = GlobalAppState::get().s_useHiResMesh; + if (!(util::fileExists(sensFile) && util::fileExists(meshFile) && util::fileExists(segsFile) && + util::fileExists(aggregationFile) && (!bUseHiResMesh || util::fileExists(meshHiFile)))) { + std::cout << "WARNING: no sens/mesh/segs/aggregation file, skipping" << std::endl; + return; + } + LabelUtil::get().init(GlobalAppState::get().s_labelMappingFile); + + m_sensorName = util::removeExtensions(util::splitPath(sensFile).back()); + std::cout << "loading scan info... "; Timer t; + m_sensorData.loadFromFile(sensFile); + //load aggregation and compute segmentation ids + Segmentation segmentation; segmentation.loadFromFile(segsFile); + Aggregation aggregation; aggregation.loadFromJSONFile(aggregationFile); + + MeshDataf meshData = MeshIOf::loadFromFile(meshFile); + MeshDataf meshHi; if (bUseHiResMesh) MeshIOf::loadFromFile(meshHiFile, meshHi); + unsigned int numObjects = computeObjectIdsAndColorsPerVertex(aggregation, segmentation, meshData, meshHi); //puts hi-res with labels into meshdata + m_mesh.init(app.graphics, TriMeshf(meshData)); + std::cout << "done! (" << t.getElapsedTime() << " s)" << std::endl; + + m_fieldOfView = 2 * 180 / PI * atan(0.5 * m_sensorData.m_colorWidth / m_sensorData.m_calibrationColor.m_intrinsic(0, 0)); + m_camera = Cameraf(m_sensorData.m_frames[0].getCameraToWorld(), m_fieldOfView, + (float)m_sensorData.m_colorWidth / (float)m_sensorData.m_colorHeight, GlobalAppState::get().s_depthMin, GlobalAppState::get().s_depthMax); + + m_constants.init(app.graphics); + + std::vector formats = { + DXGI_FORMAT::DXGI_FORMAT_R32G32B32A32_FLOAT + }; + m_renderTarget.init(app.graphics.castD3D11(), m_sensorData.m_colorWidth, m_sensorData.m_colorHeight, formats, true); + + const std::string outDir = GlobalAppState::get().s_outDir; + if (!util::directoryExists(outDir)) util::makeDirectory(outDir); +} + +void Visualizer::render(ApplicationData &app) +{ + m_timer.frame(); + + static unsigned int frame = 0; + bool validFrame = false; + if (frame < m_sensorData.m_frames.size()) { + if (m_sensorData.m_frames[frame].getCameraToWorld()._m00 != -std::numeric_limits::infinity()) validFrame = true; + m_camera = Cameraf(m_sensorData.m_frames[frame].getCameraToWorld(), m_fieldOfView, + (float)m_sensorData.m_colorWidth / (float)m_sensorData.m_colorHeight, GlobalAppState::get().s_depthMin, GlobalAppState::get().s_depthMax); + std::cout << "\r[ " << (frame + 1) << " | " << m_sensorData.m_frames.size() << " ]"; + } + else { + std::cout << std::endl << "done" << std::endl; + exit(0); + } + + std::string outDir = GlobalAppState::get().s_outDir; + outDir = (outDir.back() == '/' || outDir.back() == '\\') ? outDir + m_sensorName + "/" : outDir + "/" + m_sensorName + "/"; + if (!util::directoryExists(outDir)) util::makeDirectory(outDir); + const std::string outInstanceDir = outDir + "instance/"; if (!util::directoryExists(outInstanceDir)) util::makeDirectory(outInstanceDir); + const std::string outLabelDir = outDir + "label/"; if (!util::directoryExists(outLabelDir)) util::makeDirectory(outLabelDir); + + const bool bFilterUsingOrigDepth = GlobalAppState::get().s_filterUsingOrigialDepthImage; + const float zNear = GlobalAppState::get().s_depthMin; + const float zFar = GlobalAppState::get().s_depthMax; + const float depthDistThresh = GlobalAppState::get().s_depthDistThresh; + if (validFrame) { + DepthImage16 origDepthImage = m_sensorData.computeDepthImage(frame); + + mat4f proj = Cameraf::visionToGraphicsProj(m_sensorData.m_colorWidth, m_sensorData.m_colorHeight, m_sensorData.m_calibrationColor.m_intrinsic(0, 0), m_sensorData.m_calibrationColor.m_intrinsic(1, 1), zNear, zFar); + ConstantBuffer constants; + constants.worldViewProj = proj * m_camera.getView(); + + constants.modelColor = ml::vec4f(1.0f, 1.0f, 1.0f, 1.0f); + m_constants.updateAndBind(constants, 0); + app.graphics.castD3D11().getShaderManager().registerShader("shaders/drawAnnotations.hlsl", "drawAnnotations", "vertexShaderMain", "vs_4_0", "pixelShaderMain", "ps_4_0"); + app.graphics.castD3D11().getShaderManager().bindShaders("drawAnnotations"); + + m_renderTarget.clear(); + m_renderTarget.bind(); + m_mesh.render(); + m_renderTarget.unbind(); + + DepthImage32 depthBuffer; + ColorImageR32G32B32A32 colorBuffer; + m_renderTarget.captureColorBuffer(colorBuffer); + m_renderTarget.captureDepthBuffer(depthBuffer); + //annotations + MLIB_ASSERT(colorBuffer.getWidth() == m_sensorData.m_colorWidth && colorBuffer.getHeight() == m_sensorData.m_colorHeight); + BaseImage objectInstanceImage(colorBuffer.getWidth(), colorBuffer.getHeight()); // image with object id annotations + BaseImage objectLabelImage(colorBuffer.getWidth(), colorBuffer.getHeight()); + for (unsigned int i = 0; i < colorBuffer.getNumPixels(); i++) { + const vec4f& c = colorBuffer.getData()[i]; + float label = c.w; float id = c.z; + label = std::round(label); id = std::round(id); + MLIB_ASSERT(label >= 0 && label < 65535 && id >= 0 && id < 255); + objectInstanceImage.getData()[i] = (unsigned char)id; + objectLabelImage.getData()[i] = (unsigned short)label; + } + + //depth + mat4f projToCamera = m_camera.getProj().getInverse(); + mat4f cameraToWorld = m_camera.getView().getInverse(); + mat4f projToWorld = cameraToWorld * projToCamera; + mat4f intrinsic = Cameraf::graphicsToVisionProj(m_camera.getProj(), depthBuffer.getWidth(), depthBuffer.getHeight()); +#pragma omp parallel for + for (int y = 0; y < (int)depthBuffer.getHeight(); y++) { + for (int x = 0; x < (int)depthBuffer.getWidth(); x++) { + float d = depthBuffer(x, y); + if (d != 0.0f && d != 1.0f) { + vec3f posProj = vec3f(app.graphics.castD3D11().pixelToNDC(vec2i(x, y), depthBuffer.getWidth(), depthBuffer.getHeight()), d); + vec3f posCamera = projToCamera * posProj; + if (posCamera.z >= zNear && posCamera.z <= zFar) depthBuffer(x, y) = posCamera.z; + else depthBuffer(x, y) = 0.0f; + } + else { + depthBuffer(x, y) = 0.0f; + } + } + } + DepthImage16 depth(depthBuffer.getResized(m_sensorData.m_depthWidth, m_sensorData.m_depthHeight), 1000.0f); + + const float scaleDepthWidth = (float)(depth.getWidth() - 1) / (float)(objectLabelImage.getWidth() - 1); + const float scaleDepthHeight = (float)(depth.getHeight() - 1) / (float)(objectLabelImage.getHeight() - 1); +#pragma omp parallel for + for (int y = 0; y < (int)objectLabelImage.getHeight(); y++) { + for (int x = 0; x < (int)objectLabelImage.getWidth(); x++) { + unsigned short v = objectLabelImage(x, y); + if (v != 0) { + const unsigned int dx = (unsigned int)std::round(scaleDepthWidth * x); + const unsigned int dy = (unsigned int)std::round(scaleDepthHeight * y); + const unsigned short drndr = depth(dx, dy); + const unsigned short dorig = origDepthImage(dx, dy); + if ((bFilterUsingOrigDepth && dorig == 0) || (drndr != 0 && dorig != 0 && std::fabs((drndr - dorig) * 0.001f) > depthDistThresh + 0.01f * dorig)) { + objectLabelImage(x, y) = 0; + objectInstanceImage(x, y) = 0; + } + } + } //x + } //y + + int radius = 2; +#pragma omp parallel for + for (int y = 0; y < (int)objectLabelImage.getHeight(); y++) { + for (int x = 0; x < (int)objectLabelImage.getWidth(); x++) { + unsigned short v = objectLabelImage(x, y); + if (v != 0) { + unsigned int count = 0, total = 0; + for (int yy = y - radius; yy <= y + radius; yy++) { + for (int xx = x - radius; xx <= x + radius; xx++) { + if (xx >= 0 && xx < (int)objectLabelImage.getWidth() && yy >= 0 && yy < (int)objectLabelImage.getHeight()) { + total++; + if (objectLabelImage(xx, yy) == v) count++; + } + } + } + if ((float)count / (float)total < 0.2f) { + objectLabelImage(x, y) = 0; + objectInstanceImage(x, y) = 0; + } + } + } //x + } //y + + FreeImageWrapper::saveImage(outInstanceDir + std::to_string(frame) + ".png", objectInstanceImage); + FreeImageWrapper::saveImage(outLabelDir + std::to_string(frame) + ".png", objectLabelImage); + + if (GlobalAppState::get().s_outputDebugImages && frame % 100 == 0) { + + static std::unordered_map colors; + for (const auto& p : objectLabelImage) { + if (p.value != 0 && colors.find(p.value) == colors.end()) { + RGBColor c = RGBColor::randomColor(); + colors[p.value] = vec3uc(c.x, c.y, c.z); + } + } + for (const auto& p : objectInstanceImage) { + if (p.value != 0 && colors.find(p.value) == colors.end()) { + RGBColor c = RGBColor::randomColor(); + colors[p.value] = vec3uc(c.x, c.y, c.z); + } + } + + //debug print out colored annotation image + ColorImageR8G8B8 colorImageInstance(colorBuffer.getWidth(), colorBuffer.getHeight()); + ColorImageR8G8B8 colorImageLabel(colorBuffer.getWidth(), colorBuffer.getHeight()); + for (const auto& p : objectLabelImage) { + if (p.value != 0) { + const auto it = colors.find(p.value); + MLIB_ASSERT(it != colors.end()); + colorImageLabel(p.x, p.y) = it->second; + } + else colorImageLabel(p.x, p.y) = vec3uc(0, 0, 0); + } + for (const auto& p : objectInstanceImage) { + if (p.value != 0) { + const auto it = colors.find(p.value); + MLIB_ASSERT(it != colors.end()); + colorImageInstance(p.x, p.y) = it->second; + } + else colorImageInstance(p.x, p.y) = vec3uc(0, 0, 0); + } + FreeImageWrapper::saveImage(outDir + std::to_string(frame) + "_color-label.png", colorImageLabel); + FreeImageWrapper::saveImage(outDir + std::to_string(frame) + "_color-instance.png", colorImageInstance); + //std::cout << "waiting..." << std::endl; getchar(); + } + } + else { + BaseImage objectInstanceImage(m_sensorData.m_colorWidth, m_sensorData.m_colorHeight, (unsigned char)0); //empty image, no valid transform + BaseImage objectLabelImage(m_sensorData.m_colorWidth, m_sensorData.m_colorHeight, (unsigned short)0); //empty image, no valid transform + FreeImageWrapper::saveImage(outInstanceDir + std::to_string(frame) + ".png", objectInstanceImage); + FreeImageWrapper::saveImage(outLabelDir + std::to_string(frame) + ".png", objectLabelImage); + } + frame += GlobalAppState::get().s_frameSkip; +} + +void Visualizer::resize(ApplicationData &app) +{ + m_camera.updateAspectRatio((float)app.window.getWidth() / app.window.getHeight()); +} + +void Visualizer::keyDown(ApplicationData &app, UINT key) +{ +} + +void Visualizer::keyPressed(ApplicationData &app, UINT key) +{ +} + +void Visualizer::mouseDown(ApplicationData &app, MouseButtonType button) +{ +} + +void Visualizer::mouseWheel(ApplicationData &app, int wheelDelta) +{ +} + +void Visualizer::mouseMove(ApplicationData &app) +{ +} + +unsigned int Visualizer::computeObjectIdsAndColorsPerVertex(const Aggregation& aggregation, const Segmentation& segmentation, + MeshDataf& meshData, const MeshDataf& meshHi) +{ + const bool bUseHi = !meshHi.isEmpty(); + std::vector colorsPerVertex(meshData.m_Vertices.size(), vec4f::origin); + + const auto& aggregatedSegments = aggregation.getAggregatedSegments(); + const auto& objectIdsToLabels = aggregation.getObjectIdsToLabels(); + //generate some random colors + std::unordered_map objectColors; std::unordered_map objectIdsToLabelIds; + for (unsigned int i = 0; i < aggregatedSegments.size(); i++) { + const unsigned int objectId = i; + const auto itl = objectIdsToLabels.find(objectId); + MLIB_ASSERT(itl != objectIdsToLabels.end()); + unsigned short labelId; + if (LabelUtil::get().getIdForLabel(itl->second, labelId)) { + objectIdsToLabelIds[objectId] = labelId; + auto itc = objectColors.find(labelId); + if (itc == objectColors.end()) { + RGBColor c = RGBColor::randomColor(); + objectColors[labelId] = vec4f(c.x / 255.0f, c.y / 255.0f, objectId + 1, labelId); //objectid -> instance, labelid-> label + } + } + } + //assign object ids and colors + std::unordered_map< unsigned int, std::vector > verticesPerSegment = segmentation.getSegmentIdToVertIdMap(); + for (unsigned int i = 0; i < aggregatedSegments.size(); i++) { + const unsigned int objectId = i; + const auto itl = objectIdsToLabelIds.find(objectId); + if (itl == objectIdsToLabelIds.end()) continue; + const vec4f& color = objectColors[itl->second]; + for (unsigned int seg : aggregatedSegments[i]) { + const std::vector& vertIds = verticesPerSegment[seg]; + for (unsigned int v : vertIds) { + colorsPerVertex[v] = color; + } + } + } + meshData.m_Colors = colorsPerVertex; + if (bUseHi) { + MeshDataf propagated = meshHi; + if (!meshData.hasNormals()) meshData.computeVertexNormals(); + if (!propagated.hasNormals()) propagated.computeVertexNormals(); + propagateAnnotations(meshData, propagated); + meshData = propagated; + } + return (unsigned int)objectColors.size(); +} + +void Visualizer::propagateAnnotations(const MeshDataf& meshSrc, MeshDataf& meshDst) +{ + MLIB_ASSERT(meshSrc.hasNormals() && meshDst.hasNormals()); + const float normalThresh = GlobalAppState::get().s_propagateNormalThresh; + + const bbox3f bbox = meshSrc.computeBoundingBox(); + + //nearest neighbor search for vertices + std::vector searchVerts; + std::vector searchIndices; + for (unsigned int i = 0; i < meshSrc.m_Vertices.size(); i++) { + if (meshSrc.m_Colors[i].w > 0) { + searchVerts.push_back(meshSrc.m_Vertices[i]); + searchIndices.push_back(i); + } + } + std::vector srcVerts(searchVerts.size()); + for (unsigned int i = 0; i < searchVerts.size(); i++) { + srcVerts[i] = (const float*)&searchVerts[i]; + } + const unsigned int maxK = 3; + const float eps = 0.01f; + int numThreads = omp_get_max_threads(); + std::vector nn(numThreads); + for (unsigned int i = 0; i < nn.size(); i++) { + nn[i] = new NearestNeighborSearchFLANNf(100, 12); + nn[i]->init(srcVerts, 3, maxK); + } + const float maxThresh = std::max(bbox.getMaxExtent() * 0.01f, 0.05f); + + if (!meshDst.hasColors()) meshDst.m_Colors.resize(meshDst.m_Vertices.size()); +#pragma omp parallel for + for (int i = 0; i < (int)meshDst.m_Vertices.size(); i++) { + int thread = omp_get_thread_num(); + std::vector nearestIndices; + nn[thread]->kNearest((const float*)&meshDst.m_Vertices[i], maxK, eps, nearestIndices); + if (!nearestIndices.empty()) { + std::vector dists = nn[thread]->getDistances(maxK); + unsigned int bestIdx = (unsigned int)-1; + const vec4f& val = meshSrc.m_Colors[searchIndices[nearestIndices[0]]]; //object id + bool allSame = true; + for (unsigned int k = 0; k < maxK; k++) { + if (dists[k] < maxThresh) { + if (std::acos(math::clamp(meshSrc.m_Normals[searchIndices[nearestIndices[k]]] | meshDst.m_Normals[i], -1.0f, 1.0f)) < normalThresh) { //make sure similar normals + bestIdx = k; + break; + } + if (meshSrc.m_Colors[searchIndices[nearestIndices[k]]].z != val.z) allSame = false; + } + else allSame = false; + } + if (bestIdx != (unsigned int)-1) { + const vec3f& nearest = searchVerts[nearestIndices[bestIdx]]; + meshDst.m_Colors[i] = meshSrc.m_Colors[searchIndices[nearestIndices[bestIdx]]]; + } + else if (allSame) { + meshDst.m_Colors[i] = val; + } + else { + meshDst.m_Colors[i] = vec4f(0.0f); + } + } + else { + meshDst.m_Colors[i] = vec4f(0.0f); + } + } + for (unsigned int i = 0; i < nn.size(); i++) + SAFE_DELETE(nn[i]); +} + + diff --git a/AnnotationTools/ProjectAnnotations/Visualizer.h b/AnnotationTools/ProjectAnnotations/Visualizer.h new file mode 100644 index 0000000..2d71466 --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/Visualizer.h @@ -0,0 +1,55 @@ +#pragma once + +#include "../common/json.h" +#include "../common/Segmentation.h" +#include "../common/Aggregation.h" + +struct ConstantBuffer +{ + mat4f worldViewProj; + ml::vec4f modelColor; +}; + +class Visualizer : public ApplicationCallback +{ +public: + void init(ApplicationData &app); + void render(ApplicationData &app); + void keyDown(ApplicationData &app, UINT key); + + void keyPressed(ApplicationData &app, UINT key); + void mouseDown(ApplicationData &app, MouseButtonType button); + void mouseMove(ApplicationData &app); + void mouseWheel(ApplicationData &app, int wheelDelta); + void resize(ApplicationData &app); + +private: + //returns #unique objects/colors + unsigned int computeObjectIdsAndColorsPerVertex(const Aggregation& aggregation, const Segmentation& segmentation, MeshDataf& meshData, const MeshDataf& meshHi); + + static inline float gaussD(float sigma, int x, int y) + { + return exp(-((x*x + y*y) / (2.0f*sigma*sigma))); + } + static inline float gaussR(float sigma, float dist) + { + return exp(-(dist*dist) / (2.0f*sigma*sigma)); + } + + void propagateAnnotations(const MeshDataf& meshSrc, MeshDataf& meshDst); + + ml::D3D11TriMesh m_mesh; + + ml::D3D11ShaderManager m_shaderManager; + D3D11RenderTarget m_renderTarget; + + FrameTimer m_timer; + + D3D11ConstantBuffer m_constants; + Cameraf m_camera; + + //scan data + SensorData m_sensorData; + std::string m_sensorName; + float m_fieldOfView; +}; \ No newline at end of file diff --git a/AnnotationTools/ProjectAnnotations/mLibInclude.h b/AnnotationTools/ProjectAnnotations/mLibInclude.h new file mode 100644 index 0000000..cd2dcf6 --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/mLibInclude.h @@ -0,0 +1,23 @@ + +#ifndef MLIB_INCLUDE_H +#define MLIB_INCLUDE_H + +// +// mLib config options +// +#define MLIB_ERROR_CHECK +#define MLIB_BOUNDS_CHECK + +// +// mLib includes +// + +#include "mLibCore.h" +#include "mLibDepthCamera.h" +#include "mLibD3D11.h" +#include "mLibFLANN.h" +#include "mLibFreeImage.h" + +using namespace ml; + +#endif diff --git a/AnnotationTools/ProjectAnnotations/mLibSource.cpp b/AnnotationTools/ProjectAnnotations/mLibSource.cpp new file mode 100644 index 0000000..c7e489e --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/mLibSource.cpp @@ -0,0 +1,6 @@ + +//#include "stdafx.h" + +#include "mLibCore.cpp" +#include "mLibDepthCamera.cpp" +#include "mLibD3D11.cpp" \ No newline at end of file diff --git a/AnnotationTools/ProjectAnnotations/main.cpp b/AnnotationTools/ProjectAnnotations/main.cpp new file mode 100644 index 0000000..02cd509 --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/main.cpp @@ -0,0 +1,52 @@ + + +#include "stdafx.h" +#include "Visualizer.h" +#include "GlobalAppState.h" + +int _tmain(int argc, _TCHAR* argv[]) +{ + Visualizer callback; + + std::string fileNameDescGlobalApp = "zParametersScan.txt"; + std::string scanDir = ""; + if (argc == 3) { //overwrite scanDir with command line args + std::wstring argParam = std::wstring(argv[1]); + std::wstring argScanDir = std::wstring(argv[2]); + fileNameDescGlobalApp =std::string(argParam.begin(), argParam.end()); + scanDir = std::string(argScanDir.begin(), argScanDir.end()); + } + std::cout << VAR_NAME(fileNameDescGlobalApp) << " = " << fileNameDescGlobalApp << std::endl; + ParameterFile parameterFileGlobalApp(fileNameDescGlobalApp); + GlobalAppState::get().readMembers(parameterFileGlobalApp); + if (!scanDir.empty()) GlobalAppState::get().s_scanDir = scanDir; + GlobalAppState::get().print(); + + //get image size + unsigned int colorWidth = 0, colorHeight = 0; + scanDir = GlobalAppState::get().s_scanDir; + scanDir = util::replace(scanDir, '\\', '/'); + if (scanDir.back() != '/') scanDir.push_back('/'); + const std::string scanName = util::split(scanDir, "/").back(); + const std::string metaFile = scanDir + scanName + ".txt"; + if (util::fileExists(metaFile)) { + ParameterFile pf(metaFile); + if (!pf.readParameter("colorWidth", colorWidth)) { + std::cerr << "ERROR: failed to read \"colorWidth\" param from " << metaFile << std::endl; + return -1; + }; + if (!pf.readParameter("colorHeight", colorHeight)) { + std::cerr << "ERROR: failed to read \"colorHeight\" param from " << metaFile << std::endl; + return -1; + }; + } + else { + std::cout << "ERROR: meta-file (" << metaFile << ") does not exist! " << std::endl; + return -1; + } + + ApplicationWin32 app(NULL, colorWidth, colorHeight, "Project Annotations", GraphicsDeviceTypeD3D11, callback); + app.messageLoop(); + + return 0; +} diff --git a/AnnotationTools/ProjectAnnotations/shaders/drawAnnotations.hlsl b/AnnotationTools/ProjectAnnotations/shaders/drawAnnotations.hlsl new file mode 100644 index 0000000..668ec45 --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/shaders/drawAnnotations.hlsl @@ -0,0 +1,32 @@ + +cbuffer ConstantBuffer : register(b0) +{ + matrix worldViewProj; + float4 modelColor; +} + + +struct VertexShaderOutput +{ + float4 position : SV_POSITION; + nointerpolation float4 color : TEXCOORD0; +}; + +VertexShaderOutput vertexShaderMain( + float4 position : position, + float3 normal : normal, + float4 color : color, + float2 texCoord : texCoord) +{ + VertexShaderOutput output; + output.position = mul(position, worldViewProj); + output.color = color; + return output; +} + + +float4 pixelShaderMain(VertexShaderOutput input) : SV_Target +{ + //return float4(input.color.xyz, 1.0f); + return input.color; +} diff --git a/AnnotationTools/ProjectAnnotations/stdafx.cpp b/AnnotationTools/ProjectAnnotations/stdafx.cpp new file mode 100644 index 0000000..2b648bf --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/stdafx.cpp @@ -0,0 +1,9 @@ +// stdafx.cpp : source file that includes just the standard includes +// VirtualScan.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +#include "mLibSource.cpp" +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file \ No newline at end of file diff --git a/AnnotationTools/ProjectAnnotations/stdafx.h b/AnnotationTools/ProjectAnnotations/stdafx.h new file mode 100644 index 0000000..e494934 --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/stdafx.h @@ -0,0 +1,15 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include +#include + + +// TODO: reference additional headers your program requires here +#include "mLibInclude.h" \ No newline at end of file diff --git a/AnnotationTools/ProjectAnnotations/targetver.h b/AnnotationTools/ProjectAnnotations/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/AnnotationTools/ProjectAnnotations/zParametersScan.txt b/AnnotationTools/ProjectAnnotations/zParametersScan.txt new file mode 100644 index 0000000..d2993b1 --- /dev/null +++ b/AnnotationTools/ProjectAnnotations/zParametersScan.txt @@ -0,0 +1,16 @@ + +s_scanDir = "../../data/scans/scene0000_00/"; +s_outDir = "output/"; +s_outputDebugImages = false; //output color images for visualization +s_labelMappingFile = "../../data/tasks/scannet-labels.combined.tsv"; +s_useHiResMesh = true; //propagate annotations to hi-res mesh before projection +s_filterUsingOrigialDepthImage = false // remove label projections corresponding to invalid depth in original depth image + + +s_frameSkip = 1; + +s_depthMin = 0.1f; //meters +s_depthMax = 15.0f; //meters +s_depthDistThresh = 0.2f; //meters +s_propagateNormalThresh = 0.5f; //radians + diff --git a/AnnotationTools/Readme.md b/AnnotationTools/Readme.md new file mode 100644 index 0000000..5d529c1 --- /dev/null +++ b/AnnotationTools/Readme.md @@ -0,0 +1,28 @@ + + +## ProjectAnnotations + +For an RGB-D scan, projects 3d mesh annotations into 2d frames according to the camera trajectory of the sequence. +See the parameter file `zParametersScan.txt` for input arguments. + +### Installation +The code was developed under VS2013. + +Requirements: +- DirectX SDK June 2010 +- our research library mLib, a git submodule in ../external/mLib +- mLib external libraries can be downloaded [here](https://www.dropbox.com/s/fve3uen5mzonidx/mLibExternal.zip?dl=0) + + +## Filter2dAnnotations + +Perform some basic image filtering on the raw annotation projections from `ProjectAnnotations`. +Fill in the input paths accordingly in the main file under 'Fill in the paths accordingly here'. + +### Installation +The code was developed under VS2013. + +Requirements: +- NVIDIA CUDA 8.0 +- our research library mLib, a git submodule in ../external/mLib +- mLib external libraries can be downloaded [here](https://www.dropbox.com/s/fve3uen5mzonidx/mLibExternal.zip?dl=0) diff --git a/AnnotationTools/common/Aggregation.cpp b/AnnotationTools/common/Aggregation.cpp new file mode 100644 index 0000000..bffa49a --- /dev/null +++ b/AnnotationTools/common/Aggregation.cpp @@ -0,0 +1,3 @@ +#pragma once +#include "stdafx.h" +#include "Aggregation.h" diff --git a/AnnotationTools/common/Aggregation.h b/AnnotationTools/common/Aggregation.h new file mode 100644 index 0000000..08d0cb8 --- /dev/null +++ b/AnnotationTools/common/Aggregation.h @@ -0,0 +1,132 @@ +#pragma once +#include "json.h" + + +class Aggregation { + friend class Annotations; +public: + Aggregation() {} + Aggregation(const std::string& sceneId, const std::string& appId, + const std::vector>& aggregatedSegments, + const std::vector>& aggregatedSegmentLabels, + const std::vector& objectIds) : + m_sceneId(sceneId), m_appId(appId), + m_aggregatedSegments(aggregatedSegments), + m_aggregatedSegmentLabels(aggregatedSegmentLabels), + m_objectIds(objectIds) {} + ~Aggregation() {} + + bool empty() const { return m_aggregatedSegments.empty(); } + size_t size() const { return m_aggregatedSegments.size(); } + void clear() { + m_sceneId = ""; + m_aggregatedSegments.clear(); + m_aggregatedAnnotationIds.clear(); + m_aggregatedSegmentLabels.clear(); + } + bool empty(unsigned int i) const { return m_aggregatedSegments[i].empty(); } + + std::string getSceneId() const { return m_sceneId; } + const std::vector>& getAggregatedSegments() const { return m_aggregatedSegments; } + const std::vector& getObjectIds() const { return m_objectIds; } + const std::unordered_map& getObjectIdsToLabels() const { return m_objectIdsToLabels; } + const std::vector>& getAggregatedSegmentLabels() const { return m_aggregatedSegmentLabels; } + + std::unordered_map getSegIdToAggregatedSegId() const { + std::unordered_map mapping; + for (unsigned int aggid = 0; aggid < m_aggregatedSegments.size(); aggid++) { + const auto& agg = m_aggregatedSegments[aggid]; + for (unsigned int segid : agg) mapping[segid] = aggid; + } + return mapping; + } + + void setSceneId(const std::string& sceneId) { m_sceneId = sceneId; } + + + void loadFromJSONFile(const std::string& filename) { + if (!util::fileExists(filename)) throw MLIB_EXCEPTION("failed to open file " + filename); + rapidjson::Document aggregationData; + if (!json::parseRapidJSONDocument(filename, &aggregationData)) { + std::cerr << "Parse error reading " << filename << std::endl + << "Error code " << aggregationData.GetParseError() << " at " << aggregationData.GetErrorOffset() << std::endl; + return; + } + //meta-info + m_sceneId = aggregationData["sceneId"].GetString(); + m_appId = aggregationData["appId"].GetString(); + + //segment groups + const auto& segGroups = aggregationData["segGroups"]; + m_aggregatedSegments.resize(segGroups.Size()); + m_aggregatedSegmentLabels.resize(segGroups.Size()); + m_objectIds.resize(segGroups.Size()); + for (unsigned int i = 0; i < segGroups.Size(); i++) { + const auto& group = segGroups[i]; + unsigned int id = getUINT(group["id"]); + std::string label = group["label"].GetString(); + const auto& segs = group["segments"]; + std::vector segments(segs.Size()); + for (unsigned int s = 0; s < segs.Size(); s++) { + segments[s] = getUINT(segs[s]); + }//segment ids (-> segmentation file) + m_aggregatedSegments[i].insert(segments.begin(), segments.end()); + m_aggregatedSegmentLabels[i] = std::vector(1, label); + m_objectIdsToLabels[id] = label; + m_objectIds[i] = id; + } + } + void saveToJSONFile(const std::string& filename, const std::string& segFileSuffix = "_vh_clean_2.0.010000.segs.json") const { + using namespace json; + const bool endlines = true; + + std::ofstream ofs(filename); + if (!ofs.good()) throw MLIB_EXCEPTION("failed to open " + filename + " for writing"); + const std::function sep = put(ofs, ",", endlines); + const auto key = [](const std::string& id) { return "\"" + id + "\": "; }; + ofs << "{"; if (endlines) { ofs << std::endl; } + ofs << key("sceneId"); toJSON(ofs, m_sceneId); sep(); + ofs << key("appId"); toJSON(ofs, m_appId); sep(); + ofs << key("segGroups"); ofs << "["; if (endlines) { ofs << std::endl; } + for (unsigned int i = 0; i < m_aggregatedSegments.size(); i++) { //each aggregated segment + std::vector aggregatedSegments(m_aggregatedSegments[i].begin(), m_aggregatedSegments[i].end()); //convert unordered_set to vector for json + //write + ofs << "\t{"; if (endlines) ofs << std::endl; + ofs << "\t" << key("id"); toJSON(ofs, m_objectIds[i]); sep(); + ofs << "\t" << key("objectId"); toJSON(ofs, i); sep(); + ofs << "\t" << key("segments"); toJSON(ofs, aggregatedSegments); sep(); + ofs << "\t" << key("label"); toJSON(ofs, util::replace(m_aggregatedSegmentLabels[i].front(), "\\", "\\\\")); + if (endlines) ofs << std::endl; + ofs << "\t}"; + if (i + 1 < m_aggregatedSegments.size()) sep(); + } + if (endlines) { ofs << std::endl; } + ofs << "]"; sep(); //end segGroups + ofs << key("segmentsFile"); toJSON(ofs, m_sceneId + segFileSuffix); + ofs << "}"; if (endlines) { ofs << std::endl; } + ofs.close(); + } +private: + template + unsigned int getUINT(const rapidjson::GenericValue& d) const { + unsigned int res = (unsigned int)-1; + if (d.IsInt()) res = (unsigned int)d.GetInt(); + else if (d.IsString()) res = util::convertTo(d.GetString()); + else if (d.IsNull()) return res; //TODO HACK + else throw MLIB_EXCEPTION("invalid json type for uint!"); + return res; + } + + std::string m_sceneId; + std::string m_appId; + + std::vector> m_aggregatedSegments; //vector of segment ids corresponding to an object + std::vector m_objectIds; + + std::vector> m_aggregatedSegmentLabels; //vector of text labels (e.g., "table", "microwave") corresponding to above + + //--not saved out in file below + std::vector> m_aggregatedAnnotationIds; //indexes to std::vector m_annotations; + std::unordered_map m_objectIdsToLabels; +}; + diff --git a/AnnotationTools/common/Segmentation.cpp b/AnnotationTools/common/Segmentation.cpp new file mode 100644 index 0000000..8affcfb --- /dev/null +++ b/AnnotationTools/common/Segmentation.cpp @@ -0,0 +1,15 @@ +#pragma once +#include "stdafx.h" +#include "Segmentation.h" + +Segmentation::Segmentation(const std::vector& ids, const std::string& sceneId /*= ""*/) +{ + clear(); + m_sceneName = sceneId; + m_segmentIds = ids; + for (unsigned int i = 0; i < m_segmentIds.size(); i++) { + auto it = m_segIdsToVertIds.find(m_segmentIds[i]); + if (it == m_segIdsToVertIds.end()) m_segIdsToVertIds[m_segmentIds[i]] = std::vector(1, i); + else it->second.push_back(i); + } +} diff --git a/AnnotationTools/common/Segmentation.h b/AnnotationTools/common/Segmentation.h new file mode 100644 index 0000000..a2e8ced --- /dev/null +++ b/AnnotationTools/common/Segmentation.h @@ -0,0 +1,191 @@ +#pragma once +#include "json.h" + + +struct SegmentationParams { + float kThresh; + unsigned int segMinVerts; + unsigned int minPoints; + unsigned int maxPoints; + float thinThresh; + float flatThresh; + float minLength; + float maxLength; + + SegmentationParams() { + kThresh = 0.0f; + segMinVerts = 0; + minPoints = 0; + maxPoints = 0; + thinThresh = 0.0f; + flatThresh = 0.0f; + minLength = 0.0f; + maxLength = 0.0f; + } + + std::ostream& toJSON(std::ostream& os) const { + os << "{" << std::endl; + os << "\t\"kThresh\": \"" << kThresh << "\"," << std::endl; + os << "\t\"segMinVerts\": \"" << segMinVerts << "\"," << std::endl; + os << "\t\"minPoints\": \"" << minPoints << "\"," << std::endl; + os << "\t\"maxPoints\": \"" << maxPoints << "\"," << std::endl; + os << "\t\"thinThresh\": \"" << thinThresh << "\"," << std::endl; + os << "\t\"flatThresh\": \"" << flatThresh << "\"," << std::endl; + os << "\t\"minLength\": \"" << minLength << "\"," << std::endl; + os << "\t\"maxLength\": \"" << maxLength << "\"" << std::endl; + os << "}" << std::endl; + return os; + } +}; + +class Segmentation { +public: + Segmentation() {} + Segmentation(const std::string& filename) { loadFromFile(filename); } + Segmentation(const std::vector& ids, const std::string& sceneId = ""); + ~Segmentation() {} + + void setSceneId(const std::string& sceneId) { m_sceneName = sceneId; } + void copyParamsFrom(const Segmentation& other) { + m_params = other.m_params; + } + + void loadFromFile(const std::string& filename) + { + if (!ml::util::fileExists(filename)) throw MLIB_EXCEPTION("[parse] failed to open file " + filename); + clear(); + + // Parse JSON document + rapidjson::Document d; + if (!json::parseRapidJSONDocument(filename, &d)) { + std::cerr << "Parse error reading " << filename << std::endl + << "Error code " << d.GetParseError() << " at " << d.GetErrorOffset() << std::endl; + return; + } + + m_sceneName = d["sceneId"].GetString(); + + const auto& segIndices = d["segIndices"]; + m_segmentIds.resize(segIndices.Size()); + for (unsigned int i = 0; i < m_segmentIds.size(); i++) { + m_segmentIds[i] = getUINT(segIndices[i]); + auto it = m_segIdsToVertIds.find(m_segmentIds[i]); + if (it == m_segIdsToVertIds.end()) m_segIdsToVertIds[m_segmentIds[i]] = std::vector(1, i); + else it->second.push_back(i); + } + + if (d.HasMember("params")) { + const auto& params = d["params"]; + m_params.kThresh = params.HasMember("kThresh") ? getFloat(params["kThresh"]) : 0.0f; + m_params.segMinVerts = params.HasMember("segMinVerts") ? getUINT(params["segMinVerts"]) : 0.0f; + m_params.minPoints = params.HasMember("minPoints") ? getUINT(params["minPoints"]) : 0.0f; + m_params.maxPoints = params.HasMember("maxPoints") ? getUINT(params["maxPoints"]) : 0.0f; + m_params.thinThresh = params.HasMember("thinThresh") ? getFloat(params["thinThresh"]) : 0.0f; + m_params.flatThresh = params.HasMember("flatThresh") ? getFloat(params["flatThresh"]) : 0.0f; + m_params.minLength = params.HasMember("minLength") ? getFloat(params["minLength"]) : 0.0f; + m_params.maxLength = params.HasMember("maxLength") ? getFloat(params["maxLength"]) : 0.0f; + } + } + + void saveToFile(const std::string& filename) + { + std::ofstream ofs(filename); + const auto key = [](const std::string& id) { return "\"" + id + "\": "; }; + ofs << "{" << std::endl; + ofs << key("params"); m_params.toJSON(ofs); ofs << "," << std::endl; + ofs << key("sceneId"); ofs << "\"" << m_sceneName << "\"," << std::endl; + ofs << key("segIndices"); ofs << "["; + for (unsigned int i = 0; i < m_segmentIds.size(); i++) { + ofs << m_segmentIds[i]; + if (i + 1 < m_segmentIds.size()) ofs << ","; + } + ofs << "]" << std::endl; + ofs << "}" << std::endl; + ofs.close(); + } + + const std::vector& getSegmentIdsPerVertex() const { return m_segmentIds; } + size_t getNumSegments() const { return m_segIdsToVertIds.size(); } + const std::unordered_map>& getSegmentIdToVertIdMap() const { return m_segIdsToVertIds; } + + bool empty() const { return m_segmentIds.empty(); } + + void computeSurfaceAreaPerSegment(const TriMeshf& triMesh, std::unordered_map& segIdToSurfaceArea) const { + segIdToSurfaceArea.clear(); + std::unordered_map> vertIdsToFaceIds; + for (unsigned int i = 0; i < triMesh.m_indices.size(); i++) { + const auto& ind = triMesh.m_indices[i]; + for (unsigned int k = 0; k < 3; k++) { + auto it = vertIdsToFaceIds.find(ind[k]); + if (it == vertIdsToFaceIds.end()) vertIdsToFaceIds[ind[k]] = std::vector(1, i); + else it->second.push_back(i); + } + } + for (const auto& s : m_segIdsToVertIds) { + std::unordered_map faces; // + for (unsigned int vertid : s.second) { + const auto itf = vertIdsToFaceIds.find(vertid); + MLIB_ASSERT(itf != vertIdsToFaceIds.end()); + for (unsigned int fid : itf->second) { + auto it = faces.find(fid); + if (it == faces.end()) faces[fid] = 1; + else it->second++; + } + } + //compute sa + float segmentSA = 0.0f; + for (const auto& f : faces) { + if (f.second == 3) { + const auto& ind = triMesh.m_indices[f.first]; + Trianglef tri(triMesh.m_vertices[ind.x].position, triMesh.m_vertices[ind.y].position, triMesh.m_vertices[ind.z].position); + segmentSA += tri.getArea(); + } + } + MLIB_ASSERT(segmentSA > 0.0f); + segIdToSurfaceArea[s.first] = segmentSA; + } + } + +private: + void clear() { + m_segmentIds.clear(); + m_sceneName = ""; + m_segIdsToVertIds.clear(); + } + + //TODO WTF IS THIS NECESSARY + template + unsigned int getUINT(const rapidjson::GenericValue& d) const { + unsigned int res = (unsigned int)-1; + if (d.IsInt()) res = (unsigned int)d.GetInt(); + else if (d.IsUint()) res = d.GetUint(); + else if (d.IsString()) res = util::convertTo(d.GetString()); + else if (d.IsNull()) return res; //TODO HACK + else { + auto t = d.GetType(); + const bool b0 = d.IsDouble(); + const bool b1 = d.IsInt(); + const bool b2 = d.IsInt64(); + const bool b3 = d.IsUint(); + const bool b4 = d.IsUint64(); + throw MLIB_EXCEPTION("invalid json type for uint!"); + } + return res; + } + template + float getFloat(const rapidjson::GenericValue& d) const { + float res = -std::numeric_limits::infinity(); + if (d.IsDouble()) res = (float)d.GetDouble(); + else if (d.IsInt()) res = (float)d.GetInt(); + else if (d.IsString()) res = util::convertTo(d.GetString()); + else throw MLIB_EXCEPTION("invalid json type for float!"); + return res; + } + + std::vector m_segmentIds; //correspond to vertices (indexed by vertex id) + std::string m_sceneName; + + std::unordered_map> m_segIdsToVertIds; + + SegmentationParams m_params; +}; diff --git a/AnnotationTools/common/json.cpp b/AnnotationTools/common/json.cpp new file mode 100644 index 0000000..36e114a --- /dev/null +++ b/AnnotationTools/common/json.cpp @@ -0,0 +1,63 @@ +#include "stdafx.h" + +#include "json.h" + +#include + +//#include "io/io.h" + +namespace json { + +//! Wrapper around istream for parsing with rapidjson +class istreamwrapper { + public: + typedef char Ch; + istreamwrapper(std::istream& is) : is_(is) { } // NOLINT + Ch Peek() const { + int c = is_.peek(); + return c == std::char_traits::eof() ? '\0' : (Ch)c; + } + Ch Take() { + int c = is_.get(); + return c == std::char_traits::eof() ? '\0' : (Ch)c; + } + size_t Tell() const { return (size_t)is_.tellg(); } + Ch* PutBegin() { return 0; } + void Put(Ch) { } + void Flush() { } + size_t PutEnd(Ch* c) { return 0; } + private: + istreamwrapper(const istreamwrapper&); + istreamwrapper& operator=(const istreamwrapper&); + std::istream& is_; +}; + +bool parseRapidJSONDocument(const std::string& file, rapidjson::Document* d) { + FILE* pFile = fopen(file.c_str(), "rb"); + char buffer[65536]; + rapidjson::FileReadStream is(pFile, buffer, sizeof(buffer)); + d->ParseStream<0, rapidjson::UTF8<>, rapidjson::FileReadStream>(is); + fclose(pFile); + + if (d->HasParseError()) { + std::cerr << "Parse error reading " << file << std::endl + << "Error code " << d->GetParseError() << " at " << d->GetErrorOffset() << std::endl; + return false; + } else { + return true; + } +} + +bool parseRapidJSONString(const std::string& jsonString, rapidjson::Document* d) { + d->Parse(jsonString.c_str()); + + if (d->HasParseError()) { + std::cerr << "Parse error parsing json string " << std::endl + << "Error code " << d->GetParseError() << " at " << d->GetErrorOffset() << std::endl; + return false; + } else { + return true; + } +} + +} // namespace json diff --git a/AnnotationTools/common/json.h b/AnnotationTools/common/json.h new file mode 100644 index 0000000..2cedaa4 --- /dev/null +++ b/AnnotationTools/common/json.h @@ -0,0 +1,158 @@ +#pragma once + +#include + +#define RAPIDJSON_NO_INT64DEFINE +#include +#include + + +//#include "io/io.h" + +namespace json { + +//! Parse JSON file into rapidjson Document object d and return whether successful +bool parseRapidJSONDocument(const std::string& file, rapidjson::Document* d); + +//! Parse JSON string into rapidjson Document object d and return whether successful +bool parseRapidJSONString(const std::string& jsonString, rapidjson::Document* d); + +template +void toVector(const GV& arr, std::vector* vec, + const std::function& conv) { + const unsigned n = arr.Size(); + vec->resize(n); + for (unsigned i = 0; i < n; i++) { + (*vec)[i] = conv(arr[i]); + } +} + +template +void toIntVector(const GV& value, std::vector* vec) { + const auto conv = [](const GV& x) { + return x.GetInt(); + }; + toVector(value, vec, conv); +} + +template +void toFloatVector(const GV& value, std::vector* vec) { + const auto conv = [](const GV& x) { + return static_cast(x.GetDouble()); + }; + toVector(value, vec, conv); +} + +template +void toDoubleVector(const GV& value, std::vector* vec) { + const auto conv = [](const GV& x) { + return x.GetDouble(); + }; + toVector(value, vec, conv); +} + +////! Generic toJSON function to output array-like types (should work for any type +////! on which std::begin and std::end can work. Recurses down to basic types which +////! are then streamed out with regular call to operator<< +//template +//std::ostream& toJSON(std::ostream& os, const T& x) { +// const bool isFundamental = !std::is_arr::value; +// if (isFundamental) { +// return os << x; +// } +// +// const auto start = std::begin(x); +// const auto end = std::end(x) - 1; +// os << "["; +// for (auto it = start; it != end; it++) { +// toJSON(os, *it); os << ","; +// } +// toJSON(os, *end); os << "]"; +// +// return os; +//} + +template +std::ostream& toJSON(std::ostream& os, const T* x, size_t size) { + os << "["; + if (size == 0) { return os << "]"; } + const size_t iLast = size - 1; + for (size_t i = 0; i < iLast; i++) { + toJSON(os, x[i]) << ","; + } + return toJSON(os, x[iLast]) << "]"; +} + +template +std::ostream& toJSON(std::ostream& os, const std::vector& x) { + os << "["; + if (x.empty()) { return os << "]"; } + const size_t iLast = x.size() - 1; + for (size_t i = 0; i < iLast; i++) { + toJSON(os, x[i]) << ","; + } + return toJSON(os, x[iLast]) << "]"; +} + +template +std::ostream& toJSON(std::ostream& os, const std::vector& x, const std::function extractFun) { + os << "["; + if (x.empty()) { return os << "]"; } + const size_t iLast = x.size() - 1; + for (size_t i = 0; i < iLast; i++) { + toJSON(os, extractFun(x[i])) << ","; + } + return toJSON(os, extractFun(x[iLast])) << "]"; +} + +template +std::ostream& toJSON(std::ostream& os, const std::pair& p) { + os << "["; + toJSON(os, p.first); + os << ","; + toJSON(os, p.second); + os << "]"; + return os; +} + +inline std::ostream& toJSON(std::ostream& os, const ml::vec2f& x) { + return os << "[" << x[0] << "," << x[1] << "]"; +} + +inline std::ostream& toJSON(std::ostream& os, const ml::vec3f& x) { + return os << "[" << x[0] << "," << x[1] << "," << x[2] << "]"; +} + +inline std::ostream& toJSON(std::ostream& os, const ml::vec4f& x) { + return os << "[" << x[0] << "," << x[1] << "," << x[2] << "," << x[3] << "]"; +} + +inline std::ostream& toJSON(std::ostream& os, const ml::mat4f& m) { + os << "["; + for (int i = 0; i < 15; i++) { os << m[i] << ","; } + return os << m[15] << "]"; +} + +template +inline std::ostream& toJSON(std::ostream& os, const T& x) { + return os << x; +} + +//! Quotes string TODO(MS): Escape any quotes inside string +inline std::ostream& toJSON(std::ostream& os, const std::string& x) { + return os << "\"" << x << "\""; +} + +//! Return a function that outputs string s and optionally endline into ostream os on every call +inline std::function put(std::ostream& os, const std::string& s, bool endlines = false) { + return ([&os, s, endlines]() { + os << s; + if (endlines) { + os << std::endl; + } + }); +} + +} // namespace json + + diff --git a/BenchmarkScripts/2d_evaluation/__init__.py b/BenchmarkScripts/2d_evaluation/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/BenchmarkScripts/2d_evaluation/addToConfusionMatrix.c b/BenchmarkScripts/2d_evaluation/addToConfusionMatrix.c new file mode 100644 index 0000000..07a1585 --- /dev/null +++ b/BenchmarkScripts/2d_evaluation/addToConfusionMatrix.c @@ -0,0 +1,6780 @@ +/* Generated by Cython 0.24.1 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "depends": [ + "cityscapesscripts/evaluation/addToConfusionMatrix_impl.c" + ] + }, + "module_name": "cityscapesscripts.evaluation.addToConfusionMatrix" +} +END: Cython Metadata */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000) + #error Cython requires Python 2.6+ or Python 3.2+. +#else +#define CYTHON_ABI "0_24_1" +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#ifdef PYPY_VERSION + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 +#endif +#if !defined(CYTHON_USE_PYLONG_INTERNALS) && CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070000 + #define CYTHON_USE_PYLONG_INTERNALS 1 +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #include "longintrepr.h" + #undef SHIFT + #undef BASE + #undef MASK +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #define Py_OptimizeFlag 0 +#endif +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyClass_Type +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyType_Type +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) +#else + #define CYTHON_PEP393_ENABLED 0 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) +#endif +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t PyInt_AsLong +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func)) +#else + #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) +#endif +#if PY_VERSION_HEX >= 0x030500B1 +#define __Pyx_PyAsyncMethodsStruct PyAsyncMethods +#define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) +#elif CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 +typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; +} __Pyx_PyAsyncMethodsStruct; +#define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) +#else +#define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) + +#ifndef CYTHON_INLINE + #if defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +#if defined(WIN32) || defined(MS_WINDOWS) + #define _USE_MATH_DEFINES +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + + +#define __PYX_ERR(f_index, lineno, Ln_error) \ +{ \ + __pyx_filename = __pyx_f[f_index]; __pyx_lineno = lineno; __pyx_clineno = __LINE__; goto Ln_error; \ +} + +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__cityscapesscripts__evaluation__addToConfusionMatrix +#define __PYX_HAVE_API__cityscapesscripts__evaluation__addToConfusionMatrix +#include "string.h" +#include "stdio.h" +#include "stdlib.h" +#include "numpy/arrayobject.h" +#include "numpy/ufuncobject.h" +#include "addToConfusionMatrix_impl.c" +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#ifdef PYREX_WITHOUT_ASSERTIONS +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0 +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) && defined (_M_X64) + #define __Pyx_sst_abs(value) _abs64(value) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#if PY_MAJOR_VERSION < 3 +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) +{ + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#else +#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen +#endif +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +#define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False)) +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +#if CYTHON_COMPILING_IN_CPYTHON +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ + +static PyObject *__pyx_m; +static PyObject *__pyx_d; +static PyObject *__pyx_b; +static PyObject *__pyx_empty_tuple; +static PyObject *__pyx_empty_bytes; +static PyObject *__pyx_empty_unicode; +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm= __FILE__; +static const char *__pyx_filename; + +/* None.proto */ +#if !defined(CYTHON_CCOMPLEX) + #if defined(__cplusplus) + #define CYTHON_CCOMPLEX 1 + #elif defined(_Complex_I) + #define CYTHON_CCOMPLEX 1 + #else + #define CYTHON_CCOMPLEX 0 + #endif +#endif +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #include + #else + #include + #endif +#endif +#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) + #undef _Complex_I + #define _Complex_I 1.0fj +#endif + + +static const char *__pyx_f[] = { + "cityscapesscripts/evaluation/addToConfusionMatrix.pyx", + "__init__.pxd", + "type.pxd", +}; +/* BufferFormatStructs.proto */ +#define IS_UNSIGNED(type) (((type) -1) > 0) +struct __Pyx_StructField_; +#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0) +typedef struct { + const char* name; + struct __Pyx_StructField_* fields; + size_t size; + size_t arraysize[8]; + int ndim; + char typegroup; + char is_unsigned; + int flags; +} __Pyx_TypeInfo; +typedef struct __Pyx_StructField_ { + __Pyx_TypeInfo* type; + const char* name; + size_t offset; +} __Pyx_StructField; +typedef struct { + __Pyx_StructField* field; + size_t parent_offset; +} __Pyx_BufFmt_StackElem; +typedef struct { + __Pyx_StructField root; + __Pyx_BufFmt_StackElem* head; + size_t fmt_offset; + size_t new_count, enc_count; + size_t struct_alignment; + int is_complex; + char enc_type; + char new_packmode; + char enc_packmode; + char is_valid_array; +} __Pyx_BufFmt_Context; + + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725 + * # in Cython to enable them only on the right systems. + * + * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t + */ +typedef npy_int8 __pyx_t_5numpy_int8_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726 + * + * ctypedef npy_int8 int8_t + * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< + * ctypedef npy_int32 int32_t + * ctypedef npy_int64 int64_t + */ +typedef npy_int16 __pyx_t_5numpy_int16_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":727 + * ctypedef npy_int8 int8_t + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< + * ctypedef npy_int64 int64_t + * #ctypedef npy_int96 int96_t + */ +typedef npy_int32 __pyx_t_5numpy_int32_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":728 + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t + * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< + * #ctypedef npy_int96 int96_t + * #ctypedef npy_int128 int128_t + */ +typedef npy_int64 __pyx_t_5numpy_int64_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732 + * #ctypedef npy_int128 int128_t + * + * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t + */ +typedef npy_uint8 __pyx_t_5numpy_uint8_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733 + * + * ctypedef npy_uint8 uint8_t + * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< + * ctypedef npy_uint32 uint32_t + * ctypedef npy_uint64 uint64_t + */ +typedef npy_uint16 __pyx_t_5numpy_uint16_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":734 + * ctypedef npy_uint8 uint8_t + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< + * ctypedef npy_uint64 uint64_t + * #ctypedef npy_uint96 uint96_t + */ +typedef npy_uint32 __pyx_t_5numpy_uint32_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":735 + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t + * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< + * #ctypedef npy_uint96 uint96_t + * #ctypedef npy_uint128 uint128_t + */ +typedef npy_uint64 __pyx_t_5numpy_uint64_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":739 + * #ctypedef npy_uint128 uint128_t + * + * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< + * ctypedef npy_float64 float64_t + * #ctypedef npy_float80 float80_t + */ +typedef npy_float32 __pyx_t_5numpy_float32_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":740 + * + * ctypedef npy_float32 float32_t + * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< + * #ctypedef npy_float80 float80_t + * #ctypedef npy_float128 float128_t + */ +typedef npy_float64 __pyx_t_5numpy_float64_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749 + * # The int types are mapped a bit surprising -- + * # numpy.int corresponds to 'l' and numpy.long to 'q' + * ctypedef npy_long int_t # <<<<<<<<<<<<<< + * ctypedef npy_longlong long_t + * ctypedef npy_longlong longlong_t + */ +typedef npy_long __pyx_t_5numpy_int_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":750 + * # numpy.int corresponds to 'l' and numpy.long to 'q' + * ctypedef npy_long int_t + * ctypedef npy_longlong long_t # <<<<<<<<<<<<<< + * ctypedef npy_longlong longlong_t + * + */ +typedef npy_longlong __pyx_t_5numpy_long_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751 + * ctypedef npy_long int_t + * ctypedef npy_longlong long_t + * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< + * + * ctypedef npy_ulong uint_t + */ +typedef npy_longlong __pyx_t_5numpy_longlong_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753 + * ctypedef npy_longlong longlong_t + * + * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<< + * ctypedef npy_ulonglong ulong_t + * ctypedef npy_ulonglong ulonglong_t + */ +typedef npy_ulong __pyx_t_5numpy_uint_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":754 + * + * ctypedef npy_ulong uint_t + * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<< + * ctypedef npy_ulonglong ulonglong_t + * + */ +typedef npy_ulonglong __pyx_t_5numpy_ulong_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755 + * ctypedef npy_ulong uint_t + * ctypedef npy_ulonglong ulong_t + * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< + * + * ctypedef npy_intp intp_t + */ +typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":757 + * ctypedef npy_ulonglong ulonglong_t + * + * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< + * ctypedef npy_uintp uintp_t + * + */ +typedef npy_intp __pyx_t_5numpy_intp_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758 + * + * ctypedef npy_intp intp_t + * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< + * + * ctypedef npy_double float_t + */ +typedef npy_uintp __pyx_t_5numpy_uintp_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760 + * ctypedef npy_uintp uintp_t + * + * ctypedef npy_double float_t # <<<<<<<<<<<<<< + * ctypedef npy_double double_t + * ctypedef npy_longdouble longdouble_t + */ +typedef npy_double __pyx_t_5numpy_float_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":761 + * + * ctypedef npy_double float_t + * ctypedef npy_double double_t # <<<<<<<<<<<<<< + * ctypedef npy_longdouble longdouble_t + * + */ +typedef npy_double __pyx_t_5numpy_double_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762 + * ctypedef npy_double float_t + * ctypedef npy_double double_t + * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< + * + * ctypedef npy_cfloat cfloat_t + */ +typedef npy_longdouble __pyx_t_5numpy_longdouble_t; +/* None.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + typedef ::std::complex< float > __pyx_t_float_complex; + #else + typedef float _Complex __pyx_t_float_complex; + #endif +#else + typedef struct { float real, imag; } __pyx_t_float_complex; +#endif + +/* None.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + typedef ::std::complex< double > __pyx_t_double_complex; + #else + typedef double _Complex __pyx_t_double_complex; + #endif +#else + typedef struct { double real, imag; } __pyx_t_double_complex; +#endif + + +/*--- Type declarations ---*/ + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764 + * ctypedef npy_longdouble longdouble_t + * + * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<< + * ctypedef npy_cdouble cdouble_t + * ctypedef npy_clongdouble clongdouble_t + */ +typedef npy_cfloat __pyx_t_5numpy_cfloat_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":765 + * + * ctypedef npy_cfloat cfloat_t + * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<< + * ctypedef npy_clongdouble clongdouble_t + * + */ +typedef npy_cdouble __pyx_t_5numpy_cdouble_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766 + * ctypedef npy_cfloat cfloat_t + * ctypedef npy_cdouble cdouble_t + * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<< + * + * ctypedef npy_cdouble complex_t + */ +typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t; + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768 + * ctypedef npy_clongdouble clongdouble_t + * + * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew1(a): + */ +typedef npy_cdouble __pyx_t_5numpy_complex_t; + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, int); + void (*DECREF)(void*, PyObject*, int); + void (*GOTREF)(void*, PyObject*, int); + void (*GIVEREF)(void*, PyObject*, int); + void* (*SetupContext)(const char*, int, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) +#endif + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* PyThreadStateGet.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = PyThreadState_GET(); +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ + const char* function_name); + +/* ArgTypeTest.proto */ +static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, + const char *name, int exact); + +/* BufferFormatCheck.proto */ +static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj, + __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts); +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type); // PROTO + +/* GetModuleGlobalName.proto */ +static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* ExtTypeTest.proto */ +static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); + +/* BufferFallbackError.proto */ +static void __Pyx_RaiseBufferFallbackError(void); + +#define __Pyx_BufPtrCContig2d(type, buf, i0, s0, i1, s1) ((type)((char*)buf + i0 * s0) + i1) +/* PyObjectCallMethO.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* DictGetItem.proto */ +#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY +static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { + PyObject *value; + value = PyDict_GetItemWithError(d, key); + if (unlikely(!value)) { + if (!PyErr_Occurred()) { + PyObject* args = PyTuple_Pack(1, key); + if (likely(args)) + PyErr_SetObject(PyExc_KeyError, args); + Py_XDECREF(args); + } + return NULL; + } + Py_INCREF(value); + return value; +} +#else + #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) +#endif + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* RaiseNoneIterError.proto */ +static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* CodeObjectCache.proto */ +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* BufferStructDeclare.proto */ +typedef struct { + Py_ssize_t shape, strides, suboffsets; +} __Pyx_Buf_DimInfo; +typedef struct { + size_t refcount; + Py_buffer pybuffer; +} __Pyx_Buffer; +typedef struct { + __Pyx_Buffer *rcbuffer; + char *data; + __Pyx_Buf_DimInfo diminfo[8]; +} __Pyx_LocalBuf_ND; + +#if PY_MAJOR_VERSION < 3 + static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); + static void __Pyx_ReleaseBuffer(Py_buffer *view); +#else + #define __Pyx_GetBuffer PyObject_GetBuffer + #define __Pyx_ReleaseBuffer PyBuffer_Release +#endif + + +/* None.proto */ +static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0}; +static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1}; + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_PY_LONG_LONG(unsigned PY_LONG_LONG value); + +/* None.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #define __Pyx_CREAL(z) ((z).real()) + #define __Pyx_CIMAG(z) ((z).imag()) + #else + #define __Pyx_CREAL(z) (__real__(z)) + #define __Pyx_CIMAG(z) (__imag__(z)) + #endif +#else + #define __Pyx_CREAL(z) ((z).real) + #define __Pyx_CIMAG(z) ((z).imag) +#endif +#if defined(__cplusplus) && CYTHON_CCOMPLEX && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) + #define __Pyx_SET_CREAL(z,x) ((z).real(x)) + #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) +#else + #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) + #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) +#endif + +/* None.proto */ +static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float); + +/* None.proto */ +#if CYTHON_CCOMPLEX + #define __Pyx_c_eqf(a, b) ((a)==(b)) + #define __Pyx_c_sumf(a, b) ((a)+(b)) + #define __Pyx_c_difff(a, b) ((a)-(b)) + #define __Pyx_c_prodf(a, b) ((a)*(b)) + #define __Pyx_c_quotf(a, b) ((a)/(b)) + #define __Pyx_c_negf(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zerof(z) ((z)==(float)0) + #define __Pyx_c_conjf(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_absf(z) (::std::abs(z)) + #define __Pyx_c_powf(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zerof(z) ((z)==0) + #define __Pyx_c_conjf(z) (conjf(z)) + #if 1 + #define __Pyx_c_absf(z) (cabsf(z)) + #define __Pyx_c_powf(a, b) (cpowf(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex); + static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex); + #if 1 + static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex); + #endif +#endif + +/* None.proto */ +static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); + +/* None.proto */ +#if CYTHON_CCOMPLEX + #define __Pyx_c_eq(a, b) ((a)==(b)) + #define __Pyx_c_sum(a, b) ((a)+(b)) + #define __Pyx_c_diff(a, b) ((a)-(b)) + #define __Pyx_c_prod(a, b) ((a)*(b)) + #define __Pyx_c_quot(a, b) ((a)/(b)) + #define __Pyx_c_neg(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zero(z) ((z)==(double)0) + #define __Pyx_c_conj(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_abs(z) (::std::abs(z)) + #define __Pyx_c_pow(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zero(z) ((z)==0) + #define __Pyx_c_conj(z) (conj(z)) + #if 1 + #define __Pyx_c_abs(z) (cabs(z)) + #define __Pyx_c_pow(a, b) (cpow(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex); + static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex); + #if 1 + static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex); + #endif +#endif + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(void); + +/* PyIdentifierFromString.proto */ +#if !defined(__Pyx_PyIdentifier_FromString) +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s) +#else + #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s) +#endif +#endif + +/* ModuleImport.proto */ +static PyObject *__Pyx_ImportModule(const char *name); + +/* TypeImport.proto */ +static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + + +/* Module declarations from 'cython' */ + +/* Module declarations from 'cpython.buffer' */ + +/* Module declarations from 'libc.string' */ + +/* Module declarations from 'libc.stdio' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.type' */ +static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; + +/* Module declarations from 'cpython' */ + +/* Module declarations from 'cpython.object' */ + +/* Module declarations from 'cpython.ref' */ + +/* Module declarations from 'libc.stdlib' */ + +/* Module declarations from 'numpy' */ + +/* Module declarations from 'numpy' */ +static PyTypeObject *__pyx_ptype_5numpy_dtype = 0; +static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0; +static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0; +static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0; +static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0; +static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/ + +/* Module declarations from 'cityscapesscripts.evaluation.addToConfusionMatrix' */ +static PyObject *__pyx_f_17cityscapesscripts_10evaluation_20addToConfusionMatrix_tonumpyarray(unsigned PY_LONG_LONG *, unsigned PY_LONG_LONG); /*proto*/ +static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_uint8_t = { "uint8_t", NULL, sizeof(__pyx_t_5numpy_uint8_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_uint8_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_uint8_t), 0 }; +static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t = { "uint64_t", NULL, sizeof(__pyx_t_5numpy_uint64_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_uint64_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_uint64_t), 0 }; +static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_ulonglong_t = { "ulonglong_t", NULL, sizeof(__pyx_t_5numpy_ulonglong_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_ulonglong_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_ulonglong_t), 0 }; +#define __Pyx_MODULE_NAME "cityscapesscripts.evaluation.addToConfusionMatrix" +int __pyx_module_is_main_cityscapesscripts__evaluation__addToConfusionMatrix = 0; + +/* Implementation of 'cityscapesscripts.evaluation.addToConfusionMatrix' */ +static PyObject *__pyx_builtin_ValueError; +static PyObject *__pyx_builtin_range; +static PyObject *__pyx_builtin_RuntimeError; +static const char __pyx_k_np[] = "np"; +static const char __pyx_k_copy[] = "copy"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_dtype[] = "dtype"; +static const char __pyx_k_numpy[] = "numpy"; +static const char __pyx_k_range[] = "range"; +static const char __pyx_k_uint8[] = "uint8"; +static const char __pyx_k_ctypes[] = "ctypes"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_width_ui[] = "width_ui"; +static const char __pyx_k_height_ui[] = "height_ui"; +static const char __pyx_k_ulonglong[] = "ulonglong"; +static const char __pyx_k_ValueError[] = "ValueError"; +static const char __pyx_k_confMatrix[] = "confMatrix"; +static const char __pyx_k_evalLabels[] = "evalLabels"; +static const char __pyx_k_RuntimeError[] = "RuntimeError"; +static const char __pyx_k_confMatrix_c[] = "confMatrix_c"; +static const char __pyx_k_cEvaluatePair[] = "cEvaluatePair"; +static const char __pyx_k_confMatDim_ui[] = "confMatDim_ui"; +static const char __pyx_k_predictionArr[] = "predictionArr"; +static const char __pyx_k_groundTruthArr[] = "groundTruthArr"; +static const char __pyx_k_predictionArr_c[] = "predictionArr_c"; +static const char __pyx_k_groundTruthArr_c[] = "groundTruthArr_c"; +static const char __pyx_k_ascontiguousarray[] = "ascontiguousarray"; +static const char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous"; +static const char __pyx_k_hd_data_cityscapes_cityscapesSc[] = "/hd-data/cityscapes/cityscapesScripts/cityscapesscripts/evaluation/addToConfusionMatrix.pyx"; +static const char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)"; +static const char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd"; +static const char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported"; +static const char __pyx_k_cityscapesscripts_evaluation_add[] = "cityscapesscripts.evaluation.addToConfusionMatrix"; +static const char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous"; +static const char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short."; +static PyObject *__pyx_kp_u_Format_string_allocated_too_shor; +static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2; +static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor; +static PyObject *__pyx_n_s_RuntimeError; +static PyObject *__pyx_n_s_ValueError; +static PyObject *__pyx_n_s_ascontiguousarray; +static PyObject *__pyx_n_s_cEvaluatePair; +static PyObject *__pyx_n_s_cityscapesscripts_evaluation_add; +static PyObject *__pyx_n_s_confMatDim_ui; +static PyObject *__pyx_n_s_confMatrix; +static PyObject *__pyx_n_s_confMatrix_c; +static PyObject *__pyx_n_s_copy; +static PyObject *__pyx_n_s_ctypes; +static PyObject *__pyx_n_s_dtype; +static PyObject *__pyx_n_s_evalLabels; +static PyObject *__pyx_n_s_groundTruthArr; +static PyObject *__pyx_n_s_groundTruthArr_c; +static PyObject *__pyx_kp_s_hd_data_cityscapes_cityscapesSc; +static PyObject *__pyx_n_s_height_ui; +static PyObject *__pyx_n_s_import; +static PyObject *__pyx_n_s_main; +static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous; +static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou; +static PyObject *__pyx_n_s_np; +static PyObject *__pyx_n_s_numpy; +static PyObject *__pyx_n_s_predictionArr; +static PyObject *__pyx_n_s_predictionArr_c; +static PyObject *__pyx_n_s_range; +static PyObject *__pyx_n_s_test; +static PyObject *__pyx_n_s_uint8; +static PyObject *__pyx_n_s_ulonglong; +static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd; +static PyObject *__pyx_n_s_width_ui; +static PyObject *__pyx_pf_17cityscapesscripts_10evaluation_20addToConfusionMatrix_cEvaluatePair(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_predictionArr, PyArrayObject *__pyx_v_groundTruthArr, PyArrayObject *__pyx_v_confMatrix, CYTHON_UNUSED PyObject *__pyx_v_evalLabels); /* proto */ +static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ +static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */ +static PyObject *__pyx_tuple_; +static PyObject *__pyx_tuple__2; +static PyObject *__pyx_tuple__3; +static PyObject *__pyx_tuple__4; +static PyObject *__pyx_tuple__5; +static PyObject *__pyx_tuple__6; +static PyObject *__pyx_tuple__7; +static PyObject *__pyx_codeobj__8; + +/* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":19 + * + * + * cdef tonumpyarray(unsigned long long* data, unsigned long long size): # <<<<<<<<<<<<<< + * if not (data and size >= 0): raise ValueError + * return np.PyArray_SimpleNewFromData(2, [size, size], np.NPY_UINT64, data) + */ + +static PyObject *__pyx_f_17cityscapesscripts_10evaluation_20addToConfusionMatrix_tonumpyarray(unsigned PY_LONG_LONG *__pyx_v_data, unsigned PY_LONG_LONG __pyx_v_size) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + npy_intp __pyx_t_3[2]; + PyObject *__pyx_t_4 = NULL; + __Pyx_RefNannySetupContext("tonumpyarray", 0); + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":20 + * + * cdef tonumpyarray(unsigned long long* data, unsigned long long size): + * if not (data and size >= 0): raise ValueError # <<<<<<<<<<<<<< + * return np.PyArray_SimpleNewFromData(2, [size, size], np.NPY_UINT64, data) + * + */ + __pyx_t_2 = (__pyx_v_data != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_2 = ((__pyx_v_size >= 0) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L4_bool_binop_done:; + __pyx_t_2 = ((!__pyx_t_1) != 0); + if (__pyx_t_2) { + __Pyx_Raise(__pyx_builtin_ValueError, 0, 0, 0); + __PYX_ERR(0, 20, __pyx_L1_error) + } + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":21 + * cdef tonumpyarray(unsigned long long* data, unsigned long long size): + * if not (data and size >= 0): raise ValueError + * return np.PyArray_SimpleNewFromData(2, [size, size], np.NPY_UINT64, data) # <<<<<<<<<<<<<< + * + * @cython.boundscheck(False) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3[0] = __pyx_v_size; + __pyx_t_3[1] = __pyx_v_size; + __pyx_t_4 = PyArray_SimpleNewFromData(2, __pyx_t_3, NPY_UINT64, ((void *)__pyx_v_data)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":19 + * + * + * cdef tonumpyarray(unsigned long long* data, unsigned long long size): # <<<<<<<<<<<<<< + * if not (data and size >= 0): raise ValueError + * return np.PyArray_SimpleNewFromData(2, [size, size], np.NPY_UINT64, data) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("cityscapesscripts.evaluation.addToConfusionMatrix.tonumpyarray", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":24 + * + * @cython.boundscheck(False) + * def cEvaluatePair( np.ndarray[np.uint8_t , ndim=2] predictionArr , # <<<<<<<<<<<<<< + * np.ndarray[np.uint8_t , ndim=2] groundTruthArr , + * np.ndarray[np.uint64_t, ndim=2] confMatrix , + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_17cityscapesscripts_10evaluation_20addToConfusionMatrix_1cEvaluatePair(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_17cityscapesscripts_10evaluation_20addToConfusionMatrix_1cEvaluatePair = {"cEvaluatePair", (PyCFunction)__pyx_pw_17cityscapesscripts_10evaluation_20addToConfusionMatrix_1cEvaluatePair, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_17cityscapesscripts_10evaluation_20addToConfusionMatrix_1cEvaluatePair(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_predictionArr = 0; + PyArrayObject *__pyx_v_groundTruthArr = 0; + PyArrayObject *__pyx_v_confMatrix = 0; + CYTHON_UNUSED PyObject *__pyx_v_evalLabels = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("cEvaluatePair (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_predictionArr,&__pyx_n_s_groundTruthArr,&__pyx_n_s_confMatrix,&__pyx_n_s_evalLabels,0}; + PyObject* values[4] = {0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_predictionArr)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_groundTruthArr)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("cEvaluatePair", 1, 4, 4, 1); __PYX_ERR(0, 24, __pyx_L3_error) + } + case 2: + if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_confMatrix)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("cEvaluatePair", 1, 4, 4, 2); __PYX_ERR(0, 24, __pyx_L3_error) + } + case 3: + if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_evalLabels)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("cEvaluatePair", 1, 4, 4, 3); __PYX_ERR(0, 24, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "cEvaluatePair") < 0)) __PYX_ERR(0, 24, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 4) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + } + __pyx_v_predictionArr = ((PyArrayObject *)values[0]); + __pyx_v_groundTruthArr = ((PyArrayObject *)values[1]); + __pyx_v_confMatrix = ((PyArrayObject *)values[2]); + __pyx_v_evalLabels = values[3]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("cEvaluatePair", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 24, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("cityscapesscripts.evaluation.addToConfusionMatrix.cEvaluatePair", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_predictionArr), __pyx_ptype_5numpy_ndarray, 1, "predictionArr", 0))) __PYX_ERR(0, 24, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_groundTruthArr), __pyx_ptype_5numpy_ndarray, 1, "groundTruthArr", 0))) __PYX_ERR(0, 25, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_confMatrix), __pyx_ptype_5numpy_ndarray, 1, "confMatrix", 0))) __PYX_ERR(0, 26, __pyx_L1_error) + __pyx_r = __pyx_pf_17cityscapesscripts_10evaluation_20addToConfusionMatrix_cEvaluatePair(__pyx_self, __pyx_v_predictionArr, __pyx_v_groundTruthArr, __pyx_v_confMatrix, __pyx_v_evalLabels); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_17cityscapesscripts_10evaluation_20addToConfusionMatrix_cEvaluatePair(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_predictionArr, PyArrayObject *__pyx_v_groundTruthArr, PyArrayObject *__pyx_v_confMatrix, CYTHON_UNUSED PyObject *__pyx_v_evalLabels) { + PyArrayObject *__pyx_v_predictionArr_c = 0; + PyArrayObject *__pyx_v_groundTruthArr_c = 0; + PyArrayObject *__pyx_v_confMatrix_c = 0; + __pyx_t_5numpy_uint32_t __pyx_v_height_ui; + __pyx_t_5numpy_uint32_t __pyx_v_width_ui; + __pyx_t_5numpy_uint32_t __pyx_v_confMatDim_ui; + __Pyx_LocalBuf_ND __pyx_pybuffernd_confMatrix; + __Pyx_Buffer __pyx_pybuffer_confMatrix; + __Pyx_LocalBuf_ND __pyx_pybuffernd_confMatrix_c; + __Pyx_Buffer __pyx_pybuffer_confMatrix_c; + __Pyx_LocalBuf_ND __pyx_pybuffernd_groundTruthArr; + __Pyx_Buffer __pyx_pybuffer_groundTruthArr; + __Pyx_LocalBuf_ND __pyx_pybuffernd_groundTruthArr_c; + __Pyx_Buffer __pyx_pybuffer_groundTruthArr_c; + __Pyx_LocalBuf_ND __pyx_pybuffernd_predictionArr; + __Pyx_Buffer __pyx_pybuffer_predictionArr; + __Pyx_LocalBuf_ND __pyx_pybuffernd_predictionArr_c; + __Pyx_Buffer __pyx_pybuffer_predictionArr_c; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyArrayObject *__pyx_t_6 = NULL; + int __pyx_t_7; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyArrayObject *__pyx_t_11 = NULL; + PyArrayObject *__pyx_t_12 = NULL; + Py_ssize_t __pyx_t_13; + Py_ssize_t __pyx_t_14; + Py_ssize_t __pyx_t_15; + Py_ssize_t __pyx_t_16; + Py_ssize_t __pyx_t_17; + Py_ssize_t __pyx_t_18; + Py_ssize_t __pyx_t_19; + Py_ssize_t __pyx_t_20; + PyArrayObject *__pyx_t_21 = NULL; + __Pyx_RefNannySetupContext("cEvaluatePair", 0); + __Pyx_INCREF((PyObject *)__pyx_v_confMatrix); + __pyx_pybuffer_predictionArr_c.pybuffer.buf = NULL; + __pyx_pybuffer_predictionArr_c.refcount = 0; + __pyx_pybuffernd_predictionArr_c.data = NULL; + __pyx_pybuffernd_predictionArr_c.rcbuffer = &__pyx_pybuffer_predictionArr_c; + __pyx_pybuffer_groundTruthArr_c.pybuffer.buf = NULL; + __pyx_pybuffer_groundTruthArr_c.refcount = 0; + __pyx_pybuffernd_groundTruthArr_c.data = NULL; + __pyx_pybuffernd_groundTruthArr_c.rcbuffer = &__pyx_pybuffer_groundTruthArr_c; + __pyx_pybuffer_confMatrix_c.pybuffer.buf = NULL; + __pyx_pybuffer_confMatrix_c.refcount = 0; + __pyx_pybuffernd_confMatrix_c.data = NULL; + __pyx_pybuffernd_confMatrix_c.rcbuffer = &__pyx_pybuffer_confMatrix_c; + __pyx_pybuffer_predictionArr.pybuffer.buf = NULL; + __pyx_pybuffer_predictionArr.refcount = 0; + __pyx_pybuffernd_predictionArr.data = NULL; + __pyx_pybuffernd_predictionArr.rcbuffer = &__pyx_pybuffer_predictionArr; + __pyx_pybuffer_groundTruthArr.pybuffer.buf = NULL; + __pyx_pybuffer_groundTruthArr.refcount = 0; + __pyx_pybuffernd_groundTruthArr.data = NULL; + __pyx_pybuffernd_groundTruthArr.rcbuffer = &__pyx_pybuffer_groundTruthArr; + __pyx_pybuffer_confMatrix.pybuffer.buf = NULL; + __pyx_pybuffer_confMatrix.refcount = 0; + __pyx_pybuffernd_confMatrix.data = NULL; + __pyx_pybuffernd_confMatrix.rcbuffer = &__pyx_pybuffer_confMatrix; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_predictionArr.rcbuffer->pybuffer, (PyObject*)__pyx_v_predictionArr, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint8_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 24, __pyx_L1_error) + } + __pyx_pybuffernd_predictionArr.diminfo[0].strides = __pyx_pybuffernd_predictionArr.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_predictionArr.diminfo[0].shape = __pyx_pybuffernd_predictionArr.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_predictionArr.diminfo[1].strides = __pyx_pybuffernd_predictionArr.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_predictionArr.diminfo[1].shape = __pyx_pybuffernd_predictionArr.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_groundTruthArr.rcbuffer->pybuffer, (PyObject*)__pyx_v_groundTruthArr, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint8_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 24, __pyx_L1_error) + } + __pyx_pybuffernd_groundTruthArr.diminfo[0].strides = __pyx_pybuffernd_groundTruthArr.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_groundTruthArr.diminfo[0].shape = __pyx_pybuffernd_groundTruthArr.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_groundTruthArr.diminfo[1].strides = __pyx_pybuffernd_groundTruthArr.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_groundTruthArr.diminfo[1].shape = __pyx_pybuffernd_groundTruthArr.rcbuffer->pybuffer.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_confMatrix.rcbuffer->pybuffer, (PyObject*)__pyx_v_confMatrix, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 24, __pyx_L1_error) + } + __pyx_pybuffernd_confMatrix.diminfo[0].strides = __pyx_pybuffernd_confMatrix.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_confMatrix.diminfo[0].shape = __pyx_pybuffernd_confMatrix.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_confMatrix.diminfo[1].strides = __pyx_pybuffernd_confMatrix.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_confMatrix.diminfo[1].shape = __pyx_pybuffernd_confMatrix.rcbuffer->pybuffer.shape[1]; + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":32 + * cdef np.ndarray[np.ulonglong_t, ndim=2, mode="c"] confMatrix_c + * + * predictionArr_c = np.ascontiguousarray(predictionArr , dtype=np.uint8 ) # <<<<<<<<<<<<<< + * groundTruthArr_c = np.ascontiguousarray(groundTruthArr, dtype=np.uint8 ) + * confMatrix_c = np.ascontiguousarray(confMatrix , dtype=np.ulonglong) + */ + __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(((PyObject *)__pyx_v_predictionArr)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_predictionArr)); + PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_v_predictionArr)); + __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_uint8); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_5) < 0) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 32, __pyx_L1_error) + __pyx_t_6 = ((PyArrayObject *)__pyx_t_5); + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_predictionArr_c.rcbuffer->pybuffer); + __pyx_t_7 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_predictionArr_c.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint8_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack); + if (unlikely(__pyx_t_7 < 0)) { + PyErr_Fetch(&__pyx_t_8, &__pyx_t_9, &__pyx_t_10); + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_predictionArr_c.rcbuffer->pybuffer, (PyObject*)__pyx_v_predictionArr_c, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint8_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) { + Py_XDECREF(__pyx_t_8); Py_XDECREF(__pyx_t_9); Py_XDECREF(__pyx_t_10); + __Pyx_RaiseBufferFallbackError(); + } else { + PyErr_Restore(__pyx_t_8, __pyx_t_9, __pyx_t_10); + } + } + __pyx_pybuffernd_predictionArr_c.diminfo[0].strides = __pyx_pybuffernd_predictionArr_c.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_predictionArr_c.diminfo[0].shape = __pyx_pybuffernd_predictionArr_c.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_predictionArr_c.diminfo[1].strides = __pyx_pybuffernd_predictionArr_c.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_predictionArr_c.diminfo[1].shape = __pyx_pybuffernd_predictionArr_c.rcbuffer->pybuffer.shape[1]; + if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 32, __pyx_L1_error) + } + __pyx_t_6 = 0; + __pyx_v_predictionArr_c = ((PyArrayObject *)__pyx_t_5); + __pyx_t_5 = 0; + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":33 + * + * predictionArr_c = np.ascontiguousarray(predictionArr , dtype=np.uint8 ) + * groundTruthArr_c = np.ascontiguousarray(groundTruthArr, dtype=np.uint8 ) # <<<<<<<<<<<<<< + * confMatrix_c = np.ascontiguousarray(confMatrix , dtype=np.ulonglong) + * + */ + __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(((PyObject *)__pyx_v_groundTruthArr)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_groundTruthArr)); + PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_groundTruthArr)); + __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_uint8); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_4) < 0) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 33, __pyx_L1_error) + __pyx_t_11 = ((PyArrayObject *)__pyx_t_4); + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_groundTruthArr_c.rcbuffer->pybuffer); + __pyx_t_7 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_groundTruthArr_c.rcbuffer->pybuffer, (PyObject*)__pyx_t_11, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint8_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack); + if (unlikely(__pyx_t_7 < 0)) { + PyErr_Fetch(&__pyx_t_10, &__pyx_t_9, &__pyx_t_8); + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_groundTruthArr_c.rcbuffer->pybuffer, (PyObject*)__pyx_v_groundTruthArr_c, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint8_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) { + Py_XDECREF(__pyx_t_10); Py_XDECREF(__pyx_t_9); Py_XDECREF(__pyx_t_8); + __Pyx_RaiseBufferFallbackError(); + } else { + PyErr_Restore(__pyx_t_10, __pyx_t_9, __pyx_t_8); + } + } + __pyx_pybuffernd_groundTruthArr_c.diminfo[0].strides = __pyx_pybuffernd_groundTruthArr_c.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_groundTruthArr_c.diminfo[0].shape = __pyx_pybuffernd_groundTruthArr_c.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_groundTruthArr_c.diminfo[1].strides = __pyx_pybuffernd_groundTruthArr_c.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_groundTruthArr_c.diminfo[1].shape = __pyx_pybuffernd_groundTruthArr_c.rcbuffer->pybuffer.shape[1]; + if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 33, __pyx_L1_error) + } + __pyx_t_11 = 0; + __pyx_v_groundTruthArr_c = ((PyArrayObject *)__pyx_t_4); + __pyx_t_4 = 0; + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":34 + * predictionArr_c = np.ascontiguousarray(predictionArr , dtype=np.uint8 ) + * groundTruthArr_c = np.ascontiguousarray(groundTruthArr, dtype=np.uint8 ) + * confMatrix_c = np.ascontiguousarray(confMatrix , dtype=np.ulonglong) # <<<<<<<<<<<<<< + * + * cdef np.uint32_t height_ui = predictionArr.shape[1] + */ + __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_INCREF(((PyObject *)__pyx_v_confMatrix)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_confMatrix)); + PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_v_confMatrix)); + __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_ulonglong); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 34, __pyx_L1_error) + __pyx_t_12 = ((PyArrayObject *)__pyx_t_2); + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_confMatrix_c.rcbuffer->pybuffer); + __pyx_t_7 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_confMatrix_c.rcbuffer->pybuffer, (PyObject*)__pyx_t_12, &__Pyx_TypeInfo_nn___pyx_t_5numpy_ulonglong_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack); + if (unlikely(__pyx_t_7 < 0)) { + PyErr_Fetch(&__pyx_t_8, &__pyx_t_9, &__pyx_t_10); + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_confMatrix_c.rcbuffer->pybuffer, (PyObject*)__pyx_v_confMatrix_c, &__Pyx_TypeInfo_nn___pyx_t_5numpy_ulonglong_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) { + Py_XDECREF(__pyx_t_8); Py_XDECREF(__pyx_t_9); Py_XDECREF(__pyx_t_10); + __Pyx_RaiseBufferFallbackError(); + } else { + PyErr_Restore(__pyx_t_8, __pyx_t_9, __pyx_t_10); + } + } + __pyx_pybuffernd_confMatrix_c.diminfo[0].strides = __pyx_pybuffernd_confMatrix_c.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_confMatrix_c.diminfo[0].shape = __pyx_pybuffernd_confMatrix_c.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_confMatrix_c.diminfo[1].strides = __pyx_pybuffernd_confMatrix_c.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_confMatrix_c.diminfo[1].shape = __pyx_pybuffernd_confMatrix_c.rcbuffer->pybuffer.shape[1]; + if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 34, __pyx_L1_error) + } + __pyx_t_12 = 0; + __pyx_v_confMatrix_c = ((PyArrayObject *)__pyx_t_2); + __pyx_t_2 = 0; + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":36 + * confMatrix_c = np.ascontiguousarray(confMatrix , dtype=np.ulonglong) + * + * cdef np.uint32_t height_ui = predictionArr.shape[1] # <<<<<<<<<<<<<< + * cdef np.uint32_t width_ui = predictionArr.shape[0] + * cdef np.uint32_t confMatDim_ui = confMatrix.shape[0] + */ + __pyx_v_height_ui = (__pyx_v_predictionArr->dimensions[1]); + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":37 + * + * cdef np.uint32_t height_ui = predictionArr.shape[1] + * cdef np.uint32_t width_ui = predictionArr.shape[0] # <<<<<<<<<<<<<< + * cdef np.uint32_t confMatDim_ui = confMatrix.shape[0] + * + */ + __pyx_v_width_ui = (__pyx_v_predictionArr->dimensions[0]); + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":38 + * cdef np.uint32_t height_ui = predictionArr.shape[1] + * cdef np.uint32_t width_ui = predictionArr.shape[0] + * cdef np.uint32_t confMatDim_ui = confMatrix.shape[0] # <<<<<<<<<<<<<< + * + * addToConfusionMatrix(&predictionArr_c[0,0], &groundTruthArr_c[0,0], height_ui, width_ui, &confMatrix_c[0,0], confMatDim_ui) + */ + __pyx_v_confMatDim_ui = (__pyx_v_confMatrix->dimensions[0]); + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":40 + * cdef np.uint32_t confMatDim_ui = confMatrix.shape[0] + * + * addToConfusionMatrix(&predictionArr_c[0,0], &groundTruthArr_c[0,0], height_ui, width_ui, &confMatrix_c[0,0], confMatDim_ui) # <<<<<<<<<<<<<< + * + * confMatrix = np.ascontiguousarray(tonumpyarray(&confMatrix_c[0,0], confMatDim_ui)) + */ + __pyx_t_13 = 0; + __pyx_t_14 = 0; + if (__pyx_t_13 < 0) __pyx_t_13 += __pyx_pybuffernd_predictionArr_c.diminfo[0].shape; + if (__pyx_t_14 < 0) __pyx_t_14 += __pyx_pybuffernd_predictionArr_c.diminfo[1].shape; + __pyx_t_15 = 0; + __pyx_t_16 = 0; + if (__pyx_t_15 < 0) __pyx_t_15 += __pyx_pybuffernd_groundTruthArr_c.diminfo[0].shape; + if (__pyx_t_16 < 0) __pyx_t_16 += __pyx_pybuffernd_groundTruthArr_c.diminfo[1].shape; + __pyx_t_17 = 0; + __pyx_t_18 = 0; + if (__pyx_t_17 < 0) __pyx_t_17 += __pyx_pybuffernd_confMatrix_c.diminfo[0].shape; + if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_pybuffernd_confMatrix_c.diminfo[1].shape; + addToConfusionMatrix((&(*__Pyx_BufPtrCContig2d(__pyx_t_5numpy_uint8_t *, __pyx_pybuffernd_predictionArr_c.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_predictionArr_c.diminfo[0].strides, __pyx_t_14, __pyx_pybuffernd_predictionArr_c.diminfo[1].strides))), (&(*__Pyx_BufPtrCContig2d(__pyx_t_5numpy_uint8_t *, __pyx_pybuffernd_groundTruthArr_c.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_groundTruthArr_c.diminfo[0].strides, __pyx_t_16, __pyx_pybuffernd_groundTruthArr_c.diminfo[1].strides))), __pyx_v_height_ui, __pyx_v_width_ui, (&(*__Pyx_BufPtrCContig2d(__pyx_t_5numpy_ulonglong_t *, __pyx_pybuffernd_confMatrix_c.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_confMatrix_c.diminfo[0].strides, __pyx_t_18, __pyx_pybuffernd_confMatrix_c.diminfo[1].strides))), __pyx_v_confMatDim_ui); + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":42 + * addToConfusionMatrix(&predictionArr_c[0,0], &groundTruthArr_c[0,0], height_ui, width_ui, &confMatrix_c[0,0], confMatDim_ui) + * + * confMatrix = np.ascontiguousarray(tonumpyarray(&confMatrix_c[0,0], confMatDim_ui)) # <<<<<<<<<<<<<< + * + * return np.copy(confMatrix) + */ + __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 42, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 42, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_19 = 0; + __pyx_t_20 = 0; + if (__pyx_t_19 < 0) __pyx_t_19 += __pyx_pybuffernd_confMatrix_c.diminfo[0].shape; + if (__pyx_t_20 < 0) __pyx_t_20 += __pyx_pybuffernd_confMatrix_c.diminfo[1].shape; + __pyx_t_5 = __pyx_f_17cityscapesscripts_10evaluation_20addToConfusionMatrix_tonumpyarray((&(*__Pyx_BufPtrCContig2d(__pyx_t_5numpy_ulonglong_t *, __pyx_pybuffernd_confMatrix_c.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_confMatrix_c.diminfo[0].strides, __pyx_t_20, __pyx_pybuffernd_confMatrix_c.diminfo[1].strides))), __pyx_v_confMatDim_ui); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 42, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_1 = NULL; + if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_1)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + if (!__pyx_t_1) { + __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 42, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_GOTREF(__pyx_t_2); + } else { + __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 42, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); __pyx_t_1 = NULL; + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_5); + __pyx_t_5 = 0; + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 42, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 42, __pyx_L1_error) + __pyx_t_21 = ((PyArrayObject *)__pyx_t_2); + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_confMatrix.rcbuffer->pybuffer); + __pyx_t_7 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_confMatrix.rcbuffer->pybuffer, (PyObject*)__pyx_t_21, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack); + if (unlikely(__pyx_t_7 < 0)) { + PyErr_Fetch(&__pyx_t_10, &__pyx_t_9, &__pyx_t_8); + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_confMatrix.rcbuffer->pybuffer, (PyObject*)__pyx_v_confMatrix, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) { + Py_XDECREF(__pyx_t_10); Py_XDECREF(__pyx_t_9); Py_XDECREF(__pyx_t_8); + __Pyx_RaiseBufferFallbackError(); + } else { + PyErr_Restore(__pyx_t_10, __pyx_t_9, __pyx_t_8); + } + } + __pyx_pybuffernd_confMatrix.diminfo[0].strides = __pyx_pybuffernd_confMatrix.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_confMatrix.diminfo[0].shape = __pyx_pybuffernd_confMatrix.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_confMatrix.diminfo[1].strides = __pyx_pybuffernd_confMatrix.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_confMatrix.diminfo[1].shape = __pyx_pybuffernd_confMatrix.rcbuffer->pybuffer.shape[1]; + if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 42, __pyx_L1_error) + } + __pyx_t_21 = 0; + __Pyx_DECREF_SET(__pyx_v_confMatrix, ((PyArrayObject *)__pyx_t_2)); + __pyx_t_2 = 0; + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":44 + * confMatrix = np.ascontiguousarray(tonumpyarray(&confMatrix_c[0,0], confMatDim_ui)) + * + * return np.copy(confMatrix) # <<<<<<<<<<<<<< + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 44, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_copy); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 44, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = NULL; + if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + } + } + if (!__pyx_t_4) { + __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_confMatrix)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 44, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } else { + __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 44, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL; + __Pyx_INCREF(((PyObject *)__pyx_v_confMatrix)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_confMatrix)); + PyTuple_SET_ITEM(__pyx_t_5, 0+1, ((PyObject *)__pyx_v_confMatrix)); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 44, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":24 + * + * @cython.boundscheck(False) + * def cEvaluatePair( np.ndarray[np.uint8_t , ndim=2] predictionArr , # <<<<<<<<<<<<<< + * np.ndarray[np.uint8_t , ndim=2] groundTruthArr , + * np.ndarray[np.uint64_t, ndim=2] confMatrix , + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_confMatrix.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_confMatrix_c.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_groundTruthArr.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_groundTruthArr_c.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_predictionArr.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_predictionArr_c.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("cityscapesscripts.evaluation.addToConfusionMatrix.cEvaluatePair", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_confMatrix.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_confMatrix_c.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_groundTruthArr.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_groundTruthArr_c.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_predictionArr.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_predictionArr_c.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XDECREF((PyObject *)__pyx_v_predictionArr_c); + __Pyx_XDECREF((PyObject *)__pyx_v_groundTruthArr_c); + __Pyx_XDECREF((PyObject *)__pyx_v_confMatrix_c); + __Pyx_XDECREF((PyObject *)__pyx_v_confMatrix); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":197 + * # experimental exception made for __getbuffer__ and __releasebuffer__ + * # -- the details of this may change. + * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< + * # This implementation of getbuffer is geared towards Cython + * # requirements, and does not yet fullfill the PEP. + */ + +/* Python wrapper */ +static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ +static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); + __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { + int __pyx_v_copy_shape; + int __pyx_v_i; + int __pyx_v_ndim; + int __pyx_v_endian_detector; + int __pyx_v_little_endian; + int __pyx_v_t; + char *__pyx_v_f; + PyArray_Descr *__pyx_v_descr = 0; + int __pyx_v_offset; + int __pyx_v_hasfields; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + char *__pyx_t_7; + __Pyx_RefNannySetupContext("__getbuffer__", 0); + if (__pyx_v_info != NULL) { + __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(__pyx_v_info->obj); + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203 + * # of flags + * + * if info == NULL: return # <<<<<<<<<<<<<< + * + * cdef int copy_shape, i, ndim + */ + __pyx_t_1 = ((__pyx_v_info == NULL) != 0); + if (__pyx_t_1) { + __pyx_r = 0; + goto __pyx_L0; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206 + * + * cdef int copy_shape, i, ndim + * cdef int endian_detector = 1 # <<<<<<<<<<<<<< + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * + */ + __pyx_v_endian_detector = 1; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":207 + * cdef int copy_shape, i, ndim + * cdef int endian_detector = 1 + * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< + * + * ndim = PyArray_NDIM(self) + */ + __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209 + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * + * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<< + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + */ + __pyx_v_ndim = PyArray_NDIM(__pyx_v_self); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211 + * ndim = PyArray_NDIM(self) + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * copy_shape = 1 + * else: + */ + __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); + if (__pyx_t_1) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":212 + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + * copy_shape = 1 # <<<<<<<<<<<<<< + * else: + * copy_shape = 0 + */ + __pyx_v_copy_shape = 1; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211 + * ndim = PyArray_NDIM(self) + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * copy_shape = 1 + * else: + */ + goto __pyx_L4; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214 + * copy_shape = 1 + * else: + * copy_shape = 0 # <<<<<<<<<<<<<< + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + */ + /*else*/ { + __pyx_v_copy_shape = 0; + } + __pyx_L4:; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":216 + * copy_shape = 0 + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") + */ + __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L6_bool_binop_done; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217 + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): # <<<<<<<<<<<<<< + * raise ValueError(u"ndarray is not C contiguous") + * + */ + __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L6_bool_binop_done:; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":216 + * copy_shape = 0 + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") + */ + if (__pyx_t_1) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218 + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 218, __pyx_L1_error) + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":216 + * copy_shape = 0 + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") + */ + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":220 + * raise ValueError(u"ndarray is not C contiguous") + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") + */ + __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L9_bool_binop_done; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221 + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): # <<<<<<<<<<<<<< + * raise ValueError(u"ndarray is not Fortran contiguous") + * + */ + __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L9_bool_binop_done:; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":220 + * raise ValueError(u"ndarray is not C contiguous") + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") + */ + if (__pyx_t_1) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222 + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< + * + * info.buf = PyArray_DATA(self) + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 222, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 222, __pyx_L1_error) + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":220 + * raise ValueError(u"ndarray is not C contiguous") + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") + */ + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":224 + * raise ValueError(u"ndarray is not Fortran contiguous") + * + * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<< + * info.ndim = ndim + * if copy_shape: + */ + __pyx_v_info->buf = PyArray_DATA(__pyx_v_self); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":225 + * + * info.buf = PyArray_DATA(self) + * info.ndim = ndim # <<<<<<<<<<<<<< + * if copy_shape: + * # Allocate new buffer for strides and shape info. + */ + __pyx_v_info->ndim = __pyx_v_ndim; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226 + * info.buf = PyArray_DATA(self) + * info.ndim = ndim + * if copy_shape: # <<<<<<<<<<<<<< + * # Allocate new buffer for strides and shape info. + * # This is allocated as one block, strides first. + */ + __pyx_t_1 = (__pyx_v_copy_shape != 0); + if (__pyx_t_1) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229 + * # Allocate new buffer for strides and shape info. + * # This is allocated as one block, strides first. + * info.strides = stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2) # <<<<<<<<<<<<<< + * info.shape = info.strides + ndim + * for i in range(ndim): + */ + __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2))); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230 + * # This is allocated as one block, strides first. + * info.strides = stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2) + * info.shape = info.strides + ndim # <<<<<<<<<<<<<< + * for i in range(ndim): + * info.strides[i] = PyArray_STRIDES(self)[i] + */ + __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":231 + * info.strides = stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2) + * info.shape = info.strides + ndim + * for i in range(ndim): # <<<<<<<<<<<<<< + * info.strides[i] = PyArray_STRIDES(self)[i] + * info.shape[i] = PyArray_DIMS(self)[i] + */ + __pyx_t_4 = __pyx_v_ndim; + for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { + __pyx_v_i = __pyx_t_5; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232 + * info.shape = info.strides + ndim + * for i in range(ndim): + * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<< + * info.shape[i] = PyArray_DIMS(self)[i] + * else: + */ + (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233 + * for i in range(ndim): + * info.strides[i] = PyArray_STRIDES(self)[i] + * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<< + * else: + * info.strides = PyArray_STRIDES(self) + */ + (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]); + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226 + * info.buf = PyArray_DATA(self) + * info.ndim = ndim + * if copy_shape: # <<<<<<<<<<<<<< + * # Allocate new buffer for strides and shape info. + * # This is allocated as one block, strides first. + */ + goto __pyx_L11; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235 + * info.shape[i] = PyArray_DIMS(self)[i] + * else: + * info.strides = PyArray_STRIDES(self) # <<<<<<<<<<<<<< + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL + */ + /*else*/ { + __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self)); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236 + * else: + * info.strides = PyArray_STRIDES(self) + * info.shape = PyArray_DIMS(self) # <<<<<<<<<<<<<< + * info.suboffsets = NULL + * info.itemsize = PyArray_ITEMSIZE(self) + */ + __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self)); + } + __pyx_L11:; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":237 + * info.strides = PyArray_STRIDES(self) + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL # <<<<<<<<<<<<<< + * info.itemsize = PyArray_ITEMSIZE(self) + * info.readonly = not PyArray_ISWRITEABLE(self) + */ + __pyx_v_info->suboffsets = NULL; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":238 + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL + * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<< + * info.readonly = not PyArray_ISWRITEABLE(self) + * + */ + __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239 + * info.suboffsets = NULL + * info.itemsize = PyArray_ITEMSIZE(self) + * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<< + * + * cdef int t + */ + __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0)); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":242 + * + * cdef int t + * cdef char* f = NULL # <<<<<<<<<<<<<< + * cdef dtype descr = self.descr + * cdef int offset + */ + __pyx_v_f = NULL; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":243 + * cdef int t + * cdef char* f = NULL + * cdef dtype descr = self.descr # <<<<<<<<<<<<<< + * cdef int offset + * + */ + __pyx_t_3 = ((PyObject *)__pyx_v_self->descr); + __Pyx_INCREF(__pyx_t_3); + __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3); + __pyx_t_3 = 0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246 + * cdef int offset + * + * cdef bint hasfields = PyDataType_HASFIELDS(descr) # <<<<<<<<<<<<<< + * + * if not hasfields and not copy_shape: + */ + __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248 + * cdef bint hasfields = PyDataType_HASFIELDS(descr) + * + * if not hasfields and not copy_shape: # <<<<<<<<<<<<<< + * # do not call releasebuffer + * info.obj = None + */ + __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L15_bool_binop_done; + } + __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L15_bool_binop_done:; + if (__pyx_t_1) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":250 + * if not hasfields and not copy_shape: + * # do not call releasebuffer + * info.obj = None # <<<<<<<<<<<<<< + * else: + * # need to call releasebuffer + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); + __pyx_v_info->obj = Py_None; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248 + * cdef bint hasfields = PyDataType_HASFIELDS(descr) + * + * if not hasfields and not copy_shape: # <<<<<<<<<<<<<< + * # do not call releasebuffer + * info.obj = None + */ + goto __pyx_L14; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253 + * else: + * # need to call releasebuffer + * info.obj = self # <<<<<<<<<<<<<< + * + * if not hasfields: + */ + /*else*/ { + __Pyx_INCREF(((PyObject *)__pyx_v_self)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); + __pyx_v_info->obj = ((PyObject *)__pyx_v_self); + } + __pyx_L14:; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255 + * info.obj = self + * + * if not hasfields: # <<<<<<<<<<<<<< + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or + */ + __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0); + if (__pyx_t_1) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256 + * + * if not hasfields: + * t = descr.type_num # <<<<<<<<<<<<<< + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): + */ + __pyx_t_4 = __pyx_v_descr->type_num; + __pyx_v_t = __pyx_t_4; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257 + * if not hasfields: + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0); + if (!__pyx_t_2) { + goto __pyx_L20_next_or; + } else { + } + __pyx_t_2 = (__pyx_v_little_endian != 0); + if (!__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L19_bool_binop_done; + } + __pyx_L20_next_or:; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258 + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< + * raise ValueError(u"Non-native byte order not supported") + * if t == NPY_BYTE: f = "b" + */ + __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L19_bool_binop_done; + } + __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L19_bool_binop_done:; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257 + * if not hasfields: + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + if (__pyx_t_1) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259 + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 259, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 259, __pyx_L1_error) + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257 + * if not hasfields: + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260 + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<< + * elif t == NPY_UBYTE: f = "B" + * elif t == NPY_SHORT: f = "h" + */ + switch (__pyx_v_t) { + case NPY_BYTE: + __pyx_v_f = ((char *)"b"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261 + * raise ValueError(u"Non-native byte order not supported") + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<< + * elif t == NPY_SHORT: f = "h" + * elif t == NPY_USHORT: f = "H" + */ + case NPY_UBYTE: + __pyx_v_f = ((char *)"B"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262 + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" + * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<< + * elif t == NPY_USHORT: f = "H" + * elif t == NPY_INT: f = "i" + */ + case NPY_SHORT: + __pyx_v_f = ((char *)"h"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263 + * elif t == NPY_UBYTE: f = "B" + * elif t == NPY_SHORT: f = "h" + * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<< + * elif t == NPY_INT: f = "i" + * elif t == NPY_UINT: f = "I" + */ + case NPY_USHORT: + __pyx_v_f = ((char *)"H"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264 + * elif t == NPY_SHORT: f = "h" + * elif t == NPY_USHORT: f = "H" + * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<< + * elif t == NPY_UINT: f = "I" + * elif t == NPY_LONG: f = "l" + */ + case NPY_INT: + __pyx_v_f = ((char *)"i"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265 + * elif t == NPY_USHORT: f = "H" + * elif t == NPY_INT: f = "i" + * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<< + * elif t == NPY_LONG: f = "l" + * elif t == NPY_ULONG: f = "L" + */ + case NPY_UINT: + __pyx_v_f = ((char *)"I"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266 + * elif t == NPY_INT: f = "i" + * elif t == NPY_UINT: f = "I" + * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<< + * elif t == NPY_ULONG: f = "L" + * elif t == NPY_LONGLONG: f = "q" + */ + case NPY_LONG: + __pyx_v_f = ((char *)"l"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267 + * elif t == NPY_UINT: f = "I" + * elif t == NPY_LONG: f = "l" + * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<< + * elif t == NPY_LONGLONG: f = "q" + * elif t == NPY_ULONGLONG: f = "Q" + */ + case NPY_ULONG: + __pyx_v_f = ((char *)"L"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268 + * elif t == NPY_LONG: f = "l" + * elif t == NPY_ULONG: f = "L" + * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<< + * elif t == NPY_ULONGLONG: f = "Q" + * elif t == NPY_FLOAT: f = "f" + */ + case NPY_LONGLONG: + __pyx_v_f = ((char *)"q"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269 + * elif t == NPY_ULONG: f = "L" + * elif t == NPY_LONGLONG: f = "q" + * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<< + * elif t == NPY_FLOAT: f = "f" + * elif t == NPY_DOUBLE: f = "d" + */ + case NPY_ULONGLONG: + __pyx_v_f = ((char *)"Q"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270 + * elif t == NPY_LONGLONG: f = "q" + * elif t == NPY_ULONGLONG: f = "Q" + * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<< + * elif t == NPY_DOUBLE: f = "d" + * elif t == NPY_LONGDOUBLE: f = "g" + */ + case NPY_FLOAT: + __pyx_v_f = ((char *)"f"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271 + * elif t == NPY_ULONGLONG: f = "Q" + * elif t == NPY_FLOAT: f = "f" + * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<< + * elif t == NPY_LONGDOUBLE: f = "g" + * elif t == NPY_CFLOAT: f = "Zf" + */ + case NPY_DOUBLE: + __pyx_v_f = ((char *)"d"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272 + * elif t == NPY_FLOAT: f = "f" + * elif t == NPY_DOUBLE: f = "d" + * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<< + * elif t == NPY_CFLOAT: f = "Zf" + * elif t == NPY_CDOUBLE: f = "Zd" + */ + case NPY_LONGDOUBLE: + __pyx_v_f = ((char *)"g"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273 + * elif t == NPY_DOUBLE: f = "d" + * elif t == NPY_LONGDOUBLE: f = "g" + * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<< + * elif t == NPY_CDOUBLE: f = "Zd" + * elif t == NPY_CLONGDOUBLE: f = "Zg" + */ + case NPY_CFLOAT: + __pyx_v_f = ((char *)"Zf"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274 + * elif t == NPY_LONGDOUBLE: f = "g" + * elif t == NPY_CFLOAT: f = "Zf" + * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<< + * elif t == NPY_CLONGDOUBLE: f = "Zg" + * elif t == NPY_OBJECT: f = "O" + */ + case NPY_CDOUBLE: + __pyx_v_f = ((char *)"Zd"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":275 + * elif t == NPY_CFLOAT: f = "Zf" + * elif t == NPY_CDOUBLE: f = "Zd" + * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<< + * elif t == NPY_OBJECT: f = "O" + * else: + */ + case NPY_CLONGDOUBLE: + __pyx_v_f = ((char *)"Zg"); + break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276 + * elif t == NPY_CDOUBLE: f = "Zd" + * elif t == NPY_CLONGDOUBLE: f = "Zg" + * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<< + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + */ + case NPY_OBJECT: + __pyx_v_f = ((char *)"O"); + break; + default: + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278 + * elif t == NPY_OBJECT: f = "O" + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< + * info.format = f + * return + */ + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 278, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 278, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 278, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6); + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 278, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_Raise(__pyx_t_6, 0, 0, 0); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __PYX_ERR(1, 278, __pyx_L1_error) + break; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":279 + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * info.format = f # <<<<<<<<<<<<<< + * return + * else: + */ + __pyx_v_info->format = __pyx_v_f; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280 + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * info.format = f + * return # <<<<<<<<<<<<<< + * else: + * info.format = stdlib.malloc(_buffer_format_string_len) + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255 + * info.obj = self + * + * if not hasfields: # <<<<<<<<<<<<<< + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or + */ + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282 + * return + * else: + * info.format = stdlib.malloc(_buffer_format_string_len) # <<<<<<<<<<<<<< + * info.format[0] = c'^' # Native data types, manual alignment + * offset = 0 + */ + /*else*/ { + __pyx_v_info->format = ((char *)malloc(0xFF)); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283 + * else: + * info.format = stdlib.malloc(_buffer_format_string_len) + * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<< + * offset = 0 + * f = _util_dtypestring(descr, info.format + 1, + */ + (__pyx_v_info->format[0]) = '^'; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":284 + * info.format = stdlib.malloc(_buffer_format_string_len) + * info.format[0] = c'^' # Native data types, manual alignment + * offset = 0 # <<<<<<<<<<<<<< + * f = _util_dtypestring(descr, info.format + 1, + * info.format + _buffer_format_string_len, + */ + __pyx_v_offset = 0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":285 + * info.format[0] = c'^' # Native data types, manual alignment + * offset = 0 + * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<< + * info.format + _buffer_format_string_len, + * &offset) + */ + __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 0xFF), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) __PYX_ERR(1, 285, __pyx_L1_error) + __pyx_v_f = __pyx_t_7; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288 + * info.format + _buffer_format_string_len, + * &offset) + * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<< + * + * def __releasebuffer__(ndarray self, Py_buffer* info): + */ + (__pyx_v_f[0]) = '\x00'; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":197 + * # experimental exception made for __getbuffer__ and __releasebuffer__ + * # -- the details of this may change. + * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< + * # This implementation of getbuffer is geared towards Cython + * # requirements, and does not yet fullfill the PEP. + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) { + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL; + } + goto __pyx_L2; + __pyx_L0:; + if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) { + __Pyx_GOTREF(Py_None); + __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL; + } + __pyx_L2:; + __Pyx_XDECREF((PyObject *)__pyx_v_descr); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290 + * f[0] = c'\0' # Terminate format string + * + * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< + * if PyArray_HASFIELDS(self): + * stdlib.free(info.format) + */ + +/* Python wrapper */ +static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/ +static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0); + __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) { + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("__releasebuffer__", 0); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291 + * + * def __releasebuffer__(ndarray self, Py_buffer* info): + * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< + * stdlib.free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + */ + __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0); + if (__pyx_t_1) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292 + * def __releasebuffer__(ndarray self, Py_buffer* info): + * if PyArray_HASFIELDS(self): + * stdlib.free(info.format) # <<<<<<<<<<<<<< + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + * stdlib.free(info.strides) + */ + free(__pyx_v_info->format); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291 + * + * def __releasebuffer__(ndarray self, Py_buffer* info): + * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< + * stdlib.free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + */ + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":293 + * if PyArray_HASFIELDS(self): + * stdlib.free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * stdlib.free(info.strides) + * # info.shape was stored after info.strides in the same block + */ + __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); + if (__pyx_t_1) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":294 + * stdlib.free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + * stdlib.free(info.strides) # <<<<<<<<<<<<<< + * # info.shape was stored after info.strides in the same block + * + */ + free(__pyx_v_info->strides); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":293 + * if PyArray_HASFIELDS(self): + * stdlib.free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * stdlib.free(info.strides) + * # info.shape was stored after info.strides in the same block + */ + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290 + * f[0] = c'\0' # Terminate format string + * + * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< + * if PyArray_HASFIELDS(self): + * stdlib.free(info.format) + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":770 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771 + * + * cdef inline object PyArray_MultiIterNew1(a): + * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew2(a, b): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 771, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":770 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":773 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774 + * + * cdef inline object PyArray_MultiIterNew2(a, b): + * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 774, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":773 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":776 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777 + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 777, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":776 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":779 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, d) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780 + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 780, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":779 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, d) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":782 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783 + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< + * + * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 783, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":782 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":785 + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< + * # Recursive utility function used in __getbuffer__ to get format + * # string. The new location in the format string is returned. + */ + +static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) { + PyArray_Descr *__pyx_v_child = 0; + int __pyx_v_endian_detector; + int __pyx_v_little_endian; + PyObject *__pyx_v_fields = 0; + PyObject *__pyx_v_childname = NULL; + PyObject *__pyx_v_new_offset = NULL; + PyObject *__pyx_v_t = NULL; + char *__pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_t_6; + int __pyx_t_7; + long __pyx_t_8; + char *__pyx_t_9; + __Pyx_RefNannySetupContext("_util_dtypestring", 0); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790 + * + * cdef dtype child + * cdef int endian_detector = 1 # <<<<<<<<<<<<<< + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * cdef tuple fields + */ + __pyx_v_endian_detector = 1; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791 + * cdef dtype child + * cdef int endian_detector = 1 + * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< + * cdef tuple fields + * + */ + __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794 + * cdef tuple fields + * + * for childname in descr.names: # <<<<<<<<<<<<<< + * fields = descr.fields[childname] + * child, new_offset = fields + */ + if (unlikely(__pyx_v_descr->names == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); + __PYX_ERR(1, 794, __pyx_L1_error) + } + __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; + for (;;) { + if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break; + #if CYTHON_COMPILING_IN_CPYTHON + __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(1, 794, __pyx_L1_error) + #else + __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 794, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3); + __pyx_t_3 = 0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795 + * + * for childname in descr.names: + * fields = descr.fields[childname] # <<<<<<<<<<<<<< + * child, new_offset = fields + * + */ + if (unlikely(__pyx_v_descr->fields == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 795, __pyx_L1_error) + } + __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 795, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) __PYX_ERR(1, 795, __pyx_L1_error) + __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796 + * for childname in descr.names: + * fields = descr.fields[childname] + * child, new_offset = fields # <<<<<<<<<<<<<< + * + * if (end - f) - (new_offset - offset[0]) < 15: + */ + if (likely(__pyx_v_fields != Py_None)) { + PyObject* sequence = __pyx_v_fields; + #if CYTHON_COMPILING_IN_CPYTHON + Py_ssize_t size = Py_SIZE(sequence); + #else + Py_ssize_t size = PySequence_Size(sequence); + #endif + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(1, 796, __pyx_L1_error) + } + #if CYTHON_COMPILING_IN_CPYTHON + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + #else + __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 796, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 796, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(1, 796, __pyx_L1_error) + } + if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) __PYX_ERR(1, 796, __pyx_L1_error) + __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3)); + __pyx_t_3 = 0; + __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4); + __pyx_t_4 = 0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798 + * child, new_offset = fields + * + * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + */ + __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 798, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 798, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 798, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0); + if (__pyx_t_6) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799 + * + * if (end - f) - (new_offset - offset[0]) < 15: + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< + * + * if ((child.byteorder == c'>' and little_endian) or + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 799, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 799, __pyx_L1_error) + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798 + * child, new_offset = fields + * + * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + */ + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801 + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0); + if (!__pyx_t_7) { + goto __pyx_L8_next_or; + } else { + } + __pyx_t_7 = (__pyx_v_little_endian != 0); + if (!__pyx_t_7) { + } else { + __pyx_t_6 = __pyx_t_7; + goto __pyx_L7_bool_binop_done; + } + __pyx_L8_next_or:; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":802 + * + * if ((child.byteorder == c'>' and little_endian) or + * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< + * raise ValueError(u"Non-native byte order not supported") + * # One could encode it in the format string and have Cython + */ + __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0); + if (__pyx_t_7) { + } else { + __pyx_t_6 = __pyx_t_7; + goto __pyx_L7_bool_binop_done; + } + __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0); + __pyx_t_6 = __pyx_t_7; + __pyx_L7_bool_binop_done:; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801 + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + if (__pyx_t_6) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803 + * if ((child.byteorder == c'>' and little_endian) or + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * # One could encode it in the format string and have Cython + * # complain instead, BUT: < and > in format strings also imply + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 803, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 803, __pyx_L1_error) + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":801 + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":813 + * + * # Output padding bytes + * while offset[0] < new_offset: # <<<<<<<<<<<<<< + * f[0] = 120 # "x"; pad byte + * f += 1 + */ + while (1) { + __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 813, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 813, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 813, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (!__pyx_t_6) break; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":814 + * # Output padding bytes + * while offset[0] < new_offset: + * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<< + * f += 1 + * offset[0] += 1 + */ + (__pyx_v_f[0]) = 0x78; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":815 + * while offset[0] < new_offset: + * f[0] = 120 # "x"; pad byte + * f += 1 # <<<<<<<<<<<<<< + * offset[0] += 1 + * + */ + __pyx_v_f = (__pyx_v_f + 1); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":816 + * f[0] = 120 # "x"; pad byte + * f += 1 + * offset[0] += 1 # <<<<<<<<<<<<<< + * + * offset[0] += child.itemsize + */ + __pyx_t_8 = 0; + (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1); + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":818 + * offset[0] += 1 + * + * offset[0] += child.itemsize # <<<<<<<<<<<<<< + * + * if not PyDataType_HASFIELDS(child): + */ + __pyx_t_8 = 0; + (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820 + * offset[0] += child.itemsize + * + * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< + * t = child.type_num + * if end - f < 5: + */ + __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0); + if (__pyx_t_6) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":821 + * + * if not PyDataType_HASFIELDS(child): + * t = child.type_num # <<<<<<<<<<<<<< + * if end - f < 5: + * raise RuntimeError(u"Format string allocated too short.") + */ + __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 821, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4); + __pyx_t_4 = 0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822 + * if not PyDataType_HASFIELDS(child): + * t = child.type_num + * if end - f < 5: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short.") + * + */ + __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0); + if (__pyx_t_6) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823 + * t = child.type_num + * if end - f < 5: + * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< + * + * # Until ticket #99 is fixed, use integers to avoid warnings + */ + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 823, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_Raise(__pyx_t_4, 0, 0, 0); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __PYX_ERR(1, 823, __pyx_L1_error) + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":822 + * if not PyDataType_HASFIELDS(child): + * t = child.type_num + * if end - f < 5: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short.") + * + */ + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":826 + * + * # Until ticket #99 is fixed, use integers to avoid warnings + * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<< + * elif t == NPY_UBYTE: f[0] = 66 #"B" + * elif t == NPY_SHORT: f[0] = 104 #"h" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_BYTE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 826, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 826, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 826, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 98; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":827 + * # Until ticket #99 is fixed, use integers to avoid warnings + * if t == NPY_BYTE: f[0] = 98 #"b" + * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<< + * elif t == NPY_SHORT: f[0] = 104 #"h" + * elif t == NPY_USHORT: f[0] = 72 #"H" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UBYTE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 827, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 827, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 827, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 66; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":828 + * if t == NPY_BYTE: f[0] = 98 #"b" + * elif t == NPY_UBYTE: f[0] = 66 #"B" + * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<< + * elif t == NPY_USHORT: f[0] = 72 #"H" + * elif t == NPY_INT: f[0] = 105 #"i" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_SHORT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 828, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 828, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 828, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x68; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":829 + * elif t == NPY_UBYTE: f[0] = 66 #"B" + * elif t == NPY_SHORT: f[0] = 104 #"h" + * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<< + * elif t == NPY_INT: f[0] = 105 #"i" + * elif t == NPY_UINT: f[0] = 73 #"I" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_USHORT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 829, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 829, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 829, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 72; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":830 + * elif t == NPY_SHORT: f[0] = 104 #"h" + * elif t == NPY_USHORT: f[0] = 72 #"H" + * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<< + * elif t == NPY_UINT: f[0] = 73 #"I" + * elif t == NPY_LONG: f[0] = 108 #"l" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_INT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 830, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 830, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 830, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x69; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":831 + * elif t == NPY_USHORT: f[0] = 72 #"H" + * elif t == NPY_INT: f[0] = 105 #"i" + * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<< + * elif t == NPY_LONG: f[0] = 108 #"l" + * elif t == NPY_ULONG: f[0] = 76 #"L" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UINT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 831, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 831, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 831, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 73; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":832 + * elif t == NPY_INT: f[0] = 105 #"i" + * elif t == NPY_UINT: f[0] = 73 #"I" + * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<< + * elif t == NPY_ULONG: f[0] = 76 #"L" + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 832, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 832, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 832, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x6C; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":833 + * elif t == NPY_UINT: f[0] = 73 #"I" + * elif t == NPY_LONG: f[0] = 108 #"l" + * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<< + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 833, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 833, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 833, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 76; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":834 + * elif t == NPY_LONG: f[0] = 108 #"l" + * elif t == NPY_ULONG: f[0] = 76 #"L" + * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<< + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + * elif t == NPY_FLOAT: f[0] = 102 #"f" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 834, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 834, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 834, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x71; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":835 + * elif t == NPY_ULONG: f[0] = 76 #"L" + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<< + * elif t == NPY_FLOAT: f[0] = 102 #"f" + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 835, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 835, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 835, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 81; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":836 + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<< + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_FLOAT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 836, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 836, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 836, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x66; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":837 + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + * elif t == NPY_FLOAT: f[0] = 102 #"f" + * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<< + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 837, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 837, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 837, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x64; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":838 + * elif t == NPY_FLOAT: f[0] = 102 #"f" + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<< + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 838, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 838, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 838, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x67; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":839 + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<< + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 839, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 839, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 839, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 90; + (__pyx_v_f[1]) = 0x66; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":840 + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<< + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg + * elif t == NPY_OBJECT: f[0] = 79 #"O" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 840, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 840, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 840, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 90; + (__pyx_v_f[1]) = 0x64; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":841 + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<< + * elif t == NPY_OBJECT: f[0] = 79 #"O" + * else: + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 841, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 841, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 841, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 90; + (__pyx_v_f[1]) = 0x67; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":842 + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg + * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<< + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_OBJECT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 842, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 842, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 842, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 79; + goto __pyx_L15; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":844 + * elif t == NPY_OBJECT: f[0] = 79 #"O" + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< + * f += 1 + * else: + */ + /*else*/ { + __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 844, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 844, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); + __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 844, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 844, __pyx_L1_error) + } + __pyx_L15:; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":845 + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * f += 1 # <<<<<<<<<<<<<< + * else: + * # Cython ignores struct boundary information ("T{...}"), + */ + __pyx_v_f = (__pyx_v_f + 1); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820 + * offset[0] += child.itemsize + * + * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< + * t = child.type_num + * if end - f < 5: + */ + goto __pyx_L13; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":849 + * # Cython ignores struct boundary information ("T{...}"), + * # so don't output it + * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<< + * return f + * + */ + /*else*/ { + __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) __PYX_ERR(1, 849, __pyx_L1_error) + __pyx_v_f = __pyx_t_9; + } + __pyx_L13:; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":794 + * cdef tuple fields + * + * for childname in descr.names: # <<<<<<<<<<<<<< + * fields = descr.fields[childname] + * child, new_offset = fields + */ + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":850 + * # so don't output it + * f = _util_dtypestring(child, f, end, offset) + * return f # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __pyx_v_f; + goto __pyx_L0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":785 + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< + * # Recursive utility function used in __getbuffer__ to get format + * # string. The new location in the format string is returned. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_child); + __Pyx_XDECREF(__pyx_v_fields); + __Pyx_XDECREF(__pyx_v_childname); + __Pyx_XDECREF(__pyx_v_new_offset); + __Pyx_XDECREF(__pyx_v_t); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966 + * + * + * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * cdef PyObject* baseptr + * if base is None: + */ + +static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) { + PyObject *__pyx_v_baseptr; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + __Pyx_RefNannySetupContext("set_array_base", 0); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968 + * cdef inline void set_array_base(ndarray arr, object base): + * cdef PyObject* baseptr + * if base is None: # <<<<<<<<<<<<<< + * baseptr = NULL + * else: + */ + __pyx_t_1 = (__pyx_v_base == Py_None); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":969 + * cdef PyObject* baseptr + * if base is None: + * baseptr = NULL # <<<<<<<<<<<<<< + * else: + * Py_INCREF(base) # important to do this before decref below! + */ + __pyx_v_baseptr = NULL; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":968 + * cdef inline void set_array_base(ndarray arr, object base): + * cdef PyObject* baseptr + * if base is None: # <<<<<<<<<<<<<< + * baseptr = NULL + * else: + */ + goto __pyx_L3; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971 + * baseptr = NULL + * else: + * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<< + * baseptr = base + * Py_XDECREF(arr.base) + */ + /*else*/ { + Py_INCREF(__pyx_v_base); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972 + * else: + * Py_INCREF(base) # important to do this before decref below! + * baseptr = base # <<<<<<<<<<<<<< + * Py_XDECREF(arr.base) + * arr.base = baseptr + */ + __pyx_v_baseptr = ((PyObject *)__pyx_v_base); + } + __pyx_L3:; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973 + * Py_INCREF(base) # important to do this before decref below! + * baseptr = base + * Py_XDECREF(arr.base) # <<<<<<<<<<<<<< + * arr.base = baseptr + * + */ + Py_XDECREF(__pyx_v_arr->base); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974 + * baseptr = base + * Py_XDECREF(arr.base) + * arr.base = baseptr # <<<<<<<<<<<<<< + * + * cdef inline object get_array_base(ndarray arr): + */ + __pyx_v_arr->base = __pyx_v_baseptr; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":966 + * + * + * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * cdef PyObject* baseptr + * if base is None: + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976 + * arr.base = baseptr + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * if arr.base is NULL: + * return None + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("get_array_base", 0); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977 + * + * cdef inline object get_array_base(ndarray arr): + * if arr.base is NULL: # <<<<<<<<<<<<<< + * return None + * else: + */ + __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0); + if (__pyx_t_1) { + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978 + * cdef inline object get_array_base(ndarray arr): + * if arr.base is NULL: + * return None # <<<<<<<<<<<<<< + * else: + * return arr.base + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(Py_None); + __pyx_r = Py_None; + goto __pyx_L0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977 + * + * cdef inline object get_array_base(ndarray arr): + * if arr.base is NULL: # <<<<<<<<<<<<<< + * return None + * else: + */ + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980 + * return None + * else: + * return arr.base # <<<<<<<<<<<<<< + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)__pyx_v_arr->base)); + __pyx_r = ((PyObject *)__pyx_v_arr->base); + goto __pyx_L0; + } + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976 + * arr.base = baseptr + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * if arr.base is NULL: + * return None + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; + +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef __pyx_moduledef = { + #if PY_VERSION_HEX < 0x03020000 + { PyObject_HEAD_INIT(NULL) NULL, 0, NULL }, + #else + PyModuleDef_HEAD_INIT, + #endif + "addToConfusionMatrix", + 0, /* m_doc */ + -1, /* m_size */ + __pyx_methods /* m_methods */, + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; +#endif + +static __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0}, + {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0}, + {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0}, + {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, + {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, + {&__pyx_n_s_ascontiguousarray, __pyx_k_ascontiguousarray, sizeof(__pyx_k_ascontiguousarray), 0, 0, 1, 1}, + {&__pyx_n_s_cEvaluatePair, __pyx_k_cEvaluatePair, sizeof(__pyx_k_cEvaluatePair), 0, 0, 1, 1}, + {&__pyx_n_s_cityscapesscripts_evaluation_add, __pyx_k_cityscapesscripts_evaluation_add, sizeof(__pyx_k_cityscapesscripts_evaluation_add), 0, 0, 1, 1}, + {&__pyx_n_s_confMatDim_ui, __pyx_k_confMatDim_ui, sizeof(__pyx_k_confMatDim_ui), 0, 0, 1, 1}, + {&__pyx_n_s_confMatrix, __pyx_k_confMatrix, sizeof(__pyx_k_confMatrix), 0, 0, 1, 1}, + {&__pyx_n_s_confMatrix_c, __pyx_k_confMatrix_c, sizeof(__pyx_k_confMatrix_c), 0, 0, 1, 1}, + {&__pyx_n_s_copy, __pyx_k_copy, sizeof(__pyx_k_copy), 0, 0, 1, 1}, + {&__pyx_n_s_ctypes, __pyx_k_ctypes, sizeof(__pyx_k_ctypes), 0, 0, 1, 1}, + {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1}, + {&__pyx_n_s_evalLabels, __pyx_k_evalLabels, sizeof(__pyx_k_evalLabels), 0, 0, 1, 1}, + {&__pyx_n_s_groundTruthArr, __pyx_k_groundTruthArr, sizeof(__pyx_k_groundTruthArr), 0, 0, 1, 1}, + {&__pyx_n_s_groundTruthArr_c, __pyx_k_groundTruthArr_c, sizeof(__pyx_k_groundTruthArr_c), 0, 0, 1, 1}, + {&__pyx_kp_s_hd_data_cityscapes_cityscapesSc, __pyx_k_hd_data_cityscapes_cityscapesSc, sizeof(__pyx_k_hd_data_cityscapes_cityscapesSc), 0, 0, 1, 0}, + {&__pyx_n_s_height_ui, __pyx_k_height_ui, sizeof(__pyx_k_height_ui), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0}, + {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0}, + {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, + {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, + {&__pyx_n_s_predictionArr, __pyx_k_predictionArr, sizeof(__pyx_k_predictionArr), 0, 0, 1, 1}, + {&__pyx_n_s_predictionArr_c, __pyx_k_predictionArr_c, sizeof(__pyx_k_predictionArr_c), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_uint8, __pyx_k_uint8, sizeof(__pyx_k_uint8), 0, 0, 1, 1}, + {&__pyx_n_s_ulonglong, __pyx_k_ulonglong, sizeof(__pyx_k_ulonglong), 0, 0, 1, 1}, + {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0}, + {&__pyx_n_s_width_ui, __pyx_k_width_ui, sizeof(__pyx_k_width_ui), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} +}; +static int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(0, 20, __pyx_L1_error) + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(1, 231, __pyx_L1_error) + __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(1, 799, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218 + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + */ + __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple_)) __PYX_ERR(1, 218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple_); + __Pyx_GIVEREF(__pyx_tuple_); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222 + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< + * + * info.buf = PyArray_DATA(self) + */ + __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 222, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__2); + __Pyx_GIVEREF(__pyx_tuple__2); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259 + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" + */ + __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(1, 259, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__3); + __Pyx_GIVEREF(__pyx_tuple__3); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799 + * + * if (end - f) - (new_offset - offset[0]) < 15: + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< + * + * if ((child.byteorder == c'>' and little_endian) or + */ + __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 799, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__4); + __Pyx_GIVEREF(__pyx_tuple__4); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":803 + * if ((child.byteorder == c'>' and little_endian) or + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * # One could encode it in the format string and have Cython + * # complain instead, BUT: < and > in format strings also imply + */ + __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 803, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__5); + __Pyx_GIVEREF(__pyx_tuple__5); + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":823 + * t = child.type_num + * if end - f < 5: + * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< + * + * # Until ticket #99 is fixed, use integers to avoid warnings + */ + __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 823, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__6); + __Pyx_GIVEREF(__pyx_tuple__6); + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":24 + * + * @cython.boundscheck(False) + * def cEvaluatePair( np.ndarray[np.uint8_t , ndim=2] predictionArr , # <<<<<<<<<<<<<< + * np.ndarray[np.uint8_t , ndim=2] groundTruthArr , + * np.ndarray[np.uint64_t, ndim=2] confMatrix , + */ + __pyx_tuple__7 = PyTuple_Pack(10, __pyx_n_s_predictionArr, __pyx_n_s_groundTruthArr, __pyx_n_s_confMatrix, __pyx_n_s_evalLabels, __pyx_n_s_predictionArr_c, __pyx_n_s_groundTruthArr_c, __pyx_n_s_confMatrix_c, __pyx_n_s_height_ui, __pyx_n_s_width_ui, __pyx_n_s_confMatDim_ui); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__7); + __Pyx_GIVEREF(__pyx_tuple__7); + __pyx_codeobj__8 = (PyObject*)__Pyx_PyCode_New(4, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__7, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_hd_data_cityscapes_cityscapesSc, __pyx_n_s_cEvaluatePair, 24, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__8)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_InitGlobals(void) { + if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + return 0; + __pyx_L1_error:; + return -1; +} + +#if PY_MAJOR_VERSION < 3 +PyMODINIT_FUNC initaddToConfusionMatrix(void); /*proto*/ +PyMODINIT_FUNC initaddToConfusionMatrix(void) +#else +PyMODINIT_FUNC PyInit_addToConfusionMatrix(void); /*proto*/ +PyMODINIT_FUNC PyInit_addToConfusionMatrix(void) +#endif +{ + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannyDeclarations + #if CYTHON_REFNANNY + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); + if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); + } + #endif + __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_addToConfusionMatrix(void)", 0); + if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + #ifdef WITH_THREAD /* Python build with threading support? */ + PyEval_InitThreads(); + #endif + #endif + /*--- Module creation code ---*/ + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("addToConfusionMatrix", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + #endif + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + #if CYTHON_COMPILING_IN_PYPY + Py_INCREF(__pyx_b); + #endif + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_cityscapesscripts__evaluation__addToConfusionMatrix) { + if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "cityscapesscripts.evaluation.addToConfusionMatrix")) { + if (unlikely(PyDict_SetItemString(modules, "cityscapesscripts.evaluation.addToConfusionMatrix", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global init code ---*/ + /*--- Variable export code ---*/ + /*--- Function export code ---*/ + /*--- Type init code ---*/ + /*--- Type import code ---*/ + __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", + #if CYTHON_COMPILING_IN_PYPY + sizeof(PyTypeObject), + #else + sizeof(PyHeapTypeObject), + #endif + 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) __PYX_ERR(2, 9, __pyx_L1_error) + __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) __PYX_ERR(1, 155, __pyx_L1_error) + __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) __PYX_ERR(1, 168, __pyx_L1_error) + __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) __PYX_ERR(1, 172, __pyx_L1_error) + __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) __PYX_ERR(1, 181, __pyx_L1_error) + __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) __PYX_ERR(1, 861, __pyx_L1_error) + /*--- Variable import code ---*/ + /*--- Function import code ---*/ + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":3 + * # cython methods to speed-up evaluation + * + * import numpy as np # <<<<<<<<<<<<<< + * cimport cython + * cimport numpy as np + */ + __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 3, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":6 + * cimport cython + * cimport numpy as np + * import ctypes # <<<<<<<<<<<<<< + * + * np.import_array() + */ + __pyx_t_1 = __Pyx_Import(__pyx_n_s_ctypes, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_ctypes, __pyx_t_1) < 0) __PYX_ERR(0, 6, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":8 + * import ctypes + * + * np.import_array() # <<<<<<<<<<<<<< + * + * cdef extern from "addToConfusionMatrix_impl.c": + */ + import_array(); + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":24 + * + * @cython.boundscheck(False) + * def cEvaluatePair( np.ndarray[np.uint8_t , ndim=2] predictionArr , # <<<<<<<<<<<<<< + * np.ndarray[np.uint8_t , ndim=2] groundTruthArr , + * np.ndarray[np.uint64_t, ndim=2] confMatrix , + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_17cityscapesscripts_10evaluation_20addToConfusionMatrix_1cEvaluatePair, NULL, __pyx_n_s_cityscapesscripts_evaluation_add); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_cEvaluatePair, __pyx_t_1) < 0) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "cityscapesscripts/evaluation/addToConfusionMatrix.pyx":1 + * # cython methods to speed-up evaluation # <<<<<<<<<<<<<< + * + * import numpy as np + */ + __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "../../../home/hassan/anaconda2/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":976 + * arr.base = baseptr + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * if arr.base is NULL: + * return None + */ + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + if (__pyx_m) { + if (__pyx_d) { + __Pyx_AddTraceback("init cityscapesscripts.evaluation.addToConfusionMatrix", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + Py_DECREF(__pyx_m); __pyx_m = 0; + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init cityscapesscripts.evaluation.addToConfusionMatrix"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if PY_MAJOR_VERSION < 3 + return; + #else + return __pyx_m; + #endif +} + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule((char *)modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); + if (unlikely(!result)) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* PyErrFetchRestore */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +} +#endif + +/* RaiseException */ +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, + CYTHON_UNUSED PyObject *cause) { + __Pyx_PyThreadState_declare + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } +#if PY_VERSION_HEX >= 0x03030000 + if (cause) { +#else + if (cause && cause != Py_None) { +#endif + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { +#if CYTHON_COMPILING_IN_PYPY + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#else + PyThreadState *tstate = PyThreadState_GET(); + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* RaiseArgTupleInvalid */ + static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* RaiseDoubleKeywords */ + static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION >= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ + static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + while (PyDict_Next(kwds, &pos, &key, &value)) { + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; + continue; + } + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = (**name == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION < 3 + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + return -1; +} + +/* ArgTypeTest */ + static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) { + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", + name, type->tp_name, Py_TYPE(obj)->tp_name); +} +static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, + const char *name, int exact) +{ + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + if (none_allowed && obj == Py_None) return 1; + else if (exact) { + if (likely(Py_TYPE(obj) == type)) return 1; + #if PY_MAJOR_VERSION == 2 + else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; + #endif + } + else { + if (likely(PyObject_TypeCheck(obj, type))) return 1; + } + __Pyx_RaiseArgumentTypeInvalid(name, obj, type); + return 0; +} + +/* BufferFormatCheck */ + static CYTHON_INLINE int __Pyx_IsLittleEndian(void) { + unsigned int n = 1; + return *(unsigned char*)(&n) != 0; +} +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type) { + stack[0].field = &ctx->root; + stack[0].parent_offset = 0; + ctx->root.type = type; + ctx->root.name = "buffer dtype"; + ctx->root.offset = 0; + ctx->head = stack; + ctx->head->field = &ctx->root; + ctx->fmt_offset = 0; + ctx->head->parent_offset = 0; + ctx->new_packmode = '@'; + ctx->enc_packmode = '@'; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->is_complex = 0; + ctx->is_valid_array = 0; + ctx->struct_alignment = 0; + while (type->typegroup == 'S') { + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = 0; + type = type->fields->type; + } +} +static int __Pyx_BufFmt_ParseNumber(const char** ts) { + int count; + const char* t = *ts; + if (*t < '0' || *t > '9') { + return -1; + } else { + count = *t++ - '0'; + while (*t >= '0' && *t < '9') { + count *= 10; + count += *t++ - '0'; + } + } + *ts = t; + return count; +} +static int __Pyx_BufFmt_ExpectNumber(const char **ts) { + int number = __Pyx_BufFmt_ParseNumber(ts); + if (number == -1) + PyErr_Format(PyExc_ValueError,\ + "Does not understand character buffer dtype format string ('%c')", **ts); + return number; +} +static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { + PyErr_Format(PyExc_ValueError, + "Unexpected format string character: '%c'", ch); +} +static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { + switch (ch) { + case 'c': return "'char'"; + case 'b': return "'signed char'"; + case 'B': return "'unsigned char'"; + case 'h': return "'short'"; + case 'H': return "'unsigned short'"; + case 'i': return "'int'"; + case 'I': return "'unsigned int'"; + case 'l': return "'long'"; + case 'L': return "'unsigned long'"; + case 'q': return "'long long'"; + case 'Q': return "'unsigned long long'"; + case 'f': return (is_complex ? "'complex float'" : "'float'"); + case 'd': return (is_complex ? "'complex double'" : "'double'"); + case 'g': return (is_complex ? "'complex long double'" : "'long double'"); + case 'T': return "a struct"; + case 'O': return "Python object"; + case 'P': return "a pointer"; + case 's': case 'p': return "a string"; + case 0: return "end"; + default: return "unparseable format string"; + } +} +static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return 2; + case 'i': case 'I': case 'l': case 'L': return 4; + case 'q': case 'Q': return 8; + case 'f': return (is_complex ? 8 : 4); + case 'd': return (is_complex ? 16 : 8); + case 'g': { + PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); + return 0; + } + case 'O': case 'P': return sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { + switch (ch) { + case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(short); + case 'i': case 'I': return sizeof(int); + case 'l': case 'L': return sizeof(long); + #ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(PY_LONG_LONG); + #endif + case 'f': return sizeof(float) * (is_complex ? 2 : 1); + case 'd': return sizeof(double) * (is_complex ? 2 : 1); + case 'g': return sizeof(long double) * (is_complex ? 2 : 1); + case 'O': case 'P': return sizeof(void*); + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} +typedef struct { char c; short x; } __Pyx_st_short; +typedef struct { char c; int x; } __Pyx_st_int; +typedef struct { char c; long x; } __Pyx_st_long; +typedef struct { char c; float x; } __Pyx_st_float; +typedef struct { char c; double x; } __Pyx_st_double; +typedef struct { char c; long double x; } __Pyx_st_longdouble; +typedef struct { char c; void *x; } __Pyx_st_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; +#endif +static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_st_float) - sizeof(float); + case 'd': return sizeof(__Pyx_st_double) - sizeof(double); + case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +/* These are for computing the padding at the end of the struct to align + on the first member of the struct. This will probably the same as above, + but we don't have any guarantees. + */ +typedef struct { short x; char c; } __Pyx_pad_short; +typedef struct { int x; char c; } __Pyx_pad_int; +typedef struct { long x; char c; } __Pyx_pad_long; +typedef struct { float x; char c; } __Pyx_pad_float; +typedef struct { double x; char c; } __Pyx_pad_double; +typedef struct { long double x; char c; } __Pyx_pad_longdouble; +typedef struct { void *x; char c; } __Pyx_pad_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; +#endif +static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); + case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); + case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { + switch (ch) { + case 'c': + return 'H'; + case 'b': case 'h': case 'i': + case 'l': case 'q': case 's': case 'p': + return 'I'; + case 'B': case 'H': case 'I': case 'L': case 'Q': + return 'U'; + case 'f': case 'd': case 'g': + return (is_complex ? 'C' : 'R'); + case 'O': + return 'O'; + case 'P': + return 'P'; + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} +static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { + if (ctx->head == NULL || ctx->head->field == &ctx->root) { + const char* expected; + const char* quote; + if (ctx->head == NULL) { + expected = "end"; + quote = ""; + } else { + expected = ctx->head->field->type->name; + quote = "'"; + } + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected %s%s%s but got %s", + quote, expected, quote, + __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); + } else { + __Pyx_StructField* field = ctx->head->field; + __Pyx_StructField* parent = (ctx->head - 1)->field; + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", + field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), + parent->type->name, field->name); + } +} +static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { + char group; + size_t size, offset, arraysize = 1; + if (ctx->enc_type == 0) return 0; + if (ctx->head->field->type->arraysize[0]) { + int i, ndim = 0; + if (ctx->enc_type == 's' || ctx->enc_type == 'p') { + ctx->is_valid_array = ctx->head->field->type->ndim == 1; + ndim = 1; + if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { + PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %zu", + ctx->head->field->type->arraysize[0], ctx->enc_count); + return -1; + } + } + if (!ctx->is_valid_array) { + PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", + ctx->head->field->type->ndim, ndim); + return -1; + } + for (i = 0; i < ctx->head->field->type->ndim; i++) { + arraysize *= ctx->head->field->type->arraysize[i]; + } + ctx->is_valid_array = 0; + ctx->enc_count = 1; + } + group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); + do { + __Pyx_StructField* field = ctx->head->field; + __Pyx_TypeInfo* type = field->type; + if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { + size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); + } else { + size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); + } + if (ctx->enc_packmode == '@') { + size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); + size_t align_mod_offset; + if (align_at == 0) return -1; + align_mod_offset = ctx->fmt_offset % align_at; + if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; + if (ctx->struct_alignment == 0) + ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, + ctx->is_complex); + } + if (type->size != size || type->typegroup != group) { + if (type->typegroup == 'C' && type->fields != NULL) { + size_t parent_offset = ctx->head->parent_offset + field->offset; + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = parent_offset; + continue; + } + if ((type->typegroup == 'H' || group == 'H') && type->size == size) { + } else { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + } + offset = ctx->head->parent_offset + field->offset; + if (ctx->fmt_offset != offset) { + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", + (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); + return -1; + } + ctx->fmt_offset += size; + if (arraysize) + ctx->fmt_offset += (arraysize - 1) * size; + --ctx->enc_count; + while (1) { + if (field == &ctx->root) { + ctx->head = NULL; + if (ctx->enc_count != 0) { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + break; + } + ctx->head->field = ++field; + if (field->type == NULL) { + --ctx->head; + field = ctx->head->field; + continue; + } else if (field->type->typegroup == 'S') { + size_t parent_offset = ctx->head->parent_offset + field->offset; + if (field->type->fields->type == NULL) continue; + field = field->type->fields; + ++ctx->head; + ctx->head->field = field; + ctx->head->parent_offset = parent_offset; + break; + } else { + break; + } + } + } while (ctx->enc_count); + ctx->enc_type = 0; + ctx->is_complex = 0; + return 0; +} +static CYTHON_INLINE PyObject * +__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) +{ + const char *ts = *tsp; + int i = 0, number; + int ndim = ctx->head->field->type->ndim; +; + ++ts; + if (ctx->new_count != 1) { + PyErr_SetString(PyExc_ValueError, + "Cannot handle repeated arrays in format string"); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + while (*ts && *ts != ')') { + switch (*ts) { + case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; + default: break; + } + number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return NULL; + if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) + return PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %d", + ctx->head->field->type->arraysize[i], number); + if (*ts != ',' && *ts != ')') + return PyErr_Format(PyExc_ValueError, + "Expected a comma in format string, got '%c'", *ts); + if (*ts == ',') ts++; + i++; + } + if (i != ndim) + return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", + ctx->head->field->type->ndim, i); + if (!*ts) { + PyErr_SetString(PyExc_ValueError, + "Unexpected end of format string, expected ')'"); + return NULL; + } + ctx->is_valid_array = 1; + ctx->new_count = 1; + *tsp = ++ts; + return Py_None; +} +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { + int got_Z = 0; + while (1) { + switch(*ts) { + case 0: + if (ctx->enc_type != 0 && ctx->head == NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + if (ctx->head != NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + return ts; + case ' ': + case '\r': + case '\n': + ++ts; + break; + case '<': + if (!__Pyx_IsLittleEndian()) { + PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '>': + case '!': + if (__Pyx_IsLittleEndian()) { + PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '=': + case '@': + case '^': + ctx->new_packmode = *ts++; + break; + case 'T': + { + const char* ts_after_sub; + size_t i, struct_count = ctx->new_count; + size_t struct_alignment = ctx->struct_alignment; + ctx->new_count = 1; + ++ts; + if (*ts != '{') { + PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + ctx->enc_count = 0; + ctx->struct_alignment = 0; + ++ts; + ts_after_sub = ts; + for (i = 0; i != struct_count; ++i) { + ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); + if (!ts_after_sub) return NULL; + } + ts = ts_after_sub; + if (struct_alignment) ctx->struct_alignment = struct_alignment; + } + break; + case '}': + { + size_t alignment = ctx->struct_alignment; + ++ts; + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + if (alignment && ctx->fmt_offset % alignment) { + ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); + } + } + return ts; + case 'x': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->fmt_offset += ctx->new_count; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->enc_packmode = ctx->new_packmode; + ++ts; + break; + case 'Z': + got_Z = 1; + ++ts; + if (*ts != 'f' && *ts != 'd' && *ts != 'g') { + __Pyx_BufFmt_RaiseUnexpectedChar('Z'); + return NULL; + } + case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': + case 'l': case 'L': case 'q': case 'Q': + case 'f': case 'd': case 'g': + case 'O': case 'p': + if (ctx->enc_type == *ts && got_Z == ctx->is_complex && + ctx->enc_packmode == ctx->new_packmode) { + ctx->enc_count += ctx->new_count; + ctx->new_count = 1; + got_Z = 0; + ++ts; + break; + } + case 's': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_count = ctx->new_count; + ctx->enc_packmode = ctx->new_packmode; + ctx->enc_type = *ts; + ctx->is_complex = got_Z; + ++ts; + ctx->new_count = 1; + got_Z = 0; + break; + case ':': + ++ts; + while(*ts != ':') ++ts; + ++ts; + break; + case '(': + if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL; + break; + default: + { + int number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return NULL; + ctx->new_count = (size_t)number; + } + } + } +} +static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) { + buf->buf = NULL; + buf->obj = NULL; + buf->strides = __Pyx_zeros; + buf->shape = __Pyx_zeros; + buf->suboffsets = __Pyx_minusones; +} +static CYTHON_INLINE int __Pyx_GetBufferAndValidate( + Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, + int nd, int cast, __Pyx_BufFmt_StackElem* stack) +{ + if (obj == Py_None || obj == NULL) { + __Pyx_ZeroBuffer(buf); + return 0; + } + buf->buf = NULL; + if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail; + if (buf->ndim != nd) { + PyErr_Format(PyExc_ValueError, + "Buffer has wrong number of dimensions (expected %d, got %d)", + nd, buf->ndim); + goto fail; + } + if (!cast) { + __Pyx_BufFmt_Context ctx; + __Pyx_BufFmt_Init(&ctx, stack, dtype); + if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; + } + if ((unsigned)buf->itemsize != dtype->size) { + PyErr_Format(PyExc_ValueError, + "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", + buf->itemsize, (buf->itemsize > 1) ? "s" : "", + dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); + goto fail; + } + if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; + return 0; +fail:; + __Pyx_ZeroBuffer(buf); + return -1; +} +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { + if (info->buf == NULL) return; + if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; + __Pyx_ReleaseBuffer(info); +} + +/* GetModuleGlobalName */ + static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) { + PyObject *result; +#if CYTHON_COMPILING_IN_CPYTHON + result = PyDict_GetItem(__pyx_d, name); + if (likely(result)) { + Py_INCREF(result); + } else { +#else + result = PyObject_GetItem(__pyx_d, name); + if (!result) { + PyErr_Clear(); +#endif + result = __Pyx_GetBuiltinName(name); + } + return result; +} + +/* PyObjectCall */ + #if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = func->ob_type->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* ExtTypeTest */ + static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + if (likely(PyObject_TypeCheck(obj, type))) + return 1; + PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", + Py_TYPE(obj)->tp_name, type->tp_name); + return 0; +} + +/* BufferFallbackError */ + static void __Pyx_RaiseBufferFallbackError(void) { + PyErr_SetString(PyExc_ValueError, + "Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!"); +} + +/* PyObjectCallMethO */ + #if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = PyCFunction_GET_FUNCTION(func); + self = PyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallOneArg */ + #if CYTHON_COMPILING_IN_CPYTHON +static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_New(1); + if (unlikely(!args)) return NULL; + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 0, arg); + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { +#ifdef __Pyx_CyFunction_USED + if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) { +#else + if (likely(PyCFunction_Check(func))) { +#endif + if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { + return __Pyx_PyObject_CallMethO(func, arg); + } + } + return __Pyx__PyObject_CallOneArg(func, arg); +} +#else +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_Pack(1, arg); + if (unlikely(!args)) return NULL; + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +#endif + +/* RaiseTooManyValuesToUnpack */ + static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* RaiseNeedMoreValuesToUnpack */ + static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* RaiseNoneIterError */ + static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); +} + +/* Import */ + static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *empty_list = 0; + PyObject *module = 0; + PyObject *global_dict = 0; + PyObject *empty_dict = 0; + PyObject *list; + #if PY_VERSION_HEX < 0x03030000 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (!py_import) + goto bad; + #endif + if (from_list) + list = from_list; + else { + empty_list = PyList_New(0); + if (!empty_list) + goto bad; + list = empty_list; + } + global_dict = PyModule_GetDict(__pyx_m); + if (!global_dict) + goto bad; + empty_dict = PyDict_New(); + if (!empty_dict) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if (strchr(__Pyx_MODULE_NAME, '.')) { + #if PY_VERSION_HEX < 0x03030000 + PyObject *py_level = PyInt_FromLong(1); + if (!py_level) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, global_dict, empty_dict, list, py_level, NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, 1); + #endif + if (!module) { + if (!PyErr_ExceptionMatches(PyExc_ImportError)) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_VERSION_HEX < 0x03030000 + PyObject *py_level = PyInt_FromLong(level); + if (!py_level) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, global_dict, empty_dict, list, py_level, NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, level); + #endif + } + } +bad: + #if PY_VERSION_HEX < 0x03030000 + Py_XDECREF(py_import); + #endif + Py_XDECREF(empty_list); + Py_XDECREF(empty_dict); + return module; +} + +/* CodeObjectCache */ + static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} + +/* AddTraceback */ + #include "compile.h" +#include "frameobject.h" +#include "traceback.h" +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyObject *py_srcfile = 0; + PyObject *py_funcname = 0; + #if PY_MAJOR_VERSION < 3 + py_srcfile = PyString_FromString(filename); + #else + py_srcfile = PyUnicode_FromString(filename); + #endif + if (!py_srcfile) goto bad; + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + #else + py_funcname = PyUnicode_FromString(funcname); + #endif + } + if (!py_funcname) goto bad; + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + Py_DECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_srcfile); + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + py_code = __pyx_find_code_object(c_line ? c_line : py_line); + if (!py_code) { + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) goto bad; + __pyx_insert_code_object(c_line ? c_line : py_line, py_code); + } + py_frame = PyFrame_New( + PyThreadState_GET(), /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + py_frame->f_lineno = py_line; + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} + +#if PY_MAJOR_VERSION < 3 +static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { + if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); + if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags); + PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name); + return -1; +} +static void __Pyx_ReleaseBuffer(Py_buffer *view) { + PyObject *obj = view->obj; + if (!obj) return; + if (PyObject_CheckBuffer(obj)) { + PyBuffer_Release(view); + return; + } + if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; } + Py_DECREF(obj); + view->obj = NULL; +} +#endif + + + /* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_PY_LONG_LONG(unsigned PY_LONG_LONG value) { + const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG) -1, const_zero = (unsigned PY_LONG_LONG) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(unsigned PY_LONG_LONG) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(unsigned PY_LONG_LONG) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); + } else if (sizeof(unsigned PY_LONG_LONG) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); + } + } else { + if (sizeof(unsigned PY_LONG_LONG) <= sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(unsigned PY_LONG_LONG) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(unsigned PY_LONG_LONG), + little, !is_unsigned); + } +} + +/* None */ + #if CYTHON_CCOMPLEX + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + return ::std::complex< float >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + return x + y*(__pyx_t_float_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + __pyx_t_float_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +/* None */ + #if CYTHON_CCOMPLEX +#else + static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + float denom = b.real * b.real + b.imag * b.imag; + z.real = (a.real * b.real + a.imag * b.imag) / denom; + z.imag = (a.imag * b.real - a.real * b.imag) / denom; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) { + __pyx_t_float_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) { + __pyx_t_float_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrtf(z.real*z.real + z.imag*z.imag); + #else + return hypotf(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + float r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + float denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + z = __Pyx_c_prodf(a, a); + return __Pyx_c_prodf(a, a); + case 3: + z = __Pyx_c_prodf(a, a); + return __Pyx_c_prodf(z, a); + case 4: + z = __Pyx_c_prodf(a, a); + return __Pyx_c_prodf(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } + r = a.real; + theta = 0; + } else { + r = __Pyx_c_absf(a); + theta = atan2f(a.imag, a.real); + } + lnr = logf(r); + z_r = expf(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cosf(z_theta); + z.imag = z_r * sinf(z_theta); + return z; + } + #endif +#endif + +/* None */ + #if CYTHON_CCOMPLEX + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return ::std::complex< double >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return x + y*(__pyx_t_double_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + __pyx_t_double_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +/* None */ + #if CYTHON_CCOMPLEX +#else + static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + double denom = b.real * b.real + b.imag * b.imag; + z.real = (a.real * b.real + a.imag * b.imag) / denom; + z.imag = (a.imag * b.real - a.real * b.imag) / denom; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrt(z.real*z.real + z.imag*z.imag); + #else + return hypot(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + double r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + double denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + z = __Pyx_c_prod(a, a); + return __Pyx_c_prod(a, a); + case 3: + z = __Pyx_c_prod(a, a); + return __Pyx_c_prod(z, a); + case 4: + z = __Pyx_c_prod(a, a); + return __Pyx_c_prod(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } + r = a.real; + theta = 0; + } else { + r = __Pyx_c_abs(a); + theta = atan2(a.imag, a.real); + } + lnr = log(r); + z_r = exp(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cos(z_theta); + z.imag = z_r * sin(z_theta); + return z; + } + #endif +#endif + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { + const int neg_one = (int) -1, const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(int) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); + } + } else { + if (sizeof(int) <= sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(int), + little, !is_unsigned); + } +} + +/* CIntFromPyVerify */ + #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value) { + const enum NPY_TYPES neg_one = (enum NPY_TYPES) -1, const_zero = (enum NPY_TYPES) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(enum NPY_TYPES) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); + } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); + } + } else { + if (sizeof(enum NPY_TYPES) <= sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(enum NPY_TYPES) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(enum NPY_TYPES), + little, !is_unsigned); + } +} + +/* CIntFromPy */ + static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) -1, const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(int) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) + case -2: + if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } +#endif + if (sizeof(int) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) -1, const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); + } +} + +/* CIntFromPy */ + static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) -1, const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(long) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(long) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) + case -2: + if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } +#endif + if (sizeof(long) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CheckBinaryVersion */ + static int __Pyx_check_binary_version(void) { + char ctversion[4], rtversion[4]; + PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); + PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); + if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compiletime version %s of module '%.100s' " + "does not match runtime version %s", + ctversion, __Pyx_MODULE_NAME, rtversion); + return PyErr_WarnEx(NULL, message, 1); + } + return 0; +} + +/* ModuleImport */ + #ifndef __PYX_HAVE_RT_ImportModule +#define __PYX_HAVE_RT_ImportModule +static PyObject *__Pyx_ImportModule(const char *name) { + PyObject *py_name = 0; + PyObject *py_module = 0; + py_name = __Pyx_PyIdentifier_FromString(name); + if (!py_name) + goto bad; + py_module = PyImport_Import(py_name); + Py_DECREF(py_name); + return py_module; +bad: + Py_XDECREF(py_name); + return 0; +} +#endif + +/* TypeImport */ + #ifndef __PYX_HAVE_RT_ImportType +#define __PYX_HAVE_RT_ImportType +static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, + size_t size, int strict) +{ + PyObject *py_module = 0; + PyObject *result = 0; + PyObject *py_name = 0; + char warning[200]; + Py_ssize_t basicsize; +#ifdef Py_LIMITED_API + PyObject *py_basicsize; +#endif + py_module = __Pyx_ImportModule(module_name); + if (!py_module) + goto bad; + py_name = __Pyx_PyIdentifier_FromString(class_name); + if (!py_name) + goto bad; + result = PyObject_GetAttr(py_module, py_name); + Py_DECREF(py_name); + py_name = 0; + Py_DECREF(py_module); + py_module = 0; + if (!result) + goto bad; + if (!PyType_Check(result)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s is not a type object", + module_name, class_name); + goto bad; + } +#ifndef Py_LIMITED_API + basicsize = ((PyTypeObject *)result)->tp_basicsize; +#else + py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); + if (!py_basicsize) + goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; +#endif + if (!strict && (size_t)basicsize > size) { + PyOS_snprintf(warning, sizeof(warning), + "%s.%s size changed, may indicate binary incompatibility. Expected %zd, got %zd", + module_name, class_name, basicsize, size); + if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; + } + else if ((size_t)basicsize != size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s has the wrong size, try recompiling. Expected %zd, got %zd", + module_name, class_name, basicsize, size); + goto bad; + } + return (PyTypeObject *)result; +bad: + Py_XDECREF(py_module); + Py_XDECREF(result); + return NULL; +} +#endif + +/* InitStrings */ + static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + #if PY_MAJOR_VERSION < 3 + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + #else + if (t->is_unicode | t->is_str) { + if (t->intern) { + *t->p = PyUnicode_InternFromString(t->s); + } else if (t->encoding) { + *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); + } else { + *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); + } + } else { + *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); + } + #endif + if (!*t->p) + return -1; + ++t; + } + return 0; +} + +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); +} +static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if CYTHON_COMPILING_IN_CPYTHON && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { +#if PY_VERSION_HEX < 0x03030000 + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +#else + if (__Pyx_PyUnicode_READY(o) == -1) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (PyUnicode_IS_ASCII(o)) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +#endif + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { + PyNumberMethods *m; + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (PyInt_Check(x) || PyLong_Check(x)) +#else + if (PyLong_Check(x)) +#endif + return __Pyx_NewRef(x); + m = Py_TYPE(x)->tp_as_number; +#if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = PyNumber_Int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = PyNumber_Long(x); + } +#else + if (m && m->nb_int) { + name = "int"; + res = PyNumber_Long(x); + } +#endif + if (res) { +#if PY_MAJOR_VERSION < 3 + if (!PyInt_Check(res) && !PyLong_Check(res)) { +#else + if (!PyLong_Check(res)) { +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type %.200s)", + name, name, Py_TYPE(res)->tp_name); + Py_DECREF(res); + return NULL; + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(x); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)b)->ob_digit; + const Py_ssize_t size = Py_SIZE(b); + if (likely(__Pyx_sst_abs(size) <= 1)) { + ival = likely(size) ? digits[0] : 0; + if (size == -1) ival = -ival; + return ival; + } else { + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +#endif /* Py_PYTHON_H */ diff --git a/BenchmarkScripts/2d_evaluation/addToConfusionMatrix_impl.c b/BenchmarkScripts/2d_evaluation/addToConfusionMatrix_impl.c new file mode 100644 index 0000000..83ac1e3 --- /dev/null +++ b/BenchmarkScripts/2d_evaluation/addToConfusionMatrix_impl.c @@ -0,0 +1,17 @@ +// cython methods to speed-up evaluation + +void addToConfusionMatrix( const unsigned char* f_prediction_p , + const unsigned char* f_groundTruth_p , + const unsigned int f_width_i , + const unsigned int f_height_i , + unsigned long long* f_confMatrix_p , + const unsigned int f_confMatDim_i ) +{ + const unsigned int size_ui = f_height_i * f_width_i; + for (unsigned int i = 0; i < size_ui; ++i) + { + const unsigned char predPx = f_prediction_p [i]; + const unsigned char gtPx = f_groundTruth_p[i]; + f_confMatrix_p[f_confMatDim_i*gtPx + predPx] += 1u; + } +} \ No newline at end of file diff --git a/BenchmarkScripts/2d_evaluation/evalInstanceLevelSemanticLabeling.py b/BenchmarkScripts/2d_evaluation/evalInstanceLevelSemanticLabeling.py new file mode 100644 index 0000000..3e3d95e --- /dev/null +++ b/BenchmarkScripts/2d_evaluation/evalInstanceLevelSemanticLabeling.py @@ -0,0 +1,635 @@ +#!/usr/bin/python +# +# Adapted from: https://github.com/mcordts/cityscapesScripts +# +# The evaluation script for instance-level semantic labeling. +# We use this script to evaluate your approach on the test set. +# You can use the script to evaluate on the validation set. +# +# usage: evalInstanceLevelSemanticLabeling.py --gt_path [gtPath] --pred_path [predictionPath] +# +# To run this script, make sure that your results contain text files +# (one for each test set image) with the content: +# relPathPrediction1 labelIDPrediction1 confidencePrediction1 +# relPathPrediction2 labelIDPrediction2 confidencePrediction2 +# relPathPrediction3 labelIDPrediction3 confidencePrediction3 +# ... +# +# - The given paths "relPathPrediction" point to images that contain +# binary masks for the described predictions, where any non-zero is +# part of the predicted instance. The paths must not contain spaces, +# must be relative to the root directory and must point to locations +# within the root directory. +# - The label IDs "labelIDPrediction" specify the class of that mask +# - The field "confidencePrediction" is a float value that assigns a +# confidence score to the mask. +# +# Note that this tool creates a file named "gtInstances.json" during its +# first run. This file helps to speed up computation and should be deleted +# whenever anything changes in the ground truth annotations or anything +# goes wrong. + +# python imports +import math +import os, sys, argparse +import fnmatch +from copy import deepcopy +import json + +try: + import numpy as np +except: + print "Failed to import numpy package." + sys.exit(-1) +try: + from PIL import Image +except: + print "Please install the module 'Pillow' for image processing, e.g." + print "pip install pillow" + sys.exit(-1) + +from instances2dict import instances2dict + + +parser = argparse.ArgumentParser() +parser.add_argument('--gt_path', required=True, help='path to gt files') +parser.add_argument('--pred_path', required=True, help='path to result files') +parser.add_argument('--output_file', default='', help='output file (default pred_path/semantic_instance.txt') +opt = parser.parse_args() +if not opt.output_file: + opt.output_file = os.path.join(opt.pred_path, 'semantic_instance.txt') + + +###################### +# Parameters +###################### + +CLASS_LABELS = ['cabinet', 'bed', 'chair', 'sofa', 'table', 'door', 'window', 'bookshelf', 'picture', 'counter', 'desk', 'curtain', 'refrigerator', 'shower curtain', 'toilet', 'sink', 'bathtub', 'otherfurniture'] +VALID_CLASS_IDS = np.array([3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 24, 28, 33, 34, 36, 39]) +ID2LABEL = {} +for i in range(len(CLASS_LABELS)): + ID2LABEL[VALID_CLASS_IDS[i]] = CLASS_LABELS[i] + +# overlaps for evaluation +opt.overlaps = np.arange(0.5,1.,0.05) +# minimum region size for evaluation [pixels] +opt.minRegionSizes = np.array( [ 100 , 1000 , 1000 ] ) +# distance thresholds [m] +opt.distanceThs = np.array( [ float('inf') , 100 , 50 ] ) +# distance confidences +opt.distanceConfs = np.array( [ -float('inf') , 0.5 , 0.5 ] ) + +opt.gtInstancesFile = os.path.join(os.path.dirname(os.path.realpath(__file__)),'gtInstances.json') + + +# Print an error message and quit +def printError(message, user_fault=False): + print('ERROR: ' + str(message)) + if user_fault: + sys.exit(2) + sys.exit(-1) + +# Returns the directory name for the given filename, e.g. +# fileName = "/foo/bar/foobar.txt" +# return value is "bar" +# Not much error checking though +def getDirectory(fileName): + dirName = os.path.dirname(fileName) + return os.path.basename(dirName) + +# Make sure that the given path exists +def ensurePath(path): + if not path: + return + if not os.path.isdir(path): + os.makedirs(path) + +# Write a dictionary as json file +def writeDict2JSON(dictName, fileName): + with open(fileName, 'w') as f: + f.write(json.dumps(dictName, default=lambda o: o.__dict__, sort_keys=True, indent=4)) + + +# Read prediction info +# imgFile, predId, confidence +def readPredInfo(predInfoFileName): + predInfo = {} + if (not os.path.isfile(predInfoFileName)): + printError("Infofile '{}' for the predictions not found.".format(predInfoFileName)) + abs_pred_path = os.path.abspath(opt.pred_path) + with open(predInfoFileName, 'r') as f: + for line in f: + splittedLine = line.split(" ") + if len(splittedLine) != 3: + printError( "Invalid prediction file. Expected content: relPathPrediction1 labelIDPrediction1 confidencePrediction1", user_fault=True ) + if os.path.isabs(splittedLine[0]): + printError( "Invalid prediction file. First entry in each line must be a relative path.", user_fault=True ) + + filename = os.path.join( os.path.dirname(predInfoFileName),splittedLine[0] ) + filename = os.path.abspath( filename ) + + # check if that file is actually somewhere within the prediction root + if os.path.commonprefix( [filename,abs_pred_path] ) != abs_pred_path: + printError( "Predicted mask {} in prediction text file {} points outside of prediction path.".format(filename,predInfoFileName), user_fault=True ) + + imageInfo = {} + imageInfo["labelID"] = int(float(splittedLine[1])) + imageInfo["conf"] = float(splittedLine[2]) + predInfo[filename] = imageInfo + + return predInfo + +# Routine to read ground truth image +def readGTImage(gtImageFileName): + return Image.open(gtImageFileName) + +# either read or compute a dictionary of all ground truth instances +def getGtInstances(groundTruthList): + gtInstances = {} + # if there is a global statistics json, then load it + if (os.path.isfile(opt.gtInstancesFile)): + print "Loading ground truth instances from JSON." + with open(opt.gtInstancesFile) as json_file: + gtInstances = json.load(json_file) + # otherwise create it + else: + print "Creating ground truth instances from png files." + gtInstances = instances2dict(groundTruthList, CLASS_LABELS, VALID_CLASS_IDS) + writeDict2JSON(gtInstances, opt.gtInstancesFile) + + return gtInstances + +# Filter instances, ignore labels without instances +def filterGtInstances(singleImageInstances): + instanceDict = {} + for labelName in singleImageInstances: + if not labelName in CLASS_LABELS: + continue + instanceDict[labelName] = singleImageInstances[labelName] + return instanceDict + +# match ground truth instances with predicted instances +def matchGtWithPreds(predictionList,groundTruthList,gtInstances): + matches = {} + print "Matching {} pairs of images...".format(len(predictionList)) + + count = 0 + for (pred,gt) in zip(predictionList,groundTruthList): + # key for dicts + dictKey = os.path.abspath(gt) + + # Read input files + gtImage = readGTImage(gt) + predInfo = readPredInfo(pred) + + # Get and filter ground truth instances + unfilteredInstances = gtInstances[ dictKey ] + curGtInstancesOrig = filterGtInstances(unfilteredInstances) + + # Try to assign all predictions + (curGtInstances,curPredInstances) = assignGt2Preds(curGtInstancesOrig, gtImage, predInfo) + + # append to global dict + matches[ dictKey ] = {} + matches[ dictKey ]["groundTruth"] = curGtInstances + matches[ dictKey ]["prediction"] = curPredInstances + + count += 1 + sys.stdout.write("\rImages Processed: {}".format(count)) + sys.stdout.flush() + print "" + + return matches + +# For a given frame, assign all predicted instances to ground truth instances +def assignGt2Preds(gtInstancesOrig, gtImage, predInfo): + # In this method, we create two lists + # - predInstances: contains all predictions and their associated gt + # - gtInstances: contains all gt instances and their associated predictions + predInstances = {} + predInstCount = 0 + + # Create a prediction array for each class + for label in CLASS_LABELS: + predInstances[label] = [] + + # We already know about the gt instances + # Add the matching information array + gtInstances = deepcopy(gtInstancesOrig) + for label in gtInstances: + for gt in gtInstances[label]: + gt["matchedPred"] = [] + + # Make the gt a numpy array + gtNp = np.array(gtImage) + + # Get a mask of void labels in the groundtruth + voidLabelIDList = [] + for labelid in VALID_CLASS_IDS: + voidLabelIDList.append(labelid) + boolVoid = np.in1d(gtNp, voidLabelIDList).reshape(gtNp.shape) + + # Loop through all prediction masks + for predImageFile in predInfo: + # Additional prediction info + labelID = predInfo[predImageFile]["labelID"] + predConf = predInfo[predImageFile]["conf"] + + # maybe we are not interested in that label + if not int(labelID) in ID2LABEL: + continue + + # label name + labelName = ID2LABEL[int(labelID)] + + # Read the mask + predImage = Image.open(predImageFile) + predImage = predImage.convert("L") + predNp = np.array(predImage) + + # make the image really binary, i.e. everything non-zero is part of the prediction + boolPredInst = predNp != 0 + predPixelCount = np.count_nonzero( boolPredInst ) + + # skip if actually empty + if not predPixelCount: + continue + + # The information we want to collect for this instance + predInstance = {} + predInstance["imgName"] = predImageFile + predInstance["predID"] = predInstCount + predInstance["labelID"] = int(labelID) + predInstance["pixelCount"] = predPixelCount + predInstance["confidence"] = predConf + # Determine the number of pixels overlapping void + predInstance["voidIntersection"] = np.count_nonzero( np.logical_and(boolVoid, boolPredInst) ) + + # A list of all overlapping ground truth instances + matchedGt = [] + + # Loop through all ground truth instances with matching label + # This list contains all ground truth instances that distinguish groups + # We do not know, if a certain instance is actually a single object or a group + # e.g. car or cargroup + # However, for now we treat both the same and do the rest later + for (gtNum,gtInstance) in enumerate(gtInstancesOrig[labelName]): + + intersection = np.count_nonzero( np.logical_and( gtNp == gtInstance["instID"] , boolPredInst) ) + + # If they intersect add them as matches to both dicts + if (intersection > 0): + gtCopy = gtInstance.copy() + predCopy = predInstance.copy() + + # let the two know their intersection + gtCopy["intersection"] = intersection + predCopy["intersection"] = intersection + + # append ground truth to matches + matchedGt.append(gtCopy) + # append prediction to ground truth instance + gtInstances[labelName][gtNum]["matchedPred"].append(predCopy) + + predInstance["matchedGt"] = matchedGt + predInstCount += 1 + predInstances[labelName].append(predInstance) + + return (gtInstances,predInstances) + + +def evaluateMatches(matches): + # In the end, we need two vectors for each class and for each overlap + # The first vector (y_true) is binary and is 1, where the ground truth says true, + # and is 0 otherwise. + # The second vector (y_score) is float [0...1] and represents the confidence of + # the prediction. + # + # We represent the following cases as: + # | y_true | y_score + # gt instance with matched prediction | 1 | confidence + # gt instance w/o matched prediction | 1 | 0.0 + # false positive prediction | 0 | confidence + # + # The current implementation makes only sense for an overlap threshold >= 0.5, + # since only then, a single prediction can either be ignored or matched, but + # never both. Further, it can never match to two gt instances. + # For matching, we vary the overlap and do the following steps: + # 1.) remove all predictions that satisfy the overlap criterion with an ignore region (either void or *group) + # 2.) remove matches that do not satisfy the overlap + # 3.) mark non-matched predictions as false positive + + # AP + overlaps = opt.overlaps + # region size + minRegionSizes = opt.minRegionSizes + # distance thresholds + distThs = opt.distanceThs + # distance confidences + distConfs = opt.distanceConfs + # only keep the first, if distances are not available + #if not opt.distanceAvailable: + minRegionSizes = [ minRegionSizes[0] ] + distThs = [ distThs [0] ] + distConfs = [ distConfs [0] ] + + # last three must be of same size + if len(distThs) != len(minRegionSizes): + printError("Number of distance thresholds and region sizes different") + if len(distThs) != len(distConfs): + printError("Number of distance thresholds and confidences different") + + # Here we hold the results + # First dimension is class, second overlap + ap = np.zeros( (len(distThs) , len(CLASS_LABELS) , len(overlaps)) , np.float ) + + for dI,(minRegionSize,distanceTh,distanceConf) in enumerate(zip(minRegionSizes,distThs,distConfs)): + for (oI,overlapTh) in enumerate(overlaps): + for (lI,labelName) in enumerate(CLASS_LABELS): + y_true = np.empty( 0 ) + y_score = np.empty( 0 ) + # count hard false negatives + hardFns = 0 + # found at least one gt and predicted instance? + haveGt = False + havePred = False + + for img in matches: + predInstances = matches[img]["prediction" ][labelName] + gtInstances = matches[img]["groundTruth"][labelName] + # filter groups in ground truth + gtInstances = [ gt for gt in gtInstances if gt["instID"]>=1000 and gt["pixelCount"]>=minRegionSize and gt["medDist"]<=distanceTh and gt["distConf"]>=distanceConf ] + + if gtInstances: + haveGt = True + if predInstances: + havePred = True + + curTrue = np.ones ( len(gtInstances) ) + curScore = np.ones ( len(gtInstances) ) * (-float("inf")) + curMatch = np.zeros( len(gtInstances) , dtype=np.bool ) + + # collect matches + for (gtI,gt) in enumerate(gtInstances): + foundMatch = False + for pred in gt["matchedPred"]: + overlap = float(pred["intersection"]) / (gt["pixelCount"]+pred["pixelCount"]-pred["intersection"]) + if overlap > overlapTh: + # the score + confidence = pred["confidence"] + + # if we already hat a prediction for this groundtruth + # the prediction with the lower score is automatically a false positive + if curMatch[gtI]: + maxScore = max( curScore[gtI] , confidence ) + minScore = min( curScore[gtI] , confidence ) + curScore[gtI] = maxScore + # append false positive + curTrue = np.append(curTrue,0) + curScore = np.append(curScore,minScore) + curMatch = np.append(curMatch,True) + # otherwise set score + else: + foundMatch = True + curMatch[gtI] = True + curScore[gtI] = confidence + + if not foundMatch: + hardFns += 1 + + # remove non-matched ground truth instances + curTrue = curTrue [ curMatch==True ] + curScore = curScore[ curMatch==True ] + + # collect non-matched predictions as false positive + for pred in predInstances: + foundGt = False + for gt in pred["matchedGt"]: + overlap = float(gt["intersection"]) / (gt["pixelCount"]+pred["pixelCount"]-gt["intersection"]) + if overlap > overlapTh: + foundGt = True + break + if not foundGt: + # collect number of void and *group pixels + nbIgnorePixels = pred["voidIntersection"] + for gt in pred["matchedGt"]: + # group? + if gt["instID"] < 1000: + nbIgnorePixels += gt["intersection"] + # small ground truth instances + if gt["pixelCount"] < minRegionSize or gt["medDist"]>distanceTh or gt["distConf"]15.3f}".format(apAvg ) + sep + line += sep + "{:>15.3f}".format(ap50o ) + sep + print line + + allApAvg = avgDict["allAp"] + allAp50o = avgDict["allAp50%"] + + #if not args.csv: + # print "-"*lineLen) + print "-"*lineLen + line = "{:<15}".format("average") + sep + col1 + line += "{:>15.3f}".format(allApAvg) + sep + line += "{:>15.3f}".format(allAp50o) + sep + print line + print "" + +def prepareJSONDataForResults(avgDict, aps): + JSONData = {} + JSONData["averages"] = avgDict + JSONData["overlaps"] = opt.overlaps.tolist() + JSONData["minRegionSizes"] = opt.minRegionSizes.tolist() + JSONData["distanceThresholds"] = opt.distanceThs.tolist() + JSONData["minStereoDensities"] = opt.distanceConfs.tolist() + JSONData["instLabels"] = CLASS_LABELS + JSONData["resultApMatrix"] = aps.tolist() + + return JSONData + +def writeResultToFile(result, output_file): + _SPLITTER = ',' + with open(output_file, 'w') as f: + f.write(_SPLITTER.join(['class', 'class id', 'ap', 'ap50']) + '\n') + for i in range(len(VALID_CLASS_IDS)): + class_name = CLASS_LABELS[i] + class_id = VALID_CLASS_IDS[i] + ap = result["averages"]["classes"][class_name]["ap"] + ap50 = result["averages"]["classes"][class_name]["ap50%"] + f.write(_SPLITTER.join([str(x) for x in [class_name, class_id, ap, ap50]]) + '\n') + +# Work through image list +def evaluateImgLists(predictionList, groundTruthList): + # get dictionary of all ground truth instances + gtInstances = getGtInstances(groundTruthList) + # match predictions and ground truth + matches = matchGtWithPreds(predictionList,groundTruthList,gtInstances) + #writeDict2JSON(matches,"matches.json) + # evaluate matches + apScores = evaluateMatches(matches) + # averages + avgDict = computeAverages(apScores) + # result dict + resDict = prepareJSONDataForResults(avgDict, apScores) + #if args.JSONOutput: + # create output folder if necessary + path = os.path.dirname(opt.output_file) + ensurePath(path) + # Write APs to JSON + #writeDict2JSON(resDict, opt.output_file) + writeResultToFile(resDict, opt.output_file) + + printResults(avgDict) + + return resDict + +# The main method +def main(argv): + + #pred_files = [os.path.join(opt.pred_path, file) for file in os.listdir(opt.pred_path) if not os.path.isdir(os.path.join(opt.pred_path, file)) and file.endswith('.txt')] + pred_files = [] + # find all the text files recursively + for root, dirs, files in os.walk(opt.pred_path): + for file in files: + if file.endswith(".txt"): + pred_files.append(os.path.join(root, file)) + gt_files = [] + if len(pred_files) == 0: + printError("No result files found.", user_fault=True) + for i in range(len(pred_files)): + gt_file = os.path.join(opt.gt_path, os.path.splitext(os.path.basename(pred_files[i]))[0] + '.png') + if not os.path.isfile(gt_file): + printError("Result file {} does not match any gt file".format(pred_files[i]), user_fault=True) + gt_files.append(gt_file) + #print pred_files + #print gt_files + + # print some info for user + print "Note that this tool uses the file '{}' to cache the ground truth instances.".format(opt.gtInstancesFile) + print "If anything goes wrong, or if you change the ground truth, please delete the file." + + # evaluate + evaluateImgLists(pred_files, gt_files) + + return + +# call the main method +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/BenchmarkScripts/2d_evaluation/evalPixelLevelSemanticLabeling.py b/BenchmarkScripts/2d_evaluation/evalPixelLevelSemanticLabeling.py new file mode 100644 index 0000000..046744b --- /dev/null +++ b/BenchmarkScripts/2d_evaluation/evalPixelLevelSemanticLabeling.py @@ -0,0 +1,287 @@ +#!/usr/bin/python +# +# Adapted from: https://github.com/mcordts/cityscapesScripts +# +# The evaluation script for pixel-level semantic labeling. +# We use this script to evaluate your approach on the test set. +# You can use the script to evaluate on the validation set. +# +# usage: evalPixelLevelSemanticLabeling.py --gt_path [gtPath] --pred_path [predictionPath] +# +# Note that the script is a lot faster, if you enable cython support. +# WARNING: Cython only tested for Ubuntu 64bit OS. +# To enable cython, run +# setup.py build_ext --inplace +# +# To run this script, make sure that your results are images, +# where pixels encode the class IDs as defined in labels.py. +# Note that the regular ID is used, not the train ID. +# Further note that many classes are ignored from evaluation. +# Thus, authors are not expected to predict these classes and all +# pixels with a ground truth label that is ignored are ignored in +# evaluation. + +# python imports +import os, sys, argparse +import math +import platform +import fnmatch + +try: + import numpy as np +except: + print("Failed to import numpy package.") + sys.exit(-1) +try: + from PIL import Image +except: + print("Please install the module 'Pillow' for image processing, e.g.") + print("pip install pillow") + sys.exit(-1) +try: + from itertools import izip +except ImportError: + izip = zip + +# C Support +# Enable the cython support for faster evaluation +# Only tested for Ubuntu 64bit OS +CSUPPORT = True +# Check if C-Support is available for better performance +if CSUPPORT: + try: + import addToConfusionMatrix + except: + CSUPPORT = False + +parser = argparse.ArgumentParser() +parser.add_argument('--gt_path', required=True, help='path to gt files') +parser.add_argument('--pred_path', required=True, help='path to result files') +parser.add_argument('--output_file', default='', help='output file (default pred_path/semantic_label.txt') +opt = parser.parse_args() +if not opt.output_file: + opt.output_file = os.path.join(opt.pred_path, 'semantic_label.txt') + + + +CLASS_LABELS = ['wall', 'floor', 'cabinet', 'bed', 'chair', 'sofa', 'table', 'door', 'window', 'bookshelf', 'picture', 'counter', 'desk', 'curtain', 'refrigerator', 'shower curtain', 'toilet', 'sink', 'bathtub', 'otherfurniture'] +VALID_CLASS_IDS = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 24, 28, 33, 34, 36, 39]) +ALL_CLASS_IDS = np.arange(40 + 1) + +######################### +# Methods +######################### + +# Print an error message and quit +def printError(message, user_fault=False): + print('ERROR: ' + str(message)) + if user_fault: + sys.exit(2) + sys.exit(-1) + + +# Generate empty confusion matrix and create list of relevant labels +def generateMatrix(): + # generate for all labels, regardless of being ignored + max_id = np.max(ALL_CLASS_IDS) + return np.zeros(shape=(max_id+1, max_id+1),dtype=np.ulonglong) + + +# Get absolute or normalized value from field in confusion matrix. +def getMatrixFieldValue(confMatrix, i, j, normalized=True): + if normalized: + rowSum = confMatrix[i].sum() + if (rowSum == 0): + return float('nan') + return float(confMatrix[i][j]) / rowSum + else: + return confMatrix[i][j] + +# Calculate and return IOU score for a particular label +def getIouScoreForLabel(label, confMatrix): + if not label in VALID_CLASS_IDS: + return float('nan') + + # the number of true positive pixels for this label + # the entry on the diagonal of the confusion matrix + tp = np.longlong(confMatrix[label,label]) + + # the number of false negative pixels for this label + # the row sum of the matching row in the confusion matrix + # minus the diagonal entry + fn = np.longlong(confMatrix[label,:].sum()) - tp + + # the number of false positive pixels for this labels + # Only pixels that are not on a pixel with ground truth label that is ignored + # The column sum of the corresponding column in the confusion matrix + # without the ignored rows and without the actual label of interest + notIgnored = [l for l in VALID_CLASS_IDS if not l==label] + fp = np.longlong(confMatrix[notIgnored,label].sum()) + + # the denominator of the IOU score + denom = (tp + fp + fn) + if denom == 0: + return float('nan') + + # return IOU + return float(tp) / denom + +# Calculate prior for a particular class id. +def getPrior(label, confMatrix): + return float(confMatrix[label,:].sum()) / confMatrix.sum() + +# Get average of scores. +# Only computes the average over valid entries. +def getScoreAverage(scoreList): + validScores = 0 + scoreSum = 0.0 + for score in scoreList: + if not math.isnan(scoreList[score]): + validScores += 1 + scoreSum += scoreList[score] + if validScores == 0: + return float('nan') + return scoreSum / validScores + +# Print intersection-over-union scores for all classes. +def printClassScores(scoreList): + print 'classes IoU' + print '----------------------------' + for i in range(len(VALID_CLASS_IDS)): + label = VALID_CLASS_IDS[i] + labelName = CLASS_LABELS[i] + iouStr = "{0:>5.3f}".format(scoreList[labelName]) + print ("{0:<14s}: ".format(labelName) + iouStr) + +# Save results. +def write_result_file(conf, scores, filename): + _SPLITTER = ',' + with open(filename, 'w') as f: + f.write('iou scores\n') + for i in range(len(VALID_CLASS_IDS)): + label = VALID_CLASS_IDS[i] + label_name = CLASS_LABELS[i] + iou = scores[label_name] + f.write('{0:<14s}({1:<2d}): {2:>5.3f}\n'.format(label_name, label, iou)) + f.write('\nconfusion matrix\n') + for i in range(len(VALID_CLASS_IDS)): + f.write('\t{0:<14s}({1:<2d})'.format(CLASS_LABELS[i], VALID_CLASS_IDS[i])) + for r in range(len(VALID_CLASS_IDS)): + f.write('{0:<14s}({1:<2d})'.format(CLASS_LABELS[r], VALID_CLASS_IDS[r])) + for c in range(len(VALID_CLASS_IDS)): + f.write('\t{0:>5.3f}'.format(conf[r,c])) + f.write('\n') + print 'wrote results to', filename + + +# Evaluate image lists pairwise. +def evaluateImgLists(predictionImgList, groundTruthImgList, outputFile): + if len(predictionImgList) != len(groundTruthImgList): + printError("List of images for prediction and groundtruth are not of equal size.", user_fault=True) + confMatrix = generateMatrix() + perImageStats = {} + nbPixels = 0 + + print 'Evaluating', len(predictionImgList), 'pairs of images...' + + # Evaluate all pairs of images and save them into a matrix + for i in range(len(predictionImgList)): + predictionImgFileName = predictionImgList[i] + groundTruthImgFileName = groundTruthImgList[i] + #print "Evaluate ", predictionImgFileName, "<>", groundTruthImgFileName + nbPixels += evaluatePair(predictionImgFileName, groundTruthImgFileName, confMatrix, perImageStats) + + # sanity check + if confMatrix.sum() != nbPixels: + printError('Number of analyzed pixels and entries in confusion matrix disagree: confMatrix {}, pixels {}'.format(confMatrix.sum(),nbPixels)) + + sys.stdout.write("\rImages Processed: {}".format(i+1)) + sys.stdout.flush() + print "" + + # sanity check + if confMatrix.sum() != nbPixels: + printError('Number of analyzed pixels and entries in confusion matrix disagree: contMatrix {}, pixels {}'.format(confMatrix.sum(),nbPixels)) + + # Calculate IOU scores on class level from matrix + classScoreList = {} + for i in range(len(VALID_CLASS_IDS)): + labelName = CLASS_LABELS[i] + label = VALID_CLASS_IDS[i] + classScoreList[labelName] = getIouScoreForLabel(label, confMatrix) + + # Print IOU scores + printClassScores(classScoreList) + iouAvgStr = "{avg:5.3f}".format(avg=getScoreAverage(classScoreList)) + print "--------------------------------" + print "Score Average : " + iouAvgStr + print "--------------------------------" + print "" + + # write result file + write_result_file(confMatrix, classScoreList, outputFile) + +# Main evaluation method. Evaluates pairs of prediction and ground truth +# images which are passed as arguments. +def evaluatePair(predictionImgFileName, groundTruthImgFileName, confMatrix, perImageStats): + # Loading all resources for evaluation. + try: + predictionImg = Image.open(predictionImgFileName) + predictionNp = np.array(predictionImg) + except Exception, e: + printError("Unable to load " + predictionImgFileName + ": " + str(e)) + try: + groundTruthImg = Image.open(groundTruthImgFileName) + groundTruthNp = np.array(groundTruthImg) + except Exception, e: + printError("Unable to load " + groundTruthImgFileName + ": " + str(e)) + + # Check for equal image sizes + if not (predictionImg.size[0] == groundTruthImg.size[0] or predictionImg.size[0] == 640 and predictionImg.size[1] == 480): + printError("Invalid image size for " + predictionImgFileName, user_fault=True) + if ( len(predictionNp.shape) != 2 ): + printError("Predicted image has multiple channels.", user_fault=True) + + # resize for evaluation + predictionImg = predictionImg.resize((640, 480), Image.NEAREST) + predictionNp = np.array(predictionImg) + groundTruthImg = groundTruthImg.resize((640, 480), Image.NEAREST) + groundTruthNp = np.array(groundTruthImg) + imgWidth = predictionImg.size[0] + imgHeight = predictionImg.size[1] + nbPixels = imgWidth*imgHeight + # Evaluate images + if (CSUPPORT): + # using cython + confMatrix = addToConfusionMatrix.cEvaluatePair(predictionNp, groundTruthNp, confMatrix, VALID_CLASS_IDS.tolist()) + else: + # the slower python way + for (groundTruthImgPixel,predictionImgPixel) in izip(groundTruthImg.getdata(),predictionImg.getdata()): + if (not groundTruthImgPixel in VALID_CLASS_IDS): + printError("Unknown label with id {:}".format(groundTruthImgPixel)) + + confMatrix[groundTruthImgPixel][predictionImgPixel] += 1 + return nbPixels + +# The main method +def main(): + + pred_files = os.listdir(opt.pred_path) + gt_files = [] + if len(pred_files) == 0: + printError("No result files found.", user_fault=True) + for i in range(len(pred_files)): + gt_file = os.path.join(opt.gt_path, pred_files[i]) + if not os.path.isfile(gt_file): + printError("Result file {} does not match any gt file".format(pred_files[i]), user_fault=True) + gt_files.append(gt_file) + pred_files[i] = os.path.join(opt.pred_path, pred_files[i]) + + # evaluate + evaluateImgLists(pred_files, gt_files, opt.output_file) + + return + +# call the main method +if __name__ == "__main__": + main() diff --git a/BenchmarkScripts/2d_evaluation/instance.py b/BenchmarkScripts/2d_evaluation/instance.py new file mode 100644 index 0000000..562a69f --- /dev/null +++ b/BenchmarkScripts/2d_evaluation/instance.py @@ -0,0 +1,47 @@ +#!/usr/bin/python +# +# Instance class +# + +class Instance(object): + instID = 0 + labelID = 0 + pixelCount = 0 + medDist = -1 + distConf = 0.0 + + def __init__(self, imgNp, instID): + if (instID == -1): + return + self.instID = int(instID) + self.labelID = int(self.getLabelID(instID)) + self.pixelCount = int(self.getInstancePixels(imgNp, instID)) + + def getLabelID(self, instID): + return int(instID // 1000) + + def getInstancePixels(self, imgNp, instLabel): + return (imgNp == instLabel).sum() + + def toJSON(self): + return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) + + def toDict(self): + buildDict = {} + buildDict["instID"] = self.instID + buildDict["labelID"] = self.labelID + buildDict["pixelCount"] = self.pixelCount + buildDict["medDist"] = self.medDist + buildDict["distConf"] = self.distConf + return buildDict + + def fromJSON(self, data): + self.instID = int(data["instID"]) + self.labelID = int(data["labelID"]) + self.pixelCount = int(data["pixelCount"]) + if ("medDist" in data): + self.medDist = float(data["medDist"]) + self.distConf = float(data["distConf"]) + + def __str__(self): + return "("+str(self.instID)+")" \ No newline at end of file diff --git a/BenchmarkScripts/2d_evaluation/instances2dict.py b/BenchmarkScripts/2d_evaluation/instances2dict.py new file mode 100644 index 0000000..7dc224f --- /dev/null +++ b/BenchmarkScripts/2d_evaluation/instances2dict.py @@ -0,0 +1,67 @@ +#!/usr/bin/python +# +# Convert instances from png files to a dictionary +# + +from __future__ import print_function +import os, sys +from instance import Instance +from PIL import Image +import numpy as np + +def instances2dict(imageFileList, class_labels, class_ids, verbose=False): + imgCount = 0 + instanceDict = {} + label2id = {} + id2label = {} + for i in range(len(class_labels)): + label2id[class_labels[i]] = class_ids[i] + id2label[class_ids[i]] = class_labels[i] + + if not isinstance(imageFileList, list): + imageFileList = [imageFileList] + + if verbose: + print("Processing {} images...".format(len(imageFileList))) + + for imageFileName in imageFileList: + # Load image + img = Image.open(imageFileName) + + # Image as numpy array + imgNp = np.array(img) + + # Initialize label categories + instances = {} + for label in class_labels: + instances[label] = [] + + # Loop through all instance ids in instance image + for instanceId in np.unique(imgNp): + instanceObj = Instance(imgNp, instanceId) + if instanceObj.labelID in class_ids: + instances[id2label[instanceObj.labelID]].append(instanceObj.toDict()) + + imgKey = os.path.abspath(imageFileName) + instanceDict[imgKey] = instances + imgCount += 1 + + if verbose: + print("\rImages Processed: {}".format(imgCount), end=' ') + sys.stdout.flush() + + if verbose: + print("") + + return instanceDict + +def main(argv): + fileList = [] + if (len(argv) > 2): + for arg in argv: + if ("png" in arg): + fileList.append(arg) + instances2dict(fileList, True) + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/BenchmarkScripts/2d_evaluation/setup.py b/BenchmarkScripts/2d_evaluation/setup.py new file mode 100644 index 0000000..cea8601 --- /dev/null +++ b/BenchmarkScripts/2d_evaluation/setup.py @@ -0,0 +1,21 @@ +#!/usr/bin/python +# +# Enable cython support for eval scripts +# Run as +# setup.py build_ext --inplace +# +# WARNING: Only tested for Ubuntu 64bit OS. + +try: + from distutils.core import setup + from Cython.Build import cythonize +except: + print("Unable to setup. Please use pip to install: cython") + print("sudo pip install cython") +import os +import numpy + +os.environ["CC"] = "g++" +os.environ["CXX"] = "g++" + +setup(ext_modules = cythonize("addToConfusionMatrix.pyx"),include_dirs=[numpy.get_include()]) diff --git a/BenchmarkScripts/2d_helpers/convert_scannet_instance_image.py b/BenchmarkScripts/2d_helpers/convert_scannet_instance_image.py new file mode 100644 index 0000000..21eaccb --- /dev/null +++ b/BenchmarkScripts/2d_helpers/convert_scannet_instance_image.py @@ -0,0 +1,90 @@ +# Example script to convert instance images from the *_2d-instance.zip or *_2d-instance-filt.zip data for each scan. +# Note: already preprocessed data for a set of frames subsampled from the full datasets is available to download through the ScanNet download. +# Input: +# - path to instance image to convert +# - path to the corresponding label image +# - label mapping file (scannetv2-labels.combined.tsv) +# - output image file +# Outputs the instance image with each pixel represented by label * 1000 + instance_id as an 16-bit image +# Labels are mapped to the nyu40 set, and walls/floors/ceilings are not assigned instances (instance_id = 0) +# +# example usage: convert_scannet_instance_image.py --input_instance_file [path to input instance image] --input_label_file [path to corresponding label image] --label_map_file [path to scannetv2-labels.combined.tsv] --output_file [output image file] +# (see util.visualize_instance_image() for producing a colored visualization) + + +# python imports +import math +import os, sys, argparse +import inspect + +try: + import numpy as np +except: + print "Failed to import numpy package." + sys.exit(-1) +try: + import imageio +except: + print("Please install the module 'imageio' for image processing, e.g.") + print("pip install imageio") + sys.exit(-1) + +currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +parentdir = os.path.dirname(currentdir) +sys.path.insert(0,parentdir) +import util + +parser = argparse.ArgumentParser() +parser.add_argument('--input_instance_file', required=True, help='path to input instance image') +parser.add_argument('--input_label_file', required=True, help='path to corresponding label image') +parser.add_argument('--label_map_file', required=True, help='path to scannet-labels.combined.tsv') +parser.add_argument('--output_file', required=True, help='output image file') +opt = parser.parse_args() + + +def map_label_image(image, label_mapping): + mapped = np.copy(image) + for k,v in label_mapping.iteritems(): + mapped[image==k] = v + return mapped.astype(np.uint8) + + +def make_instance_image(label_image, instance_image): + output = np.zeros_like(instance_image, dtype=np.uint16) + # oldinst2labelinst = {} + label_instance_counts = {} + old_insts = np.unique(instance_image) + for inst in old_insts: + label = label_image[instance_image==inst][0] + if label in label_instance_counts: + inst_count = label_instance_counts[label] + 1 + label_instance_counts[label] = inst_count + else: + inst_count = 1 + label_instance_counts[label] = inst_count + # oldinst2labelinst[inst] = (label, inst_count) + output[instance_image==inst] = label * 1000 + inst_count + return output + + +def get_labels_from_instance(instance_image): + labels = instance_image // 1000 + return labels.astype(np.uint8) + + +def main(): + instance_image = np.array(imageio.imread(opt.input_instance_file)) + label_image = np.array(imageio.imread(opt.input_label_file)) + label_map = util.read_label_mapping(opt.label_map_file, label_from='id', label_to='nyu40id') + mapped_label = map_label_image(label_image, label_map) + output_instance_image = make_instance_image(mapped_label, instance_image) + imageio.imwrite(opt.output_file, output_instance_image) + # uncomment to save out visualization + #util.visualize_instance_image(os.path.splitext(opt.output_file)[0] + '_vis.jpg', output_instance_image) + #util.visualize_instance_image(os.path.splitext(opt.output_file)[0] + '_vis-labels.jpg', get_labels_from_instance(output_instance_image)) + + +if __name__ == '__main__': + main() + + diff --git a/BenchmarkScripts/2d_helpers/convert_scannet_label_image.py b/BenchmarkScripts/2d_helpers/convert_scannet_label_image.py new file mode 100644 index 0000000..bf242f2 --- /dev/null +++ b/BenchmarkScripts/2d_helpers/convert_scannet_label_image.py @@ -0,0 +1,61 @@ +# Example script to convert label images from the *_2d-label.zip or *_2d-label-filt.zip data for each scan. +# Note: already preprocessed data for a set of frames subsampled from the full datasets is available to download through the ScanNet download. +# Input: +# - path to label image to convert +# - label mapping file (scannetv2-labels.combined.tsv) +# - output image file +# Outputs the label image with nyu40 labels as an 8-bit image +# +# example usage: convert_scannet_label_image.py --input_file [path to input label image] --label_map_file [path to scannet-labels.combined.tsv] --output_file [output image file] +# (see util.visualize_label_image() for producing a colored visualization) + + +# python imports +import math +import os, sys, argparse +import inspect + +try: + import numpy as np +except: + print "Failed to import numpy package." + sys.exit(-1) +try: + import imageio +except: + print("Please install the module 'imageio' for image processing, e.g.") + print("pip install imageio") + sys.exit(-1) + +currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +parentdir = os.path.dirname(currentdir) +sys.path.insert(0,parentdir) +import util + +parser = argparse.ArgumentParser() +parser.add_argument('--input_file', required=True, help='path to input label image') +parser.add_argument('--label_map_file', required=True, help='path to scannetv2-labels.combined.tsv') +parser.add_argument('--output_file', required=True, help='output image file') +opt = parser.parse_args() + + +def map_label_image(image, label_mapping): + mapped = np.copy(image) + for k,v in label_mapping.iteritems(): + mapped[image==k] = v + return mapped.astype(np.uint8) + + +def main(): + image = np.array(imageio.imread(opt.input_file)) + label_map = util.read_label_mapping(opt.label_map_file, label_from='id', label_to='nyu40id') + mapped_image = map_label_image(image, label_map) + imageio.imwrite(opt.output_file, mapped_image) + # uncomment to save out visualization + # util.visualize_label_image(os.path.splitext(opt.output_file)[0] + '_vis.jpg', mapped_image) + + +if __name__ == '__main__': + main() + + diff --git a/BenchmarkScripts/3d_evaluation/evaluate_semantic_instance.py b/BenchmarkScripts/3d_evaluation/evaluate_semantic_instance.py new file mode 100644 index 0000000..a70d98a --- /dev/null +++ b/BenchmarkScripts/3d_evaluation/evaluate_semantic_instance.py @@ -0,0 +1,401 @@ +# Evaluates semantic instance task +# Adapted from the CityScapes evaluation: https://github.com/mcordts/cityscapesScripts/tree/master/cityscapesscripts/evaluation +# Input: +# - path to .txt prediction files +# - path to .txt ground truth files +# - output file to write results to +# Each .txt prediction file look like: +# [(pred0) rel. path to pred. mask over verts as .txt] [(pred0) label id] [(pred0) confidence] +# [(pred1) rel. path to pred. mask over verts as .txt] [(pred1) label id] [(pred1) confidence] +# [(pred2) rel. path to pred. mask over verts as .txt] [(pred2) label id] [(pred2) confidence] +# ... +# +# NOTE: The prediction files must live in the root of the given prediction path. +# Predicted mask .txt files must live in a subfolder. +# Additionally, filenames must not contain spaces. +# The relative paths to predicted masks must contain one integer per line, +# where each line corresponds to vertices in the *_vh_clean_2.ply (in that order). +# Non-zero integers indicate part of the predicted instance. +# The label ids specify the class of the corresponding mask. +# Confidence is a float confidence score of the mask. +# +# Note that only the valid classes are used for evaluation, +# i.e., any ground truth label not in the valid label set +# is ignored in the evaluation. +# +# example usage: evaluate_semantic_instance.py --scan_path [path to scan data] --output_file [output file] + +# python imports +import math +import os, sys, argparse +import inspect +from copy import deepcopy + +try: + import numpy as np +except: + print "Failed to import numpy package." + sys.exit(-1) + +currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +parentdir = os.path.dirname(currentdir) +sys.path.insert(0,parentdir) +import util +import util_3d + +parser = argparse.ArgumentParser() +parser.add_argument('--pred_path', required=True, help='path to directory of predicted .txt files') +parser.add_argument('--gt_path', required=True, help='path to directory of gt .txt files') +parser.add_argument('--output_file', default='', help='output file [default: pred_path/semantic_instance_evaluation.txt]') +opt = parser.parse_args() + +if opt.output_file == '': + opt.output_file = os.path.join(opt.pred_path, 'semantic_instance_evaluation.txt') + + +# ---------- Label info ---------- # +CLASS_LABELS = ['cabinet', 'bed', 'chair', 'sofa', 'table', 'door', 'window', 'bookshelf', 'picture', 'counter', 'desk', 'curtain', 'refrigerator', 'shower curtain', 'toilet', 'sink', 'bathtub', 'otherfurniture'] +VALID_CLASS_IDS = np.array([3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 24, 28, 33, 34, 36, 39]) +ID_TO_LABEL = {} +LABEL_TO_ID = {} +for i in range(len(VALID_CLASS_IDS)): + LABEL_TO_ID[CLASS_LABELS[i]] = VALID_CLASS_IDS[i] + ID_TO_LABEL[VALID_CLASS_IDS[i]] = CLASS_LABELS[i] +# ---------- Evaluation params ---------- # +# overlaps for evaluation +opt.overlaps = np.append(np.arange(0.5,0.95,0.05), 0.25) +# minimum region size for evaluation [verts] +opt.min_region_sizes = np.array( [ 100 ] ) +# distance thresholds [m] +opt.distance_threshes = np.array( [ float('inf') ] ) +# distance confidences +opt.distance_confs = np.array( [ -float('inf') ] ) + + +def evaluate_matches(matches): + overlaps = opt.overlaps + min_region_sizes = [ opt.min_region_sizes[0] ] + dist_threshes = [ opt.distance_threshes[0] ] + dist_confs = [ opt.distance_confs[0] ] + + # results: class x overlap + ap = np.zeros( (len(dist_threshes) , len(CLASS_LABELS) , len(overlaps)) , np.float ) + for di, (min_region_size, distance_thresh, distance_conf) in enumerate(zip(min_region_sizes, dist_threshes, dist_confs)): + for oi, overlap_th in enumerate(overlaps): + pred_visited = {} + for m in matches: + for p in matches[m]['pred']: + for label_name in CLASS_LABELS: + for p in matches[m]['pred'][label_name]: + if 'filename' in p: + pred_visited[p['filename']] = False + for li, label_name in enumerate(CLASS_LABELS): + y_true = np.empty(0) + y_score = np.empty(0) + hard_false_negatives = 0 + has_gt = False + has_pred = False + for m in matches: + pred_instances = matches[m]['pred'][label_name] + gt_instances = matches[m]['gt'][label_name] + # filter groups in ground truth + gt_instances = [ gt for gt in gt_instances if gt['instance_id']>=1000 and gt['vert_count']>=min_region_size and gt['med_dist']<=distance_thresh and gt['dist_conf']>=distance_conf ] + if gt_instances: + has_gt = True + if pred_instances: + has_pred = True + + cur_true = np.ones ( len(gt_instances) ) + cur_score = np.ones ( len(gt_instances) ) * (-float("inf")) + cur_match = np.zeros( len(gt_instances) , dtype=np.bool ) + # collect matches + for (gti,gt) in enumerate(gt_instances): + found_match = False + num_pred = len(gt['matched_pred']) + for pred in gt['matched_pred']: + # greedy assignments + if pred_visited[pred['filename']]: + continue + overlap = float(pred['intersection']) / (gt['vert_count']+pred['vert_count']-pred['intersection']) + if overlap > overlap_th: + confidence = pred['confidence'] + # if already have a prediction for this gt, + # the prediction with the lower score is automatically a false positive + if cur_match[gti]: + max_score = max( cur_score[gti] , confidence ) + min_score = min( cur_score[gti] , confidence ) + cur_score[gti] = max_score + # append false positive + cur_true = np.append(cur_true,0) + cur_score = np.append(cur_score,min_score) + cur_match = np.append(cur_match,True) + # otherwise set score + else: + found_match = True + cur_match[gti] = True + cur_score[gti] = confidence + pred_visited[pred['filename']] = True + if not found_match: + hard_false_negatives += 1 + # remove non-matched ground truth instances + cur_true = cur_true [ cur_match==True ] + cur_score = cur_score[ cur_match==True ] + + # collect non-matched predictions as false positive + for pred in pred_instances: + found_gt = False + for gt in pred['matched_gt']: + overlap = float(gt['intersection']) / (gt['vert_count']+pred['vert_count']-gt['intersection']) + if overlap > overlap_th: + found_gt = True + break + if not found_gt: + num_ignore = pred['void_intersection'] + for gt in pred['matched_gt']: + # group? + if gt['instance_id'] < 1000: + num_ignore += gt['intersection'] + # small ground truth instances + if gt['vert_count'] < min_region_size or gt['med_dist']>distance_thresh or gt['dist_conf'] 0: + gt_copy = gt_inst.copy() + pred_copy = pred_instance.copy() + gt_copy['intersection'] = intersection + pred_copy['intersection'] = intersection + matched_gt.append(gt_copy) + gt2pred[label_name][gt_num]['matched_pred'].append(pred_copy) + pred_instance['matched_gt'] = matched_gt + num_pred_instances += 1 + pred2gt[label_name].append(pred_instance) + + return gt2pred, pred2gt + + +def print_results(avgs): + sep = "" + col1 = ":" + lineLen = 64 + + print "" + print "#"*lineLen + line = "" + line += "{:<15}".format("what" ) + sep + col1 + line += "{:>15}".format("AP" ) + sep + line += "{:>15}".format("AP_50%" ) + sep + line += "{:>15}".format("AP_25%" ) + sep + print line + print "#"*lineLen + + for (li,label_name) in enumerate(CLASS_LABELS): + ap_avg = avgs["classes"][label_name]["ap"] + ap_50o = avgs["classes"][label_name]["ap50%"] + ap_25o = avgs["classes"][label_name]["ap25%"] + line = "{:<15}".format(label_name) + sep + col1 + line += sep + "{:>15.3f}".format(ap_avg ) + sep + line += sep + "{:>15.3f}".format(ap_50o ) + sep + line += sep + "{:>15.3f}".format(ap_25o ) + sep + print line + + all_ap_avg = avgs["all_ap"] + all_ap_50o = avgs["all_ap_50%"] + all_ap_25o = avgs["all_ap_25%"] + + print "-"*lineLen + line = "{:<15}".format("average") + sep + col1 + line += "{:>15.3f}".format(all_ap_avg) + sep + line += "{:>15.3f}".format(all_ap_50o) + sep + line += "{:>15.3f}".format(all_ap_25o) + sep + print line + print "" + + +def write_result_file(avgs, filename): + _SPLITTER = ',' + with open(filename, 'w') as f: + f.write(_SPLITTER.join(['class', 'class id', 'ap', 'ap50', 'ap25']) + '\n') + for i in range(len(VALID_CLASS_IDS)): + class_name = CLASS_LABELS[i] + class_id = VALID_CLASS_IDS[i] + ap = avgs["classes"][class_name]["ap"] + ap50 = avgs["classes"][class_name]["ap50%"] + ap25 = avgs["classes"][class_name]["ap25%"] + f.write(_SPLITTER.join([str(x) for x in [class_name, class_id, ap, ap50, ap25]]) + '\n') + + +def evaluate(pred_files, gt_files, pred_path, output_file): + print 'evaluating', len(pred_files), 'scans...' + matches = {} + for i in range(len(pred_files)): + matches_key = os.path.abspath(gt_files[i]) + # assign gt to predictions + gt2pred, pred2gt = assign_instances_for_scan(pred_files[i], gt_files[i], pred_path) + matches[matches_key] = {} + matches[matches_key]['gt'] = gt2pred + matches[matches_key]['pred'] = pred2gt + sys.stdout.write("\rscans processed: {}".format(i+1)) + sys.stdout.flush() + print '' + ap_scores = evaluate_matches(matches) + avgs = compute_averages(ap_scores) + + # print + print_results(avgs) + write_result_file(avgs, output_file) + + +def main(): + pred_files = [f for f in os.listdir(opt.pred_path) if f.endswith('.txt') and f != 'semantic_instance_evaluation.txt'] + gt_files = [] + if len(pred_files) == 0: + util.print_error('No result files found.', user_fault=True) + for i in range(len(pred_files)): + gt_file = os.path.join(opt.gt_path, pred_files[i]) + if not os.path.isfile(gt_file): + util.print_error('Result file {} does not match any gt file'.format(pred_files[i]), user_fault=True) + gt_files.append(gt_file) + pred_files[i] = os.path.join(opt.pred_path, pred_files[i]) + + # evaluate + evaluate(pred_files, gt_files, opt.pred_path, opt.output_file) + + +if __name__ == '__main__': + main() diff --git a/BenchmarkScripts/3d_evaluation/evaluate_semantic_label.py b/BenchmarkScripts/3d_evaluation/evaluate_semantic_label.py new file mode 100644 index 0000000..0a2f6b6 --- /dev/null +++ b/BenchmarkScripts/3d_evaluation/evaluate_semantic_label.py @@ -0,0 +1,150 @@ +# Evaluates semantic label task +# Input: +# - path to .txt prediction files +# - path to .txt ground truth files +# - output file to write results to +# Note that only the valid classes are used for evaluation, +# i.e., any ground truth label not in the valid label set +# is ignored in the evaluation. +# +# example usage: evaluate_semantic_label.py --scan_path [path to scan data] --output_file [output file] + +# python imports +import math +import os, sys, argparse +import inspect + +try: + import numpy as np +except: + print "Failed to import numpy package." + sys.exit(-1) +try: + from itertools import izip +except ImportError: + izip = zip + +currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +parentdir = os.path.dirname(currentdir) +sys.path.insert(0,parentdir) +import util +import util_3d + +parser = argparse.ArgumentParser() +parser.add_argument('--pred_path', required=True, help='path to directory of predicted .txt files') +parser.add_argument('--gt_path', required=True, help='path to gt files') +parser.add_argument('--output_file', default='', help='output file [default: pred_path/semantic_label_evaluation.txt]') +opt = parser.parse_args() + +if opt.output_file == '': + opt.output_file = os.path.join(opt.pred_path, 'semantic_label_evaluation.txt') + + +CLASS_LABELS = ['wall', 'floor', 'cabinet', 'bed', 'chair', 'sofa', 'table', 'door', 'window', 'bookshelf', 'picture', 'counter', 'desk', 'curtain', 'refrigerator', 'shower curtain', 'toilet', 'sink', 'bathtub', 'otherfurniture'] +VALID_CLASS_IDS = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 24, 28, 33, 34, 36, 39]) +UNKNOWN_ID = np.max(VALID_CLASS_IDS) + 1 + + +def evaluate_scan(pred_file, gt_file, confusion): + try: + pred_ids = util_3d.load_ids(pred_file) + except Exception, e: + util.print_error('unable to load ' + pred_file + ': ' + str(e)) + try: + gt_ids = util_3d.load_ids(gt_file) + except Exception, e: + util.print_error('unable to load ' + gt_file + ': ' + str(e)) + # sanity checks + if not pred_ids.shape == gt_ids.shape: + util.print_error('%s: number of predicted values does not match number of vertices' % pred_file, user_fault=True) + for (gt_val,pred_val) in izip(gt_ids.flatten(),pred_ids.flatten()): + if gt_val not in VALID_CLASS_IDS: + continue + if pred_val not in VALID_CLASS_IDS: + pred_val = UNKNOWN_ID + confusion[gt_val][pred_val] += 1 + + +def get_iou(label_id, confusion): + if not label_id in VALID_CLASS_IDS: + return float('nan') + # #true positives + tp = np.longlong(confusion[label_id, label_id]) + # #false negatives + fn = np.longlong(confusion[label_id, :].sum()) - tp + # #false positives + not_ignored = [l for l in VALID_CLASS_IDS if not l == label_id] + fp = np.longlong(confusion[not_ignored, label_id].sum()) + + denom = (tp + fp + fn) + if denom == 0: + return float('nan') + return (float(tp) / denom, tp, denom) + + +def write_result_file(confusion, ious, filename): + with open(filename, 'w') as f: + f.write('iou scores\n') + for i in range(len(VALID_CLASS_IDS)): + label_id = VALID_CLASS_IDS[i] + label_name = CLASS_LABELS[i] + iou = ious[label_name][0] + f.write('{0:<14s}({1:<2d}): {2:>5.3f}\n'.format(label_name, label_id, iou)) + f.write('\nconfusion matrix\n') + f.write('\t\t\t') + for i in range(len(VALID_CLASS_IDS)): + #f.write('\t{0:<14s}({1:<2d})'.format(CLASS_LABELS[i], VALID_CLASS_IDS[i])) + f.write('{0:<8d}'.format(VALID_CLASS_IDS[i])) + f.write('\n') + for r in range(len(VALID_CLASS_IDS)): + f.write('{0:<14s}({1:<2d})'.format(CLASS_LABELS[r], VALID_CLASS_IDS[r])) + for c in range(len(VALID_CLASS_IDS)): + f.write('\t{0:>5.3f}'.format(confusion[VALID_CLASS_IDS[r],VALID_CLASS_IDS[c]])) + f.write('\n') + print 'wrote results to', filename + + +def evaluate(pred_files, gt_files, output_file): + max_id = UNKNOWN_ID + confusion = np.zeros((max_id+1, max_id+1), dtype=np.ulonglong) + + print 'evaluating', len(pred_files), 'scans...' + for i in range(len(pred_files)): + evaluate_scan(pred_files[i], gt_files[i], confusion) + sys.stdout.write("\rscans processed: {}".format(i+1)) + sys.stdout.flush() + print '' + + class_ious = {} + for i in range(len(VALID_CLASS_IDS)): + label_name = CLASS_LABELS[i] + label_id = VALID_CLASS_IDS[i] + class_ious[label_name] = get_iou(label_id, confusion) + # print + print 'classes IoU' + print '----------------------------' + for i in range(len(VALID_CLASS_IDS)): + label_name = CLASS_LABELS[i] + #print('{{0:<14s}: 1:>5.3f}'.format(label_name, class_ious[label_name][0])) + print('{0:<14s}: {1:>5.3f} ({2:>6d}/{3:<6d})'.format(label_name, class_ious[label_name][0], class_ious[label_name][1], class_ious[label_name][2])) + write_result_file(confusion, class_ious, output_file) + + +def main(): + pred_files = [f for f in os.listdir(opt.pred_path) if f.endswith('.txt') and f != 'semantic_label_evaluation.txt'] + gt_files = [] + if len(pred_files) == 0: + util.print_error('No result files found.', user_fault=True) + for i in range(len(pred_files)): + gt_file = os.path.join(opt.gt_path, pred_files[i]) + if not os.path.isfile(gt_file): + util.print_error('Result file {} does not match any gt file'.format(pred_files[i]), user_fault=True) + gt_files.append(gt_file) + pred_files[i] = os.path.join(opt.pred_path, pred_files[i]) + + # evaluate + evaluate(pred_files, gt_files, opt.output_file) + + +if __name__ == '__main__': + main() diff --git a/BenchmarkScripts/3d_helpers/export_semantic_label_grid_for_evaluation.py b/BenchmarkScripts/3d_helpers/export_semantic_label_grid_for_evaluation.py new file mode 100644 index 0000000..752b973 --- /dev/null +++ b/BenchmarkScripts/3d_helpers/export_semantic_label_grid_for_evaluation.py @@ -0,0 +1,59 @@ +# Example script to output evaluation format given a volumetric grid of predictions. +# Input: +# - prediction grid as path to .npy np array +# - world2grid transform as path to .npy 4x4 np array +# - path to the corresponding *_vh_clean_2.ply mesh +# - output file to write evaluation format .txt file +# +# example usage: export_semantic_label_grid_for_evaluation.py --grid_file [path to predicted grid] --world2grid_file [path to world to grid] --output_file [output file] --mesh_file [path to corresponding mesh file] + +# python imports +import math +import os, sys, argparse +import inspect + +try: + import numpy as np +except: + print "Failed to import numpy package." + sys.exit(-1) + +currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +parentdir = os.path.dirname(currentdir) +sys.path.insert(0,parentdir) +import util_3d + +parser = argparse.ArgumentParser() +parser.add_argument('--grid_file', required=True, help='path to predicted grid as np array') +parser.add_argument('--world2grid_file', required=True, help='path to world2grid matrix as np array') +parser.add_argument('--output_file', required=True, help='output file') +parser.add_argument('--mesh_file', required=True, help='path to scene*_vh_clean_2.ply') +opt = parser.parse_args() + + +# find label/instance ids per mesh vertex by looking up each mesh vertex in the grid of predicted ids +def export(prediction_grid, world2grid, mesh_vertices, output_file): + grid_dim = prediction_grid.shape + grid_dim = np.flip(np.array(grid_dim), axis=0) + num_verts = mesh_vertices.shape[0] + ids = np.zeros(shape=(num_verts), dtype=np.uint32) + vertices_grid = util_3d.transform_points(world2grid, mesh_vertices) + for i in range(num_verts): + v = vertices_grid[i] + grid_coord = np.floor(v) + # clamp to grid bounds + grid_coord = np.clip(grid_coord, np.zeros((3)), grid_dim-1).astype(np.int32) + ids[i] = prediction_grid[grid_coord[2], grid_coord[1], grid_coord[0]] + util_3d.export_ids(output_file, ids) + + +def main(): + prediction_grid = np.load(opt.grid_file) + world2grid = np.load(opt.world2grid_file) + assert len(prediction_grid.shape) == 3 and world2grid.shape == (4,4) + mesh_vertices = util_3d.read_mesh_vertices(opt.mesh_file) + export(prediction_grid, world2grid, mesh_vertices, opt.output_file) + + +if __name__ == '__main__': + main() diff --git a/BenchmarkScripts/3d_helpers/export_train_mesh_for_evaluation.py b/BenchmarkScripts/3d_helpers/export_train_mesh_for_evaluation.py new file mode 100644 index 0000000..3f60aa7 --- /dev/null +++ b/BenchmarkScripts/3d_helpers/export_train_mesh_for_evaluation.py @@ -0,0 +1,105 @@ +# Example of the output format for evaluation for 3d semantic label and instance prediction. +# Exports a train scan in the evaluation format using: +# - the *_vh_clean_2.ply mesh +# - the labels defined by the *.aggregation.json and *_vh_clean_2.0.010000.segs.json files +# +# example usage: export_train_mesh_for_evaluation.py --scan_path [path to scan data] --output_file [output file] --type label +# Note: technically does not need to load in the ply file, since the ScanNet annotations are defined against the mesh vertices, but we load it in here as an example. + +# python imports +import math +import os, sys, argparse +import inspect +import json + +try: + import numpy as np +except: + print "Failed to import numpy package." + sys.exit(-1) + +currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +parentdir = os.path.dirname(currentdir) +sys.path.insert(0,parentdir) +import util +import util_3d + +TASK_TYPES = {'label', 'instance'} + +parser = argparse.ArgumentParser() +parser.add_argument('--scan_path', required=True, help='path to scannet scene (e.g., data/ScanNet/v2/scene0000_00') +parser.add_argument('--output_file', required=True, help='output file') +parser.add_argument('--label_map_file', required=True, help='path to scannetv2-labels.combined.tsv') +parser.add_argument('--type', required=True, help='task type [label or instance]') +opt = parser.parse_args() +assert opt.type in TASK_TYPES + + +def read_aggregation(filename): + assert os.path.isfile(filename) + object_id_to_segs = {} + label_to_segs = {} + with open(filename) as f: + data = json.load(f) + num_objects = len(data['segGroups']) + for i in range(num_objects): + object_id = data['segGroups'][i]['objectId'] + 1 # instance ids should be 1-indexed + label = data['segGroups'][i]['label'] + segs = data['segGroups'][i]['segments'] + object_id_to_segs[object_id] = segs + if label in label_to_segs: + label_to_segs[label].extend(segs) + else: + label_to_segs[label] = segs + return object_id_to_segs, label_to_segs + + +def read_segmentation(filename): + assert os.path.isfile(filename) + seg_to_verts = {} + with open(filename) as f: + data = json.load(f) + num_verts = len(data['segIndices']) + for i in range(num_verts): + seg_id = data['segIndices'][i] + if seg_id in seg_to_verts: + seg_to_verts[seg_id].append(i) + else: + seg_to_verts[seg_id] = [i] + return seg_to_verts, num_verts + + +def export(mesh_file, agg_file, seg_file, label_map_file, type, output_file): + label_map = util.read_label_mapping(opt.label_map_file, label_from='raw_category', label_to='nyu40id') + mesh_vertices = util_3d.read_mesh_vertices(mesh_file) + object_id_to_segs, label_to_segs = read_aggregation(agg_file) + seg_to_verts, num_verts = read_segmentation(seg_file) + label_ids = np.zeros(shape=(num_verts), dtype=np.uint32) # 0: unannotated + for label, segs in label_to_segs.iteritems(): + label_id = label_map[label] + for seg in segs: + verts = seg_to_verts[seg] + label_ids[verts] = label_id + if type == 'label': + util_3d.export_ids(output_file, label_ids) + elif type == 'instance': + instance_ids = np.zeros(shape=(num_verts), dtype=np.uint32) # 0: unannotated + for object_id, segs in object_id_to_segs.iteritems(): + for seg in segs: + verts = seg_to_verts[seg] + instance_ids[verts] = object_id + util_3d.export_instance_ids_for_eval(output_file, label_ids, instance_ids) + else: + raise + + +def main(): + scan_name = os.path.split(opt.scan_path)[-1] + mesh_file = os.path.join(opt.scan_path, scan_name + '_vh_clean_2.ply') + agg_file = os.path.join(opt.scan_path, scan_name + '.aggregation.json') + seg_file = os.path.join(opt.scan_path, scan_name + '_vh_clean_2.0.010000.segs.json') + export(mesh_file, agg_file, seg_file, opt.label_map_file, opt.type, opt.output_file) + + +if __name__ == '__main__': + main() diff --git a/BenchmarkScripts/3d_helpers/visualize_labels_on_mesh.py b/BenchmarkScripts/3d_helpers/visualize_labels_on_mesh.py new file mode 100644 index 0000000..53f1d8e --- /dev/null +++ b/BenchmarkScripts/3d_helpers/visualize_labels_on_mesh.py @@ -0,0 +1,67 @@ +# Example script to visualize labels in the evaluation format on the corresponding mesh. +# Inputs: +# - predicted labels as a .txt file with one line per vertex +# - the corresponding *_vh_clean_2.ply mesh +# Outputs a .ply with vertex colors, a different color per value in the predicted .txt file +# +# example usage: visualize_labels_on_mesh.py --pred_file [path to predicted labels file] --mesh_file [path to the *_vh_clean_2.ply mesh] --output_file [output file] + +# python imports +import math +import os, sys, argparse +import inspect +import json + +try: + import numpy as np +except: + print "Failed to import numpy package." + sys.exit(-1) +try: + from plyfile import PlyData, PlyElement +except: + print "Please install the module 'plyfile' for PLY i/o, e.g." + print "pip install plyfile" + sys.exit(-1) + +currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +parentdir = os.path.dirname(currentdir) +sys.path.insert(0,parentdir) +import util +import util_3d + +parser = argparse.ArgumentParser() +parser.add_argument('--pred_file', required=True, help='path to predicted labels file as .txt evaluation format') +parser.add_argument('--mesh_file', required=True, help='path to the *_vh_clean_2.ply mesh') +parser.add_argument('--output_file', required=True, help='output .ply file') +opt = parser.parse_args() + + +def visualize(pred_file, mesh_file, output_file): + if not output_file.endswith('.ply'): + util.print_error('output file must be a .ply file') + colors = util.create_color_palette() + num_colors = len(colors) + ids = util_3d.load_ids(pred_file) + with open(mesh_file, 'rb') as f: + plydata = PlyData.read(f) + num_verts = plydata['vertex'].count + if num_verts != len(ids): + util.print_error('#predicted labels = ' + str(len(ids)) + 'vs #mesh vertices = ' + str(num_verts)) + # *_vh_clean_2.ply has colors already + for i in range(num_verts): + if ids[i] >= num_colors: + util.print_error('found predicted label ' + str(ids[i]) + ' not in nyu40 label set') + color = colors[ids[i]] + plydata['vertex']['red'][i] = color[0] + plydata['vertex']['green'][i] = color[1] + plydata['vertex']['blue'][i] = color[2] + plydata.write(output_file) + + +def main(): + visualize(opt.pred_file, opt.mesh_file, opt.output_file) + + +if __name__ == '__main__': + main() diff --git a/BenchmarkScripts/README.md b/BenchmarkScripts/README.md new file mode 100644 index 0000000..0c7e8cf --- /dev/null +++ b/BenchmarkScripts/README.md @@ -0,0 +1,24 @@ +# ScanNet Benchmark Scripts + +We provide scripts for evaluation of the tasks in the [ScanNet benchmark](http://kaldir.vc.in.tum.de/scannet_benchmark), as well as some helper scripts which prepare and visualize data. + +These scripts have been developed and tested with Python 2.7. + +## Evaluation Scripts +The evaluation for both 2D and 3D semantic label and instance segmentation tasks are adapted from the [CityScapes evaluation](https://github.com/mcordts/cityscapesScripts), and provided in [2d_evaluation](2d_evaluation) and [3d_evaluation](3d_evaluation), respectively. The evaluation for the scene type classification task is provided in [scene_type_evaluation](scene_type_evaluation). + +Note that visualization and data preparation scripts for semantic instance and label prediction depend on the ScanNet label mapping file `scannetv2-labels.combined.tsv` to convert labels into the NYUv2 40-label set, which we use for evaluation. + +Please see the [benchmark evaluation documentation](http://kaldir.vc.in.tum.de/scannet_benchmark/documentation) for more information about evaluation data formats and label sets. + +## Helper Scripts +* 2D: + * [2d_helpers](2d_helpers) contains helper scripts for converting ScanNet label images (`*_2d-label.zip`, `*_2d-label-filt.zip`) to the NYUv2 40-label set as 8-bit `png`s, as well as converting ScanNet instance images (`*_2d-instance.zip`, `*_2d-instance-filt.zip`) to 16-bit `png`s containing `[NYUv2 40-label]*1000+instance_id`. An already pre-processed subset of approximately 25,000 frames is available to download with the ScanNet download. + * `util.visualize_label_image` and `util.visualize_instace_image` can be used to visualize these processed label and instance images (assumes NYUv2 40 labels). + +* 3D: + * [3d_helpers](3d_helpers) contains helper scripts for exporting a train scan into the 3D evaluation format for semantic instance and label segmentation. + * `3d_helpers/visualize_labels_on_mesh` can be used to visualize semantic labels on a mesh (assumes NYUv2 40 labels). + +* Scene Types: + * `scene_type_helpers/get_scene_type_for_scan` can be used to get the scene type id from the info `.txt` file for a scan in the ScanNet release. diff --git a/BenchmarkScripts/ScanNet200/README.md b/BenchmarkScripts/ScanNet200/README.md new file mode 100644 index 0000000..f175272 --- /dev/null +++ b/BenchmarkScripts/ScanNet200/README.md @@ -0,0 +1,60 @@ +# ScanNet200 Preprocessing Scripts and description + +We provide the preprocessing scripts and benchmark data for the ScanNet200 Benchmark. +The raw scans and annotations are shared with the original [ScanNet benchmark](http://kaldir.vc.in.tum.de/scannet_benchmark); these scripts provided output semantic and instance labeled meshes according to the ScanNet200 categories. +The ScanNet scene meshes are surface annotated, where every vertex is described with the raw category id. +These IDs can be parsed based on the mapping defined in the `scannetv2-labels.combined.tsv`. + +**Important Note:** The `scannetv2-labels.combined.tsv` file was updated with the introduction of the ScanNet200 benchmark, please download the latest version using the script obtained after filling the [Terms of Use form](https://github.com/ScanNet/ScanNet#scannet-data). + + +Differences and similarities to the original benchmark + - The ScanNet200 benchmark evaluates 200 categories, an order of magnitude larger than the original set of 20 classical semantic labels. + - This new benchmark follows the original _train_/_val_/_test_ scene splits published in this repository, + - We presented a further split of the category sets into three sets based on their point and instance frequencies, namely **head**, **common**, and **tail**. The category splits can be found in `scannet200_split.py` file + - The raw annotations in the training set containing 550 distinct categories, many of which appear only once, and were filtered to produce the large-vocabulary, challenging ScanNet200 setting. The mapping of annotation category IDs to ScanNet200 valid categories can be found in `scannet200_constants.py`. + - This larger vocabulary includes a strong natural imbalance and diversity for evaluating modern 3D scene understanding methods in a challenging scenario. + +![](docs/dataset_histograms.jpg) + +We provide scripts for preprocessing and parsing the scene meshes to semantically and instance labeled meshes in `preprocess_scannet200.py`. +Additionally, helper functions such as mesh voxelization can be found in `utils.py` + +### Running the preprocessing + +The scripts are developed and tested with Python 3, and basic libraries like _pandas_ and _plyfile_ are expected to be installed. +Additionally, we rely on _trimesh_ and _MinkowskiEngine_ for uniform mesh voxelization, but these libraries are not strictly necessary + +For the installation of all required libraries + +``` +conda create -n scannet200 python=3.8 +pip install -r requirements.txt +``` + +For the optional MinkowskiEngine required in the voxelization script, please refer to the [installation guide](https://github.com/NVIDIA/MinkowskiEngine#anaconda) corresponding the specific GPU version. + + +The preprocessing can be started with + +``` +python --dataset_root + --output_root + --label_map_file +``` + +Where script options: +``` +--dataset_root: + Path to the ScanNet dataset containing scene folders +--output_root: + Output path where train/val folders will be located +--label_map_file: + path to the updated scannetv2-labels.combined.tsv +--num_workers: + The number of parallel workers for multiprocessing + default=4 +--train_val_splits_path: + Where the txt files with the train/val splits live + default='../../Tasks/Benchmark' +``` diff --git a/BenchmarkScripts/ScanNet200/docs/dataset_histograms.jpg b/BenchmarkScripts/ScanNet200/docs/dataset_histograms.jpg new file mode 100644 index 0000000..227baaa Binary files /dev/null and b/BenchmarkScripts/ScanNet200/docs/dataset_histograms.jpg differ diff --git a/BenchmarkScripts/ScanNet200/preprocess_scannet200.py b/BenchmarkScripts/ScanNet200/preprocess_scannet200.py new file mode 100644 index 0000000..6f0e2bb --- /dev/null +++ b/BenchmarkScripts/ScanNet200/preprocess_scannet200.py @@ -0,0 +1,133 @@ +import warnings +warnings.filterwarnings("ignore", category=DeprecationWarning) + +import sys +import os +import argparse +import glob +import json +from concurrent.futures import ProcessPoolExecutor +from itertools import repeat + +# Load external constants +from scannet200_constants import * +from scannet200_splits import * +from utils import * + +CLOUD_FILE_PFIX = '_vh_clean_2' +SEGMENTS_FILE_PFIX = '.0.010000.segs.json' +AGGREGATIONS_FILE_PFIX = '.aggregation.json' +CLASS_IDs = VALID_CLASS_IDS_200 + +def handle_process(scene_path, output_path, labels_pd, train_scenes, val_scenes): + + scene_id = scene_path.split('/')[-1] + mesh_path = os.path.join(scene_path, f'{scene_id}{CLOUD_FILE_PFIX}.ply') + segments_file = os.path.join(scene_path, f'{scene_id}{CLOUD_FILE_PFIX}{SEGMENTS_FILE_PFIX}') + aggregations_file = os.path.join(scene_path, f'{scene_id}{AGGREGATIONS_FILE_PFIX}') + info_file = os.path.join(scene_path, f'{scene_id}.txt') + + if scene_id in train_scenes: + output_file = os.path.join(output_path, 'train', f'{scene_id}.ply') + split_name = 'train' + elif scene_id in val_scenes: + output_file = os.path.join(output_path, 'val', f'{scene_id}.ply') + split_name = 'val' + else: + output_file = os.path.join(output_path, 'test', f'{scene_id}.ply') + split_name = 'test' + + print('Processing: ', scene_id, 'in ', split_name) + + # Rotating the mesh to axis aligned + info_dict = {} + with open(info_file) as f: + for line in f: + (key, val) = line.split(" = ") + info_dict[key] = np.fromstring(val, sep=' ') + + if 'axisAlignment' not in info_dict: + rot_matrix = np.identity(4) + else: + rot_matrix = info_dict['axisAlignment'].reshape(4, 4) + + pointcloud, faces_array = read_plymesh(mesh_path) + points = pointcloud[:, :3] + colors = pointcloud[:, 3:6] + alphas = pointcloud[:, -1] + + # Rotate PC to axis aligned + r_points = pointcloud[:, :3].transpose() + r_points = np.append(r_points, np.ones((1, r_points.shape[1])), axis=0) + r_points = np.dot(rot_matrix, r_points) + pointcloud = np.append(r_points.transpose()[:, :3], pointcloud[:, 3:], axis=1) + + # Load segments file + with open(segments_file) as f: + segments = json.load(f) + seg_indices = np.array(segments['segIndices']) + + # Load Aggregations file + with open(aggregations_file) as f: + aggregation = json.load(f) + seg_groups = np.array(aggregation['segGroups']) + + # Generate new labels + labelled_pc = np.zeros((pointcloud.shape[0], 1)) + instance_ids = np.zeros((pointcloud.shape[0], 1)) + for group in seg_groups: + segment_points, p_inds, label_id = point_indices_from_group(pointcloud, seg_indices, group, labels_pd, CLASS_IDs) + + labelled_pc[p_inds] = label_id + instance_ids[p_inds] = group['id'] + + labelled_pc = labelled_pc.astype(int) + instance_ids = instance_ids.astype(int) + + # Concatenate with original cloud + processed_vertices = np.hstack((pointcloud[:, :6], labelled_pc, instance_ids)) + + if (np.any(np.isnan(processed_vertices)) or not np.all(np.isfinite(processed_vertices))): + raise ValueError('nan') + + # Save processed mesh + save_plymesh(processed_vertices, faces_array, output_file, with_label=True, verbose=False) + + # Uncomment the following lines if saving the output in voxelized point cloud + # quantized_points, quantized_scene_colors, quantized_labels, quantized_instances = voxelize_pointcloud(points, colors, labelled_pc, instance_ids, faces_array) + # quantized_pc = np.hstack((quantized_points, quantized_scene_colors, quantized_labels, quantized_instances)) + # save_plymesh(quantized_pc, faces=None, filename=output_file, with_label=True, verbose=False) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--dataset_root', required=True, help='Path to the ScanNet dataset containing scene folders') + parser.add_argument('--output_root', required=True, help='Output path where train/val folders will be located') + parser.add_argument('--label_map_file', required=True, help='path to scannetv2-labels.combined.tsv') + parser.add_argument('--num_workers', default=4, type=int, help='The number of parallel workers') + parser.add_argument('--train_val_splits_path', default='../../Tasks/Benchmark', help='Where the txt files with the train/val splits live') + config = parser.parse_args() + + # Load label map + labels_pd = pd.read_csv(config.label_map_file, sep='\t', header=0) + + # Load train/val splits + with open(config.train_val_splits_path + '/scannetv2_train.txt') as train_file: + train_scenes = train_file.read().splitlines() + with open(config.train_val_splits_path + '/scannetv2_val.txt') as val_file: + val_scenes = val_file.read().splitlines() + + # Create output directories + train_output_dir = os.path.join(config.output_root, 'train') + if not os.path.exists(train_output_dir): + os.makedirs(train_output_dir) + val_output_dir = os.path.join(config.output_root, 'val') + if not os.path.exists(val_output_dir): + os.makedirs(val_output_dir) + + # Load scene paths + scene_paths = sorted(glob.glob(config.dataset_root + '/*')) + + # Preprocess data. + pool = ProcessPoolExecutor(max_workers=config.num_workers) + print('Processing scenes...') + _ = list(pool.map(handle_process, scene_paths, repeat(config.output_root), repeat(labels_pd), repeat(train_scenes), repeat(val_scenes))) diff --git a/BenchmarkScripts/ScanNet200/requirements.txt b/BenchmarkScripts/ScanNet200/requirements.txt new file mode 100644 index 0000000..ccf5e0a --- /dev/null +++ b/BenchmarkScripts/ScanNet200/requirements.txt @@ -0,0 +1,15 @@ +certifi==2022.5.18.1 +joblib==1.1.0 +numpy==1.22.4 +pandas==1.4.2 +pip==21.2.4 +plyfile==0.7.4 +python-dateutil==2.8.2 +pytz==2022.1 +scikit-learn==1.1.1 +scipy==1.8.1 +setuptools==61.2.0 +six==1.16.0 +threadpoolctl==3.1.0 +trimesh==3.12.6 +wheel==0.37.1 diff --git a/BenchmarkScripts/ScanNet200/scannet200_constants.py b/BenchmarkScripts/ScanNet200/scannet200_constants.py new file mode 100644 index 0000000..388c497 --- /dev/null +++ b/BenchmarkScripts/ScanNet200/scannet200_constants.py @@ -0,0 +1,277 @@ +### ScanNet Benchmark constants ### +VALID_CLASS_IDS_20 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 24, 28, 33, 34, 36, 39) + +CLASS_LABELS_20 = ('wall', 'floor', 'cabinet', 'bed', 'chair', 'sofa', 'table', 'door', 'window', + 'bookshelf', 'picture', 'counter', 'desk', 'curtain', 'refrigerator', + 'shower curtain', 'toilet', 'sink', 'bathtub', 'otherfurniture') + +SCANNET_COLOR_MAP_20 = { + 0: (0., 0., 0.), + 1: (174., 199., 232.), + 2: (152., 223., 138.), + 3: (31., 119., 180.), + 4: (255., 187., 120.), + 5: (188., 189., 34.), + 6: (140., 86., 75.), + 7: (255., 152., 150.), + 8: (214., 39., 40.), + 9: (197., 176., 213.), + 10: (148., 103., 189.), + 11: (196., 156., 148.), + 12: (23., 190., 207.), + 14: (247., 182., 210.), + 15: (66., 188., 102.), + 16: (219., 219., 141.), + 17: (140., 57., 197.), + 18: (202., 185., 52.), + 19: (51., 176., 203.), + 20: (200., 54., 131.), + 21: (92., 193., 61.), + 22: (78., 71., 183.), + 23: (172., 114., 82.), + 24: (255., 127., 14.), + 25: (91., 163., 138.), + 26: (153., 98., 156.), + 27: (140., 153., 101.), + 28: (158., 218., 229.), + 29: (100., 125., 154.), + 30: (178., 127., 135.), + 32: (146., 111., 194.), + 33: (44., 160., 44.), + 34: (112., 128., 144.), + 35: (96., 207., 209.), + 36: (227., 119., 194.), + 37: (213., 92., 176.), + 38: (94., 106., 211.), + 39: (82., 84., 163.), + 40: (100., 85., 144.), +} + +### ScanNet200 Benchmark constants ### +VALID_CLASS_IDS_200 = ( +1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 35, 36, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, +72, 73, 74, 75, 76, 77, 78, 79, 80, 82, 84, 86, 87, 88, 89, 90, 93, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 110, 112, 115, 116, 118, 120, 121, 122, 125, 128, 130, 131, 132, 134, 136, 138, 139, 140, 141, 145, 148, 154, +155, 156, 157, 159, 161, 163, 165, 166, 168, 169, 170, 177, 180, 185, 188, 191, 193, 195, 202, 208, 213, 214, 221, 229, 230, 232, 233, 242, 250, 261, 264, 276, 283, 286, 300, 304, 312, 323, 325, 331, 342, 356, 370, 392, 395, 399, 408, 417, +488, 540, 562, 570, 572, 581, 609, 748, 776, 1156, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191) + +CLASS_LABELS_200 = ( +'wall', 'chair', 'floor', 'table', 'door', 'couch', 'cabinet', 'shelf', 'desk', 'office chair', 'bed', 'pillow', 'sink', 'picture', 'window', 'toilet', 'bookshelf', 'monitor', 'curtain', 'book', 'armchair', 'coffee table', 'box', +'refrigerator', 'lamp', 'kitchen cabinet', 'towel', 'clothes', 'tv', 'nightstand', 'counter', 'dresser', 'stool', 'cushion', 'plant', 'ceiling', 'bathtub', 'end table', 'dining table', 'keyboard', 'bag', 'backpack', 'toilet paper', +'printer', 'tv stand', 'whiteboard', 'blanket', 'shower curtain', 'trash can', 'closet', 'stairs', 'microwave', 'stove', 'shoe', 'computer tower', 'bottle', 'bin', 'ottoman', 'bench', 'board', 'washing machine', 'mirror', 'copier', +'basket', 'sofa chair', 'file cabinet', 'fan', 'laptop', 'shower', 'paper', 'person', 'paper towel dispenser', 'oven', 'blinds', 'rack', 'plate', 'blackboard', 'piano', 'suitcase', 'rail', 'radiator', 'recycling bin', 'container', +'wardrobe', 'soap dispenser', 'telephone', 'bucket', 'clock', 'stand', 'light', 'laundry basket', 'pipe', 'clothes dryer', 'guitar', 'toilet paper holder', 'seat', 'speaker', 'column', 'bicycle', 'ladder', 'bathroom stall', 'shower wall', +'cup', 'jacket', 'storage bin', 'coffee maker', 'dishwasher', 'paper towel roll', 'machine', 'mat', 'windowsill', 'bar', 'toaster', 'bulletin board', 'ironing board', 'fireplace', 'soap dish', 'kitchen counter', 'doorframe', +'toilet paper dispenser', 'mini fridge', 'fire extinguisher', 'ball', 'hat', 'shower curtain rod', 'water cooler', 'paper cutter', 'tray', 'shower door', 'pillar', 'ledge', 'toaster oven', 'mouse', 'toilet seat cover dispenser', +'furniture', 'cart', 'storage container', 'scale', 'tissue box', 'light switch', 'crate', 'power outlet', 'decoration', 'sign', 'projector', 'closet door', 'vacuum cleaner', 'candle', 'plunger', 'stuffed animal', 'headphones', 'dish rack', +'broom', 'guitar case', 'range hood', 'dustpan', 'hair dryer', 'water bottle', 'handicap bar', 'purse', 'vent', 'shower floor', 'water pitcher', 'mailbox', 'bowl', 'paper bag', 'alarm clock', 'music stand', 'projector screen', 'divider', +'laundry detergent', 'bathroom counter', 'object', 'bathroom vanity', 'closet wall', 'laundry hamper', 'bathroom stall door', 'ceiling light', 'trash bin', 'dumbbell', 'stair rail', 'tube', 'bathroom cabinet', 'cd case', 'closet rod', +'coffee kettle', 'structure', 'shower head', 'keyboard piano', 'case of water bottles', 'coat rack', 'storage organizer', 'folded chair', 'fire alarm', 'power strip', 'calendar', 'poster', 'potted plant', 'luggage', 'mattress') + +SCANNET_COLOR_MAP_200 = { +0: (0., 0., 0.), +1: (174., 199., 232.), +2: (188., 189., 34.), +3: (152., 223., 138.), +4: (255., 152., 150.), +5: (214., 39., 40.), +6: (91., 135., 229.), +7: (31., 119., 180.), +8: (229., 91., 104.), +9: (247., 182., 210.), +10: (91., 229., 110.), +11: (255., 187., 120.), +13: (141., 91., 229.), +14: (112., 128., 144.), +15: (196., 156., 148.), +16: (197., 176., 213.), +17: (44., 160., 44.), +18: (148., 103., 189.), +19: (229., 91., 223.), +21: (219., 219., 141.), +22: (192., 229., 91.), +23: (88., 218., 137.), +24: (58., 98., 137.), +26: (177., 82., 239.), +27: (255., 127., 14.), +28: (237., 204., 37.), +29: (41., 206., 32.), +31: (62., 143., 148.), +32: (34., 14., 130.), +33: (143., 45., 115.), +34: (137., 63., 14.), +35: (23., 190., 207.), +36: (16., 212., 139.), +38: (90., 119., 201.), +39: (125., 30., 141.), +40: (150., 53., 56.), +41: (186., 197., 62.), +42: (227., 119., 194.), +44: (38., 100., 128.), +45: (120., 31., 243.), +46: (154., 59., 103.), +47: (169., 137., 78.), +48: (143., 245., 111.), +49: (37., 230., 205.), +50: (14., 16., 155.), +51: (196., 51., 182.), +52: (237., 80., 38.), +54: (138., 175., 62.), +55: (158., 218., 229.), +56: (38., 96., 167.), +57: (190., 77., 246.), +58: (208., 49., 84.), +59: (208., 193., 72.), +62: (55., 220., 57.), +63: (10., 125., 140.), +64: (76., 38., 202.), +65: (191., 28., 135.), +66: (211., 120., 42.), +67: (118., 174., 76.), +68: (17., 242., 171.), +69: (20., 65., 247.), +70: (208., 61., 222.), +71: (162., 62., 60.), +72: (210., 235., 62.), +73: (45., 152., 72.), +74: (35., 107., 149.), +75: (160., 89., 237.), +76: (227., 56., 125.), +77: (169., 143., 81.), +78: (42., 143., 20.), +79: (25., 160., 151.), +80: (82., 75., 227.), +82: (253., 59., 222.), +84: (240., 130., 89.), +86: (123., 172., 47.), +87: (71., 194., 133.), +88: (24., 94., 205.), +89: (134., 16., 179.), +90: (159., 32., 52.), +93: (213., 208., 88.), +95: (64., 158., 70.), +96: (18., 163., 194.), +97: (65., 29., 153.), +98: (177., 10., 109.), +99: (152., 83., 7.), +100: (83., 175., 30.), +101: (18., 199., 153.), +102: (61., 81., 208.), +103: (213., 85., 216.), +104: (170., 53., 42.), +105: (161., 192., 38.), +106: (23., 241., 91.), +107: (12., 103., 170.), +110: (151., 41., 245.), +112: (133., 51., 80.), +115: (184., 162., 91.), +116: (50., 138., 38.), +118: (31., 237., 236.), +120: (39., 19., 208.), +121: (223., 27., 180.), +122: (254., 141., 85.), +125: (97., 144., 39.), +128: (106., 231., 176.), +130: (12., 61., 162.), +131: (124., 66., 140.), +132: (137., 66., 73.), +134: (250., 253., 26.), +136: (55., 191., 73.), +138: (60., 126., 146.), +139: (153., 108., 234.), +140: (184., 58., 125.), +141: (135., 84., 14.), +145: (139., 248., 91.), +148: (53., 200., 172.), +154: (63., 69., 134.), +155: (190., 75., 186.), +156: (127., 63., 52.), +157: (141., 182., 25.), +159: (56., 144., 89.), +161: (64., 160., 250.), +163: (182., 86., 245.), +165: (139., 18., 53.), +166: (134., 120., 54.), +168: (49., 165., 42.), +169: (51., 128., 133.), +170: (44., 21., 163.), +177: (232., 93., 193.), +180: (176., 102., 54.), +185: (116., 217., 17.), +188: (54., 209., 150.), +191: (60., 99., 204.), +193: (129., 43., 144.), +195: (252., 100., 106.), +202: (187., 196., 73.), +208: (13., 158., 40.), +213: (52., 122., 152.), +214: (128., 76., 202.), +221: (187., 50., 115.), +229: (180., 141., 71.), +230: (77., 208., 35.), +232: (72., 183., 168.), +233: (97., 99., 203.), +242: (172., 22., 158.), +250: (155., 64., 40.), +261: (118., 159., 30.), +264: (69., 252., 148.), +276: (45., 103., 173.), +283: (111., 38., 149.), +286: (184., 9., 49.), +300: (188., 174., 67.), +304: (53., 206., 53.), +312: (97., 235., 252.), +323: (66., 32., 182.), +325: (236., 114., 195.), +331: (241., 154., 83.), +342: (133., 240., 52.), +356: (16., 205., 144.), +370: (75., 101., 198.), +392: (237., 95., 251.), +395: (191., 52., 49.), +399: (227., 254., 54.), +408: (49., 206., 87.), +417: (48., 113., 150.), +488: (125., 73., 182.), +540: (229., 32., 114.), +562: (158., 119., 28.), +570: (60., 205., 27.), +572: (18., 215., 201.), +581: (79., 76., 153.), +609: (134., 13., 116.), +748: (192., 97., 63.), +776: (108., 163., 18.), +1156: (95., 220., 156.), +1163: (98., 141., 208.), +1164: (144., 19., 193.), +1165: (166., 36., 57.), +1166: (212., 202., 34.), +1167: (23., 206., 34.), +1168: (91., 211., 236.), +1169: (79., 55., 137.), +1170: (182., 19., 117.), +1171: (134., 76., 14.), +1172: (87., 185., 28.), +1173: (82., 224., 187.), +1174: (92., 110., 214.), +1175: (168., 80., 171.), +1176: (197., 63., 51.), +1178: (175., 199., 77.), +1179: (62., 180., 98.), +1180: (8., 91., 150.), +1181: (77., 15., 130.), +1182: (154., 65., 96.), +1183: (197., 152., 11.), +1184: (59., 155., 45.), +1185: (12., 147., 145.), +1186: (54., 35., 219.), +1187: (210., 73., 181.), +1188: (221., 124., 77.), +1189: (149., 214., 66.), +1190: (72., 185., 134.), +1191: (42., 94., 198.), +} + +### For instance segmentation the non-object categories ### +VALID_PANOPTIC_IDS = (1, 3) + +CLASS_LABELS_PANOPTIC = ('wall', 'floor') \ No newline at end of file diff --git a/BenchmarkScripts/ScanNet200/scannet200_splits.py b/BenchmarkScripts/ScanNet200/scannet200_splits.py new file mode 100644 index 0000000..cf3d134 --- /dev/null +++ b/BenchmarkScripts/ScanNet200/scannet200_splits.py @@ -0,0 +1,18 @@ +### This file contains the HEAD - COMMON - TAIL split category ids for ScanNet 200 + +HEAD_CATS_SCANNET_200 = ['tv stand', 'curtain', 'blinds', 'shower curtain', 'bookshelf', 'tv', 'kitchen cabinet', 'pillow', 'lamp', 'dresser', 'monitor', 'object', 'ceiling', 'board', 'stove', 'closet wall', 'couch', 'office chair', 'kitchen counter', 'shower', 'closet', 'doorframe', 'sofa chair', 'mailbox', 'nightstand', 'washing machine', 'picture', 'book', 'sink', 'recycling bin', 'table', 'backpack', 'shower wall', 'toilet', 'copier', 'counter', 'stool', 'refrigerator', 'window', 'file cabinet', 'chair', 'wall', 'plant', 'coffee table', 'stairs', 'armchair', 'cabinet', 'bathroom vanity', 'bathroom stall', 'mirror', 'blackboard', 'trash can', 'stair rail', 'box', 'towel', 'door', 'clothes', 'whiteboard', 'bed', 'floor', 'bathtub', 'desk', 'wardrobe', 'clothes dryer', 'radiator', 'shelf'] +COMMON_CATS_SCANNET_200 = ["cushion", "end table", "dining table", "keyboard", "bag", "toilet paper", "printer", "blanket", "microwave", "shoe", "computer tower", "bottle", "bin", "ottoman", "bench", "basket", "fan", "laptop", "person", "paper towel dispenser", "oven", "rack", "piano", "suitcase", "rail", "container", "telephone", "stand", "light", "laundry basket", "pipe", "seat", "column", "bicycle", "ladder", "jacket", "storage bin", "coffee maker", "dishwasher", "machine", "mat", "windowsill", "bulletin board", "fireplace", "mini fridge", "water cooler", "shower door", "pillar", "ledge", "furniture", "cart", "decoration", "closet door", "vacuum cleaner", "dish rack", "range hood", "projector screen", "divider", "bathroom counter", "laundry hamper", "bathroom stall door", "ceiling light", "trash bin", "bathroom cabinet", "structure", "storage organizer", "potted plant", "mattress"] +TAIL_CATS_SCANNET_200 = ["paper", "plate", "soap dispenser", "bucket", "clock", "guitar", "toilet paper holder", "speaker", "cup", "paper towel roll", "bar", "toaster", "ironing board", "soap dish", "toilet paper dispenser", "fire extinguisher", "ball", "hat", "shower curtain rod", "paper cutter", "tray", "toaster oven", "mouse", "toilet seat cover dispenser", "storage container", "scale", "tissue box", "light switch", "crate", "power outlet", "sign", "projector", "candle", "plunger", "stuffed animal", "headphones", "broom", "guitar case", "dustpan", "hair dryer", "water bottle", "handicap bar", "purse", "vent", "shower floor", "water pitcher", "bowl", "paper bag", "alarm clock", "music stand", "laundry detergent", "dumbbell", "tube", "cd case", "closet rod", "coffee kettle", "shower head", "keyboard piano", "case of water bottles", "coat rack", "folded chair", "fire alarm", "power strip", "calendar", "poster", "luggage"] + + +### Given the different size of the official train and val sets, not all ScanNet200 categories are present in the validation set. +### Here we list of categories with labels and IDs present in both train and validation set, and the remaining categories those are present in train, but not in val +### We dont evaluate on unseen validation categories in this benchmark + +VALID_CLASS_IDS_200_VALIDATION = ('wall', 'chair', 'floor', 'table', 'door', 'couch', 'cabinet', 'shelf', 'desk', 'office chair', 'bed', 'pillow', 'sink', 'picture', 'window', 'toilet', 'bookshelf', 'monitor', 'curtain', 'book', 'armchair', 'coffee table', 'box', 'refrigerator', 'lamp', 'kitchen cabinet', 'towel', 'clothes', 'tv', 'nightstand', 'counter', 'dresser', 'stool', 'cushion', 'plant', 'ceiling', 'bathtub', 'end table', 'dining table', 'keyboard', 'bag', 'backpack', 'toilet paper', 'printer', 'tv stand', 'whiteboard', 'blanket', 'shower curtain', 'trash can', 'closet', 'stairs', 'microwave', 'stove', 'shoe', 'computer tower', 'bottle', 'bin', 'ottoman', 'bench', 'board', 'washing machine', 'mirror', 'copier', 'basket', 'sofa chair', 'file cabinet', 'fan', 'laptop', 'shower', 'paper', 'person', 'paper towel dispenser', 'oven', 'blinds', 'rack', 'plate', 'blackboard', 'piano', 'suitcase', 'rail', 'radiator', 'recycling bin', 'container', 'wardrobe', 'soap dispenser', 'telephone', 'bucket', 'clock', 'stand', 'light', 'laundry basket', 'pipe', 'clothes dryer', 'guitar', 'toilet paper holder', 'seat', 'speaker', 'column', 'ladder', 'bathroom stall', 'shower wall', 'cup', 'jacket', 'storage bin', 'coffee maker', 'dishwasher', 'paper towel roll', 'machine', 'mat', 'windowsill', 'bar', 'toaster', 'bulletin board', 'ironing board', 'fireplace', 'soap dish', 'kitchen counter', 'doorframe', 'toilet paper dispenser', 'mini fridge', 'fire extinguisher', 'ball', 'hat', 'shower curtain rod', 'water cooler', 'paper cutter', 'tray', 'shower door', 'pillar', 'ledge', 'toaster oven', 'mouse', 'toilet seat cover dispenser', 'furniture', 'cart', 'scale', 'tissue box', 'light switch', 'crate', 'power outlet', 'decoration', 'sign', 'projector', 'closet door', 'vacuum cleaner', 'plunger', 'stuffed animal', 'headphones', 'dish rack', 'broom', 'range hood', 'dustpan', 'hair dryer', 'water bottle', 'handicap bar', 'vent', 'shower floor', 'water pitcher', 'mailbox', 'bowl', 'paper bag', 'projector screen', 'divider', 'laundry detergent', 'bathroom counter', 'object', 'bathroom vanity', 'closet wall', 'laundry hamper', 'bathroom stall door', 'ceiling light', 'trash bin', 'dumbbell', 'stair rail', 'tube', 'bathroom cabinet', 'closet rod', 'coffee kettle', 'shower head', 'keyboard piano', 'case of water bottles', 'coat rack', 'folded chair', 'fire alarm', 'power strip', 'calendar', 'poster', 'potted plant', 'mattress') + +CLASS_LABELS_200_VALIDATION = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 35, 36, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 82, 84, 86, 87, 88, 89, 90, 93, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 110, 112, 115, 116, 118, 120, 122, 125, 128, 130, 131, 132, 134, 136, 138, 139, 140, 141, 145, 148, 154, 155, 156, 157, 159, 161, 163, 165, 166, 168, 169, 170, 177, 180, 185, 188, 191, 193, 195, 202, 208, 213, 214, 229, 230, 232, 233, 242, 250, 261, 264, 276, 283, 300, 304, 312, 323, 325, 342, 356, 370, 392, 395, 408, 417, 488, 540, 562, 570, 609, 748, 776, 1156, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1175, 1176, 1179, 1180, 1181, 1182, 1184, 1185, 1186, 1187, 1188, 1189, 1191) + +VALID_CLASS_IDS_200_TRAIN_ONLY = ('bicycle', 'storage container', 'candle', 'guitar case', 'purse', 'alarm clock', 'music stand', 'cd case', 'structure', 'storage organizer', 'luggage') + +CLASS_LABELS_200_TRAIN_ONLY = (121, 221, 286, 331, 399, 572, 581, 1174, 1178, 1183, 1190) diff --git a/BenchmarkScripts/ScanNet200/utils.py b/BenchmarkScripts/ScanNet200/utils.py new file mode 100644 index 0000000..0c6b1f8 --- /dev/null +++ b/BenchmarkScripts/ScanNet200/utils.py @@ -0,0 +1,115 @@ +import os +import numpy as np +from plyfile import PlyData, PlyElement +import pandas as pd + +from scannet200_constants import * + +def read_plymesh(filepath): + """Read ply file and return it as numpy array. Returns None if emtpy.""" + with open(filepath, 'rb') as f: + plydata = PlyData.read(f) + if plydata.elements: + vertices = pd.DataFrame(plydata['vertex'].data).values + faces = np.array([f[0] for f in plydata["face"].data]) + return vertices, faces + +def save_plymesh(vertices, faces, filename, verbose=True, with_label=True): + """Save an RGB point cloud as a PLY file. + + Args: + points_3d: Nx6 matrix where points_3d[:, :3] are the XYZ coordinates and points_3d[:, 4:] are + the RGB values. If Nx3 matrix, save all points with [128, 128, 128] (gray) color. + """ + assert vertices.ndim == 2 + if with_label: + if vertices.shape[1] == 7: + python_types = (float, float, float, int, int, int, int) + npy_types = [('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), + ('blue', 'u1'), ('label', 'u4')] + + if vertices.shape[1] == 8: + python_types = (float, float, float, int, int, int, int, int) + npy_types = [('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), + ('blue', 'u1'), ('label', 'u4'), ('instance_id', 'u4')] + + else: + if vertices.shape[1] == 3: + gray_concat = np.tile(np.array([128], dtype=np.uint8), (vertices.shape[0], 3)) + vertices = np.hstack((vertices, gray_concat)) + elif vertices.shape[1] == 6: + python_types = (float, float, float, int, int, int) + npy_types = [('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), + ('blue', 'u1')] + else: + pass + + vertices_list = [] + for row_idx in range(vertices.shape[0]): + cur_point = vertices[row_idx] + vertices_list.append(tuple(dtype(point) for dtype, point in zip(python_types, cur_point))) + vertices_array = np.array(vertices_list, dtype=npy_types) + elements = [PlyElement.describe(vertices_array, 'vertex')] + + if faces is not None: + faces_array = np.empty(len(faces), dtype=[('vertex_indices', 'i4', (3,))]) + faces_array['vertex_indices'] = faces + elements += [PlyElement.describe(faces_array, 'face')] + + # Write + PlyData(elements).write(filename) + + if verbose is True: + print('Saved point cloud to: %s' % filename) + + +# Map the raw category id to the point cloud +def point_indices_from_group(points, seg_indices, group, labels_pd, CLASS_IDs): + group_segments = np.array(group['segments']) + label = group['label'] + + # Map the category name to id + label_ids = labels_pd[labels_pd['raw_category'] == label]['id'] + label_id = int(label_ids.iloc[0]) if len(label_ids) > 0 else 0 + + # Only store for the valid categories + if not label_id in CLASS_IDs: + label_id = 0 + + # get points, where segment indices (points labelled with segment ids) are in the group segment list + point_IDs = np.where(np.isin(seg_indices, group_segments)) + + return points[point_IDs], point_IDs[0], label_id + + +# Uncomment out if mesh voxelization is required +# import trimesh +# from trimesh.voxel import creation +# from sklearn.neighbors import KDTree +# import MinkowskiEngine as ME + + +# VOXELIZE the scene from sampling on the mesh directly instead of vertices +def voxelize_pointcloud(points, colors, labels, instances, faces, voxel_size=0.2): + + # voxelize mesh first and determine closest labels with KDTree search + trimesh_scene_mesh = trimesh.Trimesh(vertices=points, faces=faces) + voxel_grid = creation.voxelize(trimesh_scene_mesh, voxel_size) + voxel_cloud = np.asarray(voxel_grid.points) + orig_tree = KDTree(points, leaf_size=8) + _, voxel_pc_matches = orig_tree.query(voxel_cloud, k=1) + voxel_pc_matches = voxel_pc_matches.flatten() + + # match colors to voxel ids + points = points[voxel_pc_matches] / voxel_size + colors = colors[voxel_pc_matches] + labels = labels[voxel_pc_matches] + instances = instances[voxel_pc_matches] + + # Voxelize scene + quantized_scene, scene_inds = ME.utils.sparse_quantize(points, return_index=True) + quantized_scene_colors = colors[scene_inds] + quantized_labels = labels[scene_inds] + quantized_instances = instances[scene_inds] + + return quantized_scene, quantized_scene_colors, quantized_labels, quantized_instances diff --git a/BenchmarkScripts/convert2panoptic.py b/BenchmarkScripts/convert2panoptic.py new file mode 100644 index 0000000..d1c919f --- /dev/null +++ b/BenchmarkScripts/convert2panoptic.py @@ -0,0 +1,170 @@ +#!/usr/bin/python +# +# Convert to COCO-style panoptic segmentation format (http://cocodataset.org/#format-data). +# + +# python imports +from __future__ import print_function, absolute_import, division, unicode_literals +import os +import glob +import sys +import argparse +import json +import numpy as np + +# Image processing +from PIL import Image + +EVAL_LABELS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 24, 28, 33, 34, 36, 39] +EVAL_LABEL_NAMES = ["wall", "floor", "cabinet", "bed", "chair", "sofa", "table", "door", "window", "bookshelf", "picture", "counter", "desk", "curtain", "refrigerator", "shower curtain", "toilet", "sink", "bathtub", "otherfurniture"] +EVAL_LABEL_CATS = ["indoor", "indoor", "furniture", "furniture", "furniture", "furniture", "furniture", "furniture", "furniture", "furniture", "furniture", "furniture", "furniture", "furniture", "appliance", "furniture", "furniture", "appliance", "furniture", "furniture"] +EVAL_LABEL_COLORS = [(174, 199, 232), (152, 223, 138), (31, 119, 180), (255, 187, 120), (188, 189, 34), (140, 86, 75), (255, 152, 150), (214, 39, 40), (197, 176, 213), (148, 103, 189), (196, 156, 148), (23, 190, 207), (247, 182, 210), (219, 219, 141), (255, 127, 14), (158, 218, 229), (44, 160, 44), (112, 128, 144), (227, 119, 194), (82, 84, 163)] + +def splitall(path): + allparts = [] + while 1: + parts = os.path.split(path) + if parts[0] == path: # sentinel for absolute paths + allparts.insert(0, parts[0]) + break + elif parts[1] == path: # sentinel for relative paths + allparts.insert(0, parts[1]) + break + else: + path = parts[0] + allparts.insert(0, parts[1]) + return allparts + +# The main method +def convert2panoptic(scannetPath, outputFolder=None): + + if outputFolder is None: + outputFolder = scannetPath + + # find files + search = os.path.join(scannetPath, "*", "instance", "*.png") + files = glob.glob(search) + files.sort() + # quit if we did not find anything + if not files: + print( + "Did not find any files for using matching pattern {}. Please consult the README.".format(search) + ) + sys.exit(-1) + # a bit verbose + print("Converting {} annotation files.".format(len(files))) + + outputBaseFile = "scannet_panoptic" + outFile = os.path.join(outputFolder, "{}.json".format(outputBaseFile)) + print("Json file with the annotations in panoptic format will be saved in {}".format(outFile)) + panopticFolder = os.path.join(outputFolder, outputBaseFile) + if not os.path.isdir(panopticFolder): + print("Creating folder {} for panoptic segmentation PNGs".format(panopticFolder)) + os.mkdir(panopticFolder) + print("Corresponding segmentations in .png format will be saved in {}".format(panopticFolder)) + + categories = [] + for idx in range(len(EVAL_LABELS)): + label = EVAL_LABELS[idx] + name = EVAL_LABEL_NAMES[idx] + cat = EVAL_LABEL_CATS[idx] + color = EVAL_LABEL_COLORS[idx] + isthing = label > 2 + categories.append({'id': int(label), + 'name': name, + 'color': color, + 'supercategory': cat, + 'isthing': isthing}) + + images = [] + annotations = [] + for progress, f in enumerate(files): + + originalFormat = np.array(Image.open(f)) + + parts = splitall(f) + fileName = parts[-1] + sceneName = parts[-3] + outputFileName = "{}__{}".format(sceneName, fileName) + inputFileName = os.path.join(sceneName, "color", fileName) + imageId = os.path.splitext(outputFileName)[0] + # image entry, id for image is its filename without extension + images.append({"id": imageId, + "width": int(originalFormat.shape[1]), + "height": int(originalFormat.shape[0]), + "file_name": inputFileName}) + + pan_format = np.zeros( + (originalFormat.shape[0], originalFormat.shape[1], 3), dtype=np.uint8 + ) + segmentIds = np.unique(originalFormat) + segmInfo = [] + for segmentId in segmentIds: + isCrowd = 0 + if segmentId < 1000: + semanticId = segmentId + else: + semanticId = segmentId // 1000 + if semanticId not in EVAL_LABELS: + continue + + mask = originalFormat == segmentId + color = [segmentId % 256, segmentId // 256, segmentId // 256 // 256] + pan_format[mask] = color + + area = np.sum(mask) # segment area computation + + # bbox computation for a segment + hor = np.sum(mask, axis=0) + hor_idx = np.nonzero(hor)[0] + x = hor_idx[0] + width = hor_idx[-1] - x + 1 + vert = np.sum(mask, axis=1) + vert_idx = np.nonzero(vert)[0] + y = vert_idx[0] + height = vert_idx[-1] - y + 1 + bbox = [int(x), int(y), int(width), int(height)] + + segmInfo.append({"id": int(segmentId), + "category_id": int(semanticId), + "area": int(area), + "bbox": bbox, + "iscrowd": isCrowd}) + + annotations.append({'image_id': imageId, + 'file_name': outputFileName, + "segments_info": segmInfo}) + + Image.fromarray(pan_format).save(os.path.join(panopticFolder, outputFileName)) + + print("\rProgress: {:>3.2f} %".format((progress + 1) * 100 / len(files)), end=' ') + sys.stdout.flush() + + print("\nSaving the json file {}".format(outFile)) + d = {'images': images, + 'annotations': annotations, + 'categories': categories} + with open(outFile, 'w') as f: + json.dump(d, f, sort_keys=True, indent=4) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--dataset-folder", + dest="scannetPath", + help="path to the ScanNet data 'scannet_frames_25k' folder", + required=True, + type=str) + parser.add_argument("--output-folder", + dest="outputFolder", + help="path to the output folder.", + default=None, + type=str) + args = parser.parse_args() + + convert2panoptic(args.scannetPath, args.outputFolder) + + +# call the main +if __name__ == "__main__": + main() diff --git a/BenchmarkScripts/scene_type_evaluation/evaluate_scene_type.py b/BenchmarkScripts/scene_type_evaluation/evaluate_scene_type.py new file mode 100644 index 0000000..922a984 --- /dev/null +++ b/BenchmarkScripts/scene_type_evaluation/evaluate_scene_type.py @@ -0,0 +1,173 @@ +# Evaluates scene type classification task +# Input: +# - path to .txt prediction file +# - path to .txt ground truth file +# - output file to write results to +# Note that only the valid classes are used for evaluation, +# i.e., any ground truth label not in the valid label set +# is ignored in the evaluation. +# +# example usage: evaluate_scene_type.py --pred_file [path to prediction file] --gt_file [path to gt file] --output_file [output file] + +# python imports +import math +import os, sys, argparse +import inspect + +try: + import numpy as np +except: + print "Failed to import numpy package." + sys.exit(-1) +try: + from itertools import izip +except ImportError: + izip = zip + +currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +parentdir = os.path.dirname(currentdir) +sys.path.insert(0,parentdir) +import util +import util_3d + +parser = argparse.ArgumentParser() +parser.add_argument('--pred_file', required=True, help='path to directory of predicted grids and world2grids as np arrays') +parser.add_argument('--gt_file', required=True, help='path to gt files') +parser.add_argument('--output_file', default='', help='output file [default: scene_type_evaluation.txt]') +opt = parser.parse_args() + +if opt.output_file == '': + opt.output_file = 'scene_type_evaluation.txt' + + +CLASS_LABELS = ['apartment', 'bathroom', 'bedroom / hotel', 'bookstore / library', 'conference room', 'copy/mail room', 'hallway', 'kitchen', 'laundry room', 'living_room / lounge', 'office', 'storage / basement / garage', 'misc.'] +VALID_CLASS_IDS = np.array([1, 2, 3, 4, 8, 9, 13, 14, 15, 16, 18, 20, 21]) +UNKNOWN_ID = np.max(VALID_CLASS_IDS + 1) + + +def get_iou(label_id, confusion): + if not label_id in VALID_CLASS_IDS: + return float('nan') + # #true positives + tp = np.longlong(confusion[label_id, label_id]) + # #false negatives + fn = np.longlong(confusion[label_id, :].sum()) - tp + # #false positives + not_ignored = [l for l in VALID_CLASS_IDS if not l == label_id] + fp = np.longlong(confusion[not_ignored, label_id].sum()) + + denom = (tp + fp + fn) + if denom == 0: + return float('nan') + return (float(tp) / denom, tp, denom) + + +def get_acc(label_id, confusion): + if not label_id in VALID_CLASS_IDS: + return float('nan') + # #true positives + tp = np.longlong(confusion[label_id, label_id]) + # #false negatives + fn = np.longlong(confusion[label_id, :].sum()) - tp + denom = (tp + fn) + if denom == 0: + return float('nan') + return (float(tp) / denom, tp, denom) + + +def write_result_file(confusion, ious, accs, filename): + with open(filename, 'w') as f: + f.write('iou scores\n') + for i in range(len(VALID_CLASS_IDS)): + label_id = VALID_CLASS_IDS[i] + label_name = CLASS_LABELS[i] + iou = ious[label_name][0] + f.write('{0:<32s}({1:<2d}): {2:>5.3f}\n'.format(label_name, label_id, iou)) + f.write('recall scores\n') + for i in range(len(VALID_CLASS_IDS)): + label_id = VALID_CLASS_IDS[i] + label_name = CLASS_LABELS[i] + acc = accs[label_name][0] + f.write('{0:<32s}({1:<2d}): {2:>5.3f}\n'.format(label_name, label_id, acc)) + f.write('\nconfusion matrix\n') + f.write('\t\t\t') + for i in range(len(VALID_CLASS_IDS)): + #f.write('\t{0:<32s}({1:<2d})'.format(CLASS_LABELS[i], VALID_CLASS_IDS[i])) + f.write('{0:<8d}'.format(VALID_CLASS_IDS[i])) + f.write('\n') + for r in range(len(VALID_CLASS_IDS)): + f.write('{0:<32s}({1:<2d})'.format(CLASS_LABELS[r], VALID_CLASS_IDS[r])) + for c in range(len(VALID_CLASS_IDS)): + f.write('\t{0:>5.3f}'.format(confusion[VALID_CLASS_IDS[r],VALID_CLASS_IDS[c]])) + f.write('\n') + print 'wrote results to', filename + + +def evaluate(pred_file, gt_file, output_file): + max_id = UNKNOWN_ID + 1 + confusion = np.zeros((max_id+1, max_id+1), dtype=np.ulonglong) + + predictions = {} + gt = {} + try: + lines = open(pred_file).read().splitlines() + except Exception, e: + util.print_error('unable to load ' + pred_file + ': ' + str(e)) + for line in lines: + parts = line.split(' ') + if len(parts) != 2 or not util.represents_int(parts[1]): + util.print_error('Prediction file must have lines of format [%s %d] for scan name and scene type, respectively') + predictions[parts[0]] = int(parts[1]) + try: + lines = open(gt_file).read().splitlines() + except Exception, e: + util.print_error('unable to load ' + gt_file + ': ' + str(e)) + for line in lines: + parts = line.split(' ') + if len(parts) != 2 or not util.represents_int(parts[1]): + util.print_error('Ground truth file must have lines of format [%s %d] for scan name and scene type, respectively') + gt[parts[0]] = int(parts[1]) + # sanity checks + if len(predictions) != len(gt): + util.print_error('number of predicted scans (%d) does not match number of ground truth scans (%d)' % (len(predictions), len(gt))) + print 'evaluating', len(predictions), 'scans...' + for gt_scan,gt_type in gt.iteritems(): + if gt_type not in VALID_CLASS_IDS: + continue + if gt_scan not in predictions: + util.print_error('prediction file does not contain gt scan %s' % gt_scan) + pred_type = predictions[gt_scan] + if pred_type not in VALID_CLASS_IDS: + pred_type = UNKNOWN_ID + confusion[gt_type][pred_type] += 1 + + class_ious = {} + class_accs = {} + for i in range(len(VALID_CLASS_IDS)): + label_name = CLASS_LABELS[i] + label_id = VALID_CLASS_IDS[i] + class_ious[label_name] = get_iou(label_id, confusion) + class_accs[label_name] = get_acc(label_id, confusion) + # print + print 'classes IoU' + print '----------------------------' + for i in range(len(VALID_CLASS_IDS)): + label_name = CLASS_LABELS[i] + #print('{{0:<32s}: 1:>5.3f}'.format(label_name, class_ious[label_name][0])) + print('{0:<32s}: {1:>5.3f} ({2:>6d}/{3:<6d})'.format(label_name, class_ious[label_name][0], class_ious[label_name][1], class_ious[label_name][2])) + print '' + print 'classes recall' + print '----------------------------' + for i in range(len(VALID_CLASS_IDS)): + label_name = CLASS_LABELS[i] + print('{0:<32s}: {1:>5.3f} ({2:>6d}/{3:<6d})'.format(label_name, class_accs[label_name][0], class_accs[label_name][1], class_accs[label_name][2])) + write_result_file(confusion, class_ious, class_accs, output_file) + + +def main(): + # evaluate + evaluate(opt.pred_file, opt.gt_file, opt.output_file) + + +if __name__ == '__main__': + main() diff --git a/BenchmarkScripts/scene_type_helpers/get_scene_type_for_scan.py b/BenchmarkScripts/scene_type_helpers/get_scene_type_for_scan.py new file mode 100644 index 0000000..aa7fb5c --- /dev/null +++ b/BenchmarkScripts/scene_type_helpers/get_scene_type_for_scan.py @@ -0,0 +1,53 @@ +# Example script to get the scene type from a scan in the ScanNet release +# Input: +# - path to the *.txt info file for the scan +# - path to scene_types.txt or scene_types_all.txt +# +# example usage: get_scene_type_for_scan.py --info_file ./data/ScanNet/v2/scans/scene0000_00/scene0000_00.txt --scene_type_labels_file ./data/ScanNet/v2/tasks/scene_types_all.txt + +# python imports +import math +import os, sys, argparse +import inspect + +currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +parentdir = os.path.dirname(currentdir) +sys.path.insert(0,parentdir) +import util + +parser = argparse.ArgumentParser() +parser.add_argument('--info_file', required=True, help='path to the *.txt info file for the scan') +parser.add_argument('--scene_type_labels_file', required=True, help='path to scene_types.txt or scene_types_all.txt') +opt = parser.parse_args() + + +def get_scene_type_id(type_name, type_mapping): + name = type_name.strip().lower() + if name in type_mapping: + return type_mapping[name] + return -1 + + +def get_field_from_info_file(filename, field_name): + lines = open(filename).read().splitlines() + lines = [line.split(' = ') for line in lines] + mapping = { x[0]:x[1] for x in lines } + if field_name in mapping: + return mapping[field_name] + else: + util.print_error('Failed to find %s in info file %s' % (field_name, filename)) + + +def main(): + scene_name = os.path.splitext(os.path.basename(opt.info_file))[0] + scene_type_mapping = util.read_scene_types_mapping(opt.scene_type_labels_file, remove_spaces=True) + type_name = get_field_from_info_file(opt.info_file, 'sceneType') + id = get_scene_type_id(type_name, scene_type_mapping) + if id == -1: + print('%s ==> %s ==> (not in scene types list)' % (scene_name, type_name)) + else: + print('%s ==> %s ==> %d' % (scene_name, type_name, id)) + + +if __name__ == '__main__': + main() diff --git a/BenchmarkScripts/util.py b/BenchmarkScripts/util.py new file mode 100644 index 0000000..33298a1 --- /dev/null +++ b/BenchmarkScripts/util.py @@ -0,0 +1,125 @@ +import os, sys +import csv +try: + import numpy as np +except: + print "Failed to import numpy package." + sys.exit(-1) +try: + import imageio +except: + print("Please install the module 'imageio' for image processing, e.g.") + print("pip install imageio") + sys.exit(-1) + +# print an error message and quit +def print_error(message, user_fault=False): + sys.stderr.write('ERROR: ' + str(message) + '\n') + if user_fault: + sys.exit(2) + sys.exit(-1) + + +# if string s represents an int +def represents_int(s): + try: + int(s) + return True + except ValueError: + return False + + +def read_label_mapping(filename, label_from='raw_category', label_to='nyu40id'): + assert os.path.isfile(filename) + mapping = dict() + with open(filename) as csvfile: + reader = csv.DictReader(csvfile, delimiter='\t') + for row in reader: + mapping[row[label_from]] = int(row[label_to]) + # if ints convert + if represents_int(mapping.keys()[0]): + mapping = {int(k):v for k,v in mapping.items()} + return mapping + + +# input: scene_types.txt or scene_types_all.txt +def read_scene_types_mapping(filename, remove_spaces=True): + assert os.path.isfile(filename) + mapping = dict() + lines = open(filename).read().splitlines() + lines = [line.split('\t') for line in lines] + if remove_spaces: + mapping = { x[1].strip():int(x[0]) for x in lines } + else: + mapping = { x[1]:int(x[0]) for x in lines } + return mapping + + +# color by label +def visualize_label_image(filename, image): + height = image.shape[0] + width = image.shape[1] + vis_image = np.zeros([height, width, 3], dtype=np.uint8) + color_palette = create_color_palette() + for idx, color in enumerate(color_palette): + vis_image[image==idx] = color + imageio.imwrite(filename, vis_image) + + +# color by different instances (mod length of color palette) +def visualize_instance_image(filename, image): + height = image.shape[0] + width = image.shape[1] + vis_image = np.zeros([height, width, 3], dtype=np.uint8) + color_palette = create_color_palette() + instances = np.unique(image) + for idx, inst in enumerate(instances): + vis_image[image==inst] = color_palette[inst%len(color_palette)] + imageio.imwrite(filename, vis_image) + + +# color palette for nyu40 labels +def create_color_palette(): + return [ + (0, 0, 0), + (174, 199, 232), # wall + (152, 223, 138), # floor + (31, 119, 180), # cabinet + (255, 187, 120), # bed + (188, 189, 34), # chair + (140, 86, 75), # sofa + (255, 152, 150), # table + (214, 39, 40), # door + (197, 176, 213), # window + (148, 103, 189), # bookshelf + (196, 156, 148), # picture + (23, 190, 207), # counter + (178, 76, 76), + (247, 182, 210), # desk + (66, 188, 102), + (219, 219, 141), # curtain + (140, 57, 197), + (202, 185, 52), + (51, 176, 203), + (200, 54, 131), + (92, 193, 61), + (78, 71, 183), + (172, 114, 82), + (255, 127, 14), # refrigerator + (91, 163, 138), + (153, 98, 156), + (140, 153, 101), + (158, 218, 229), # shower curtain + (100, 125, 154), + (178, 127, 135), + (120, 185, 128), + (146, 111, 194), + (44, 160, 44), # toilet + (112, 128, 144), # sink + (96, 207, 209), + (227, 119, 194), # bathtub + (213, 92, 176), + (94, 106, 211), + (82, 84, 163), # otherfurn + (100, 85, 144) + ] diff --git a/BenchmarkScripts/util_3d.py b/BenchmarkScripts/util_3d.py new file mode 100644 index 0000000..9cae538 --- /dev/null +++ b/BenchmarkScripts/util_3d.py @@ -0,0 +1,162 @@ +import os, sys +import json + +try: + import numpy as np +except: + print "Failed to import numpy package." + sys.exit(-1) + +try: + from plyfile import PlyData, PlyElement +except: + print "Please install the module 'plyfile' for PLY i/o, e.g." + print "pip install plyfile" + sys.exit(-1) + +import util + + +# matrix: 4x4 np array +# points Nx3 np array +def transform_points(matrix, points): + assert len(points.shape) == 2 and points.shape[1] == 3 + num_points = points.shape[0] + p = np.concatenate([points, np.ones((num_points, 1))], axis=1) + p = np.matmul(matrix, np.transpose(p)) + p = np.transpose(p) + p[:,:3] /= p[:,3,None] + return p[:,:3] + + +def export_ids(filename, ids): + with open(filename, 'w') as f: + for id in ids: + f.write('%d\n' % id) + + +def load_ids(filename): + ids = open(filename).read().splitlines() + ids = np.array(ids, dtype=np.int64) + return ids + + +def read_mesh_vertices(filename): + assert os.path.isfile(filename) + with open(filename, 'rb') as f: + plydata = PlyData.read(f) + num_verts = plydata['vertex'].count + vertices = np.zeros(shape=[num_verts, 3], dtype=np.float32) + vertices[:,0] = plydata['vertex'].data['x'] + vertices[:,1] = plydata['vertex'].data['y'] + vertices[:,2] = plydata['vertex'].data['z'] + return vertices + + +# export 3d instance labels for instance evaluation +def export_instance_ids_for_eval(filename, label_ids, instance_ids): + assert label_ids.shape[0] == instance_ids.shape[0] + output_mask_path_relative = 'pred_mask' + name = os.path.splitext(os.path.basename(filename))[0] + output_mask_path = os.path.join(os.path.dirname(filename), output_mask_path_relative) + if not os.path.isdir(output_mask_path): + os.mkdir(output_mask_path) + insts = np.unique(instance_ids) + zero_mask = np.zeros(shape=(instance_ids.shape[0]), dtype=np.int32) + with open(filename, 'w') as f: + for idx, inst_id in enumerate(insts): + if inst_id == 0: # 0 -> no instance for this vertex + continue + output_mask_file = os.path.join(output_mask_path_relative, name + '_' + str(idx) + '.txt') + loc = np.where(instance_ids == inst_id) + label_id = label_ids[loc[0][0]] + f.write('%s %d %f\n' % (output_mask_file, label_id, 1.0)) + # write mask + mask = np.copy(zero_mask) + mask[loc[0]] = 1 + export_ids(output_mask_file, mask) + + +# ------------ Instance Utils ------------ # + +class Instance(object): + instance_id = 0 + label_id = 0 + vert_count = 0 + med_dist = -1 + dist_conf = 0.0 + + def __init__(self, mesh_vert_instances, instance_id): + if (instance_id == -1): + return + self.instance_id = int(instance_id) + self.label_id = int(self.get_label_id(instance_id)) + self.vert_count = int(self.get_instance_verts(mesh_vert_instances, instance_id)) + + def get_label_id(self, instance_id): + return int(instance_id // 1000) + + def get_instance_verts(self, mesh_vert_instances, instance_id): + return (mesh_vert_instances == instance_id).sum() + + def to_json(self): + return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) + + def to_dict(self): + dict = {} + dict["instance_id"] = self.instance_id + dict["label_id"] = self.label_id + dict["vert_count"] = self.vert_count + dict["med_dist"] = self.med_dist + dict["dist_conf"] = self.dist_conf + return dict + + def from_json(self, data): + self.instance_id = int(data["instance_id"]) + self.label_id = int(data["label_id"]) + self.vert_count = int(data["vert_count"]) + if ("med_dist" in data): + self.med_dist = float(data["med_dist"]) + self.dist_conf = float(data["dist_conf"]) + + def __str__(self): + return "("+str(self.instance_id)+")" + +def read_instance_prediction_file(filename, pred_path): + lines = open(filename).read().splitlines() + instance_info = {} + abs_pred_path = os.path.abspath(pred_path) + for line in lines: + parts = line.split(' ') + if len(parts) != 3: + util.print_error('invalid instance prediction file. Expected (per line): [rel path prediction] [label id prediction] [confidence prediction]') + if os.path.isabs(parts[0]): + util.print_error('invalid instance prediction file. First entry in line must be a relative path') + mask_file = os.path.join(os.path.dirname(filename), parts[0]) + mask_file = os.path.abspath(mask_file) + # check that mask_file lives inside prediction path + if os.path.commonprefix([mask_file, abs_pred_path]) != abs_pred_path: + util.print_error('predicted mask {} in prediction text file {} points outside of prediction path.'.format(mask_file,filename)) + + info = {} + info["label_id"] = int(float(parts[1])) + info["conf"] = float(parts[2]) + instance_info[mask_file] = info + return instance_info + + +def get_instances(ids, class_ids, class_labels, id2label): + instances = {} + for label in class_labels: + instances[label] = [] + instance_ids = np.unique(ids) + for id in instance_ids: + if id == 0: + continue + inst = Instance(ids, id) + if inst.label_id in class_ids: + instances[id2label[inst.label_id]].append(inst.to_dict()) + return instances + + + diff --git a/Calibrate/README.md b/Calibrate/README.md new file mode 100644 index 0000000..303d826 --- /dev/null +++ b/Calibrate/README.md @@ -0,0 +1,17 @@ +## Converts uncalibrated .sens data to color/depth calibrated .sens data +=========================================================================== + +Converts uncalibrated `.sens` file to calibrated `.sens` file; calibrates color and depth distortion and aligns depth with color space. +Uses the calibration output of [CameraParameterEstimation](../CameraParameterEstimation) for a calibrated device. + +### Installation. +This code was developed under VS2013. + +Requirements: +- DirectX SDK June 2010 +- our research library mLib, a git submodule in ../external/mLib +- mLib external libraries can be downloaded [here](https://www.dropbox.com/s/fve3uen5mzonidx/mLibExternal.zip?dl=0) + + +To run: +`calibrate.exe [input sens file] [output sens file] [device calibration map file (from CameraParameterEstimation)] [directory of device calibration map files]` \ No newline at end of file diff --git a/Calibrate/calibrate.sln b/Calibrate/calibrate.sln new file mode 100644 index 0000000..9ac4411 --- /dev/null +++ b/Calibrate/calibrate.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "calibrate", "calibrate.vcxproj", "{EB0D04B5-579C-4BF9-8FC3-58DFB235231F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EB0D04B5-579C-4BF9-8FC3-58DFB235231F}.Debug|x64.ActiveCfg = Debug|x64 + {EB0D04B5-579C-4BF9-8FC3-58DFB235231F}.Debug|x64.Build.0 = Debug|x64 + {EB0D04B5-579C-4BF9-8FC3-58DFB235231F}.Release|x64.ActiveCfg = Release|x64 + {EB0D04B5-579C-4BF9-8FC3-58DFB235231F}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Calibrate/calibrate.vcxproj b/Calibrate/calibrate.vcxproj new file mode 100644 index 0000000..ba7c9f7 --- /dev/null +++ b/Calibrate/calibrate.vcxproj @@ -0,0 +1,113 @@ + + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + true + true + + + Create + Create + + + + + true + true + + + + {EB0D04B5-579C-4BF9-8FC3-58DFB235231F} + alignment + calibrate + + + + Application + true + v120 + MultiByte + + + Application + false + v120 + true + MultiByte + + + + + + + + + + + + + ../external/mLib/include;../external/mLibExternal/include/;./src/;C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include;$(IncludePath) + ..\external\mLibExternal\libsWindows\lib64;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath) + + + ../external/mLib/include;../external/mLibExternal/include/;./src/;C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include;$(IncludePath) + ..\external\mLibExternal\libsWindows\lib64;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath) + + + + Level3 + Disabled + true + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + Use + -Zm400 %(AdditionalOptions) + + + true + D3DCompiler.lib;FW1FontWrapper.lib;d3d11.lib;d3dx11.lib;kernel32.lib;user32.lib;gdi32.lib;zlib64.lib;freeimage.lib;%(AdditionalDependencies) + + + + + Level2 + MaxSpeed + true + true + true + NOMINMAX;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + Use + -Zm400 %(AdditionalOptions) + + + true + true + true + D3DCompiler.lib;FW1FontWrapper.lib;d3d11.lib;d3dx11.lib;kernel32.lib;user32.lib;gdi32.lib;zlib64.lib;freeimage.lib;%(AdditionalDependencies) + + + + + + \ No newline at end of file diff --git a/Calibrate/calibrate.vcxproj.filters b/Calibrate/calibrate.vcxproj.filters new file mode 100644 index 0000000..3c5acfa --- /dev/null +++ b/Calibrate/calibrate.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Calibrate/shaders/aligner.hlsl b/Calibrate/shaders/aligner.hlsl new file mode 100644 index 0000000..f8760a1 --- /dev/null +++ b/Calibrate/shaders/aligner.hlsl @@ -0,0 +1,180 @@ + +#define MINF asfloat(0xff800000) + +#define DEPTH_WORLD_MIN 0.1f +#define DEPTH_WORLD_MAX 10.0f + +float cameraToKinectProjZ(float z) +{ + return (z - DEPTH_WORLD_MIN) / (DEPTH_WORLD_MAX - DEPTH_WORLD_MIN); +} + +float kinectProjZToCamera(float z) +{ + return DEPTH_WORLD_MIN + z*(DEPTH_WORLD_MAX - DEPTH_WORLD_MIN); +} + + +Buffer g_depth : register(t0); + +cbuffer ConstantBuffer : register(b0) +{ + matrix g_mIntrinsicInverse; + matrix g_mIntrinsicNew; + matrix g_mExtrinsic; + uint g_uWidth; + uint g_uHeight; + uint g_uWidthNew; + uint g_uHeightNew; + float g_fDepthThreshOffset; + float g_fDepthThreshLin; + float2 g_dummy123; +} + + +void vertexShaderMain() +{ +} + +struct GS_INPUT +{ +}; + +struct PS_INPUT +{ + float4 vPosition : SV_POSITION; + float fDepth : DE; +}; + +struct PS_OUTPUT +{ + float depth; +}; + +float4 getWorldSpacePosition(uint x, uint y) +{ + float d = g_depth[y*g_uWidth + x]; + float4 posCam = mul(float4((float)x*d, (float)y*d, d, d), g_mIntrinsicInverse); + posCam = float4(posCam.x, posCam.y, posCam.z, 1.0f); + + float4 posWorld = mul(posCam, g_mExtrinsic); + posWorld /= posWorld.w; + + return posWorld; +} + +PS_INPUT ComputeQuadVertex(uint x, uint y) +{ + float d = g_depth[y*g_uWidth + x]; + float4 posWorldCC = getWorldSpacePosition(x, y); + + //float4 posWorlMC = getWorldSpacePosition(x - 1, y + 0); + //float4 posWorlCM = getWorldSpacePosition(x + 0, y - 1); + //float4 posWorlCP = getWorldSpacePosition(x + 0, y + 1); + //float4 posWorlPC = getWorldSpacePosition(x + 1, y + 0); + + //float3 normal = cross(posWorlCP.xyz - posWorlCM.xyz, posWorlPC.xyz - posWorlMC.xyz); + // normal = normalize(normal); + + float4 posClip = mul(float4(posWorldCC.x, posWorldCC.y, posWorldCC.z, 1.0f), g_mIntrinsicNew); + posClip = float4(posClip.x / posClip.z, posClip.y / posClip.z, posClip.z, 1.0f); + + // NOTE: The aspect ratio is not 2.0! + float fx = ((float)posClip.x / (float)(g_uWidthNew - 1))*2.0f - 1.0f; + //float fy = ((float)posClip.y / (float)(g_uHeightNew-1))*2.0f - 1.0f; + float fy = 1.0f - ((float) posClip.y / (float) (g_uHeightNew - 1.0f))*2.0f; + float fz = cameraToKinectProjZ(posClip.z); + posClip.x = fx; + posClip.y = fy; + posClip.z = fz; + posClip.w = 1.0f; + + PS_INPUT Out; + //Out.camSpacePosition = posWorldCC; + Out.vPosition = posClip; + //Out.vNormal = float4(normal, 1.0f); + //Out.vTexCoord = float2(0.0f, 0.0f); + Out.fDepth = d; + + return Out; +} + +PS_INPUT ComputeDebugQuadVertex(uint x, uint y) { + float d = g_depth[y*g_uWidth + x]; + + float4 posClip; + float fx = ((float)x / (float)(g_uWidth - 1))*2.0f - 1.0f; + float fy = 1.0f - ((float)y / (float)(g_uHeight - 1))*2.0f; + float fz = cameraToKinectProjZ(d); + + posClip.x = fx; + posClip.y = fy; + posClip.z = fz; + posClip.w = 1.0f; + + PS_INPUT Out; + Out.vPosition = posClip; + Out.fDepth = d; + return Out; +} + +bool isValidVertex(PS_INPUT v) { + if (v.vPosition.x < -1.0f || v.vPosition.x > 1.0f) return false; + if (v.vPosition.y < -1.0f || v.vPosition.y > 1.0f) return false; + if (v.vPosition.z < 0.0f || v.vPosition.z > 1.0f) return false; + + return true; +} + +[maxvertexcount(4)] +void geometryShaderMain(point GS_INPUT fake[1], uint quadIdx : SV_PrimitiveID, inout TriangleStream OutStream) +{ + PS_INPUT Out = (PS_INPUT)0; + + uint x = quadIdx % g_uWidth; + uint y = quadIdx / g_uWidth; + + if (x >= g_uWidth - 1) return; + if (y >= g_uHeight - 1) return; + + float d0 = g_depth[(x + 0) + g_uWidth*(y + 0)]; + float d1 = g_depth[(x + 0) + g_uWidth*(y + 1)]; + float d2 = g_depth[(x + 1) + g_uWidth*(y + 0)]; + float d3 = g_depth[(x + 1) + g_uWidth*(y + 1)]; + + if (d0 <= DEPTH_WORLD_MIN || d1 <= DEPTH_WORLD_MIN || d2 <= DEPTH_WORLD_MIN || d3 <= DEPTH_WORLD_MIN) return; + if (d0 == MINF || d1 == MINF || d2 == MINF || d3 == MINF) return; + + float dmax = max(max(d0, d1), max(d2, d3)); + float dmin = min(min(d0, d1), min(d2, d3)); + + float d = 0.5f*(dmax + dmin); + if (dmax - dmin > g_fDepthThreshOffset + g_fDepthThreshLin*d) return; + + //be aware of the order for CULLING + PS_INPUT v0 = ComputeQuadVertex(x + 0, y + 1); + PS_INPUT v1 = ComputeQuadVertex(x + 0, y + 0); + PS_INPUT v2 = ComputeQuadVertex(x + 1, y + 1); + PS_INPUT v3 = ComputeQuadVertex(x + 1, y + 0); + + if (isValidVertex(v0) && isValidVertex(v1) && isValidVertex(v2) && isValidVertex(v3)) { + OutStream.Append(v0); + OutStream.Append(v1); + OutStream.Append(v2); + OutStream.Append(v3); + } + + //OutStream.Append(ComputeQuadVertex(x + 0, y + 1)); + //OutStream.Append(ComputeQuadVertex(x + 0, y + 0)); + //OutStream.Append(ComputeQuadVertex(x + 1, y + 1)); + //OutStream.Append(ComputeQuadVertex(x + 1, y + 0)); +} + +float4 pixelShaderMain(PS_INPUT input) : SV_Target +{ + PS_OUTPUT res; + res.depth = input.fDepth; + + return float4(res, res, res, 1.0f); +} + diff --git a/Calibrate/src/aligner.cpp b/Calibrate/src/aligner.cpp new file mode 100644 index 0000000..55d6a1c --- /dev/null +++ b/Calibrate/src/aligner.cpp @@ -0,0 +1,4 @@ + +#include "stdafx.h" + +#include "aligner.h" \ No newline at end of file diff --git a/Calibrate/src/aligner.h b/Calibrate/src/aligner.h new file mode 100644 index 0000000..5c8ca1c --- /dev/null +++ b/Calibrate/src/aligner.h @@ -0,0 +1,145 @@ + +#pragma once + +#include "mLibInclude.h" + +class Aligner { +public: + Aligner(GraphicsDevice& g) { + m_graphics = &g; + + m_shaderManager.init(*m_graphics); + std::string shaderPath = util::getExecutablePath() + "../../"; + const std::string shaderFile = "shaders/aligner.hlsl"; + if (!util::fileExists(shaderPath + shaderFile)) shaderPath = util::getExecutablePath(); + m_shaderManager.registerShaderWithGS(shaderPath + shaderFile, "aligner"); + + m_constantBuffer.init(*m_graphics); + } + + ~Aligner() { + + } + + DepthImage32 depthToColor(const DepthImage32& input, const mat4f& depthIntrinsic, const mat4f& depthExtrinsic, const mat4f& colorIntrinsic, unsigned int colorWidth, unsigned int colorHeight) { + + CB cb; + cb.intrinsicInverse = depthIntrinsic.getInverse(); + cb.extrinsic = depthExtrinsic; + cb.intrinsicNew = colorIntrinsic; + cb.width = input.getWidth(); + cb.height = input.getHeight(); + cb.widthNew = colorWidth; + cb.heightNew = colorHeight; + cb.depthThreshLin = 0.05f; // additional discontinuity threshold per meter + cb.depthThreshOffset = 0.01f; // discontinuity offset in meter + m_constantBuffer.update(cb); + + D3D11Buffer depthGPU; + std::vector inputVec(input.getWidth()*input.getHeight()); + for (size_t i = 0; i < inputVec.size(); i++) inputVec[i] = input.getData()[i]; + depthGPU.init(*m_graphics, inputVec); + + D3D11RenderTarget renderTarget; + renderTarget.init(m_graphics->castD3D11(), input.getWidth(), input.getHeight(), std::vector < DXGI_FORMAT > {DXGI_FORMAT_R8G8B8A8_UNORM}, true); + renderTarget.clear(); + renderTarget.bind(); + + ID3D11DeviceContext& context = m_graphics->castD3D11().getContext(); + + context.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); + context.IASetInputLayout(NULL); + unsigned int stride = 0; + unsigned int offset = 0; + context.IASetVertexBuffers(0, 0, NULL, &stride, &offset); + + m_shaderManager.bindShaders("aligner"); + depthGPU.bindSRV(0); + m_constantBuffer.bind(0); + + m_graphics->castD3D11().setCullMode(D3D11_CULL_NONE); + unsigned int numQuads = input.getWidth()*input.getHeight(); + context.Draw(numQuads, 0); + + + //! reset the state + m_shaderManager.unbindShaders(); + depthGPU.unbindSRV(0); + + renderTarget.unbind(); + + DepthImage32 res; + res.setInvalidValue(input.getInvalidValue()); + renderTarget.captureDepthBuffer(res); + for (auto& r : res) { + if (r.value == 1.0f) r.value = res.getInvalidValue(); + else r.value = kinectProjZToCamera(r.value); + } + + context.Flush(); + + return res; + } + + //projects a depth image into color space (debug version with aliasing) + static DepthImage32 depthToColorDebug(const DepthImage32& input, const mat4f& depthIntrinsic, const mat4f& depthExtrinsic, const mat4f& colorIntrinsic, unsigned int colorWidth, unsigned int colorHeight) { + + mat4f depthIntrinsicInv = depthIntrinsic.getInverse(); + + float scalarWidth = (float)(input.getWidth()-1) / (float)(colorWidth-1); + float scalarHeight = (float)(input.getHeight()-1) / (float)(colorHeight-1); + + DepthImage32 res(input.getWidth(), input.getHeight()); + res.setInvalidValue(input.getInvalidValue()); + res.setPixels(input.getInvalidValue()); + + for (auto& o : input) { + float d = o.value; + if (d != res.getInvalidValue()) { + vec3f p = depthIntrinsicInv*vec3f((float)o.x*d, (float)o.y*d, d); //back-project to camera space + p = depthExtrinsic * p; //project to color frame + vec3f colorCoord = colorIntrinsic * p; //project to color image space + colorCoord.x /= colorCoord.z; colorCoord.y /= colorCoord.z; + vec2i colorCoordi = math::round(colorCoord); //use that to get color values + colorCoordi.x = math::round(colorCoord.x * scalarWidth); + colorCoordi.y = math::round(colorCoord.y * scalarHeight); + + if (colorCoordi.x >= 0 && colorCoordi.x < (int)res.getWidth() && colorCoordi.y >= 0 && colorCoordi.y < (int)res.getHeight()) { + res(colorCoordi.x, colorCoordi.y) = colorCoord.z; + } + } + } + return res; + } +private: +#define DEPTH_WORLD_MIN 0.1f +#define DEPTH_WORLD_MAX 10.0f + + float cameraToKinectProjZ(float z) + { + return (z - DEPTH_WORLD_MIN) / (DEPTH_WORLD_MAX - DEPTH_WORLD_MIN); + } + + float kinectProjZToCamera(float z) + { + return DEPTH_WORLD_MIN + z*(DEPTH_WORLD_MAX - DEPTH_WORLD_MIN); + } + + GraphicsDevice* m_graphics; + D3D11ShaderManager m_shaderManager; + + struct CB { + mat4f intrinsicInverse; + mat4f intrinsicNew; + mat4f extrinsic; + unsigned int width; + unsigned int height; + unsigned int widthNew; + unsigned int heightNew; + float depthThreshOffset; + float depthThreshLin; + vec2f dummy; + }; + D3D11ConstantBuffer m_constantBuffer; + +}; \ No newline at end of file diff --git a/Calibrate/src/calibration.h b/Calibrate/src/calibration.h new file mode 100644 index 0000000..8f14d93 --- /dev/null +++ b/Calibrate/src/calibration.h @@ -0,0 +1,311 @@ +#pragma once + +#include "stdafx.h" +#include "grid3d.h" + +#include "aligner.h" + +#include "omp.h" + +class Calib { +public: + Calib(const std::string& str) { + reset(); + readFromFile(str); + } + ~Calib() { + } + + void readFromFile(const std::string& str) { + ParameterFile parameterFile(str); + + reset(); + + parameterFile.readParameter("colorWidth", color_width); + parameterFile.readParameter("colorHeight", color_height); + parameterFile.readParameter("fx_color", color_intrinsic(0, 0)); + parameterFile.readParameter("fy_color", color_intrinsic(1, 1)); + parameterFile.readParameter("mx_color", color_intrinsic(0, 2)); + parameterFile.readParameter("my_color", color_intrinsic(1, 2)); + parameterFile.readParameter("k1_color", color_dist_coeff[0]); + parameterFile.readParameter("k2_color", color_dist_coeff[1]); + parameterFile.readParameter("k3_color", color_dist_coeff[2]); + parameterFile.readParameter("k4_color", color_dist_coeff[3]); + parameterFile.readParameter("k5_color", color_dist_coeff[4]); + + parameterFile.readParameter("depthWidth", depth_width); + parameterFile.readParameter("depthHeight", depth_height); + parameterFile.readParameter("fx_depth", depth_intrinsic(0, 0)); + parameterFile.readParameter("fy_depth", depth_intrinsic(1, 1)); + parameterFile.readParameter("mx_depth", depth_intrinsic(0, 2)); + parameterFile.readParameter("my_depth", depth_intrinsic(1, 2)); + parameterFile.readParameter("k1_depth", depth_dist_coeff[0]); + parameterFile.readParameter("k2_depth", depth_dist_coeff[1]); + parameterFile.readParameter("k3_depth", depth_dist_coeff[2]); + parameterFile.readParameter("k4_depth", depth_dist_coeff[3]); + parameterFile.readParameter("k5_depth", depth_dist_coeff[4]); + + parameterFile.readParameter("depthToColorExtrinsics", depth_extrinsic); + } + + unsigned int color_width, color_height; + mat4f color_extrinsic; + mat4f color_intrinsic; + float color_dist_coeff[5]; + + unsigned int depth_width, depth_height; + mat4f depth_intrinsic; + mat4f depth_extrinsic; //depth-to-color map; + float depth_dist_coeff[5]; + +private: + void reset() + { + color_extrinsic.setIdentity(); + color_intrinsic.setIdentity(); + memset(color_dist_coeff, 0, sizeof(float) * 5); + depth_extrinsic.setIdentity(); + depth_intrinsic.setIdentity(); + memset(depth_dist_coeff, 0, sizeof(float) * 5); + } + +}; + +// "Public" interface +class Calibration +{ +public: + Calibration() { + m_graphics = new D3D11GraphicsDevice(); + m_graphics->initWithoutWindow(); + } + ~Calibration() { + SAFE_DELETE(m_graphics); + } + + + void Calibration::calibrateScan(const std::string& inSensFilename, const std::string &outSensFilename, const std::string& parametersFilename, const std::string& undistortTableFilename) + { + if (!util::fileExists(inSensFilename)) { + if (util::fileExists(outSensFilename)) { + std::cout << "output sens file " << outSensFilename << " already exists, skipping" << std::endl; + return; + } + else { + throw MLIB_EXCEPTION("no sens file: " + inSensFilename); + } + } + if (!util::fileExists(parametersFilename) || !util::fileExists(undistortTableFilename)) throw MLIB_EXCEPTION("no calibration param file(s): " + parametersFilename + " / " + undistortTableFilename); + + // Read in lookup table + Grid3D undistortTable(undistortTableFilename); + + + // Read in parameters + Calib cd(parametersFilename); + + // Read in sens file + std::cout << "loading .sens file " << inSensFilename << "... "; + SensorData sd(inSensFilename); + std::cout << "done!" << std::endl; + + if (sd.m_calibrationDepth.m_extrinsic == mat4f::identity()) { + if (inSensFilename != outSensFilename) util::moveFile(inSensFilename, outSensFilename); + std::cout << "color and depth is already aligned -- cannot further calibrate .sens file -> exiting" << std::endl; + return; + } + + calibrateScan(sd, cd, undistortTable); + + // Updating .sens file meta data + sd.m_sensorName = sd.m_sensorName + " (calibrated)"; + sd.m_calibrationColor.m_extrinsic.setIdentity(); + sd.m_calibrationColor.m_intrinsic = cd.color_intrinsic; + sd.m_calibrationDepth.m_extrinsic.setIdentity(); + sd.m_calibrationDepth.m_intrinsic = sd.m_calibrationColor.m_intrinsic; + + sd.m_calibrationDepth.m_intrinsic(0, 0) *= (float)sd.m_depthWidth / (float)sd.m_colorWidth; + sd.m_calibrationDepth.m_intrinsic(1, 1) *= (float)sd.m_depthHeight / (float)sd.m_colorHeight; + sd.m_calibrationDepth.m_intrinsic(0, 2) *= (float)(sd.m_depthWidth - 1) / (float)(sd.m_colorWidth - 1); + sd.m_calibrationDepth.m_intrinsic(1, 2) *= (float)(sd.m_depthHeight - 1) / (float)(sd.m_colorHeight - 1); + + + // write sens file + std::cout << "saving .sens file " << outSensFilename << "... "; + sd.saveToFile(outSensFilename); + if (inSensFilename != outSensFilename) util::deleteFile(inSensFilename); + std::cout << "done!" << std::endl; + } + +private: + + DepthImage32 depthToColor(const DepthImage32& input, const Calib& cb) { + DepthImage32 res; +#pragma omp critical + { + Aligner aligner(*m_graphics); + res = aligner.depthToColor(input, cb.depth_intrinsic, cb.depth_extrinsic, cb.color_intrinsic, cb.color_width, cb.color_height); + } + return res; + } + + //projects a depth image into color space + DepthImage32 depthToColorDebug(const DepthImage32& input, const Calib& cb) { + + mat4f depthIntrinsicInv = cb.depth_intrinsic.getInverse(); + const mat4f& extrinsic = cb.depth_extrinsic; + const mat4f& colorIntrinsic = cb.color_intrinsic; + + float scalarWidth = (float)(input.getWidth()-1) / (float)(cb.color_width-1); + float scalarHeight = (float)(input.getHeight()-1) / (float)(cb.color_height-1); + + DepthImage32 res(input.getWidth(), input.getHeight()); + res.setInvalidValue(input.getInvalidValue()); + res.setPixels(input.getInvalidValue()); + + for (auto& o : input) { + float d = o.value; + if (d != res.getInvalidValue()) { + vec3f p = depthIntrinsicInv*vec3f((float)o.x*d, (float)o.y*d, d); //back-project to camera space + p = extrinsic * p; //project to color frame + vec3f colorCoord = colorIntrinsic * p; //project to color image space + colorCoord.x /= colorCoord.z; colorCoord.y /= colorCoord.z; + vec2i colorCoordi = math::round(colorCoord); //use that to get color values + colorCoordi.x = math::round(colorCoord.x * scalarWidth); + colorCoordi.y = math::round(colorCoord.y * scalarHeight); + + if (colorCoordi.x >= 0 && colorCoordi.x < (int)res.getWidth() && colorCoordi.y >= 0 && colorCoordi.y < (int)res.getHeight()) { + res(colorCoordi.x, colorCoordi.y) = colorCoord.z; + } + } + } + return res; + } + + template BaseImage undistort(const BaseImage& src, const mat4f& intrinsic, const float coeff[5]) + { + BaseImage res(src.getWidth(), src.getHeight()); + res.setInvalidValue(src.getInvalidValue()); + res.setPixels(res.getInvalidValue()); + + for (unsigned int y = 0; y < src.getHeight(); y++) { + for (unsigned int x = 0; x < src.getWidth(); x++) { + vec2f nic_loc; + vec2f sample_loc; + + //Normalized image coords + nic_loc.x = (x - intrinsic(0, 2)) / intrinsic(0, 0); + nic_loc.y = (y - intrinsic(1, 2)) / intrinsic(1, 1); + + float r2 = nic_loc.x * nic_loc.x + nic_loc.y * nic_loc.y; + + // Radial distortion + sample_loc.x = nic_loc.x * (1.0f + r2 * coeff[0] + r2*r2 * coeff[1] + r2*r2*r2 * coeff[4]); + sample_loc.y = nic_loc.y * (1.0f + r2 * coeff[0] + r2*r2 * coeff[1] + r2*r2*r2 * coeff[4]); + + // Tangential distortion + sample_loc.x += 2.0f * coeff[2] * nic_loc.x * nic_loc.y + coeff[3] * (r2 + 2.0f * nic_loc.x * nic_loc.x); + sample_loc.y += coeff[2] * (r2 + 2.0f * nic_loc.y * nic_loc.y) + 2.0f * coeff[3] * nic_loc.x * nic_loc.y; + + // Move back to the image space + sample_loc.x = sample_loc.x * intrinsic(0, 0) + intrinsic(0, 2); + sample_loc.y = sample_loc.y * intrinsic(1, 1) + intrinsic(1, 2); + + //TODO CONTINUE HERE + vec2i sample_loc_i = math::round(sample_loc); + if (src.isValidCoordinate(sample_loc_i)) { + res(x, y) = src(sample_loc_i); + } + } + } + return res; + } + + + void undistortDistance(unsigned short * depthData, const SensorData &sd, const Grid3D& undistortTable) { + + // Prepare storage + // Useful vars + int w = sd.m_depthWidth; + int h = sd.m_depthHeight; + int nSlices = undistortTable.ZRes(); + float xBin = (float)(w / undistortTable.XRes()); + float yBin = (float)(h / undistortTable.YRes()); + float zBin = undistortTable.ZRes() / undistortTable.MaxDist(); + float depthShift = sd.m_depthShift; + + for (int j = 0; j < h; ++j) + { + for (int i = 0; i < w; ++i) + { + float depth = depthData[j * w + i] / depthShift; + float zIdx = std::min((float)depth * zBin, (float)nSlices - 1.0f); + + float multiplier = 1.0f / undistortTable.GetValue((float)i / xBin, (float)j / yBin, zIdx); + float newDepth = depth * multiplier; + depthData[j*w + i] = (unsigned short)(newDepth * depthShift); + + } + } + } + + + void calibrateScan(SensorData& sd, const Calib& cd, const Grid3D& undistortTable) { + if (cd.depth_width != sd.m_depthWidth || cd.depth_height != sd.m_depthHeight) throw MLIB_EXCEPTION("image dimensions do not match with calibration"); + +#pragma omp parallel for + for (int i = 0; i < (int)sd.m_frames.size(); i ++) { + auto& f = sd.m_frames[i]; + if (omp_get_thread_num() == 0) { + std::cout << "\rcalibrateScan frame [ " << i*omp_get_num_threads() << " | " << sd.m_frames.size() << " ] "; + } + + // apply un-distortion to color + vec3uc* color = sd.decompressColorAlloc(f); + ColorImageR8G8B8 c(sd.m_colorWidth, sd.m_colorHeight, color); + c.setInvalidValue(vec3uc(0, 0, 0)); + c = undistort(c, cd.color_intrinsic, cd.color_dist_coeff); + std::free(color); + sd.replaceColor(f, c.getData()); + + + unsigned short* depth = sd.decompressDepthAlloc(f); + undistortDistance(depth, sd, undistortTable); // apply un-distortion based on distance + DepthImage32 d(sd.m_depthWidth, sd.m_depthHeight); + d.setInvalidValue(0.0f); + for (auto& v : d) { + unsigned int idx = v.y*sd.m_depthWidth + v.x; + v.value = (float)depth[idx] / sd.m_depthShift; + } + + // apply barell un-distortion to depth + d = (DepthImage32)Calibration::undistort(d, cd.depth_intrinsic, cd.depth_dist_coeff); + // align depth to color + d = Calibration::depthToColor(d, cd); + + // invalidate depth where we have no color + float scalarWidth = (float)(d.getWidth()-1) / (float)(sd.m_colorWidth-1); + float scalarHeight = (float)(d.getHeight()-1) / (float)(sd.m_colorHeight-1); + + for (auto& v : d) { + int x = math::round(v.x / scalarWidth); + int y = math::round(v.y / scalarHeight); + if (c(x,y) == vec3uc(0, 0, 0)) { + v.value = d.getInvalidValue(); + } + } + + // convert back to u16 + for (auto& v : d) { + unsigned int idx = v.y*(size_t)sd.m_depthWidth + v.x; + depth[idx] = math::round(v.value * sd.m_depthShift); + } + sd.replaceDepth(f, depth); + + std::free(depth); + } + std::cout << std::endl; + } + + D3D11GraphicsDevice* m_graphics; +}; \ No newline at end of file diff --git a/Calibrate/src/grid3d.cpp b/Calibrate/src/grid3d.cpp new file mode 100644 index 0000000..938838b --- /dev/null +++ b/Calibrate/src/grid3d.cpp @@ -0,0 +1,437 @@ +#include "stdafx.h" +#include "grid3d.h" + +Grid3D:: +Grid3D() +{ + m_xRes = -1; + m_yRes = -1; + m_zRes = -1; + m_maxDist = -1; + + m_data = nullptr; +} + +Grid3D:: +Grid3D(int xRes, int yRes, int zRes, float maxDist) +{ + m_xRes = xRes; + m_yRes = yRes; + m_zRes = zRes; + m_maxDist = maxDist; + + int nElements = NElements(); + m_data = new float[nElements]; + for (int i = 0; i < nElements; ++i) + { + m_data[i] = 0.0f; + } +} + +Grid3D:: +Grid3D(const Grid3D &other) +{ + m_xRes = other.XRes(); + m_yRes = other.YRes(); + m_zRes = other.ZRes(); + m_maxDist = other.MaxDist(); + + int nElements = NElements(); + m_data = new float[nElements]; + for (int i = 0; i < nElements; ++i) + { + m_data[i] = other.GetValue(i); + } +} + +Grid3D:: +Grid3D(const std::string &filename) +{ + ReadFile(filename); +} + +Grid3D:: +~Grid3D() +{ + if (m_data != nullptr) + { + delete [] m_data; + m_data = nullptr; + } + m_xRes = -1; + m_yRes = -1; + m_zRes = -1; + m_maxDist = -1; +} + +int Grid3D:: +ToIndex(int x, int y, int z) const +{ + return (z * m_xRes * m_yRes) + (y * m_xRes) + x; +} + +int Grid3D:: +XRes() const +{ + return m_xRes; +} + +int Grid3D:: +YRes() const +{ + return m_yRes; +} + +int Grid3D:: +ZRes() const +{ + return m_zRes; +} + +int Grid3D:: +NElements() const +{ + return m_xRes * m_yRes * m_zRes; +} + +float Grid3D:: +MaxDist() const +{ + return m_maxDist; +} + +float Grid3D:: +GetValue(int i) const +{ + assert(i >= 0 && i < NElements()); + return m_data[i]; +} + +float Grid3D:: +GetValue(int x, int y, int z) const +{ + assert(x >= 0 && x < m_xRes); + assert(y >= 0 && y < m_yRes); + assert(z >= 0 && z < m_zRes); + return m_data[ToIndex(x, y, z)]; +} + +float Grid3D:: +GetValue(float x, float y, float z) const +{ + assert(x >= 0 && x < m_xRes); + assert(y >= 0 && y < m_yRes); + assert(z >= 0 && z < m_zRes); + + int x1 = (int) x; + int y1 = (int) y; + int z1 = (int) z; + int x2 = x1 + 1; + int y2 = y1 + 1; + int z2 = z1 + 1; + if (x2 >= m_xRes) x2 = x1; + if (y2 >= m_yRes) y2 = y1; + if (z2 >= m_zRes) z2 = z1; + float dx = x - x1; + float dy = y - y1; + float dz = z - z1; + + float value = 0.0f; + value += GetValue(x1, y1, z1) * (1.0f - dx) * (1.0f - dy) * (1.0f - dz); + value += GetValue(x1, y1, z2) * (1.0f - dx) * (1.0f - dy) * dz; + value += GetValue(x1, y2, z1) * (1.0f - dx) * dy * (1.0f - dz); + value += GetValue(x1, y2, z2) * (1.0f - dx) * dy * dz; + + value += GetValue(x2, y1, z1) * dx * (1.0f - dy) * (1.0f - dz); + value += GetValue(x2, y1, z2) * dx * (1.0f - dy) * dz; + value += GetValue(x2, y2, z1) * dx * dy * (1.0f - dz); + value += GetValue(x2, y2, z2) * dx * dy * dz; + + return value; +} + +void Grid3D:: +SetValue(int i, float val) +{ + assert(i >= 0 && i < NElements()); + + m_data[i] = val; +} + +void Grid3D:: +SetValue(int x, int y, int z, float val) +{ + assert(x >= 0 && x < m_xRes); + assert(y >= 0 && y < m_yRes); + assert(z >= 0 && z < m_zRes); + + m_data[ToIndex(x, y, z)] = val; +} + +void Grid3D:: +Add(const float val) +{ + int nElements = NElements(); + for (int i = 0; i < nElements; ++i) + { + if (m_data[i] != GRID3D_UNKNOWN_VALUE) + m_data[i] += val; + } +} + +void Grid3D:: +Add(int x, int y, int z, float val) +{ + assert(x >= 0 && x < m_xRes); + assert(y >= 0 && y < m_yRes); + assert(z >= 0 && z < m_zRes); + int i = ToIndex(x, y, z); + if (m_data[i] != GRID3D_UNKNOWN_VALUE) + { + m_data[i] += val; + } +} + +void Grid3D:: +Add(const Grid3D &other) +{ + assert(other.XRes() == m_xRes); + assert(other.YRes() == m_yRes); + assert(other.ZRes() == m_zRes); + + int nElements = NElements(); + for (int i = 0; i < nElements; ++i) + { + if (m_data[i] != GRID3D_UNKNOWN_VALUE && + other.GetValue(i) != GRID3D_UNKNOWN_VALUE) + { + m_data[i] += other.GetValue(i); + } + } +} + +void Grid3D:: +Multiply(const float val) +{ + int nElements = NElements(); + for (int i = 0; i < nElements; ++i) + { + if (m_data[i] != GRID3D_UNKNOWN_VALUE) + { + m_data[i] *= val; + } + } +} + +void Grid3D:: +Multiply(int x, int y, int z, float val) +{ + assert(x >= 0 && x < m_xRes); + assert(y >= 0 && y < m_yRes); + assert(z >= 0 && z < m_zRes); + int i = ToIndex(x, y, z); + if (m_data[i] != GRID3D_UNKNOWN_VALUE) + { + m_data[i] *= val; + } +} + +void Grid3D:: +Multiply(const Grid3D &other) +{ + assert(other.XRes() == m_xRes); + assert(other.YRes() == m_yRes); + assert(other.ZRes() == m_zRes); + + int nElements = NElements(); + for (int i = 0; i < nElements; ++i) + { + if (m_data[i] != GRID3D_UNKNOWN_VALUE && + other.GetValue(i) != GRID3D_UNKNOWN_VALUE) + { + m_data[i] *= other.GetValue(i); + } + } +} + +void Grid3D:: +Divide(const float val) +{ + if (val == 0.0f) return; + + int nElements = NElements(); + for (int i = 0; i < nElements; ++i) + { + if (m_data[i] != GRID3D_UNKNOWN_VALUE) + { + m_data[i] /= val; + } + } +} + +void Grid3D:: +Divide(int x, int y, int z, float val) +{ + if (val == 0.0f) return; + assert(x >= 0 && x < m_xRes); + assert(y >= 0 && y < m_yRes); + assert(z >= 0 && z < m_zRes); + + int i = ToIndex(x, y, z); + if (m_data[i] != GRID3D_UNKNOWN_VALUE) + { + m_data[i] /= val; + } +} + +void Grid3D:: +Divide(const Grid3D &other) +{ + assert(other.XRes() == m_xRes); + assert(other.YRes() == m_yRes); + assert(other.ZRes() == m_zRes); + + int nElements = NElements(); + for (int i = 0; i < nElements; ++i) + { + if (other.GetValue(i) == 0.0f) // dont divide by zero. + { + m_data[i] = GRID3D_UNKNOWN_VALUE; + continue; + } + + if (m_data[i] != GRID3D_UNKNOWN_VALUE && + other.GetValue(i) != GRID3D_UNKNOWN_VALUE) + { + m_data[i] /= other.GetValue(i); + } + } +} + +void Grid3D:: +InvertElements() +{ + int nElements = NElements(); + for (int i = 0; i < nElements; ++i) + { + if (m_data[i] == 0.0f) // dont divide by zero. + { + m_data[i] = GRID3D_UNKNOWN_VALUE; + continue; + } + + if (m_data[i] != GRID3D_UNKNOWN_VALUE) + { + m_data[i] = 1.0f / m_data[i]; + } + } +} + +float Grid3D:: +Min() const +{ + float min = 1e9; + int nElements = NElements(); + for (int i = 0; i < nElements; ++i) + { + if (m_data[i] != GRID3D_UNKNOWN_VALUE && + m_data[i] < min) + { + min = m_data[i]; + } + } + return min; +} + +float Grid3D:: +Max() const +{ + float max = -1e9; + int nElements = NElements(); + for (int i = 0; i < nElements; ++i) + { + if (m_data[i] != GRID3D_UNKNOWN_VALUE && + m_data[i] > max) + { + max = m_data[i]; + } + } + return max; +} + +int Grid3D:: +ReadFile(const std::string &filename) +{ + // clear old data + if (m_data != nullptr) + { + delete [] m_data; + m_data = nullptr; + } + + // open file + FILE * fp = fopen(filename.c_str(), "rb"); + if (!fp) + { + printf("Could not open file %s for reading!\n", filename.c_str()); + fflush(stdout); + return 0; + } + + // read in header + int res[3]; + if (fread(res, sizeof(int), 3, fp) != 3) { + printf("Unable to read resolution from file %s\n", filename.c_str()); + return 0; + } + m_xRes = res[0]; + m_yRes = res[1]; + m_zRes = res[2]; + + if (fread(&m_maxDist, sizeof(float), 1, fp) != 1) { + printf("Unable to read max. distance from file %s\n", filename.c_str()); + return 0; + } + + // allocate and read data + int nElements = NElements(); + m_data = new float[nElements]; + if (fread(&(m_data[0]), sizeof(float), nElements, fp) != nElements) { + printf("Unable to read grid values from file %s\n", filename.c_str()); + return 0; + } + + return -1; +} + +int Grid3D:: +WriteFile(const std::string &filename) const +{ + FILE * fp = fopen(filename.c_str(), "wb"); + if (!fp) + { + printf("Could not open file %s for writing!\n", filename.c_str()); + return 0; + } + + if (fwrite(&m_xRes, sizeof(int), 3, fp) != 3) { + printf("Unable to write resolution to file %s\n", filename.c_str()); + return 0; + } + + if (fwrite(&m_maxDist, sizeof(float), 1, fp) != 1) { + printf("Unable to write maximum distance to file %s\n", filename.c_str()); + return 0; + } + + const int nElements = NElements(); + int test = (int)fwrite(&(m_data[0]), sizeof(float), nElements, fp); + if (test != nElements) { + printf("Unable to write grid values to file %s\n", filename.c_str()); + return 0; + } + + fclose(fp); + + return 1; +} \ No newline at end of file diff --git a/Calibrate/src/grid3d.h b/Calibrate/src/grid3d.h new file mode 100644 index 0000000..cd3309c --- /dev/null +++ b/Calibrate/src/grid3d.h @@ -0,0 +1,55 @@ +#pragma once + +#define GRID3D_UNKNOWN_VALUE -321 + +class Grid3D +{ +public: + Grid3D(); + Grid3D(int xRes, int yRes, int zRes, float maxDist); + Grid3D(const Grid3D &other); + Grid3D(const std::string &filename); + ~Grid3D(); + + int XRes() const; + int YRes() const; + int ZRes() const; + int NElements() const; + float MaxDist() const; + + float GetValue(int i) const; + float GetValue(int x, int y, int z) const; + float GetValue(float x, float y, float z) const; + void SetValue(int i, float val); + void SetValue(int x, int y, int z, float val); + + void Add(const float val); + void Add(int x, int y, int z, float val); + void Add(const Grid3D &other); + + void Multiply(const float val); + void Multiply(int x, int y, int z, float val); + void Multiply(const Grid3D &other); + + void Divide(const float val); + void Divide(int x, int y, int z, float val); + void Divide(const Grid3D &other); + + float Min() const; + float Max() const; + + void InvertElements(); + + int ReadFile(const std::string &filename); + int WriteFile(const std::string &filename) const; + +private: + int m_xRes; + int m_yRes; + int m_zRes; + float m_maxDist; + + float * m_data; + + int ToIndex(int x, int y, int z) const; +}; diff --git a/Calibrate/src/mLibInclude.h b/Calibrate/src/mLibInclude.h new file mode 100644 index 0000000..ddc5706 --- /dev/null +++ b/Calibrate/src/mLibInclude.h @@ -0,0 +1,20 @@ +#ifndef _MLIB_INCLUDE_H_ +#define _MLIB_INCLUDE_H_ + + +#include "mLibCore.h" +#include "mLibLodePNG.h" + +#include "mLibD3D11.h" +#include "mLibD3D11Font.h" + +#include "mLibFreeImage.h" +#include "mLibDepthCamera.h" + +#include "mLibZLib.h" + + + +using namespace ml; + +#endif \ No newline at end of file diff --git a/Calibrate/src/mLibSource.cpp b/Calibrate/src/mLibSource.cpp new file mode 100644 index 0000000..05f5606 --- /dev/null +++ b/Calibrate/src/mLibSource.cpp @@ -0,0 +1,8 @@ + +#include "stdafx.h" + +#include "mLibCore.cpp" +#include "mLibD3D11.cpp" +#include "mLibLodePNG.cpp" +#include "mLibDepthCamera.cpp" +#include "mLibZLib.cpp" \ No newline at end of file diff --git a/Calibrate/src/main.cpp b/Calibrate/src/main.cpp new file mode 100644 index 0000000..02f3cb7 --- /dev/null +++ b/Calibrate/src/main.cpp @@ -0,0 +1,80 @@ + +#include "stdafx.h" + +#include "main.h" +#include "calibration.h" +#include "aligner.h" + +std::string getCalibrationNameFromMap(const std::string& deviceCalibrationMapCsv, std::string scanDirectory) { + if (!util::directoryExists(scanDirectory)) throw MLIB_EXCEPTION(scanDirectory + " does not exist!"); + scanDirectory = util::replace(scanDirectory, '\\', '/'); + if (scanDirectory.back() == '/') scanDirectory.pop_back(); + const std::string scanMetaFile = scanDirectory + "/" + util::split(scanDirectory, '/').back() + ".txt"; + if (!util::fileExists(scanMetaFile)) return ""; + ParameterFile pf(scanMetaFile); std::string deviceId; + if (!pf.readParameter("deviceId", deviceId)) throw MLIB_EXCEPTION("no device id in meta file: " + scanMetaFile); + + std::unordered_map deviceIdToCalibrationName; + const std::string deviceIdHeader = "id", calibNameHeader = "calibration_name"; + unsigned int deviceIdIndex = (unsigned int)-1, calibNameIndex = (unsigned int)-1; + std::ifstream s(deviceCalibrationMapCsv); + //read header + std::string line; + if (!std::getline(s, line)) throw MLIB_EXCEPTION("failed to read device calibration map csv: " + deviceCalibrationMapCsv); + const auto headers = util::split(line, ','); + for (unsigned int i = 0; i < headers.size(); i++) { + if (headers[i] == deviceIdHeader) deviceIdIndex = i; + if (headers[i] == calibNameHeader) calibNameIndex = i; + } + if (deviceIdIndex == (unsigned int)-1 || calibNameIndex == (unsigned int)-1) throw MLIB_EXCEPTION("unable to find device id/calibration name in device calibration map cs file: " + deviceCalibrationMapCsv); + //find our device id + while (std::getline(s, line)) { + const auto elements = util::split(line, ',', true); //include empty strings + if (elements[deviceIdIndex] == deviceId) { + std::cout << "\tdevice id: " << deviceId << ", calibration name: " << elements[calibNameIndex] << std::endl; + return elements[calibNameIndex]; + } + } + s.close(); + + return ""; //nothing found +} + + +int main(int argc, char* argv[]) +{ + try { + if (argc == 5) { //converts a specific scan given by the command line arguments ( input_sens_file, output_sens_file, device_calibration_map, device_calibration_directory ) + const std::string inputSensFilename(argv[1]); + const std::string outputSensFilename(argv[2]); + const std::string deviceCalibrationMapFile(argv[3]); + std::string deviceCalibrationDir(argv[4]); + if (!(deviceCalibrationDir.back() == '/' || deviceCalibrationDir.back() == '\\')) deviceCalibrationDir.push_back('/'); + + const std::string calibrationName = getCalibrationNameFromMap(deviceCalibrationMapFile, util::directoryFromPath(inputSensFilename)); + if (!calibrationName.empty()) { + Calibration cb; + cb.calibrateScan(inputSensFilename, outputSensFilename, + deviceCalibrationDir + calibrationName + ".txt", deviceCalibrationDir + calibrationName + ".lut"); + } + else std::cout << "no calibration name found" << std::endl; + } + else { + throw MLIB_EXCEPTION("requires the input sens filepath, output sens filepath, parameter file, and input undistortion table as a command line arguments"); + } + } + catch (const std::exception& e) + { + MessageBoxA(NULL, e.what(), "Exception caught", MB_ICONERROR); + exit(EXIT_FAILURE); + } + catch (...) + { + MessageBoxA(NULL, "UNKNOWN EXCEPTION", "Exception caught", MB_ICONERROR); + exit(EXIT_FAILURE); + } + + return 0; +} + + diff --git a/Calibrate/src/main.h b/Calibrate/src/main.h new file mode 100644 index 0000000..9e593e5 --- /dev/null +++ b/Calibrate/src/main.h @@ -0,0 +1,9 @@ + +#include +#include +#include +#include +#include +#include + +#include "stdafx.h" diff --git a/Calibrate/src/processedFile.h b/Calibrate/src/processedFile.h new file mode 100644 index 0000000..3930691 --- /dev/null +++ b/Calibrate/src/processedFile.h @@ -0,0 +1,87 @@ +#pragma once + + +#include "mLibInclude.h" + +#define X_PROCESSED_FILE_STATE_FIELDS \ + X(bool, valid) \ + X(unsigned int, heapFreeCount) \ + X(unsigned int, numValidOptTransforms) \ + X(unsigned int, numTransforms) \ + X(bool, aligned) + + +#ifndef VAR_NAME +#define VAR_NAME(x) #x +#endif + +#define checkSizeArray(a, d)( (((sizeof a)/(sizeof a[0])) >= d)) + +class ProcessedFile +{ +public: + +#define X(type, name) type name; + X_PROCESSED_FILE_STATE_FIELDS +#undef X + + //! sets the parameter file and reads + void readMembers(const ParameterFile& parameterFile) { + m_ParameterFile = parameterFile; + readMembers(); + } + + //! reads all the members from the given parameter file (could be called for reloading) + void readMembers() { + aligned = false; + +#define X(type, name) \ + if (!m_ParameterFile.readParameter(std::string(#name), name) && std::string(#name) != "aligned") {MLIB_WARNING(std::string(#name).append(" ").append("uninitialized")); name = type();} + X_PROCESSED_FILE_STATE_FIELDS +#undef X + + m_bIsInitialized = true; + } + + template + std::string makeString(const T& in) { + std::string ret = std::to_string(in); + return ret; + } + template <> + std::string makeString(const bool& in) { + if (in == true) return "true"; + else return "false"; + } + + void saveToFile(const std::string& outFile) { + std::ofstream out(outFile); +#define X(type, name) \ + { out << #name << " = " << makeString(name) << std::endl; } + X_PROCESSED_FILE_STATE_FIELDS +#undef X + } + + void print() const { +#define X(type, name) \ + std::cout << #name " = " << name << std::endl; + X_PROCESSED_FILE_STATE_FIELDS +#undef X + } + + + //! constructor + ProcessedFile() { + m_bIsInitialized = false; + } + + //! destructor + ~ProcessedFile() { + } + + +private: + bool m_bIsInitialized; + ParameterFile m_ParameterFile; +}; + diff --git a/Calibrate/src/stdafx.cpp b/Calibrate/src/stdafx.cpp new file mode 100644 index 0000000..3f38672 --- /dev/null +++ b/Calibrate/src/stdafx.cpp @@ -0,0 +1,11 @@ +// stdafx.cpp : source file that includes just the standard includes +// VirtualScan.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#pragma warning (disable : 4996) + +#include "stdafx.h" + +#include "mLibSource.cpp" +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/Calibrate/src/stdafx.h b/Calibrate/src/stdafx.h new file mode 100644 index 0000000..7c83918 --- /dev/null +++ b/Calibrate/src/stdafx.h @@ -0,0 +1,16 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include +#include + +// TODO: reference additional headers your program requires here + +#include "WinSock2.h" +#include "windows.h" + +#include "mLibInclude.h" \ No newline at end of file diff --git a/CameraParameterEstimation/README.md b/CameraParameterEstimation/README.md new file mode 100644 index 0000000..e063244 --- /dev/null +++ b/CameraParameterEstimation/README.md @@ -0,0 +1,48 @@ +Structured Light Camera Calibration +===================================== + +This repository includes set of Matlab scripts and C++ programs used for +calibration of structured light depth camera. Specifically, we have calibrated +a set of Structure Sensor Cameras from [Occipital](http://http://occipital.com). + +We perform two types of calibration: + 1. Depth-To-Color Calibration + 2. Depth Distortion Calibration + +Code for performing the Depth-To-Color calibration depends on Matlab's +[Single Camera Calibration App](https://www.mathworks.com/help/vision/ug/single-camera-calibrator-app.html) + +Below we describe the both calibration types. For detailed step-by-step guide +for calibrating your camera, please see example folder. + +------------------------- + +## Depth-To-Color +This step's input is a set of 20-30 image pairs, observing a calibration grid +from different angles and distances. For this step we record rgb and infrared +images. + +Output is set of intrinsic properties for both color and infrared(depth) cameras, +as well as rigid transformation that aligns depth to color. + +------------------------- + +## Depth Distortion Calibration +The depth images returned by Structure Sensor suffer from severe distortion, that +get worse with the distance to the observed object. To undistort such images use of +a lookup table has been proposed ([Teichman et al. 13](https://pdfs.semanticscholar.org/193c/9974f85ab12636cb9bfdcabd345393c357d4.pdf)) + +Input to this step is a rgbd video sequence (~400 frames in our experiments) observing a large flat +wall with a calibration grid on it. ( it is important that flat wall covers entire +view frustrum of a camera ) + +The output is a lookup table. We provide a C++ program that applies estimated +calibration to 16-bit depth images stored as png. + +------------------------- + +## Validation +We also provide calibration_explorer application that can be used to verify the +calibration results. + + diff --git a/CameraParameterEstimation/apps/README.md b/CameraParameterEstimation/apps/README.md new file mode 100644 index 0000000..06c7866 --- /dev/null +++ b/CameraParameterEstimation/apps/README.md @@ -0,0 +1 @@ +TODO: Descibe dependiencies and what is necessary to build these. \ No newline at end of file diff --git a/CameraParameterEstimation/apps/basics/Readme.md b/CameraParameterEstimation/apps/basics/Readme.md new file mode 100644 index 0000000..f28a83c --- /dev/null +++ b/CameraParameterEstimation/apps/basics/Readme.md @@ -0,0 +1,4 @@ +# basics + +basics is work-in-progress library for developing computer graphics / vision +projects in c++ \ No newline at end of file diff --git a/CameraParameterEstimation/apps/basics/argparse.h b/CameraParameterEstimation/apps/basics/argparse.h new file mode 100644 index 0000000..6284e32 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/argparse.h @@ -0,0 +1,606 @@ +// Simple argument parsing +// Author: Maciej Halber +// Date: 03/24/16 +// License: Public Domain + + +// NOTE: This is a bit crazy part of basics, with a lot of templating . +// Possibly change this to something closer to c. +// This thing needs to go. + +#pragma once + +#include +#include +#include +#include + +namespace bsc +{ + template + struct argument + { + std::string name; + std::string short_name; + std::string message; + T * value = NULL; + + bool required = false; + int positional = -1; + int length = -1; + + argument ( std::string name, + std::string message, + T * value, + int length = 0 ); + argument ( std::string short_name, + std::string name, + std::string message, + T * value, + int length = 1 ); + }; + + class arg_parse + { + public: + std::string name; + std::string description; + + + void add( argument arg ) + { + add( arg, cstr_args ); + } + + void add( argument arg ) + { + add( arg, str_args ); + } + + void add( argument arg ) + { + add( arg, int_args ); + } + + void add( argument arg ) + { + add( arg, float_args ); + } + + void add( argument arg ) + { + add( arg, double_args ); + } + + void add( argument arg ) + { + add( arg, bool_args ); + } + + void parse( int argc, char** argv ); + + bool exists_already( std::string name ) const; + + argument * find_string( std::string key ) + { + return find( key, str_args ); + } + + argument * find_int( std::string key ) + { + return find( key, int_args ); + } + + argument * find_float( std::string key ) + { + return find( key, float_args ); + } + + argument * find_double( std::string key ) + { + return find( key, double_args ); + } + + argument * find_bool( std::string key ) + { + return find( key, bool_args ); + } + + void print_help() const; + + private: + std::unordered_map< std::string, argument< std::string > > str_args; + std::unordered_map< std::string, argument< char* > > cstr_args; + std::unordered_map< std::string, argument< int > > int_args; + std::unordered_map< std::string, argument< float > > float_args; + std::unordered_map< std::string, argument< double > > double_args; + std::unordered_map< std::string, argument< bool > > bool_args; + + template + void add( argument & arg, + std::unordered_map< std::string, + argument< T > > & args ); + + template + argument * find( std::string key, + std::unordered_map< std::string, + argument< T > > & args ); + + template + argument * find_at_position ( int position, + std::unordered_map< std::string, + argument< T > > & args ); + }; + + static int arg_parse_num_required = 0; +} + + +//////////////////////////////////////////////////////////////////////////////// +// Implementation +//////////////////////////////////////////////////////////////////////////////// +#ifdef BSC_IMPLEMENTATION + +// argument constructors. little lengthy due to error checking +template +bsc::argument:: +argument ( std::string name, std::string message, T * value, int length ) +{ + if ( name.empty() ) + { + printf( "argument name must not be an empty string\n" ); + exit(-1); + } + + this->name = name; + this->value = value; + this->message = message; + this->length = length; + + if ( name[0] == '-' && name[1] == '-' ) + { + this->required = false; + if ( length < 2 ) this->length = 1; + if ( name.length() < 3 ) + { + printf( "argument \"%s\" name must be at least 3" + " characters long! ( -- )\n", name.c_str() ); + exit(-1); + } + } + else if ( name[0] == '-' ) + { + this->required = false; + if ( length < 2 ) this->length = 1; + if ( name.length() != 2 ) + { + printf( "argument \"%s\" shorthand \"%s\" must be at least 2" + " characters long ( - )\n", + name.c_str(), name.c_str() ); + exit(-1); + } + } + else + { + this->required = true; + this->positional = ++arg_parse_num_required - 1; + } +} + +template +bsc::argument:: +argument ( std::string short_name, + std::string name, + std::string message, + T * value, int length ) +{ + if ( name.length() < 3 ) + { + printf( "argument \"%s\" name must be at least 3" + " characters long! ( -- )\n", name.c_str() ); + exit(-1); + } + + if ( short_name.length() > 4 ) + { + printf( "argument \"%s\" shorthand \"%s\" must be at" + " less then 4 characters long ( - )\n", + name.c_str(), short_name.c_str() ); + exit(-1); + } + + this->name = name; + this->short_name = short_name; + this->value = value; + this->message = message; + this->length = length; + this->required = false; +} + + +bool bsc::arg_parse :: +exists_already ( std::string name ) const +{ + if ( str_args.find( name ) != str_args.end() ) return true; + if ( int_args.find( name ) != int_args.end() ) return true; + if ( float_args.find( name ) != float_args.end() ) return true; + if ( double_args.find( name ) != double_args.end() ) return true; + if ( bool_args.find( name ) != bool_args.end() ) return true; + return false; +} + + +template +void bsc::arg_parse :: +add ( argument & arg, + std::unordered_map< std::string, argument< T > > & args ) +{ + bool check_name = !exists_already( arg.name ); + bool check_short_name = arg.short_name.empty() + ? 1 + : !exists_already( arg.short_name ); + if ( check_name && check_short_name ) + { + args.insert( std::make_pair( arg.name, arg ) ); + if ( !arg.required ) + { + args.insert( std::make_pair( arg.short_name, arg ) ); + } + } + else + { + printf("argument with name \"%s\" is in conflict!", arg.name.c_str() ); + print_help(); + } +} + +template +bsc::argument * bsc::arg_parse :: +find ( std::string key, + std::unordered_map< std::string, + argument< T > > & args ) +{ + auto arg = args.find( key ); + if ( arg != args.end() ) + { + return &( arg->second ); + } + else + { + return nullptr; + } +} + +template +bsc::argument * bsc::arg_parse :: +find_at_position ( int position, + std::unordered_map< std::string, + argument< T > > & args ) +{ + argument * retval = nullptr; + for ( auto & arg : args ) + { + if ( arg.second.positional == position ) + { + retval = &( arg.second ); + break; + } + } + return retval; +} +//////////////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////////////// + +// check if arg passed during parsing is correct, when parsing multiple values +template +void check_validity( int idx, + int n_args, + std::string to_parse, + bsc::argument *arg ) +{ + if ( idx >= n_args || to_parse[0] == '-' ) + { + printf ("No more values to parse for argument %s (%s)," + " correct value is %d argument(s)\n", + arg->name.c_str(), + arg->short_name.c_str(), arg->length ); + exit( -1 ); + } +}; + +template +void parse_arg ( std::vector & args_to_parse, + int & idx, + bsc::argument * arg, + std::string to_parse, + std::function acceptance_function, + std::function conversion_funct ) +{ + if ( arg->length == 0 ) + { + *(arg->value) = acceptance_function( to_parse ); + } + + for ( int i = 0 ; i < arg->length ; ++i ) + { + to_parse = args_to_parse[ ++idx ]; + check_validity( idx, args_to_parse.size(), to_parse, arg ); + *(arg->value + i) = conversion_funct( to_parse ); + } +}; + +void bsc::arg_parse :: +parse ( int argc, char** argv ) +{ + // skip name of program + name = std::string( *argv ); + argc--; argv++; + + // parse into helper data structure + std::vector< std::string > args_to_parse; + args_to_parse.reserve( argc ); + while ( argc > 0 ) + { + args_to_parse.push_back( std::string( *argv ) ); + argc--; argv++; + } + + // helper variables + int idx = 0; + int n_args = args_to_parse.size(); + + // parse value to correct argument + auto parse_argument = [ &args_to_parse, &idx, n_args ] + ( std::string to_parse, + argument* str_arg, + argument* cstr_arg, + argument* int_arg, + argument* float_arg, + argument* double_arg, + argument* bool_arg ) + { + // define some conversion function wrappers + std::function identity = [] ( std::string arg ) { return arg; }; + std::function to_cstr = [] ( std::string arg ) { return strdup( arg.c_str() ); }; + std::function to_int = [] ( std::string arg ) { return std::stoi( arg ); }; + std::function to_float = [] ( std::string arg ) { return std::stof( arg ); }; + std::function to_double = [] ( std::string arg ) { return std::stod( arg ); }; + std::function to_bool = [] ( std::string arg ) { return (bool)std::stoi( arg ); }; + std::function accept_int = [] ( std::string arg ) { return 1; }; + std::function accept_float = [] ( std::string arg ) { return 1; }; + std::function accept_double = [] ( std::string arg ) { return 1; }; + std::function accept_bool = [] ( std::string arg ) { return 1; }; + + // actual parsing happens here. We either accept the value + // ( if length is 0 ), or convert to correct type using conversion function + + // NOTE:This lambda needs to be templated + + if ( str_arg != nullptr ) + { + parse_arg( args_to_parse, idx, str_arg, to_parse, identity, identity ); + } + if ( cstr_arg != nullptr ) + { + parse_arg( args_to_parse, idx, cstr_arg, to_parse, to_cstr, to_cstr ); + } + else if ( int_arg != nullptr ) + { + parse_arg( args_to_parse, idx, int_arg, to_parse, accept_int, to_int ); + } + else if ( float_arg != nullptr ) + { + parse_arg( args_to_parse, idx, float_arg, to_parse, accept_float, to_float ); + } + else if ( double_arg != nullptr ) + { + parse_arg( args_to_parse, idx, double_arg, to_parse, accept_double, to_double ); + } + else if ( bool_arg != nullptr ) + { + parse_arg( args_to_parse, idx, bool_arg, to_parse, accept_bool, to_bool ); + } + }; + + // check if help is there + for ( int str_idx = 0 ; str_idx < n_args ; ++str_idx ) + { + if ( args_to_parse[str_idx] == "--help" || + args_to_parse[str_idx] == "-h" ) + { + print_help(); + } + } + + // Some corner cases + if ( n_args < arg_parse_num_required ) print_help(); + if ( args_to_parse.empty() ) return; + + // Get required positional arguments + for ( int position = 0 ; position < arg_parse_num_required ; ++position ) + { + argument * str_arg = find_at_position( position, str_args ); + argument * cstr_arg = find_at_position( position, cstr_args ); + argument * int_arg = find_at_position( position, int_args ); + argument * float_arg = find_at_position( position, float_args ); + argument * double_arg = find_at_position( position, double_args ); + argument * bool_arg = find_at_position( position, bool_args ); + + std::string cur_arg = args_to_parse[ idx ]; + if ( cur_arg[0] == '-' ) + { + printf( "Invalid argument \"%s\" at position %d!\n", + cur_arg.c_str(), position ); + print_help(); + } + + parse_argument( cur_arg, str_arg, cstr_arg, + int_arg, float_arg, double_arg, bool_arg ); + idx++; + } + + // Get the rest of arguments + while ( idx < n_args ) + { + // check which one it is + std::string cur_arg = args_to_parse[ idx ]; + + // try to find it + bool found = true; + argument * str_arg = find( cur_arg, str_args ); + argument * cstr_arg = find( cur_arg, cstr_args ); + argument * int_arg = find( cur_arg, int_args ); + argument * float_arg = find( cur_arg, float_args ); + argument * double_arg = find( cur_arg, double_args ); + argument * bool_arg = find( cur_arg, bool_args ); + + if ( str_arg == nullptr && int_arg == nullptr && cstr_arg == nullptr && + float_arg == nullptr && double_arg == nullptr && + bool_arg == nullptr ) + { + found = false; + } + + if ( found ) + { + parse_argument( cur_arg, str_arg, cstr_arg, + int_arg, float_arg, double_arg, bool_arg ); + } + else + { + printf( "Unrecognized argument \"%s\"\n", cur_arg.c_str() ); + print_help(); + } + + idx++; + } +} + +// helper storage struct +struct argument_info +{ + std::string name; + std::string short_name; + std::string message; + std::string type; + int count; +}; + + +// copy from actual argument storage to local sturctures + // that do not vary on type +template +void group_arguments ( std::vector & required_args, + std::unordered_map & optional_args_map, + const std::unordered_map< std::string, bsc::argument< T > >& args, + const std::string type ) +{ + for ( const auto & arg : args ) + { + argument_info info = { arg.second.name, arg.second.short_name, + arg.second.message, type, arg.second.length }; + if ( arg.second.required ) + { + required_args[ arg.second.positional ] = info; + } + else + { + optional_args_map.insert( std::make_pair( info.name, info ) ); + } + } +}; + +// formatted printing +void print_args( std::vector &args ) +{ + for ( const auto & arg : args ) + { + std::string full_name = arg.name; + if ( !arg.short_name.empty() ) + { + full_name = arg.short_name + ", " + full_name; + } + + if ( arg.count <= 1 ) + { + printf(" %-24s - %s <%s>\n", full_name.c_str(), + arg.message.c_str(), + arg.type.c_str() ); + } + else + { + printf(" %-24s - %s <%d %ss>\n", full_name.c_str(), + arg.message.c_str(), + arg.count, + arg.type.c_str() ); + } + } +}; + +void bsc::arg_parse :: +print_help() const +{ + + // printing help is here by default + argument_info help_info = { "--help", "-h", + "Show this help message and exit", "", 0 }; + + // storage + std::vector< argument_info > required_args; + std::vector< argument_info > optional_args; + required_args.resize( arg_parse_num_required ); + std::unordered_map< std::string, argument_info > optional_args_map; + + // Gather info + group_arguments( required_args, optional_args_map, str_args, "string"); + group_arguments( required_args, optional_args_map, cstr_args, "cstring" ); + group_arguments( required_args, optional_args_map, int_args, "int" ); + group_arguments( required_args, optional_args_map, float_args, "float" ); + group_arguments( required_args, optional_args_map, double_args, "doule" ); + group_arguments( required_args, optional_args_map, bool_args, "bool" ); + + // Copy form a map to vector ( done to avoid duplicates ) + for ( const auto & elem : optional_args_map ) + { + optional_args.push_back( elem.second ); + } + optional_args.push_back( help_info ); + + // Sort optionals + std::sort( optional_args.begin(), optional_args.end(), + []( const argument_info & a, const argument_info & b ) + { + int idx_a = a.name.find_last_of("-") + 1; + int idx_b = b.name.find_last_of("-") + 1; + std::string a_name = a.name.substr( idx_a, -1 ); + std::string b_name = b.name.substr( idx_b, -1 ); + return a_name < b_name; + } ); + + // Actual printing of help message + printf( "\nUsage : %s ", name.c_str() ); + for ( const auto & arg : required_args ) printf( "%s ", arg.name.c_str() ); + for ( const auto & arg : optional_args ) printf( "%s ", arg.name.c_str() ); + printf("\n\n"); + + if ( !description.empty() ) + { + printf("Description: %s\n\n", description.c_str() ); + } + + if ( !required_args.empty() ) + { + printf("Required arguments:\n"); + print_args( required_args ); + printf("\n"); + } + + printf("Optional arguments:\n"); + print_args( optional_args ); + printf("\n"); + + exit(-1); +} + +#endif //BSC_IMPLEMENTATION \ No newline at end of file diff --git a/CameraParameterEstimation/apps/basics/basics.h b/CameraParameterEstimation/apps/basics/basics.h new file mode 100644 index 0000000..245cc86 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/basics.h @@ -0,0 +1,182 @@ +// basics v0.07 +// by Maciej Halber + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +// This is a 'work-in-progress', header-only library, aimed at simplifying +// writing graphics api. Currently *all* of the features are in progress and +// might change. + +// Semi stable features: +// - window creation and display loops ( powered by GLFW3 ) +// - linear algebra ( vec2/3/4, mat2/3/4, quaternions -> modelled after glm ) +// - opengl shader creation + +// BIG TODO's +// - 2d graphics api +// - 3d graphics api +// - data containers ( hashmaps, grids, kdtrees ) + +// This library is needs C++11 compiler, however use of C++ features is aimed to +// be kept low. C++ features that this library does use: +// - operator overloading ( for math ) +// - function overridng +// - templates ( very sparsely, for math ) +// - threads + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +//TODO(maciej): Insert define flags to improve modularity of basics + +//////////////////////////////////////////////////////////////////////////////// +// EMSCRIPTEN +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __BSC__ +#define __BSC__ + +#ifdef __EMSCRIPTEN__ + #include "emscripten.h" +#endif + +//////////////////////////////////////////////////////////////////////////////// +// C / C++ HEADERS +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include + +// TODO(maciej): try to limit usage of cpp headers? +#include +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +// THIRD PARTY LIBRARIES +//////////////////////////////////////////////////////////////////////////////// + +#ifdef BSC_USE_WINDOW // Graphics through window + + // glew for opengl extension + // TODO(maciej): To be removed and replaced with some inline loader + #ifndef __EMSCRIPTEN__ + #if defined(_WIN32) || defined(_WIN64) + #include "GL/glew.h" + #endif + #else + #define GLFW_INCLUDE_ES2 + #endif + + // glfw configuration + // TODO(maciej): Unlikely in near feature, but we might strip this. + #define GLFW_INCLUDE_GLCOREARB /* don't drag in legacy GL headers. */ + #define GLFW_NO_GLU + #include "GLFW/glfw3.h" + +#else // offscreen rendering + + #ifdef __APPLE__ + #include + #include + #include + #include + #endif + + #ifdef __unix__ + #include + #include + #include + #include + #endif + + //TODO: Windows + +#endif + + +// tiny_dir for easy directory stepping and file name/extension tokenizing +#include "extern/tiny_dir.h" + + +// IMAGES +// Basics supports reading/writing of 2 image types: PNG, JPEG +// This is accomplished by a handful of nice single header libraries + +// stb_image.h by Sean T. Barret -> JPEG(read) +// tiny_jpeg.h by Sergio Gonzalez -> JPEG(write) +// lodepng.h by Lode Vandevenne -> PNG(read/write) + +// TODO(maciej): Add support for BMP and TGA + +// stb_image configuration +#define STBI_ONLY_JPEG +#define STBI_FAILURE_USERMSG +#define STB_IMAGE_IMPLEMENTATION +#include "extern/stb_image.h" + +// stb_image_write configuration +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include "extern/stb_image_write.h" + +// lodepng configuration +// TODO(maciej): Can we use zlib implementation from stb? +#define LODEPNG_IMPLEMENTATION +#include "extern/lodepng.h" + +// tinyjpeg configuration +#define TJE_IMPLEMENTATION +#include "extern/tiny_jpeg.h" + +// 3D formats +// TODO(maciej): This needs to be added + +// Optionally a support is provided for imgui. Ideally bsc::ui will allow user +// to create immediate mode interfaces, but for the time being, user can enable +// using imgui. +// Note that you only need to add imgui calls in your rendering code. Standard +// per frame calls and initialization is managed by bsc::ui +#ifdef BSC_USE_IMGUI +#include "extern/imgui/imgui.h" +#endif + +//////////////////////////////////////////////////////////////////////////////// +// BASICS MODULES +//////////////////////////////////////////////////////////////////////////////// + +// NOTE: (maciej) These files are quite big, and thye only contain a font... +// need to come up with better idea +#include "ubuntu_mono.h" + +#include "common.h" + +#include "argparse.h" + +#include "linalg/vector.h" +#include "linalg/matrix.h" +#include "linalg/quaternion.h" +#include "linalg/geometry.h" +#include "linalg/debug.h" + +#include "gfx/image.h" +#include "gfx/shader.h" + +#ifdef BSC_USE_WINDOW + #include "window/window.h" + #include "gfx/camera.h" // camera controls only make sense with mouse + #include "gfx/draw2d.h" // TODO: Fix that! +#endif + +#include "gfx/gpu_assets.h" +#include "gfx/param_shapes.h" + + +#endif /*__BSC__*/ diff --git a/CameraParameterEstimation/apps/basics/common.h b/CameraParameterEstimation/apps/basics/common.h new file mode 100644 index 0000000..fe1d73d --- /dev/null +++ b/CameraParameterEstimation/apps/basics/common.h @@ -0,0 +1,366 @@ +// basics v0.07 +// by Maciej Halber + +//////////////////////////////////////////////////////////////////////////////// +// TYPES +//////////////////////////////////////////////////////////////////////////////// + +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef float r32; +typedef double r64; + +//////////////////////////////////////////////////////////////////////////////// +// MACROS +//////////////////////////////////////////////////////////////////////////////// + +#define STR(x) #x +#define XSTR(x) STR(x) +#define COUNT_OF(x) (sizeof(x) / sizeof((x)[0])) + +#define CCAT(A, B) A ## B +#define XCCAT(A, B) CCAT(A, B) +#define XSTR_CCAT(A,B) XSTR(XCCAT(A,B)) + +// TODO foreach loop +// TODO iterating over enum +// TODO get max of enum + +//////////////////////////////////////////////////////////////////////////////// +// SIMPLE COMMON FUNCTIONS +//////////////////////////////////////////////////////////////////////////////// +#ifdef BSC_IMPLEMENTATION + +namespace bsc +{ + template + inline T + clamp ( T val, T min = (T)0, T max = (T)1 ) + { + if ( val < min ) val = min; + if ( val > max ) val = max; + return val; + } + + template + inline T + lerp ( T a, T b, T t ) + { + return a + ( b - a ) * t; + } + + template + inline void + swap ( T & a, T & b ) + { + T tmp = a; + a = b; + b = tmp; + } + + template + inline T + square ( const T & a ) + { + return a * a; + } + + template + inline T + max ( T a, T b ) + { + return a > b ? a : b; + } + + template + inline T + min ( T a, T b ) + { + return a > b ? b : a; + } + + template + inline T + min3 ( T a, T b, T c ) + { + return min( c, min( a, b ) ); + } + + template + inline T + max3 ( T a, T b, T c ) + { + return max( c, max( a, b ) ); + } + + + template + inline T + deg2rad ( T deg ) + { + return deg * M_PI / 180.0; + } + + template + inline T + rad2deg ( T rad ) + { + return rad * 180.0 / M_PI; + } + + template< int n_reps = 1, + typename TimeUnit = std::chrono::duration, + typename F, typename ...Args > + typename TimeUnit::rep MeasureTime ( F function, Args&&... arguments ) + { + using namespace std::chrono; + auto start = system_clock::now(); + + for ( int i = 0 ; i < n_reps; ++i ) + { + function( std::forward(arguments)... ); + } + + auto duration = duration_cast( system_clock::now() - start ); + + return duration.count() / (double)n_reps; + } + + template > + struct StopWatch + { + std::chrono::time_point s; // start + std::chrono::time_point e; // end + + void start () { s = std::chrono::system_clock::now(); } + void read () { s = std::chrono::system_clock::now(); } + typename TimeUnit::rep duration() + { + return std::chrono::duration_cast( e - s ).count(); + } + + typename TimeUnit::rep elapsed () + { + return std::chrono::duration_cast( + std::chrono::system_clock::now() - s ).count(); + } + + }; + + typedef StopWatch< std::chrono::duration > stop_watch; + + + // Based on notes by Humus : + // http://www.humus.name/index.php?page=Comments&ID=296 + inline int + string_hash ( const char * str ) + { + int hash = 0; + for ( int i = 0; i < strlen( str ) ; ++i ) + hash = hash * 65599 + str[i]; + return hash; + } + + + // Floating point comparisons based on Thomas Funkhouser gaps library + inline bool + is_positive( r32 s, r32 epsilon ) + { + return (s > epsilon); + } + + inline bool + is_positive( r64 s, r64 epsilon ) + { + return (s > epsilon); + } + + inline bool + is_negative ( r32 s, r32 epsilon ) + { + return ( s < -epsilon ); + } + + inline bool + is_negative ( r64 s, r64 epsilon ) + { + return ( s < -epsilon ); + } + + inline bool + is_positive_or_zero ( r32 s, r32 epsilon ) + { + return ( s >= -epsilon ); + } + + inline bool + is_positive_or_zero ( r64 s, r64 epsilon ) + { + return ( s >= -epsilon ); + } + + inline bool + is_negative_or_zero ( r32 s, r32 epsilon ) + { + return ( s <= epsilon ); + } + + inline bool + is_negative_or_zero ( r64 s, r64 epsilon ) + { + return ( s <= epsilon ); + } + + inline bool + is_zero ( r32 s, r32 epsilon ) + { + return ( is_positive_or_zero( s, epsilon ) && + is_negative_or_zero( s, epsilon ) ); + } + + inline bool + is_zero ( r64 s, r64 epsilon ) + { + return ( is_positive_or_zero( s, epsilon ) && + is_negative_or_zero( s, epsilon ) ); + } + + inline bool + is_not_zero ( r32 s, r32 epsilon ) + { + return ( is_positive( s, epsilon ) || + is_negative( s, epsilon ) ); + } + + inline bool + is_not_zero ( r64 s, r64 epsilon ) + { + return ( is_positive( s, epsilon ) || + is_negative( s, epsilon ) ); + } + + inline bool + equal ( r32 s1, r32 s2, r32 epsilon ) + { + return is_zero( s1 - s2, epsilon ); + } + + inline bool + equal ( r64 s1, r64 s2, r64 epsilon ) + { + return is_zero( s1 - s2, epsilon ); + } + + inline bool + notEqual ( r32 s1, r32 s2, r32 epsilon ) + { + return is_not_zero( s1 - s2, epsilon ); + } + + inline bool + notEqual ( r64 s1, r64 s2, r64 epsilon ) + { + return is_not_zero( s1 - s2, epsilon ); + } + + inline bool + greater ( r32 s1, r32 s2, r32 epsilon ) + { + return is_positive( s1 - s2, epsilon ); + } + + inline bool + greater ( r64 s1, r64 s2, r64 epsilon ) + { + return is_positive( s1 - s2, epsilon ); + } + + inline bool + less ( r32 s1, r32 s2, r32 epsilon ) + { + return is_negative( s1 - s2, epsilon ); + } + + inline bool + less ( r64 s1, r64 s2, r64 epsilon ) + { + return is_negative( s1 - s2, epsilon ); + } + + inline bool + greater_or_equal ( r32 s1, r32 s2, r32 epsilon ) + { + return is_positive_or_zero( s1 - s2, epsilon ); + } + + inline bool + greater_or_equal ( r64 s1, r64 s2, r64 epsilon ) + { + return is_positive_or_zero( s1 - s2, epsilon ); + } + + inline bool + less_or_equal ( r32 s1, r32 s2, r32 epsilon ) + { + return is_negative_or_zero( s1 - s2, epsilon ); + } + + inline bool + less_or_equal ( r64 s1, r64 s2, r64 epsilon ) + { + return is_negative_or_zero( s1 - s2, epsilon ); + } + + // error reporting + inline void + error ( const char * title, const int line, + const char * description ) + { + fprintf( stderr, "%s at line %d -> %s\n", title, line, description ); + } + +// Array stuff +// TODO: Testing! + + inline r32 inner_product( const r32 *vals, const i32 n_vals ) + { + r32 value = 0.0f; + for ( int i = 0 ; i < n_vals ; ++i ) + { + value += vals[i] * vals[i]; + } + return value; + } + + inline r32 compute_sum( const r32 *vals, const i32 n_vals ) + { + // TODO: Assertions and errors + r32 sum = 0; + for ( int i = 0 ; i < n_vals ; ++i ) + { + sum += vals[i]; + } + return sum; + } + + inline r32 compute_mean( const r32 *vals, const i32 n_vals ) + { + r32 sum = compute_sum( vals, n_vals ); + return sum / (r32) n_vals; + } + + inline r32 compute_stddev( r32 mean, r32 *vals, i32 n_vals ) + { + r32 sq_sum = inner_product( vals, n_vals ); + return sqrtf( sq_sum / (r32)n_vals - mean * mean ); + } +} +#endif //BSC_IMPLEMENTATION diff --git a/CameraParameterEstimation/apps/basics/extern/imgui/LICENSE b/CameraParameterEstimation/apps/basics/extern/imgui/LICENSE new file mode 100644 index 0000000..b28ef22 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/imgui/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2015 Omar Cornut and ImGui contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/CameraParameterEstimation/apps/basics/extern/imgui/imconfig.h b/CameraParameterEstimation/apps/basics/extern/imgui/imconfig.h new file mode 100644 index 0000000..33cbadd --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/imgui/imconfig.h @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------------- +// USER IMPLEMENTATION +// This file contains compile-time options for ImGui. +// Other options (memory allocation overrides, callbacks, etc.) can be set at runtime via the ImGuiIO structure - ImGui::GetIO(). +//----------------------------------------------------------------------------- + +#pragma once + +//---- Define assertion handler. Defaults to calling assert(). +//#define IM_ASSERT(_EXPR) MyAssert(_EXPR) + +//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows. +//#define IMGUI_API __declspec( dllexport ) +//#define IMGUI_API __declspec( dllimport ) + +//---- Include imgui_user.h at the end of imgui.h +//#define IMGUI_INCLUDE_IMGUI_USER_H + +//---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions) +//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS +//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS + +//---- Don't implement help and test window functionality (ShowUserGuide()/ShowStyleEditor()/ShowTestWindow() methods will be empty) +//#define IMGUI_DISABLE_TEST_WINDOWS + +//---- Don't define obsolete functions names +//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS + +//---- Implement STB libraries in a namespace to avoid conflicts +//#define IMGUI_STB_NAMESPACE ImGuiStb + +//---- Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4. +/* +#define IM_VEC2_CLASS_EXTRA \ + ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ + operator MyVec2() const { return MyVec2(x,y); } + +#define IM_VEC4_CLASS_EXTRA \ + ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ + operator MyVec4() const { return MyVec4(x,y,z,w); } +*/ + +//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. +//---- e.g. create variants of the ImGui::Value() helper for your low-level math types, or your own widgets/helpers. +/* +namespace ImGui +{ + void Value(const char* prefix, const MyMatrix44& v, const char* float_format = NULL); +} +*/ + diff --git a/CameraParameterEstimation/apps/basics/extern/imgui/imgui.cpp b/CameraParameterEstimation/apps/basics/extern/imgui/imgui.cpp new file mode 100644 index 0000000..28c3571 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/imgui/imgui.cpp @@ -0,0 +1,9777 @@ +// dear imgui, v1.50 WIP +// (main code and documentation) + +// See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. +// Newcomers, read 'Programmer guide' below for notes on how to setup ImGui in your codebase. +// Get latest version at https://github.com/ocornut/imgui +// Releases change-log at https://github.com/ocornut/imgui/releases +// Developed by Omar Cornut and every direct or indirect contributors to the GitHub. +// This library is free but I need your support to sustain development and maintenance. +// If you work for a company, please consider financial support, e.g: https://www.patreon.com/imgui + +/* + + Index + - MISSION STATEMENT + - END-USER GUIDE + - PROGRAMMER GUIDE (read me!) + - API BREAKING CHANGES (read me when you update!) + - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS + - How can I help? + - How do I update to a newer version of ImGui? + - What is ImTextureID and how do I display an image? + - I integrated ImGui in my engine and the text or lines are blurry.. + - I integrated ImGui in my engine and some elements are clipping or disappearing when I move windows around.. + - How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs. + - How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application? + - How can I load a different font than the default? + - How can I load multiple fonts? + - How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic? + - How can I use the drawing facilities without an ImGui window? (using ImDrawList API) + - ISSUES & TODO-LIST + - CODE + + + MISSION STATEMENT + ================= + + - easy to use to create code-driven and data-driven tools + - easy to use to create ad hoc short-lived tools and long-lived, more elaborate tools + - easy to hack and improve + - minimize screen real-estate usage + - minimize setup and maintenance + - minimize state storage on user side + - portable, minimize dependencies, run on target (consoles, phones, etc.) + - efficient runtime (NB- we do allocate when "growing" content - creating a window / opening a tree node for the first time, etc. - but a typical frame won't allocate anything) + - read about immediate-mode gui principles @ http://mollyrocket.com/861, http://mollyrocket.com/forums/index.html + + Designed for developers and content-creators, not the typical end-user! Some of the weaknesses includes: + - doesn't look fancy, doesn't animate + - limited layout features, intricate layouts are typically crafted in code + - occasionally uses statically sized buffers for string manipulations - won't crash, but some very long pieces of text may be clipped. functions like ImGui::TextUnformatted() don't have such restriction. + + + END-USER GUIDE + ============== + + - double-click title bar to collapse window + - click upper right corner to close a window, available when 'bool* p_open' is passed to ImGui::Begin() + - click and drag on lower right corner to resize window + - click and drag on any empty space to move window + - double-click/double-tap on lower right corner grip to auto-fit to content + - TAB/SHIFT+TAB to cycle through keyboard editable fields + - use mouse wheel to scroll + - use CTRL+mouse wheel to zoom window contents (if IO.FontAllowScaling is true) + - CTRL+Click on a slider or drag box to input value as text + - text editor: + - Hold SHIFT or use mouse to select text. + - CTRL+Left/Right to word jump + - CTRL+Shift+Left/Right to select words + - CTRL+A our Double-Click to select all + - CTRL+X,CTRL+C,CTRL+V to use OS clipboard + - CTRL+Z,CTRL+Y to undo/redo + - ESCAPE to revert text to its original value + - You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!) + + + PROGRAMMER GUIDE + ================ + + - read the FAQ below this section! + - your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs. + - call and read ImGui::ShowTestWindow() for demo code demonstrating most features. + - see examples/ folder for standalone sample applications. Prefer reading examples/opengl2_example/ first as it is the simplest. + you may be able to grab and copy a ready made imgui_impl_*** file from the examples/. + - customization: PushStyleColor()/PushStyleVar() or the style editor to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme). + + - getting started: + - init: call ImGui::GetIO() to retrieve the ImGuiIO structure and fill the fields marked 'Settings'. + - init: call io.Fonts->GetTexDataAsRGBA32(...) and load the font texture pixels into graphics memory. + - every frame: + 1/ in your mainloop or right after you got your keyboard/mouse info, call ImGui::GetIO() and fill the fields marked 'Input' + 2/ call ImGui::NewFrame() as early as you can! + 3/ use any ImGui function you want between NewFrame() and Render() + 4/ call ImGui::Render() as late as you can to end the frame and finalize render data. it will call your RenderDrawListFn handler that you set in the IO structure. + (if you don't need to render, you still need to call Render() and ignore the callback, or call EndFrame() instead. if you call neither some aspects of windows focusing/moving will appear broken.) + - all rendering information are stored into command-lists until ImGui::Render() is called. + - ImGui never touches or know about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you provide. + - effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" phases of your own application. + - refer to the examples applications in the examples/ folder for instruction on how to setup your code. + - a typical application skeleton may be: + + // Application init + ImGuiIO& io = ImGui::GetIO(); + io.DisplaySize.x = 1920.0f; + io.DisplaySize.y = 1280.0f; + io.IniFilename = "imgui.ini"; + io.RenderDrawListsFn = my_render_function; // Setup a render function, or set to NULL and call GetDrawData() after Render() to access the render data. + // TODO: Fill others settings of the io structure + + // Load texture atlas + // There is a default font so you don't need to care about choosing a font yet + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(pixels, &width, &height); + // TODO: At this points you've got a texture pointed to by 'pixels' and you need to upload that your your graphic system + // TODO: Store your texture pointer/identifier (whatever your engine uses) in 'io.Fonts->TexID' + + // Application main loop + while (true) + { + // 1) get low-level inputs (e.g. on Win32, GetKeyboardState(), or poll your events, etc.) + // TODO: fill all fields of IO structure and call NewFrame + ImGuiIO& io = ImGui::GetIO(); + io.DeltaTime = 1.0f/60.0f; + io.MousePos = mouse_pos; + io.MouseDown[0] = mouse_button_0; + io.MouseDown[1] = mouse_button_1; + io.KeysDown[i] = ... + + // 2) call NewFrame(), after this point you can use ImGui::* functions anytime + ImGui::NewFrame(); + + // 3) most of your application code here + MyGameUpdate(); // may use any ImGui functions, e.g. ImGui::Begin("My window"); ImGui::Text("Hello, world!"); ImGui::End(); + MyGameRender(); // may use any ImGui functions + + // 4) render & swap video buffers + ImGui::Render(); + SwapBuffers(); + } + + - You can read back 'io.WantCaptureMouse', 'io.WantCaptureKeybord' etc. flags from the IO structure to tell how ImGui intends to use your + inputs and to know if you should share them or hide them from the rest of your application. Read the FAQ below for more information. + + + API BREAKING CHANGES + ==================== + + Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix. + Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. + Also read releases logs https://github.com/ocornut/imgui/releases for more details. + + - 2016/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully breakage should be minimal. + - 2016/05/12 (1.49) - title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore. + If your TitleBg/TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you. + However if your TitleBg/TitleBgActive alpha was <1.0f you need to tweak your custom theme to readjust for the fact that we don't draw a WindowBg background behind the title bar. + This helper function will convert an old TitleBg/TitleBgActive color into a new one with the same visual output, given the OLD color and the OLD WindowBg color. + ImVec4 ConvertTitleBgCol(const ImVec4& win_bg_col, const ImVec4& title_bg_col) + { + float new_a = 1.0f - ((1.0f - win_bg_col.w) * (1.0f - title_bg_col.w)), k = title_bg_col.w / new_a; + return ImVec4((win_bg_col.x * win_bg_col.w + title_bg_col.x) * k, (win_bg_col.y * win_bg_col.w + title_bg_col.y) * k, (win_bg_col.z * win_bg_col.w + title_bg_col.z) * k, new_a); + } + If this is confusing, pick the RGB value from title bar from an old screenshot and apply this as TitleBg/TitleBgActive. Or you may just create TitleBgActive from a tweaked TitleBg color. + - 2016/05/07 (1.49) - removed confusing set of GetInternalState(), GetInternalStateSize(), SetInternalState() functions. Now using CreateContext(), DestroyContext(), GetCurrentContext(), SetCurrentContext(). + - 2016/05/02 (1.49) - renamed SetNextTreeNodeOpened() to SetNextTreeNodeOpen(), no redirection. + - 2016/05/01 (1.49) - obsoleted old signature of CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false) as extra parameters were badly designed and rarely used. You can replace the "default_open = true" flag in new API with CollapsingHeader(label, ImGuiTreeNodeFlags_DefaultOpen). + - 2016/04/26 (1.49) - changed ImDrawList::PushClipRect(ImVec4 rect) to ImDraw::PushClipRect(Imvec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false). Note that higher-level ImGui::PushClipRect() is preferable because it will clip at logic/widget level, whereas ImDrawList::PushClipRect() only affect your renderer. + - 2016/04/03 (1.48) - removed style.WindowFillAlphaDefault setting which was redundant. Bake default BG alpha inside style.Colors[ImGuiCol_WindowBg] and all other Bg color values. (ref github issue #337). + - 2016/04/03 (1.48) - renamed ImGuiCol_TooltipBg to ImGuiCol_PopupBg, used by popups/menus and tooltips. popups/menus were previously using ImGuiCol_WindowBg. (ref github issue #337) + - 2016/03/21 (1.48) - renamed GetWindowFont() to GetFont(), GetWindowFontSize() to GetFontSize(). Kept inline redirection function (will obsolete). + - 2016/03/02 (1.48) - InputText() completion/history/always callbacks: if you modify the text buffer manually (without using DeleteChars()/InsertChars() helper) you need to maintain the BufTextLen field. added an assert. + - 2016/01/23 (1.48) - fixed not honoring exact width passed to PushItemWidth(), previously it would add extra FramePadding.x*2 over that width. if you had manual pixel-perfect alignment in place it might affect you. + - 2015/12/27 (1.48) - fixed ImDrawList::AddRect() which used to render a rectangle 1 px too large on each axis. + - 2015/12/04 (1.47) - renamed Color() helpers to ValueColor() - dangerously named, rarely used and probably to be made obsolete. + - 2015/08/29 (1.45) - with the addition of horizontal scrollbar we made various fixes to inconsistencies with dealing with cursor position. + GetCursorPos()/SetCursorPos() functions now include the scrolled amount. It shouldn't affect the majority of users, but take note that SetCursorPosX(100.0f) puts you at +100 from the starting x position which may include scrolling, not at +100 from the window left side. + GetContentRegionMax()/GetWindowContentRegionMin()/GetWindowContentRegionMax() functions allow include the scrolled amount. Typically those were used in cases where no scrolling would happen so it may not be a problem, but watch out! + - 2015/08/29 (1.45) - renamed style.ScrollbarWidth to style.ScrollbarSize + - 2015/08/05 (1.44) - split imgui.cpp into extra files: imgui_demo.cpp imgui_draw.cpp imgui_internal.h that you need to add to your project. + - 2015/07/18 (1.44) - fixed angles in ImDrawList::PathArcTo(), PathArcToFast() (introduced in 1.43) being off by an extra PI for no justifiable reason + - 2015/07/14 (1.43) - add new ImFontAtlas::AddFont() API. For the old AddFont***, moved the 'font_no' parameter of ImFontAtlas::AddFont** functions to the ImFontConfig structure. + you need to render your textured triangles with bilinear filtering to benefit from sub-pixel positioning of text. + - 2015/07/08 (1.43) - switched rendering data to use indexed rendering. this is saving a fair amount of CPU/GPU and enables us to get anti-aliasing for a marginal cost. + this necessary change will break your rendering function! the fix should be very easy. sorry for that :( + - if you are using a vanilla copy of one of the imgui_impl_XXXX.cpp provided in the example, you just need to update your copy and you can ignore the rest. + - the signature of the io.RenderDrawListsFn handler has changed! + ImGui_XXXX_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) + became: + ImGui_XXXX_RenderDrawLists(ImDrawData* draw_data). + argument 'cmd_lists' -> 'draw_data->CmdLists' + argument 'cmd_lists_count' -> 'draw_data->CmdListsCount' + ImDrawList 'commands' -> 'CmdBuffer' + ImDrawList 'vtx_buffer' -> 'VtxBuffer' + ImDrawList n/a -> 'IdxBuffer' (new) + ImDrawCmd 'vtx_count' -> 'ElemCount' + ImDrawCmd 'clip_rect' -> 'ClipRect' + ImDrawCmd 'user_callback' -> 'UserCallback' + ImDrawCmd 'texture_id' -> 'TextureId' + - each ImDrawList now contains both a vertex buffer and an index buffer. For each command, render ElemCount/3 triangles using indices from the index buffer. + - if you REALLY cannot render indexed primitives, you can call the draw_data->DeIndexAllBuffers() method to de-index the buffers. This is slow and a waste of CPU/GPU. Prefer using indexed rendering! + - refer to code in the examples/ folder or ask on the GitHub if you are unsure of how to upgrade. please upgrade! + - 2015/07/10 (1.43) - changed SameLine() parameters from int to float. + - 2015/07/02 (1.42) - renamed SetScrollPosHere() to SetScrollFromCursorPos(). Kept inline redirection function (will obsolete). + - 2015/07/02 (1.42) - renamed GetScrollPosY() to GetScrollY(). Necessary to reduce confusion along with other scrolling functions, because positions (e.g. cursor position) are not equivalent to scrolling amount. + - 2015/06/14 (1.41) - changed ImageButton() default bg_col parameter from (0,0,0,1) (black) to (0,0,0,0) (transparent) - makes a difference when texture have transparence + - 2015/06/14 (1.41) - changed Selectable() API from (label, selected, size) to (label, selected, flags, size). Size override should have been rarely be used. Sorry! + - 2015/05/31 (1.40) - renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline redirection function (will obsolete). + - 2015/05/31 (1.40) - renamed IsRectClipped() to IsRectVisible() for consistency. Note that return value is opposite! Kept inline redirection function (will obsolete). + - 2015/05/27 (1.40) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons. + - 2015/05/11 (1.40) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "open" state of a popup. BeginPopup() returns true if the popup is opened. + - 2015/05/03 (1.40) - removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same). + - 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function until 1.50. + - 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API + - 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive. + - 2014/04/03 (1.38) - removed support for passing -FLT_MAX..+FLT_MAX as the range for a SliderFloat(). Use DragFloat() or Inputfloat() instead. + - 2015/03/17 (1.36) - renamed GetItemBoxMin()/GetItemBoxMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function until 1.50. + - 2015/03/15 (1.36) - renamed style.TreeNodeSpacing to style.IndentSpacing, ImGuiStyleVar_TreeNodeSpacing to ImGuiStyleVar_IndentSpacing + - 2015/03/13 (1.36) - renamed GetWindowIsFocused() to IsWindowFocused(). Kept inline redirection function until 1.50. + - 2015/03/08 (1.35) - renamed style.ScrollBarWidth to style.ScrollbarWidth (casing) + - 2015/02/27 (1.34) - renamed OpenNextNode(bool) to SetNextTreeNodeOpened(bool, ImGuiSetCond). Kept inline redirection function until 1.50. + - 2015/02/27 (1.34) - renamed ImGuiSetCondition_*** to ImGuiSetCond_***, and _FirstUseThisSession becomes _Once. + - 2015/02/11 (1.32) - changed text input callback ImGuiTextEditCallback return type from void-->int. reserved for future use, return 0 for now. + - 2015/02/10 (1.32) - renamed GetItemWidth() to CalcItemWidth() to clarify its evolving behavior + - 2015/02/08 (1.31) - renamed GetTextLineSpacing() to GetTextLineHeightWithSpacing() + - 2015/02/01 (1.31) - removed IO.MemReallocFn (unused) + - 2015/01/19 (1.30) - renamed ImGuiStorage::GetIntPtr()/GetFloatPtr() to GetIntRef()/GetIntRef() because Ptr was conflicting with actual pointer storage functions. + - 2015/01/11 (1.30) - big font/image API change! now loads TTF file. allow for multiple fonts. no need for a PNG loader. + (1.30) - removed GetDefaultFontData(). uses io.Fonts->GetTextureData*() API to retrieve uncompressed pixels. + this sequence: + const void* png_data; + unsigned int png_size; + ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size); + // + became: + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + // + io.Fonts->TexID = (your_texture_identifier); + you now have much more flexibility to load multiple TTF fonts and manage the texture buffer for internal needs. + it is now recommended that you sample the font texture with bilinear interpolation. + (1.30) - added texture identifier in ImDrawCmd passed to your render function (we can now render images). make sure to set io.Fonts->TexID. + (1.30) - removed IO.PixelCenterOffset (unnecessary, can be handled in user projection matrix) + (1.30) - removed ImGui::IsItemFocused() in favor of ImGui::IsItemActive() which handles all widgets + - 2014/12/10 (1.18) - removed SetNewWindowDefaultPos() in favor of new generic API SetNextWindowPos(pos, ImGuiSetCondition_FirstUseEver) + - 2014/11/28 (1.17) - moved IO.Font*** options to inside the IO.Font-> structure (FontYOffset, FontTexUvForWhite, FontBaseScale, FontFallbackGlyph) + - 2014/11/26 (1.17) - reworked syntax of IMGUI_ONCE_UPON_A_FRAME helper macro to increase compiler compatibility + - 2014/11/07 (1.15) - renamed IsHovered() to IsItemHovered() + - 2014/10/02 (1.14) - renamed IMGUI_INCLUDE_IMGUI_USER_CPP to IMGUI_INCLUDE_IMGUI_USER_INL and imgui_user.cpp to imgui_user.inl (more IDE friendly) + - 2014/09/25 (1.13) - removed 'text_end' parameter from IO.SetClipboardTextFn (the string is now always zero-terminated for simplicity) + - 2014/09/24 (1.12) - renamed SetFontScale() to SetWindowFontScale() + - 2014/09/24 (1.12) - moved IM_MALLOC/IM_REALLOC/IM_FREE preprocessor defines to IO.MemAllocFn/IO.MemReallocFn/IO.MemFreeFn + - 2014/08/30 (1.09) - removed IO.FontHeight (now computed automatically) + - 2014/08/30 (1.09) - moved IMGUI_FONT_TEX_UV_FOR_WHITE preprocessor define to IO.FontTexUvForWhite + - 2014/08/28 (1.09) - changed the behavior of IO.PixelCenterOffset following various rendering fixes + + + FREQUENTLY ASKED QUESTIONS (FAQ), TIPS + ====================================== + + Q: How can I help? + A: - If you are experienced enough with ImGui and with C/C++, look at the todo list and see how you want/can help! + - Become a Patron/donate. Convince your company to become a Patron or provide serious funding for development time. + + Q: How do I update to a newer version of ImGui? + A: Overwrite the following files: + imgui.cpp + imgui.h + imgui_demo.cpp + imgui_draw.cpp + imgui_internal.h + stb_rect_pack.h + stb_textedit.h + stb_truetype.h + Don't overwrite imconfig.h if you have made modification to your copy. + Check the "API BREAKING CHANGES" sections for a list of occasional API breaking changes. If you have a problem with a function, search for its name + in the code, there will likely be a comment about it. Please report any issue to the GitHub page! + + + Q: What is ImTextureID and how do I display an image? + A: ImTextureID is a void* used to pass renderer-agnostic texture references around until it hits your render function. + ImGui knows nothing about what those bits represent, it just passes them around. It is up to you to decide what you want the void* to carry! + It could be an identifier to your OpenGL texture (cast GLuint to void*), a pointer to your custom engine material (cast MyMaterial* to void*), etc. + At the end of the chain, your renderer takes this void* to cast it back into whatever it needs to select a current texture to render. + Refer to examples applications, where each renderer (in a imgui_impl_xxxx.cpp file) is treating ImTextureID as a different thing. + (c++ tip: OpenGL uses integers to identify textures. You can safely store an integer into a void*, just cast it to void*, don't take it's address!) + To display a custom image/texture within an ImGui window, you may use ImGui::Image(), ImGui::ImageButton(), ImDrawList::AddImage() functions. + ImGui will generate the geometry and draw calls using the ImTextureID that you passed and which your renderer can use. + It is your responsibility to get textures uploaded to your GPU. + + Q: I integrated ImGui in my engine and the text or lines are blurry.. + A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f). + Also make sure your orthographic projection matrix and io.DisplaySize matches your actual framebuffer dimension. + + Q: I integrated ImGui in my engine and some elements are clipping or disappearing when I move windows around.. + A: Most likely you are mishandling the clipping rectangles in your render function. Rectangles provided by ImGui are defined as (x1,y1,x2,y2) and NOT as (x1,y1,width,height). + + Q: Can I have multiple widgets with the same label? Can I have widget without a label? (Yes) + A: Yes. A primer on the use of labels/IDs in ImGui.. + + - Elements that are not clickable, such as Text() items don't need an ID. + + - Interactive widgets require state to be carried over multiple frames (most typically ImGui often needs to remember what is the "active" widget). + to do so they need an unique ID. unique ID are typically derived from a string label, an integer index or a pointer. + + Button("OK"); // Label = "OK", ID = hash of "OK" + Button("Cancel"); // Label = "Cancel", ID = hash of "Cancel" + + - ID are uniquely scoped within windows, tree nodes, etc. so no conflict can happen if you have two buttons called "OK" in two different windows + or in two different locations of a tree. + + - If you have a same ID twice in the same location, you'll have a conflict: + + Button("OK"); + Button("OK"); // ID collision! Both buttons will be treated as the same. + + Fear not! this is easy to solve and there are many ways to solve it! + + - When passing a label you can optionally specify extra unique ID information within string itself. This helps solving the simpler collision cases. + use "##" to pass a complement to the ID that won't be visible to the end-user: + + Button("Play"); // Label = "Play", ID = hash of "Play" + Button("Play##foo1"); // Label = "Play", ID = hash of "Play##foo1" (different from above) + Button("Play##foo2"); // Label = "Play", ID = hash of "Play##foo2" (different from above) + + - If you want to completely hide the label, but still need an ID: + + Checkbox("##On", &b); // Label = "", ID = hash of "##On" (no label!) + + - Occasionally/rarely you might want change a label while preserving a constant ID. This allows you to animate labels. + For example you may want to include varying information in a window title bar (and windows are uniquely identified by their ID.. obviously) + Use "###" to pass a label that isn't part of ID: + + Button("Hello###ID"; // Label = "Hello", ID = hash of "ID" + Button("World###ID"; // Label = "World", ID = hash of "ID" (same as above) + + sprintf(buf, "My game (%f FPS)###MyGame"); + Begin(buf); // Variable label, ID = hash of "MyGame" + + - Use PushID() / PopID() to create scopes and avoid ID conflicts within the same Window. + This is the most convenient way of distinguishing ID if you are iterating and creating many UI elements. + You can push a pointer, a string or an integer value. Remember that ID are formed from the concatenation of everything in the ID stack! + + for (int i = 0; i < 100; i++) + { + PushID(i); + Button("Click"); // Label = "Click", ID = hash of integer + "label" (unique) + PopID(); + } + + for (int i = 0; i < 100; i++) + { + MyObject* obj = Objects[i]; + PushID(obj); + Button("Click"); // Label = "Click", ID = hash of pointer + "label" (unique) + PopID(); + } + + for (int i = 0; i < 100; i++) + { + MyObject* obj = Objects[i]; + PushID(obj->Name); + Button("Click"); // Label = "Click", ID = hash of string + "label" (unique) + PopID(); + } + + - More example showing that you can stack multiple prefixes into the ID stack: + + Button("Click"); // Label = "Click", ID = hash of "Click" + PushID("node"); + Button("Click"); // Label = "Click", ID = hash of "node" + "Click" + PushID(my_ptr); + Button("Click"); // Label = "Click", ID = hash of "node" + ptr + "Click" + PopID(); + PopID(); + + - Tree nodes implicitly creates a scope for you by calling PushID(). + + Button("Click"); // Label = "Click", ID = hash of "Click" + if (TreeNode("node")) + { + Button("Click"); // Label = "Click", ID = hash of "node" + "Click" + TreePop(); + } + + - When working with trees, ID are used to preserve the open/close state of each tree node. + Depending on your use cases you may want to use strings, indices or pointers as ID. + e.g. when displaying a single object that may change over time (1-1 relationship), using a static string as ID will preserve your node open/closed state when the targeted object change. + e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense! + + Q: How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application? + A: You can read the 'io.WantCaptureXXX' flags in the ImGuiIO structure. Preferably read them after calling ImGui::NewFrame() to avoid those flags lagging by one frame, but either should be fine. + When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application. + When 'io.WantInputsCharacters' is set to may want to notify your OS to popup an on-screen keyboard, if available. + ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, so 'io.WantCaptureMouse' is a more accurate and complete than testing for ImGui::IsMouseHoveringAnyWindow(). + (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically have 'io.WantcaptureKeyboard=false'. + Depending on your application logic it may or not be inconvenient. You might want to track which key-downs were for ImGui (e.g. with an array of bool) and filter out the corresponding key-ups.) + + Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) + A: Use the font atlas to load the TTF file you want: + + ImGuiIO& io = ImGui::GetIO(); + io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); + io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() + + Q: How can I load multiple fonts? + A: Use the font atlas to pack them into a single texture: + (Read extra_fonts/README.txt and the code in ImFontAtlas for more details.) + + ImGuiIO& io = ImGui::GetIO(); + ImFont* font0 = io.Fonts->AddFontDefault(); + ImFont* font1 = io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); + ImFont* font2 = io.Fonts->AddFontFromFileTTF("myfontfile2.ttf", size_in_pixels); + io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() + // the first loaded font gets used by default + // use ImGui::PushFont()/ImGui::PopFont() to change the font at runtime + + // Options + ImFontConfig config; + config.OversampleH = 3; + config.OversampleV = 1; + config.GlyphExtraSpacing.x = 1.0f; + io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, &config); + + // Combine multiple fonts into one + ImWchar ranges[] = { 0xf000, 0xf3ff, 0 }; + ImFontConfig config; + config.MergeMode = true; + io.Fonts->AddFontDefault(); + io.Fonts->LoadFromFileTTF("fontawesome-webfont.ttf", 16.0f, &config, ranges); + io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, NULL, &config, io.Fonts->GetGlyphRangesJapanese()); + + Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic? + A: When loading a font, pass custom Unicode ranges to specify the glyphs to load. + All your strings needs to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese or CP-1251 for Cyrillic) will not work. + In C++11 you can encode a string literal in UTF-8 by using the u8"hello" syntax. Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8. + You can also try to remap your local codepage characters to their Unicode codepoint using font->AddRemapChar(), but international users may have problems reading/editing your source code. + + io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, io.Fonts->GetGlyphRangesJapanese()); // Load Japanese characters + io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() + io.ImeWindowHandle = MY_HWND; // To input using Microsoft IME, give ImGui the hwnd of your application + + As for text input, depends on you passing the right character code to io.AddInputCharacter(). The example applications do that. + + Q: How can I use the drawing facilities without an ImGui window? (using ImDrawList API) + A: The easiest way is to create a dummy window. Call Begin() with NoTitleBar|NoResize|NoMove|NoScrollbar|NoSavedSettings|NoInputs flag, zero background alpha, + then retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. + + - tip: the construct 'IMGUI_ONCE_UPON_A_FRAME { ... }' will run the block of code only once a frame. You can use it to quickly add custom UI in the middle of a deep nested inner loop in your code. + - tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug" + - tip: you can call Begin() multiple times with the same name during the same frame, it will keep appending to the same window. this is also useful to set yourself in the context of another window (to get/set other settings) + - tip: you can call Render() multiple times (e.g for VR renders). + - tip: call and read the ShowTestWindow() code in imgui_demo.cpp for more example of how to use ImGui! + + + ISSUES & TODO-LIST + ================== + Issue numbers (#) refer to github issues listed at https://github.com/ocornut/imgui/issues + The list below consist mostly of notes of things to do before they are requested/discussed by users (at that point it usually happens on the github) + + - doc: add a proper documentation+regression testing system (#435) + - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass. + - window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis) (#690) + - window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify. + - window: allow resizing of child windows (possibly given min/max for each axis?) + - window: background options for child windows, border option (disable rounding) + - window: add a way to clear an existing window instead of appending (e.g. for tooltip override using a consistent api rather than the deferred tooltip) + - window: resizing from any sides? + mouse cursor directives for app. +!- window: begin with *p_open == false should return false. + - window: get size/pos helpers given names (see discussion in #249) + - window: a collapsed window can be stuck behind the main menu bar? + - window: when window is small, prioritize resize button over close button. + - window: detect extra End() call that pop the "Debug" window out and assert at call site instead of later. + - window/tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic. + - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. + - draw-list: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). +!- scrolling: allow immediately effective change of scroll if we haven't appended items yet + - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) + - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. + - widgets: clean up widgets internal toward exposing everything. + - widgets: add disabled and read-only modes (#211) + - main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them. +!- main: make it so that a frame with no window registered won't refocus every window on subsequent frames (~bump LastFrameActive of all windows). + - main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes + - main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode? + - input text: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now and super fragile. + - input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541) + - input text: expose CursorPos in char filter event (#816) + - input text: flag to disable live update of the user buffer (also applies to float/int text input) + - input text: resize behavior - field could stretch when being edited? hover tooltip shows more text? + - input text: add ImGuiInputTextFlags_EnterToApply? (off #218) + - input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725) + - input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc). + - input text multi-line: way to dynamically grow the buffer without forcing the user to initially allocate for worse case (follow up on #200) + - input text multi-line: line numbers? status bar? (follow up on #200) + - input text multi-line: behave better when user changes input buffer while editing is active (even though it is illegal behavior). namely, the change of buffer can create a scrollbar glitch (#725) + - input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position. + - input number: optional range min/max for Input*() functions + - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled) + - input number: use mouse wheel to step up/down + - input number: applying arithmetics ops (+,-,*,/) messes up with text edit undo stack. + - button: provide a button that looks framed. + - text: proper alignment options + - image/image button: misalignment on padded/bordered button? + - image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that? + - layout: horizontal layout helper (#97) + - layout: horizontal flow until no space left (#404) + - layout: more generic alignment state (left/right/centered) for single items? + - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding. + - layout: BeginGroup() needs a border option. + - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills) (#513, #125) + - columns: add a conditional parameter to SetColumnOffset() (#513, #125) + - columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (#125) + - columns: columns header to act as button (~sort op) and allow resize/reorder (#513, #125) + - columns: user specify columns size (#513, #125) + - columns: flag to add horizontal separator above/below? + - columns/layout: setup minimum line height (equivalent of automatically calling AlignFirstTextHeightToWidgets) + - combo: sparse combo boxes (via function call?) / iterators + - combo: contents should extends to fit label if combo widget is small + - combo/listbox: keyboard control. need InputText-like non-active focus + key handling. considering keyboard for custom listbox (pr #203) + - listbox: multiple selection + - listbox: user may want to initial scroll to focus on the one selected value? + - listbox: keyboard navigation. + - listbox: scrolling should track modified selection. +!- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402) + - popups: add variant using global identifier similar to Begin/End (#402) + - popups: border options. richer api like BeginChild() perhaps? (#197) + - tooltip: tooltip that doesn't fit in entire screen seems to lose their "last prefered button" and may teleport when moving mouse + - menus: local shortcuts, global shortcuts (#456, #126) + - menus: icons + - menus: menubars: some sort of priority / effect of main menu-bar on desktop size? + - menus: calling BeginMenu() twice with a same name doesn't seem to append nicely + - statusbar: add a per-window status bar helper similar to what menubar does. + - tabs (#261, #351) + - separator: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y) +!- color: the color helpers/typing is a mess and needs sorting out. + - color: add a better color picker (#346) + - node/graph editor (#306) + - pie menus patterns (#434) + - drag'n drop, dragging helpers (carry dragging info, visualize drag source before clicking, drop target, etc.) (#143, #479) + - plot: PlotLines() should use the polygon-stroke facilities (currently issues with averaging normals) + - plot: make it easier for user to draw extra stuff into the graph (e.g: draw basis, highlight certain points, 2d plots, multiple plots) + - plot: "smooth" automatic scale over time, user give an input 0.0(full user scale) 1.0(full derived from value) + - plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID) + - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt() + - slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). + - slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate. + - slider: tint background based on value (e.g. v_min -> v_max, or use 0.0f either side of the sign) + - slider & drag: int data passing through a float + - drag float: up/down axis + - drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits) + - tree node / optimization: avoid formatting when clipped. + - tree node: tree-node/header right-most side doesn't take account of horizontal scrolling. + - tree node: add treenode/treepush int variants? not there because (void*) cast from int warns on some platforms/settings? + - tree node: try to apply scrolling at time of TreePop() if node was just opened and end of node is past scrolling limits? + - tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer) + - tree node: tweak color scheme to distinguish headers from selected tree node (#581) + - textwrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249) + - settings: write more decent code to allow saving/loading new fields + - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file + - style: add window shadows. + - style/optimization: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. + - style: color-box not always square? + - style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc. + - style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation). + - style/opt: PopStyleVar could be optimized by having GetStyleVar returns the type, using a table mapping stylevar enum to data type. + - style: global scale setting. + - style: WindowPadding needs to be EVEN needs the 0.5 multiplier probably have a subtle effect on clip rectangle + - text: simple markup language for color change? + - font: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier. + - font: small opt: for monospace font (like the defalt one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance + - font: add support for kerning, probably optional. perhaps default to (32..128)^2 matrix ~ 36KB then hash fallback. + - font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize) + - font: fix AddRemapChar() to work before font has been built. + - log: LogButtons() options for specifying depth and/or hiding depth slider + - log: have more control over the log scope (e.g. stop logging when leaving current tree node scope) + - log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard) + - log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs. + - filters: set a current filter that tree node can automatically query to hide themselves + - filters: handle wildcards (with implicit leading/trailing *), regexps + - shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus) +!- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing + - keyboard: full keyboard navigation and focus. (#323) + - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622) + - focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame) + - input: rework IO system to be able to pass actual ordered/timestamped events. (~#335, #71) + - input: allow to decide and pass explicit double-clicks (e.g. for windows by the CS_DBLCLKS style). + - input: support track pad style scrolling & slider edit. + - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) + - misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? + - misc: provide HoveredTime and ActivatedTime to ease the creation of animations. + - style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438) + - style editor: color child window height expressed in multiple of line height. + - remote: make a system like RemoteImGui first-class citizen/project (#75) + - drawlist: move Font, FontSize, FontTexUvWhitePixel inside ImDrawList and make it self-contained (apart from drawing settings?) + - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. + - examples: directx9: save/restore device state more thoroughly. + - examples: window minimize, maximize (#583) + - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335) + - optimization: use another hash function than crc32, e.g. FNV1a + - optimization/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)? + - optimization: turn some the various stack vectors into statically-sized arrays + - optimization: better clipping for multi-component widgets +*/ + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "imgui.h" +#define IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_PLACEMENT_NEW +#include "imgui_internal.h" + +#include // toupper, isprint +#include // NULL, malloc, free, qsort, atoi +#include // vsnprintf, sscanf, printf +#include // INT_MIN, INT_MAX +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4127) // condition expression is constant +#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff) +#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen +#endif + +// Clang warnings with -Weverything +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. +#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok. +#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning : format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code. +#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. +#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. +#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // +#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int' // +#elif defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used +#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size +#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'void*', but argument 6 has type 'ImGuiWindow*' +#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value +#endif + +//------------------------------------------------------------------------- +// Forward Declarations +//------------------------------------------------------------------------- + +static void LogRenderedText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL); + +static void PushMultiItemsWidths(int components, float w_full = 0.0f); +static float GetDraggedColumnOffset(int column_index); + +static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); + +static void SetCurrentFont(ImFont* font); +static void SetCurrentWindow(ImGuiWindow* window); +static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y); +static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiSetCond cond); +static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiSetCond cond); +static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiSetCond cond); +static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs); +static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags); +static inline bool IsWindowContentHoverable(ImGuiWindow* window); +static void ClearSetNextWindowData(); +static void CheckStacksSize(ImGuiWindow* window, bool write); +static void Scrollbar(ImGuiWindow* window, bool horizontal); + +static void AddDrawListToRenderList(ImVector& out_render_list, ImDrawList* draw_list); +static void AddWindowToRenderList(ImVector& out_render_list, ImGuiWindow* window); +static void AddWindowToSortedBuffer(ImVector& out_sorted_windows, ImGuiWindow* window); + +static ImGuiIniData* FindWindowSettings(const char* name); +static ImGuiIniData* AddWindowSettings(const char* name); +static void LoadSettings(); +static void SaveSettings(); +static void MarkSettingsDirty(); + +static void PushColumnClipRect(int column_index = -1); +static ImRect GetVisibleRect(); + +static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags); +static void CloseInactivePopups(); +static void ClosePopupToLevel(int remaining); +static void ClosePopup(ImGuiID id); +static bool IsPopupOpen(ImGuiID id); +static ImGuiWindow* GetFrontMostModalRootWindow(); +static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& rect_to_avoid); + +static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data); +static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); +static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false); + +static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, const char* display_format, char* buf, int buf_size); +static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, int decimal_precision, char* buf, int buf_size); +static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* value1, const void* value2); +static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format); + +//----------------------------------------------------------------------------- +// Platform dependent default implementations +//----------------------------------------------------------------------------- + +static const char* GetClipboardTextFn_DefaultImpl(); +static void SetClipboardTextFn_DefaultImpl(const char* text); +static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y); + +//----------------------------------------------------------------------------- +// Context +//----------------------------------------------------------------------------- + +// Default context, default font atlas. +// New contexts always point by default to this font atlas. It can be changed by reassigning the GetIO().Fonts variable. +static ImGuiContext GImDefaultContext; +static ImFontAtlas GImDefaultFontAtlas; + +// Current context pointer. Implicitely used by all ImGui functions. Always assumed to be != NULL. Change to a different context by calling ImGui::SetCurrentContext() +// ImGui is currently not thread-safe because of this variable. If you want thread-safety to allow N threads to access N different contexts, you might work around it by (A) having two instances of the ImGui code under different namespaces or (B) change this variable to be TLS. Further development aim to make this context pointer explicit to all calls. Also read https://github.com/ocornut/imgui/issues/586 +ImGuiContext* GImGui = &GImDefaultContext; + +//----------------------------------------------------------------------------- +// User facing structures +//----------------------------------------------------------------------------- + +ImGuiStyle::ImGuiStyle() +{ + Alpha = 1.0f; // Global alpha applies to everything in ImGui + WindowPadding = ImVec2(8,8); // Padding within a window + WindowMinSize = ImVec2(32,32); // Minimum window size + WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + WindowTitleAlign = ImGuiAlign_Left; // Alignment for title bar text + ChildWindowRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows + FramePadding = ImVec2(4,3); // Padding within a framed rectangle (used by most widgets) + FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets). + ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines + ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) + TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! + IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). + ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns + ScrollbarSize = 16.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar + ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar + GrabMinSize = 10.0f; // Minimum width/height of a grab box for slider/scrollbar + GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. + DisplayWindowPadding = ImVec2(22,22); // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows. + DisplaySafeAreaPadding = ImVec2(4,4); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. + AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU. + AntiAliasedShapes = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) + CurveTessellationTol = 1.25f; // Tessellation tolerance. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. + + Colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); + Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); + Colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + Colors[ImGuiCol_PopupBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); + Colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.65f); + Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input + Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); + Colors[ImGuiCol_FrameBgActive] = ImVec4(0.90f, 0.65f, 0.65f, 0.45f); + Colors[ImGuiCol_TitleBg] = ImVec4(0.27f, 0.27f, 0.54f, 0.83f); + Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); + Colors[ImGuiCol_TitleBgActive] = ImVec4(0.32f, 0.32f, 0.63f, 0.87f); + Colors[ImGuiCol_MenuBarBg] = ImVec4(0.40f, 0.40f, 0.55f, 0.80f); + Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.25f, 0.30f, 0.60f); + Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); + Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); + Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 0.40f); + Colors[ImGuiCol_ComboBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.99f); + Colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); + Colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); + Colors[ImGuiCol_Button] = ImVec4(0.67f, 0.40f, 0.40f, 0.60f); + Colors[ImGuiCol_ButtonHovered] = ImVec4(0.67f, 0.40f, 0.40f, 1.00f); + Colors[ImGuiCol_ButtonActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); + Colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); + Colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); + Colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); + Colors[ImGuiCol_Column] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + Colors[ImGuiCol_ColumnHovered] = ImVec4(0.70f, 0.60f, 0.60f, 1.00f); + Colors[ImGuiCol_ColumnActive] = ImVec4(0.90f, 0.70f, 0.70f, 1.00f); + Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + Colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); + Colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f); + Colors[ImGuiCol_CloseButton] = ImVec4(0.50f, 0.50f, 0.90f, 0.50f); + Colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.70f, 0.70f, 0.90f, 0.60f); + Colors[ImGuiCol_CloseButtonActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); + Colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); + Colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); +} + +ImGuiIO::ImGuiIO() +{ + // Most fields are initialized with zero + memset(this, 0, sizeof(*this)); + + DisplaySize = ImVec2(-1.0f, -1.0f); + DeltaTime = 1.0f/60.0f; + IniSavingRate = 5.0f; + IniFilename = "imgui.ini"; + LogFilename = "imgui_log.txt"; + Fonts = &GImDefaultFontAtlas; + FontGlobalScale = 1.0f; + DisplayFramebufferScale = ImVec2(1.0f, 1.0f); + MousePos = ImVec2(-1,-1); + MousePosPrev = ImVec2(-1,-1); + MouseDoubleClickTime = 0.30f; + MouseDoubleClickMaxDist = 6.0f; + MouseDragThreshold = 6.0f; + for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) + MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f; + for (int i = 0; i < IM_ARRAYSIZE(KeysDownDuration); i++) + KeysDownDuration[i] = KeysDownDurationPrev[i] = -1.0f; + for (int i = 0; i < ImGuiKey_COUNT; i++) + KeyMap[i] = -1; + KeyRepeatDelay = 0.250f; + KeyRepeatRate = 0.050f; + UserData = NULL; + + // User functions + RenderDrawListsFn = NULL; + MemAllocFn = malloc; + MemFreeFn = free; + GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations + SetClipboardTextFn = SetClipboardTextFn_DefaultImpl; + ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl; + + // Set OS X style defaults based on __APPLE__ compile time flag +#ifdef __APPLE__ + OSXBehaviors = true; +#endif +} + +// Pass in translated ASCII characters for text input. +// - with glfw you can get those from the callback set in glfwSetCharCallback() +// - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message +void ImGuiIO::AddInputCharacter(ImWchar c) +{ + const int n = ImStrlenW(InputCharacters); + if (n + 1 < IM_ARRAYSIZE(InputCharacters)) + { + InputCharacters[n] = c; + InputCharacters[n+1] = '\0'; + } +} + +void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars) +{ + // We can't pass more wchars than ImGuiIO::InputCharacters[] can hold so don't convert more + const int wchars_buf_len = sizeof(ImGuiIO::InputCharacters) / sizeof(ImWchar); + ImWchar wchars[wchars_buf_len]; + ImTextStrFromUtf8(wchars, wchars_buf_len, utf8_chars, NULL); + for (int i = 0; i < wchars_buf_len && wchars[i] != 0; i++) + AddInputCharacter(wchars[i]); +} + +//----------------------------------------------------------------------------- +// HELPERS +//----------------------------------------------------------------------------- + +#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose +#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255 + +// Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n. +#ifdef _WIN32 +#define IM_NEWLINE "\r\n" +#else +#define IM_NEWLINE "\n" +#endif + +bool ImIsPointInTriangle(const ImVec2& p, const ImVec2& a, const ImVec2& b, const ImVec2& c) +{ + bool b1 = ((p.x - b.x) * (a.y - b.y) - (p.y - b.y) * (a.x - b.x)) < 0.0f; + bool b2 = ((p.x - c.x) * (b.y - c.y) - (p.y - c.y) * (b.x - c.x)) < 0.0f; + bool b3 = ((p.x - a.x) * (c.y - a.y) - (p.y - a.y) * (c.x - a.x)) < 0.0f; + return ((b1 == b2) && (b2 == b3)); +} + +int ImStricmp(const char* str1, const char* str2) +{ + int d; + while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } + return d; +} + +int ImStrnicmp(const char* str1, const char* str2, int count) +{ + int d = 0; + while (count > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; count--; } + return d; +} + +void ImStrncpy(char* dst, const char* src, int count) +{ + if (count < 1) return; + strncpy(dst, src, (size_t)count); + dst[count-1] = 0; +} + +char* ImStrdup(const char *str) +{ + size_t len = strlen(str) + 1; + void* buff = ImGui::MemAlloc(len); + return (char*)memcpy(buff, (const void*)str, len); +} + +int ImStrlenW(const ImWchar* str) +{ + int n = 0; + while (*str++) n++; + return n; +} + +const ImWchar* ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin) // find beginning-of-line +{ + while (buf_mid_line > buf_begin && buf_mid_line[-1] != '\n') + buf_mid_line--; + return buf_mid_line; +} + +const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end) +{ + if (!needle_end) + needle_end = needle + strlen(needle); + + const char un0 = (char)toupper(*needle); + while ((!haystack_end && *haystack) || (haystack_end && haystack < haystack_end)) + { + if (toupper(*haystack) == un0) + { + const char* b = needle + 1; + for (const char* a = haystack + 1; b < needle_end; a++, b++) + if (toupper(*a) != toupper(*b)) + break; + if (b == needle_end) + return haystack; + } + haystack++; + } + return NULL; +} + + +// MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size). +// Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm. +int ImFormatString(char* buf, int buf_size, const char* fmt, ...) +{ + IM_ASSERT(buf_size > 0); + va_list args; + va_start(args, fmt); + int w = vsnprintf(buf, buf_size, fmt, args); + va_end(args); + if (w == -1 || w >= buf_size) + w = buf_size - 1; + buf[w] = 0; + return w; +} + +int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args) +{ + IM_ASSERT(buf_size > 0); + int w = vsnprintf(buf, buf_size, fmt, args); + if (w == -1 || w >= buf_size) + w = buf_size - 1; + buf[w] = 0; + return w; +} + +// Pass data_size==0 for zero-terminated strings +// FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements. +ImU32 ImHash(const void* data, int data_size, ImU32 seed) +{ + static ImU32 crc32_lut[256] = { 0 }; + if (!crc32_lut[1]) + { + const ImU32 polynomial = 0xEDB88320; + for (ImU32 i = 0; i < 256; i++) + { + ImU32 crc = i; + for (ImU32 j = 0; j < 8; j++) + crc = (crc >> 1) ^ (ImU32(-int(crc & 1)) & polynomial); + crc32_lut[i] = crc; + } + } + + seed = ~seed; + ImU32 crc = seed; + const unsigned char* current = (const unsigned char*)data; + + if (data_size > 0) + { + // Known size + while (data_size--) + crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ *current++]; + } + else + { + // Zero-terminated string + while (unsigned char c = *current++) + { + // We support a syntax of "label###id" where only "###id" is included in the hash, and only "label" gets displayed. + // Because this syntax is rarely used we are optimizing for the common case. + // - If we reach ### in the string we discard the hash so far and reset to the seed. + // - We don't do 'current += 2; continue;' after handling ### to keep the code smaller. + if (c == '#' && current[0] == '#' && current[1] == '#') + crc = seed; + crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; + } + } + return ~crc; +} + +//----------------------------------------------------------------------------- +// ImText* helpers +//----------------------------------------------------------------------------- + +// Convert UTF-8 to 32-bits character, process single character input. +// Based on stb_from_utf8() from github.com/nothings/stb/ +// We handle UTF-8 decoding error by skipping forward. +int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end) +{ + unsigned int c = (unsigned int)-1; + const unsigned char* str = (const unsigned char*)in_text; + if (!(*str & 0x80)) + { + c = (unsigned int)(*str++); + *out_char = c; + return 1; + } + if ((*str & 0xe0) == 0xc0) + { + *out_char = 0xFFFD; // will be invalid but not end of string + if (in_text_end && in_text_end - (const char*)str < 2) return 1; + if (*str < 0xc2) return 2; + c = (unsigned int)((*str++ & 0x1f) << 6); + if ((*str & 0xc0) != 0x80) return 2; + c += (*str++ & 0x3f); + *out_char = c; + return 2; + } + if ((*str & 0xf0) == 0xe0) + { + *out_char = 0xFFFD; // will be invalid but not end of string + if (in_text_end && in_text_end - (const char*)str < 3) return 1; + if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return 3; + if (*str == 0xed && str[1] > 0x9f) return 3; // str[1] < 0x80 is checked below + c = (unsigned int)((*str++ & 0x0f) << 12); + if ((*str & 0xc0) != 0x80) return 3; + c += (unsigned int)((*str++ & 0x3f) << 6); + if ((*str & 0xc0) != 0x80) return 3; + c += (*str++ & 0x3f); + *out_char = c; + return 3; + } + if ((*str & 0xf8) == 0xf0) + { + *out_char = 0xFFFD; // will be invalid but not end of string + if (in_text_end && in_text_end - (const char*)str < 4) return 1; + if (*str > 0xf4) return 4; + if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return 4; + if (*str == 0xf4 && str[1] > 0x8f) return 4; // str[1] < 0x80 is checked below + c = (unsigned int)((*str++ & 0x07) << 18); + if ((*str & 0xc0) != 0x80) return 4; + c += (unsigned int)((*str++ & 0x3f) << 12); + if ((*str & 0xc0) != 0x80) return 4; + c += (unsigned int)((*str++ & 0x3f) << 6); + if ((*str & 0xc0) != 0x80) return 4; + c += (*str++ & 0x3f); + // utf-8 encodings of values used in surrogate pairs are invalid + if ((c & 0xFFFFF800) == 0xD800) return 4; + *out_char = c; + return 4; + } + *out_char = 0; + return 0; +} + +int ImTextStrFromUtf8(ImWchar* buf, int buf_size, const char* in_text, const char* in_text_end, const char** in_text_remaining) +{ + ImWchar* buf_out = buf; + ImWchar* buf_end = buf + buf_size; + while (buf_out < buf_end-1 && (!in_text_end || in_text < in_text_end) && *in_text) + { + unsigned int c; + in_text += ImTextCharFromUtf8(&c, in_text, in_text_end); + if (c == 0) + break; + if (c < 0x10000) // FIXME: Losing characters that don't fit in 2 bytes + *buf_out++ = (ImWchar)c; + } + *buf_out = 0; + if (in_text_remaining) + *in_text_remaining = in_text; + return (int)(buf_out - buf); +} + +int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end) +{ + int char_count = 0; + while ((!in_text_end || in_text < in_text_end) && *in_text) + { + unsigned int c; + in_text += ImTextCharFromUtf8(&c, in_text, in_text_end); + if (c == 0) + break; + if (c < 0x10000) + char_count++; + } + return char_count; +} + +// Based on stb_to_utf8() from github.com/nothings/stb/ +static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c) +{ + if (c < 0x80) + { + buf[0] = (char)c; + return 1; + } + if (c < 0x800) + { + if (buf_size < 2) return 0; + buf[0] = (char)(0xc0 + (c >> 6)); + buf[1] = (char)(0x80 + (c & 0x3f)); + return 2; + } + if (c >= 0xdc00 && c < 0xe000) + { + return 0; + } + if (c >= 0xd800 && c < 0xdc00) + { + if (buf_size < 4) return 0; + buf[0] = (char)(0xf0 + (c >> 18)); + buf[1] = (char)(0x80 + ((c >> 12) & 0x3f)); + buf[2] = (char)(0x80 + ((c >> 6) & 0x3f)); + buf[3] = (char)(0x80 + ((c ) & 0x3f)); + return 4; + } + //else if (c < 0x10000) + { + if (buf_size < 3) return 0; + buf[0] = (char)(0xe0 + (c >> 12)); + buf[1] = (char)(0x80 + ((c>> 6) & 0x3f)); + buf[2] = (char)(0x80 + ((c ) & 0x3f)); + return 3; + } +} + +static inline int ImTextCountUtf8BytesFromChar(unsigned int c) +{ + if (c < 0x80) return 1; + if (c < 0x800) return 2; + if (c >= 0xdc00 && c < 0xe000) return 0; + if (c >= 0xd800 && c < 0xdc00) return 4; + return 3; +} + +int ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end) +{ + char* buf_out = buf; + const char* buf_end = buf + buf_size; + while (buf_out < buf_end-1 && (!in_text_end || in_text < in_text_end) && *in_text) + { + unsigned int c = (unsigned int)(*in_text++); + if (c < 0x80) + *buf_out++ = (char)c; + else + buf_out += ImTextCharToUtf8(buf_out, (int)(buf_end-buf_out-1), c); + } + *buf_out = 0; + return (int)(buf_out - buf); +} + +int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end) +{ + int bytes_count = 0; + while ((!in_text_end || in_text < in_text_end) && *in_text) + { + unsigned int c = (unsigned int)(*in_text++); + if (c < 0x80) + bytes_count++; + else + bytes_count += ImTextCountUtf8BytesFromChar(c); + } + return bytes_count; +} + +ImVec4 ImGui::ColorConvertU32ToFloat4(ImU32 in) +{ + float s = 1.0f/255.0f; + return ImVec4((in & 0xFF) * s, ((in >> 8) & 0xFF) * s, ((in >> 16) & 0xFF) * s, (in >> 24) * s); +} + +ImU32 ImGui::ColorConvertFloat4ToU32(const ImVec4& in) +{ + ImU32 out; + out = ((ImU32)IM_F32_TO_INT8_SAT(in.x)); + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.y)) << 8; + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.z)) << 16; + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.w)) << 24; + return out; +} + +ImU32 ImGui::GetColorU32(ImGuiCol idx, float alpha_mul) +{ + ImVec4 c = GImGui->Style.Colors[idx]; + c.w *= GImGui->Style.Alpha * alpha_mul; + return ImGui::ColorConvertFloat4ToU32(c); +} + +ImU32 ImGui::GetColorU32(const ImVec4& col) +{ + ImVec4 c = col; + c.w *= GImGui->Style.Alpha; + return ImGui::ColorConvertFloat4ToU32(c); +} + +// Convert rgb floats ([0-1],[0-1],[0-1]) to hsv floats ([0-1],[0-1],[0-1]), from Foley & van Dam p592 +// Optimized http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv +void ImGui::ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v) +{ + float K = 0.f; + if (g < b) + { + const float tmp = g; g = b; b = tmp; + K = -1.f; + } + if (r < g) + { + const float tmp = r; r = g; g = tmp; + K = -2.f / 6.f - K; + } + + const float chroma = r - (g < b ? g : b); + out_h = fabsf(K + (g - b) / (6.f * chroma + 1e-20f)); + out_s = chroma / (r + 1e-20f); + out_v = r; +} + +// Convert hsv floats ([0-1],[0-1],[0-1]) to rgb floats ([0-1],[0-1],[0-1]), from Foley & van Dam p593 +// also http://en.wikipedia.org/wiki/HSL_and_HSV +void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b) +{ + if (s == 0.0f) + { + // gray + out_r = out_g = out_b = v; + return; + } + + h = fmodf(h, 1.0f) / (60.0f/360.0f); + int i = (int)h; + float f = h - (float)i; + float p = v * (1.0f - s); + float q = v * (1.0f - s * f); + float t = v * (1.0f - s * (1.0f - f)); + + switch (i) + { + case 0: out_r = v; out_g = t; out_b = p; break; + case 1: out_r = q; out_g = v; out_b = p; break; + case 2: out_r = p; out_g = v; out_b = t; break; + case 3: out_r = p; out_g = q; out_b = v; break; + case 4: out_r = t; out_g = p; out_b = v; break; + case 5: default: out_r = v; out_g = p; out_b = q; break; + } +} + +// Load file content into memory +// Memory allocated with ImGui::MemAlloc(), must be freed by user using ImGui::MemFree() +void* ImLoadFileToMemory(const char* filename, const char* file_open_mode, int* out_file_size, int padding_bytes) +{ + IM_ASSERT(filename && file_open_mode); + if (out_file_size) + *out_file_size = 0; + + FILE* f; + if ((f = fopen(filename, file_open_mode)) == NULL) + return NULL; + + long file_size_signed; + if (fseek(f, 0, SEEK_END) || (file_size_signed = ftell(f)) == -1 || fseek(f, 0, SEEK_SET)) + { + fclose(f); + return NULL; + } + + int file_size = (int)file_size_signed; + void* file_data = ImGui::MemAlloc(file_size + padding_bytes); + if (file_data == NULL) + { + fclose(f); + return NULL; + } + if (fread(file_data, 1, (size_t)file_size, f) != (size_t)file_size) + { + fclose(f); + ImGui::MemFree(file_data); + return NULL; + } + if (padding_bytes > 0) + memset((void *)(((char*)file_data) + file_size), 0, padding_bytes); + + fclose(f); + if (out_file_size) + *out_file_size = file_size; + + return file_data; +} + +//----------------------------------------------------------------------------- +// ImGuiStorage +//----------------------------------------------------------------------------- + +// Helper: Key->value storage +void ImGuiStorage::Clear() +{ + Data.clear(); +} + +// std::lower_bound but without the bullshit +static ImVector::iterator LowerBound(ImVector& data, ImGuiID key) +{ + ImVector::iterator first = data.begin(); + ImVector::iterator last = data.end(); + int count = (int)(last - first); + while (count > 0) + { + int count2 = count / 2; + ImVector::iterator mid = first + count2; + if (mid->key < key) + { + first = ++mid; + count -= count2 + 1; + } + else + { + count = count2; + } + } + return first; +} + +int ImGuiStorage::GetInt(ImGuiID key, int default_val) const +{ + ImVector::iterator it = LowerBound(const_cast&>(Data), key); + if (it == Data.end() || it->key != key) + return default_val; + return it->val_i; +} + +bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const +{ + return GetInt(key, default_val ? 1 : 0) != 0; +} + +float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const +{ + ImVector::iterator it = LowerBound(const_cast&>(Data), key); + if (it == Data.end() || it->key != key) + return default_val; + return it->val_f; +} + +void* ImGuiStorage::GetVoidPtr(ImGuiID key) const +{ + ImVector::iterator it = LowerBound(const_cast&>(Data), key); + if (it == Data.end() || it->key != key) + return NULL; + return it->val_p; +} + +// References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer. +int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val) +{ + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + it = Data.insert(it, Pair(key, default_val)); + return &it->val_i; +} + +bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val) +{ + return (bool*)GetIntRef(key, default_val ? 1 : 0); +} + +float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) +{ + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + it = Data.insert(it, Pair(key, default_val)); + return &it->val_f; +} + +void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) +{ + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + it = Data.insert(it, Pair(key, default_val)); + return &it->val_p; +} + +// FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame) +void ImGuiStorage::SetInt(ImGuiID key, int val) +{ + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + { + Data.insert(it, Pair(key, val)); + return; + } + it->val_i = val; +} + +void ImGuiStorage::SetBool(ImGuiID key, bool val) +{ + SetInt(key, val ? 1 : 0); +} + +void ImGuiStorage::SetFloat(ImGuiID key, float val) +{ + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + { + Data.insert(it, Pair(key, val)); + return; + } + it->val_f = val; +} + +void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val) +{ + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + { + Data.insert(it, Pair(key, val)); + return; + } + it->val_p = val; +} + +void ImGuiStorage::SetAllInt(int v) +{ + for (int i = 0; i < Data.Size; i++) + Data[i].val_i = v; +} + +//----------------------------------------------------------------------------- +// ImGuiTextFilter +//----------------------------------------------------------------------------- + +// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" +ImGuiTextFilter::ImGuiTextFilter(const char* default_filter) +{ + if (default_filter) + { + ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf)); + Build(); + } + else + { + InputBuf[0] = 0; + CountGrep = 0; + } +} + +bool ImGuiTextFilter::Draw(const char* label, float width) +{ + if (width != 0.0f) + ImGui::PushItemWidth(width); + bool value_changed = ImGui::InputText(label, InputBuf, IM_ARRAYSIZE(InputBuf)); + if (width != 0.0f) + ImGui::PopItemWidth(); + if (value_changed) + Build(); + return value_changed; +} + +void ImGuiTextFilter::TextRange::split(char separator, ImVector& out) +{ + out.resize(0); + const char* wb = b; + const char* we = wb; + while (we < e) + { + if (*we == separator) + { + out.push_back(TextRange(wb, we)); + wb = we + 1; + } + we++; + } + if (wb != we) + out.push_back(TextRange(wb, we)); +} + +void ImGuiTextFilter::Build() +{ + Filters.resize(0); + TextRange input_range(InputBuf, InputBuf+strlen(InputBuf)); + input_range.split(',', Filters); + + CountGrep = 0; + for (int i = 0; i != Filters.Size; i++) + { + Filters[i].trim_blanks(); + if (Filters[i].empty()) + continue; + if (Filters[i].front() != '-') + CountGrep += 1; + } +} + +bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const +{ + if (Filters.empty()) + return true; + + if (text == NULL) + text = ""; + + for (int i = 0; i != Filters.Size; i++) + { + const TextRange& f = Filters[i]; + if (f.empty()) + continue; + if (f.front() == '-') + { + // Subtract + if (ImStristr(text, text_end, f.begin()+1, f.end()) != NULL) + return false; + } + else + { + // Grep + if (ImStristr(text, text_end, f.begin(), f.end()) != NULL) + return true; + } + } + + // Implicit * grep + if (CountGrep == 0) + return true; + + return false; +} + +//----------------------------------------------------------------------------- +// ImGuiTextBuffer +//----------------------------------------------------------------------------- + +// On some platform vsnprintf() takes va_list by reference and modifies it. +// va_copy is the 'correct' way to copy a va_list but Visual Studio prior to 2013 doesn't have it. +#ifndef va_copy +#define va_copy(dest, src) (dest = src) +#endif + +// Helper: Text buffer for logging/accumulating text +void ImGuiTextBuffer::appendv(const char* fmt, va_list args) +{ + va_list args_copy; + va_copy(args_copy, args); + + int len = vsnprintf(NULL, 0, fmt, args); // FIXME-OPT: could do a first pass write attempt, likely successful on first pass. + if (len <= 0) + return; + + const int write_off = Buf.Size; + const int needed_sz = write_off + len; + if (write_off + len >= Buf.Capacity) + { + int double_capacity = Buf.Capacity * 2; + Buf.reserve(needed_sz > double_capacity ? needed_sz : double_capacity); + } + + Buf.resize(needed_sz); + ImFormatStringV(&Buf[write_off] - 1, len+1, fmt, args_copy); +} + +void ImGuiTextBuffer::append(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + appendv(fmt, args); + va_end(args); +} + +//----------------------------------------------------------------------------- +// ImGuiSimpleColumns +//----------------------------------------------------------------------------- + +ImGuiSimpleColumns::ImGuiSimpleColumns() +{ + Count = 0; + Spacing = Width = NextWidth = 0.0f; + memset(Pos, 0, sizeof(Pos)); + memset(NextWidths, 0, sizeof(NextWidths)); +} + +void ImGuiSimpleColumns::Update(int count, float spacing, bool clear) +{ + IM_ASSERT(Count <= IM_ARRAYSIZE(Pos)); + Count = count; + Width = NextWidth = 0.0f; + Spacing = spacing; + if (clear) memset(NextWidths, 0, sizeof(NextWidths)); + for (int i = 0; i < Count; i++) + { + if (i > 0 && NextWidths[i] > 0.0f) + Width += Spacing; + Pos[i] = (float)(int)Width; + Width += NextWidths[i]; + NextWidths[i] = 0.0f; + } +} + +float ImGuiSimpleColumns::DeclColumns(float w0, float w1, float w2) // not using va_arg because they promote float to double +{ + NextWidth = 0.0f; + NextWidths[0] = ImMax(NextWidths[0], w0); + NextWidths[1] = ImMax(NextWidths[1], w1); + NextWidths[2] = ImMax(NextWidths[2], w2); + for (int i = 0; i < 3; i++) + NextWidth += NextWidths[i] + ((i > 0 && NextWidths[i] > 0.0f) ? Spacing : 0.0f); + return ImMax(Width, NextWidth); +} + +float ImGuiSimpleColumns::CalcExtraSpace(float avail_w) +{ + return ImMax(0.0f, avail_w - Width); +} + +//----------------------------------------------------------------------------- +// ImGuiListClipper +//----------------------------------------------------------------------------- + +static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height) +{ + // Set cursor position and a few other things so that SetScrollHere() and Columns() can work when seeking cursor. + // FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue. Consider moving within SetCursorXXX functions? + ImGui::SetCursorPosY(pos_y); + ImGuiWindow* window = ImGui::GetCurrentWindow(); + window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHere() can properly function after the end of our clipper usage. + window->DC.PrevLineHeight = (line_height - GImGui->Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list. + if (window->DC.ColumnsCount > 1) + window->DC.ColumnsCellMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly +} + +// Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1 +// Use case B: Begin() called from constructor with items_height>0 +// FIXME-LEGACY: Ideally we should remove the Begin/End functions but they are part of the legacy API we still support. This is why some of the code in Step() calling Begin() and reassign some fields, spaghetti style. +void ImGuiListClipper::Begin(int count, float items_height) +{ + StartPosY = ImGui::GetCursorPosY(); + ItemsHeight = items_height; + ItemsCount = count; + StepNo = 0; + DisplayEnd = DisplayStart = -1; + if (ItemsHeight > 0.0f) + { + ImGui::CalcListClipping(ItemsCount, ItemsHeight, &DisplayStart, &DisplayEnd); // calculate how many to clip/display + if (DisplayStart > 0) + SetCursorPosYAndSetupDummyPrevLine(StartPosY + DisplayStart * ItemsHeight, ItemsHeight); // advance cursor + StepNo = 2; + } +} + +void ImGuiListClipper::End() +{ + if (ItemsCount < 0) + return; + // In theory here we should assert that ImGui::GetCursorPosY() == StartPosY + DisplayEnd * ItemsHeight, but it feels saner to just seek at the end and not assert/crash the user. + if (ItemsCount < INT_MAX) + SetCursorPosYAndSetupDummyPrevLine(StartPosY + ItemsCount * ItemsHeight, ItemsHeight); // advance cursor + ItemsCount = -1; + StepNo = 3; +} + +bool ImGuiListClipper::Step() +{ + if (ItemsCount == 0 || ImGui::GetCurrentWindowRead()->SkipItems) + { + ItemsCount = -1; + return false; + } + if (StepNo == 0) // Step 0: the clipper let you process the first element, regardless of it being visible or not, so we can measure the element height. + { + DisplayStart = 0; + DisplayEnd = 1; + StartPosY = ImGui::GetCursorPosY(); + StepNo = 1; + return true; + } + if (StepNo == 1) // Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element. + { + if (ItemsCount == 1) { ItemsCount = -1; return false; } + float items_height = ImGui::GetCursorPosY() - StartPosY; + IM_ASSERT(items_height > 0.0f); // If this triggers, it means Item 0 hasn't moved the cursor vertically + Begin(ItemsCount-1, items_height); + DisplayStart++; + DisplayEnd++; + StepNo = 3; + return true; + } + if (StepNo == 2) // Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user still call Step(). Does nothing and switch to Step 3. + { + IM_ASSERT(DisplayStart >= 0 && DisplayEnd >= 0); + StepNo = 3; + return true; + } + if (StepNo == 3) // Step 3: the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), advance the cursor to the end of the list and then returns 'false' to end the loop. + End(); + return false; +} + +//----------------------------------------------------------------------------- +// ImGuiWindow +//----------------------------------------------------------------------------- + +ImGuiWindow::ImGuiWindow(const char* name) +{ + Name = ImStrdup(name); + ID = ImHash(name, 0); + IDStack.push_back(ID); + MoveId = GetID("#MOVE"); + + Flags = 0; + IndexWithinParent = 0; + PosFloat = Pos = ImVec2(0.0f, 0.0f); + Size = SizeFull = ImVec2(0.0f, 0.0f); + SizeContents = SizeContentsExplicit = ImVec2(0.0f, 0.0f); + WindowPadding = ImVec2(0.0f, 0.0f); + Scroll = ImVec2(0.0f, 0.0f); + ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); + ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f); + ScrollbarX = ScrollbarY = false; + ScrollbarSizes = ImVec2(0.0f, 0.0f); + BorderSize = 0.0f; + Active = WasActive = false; + Accessed = false; + Collapsed = false; + SkipItems = false; + BeginCount = 0; + PopupId = 0; + AutoFitFramesX = AutoFitFramesY = -1; + AutoFitOnlyGrows = false; + AutoPosLastDirection = -1; + HiddenFrames = 0; + SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiSetCond_Always | ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing; + SetWindowPosCenterWanted = false; + + LastFrameActive = -1; + ItemWidthDefault = 0.0f; + FontWindowScale = 1.0f; + + DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList)); + IM_PLACEMENT_NEW(DrawList) ImDrawList(); + DrawList->_OwnerName = Name; + RootWindow = NULL; + RootNonPopupWindow = NULL; + ParentWindow = NULL; + + FocusIdxAllCounter = FocusIdxTabCounter = -1; + FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = INT_MAX; + FocusIdxAllRequestNext = FocusIdxTabRequestNext = INT_MAX; +} + +ImGuiWindow::~ImGuiWindow() +{ + DrawList->~ImDrawList(); + ImGui::MemFree(DrawList); + DrawList = NULL; + ImGui::MemFree(Name); + Name = NULL; +} + +ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) +{ + ImGuiID seed = IDStack.back(); + ImGuiID id = ImHash(str, str_end ? (int)(str_end - str) : 0, seed); + ImGui::KeepAliveID(id); + return id; +} + +ImGuiID ImGuiWindow::GetID(const void* ptr) +{ + ImGuiID seed = IDStack.back(); + ImGuiID id = ImHash(&ptr, sizeof(void*), seed); + ImGui::KeepAliveID(id); + return id; +} + +ImGuiID ImGuiWindow::GetIDNoKeepAlive(const char* str, const char* str_end) +{ + ImGuiID seed = IDStack.back(); + return ImHash(str, str_end ? (int)(str_end - str) : 0, seed); +} + +//----------------------------------------------------------------------------- +// Internal API exposed in imgui_internal.h +//----------------------------------------------------------------------------- + +static void SetCurrentWindow(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + g.CurrentWindow = window; + if (window) + g.FontSize = window->CalcFontSize(); +} + +ImGuiWindow* ImGui::GetParentWindow() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.CurrentWindowStack.Size >= 2); + return g.CurrentWindowStack[(unsigned int)g.CurrentWindowStack.Size - 2]; +} + +void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window = NULL) +{ + ImGuiContext& g = *GImGui; + g.ActiveId = id; + g.ActiveIdAllowOverlap = false; + g.ActiveIdIsJustActivated = true; + g.ActiveIdWindow = window; +} + +void ImGui::SetHoveredID(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + g.HoveredId = id; + g.HoveredIdAllowOverlap = false; +} + +void ImGui::KeepAliveID(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + if (g.ActiveId == id) + g.ActiveIdIsAlive = true; +} + +// Advance cursor given item size for layout. +void ImGui::ItemSize(const ImVec2& size, float text_offset_y) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + // Always align ourselves on pixel boundaries + ImGuiContext& g = *GImGui; + const float line_height = ImMax(window->DC.CurrentLineHeight, size.y); + const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y); + window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y); + window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y)); + window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); + window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); + + //window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // Debug + + window->DC.PrevLineHeight = line_height; + window->DC.PrevLineTextBaseOffset = text_base_offset; + window->DC.CurrentLineHeight = window->DC.CurrentLineTextBaseOffset = 0.0f; +} + +void ImGui::ItemSize(const ImRect& bb, float text_offset_y) +{ + ItemSize(bb.GetSize(), text_offset_y); +} + +// Declare item bounding box for clipping and interaction. +// Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface +// declares their minimum size requirement to ItemSize() and then use a larger region for drawing/interaction, which is passed to ItemAdd(). +bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.LastItemId = id ? *id : 0; + window->DC.LastItemRect = bb; + window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false; + if (IsClippedEx(bb, id, false)) + return false; + + // This is a sensible default, but widgets are free to override it after calling ItemAdd() + ImGuiContext& g = *GImGui; + if (IsMouseHoveringRect(bb.Min, bb.Max)) + { + // Matching the behavior of IsHovered() but allow if ActiveId==window->MoveID (we clicked on the window background) + // So that clicking on items with no active id such as Text() still returns true with IsItemHovered() + window->DC.LastItemHoveredRect = true; + if (g.HoveredRootWindow == window->RootWindow) + if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowOverlap || (g.ActiveId == window->MoveId)) + if (IsWindowContentHoverable(window)) + window->DC.LastItemHoveredAndUsable = true; + } + + return true; +} + +bool ImGui::IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindowRead(); + + if (!bb.Overlaps(window->ClipRect)) + if (!id || *id != GImGui->ActiveId) + if (clip_even_when_logged || !g.LogEnabled) + return true; + return false; +} + +// NB: This is an internal helper. The user-facing IsItemHovered() is using data emitted from ItemAdd(), with a slightly different logic. +bool ImGui::IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs) +{ + ImGuiContext& g = *GImGui; + if (g.HoveredId == 0 || g.HoveredId == id || g.HoveredIdAllowOverlap) + { + ImGuiWindow* window = GetCurrentWindowRead(); + if (g.HoveredWindow == window || (flatten_childs && g.HoveredRootWindow == window->RootWindow)) + if ((g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowOverlap) && IsMouseHoveringRect(bb.Min, bb.Max)) + if (IsWindowContentHoverable(g.HoveredRootWindow)) + return true; + } + return false; +} + +bool ImGui::FocusableItemRegister(ImGuiWindow* window, bool is_active, bool tab_stop) +{ + ImGuiContext& g = *GImGui; + + const bool allow_keyboard_focus = window->DC.AllowKeyboardFocus; + window->FocusIdxAllCounter++; + if (allow_keyboard_focus) + window->FocusIdxTabCounter++; + + // Process keyboard input at this point: TAB, Shift-TAB switch focus + // We can always TAB out of a widget that doesn't allow tabbing in. + if (tab_stop && window->FocusIdxAllRequestNext == INT_MAX && window->FocusIdxTabRequestNext == INT_MAX && is_active && IsKeyPressedMap(ImGuiKey_Tab)) + { + // Modulo on index will be applied at the end of frame once we've got the total counter of items. + window->FocusIdxTabRequestNext = window->FocusIdxTabCounter + (g.IO.KeyShift ? (allow_keyboard_focus ? -1 : 0) : +1); + } + + if (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent) + return true; + + if (allow_keyboard_focus) + if (window->FocusIdxTabCounter == window->FocusIdxTabRequestCurrent) + return true; + + return false; +} + +void ImGui::FocusableItemUnregister(ImGuiWindow* window) +{ + window->FocusIdxAllCounter--; + window->FocusIdxTabCounter--; +} + +ImVec2 ImGui::CalcItemSize(ImVec2 size, float default_x, float default_y) +{ + ImGuiContext& g = *GImGui; + ImVec2 content_max; + if (size.x < 0.0f || size.y < 0.0f) + content_max = g.CurrentWindow->Pos + GetContentRegionMax(); + if (size.x <= 0.0f) + size.x = (size.x == 0.0f) ? default_x : ImMax(content_max.x - g.CurrentWindow->DC.CursorPos.x, 4.0f) + size.x; + if (size.y <= 0.0f) + size.y = (size.y == 0.0f) ? default_y : ImMax(content_max.y - g.CurrentWindow->DC.CursorPos.y, 4.0f) + size.y; + return size; +} + +float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) +{ + if (wrap_pos_x < 0.0f) + return 0.0f; + + ImGuiWindow* window = GetCurrentWindowRead(); + if (wrap_pos_x == 0.0f) + wrap_pos_x = GetContentRegionMax().x + window->Pos.x; + else if (wrap_pos_x > 0.0f) + wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space + + return ImMax(wrap_pos_x - pos.x, 1.0f); +} + +//----------------------------------------------------------------------------- + +void* ImGui::MemAlloc(size_t sz) +{ + GImGui->IO.MetricsAllocs++; + return GImGui->IO.MemAllocFn(sz); +} + +void ImGui::MemFree(void* ptr) +{ + if (ptr) GImGui->IO.MetricsAllocs--; + return GImGui->IO.MemFreeFn(ptr); +} + +const char* ImGui::GetClipboardText() +{ + return GImGui->IO.GetClipboardTextFn ? GImGui->IO.GetClipboardTextFn() : ""; +} + +void ImGui::SetClipboardText(const char* text) +{ + if (GImGui->IO.SetClipboardTextFn) + GImGui->IO.SetClipboardTextFn(text); +} + +const char* ImGui::GetVersion() +{ + return IMGUI_VERSION; +} + +// Internal state access - if you want to share ImGui state between modules (e.g. DLL) or allocate it yourself +// Note that we still point to some static data and members (such as GFontAtlas), so the state instance you end up using will point to the static data within its module +ImGuiContext* ImGui::GetCurrentContext() +{ + return GImGui; +} + +void ImGui::SetCurrentContext(ImGuiContext* ctx) +{ + GImGui = ctx; +} + +ImGuiContext* ImGui::CreateContext(void* (*malloc_fn)(size_t), void (*free_fn)(void*)) +{ + if (!malloc_fn) malloc_fn = malloc; + ImGuiContext* ctx = (ImGuiContext*)malloc_fn(sizeof(ImGuiContext)); + IM_PLACEMENT_NEW(ctx) ImGuiContext(); + ctx->IO.MemAllocFn = malloc_fn; + ctx->IO.MemFreeFn = free_fn ? free_fn : free; + return ctx; +} + +void ImGui::DestroyContext(ImGuiContext* ctx) +{ + void (*free_fn)(void*) = ctx->IO.MemFreeFn; + ctx->~ImGuiContext(); + free_fn(ctx); + if (GImGui == ctx) + GImGui = NULL; +} + +ImGuiIO& ImGui::GetIO() +{ + return GImGui->IO; +} + +ImGuiStyle& ImGui::GetStyle() +{ + return GImGui->Style; +} + +// Same value as passed to your RenderDrawListsFn() function. valid after Render() and until the next call to NewFrame() +ImDrawData* ImGui::GetDrawData() +{ + return GImGui->RenderDrawData.Valid ? &GImGui->RenderDrawData : NULL; +} + +float ImGui::GetTime() +{ + return GImGui->Time; +} + +int ImGui::GetFrameCount() +{ + return GImGui->FrameCount; +} + +void ImGui::NewFrame() +{ + ImGuiContext& g = *GImGui; + + // Check user data + IM_ASSERT(g.IO.DeltaTime >= 0.0f); // Need a positive DeltaTime (zero is tolerated but will cause some timing issues) + IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f); + IM_ASSERT(g.IO.Fonts->Fonts.Size > 0); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? + IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? + IM_ASSERT(g.Style.CurveTessellationTol > 0.0f); // Invalid style setting + + if (!g.Initialized) + { + // Initialize on first frame + g.LogClipboard = (ImGuiTextBuffer*)ImGui::MemAlloc(sizeof(ImGuiTextBuffer)); + IM_PLACEMENT_NEW(g.LogClipboard) ImGuiTextBuffer(); + + IM_ASSERT(g.Settings.empty()); + LoadSettings(); + g.Initialized = true; + } + + SetCurrentFont(g.IO.Fonts->Fonts[0]); + + g.Time += g.IO.DeltaTime; + g.FrameCount += 1; + g.Tooltip[0] = '\0'; + g.OverlayDrawList.Clear(); + g.OverlayDrawList.PushTextureID(g.IO.Fonts->TexID); + g.OverlayDrawList.PushClipRectFullScreen(); + + // Mark rendering data as invalid to prevent user who may have a handle on it to use it + g.RenderDrawData.Valid = false; + g.RenderDrawData.CmdLists = NULL; + g.RenderDrawData.CmdListsCount = g.RenderDrawData.TotalVtxCount = g.RenderDrawData.TotalIdxCount = 0; + + // Update inputs state + if (g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) + g.IO.MousePos = ImVec2(-9999.0f, -9999.0f); + if ((g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) || (g.IO.MousePosPrev.x < 0 && g.IO.MousePosPrev.y < 0)) // if mouse just appeared or disappeared (negative coordinate) we cancel out movement in MouseDelta + g.IO.MouseDelta = ImVec2(0.0f, 0.0f); + else + g.IO.MouseDelta = g.IO.MousePos - g.IO.MousePosPrev; + g.IO.MousePosPrev = g.IO.MousePos; + for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) + { + g.IO.MouseClicked[i] = g.IO.MouseDown[i] && g.IO.MouseDownDuration[i] < 0.0f; + g.IO.MouseReleased[i] = !g.IO.MouseDown[i] && g.IO.MouseDownDuration[i] >= 0.0f; + g.IO.MouseDownDurationPrev[i] = g.IO.MouseDownDuration[i]; + g.IO.MouseDownDuration[i] = g.IO.MouseDown[i] ? (g.IO.MouseDownDuration[i] < 0.0f ? 0.0f : g.IO.MouseDownDuration[i] + g.IO.DeltaTime) : -1.0f; + g.IO.MouseDoubleClicked[i] = false; + if (g.IO.MouseClicked[i]) + { + if (g.Time - g.IO.MouseClickedTime[i] < g.IO.MouseDoubleClickTime) + { + if (ImLengthSqr(g.IO.MousePos - g.IO.MouseClickedPos[i]) < g.IO.MouseDoubleClickMaxDist * g.IO.MouseDoubleClickMaxDist) + g.IO.MouseDoubleClicked[i] = true; + g.IO.MouseClickedTime[i] = -FLT_MAX; // so the third click isn't turned into a double-click + } + else + { + g.IO.MouseClickedTime[i] = g.Time; + } + g.IO.MouseClickedPos[i] = g.IO.MousePos; + g.IO.MouseDragMaxDistanceSqr[i] = 0.0f; + } + else if (g.IO.MouseDown[i]) + { + g.IO.MouseDragMaxDistanceSqr[i] = ImMax(g.IO.MouseDragMaxDistanceSqr[i], ImLengthSqr(g.IO.MousePos - g.IO.MouseClickedPos[i])); + } + } + memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); + for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) + g.IO.KeysDownDuration[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownDuration[i] < 0.0f ? 0.0f : g.IO.KeysDownDuration[i] + g.IO.DeltaTime) : -1.0f; + + // Calculate frame-rate for the user, as a purely luxurious feature + g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx]; + g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime; + g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame); + g.IO.Framerate = 1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame)); + + // Clear reference to active widget if the widget isn't alive anymore + g.HoveredIdPreviousFrame = g.HoveredId; + g.HoveredId = 0; + g.HoveredIdAllowOverlap = false; + if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) + SetActiveID(0); + g.ActiveIdPreviousFrame = g.ActiveId; + g.ActiveIdIsAlive = false; + g.ActiveIdIsJustActivated = false; + + // Handle user moving window (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows. + if (g.MovedWindowMoveId && g.MovedWindowMoveId == g.ActiveId) + { + KeepAliveID(g.MovedWindowMoveId); + IM_ASSERT(g.MovedWindow && g.MovedWindow->RootWindow); + IM_ASSERT(g.MovedWindow->RootWindow->MoveId == g.MovedWindowMoveId); + if (g.IO.MouseDown[0]) + { + if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoMove)) + { + g.MovedWindow->PosFloat += g.IO.MouseDelta; + if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoSavedSettings)) + MarkSettingsDirty(); + } + FocusWindow(g.MovedWindow); + } + else + { + SetActiveID(0); + g.MovedWindow = NULL; + g.MovedWindowMoveId = 0; + } + } + else + { + g.MovedWindow = NULL; + g.MovedWindowMoveId = 0; + } + + // Delay saving settings so we don't spam disk too much + if (g.SettingsDirtyTimer > 0.0f) + { + g.SettingsDirtyTimer -= g.IO.DeltaTime; + if (g.SettingsDirtyTimer <= 0.0f) + SaveSettings(); + } + + // Find the window we are hovering. Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow + g.HoveredWindow = g.MovedWindow ? g.MovedWindow : FindHoveredWindow(g.IO.MousePos, false); + if (g.HoveredWindow && (g.HoveredWindow->Flags & ImGuiWindowFlags_ChildWindow)) + g.HoveredRootWindow = g.HoveredWindow->RootWindow; + else + g.HoveredRootWindow = g.MovedWindow ? g.MovedWindow->RootWindow : FindHoveredWindow(g.IO.MousePos, true); + + if (ImGuiWindow* modal_window = GetFrontMostModalRootWindow()) + { + g.ModalWindowDarkeningRatio = ImMin(g.ModalWindowDarkeningRatio + g.IO.DeltaTime * 6.0f, 1.0f); + ImGuiWindow* window = g.HoveredRootWindow; + while (window && window != modal_window) + window = window->ParentWindow; + if (!window) + g.HoveredRootWindow = g.HoveredWindow = NULL; + } + else + { + g.ModalWindowDarkeningRatio = 0.0f; + } + + // Are we using inputs? Tell user so they can capture/discard the inputs away from the rest of their application. + // When clicking outside of a window we assume the click is owned by the application and won't request capture. We need to track click ownership. + int mouse_earliest_button_down = -1; + bool mouse_any_down = false; + for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) + { + if (g.IO.MouseClicked[i]) + g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenPopupStack.empty()); + mouse_any_down |= g.IO.MouseDown[i]; + if (g.IO.MouseDown[i]) + if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[mouse_earliest_button_down] > g.IO.MouseClickedTime[i]) + mouse_earliest_button_down = i; + } + bool mouse_avail_to_imgui = (mouse_earliest_button_down == -1) || g.IO.MouseDownOwned[mouse_earliest_button_down]; + if (g.CaptureMouseNextFrame != -1) + g.IO.WantCaptureMouse = (g.CaptureMouseNextFrame != 0); + else + g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.ActiveId != 0) || (!g.OpenPopupStack.empty()); + g.IO.WantCaptureKeyboard = (g.CaptureKeyboardNextFrame != -1) ? (g.CaptureKeyboardNextFrame != 0) : (g.ActiveId != 0); + g.IO.WantTextInput = (g.ActiveId != 0 && g.InputTextState.Id == g.ActiveId); + g.MouseCursor = ImGuiMouseCursor_Arrow; + g.CaptureMouseNextFrame = g.CaptureKeyboardNextFrame = -1; + g.OsImePosRequest = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default + + // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. + if (!mouse_avail_to_imgui) + g.HoveredWindow = g.HoveredRootWindow = NULL; + + // Scale & Scrolling + if (g.HoveredWindow && g.IO.MouseWheel != 0.0f && !g.HoveredWindow->Collapsed) + { + ImGuiWindow* window = g.HoveredWindow; + if (g.IO.KeyCtrl) + { + if (g.IO.FontAllowUserScaling) + { + // Zoom / Scale window + float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f); + float scale = new_font_scale / window->FontWindowScale; + window->FontWindowScale = new_font_scale; + + const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; + window->Pos += offset; + window->PosFloat += offset; + window->Size *= scale; + window->SizeFull *= scale; + } + } + else if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) + { + // Scroll + const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5; + SetWindowScrollY(window, window->Scroll.y - g.IO.MouseWheel * window->CalcFontSize() * scroll_lines); + } + } + + // Pressing TAB activate widget focus + // NB: Don't discard FocusedWindow if it isn't active, so that a window that go on/off programatically won't lose its keyboard focus. + if (g.ActiveId == 0 && g.FocusedWindow != NULL && g.FocusedWindow->Active && IsKeyPressedMap(ImGuiKey_Tab, false)) + g.FocusedWindow->FocusIdxTabRequestNext = 0; + + // Mark all windows as not visible + for (int i = 0; i != g.Windows.Size; i++) + { + ImGuiWindow* window = g.Windows[i]; + window->WasActive = window->Active; + window->Active = false; + window->Accessed = false; + } + + // Closing the focused window restore focus to the first active root window in descending z-order + if (g.FocusedWindow && !g.FocusedWindow->WasActive) + for (int i = g.Windows.Size-1; i >= 0; i--) + if (g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow)) + { + FocusWindow(g.Windows[i]); + break; + } + + // No window should be open at the beginning of the frame. + // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. + g.CurrentWindowStack.resize(0); + g.CurrentPopupStack.resize(0); + CloseInactivePopups(); + + // Create implicit window - we will only render it if the user has added something to it. + ImGui::SetNextWindowSize(ImVec2(400,400), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Debug"); +} + +// NB: behavior of ImGui after Shutdown() is not tested/guaranteed at the moment. This function is merely here to free heap allocations. +void ImGui::Shutdown() +{ + ImGuiContext& g = *GImGui; + + // The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame) + if (g.IO.Fonts) // Testing for NULL to allow user to NULLify in case of running Shutdown() on multiple contexts. Bit hacky. + g.IO.Fonts->Clear(); + + // Cleanup of other data are conditional on actually having used ImGui. + if (!g.Initialized) + return; + + SaveSettings(); + + for (int i = 0; i < g.Windows.Size; i++) + { + g.Windows[i]->~ImGuiWindow(); + ImGui::MemFree(g.Windows[i]); + } + g.Windows.clear(); + g.WindowsSortBuffer.clear(); + g.CurrentWindowStack.clear(); + g.FocusedWindow = NULL; + g.HoveredWindow = NULL; + g.HoveredRootWindow = NULL; + for (int i = 0; i < g.Settings.Size; i++) + ImGui::MemFree(g.Settings[i].Name); + g.Settings.clear(); + g.ColorModifiers.clear(); + g.StyleModifiers.clear(); + g.FontStack.clear(); + g.OpenPopupStack.clear(); + g.CurrentPopupStack.clear(); + for (int i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) + g.RenderDrawLists[i].clear(); + g.OverlayDrawList.ClearFreeMemory(); + g.ColorEditModeStorage.Clear(); + if (g.PrivateClipboard) + { + ImGui::MemFree(g.PrivateClipboard); + g.PrivateClipboard = NULL; + } + g.InputTextState.Text.clear(); + g.InputTextState.InitialText.clear(); + g.InputTextState.TempTextBuffer.clear(); + + if (g.LogFile && g.LogFile != stdout) + { + fclose(g.LogFile); + g.LogFile = NULL; + } + if (g.LogClipboard) + { + g.LogClipboard->~ImGuiTextBuffer(); + ImGui::MemFree(g.LogClipboard); + } + + g.Initialized = false; +} + +static ImGuiIniData* FindWindowSettings(const char* name) +{ + ImGuiContext& g = *GImGui; + ImGuiID id = ImHash(name, 0); + for (int i = 0; i != g.Settings.Size; i++) + { + ImGuiIniData* ini = &g.Settings[i]; + if (ini->Id == id) + return ini; + } + return NULL; +} + +static ImGuiIniData* AddWindowSettings(const char* name) +{ + GImGui->Settings.resize(GImGui->Settings.Size + 1); + ImGuiIniData* ini = &GImGui->Settings.back(); + ini->Name = ImStrdup(name); + ini->Id = ImHash(name, 0); + ini->Collapsed = false; + ini->Pos = ImVec2(FLT_MAX,FLT_MAX); + ini->Size = ImVec2(0,0); + return ini; +} + +// Zero-tolerance, poor-man .ini parsing +// FIXME: Write something less rubbish +static void LoadSettings() +{ + ImGuiContext& g = *GImGui; + const char* filename = g.IO.IniFilename; + if (!filename) + return; + + int file_size; + char* file_data = (char*)ImLoadFileToMemory(filename, "rb", &file_size, 1); + if (!file_data) + return; + + ImGuiIniData* settings = NULL; + const char* buf_end = file_data + file_size; + for (const char* line_start = file_data; line_start < buf_end; ) + { + const char* line_end = line_start; + while (line_end < buf_end && *line_end != '\n' && *line_end != '\r') + line_end++; + + if (line_start[0] == '[' && line_end > line_start && line_end[-1] == ']') + { + char name[64]; + ImFormatString(name, IM_ARRAYSIZE(name), "%.*s", (int)(line_end-line_start-2), line_start+1); + settings = FindWindowSettings(name); + if (!settings) + settings = AddWindowSettings(name); + } + else if (settings) + { + float x, y; + int i; + if (sscanf(line_start, "Pos=%f,%f", &x, &y) == 2) + settings->Pos = ImVec2(x, y); + else if (sscanf(line_start, "Size=%f,%f", &x, &y) == 2) + settings->Size = ImMax(ImVec2(x, y), g.Style.WindowMinSize); + else if (sscanf(line_start, "Collapsed=%d", &i) == 1) + settings->Collapsed = (i != 0); + } + + line_start = line_end+1; + } + + ImGui::MemFree(file_data); +} + +static void SaveSettings() +{ + ImGuiContext& g = *GImGui; + const char* filename = g.IO.IniFilename; + if (!filename) + return; + + // Gather data from windows that were active during this session + for (int i = 0; i != g.Windows.Size; i++) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Flags & ImGuiWindowFlags_NoSavedSettings) + continue; + ImGuiIniData* settings = FindWindowSettings(window->Name); + settings->Pos = window->Pos; + settings->Size = window->SizeFull; + settings->Collapsed = window->Collapsed; + } + + // Write .ini file + // If a window wasn't opened in this session we preserve its settings + FILE* f = fopen(filename, "wt"); + if (!f) + return; + for (int i = 0; i != g.Settings.Size; i++) + { + const ImGuiIniData* settings = &g.Settings[i]; + if (settings->Pos.x == FLT_MAX) + continue; + const char* name = settings->Name; + if (const char* p = strstr(name, "###")) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID() + name = p; + fprintf(f, "[%s]\n", name); + fprintf(f, "Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y); + fprintf(f, "Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y); + fprintf(f, "Collapsed=%d\n", settings->Collapsed); + fprintf(f, "\n"); + } + + fclose(f); +} + +static void MarkSettingsDirty() +{ + ImGuiContext& g = *GImGui; + if (g.SettingsDirtyTimer <= 0.0f) + g.SettingsDirtyTimer = g.IO.IniSavingRate; +} + +// FIXME: Add a more explicit sort order in the window structure. +static int ChildWindowComparer(const void* lhs, const void* rhs) +{ + const ImGuiWindow* a = *(const ImGuiWindow**)lhs; + const ImGuiWindow* b = *(const ImGuiWindow**)rhs; + if (int d = (a->Flags & ImGuiWindowFlags_Popup) - (b->Flags & ImGuiWindowFlags_Popup)) + return d; + if (int d = (a->Flags & ImGuiWindowFlags_Tooltip) - (b->Flags & ImGuiWindowFlags_Tooltip)) + return d; + if (int d = (a->Flags & ImGuiWindowFlags_ComboBox) - (b->Flags & ImGuiWindowFlags_ComboBox)) + return d; + return (a->IndexWithinParent - b->IndexWithinParent); +} + +static void AddWindowToSortedBuffer(ImVector& out_sorted_windows, ImGuiWindow* window) +{ + out_sorted_windows.push_back(window); + if (window->Active) + { + int count = window->DC.ChildWindows.Size; + if (count > 1) + qsort(window->DC.ChildWindows.begin(), (size_t)count, sizeof(ImGuiWindow*), ChildWindowComparer); + for (int i = 0; i < count; i++) + { + ImGuiWindow* child = window->DC.ChildWindows[i]; + if (child->Active) + AddWindowToSortedBuffer(out_sorted_windows, child); + } + } +} + +static void AddDrawListToRenderList(ImVector& out_render_list, ImDrawList* draw_list) +{ + if (draw_list->CmdBuffer.empty()) + return; + + // Remove trailing command if unused + ImDrawCmd& last_cmd = draw_list->CmdBuffer.back(); + if (last_cmd.ElemCount == 0 && last_cmd.UserCallback == NULL) + { + draw_list->CmdBuffer.pop_back(); + if (draw_list->CmdBuffer.empty()) + return; + } + + // Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc. + IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size); + IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size); + IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); + + // Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = 2 bytes = 64K vertices) + // If this assert triggers because you are drawing lots of stuff manually, A) workaround by calling BeginChild()/EndChild() to put your draw commands in multiple draw lists, B) #define ImDrawIdx to a 'unsigned int' in imconfig.h and render accordingly. + IM_ASSERT((int64_t)draw_list->_VtxCurrentIdx <= ((int64_t)1L << (sizeof(ImDrawIdx)*8))); // Too many vertices in same ImDrawList. See comment above. + + out_render_list.push_back(draw_list); + GImGui->IO.MetricsRenderVertices += draw_list->VtxBuffer.Size; + GImGui->IO.MetricsRenderIndices += draw_list->IdxBuffer.Size; +} + +static void AddWindowToRenderList(ImVector& out_render_list, ImGuiWindow* window) +{ + AddDrawListToRenderList(out_render_list, window->DrawList); + for (int i = 0; i < window->DC.ChildWindows.Size; i++) + { + ImGuiWindow* child = window->DC.ChildWindows[i]; + if (!child->Active) // clipped children may have been marked not active + continue; + if ((child->Flags & ImGuiWindowFlags_Popup) && child->HiddenFrames > 0) + continue; + AddWindowToRenderList(out_render_list, child); + } +} + +// When using this function it is sane to ensure that float are perfectly rounded to integer values, to that e.g. (int)(max.x-min.x) in user's render produce correct result. +void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DrawList->PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect); + window->ClipRect = window->DrawList->_ClipRectStack.back(); +} + +void ImGui::PopClipRect() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DrawList->PopClipRect(); + window->ClipRect = window->DrawList->_ClipRectStack.back(); +} + +// This is normally called by Render(). You may want to call it directly if you want to avoid calling Render() but the gain will be very minimal. +void ImGui::EndFrame() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() + IM_ASSERT(g.FrameCountEnded != g.FrameCount); // ImGui::EndFrame() called multiple times, or forgot to call ImGui::NewFrame() again + + // Render tooltip + if (g.Tooltip[0]) + { + ImGui::BeginTooltip(); + ImGui::TextUnformatted(g.Tooltip); + ImGui::EndTooltip(); + } + + // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME) + if (g.IO.ImeSetInputScreenPosFn && ImLengthSqr(g.OsImePosRequest - g.OsImePosSet) > 0.0001f) + { + g.IO.ImeSetInputScreenPosFn((int)g.OsImePosRequest.x, (int)g.OsImePosRequest.y); + g.OsImePosSet = g.OsImePosRequest; + } + + // Hide implicit "Debug" window if it hasn't been used + IM_ASSERT(g.CurrentWindowStack.Size == 1); // Mismatched Begin()/End() calls + if (g.CurrentWindow && !g.CurrentWindow->Accessed) + g.CurrentWindow->Active = false; + ImGui::End(); + + // Click to focus window and start moving (after we're done with all our widgets) + if (g.ActiveId == 0 && g.HoveredId == 0 && g.IO.MouseClicked[0]) + { + if (!(g.FocusedWindow && !g.FocusedWindow->WasActive && g.FocusedWindow->Active)) // Unless we just made a popup appear + { + if (g.HoveredRootWindow != NULL) + { + FocusWindow(g.HoveredWindow); + if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove)) + { + g.MovedWindow = g.HoveredWindow; + g.MovedWindowMoveId = g.HoveredRootWindow->MoveId; + SetActiveID(g.MovedWindowMoveId, g.HoveredRootWindow); + } + } + else if (g.FocusedWindow != NULL && GetFrontMostModalRootWindow() == NULL) + { + // Clicking on void disable focus + FocusWindow(NULL); + } + } + } + + // Sort the window list so that all child windows are after their parent + // We cannot do that on FocusWindow() because childs may not exist yet + g.WindowsSortBuffer.resize(0); + g.WindowsSortBuffer.reserve(g.Windows.Size); + for (int i = 0; i != g.Windows.Size; i++) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Active && (window->Flags & ImGuiWindowFlags_ChildWindow)) // if a child is active its parent will add it + continue; + AddWindowToSortedBuffer(g.WindowsSortBuffer, window); + } + IM_ASSERT(g.Windows.Size == g.WindowsSortBuffer.Size); // we done something wrong + g.Windows.swap(g.WindowsSortBuffer); + + // Clear Input data for next frame + g.IO.MouseWheel = 0.0f; + memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); + + g.FrameCountEnded = g.FrameCount; +} + +void ImGui::Render() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() + + if (g.FrameCountEnded != g.FrameCount) + ImGui::EndFrame(); + g.FrameCountRendered = g.FrameCount; + + // Skip render altogether if alpha is 0.0 + // Note that vertex buffers have been created and are wasted, so it is best practice that you don't create windows in the first place, or consistently respond to Begin() returning false. + if (g.Style.Alpha > 0.0f) + { + // Gather windows to render + g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsActiveWindows = 0; + for (int i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) + g.RenderDrawLists[i].resize(0); + for (int i = 0; i != g.Windows.Size; i++) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Active && window->HiddenFrames <= 0 && (window->Flags & (ImGuiWindowFlags_ChildWindow)) == 0) + { + // FIXME: Generalize this with a proper layering system so e.g. user can draw in specific layers, below text, .. + g.IO.MetricsActiveWindows++; + if (window->Flags & ImGuiWindowFlags_Popup) + AddWindowToRenderList(g.RenderDrawLists[1], window); + else if (window->Flags & ImGuiWindowFlags_Tooltip) + AddWindowToRenderList(g.RenderDrawLists[2], window); + else + AddWindowToRenderList(g.RenderDrawLists[0], window); + } + } + + // Flatten layers + int n = g.RenderDrawLists[0].Size; + int flattened_size = n; + for (int i = 1; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) + flattened_size += g.RenderDrawLists[i].Size; + g.RenderDrawLists[0].resize(flattened_size); + for (int i = 1; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) + { + ImVector& layer = g.RenderDrawLists[i]; + if (layer.empty()) + continue; + memcpy(&g.RenderDrawLists[0][n], &layer[0], layer.Size * sizeof(ImDrawList*)); + n += layer.Size; + } + + // Draw software mouse cursor if requested + if (g.IO.MouseDrawCursor) + { + const ImGuiMouseCursorData& cursor_data = g.MouseCursorData[g.MouseCursor]; + const ImVec2 pos = g.IO.MousePos - cursor_data.HotOffset; + const ImVec2 size = cursor_data.Size; + const ImTextureID tex_id = g.IO.Fonts->TexID; + g.OverlayDrawList.PushTextureID(tex_id); + g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(1,0), pos+ImVec2(1,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], IM_COL32(0,0,0,48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(2,0), pos+ImVec2(2,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], IM_COL32(0,0,0,48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], IM_COL32(0,0,0,255)); // Black border + g.OverlayDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[0], cursor_data.TexUvMax[0], IM_COL32(255,255,255,255)); // White fill + g.OverlayDrawList.PopTextureID(); + } + if (!g.OverlayDrawList.VtxBuffer.empty()) + AddDrawListToRenderList(g.RenderDrawLists[0], &g.OverlayDrawList); + + // Setup draw data + g.RenderDrawData.Valid = true; + g.RenderDrawData.CmdLists = (g.RenderDrawLists[0].Size > 0) ? &g.RenderDrawLists[0][0] : NULL; + g.RenderDrawData.CmdListsCount = g.RenderDrawLists[0].Size; + g.RenderDrawData.TotalVtxCount = g.IO.MetricsRenderVertices; + g.RenderDrawData.TotalIdxCount = g.IO.MetricsRenderIndices; + + // Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData() + if (g.RenderDrawData.CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL) + g.IO.RenderDrawListsFn(&g.RenderDrawData); + } +} + +const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end) +{ + const char* text_display_end = text; + if (!text_end) + text_end = (const char*)-1; + + while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#')) + text_display_end++; + return text_display_end; +} + +// Pass text data straight to log (without being displayed) +void ImGui::LogText(const char* fmt, ...) +{ + ImGuiContext& g = *GImGui; + if (!g.LogEnabled) + return; + + va_list args; + va_start(args, fmt); + if (g.LogFile) + { + vfprintf(g.LogFile, fmt, args); + } + else + { + g.LogClipboard->appendv(fmt, args); + } + va_end(args); +} + +// Internal version that takes a position to decide on newline placement and pad items according to their depth. +// We split text into individual lines to add current tree level padding +static void LogRenderedText(const ImVec2& ref_pos, const char* text, const char* text_end) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = ImGui::GetCurrentWindowRead(); + + if (!text_end) + text_end = ImGui::FindRenderedTextEnd(text, text_end); + + const bool log_new_line = ref_pos.y > window->DC.LogLinePosY+1; + window->DC.LogLinePosY = ref_pos.y; + + const char* text_remaining = text; + if (g.LogStartDepth > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth + g.LogStartDepth = window->DC.TreeDepth; + const int tree_depth = (window->DC.TreeDepth - g.LogStartDepth); + for (;;) + { + // Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry. + const char* line_end = text_remaining; + while (line_end < text_end) + if (*line_end == '\n') + break; + else + line_end++; + if (line_end >= text_end) + line_end = NULL; + + const bool is_first_line = (text == text_remaining); + bool is_last_line = false; + if (line_end == NULL) + { + is_last_line = true; + line_end = text_end; + } + if (line_end != NULL && !(is_last_line && (line_end - text_remaining)==0)) + { + const int char_count = (int)(line_end - text_remaining); + if (log_new_line || !is_first_line) + ImGui::LogText(IM_NEWLINE "%*s%.*s", tree_depth*4, "", char_count, text_remaining); + else + ImGui::LogText(" %.*s", char_count, text_remaining); + } + + if (is_last_line) + break; + text_remaining = line_end + 1; + } +} + +// Internal ImGui functions to render text +// RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText() +void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + // Hide anything after a '##' string + const char* text_display_end; + if (hide_text_after_hash) + { + text_display_end = FindRenderedTextEnd(text, text_end); + } + else + { + if (!text_end) + text_end = text + strlen(text); // FIXME-OPT + text_display_end = text_end; + } + + const int text_len = (int)(text_display_end - text); + if (text_len > 0) + { + window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end); + if (g.LogEnabled) + LogRenderedText(pos, text, text_display_end); + } +} + +void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + if (!text_end) + text_end = text + strlen(text); // FIXME-OPT + + const int text_len = (int)(text_end - text); + if (text_len > 0) + { + window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width); + if (g.LogEnabled) + LogRenderedText(pos, text, text_end); + } +} + +// Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges) +void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, ImGuiAlign align, const ImVec2* clip_min, const ImVec2* clip_max) +{ + // Hide anything after a '##' string + const char* text_display_end = FindRenderedTextEnd(text, text_end); + const int text_len = (int)(text_display_end - text); + if (text_len == 0) + return; + + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + // Perform CPU side clipping for single clipped element to avoid using scissor state + ImVec2 pos = pos_min; + const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f); + + if (!clip_max) clip_max = &pos_max; + bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y); + if (!clip_min) clip_min = &pos_min; else need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y); + + // Align + if (align & ImGuiAlign_Center) pos.x = ImMax(pos.x, (pos.x + pos_max.x - text_size.x) * 0.5f); + else if (align & ImGuiAlign_Right) pos.x = ImMax(pos.x, pos_max.x - text_size.x); + if (align & ImGuiAlign_VCenter) pos.y = ImMax(pos.y, (pos.y + pos_max.y - text_size.y) * 0.5f); + + // Render + if (need_clipping) + { + ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y); + window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect); + } + else + { + window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL); + } + if (g.LogEnabled) + LogRenderedText(pos, text, text_display_end); +} + +// Render a rectangle shaped with optional rounding and borders +void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding) +{ + ImGuiWindow* window = GetCurrentWindow(); + + window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding); + if (border && (window->Flags & ImGuiWindowFlags_ShowBorders)) + { + window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding); + } +} + +// Render a triangle to denote expanded/collapsed state +void ImGui::RenderCollapseTriangle(ImVec2 p_min, bool is_open, float scale, bool shadow) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + const float h = g.FontSize * 1.00f; + const float r = h * 0.40f * scale; + ImVec2 center = p_min + ImVec2(h*0.50f, h*0.50f*scale); + + ImVec2 a, b, c; + if (is_open) + { + center.y -= r*0.25f; + a = center + ImVec2(0,1)*r; + b = center + ImVec2(-0.866f,-0.5f)*r; + c = center + ImVec2(0.866f,-0.5f)*r; + } + else + { + a = center + ImVec2(1,0)*r; + b = center + ImVec2(-0.500f,0.866f)*r; + c = center + ImVec2(-0.500f,-0.866f)*r; + } + + if (shadow && (window->Flags & ImGuiWindowFlags_ShowBorders) != 0) + window->DrawList->AddTriangleFilled(a+ImVec2(2,2), b+ImVec2(2,2), c+ImVec2(2,2), GetColorU32(ImGuiCol_BorderShadow)); + window->DrawList->AddTriangleFilled(a, b, c, GetColorU32(ImGuiCol_Text)); +} + +void ImGui::RenderBullet(ImVec2 pos) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DrawList->AddCircleFilled(pos, GImGui->FontSize*0.20f, GetColorU32(ImGuiCol_Text), 8); +} + +void ImGui::RenderCheckMark(ImVec2 pos, ImU32 col) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + ImVec2 a, b, c; + float start_x = (float)(int)(g.FontSize * 0.307f + 0.5f); + float rem_third = (float)(int)((g.FontSize - start_x) / 3.0f); + a.x = pos.x + 0.5f + start_x; + b.x = a.x + rem_third; + c.x = a.x + rem_third * 3.0f; + b.y = pos.y - 1.0f + (float)(int)(g.Font->Ascent * (g.FontSize / g.Font->FontSize) + 0.5f) + (float)(int)(g.Font->DisplayOffset.y); + a.y = b.y - rem_third; + c.y = b.y - rem_third * 2.0f; + + window->DrawList->PathLineTo(a); + window->DrawList->PathLineTo(b); + window->DrawList->PathLineTo(c); + window->DrawList->PathStroke(col, false); +} + +// Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker. +// CalcTextSize("") should return ImVec2(0.0f, GImGui->FontSize) +ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) +{ + ImGuiContext& g = *GImGui; + + const char* text_display_end; + if (hide_text_after_double_hash) + text_display_end = FindRenderedTextEnd(text, text_end); // Hide anything after a '##' string + else + text_display_end = text_end; + + ImFont* font = g.Font; + const float font_size = g.FontSize; + if (text == text_display_end) + return ImVec2(0.0f, font_size); + ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL); + + // Cancel out character spacing for the last character of a line (it is baked into glyph->XAdvance field) + const float font_scale = font_size / font->FontSize; + const float character_spacing_x = 1.0f * font_scale; + if (text_size.x > 0.0f) + text_size.x -= character_spacing_x; + text_size.x = (float)(int)(text_size.x + 0.95f); + + return text_size; +} + +// Helper to calculate coarse clipping of large list of evenly sized items. +// NB: Prefer using the ImGuiListClipper higher-level helper if you can! Read comments and instructions there on how those use this sort of pattern. +// NB: 'items_count' is only used to clamp the result, if you don't know your count you can use INT_MAX +void ImGui::CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindowRead(); + if (g.LogEnabled) + { + // If logging is active, do not perform any clipping + *out_items_display_start = 0; + *out_items_display_end = items_count; + return; + } + if (window->SkipItems) + { + *out_items_display_start = *out_items_display_end = 0; + return; + } + + const ImVec2 pos = window->DC.CursorPos; + int start = (int)((window->ClipRect.Min.y - pos.y) / items_height); + int end = (int)((window->ClipRect.Max.y - pos.y) / items_height); + start = ImClamp(start, 0, items_count); + end = ImClamp(end + 1, start, items_count); + *out_items_display_start = start; + *out_items_display_end = end; +} + +// Find window given position, search front-to-back +// FIXME: Note that we have a lag here because WindowRectClipped is updated in Begin() so windows moved by user via SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is called, aka before the next Begin(). Moving window thankfully isn't affected. +static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs) +{ + ImGuiContext& g = *GImGui; + for (int i = g.Windows.Size-1; i >= 0; i--) + { + ImGuiWindow* window = g.Windows[i]; + if (!window->Active) + continue; + if (window->Flags & ImGuiWindowFlags_NoInputs) + continue; + if (excluding_childs && (window->Flags & ImGuiWindowFlags_ChildWindow) != 0) + continue; + + // Using the clipped AABB so a child window will typically be clipped by its parent. + ImRect bb(window->WindowRectClipped.Min - g.Style.TouchExtraPadding, window->WindowRectClipped.Max + g.Style.TouchExtraPadding); + if (bb.Contains(pos)) + return window; + } + return NULL; +} + +// Test if mouse cursor is hovering given rectangle +// NB- Rectangle is clipped by our current clip setting +// NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding) +bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindowRead(); + + // Clip + ImRect rect_clipped(r_min, r_max); + if (clip) + rect_clipped.Clip(window->ClipRect); + + // Expand for touch input + const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding); + return rect_for_touch.Contains(g.IO.MousePos); +} + +bool ImGui::IsMouseHoveringWindow() +{ + ImGuiContext& g = *GImGui; + return g.HoveredWindow == g.CurrentWindow; +} + +bool ImGui::IsMouseHoveringAnyWindow() +{ + ImGuiContext& g = *GImGui; + return g.HoveredWindow != NULL; +} + +bool ImGui::IsPosHoveringAnyWindow(const ImVec2& pos) +{ + return FindHoveredWindow(pos, false) != NULL; +} + +static bool IsKeyPressedMap(ImGuiKey key, bool repeat) +{ + const int key_index = GImGui->IO.KeyMap[key]; + return ImGui::IsKeyPressed(key_index, repeat); +} + +int ImGui::GetKeyIndex(ImGuiKey key) +{ + IM_ASSERT(key >= 0 && key < ImGuiKey_COUNT); + return GImGui->IO.KeyMap[key]; +} + +bool ImGui::IsKeyDown(int key_index) +{ + if (key_index < 0) return false; + IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(GImGui->IO.KeysDown)); + return GImGui->IO.KeysDown[key_index]; +} + +bool ImGui::IsKeyPressed(int key_index, bool repeat) +{ + ImGuiContext& g = *GImGui; + if (key_index < 0) return false; + IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown)); + const float t = g.IO.KeysDownDuration[key_index]; + if (t == 0.0f) + return true; + + if (repeat && t > g.IO.KeyRepeatDelay) + { + float delay = g.IO.KeyRepeatDelay, rate = g.IO.KeyRepeatRate; + if ((fmodf(t - delay, rate) > rate*0.5f) != (fmodf(t - delay - g.IO.DeltaTime, rate) > rate*0.5f)) + return true; + } + return false; +} + +bool ImGui::IsKeyReleased(int key_index) +{ + ImGuiContext& g = *GImGui; + if (key_index < 0) return false; + IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown)); + if (g.IO.KeysDownDurationPrev[key_index] >= 0.0f && !g.IO.KeysDown[key_index]) + return true; + return false; +} + +bool ImGui::IsMouseDown(int button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseDown[button]; +} + +bool ImGui::IsMouseClicked(int button, bool repeat) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + const float t = g.IO.MouseDownDuration[button]; + if (t == 0.0f) + return true; + + if (repeat && t > g.IO.KeyRepeatDelay) + { + float delay = g.IO.KeyRepeatDelay, rate = g.IO.KeyRepeatRate; + if ((fmodf(t - delay, rate) > rate*0.5f) != (fmodf(t - delay - g.IO.DeltaTime, rate) > rate*0.5f)) + return true; + } + + return false; +} + +bool ImGui::IsMouseReleased(int button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseReleased[button]; +} + +bool ImGui::IsMouseDoubleClicked(int button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseDoubleClicked[button]; +} + +bool ImGui::IsMouseDragging(int button, float lock_threshold) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + if (!g.IO.MouseDown[button]) + return false; + if (lock_threshold < 0.0f) + lock_threshold = g.IO.MouseDragThreshold; + return g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold; +} + +ImVec2 ImGui::GetMousePos() +{ + return GImGui->IO.MousePos; +} + +// NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed! +ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup() +{ + ImGuiContext& g = *GImGui; + if (g.CurrentPopupStack.Size > 0) + return g.OpenPopupStack[g.CurrentPopupStack.Size-1].MousePosOnOpen; + return g.IO.MousePos; +} + +ImVec2 ImGui::GetMouseDragDelta(int button, float lock_threshold) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + if (lock_threshold < 0.0f) + lock_threshold = g.IO.MouseDragThreshold; + if (g.IO.MouseDown[button]) + if (g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold) + return g.IO.MousePos - g.IO.MouseClickedPos[button]; // Assume we can only get active with left-mouse button (at the moment). + return ImVec2(0.0f, 0.0f); +} + +void ImGui::ResetMouseDragDelta(int button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + // NB: We don't need to reset g.IO.MouseDragMaxDistanceSqr + g.IO.MouseClickedPos[button] = g.IO.MousePos; +} + +ImGuiMouseCursor ImGui::GetMouseCursor() +{ + return GImGui->MouseCursor; +} + +void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type) +{ + GImGui->MouseCursor = cursor_type; +} + +void ImGui::CaptureKeyboardFromApp(bool capture) +{ + GImGui->CaptureKeyboardNextFrame = capture ? 1 : 0; +} + +void ImGui::CaptureMouseFromApp(bool capture) +{ + GImGui->CaptureMouseNextFrame = capture ? 1 : 0; +} + +bool ImGui::IsItemHovered() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.LastItemHoveredAndUsable; +} + +bool ImGui::IsItemHoveredRect() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.LastItemHoveredRect; +} + +bool ImGui::IsItemActive() +{ + ImGuiContext& g = *GImGui; + if (g.ActiveId) + { + ImGuiWindow* window = GetCurrentWindowRead(); + return g.ActiveId == window->DC.LastItemId; + } + return false; +} + +bool ImGui::IsItemClicked(int mouse_button) +{ + return IsMouseClicked(mouse_button) && IsItemHovered(); +} + +bool ImGui::IsAnyItemHovered() +{ + return GImGui->HoveredId != 0 || GImGui->HoveredIdPreviousFrame != 0; +} + +bool ImGui::IsAnyItemActive() +{ + return GImGui->ActiveId != 0; +} + +bool ImGui::IsItemVisible() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + ImRect r(window->ClipRect); + return r.Overlaps(window->DC.LastItemRect); +} + +// Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority. +void ImGui::SetItemAllowOverlap() +{ + ImGuiContext& g = *GImGui; + if (g.HoveredId == g.CurrentWindow->DC.LastItemId) + g.HoveredIdAllowOverlap = true; + if (g.ActiveId == g.CurrentWindow->DC.LastItemId) + g.ActiveIdAllowOverlap = true; +} + +ImVec2 ImGui::GetItemRectMin() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.LastItemRect.Min; +} + +ImVec2 ImGui::GetItemRectMax() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.LastItemRect.Max; +} + +ImVec2 ImGui::GetItemRectSize() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.LastItemRect.GetSize(); +} + +ImVec2 ImGui::CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge, float outward) +{ + ImGuiWindow* window = GetCurrentWindowRead(); + ImRect rect = window->DC.LastItemRect; + rect.Expand(outward); + return rect.GetClosestPoint(pos, on_edge); +} + +// Tooltip is stored and turned into a BeginTooltip()/EndTooltip() sequence at the end of the frame. Each call override previous value. +void ImGui::SetTooltipV(const char* fmt, va_list args) +{ + ImGuiContext& g = *GImGui; + ImFormatStringV(g.Tooltip, IM_ARRAYSIZE(g.Tooltip), fmt, args); +} + +void ImGui::SetTooltip(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + SetTooltipV(fmt, args); + va_end(args); +} + +static ImRect GetVisibleRect() +{ + ImGuiContext& g = *GImGui; + if (g.IO.DisplayVisibleMin.x != g.IO.DisplayVisibleMax.x && g.IO.DisplayVisibleMin.y != g.IO.DisplayVisibleMax.y) + return ImRect(g.IO.DisplayVisibleMin, g.IO.DisplayVisibleMax); + return ImRect(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y); +} + +void ImGui::BeginTooltip() +{ + ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; + ImGui::Begin("##Tooltip", NULL, flags); +} + +void ImGui::EndTooltip() +{ + IM_ASSERT(GetCurrentWindowRead()->Flags & ImGuiWindowFlags_Tooltip); // Mismatched BeginTooltip()/EndTooltip() calls + ImGui::End(); +} + +static bool IsPopupOpen(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + const bool is_open = g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupId == id; + return is_open; +} + +// Mark popup as open (toggle toward open state). +// Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. +// Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). +// One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL) +void ImGui::OpenPopupEx(const char* str_id, bool reopen_existing) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiID id = window->GetID(str_id); + int current_stack_size = g.CurrentPopupStack.Size; + ImGuiPopupRef popup_ref = ImGuiPopupRef(id, window, window->GetID("##menus"), g.IO.MousePos); // Tagged as new ref because constructor sets Window to NULL (we are passing the ParentWindow info here) + if (g.OpenPopupStack.Size < current_stack_size + 1) + g.OpenPopupStack.push_back(popup_ref); + else if (reopen_existing || g.OpenPopupStack[current_stack_size].PopupId != id) + { + g.OpenPopupStack.resize(current_stack_size+1); + g.OpenPopupStack[current_stack_size] = popup_ref; + } +} + +void ImGui::OpenPopup(const char* str_id) +{ + ImGui::OpenPopupEx(str_id, false); +} + +static void CloseInactivePopups() +{ + ImGuiContext& g = *GImGui; + if (g.OpenPopupStack.empty()) + return; + + // When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it. + // Don't close our own child popup windows + int n = 0; + if (g.FocusedWindow) + { + for (n = 0; n < g.OpenPopupStack.Size; n++) + { + ImGuiPopupRef& popup = g.OpenPopupStack[n]; + if (!popup.Window) + continue; + IM_ASSERT((popup.Window->Flags & ImGuiWindowFlags_Popup) != 0); + if (popup.Window->Flags & ImGuiWindowFlags_ChildWindow) + continue; + + bool has_focus = false; + for (int m = n; m < g.OpenPopupStack.Size && !has_focus; m++) + has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == g.FocusedWindow->RootWindow); + if (!has_focus) + break; + } + } + if (n < g.OpenPopupStack.Size) // This test is not required but it allows to set a useful breakpoint on the line below + g.OpenPopupStack.resize(n); +} + +static ImGuiWindow* GetFrontMostModalRootWindow() +{ + ImGuiContext& g = *GImGui; + for (int n = g.OpenPopupStack.Size-1; n >= 0; n--) + if (ImGuiWindow* front_most_popup = g.OpenPopupStack.Data[n].Window) + if (front_most_popup->Flags & ImGuiWindowFlags_Modal) + return front_most_popup; + return NULL; +} + +static void ClosePopupToLevel(int remaining) +{ + ImGuiContext& g = *GImGui; + if (remaining > 0) + ImGui::FocusWindow(g.OpenPopupStack[remaining-1].Window); + else + ImGui::FocusWindow(g.OpenPopupStack[0].ParentWindow); + g.OpenPopupStack.resize(remaining); +} + +static void ClosePopup(ImGuiID id) +{ + if (!IsPopupOpen(id)) + return; + ImGuiContext& g = *GImGui; + ClosePopupToLevel(g.OpenPopupStack.Size - 1); +} + +// Close the popup we have begin-ed into. +void ImGui::CloseCurrentPopup() +{ + ImGuiContext& g = *GImGui; + int popup_idx = g.CurrentPopupStack.Size - 1; + if (popup_idx < 0 || popup_idx > g.OpenPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupId != g.OpenPopupStack[popup_idx].PopupId) + return; + while (popup_idx > 0 && g.OpenPopupStack[popup_idx].Window && (g.OpenPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu)) + popup_idx--; + ClosePopupToLevel(popup_idx); +} + +static inline void ClearSetNextWindowData() +{ + ImGuiContext& g = *GImGui; + g.SetNextWindowPosCond = g.SetNextWindowSizeCond = g.SetNextWindowContentSizeCond = g.SetNextWindowCollapsedCond = 0; + g.SetNextWindowSizeConstraint = g.SetNextWindowFocus = false; +} + +static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + const ImGuiID id = window->GetID(str_id); + if (!IsPopupOpen(id)) + { + ClearSetNextWindowData(); // We behave like Begin() and need to consume those values + return false; + } + + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; + + char name[32]; + if (flags & ImGuiWindowFlags_ChildMenu) + ImFormatString(name, 20, "##menu_%d", g.CurrentPopupStack.Size); // Recycle windows based on depth + else + ImFormatString(name, 20, "##popup_%08x", id); // Not recycling, so we can close/open during the same frame + + bool is_open = ImGui::Begin(name, NULL, flags); + if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) + g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders; + if (!is_open) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + ImGui::EndPopup(); + + return is_open; +} + +bool ImGui::BeginPopup(const char* str_id) +{ + if (GImGui->OpenPopupStack.Size <= GImGui->CurrentPopupStack.Size) // Early out for performance + { + ClearSetNextWindowData(); // We behave like Begin() and need to consume those values + return false; + } + return BeginPopupEx(str_id, ImGuiWindowFlags_ShowBorders); +} + +bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags extra_flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + const ImGuiID id = window->GetID(name); + if (!IsPopupOpen(id)) + { + ClearSetNextWindowData(); // We behave like Begin() and need to consume those values + return false; + } + + ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings; + bool is_open = ImGui::Begin(name, p_open, flags); + if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + { + ImGui::EndPopup(); + if (is_open) + ClosePopup(id); + return false; + } + + return is_open; +} + +void ImGui::EndPopup() +{ + ImGuiWindow* window = GetCurrentWindow(); + IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls + IM_ASSERT(GImGui->CurrentPopupStack.Size > 0); + ImGui::End(); + if (!(window->Flags & ImGuiWindowFlags_Modal)) + ImGui::PopStyleVar(); +} + +// This is a helper to handle the most simple case of associating one named popup to one given widget. +// 1. If you have many possible popups (for different "instances" of a same widget, or for wholly different widgets), you may be better off handling +// this yourself so you can store data relative to the widget that opened the popup instead of choosing different popup identifiers. +// 2. If you want right-clicking on the same item to reopen the popup at new location, use the same code replacing IsItemHovered() with IsItemHoveredRect() +// and passing true to the OpenPopupEx(). +// Because: hovering an item in a window below the popup won't normally trigger is hovering behavior/coloring. The pattern of ignoring the fact that +// the item isn't interactable (because it is blocked by the active popup) may useful in some situation when e.g. large canvas as one item, content of menu +// driven by click position. +bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) +{ + if (IsItemHovered() && IsMouseClicked(mouse_button)) + OpenPopupEx(str_id, false); + return BeginPopup(str_id); +} + +bool ImGui::BeginPopupContextWindow(bool also_over_items, const char* str_id, int mouse_button) +{ + if (!str_id) str_id = "window_context_menu"; + if (IsMouseHoveringWindow() && IsMouseClicked(mouse_button)) + if (also_over_items || !IsAnyItemHovered()) + OpenPopupEx(str_id, true); + return BeginPopup(str_id); +} + +bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) +{ + if (!str_id) str_id = "void_context_menu"; + if (!IsMouseHoveringAnyWindow() && IsMouseClicked(mouse_button)) + OpenPopupEx(str_id, true); + return BeginPopup(str_id); +} + +bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow; + + const ImVec2 content_avail = GetContentRegionAvail(); + ImVec2 size = ImFloor(size_arg); + if (size.x <= 0.0f) + { + if (size.x == 0.0f) + flags |= ImGuiWindowFlags_ChildWindowAutoFitX; + size.x = ImMax(content_avail.x, 4.0f) - fabsf(size.x); // Arbitrary minimum zero-ish child size of 4.0f (0.0f causing too much issues) + } + if (size.y <= 0.0f) + { + if (size.y == 0.0f) + flags |= ImGuiWindowFlags_ChildWindowAutoFitY; + size.y = ImMax(content_avail.y, 4.0f) - fabsf(size.y); + } + if (border) + flags |= ImGuiWindowFlags_ShowBorders; + flags |= extra_flags; + + char title[256]; + ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s", window->Name, str_id); + + bool ret = ImGui::Begin(title, NULL, size, -1.0f, flags); + + if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) + GetCurrentWindow()->Flags &= ~ImGuiWindowFlags_ShowBorders; + + return ret; +} + +bool ImGui::BeginChild(ImGuiID id, const ImVec2& size, bool border, ImGuiWindowFlags extra_flags) +{ + char str_id[32]; + ImFormatString(str_id, IM_ARRAYSIZE(str_id), "child_%08x", id); + bool ret = ImGui::BeginChild(str_id, size, border, extra_flags); + return ret; +} + +void ImGui::EndChild() +{ + ImGuiWindow* window = GetCurrentWindow(); + + IM_ASSERT(window->Flags & ImGuiWindowFlags_ChildWindow); // Mismatched BeginChild()/EndChild() callss + if ((window->Flags & ImGuiWindowFlags_ComboBox) || window->BeginCount > 1) + { + ImGui::End(); + } + else + { + // When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting. + ImVec2 sz = GetWindowSize(); + if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitX) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f + sz.x = ImMax(4.0f, sz.x); + if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitY) + sz.y = ImMax(4.0f, sz.y); + + ImGui::End(); + + window = GetCurrentWindow(); + ImRect bb(window->DC.CursorPos, window->DC.CursorPos + sz); + ItemSize(sz); + ItemAdd(bb, NULL); + } +} + +// Helper to create a child window / scrolling region that looks like a normal widget frame. +bool ImGui::BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags extra_flags) +{ + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, style.Colors[ImGuiCol_FrameBg]); + ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, style.FrameRounding); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); + return ImGui::BeginChild(id, size, (g.CurrentWindow->Flags & ImGuiWindowFlags_ShowBorders) ? true : false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); +} + +void ImGui::EndChildFrame() +{ + ImGui::EndChild(); + ImGui::PopStyleVar(2); + ImGui::PopStyleColor(); +} + +// Save and compare stack sizes on Begin()/End() to detect usage errors +static void CheckStacksSize(ImGuiWindow* window, bool write) +{ + // NOT checking: DC.ItemWidth, DC.AllowKeyboardFocus, DC.ButtonRepeat, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin) + ImGuiContext& g = *GImGui; + int* p_backup = &window->DC.StackSizesBackup[0]; + { int current = window->IDStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushID/PopID Mismatch!"); p_backup++; } // User forgot PopID() + { int current = window->DC.GroupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginGroup/EndGroup Mismatch!"); p_backup++; } // User forgot EndGroup() + { int current = g.CurrentPopupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginMenu/EndMenu or BeginPopup/EndPopup Mismatch"); p_backup++; }// User forgot EndPopup()/EndMenu() + { int current = g.ColorModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleColor/PopStyleColor Mismatch!"); p_backup++; } // User forgot PopStyleColor() + { int current = g.StyleModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleVar/PopStyleVar Mismatch!"); p_backup++; } // User forgot PopStyleVar() + { int current = g.FontStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushFont/PopFont Mismatch!"); p_backup++; } // User forgot PopFont() + IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup)); +} + +static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& r_inner) +{ + const ImGuiStyle& style = GImGui->Style; + + // Clamp into visible area while not overlapping the cursor. Safety padding is optional if our popup size won't fit without it. + ImVec2 safe_padding = style.DisplaySafeAreaPadding; + ImRect r_outer(GetVisibleRect()); + r_outer.Reduce(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? safe_padding.y : 0.0f)); + ImVec2 base_pos_clamped = ImClamp(base_pos, r_outer.Min, r_outer.Max - size); + + for (int n = (*last_dir != -1) ? -1 : 0; n < 4; n++) // Last, Right, down, up, left. (Favor last used direction). + { + const int dir = (n == -1) ? *last_dir : n; + ImRect rect(dir == 0 ? r_inner.Max.x : r_outer.Min.x, dir == 1 ? r_inner.Max.y : r_outer.Min.y, dir == 3 ? r_inner.Min.x : r_outer.Max.x, dir == 2 ? r_inner.Min.y : r_outer.Max.y); + if (rect.GetWidth() < size.x || rect.GetHeight() < size.y) + continue; + *last_dir = dir; + return ImVec2(dir == 0 ? r_inner.Max.x : dir == 3 ? r_inner.Min.x - size.x : base_pos_clamped.x, dir == 1 ? r_inner.Max.y : dir == 2 ? r_inner.Min.y - size.y : base_pos_clamped.y); + } + + // Fallback, try to keep within display + *last_dir = -1; + ImVec2 pos = base_pos; + pos.x = ImMax(ImMin(pos.x + size.x, r_outer.Max.x) - size.x, r_outer.Min.x); + pos.y = ImMax(ImMin(pos.y + size.y, r_outer.Max.y) - size.y, r_outer.Min.y); + return pos; +} + +ImGuiWindow* ImGui::FindWindowByName(const char* name) +{ + // FIXME-OPT: Store sorted hashes -> pointers so we can do a bissection in a contiguous block + ImGuiContext& g = *GImGui; + ImGuiID id = ImHash(name, 0); + for (int i = 0; i < g.Windows.Size; i++) + if (g.Windows[i]->ID == id) + return g.Windows[i]; + return NULL; +} + +static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags) +{ + ImGuiContext& g = *GImGui; + + // Create window the first time + ImGuiWindow* window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow)); + IM_PLACEMENT_NEW(window) ImGuiWindow(name); + window->Flags = flags; + + if (flags & ImGuiWindowFlags_NoSavedSettings) + { + // User can disable loading and saving of settings. Tooltip and child windows also don't store settings. + window->Size = window->SizeFull = size; + } + else + { + // Retrieve settings from .ini file + // Use SetWindowPos() or SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. + window->PosFloat = ImVec2(60, 60); + window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); + + ImGuiIniData* settings = FindWindowSettings(name); + if (!settings) + { + settings = AddWindowSettings(name); + } + else + { + window->SetWindowPosAllowFlags &= ~ImGuiSetCond_FirstUseEver; + window->SetWindowSizeAllowFlags &= ~ImGuiSetCond_FirstUseEver; + window->SetWindowCollapsedAllowFlags &= ~ImGuiSetCond_FirstUseEver; + } + + if (settings->Pos.x != FLT_MAX) + { + window->PosFloat = settings->Pos; + window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); + window->Collapsed = settings->Collapsed; + } + + if (ImLengthSqr(settings->Size) > 0.00001f && !(flags & ImGuiWindowFlags_NoResize)) + size = settings->Size; + window->Size = window->SizeFull = size; + } + + if ((flags & ImGuiWindowFlags_AlwaysAutoResize) != 0) + { + window->AutoFitFramesX = window->AutoFitFramesY = 2; + window->AutoFitOnlyGrows = false; + } + else + { + if (window->Size.x <= 0.0f) + window->AutoFitFramesX = 2; + if (window->Size.y <= 0.0f) + window->AutoFitFramesY = 2; + window->AutoFitOnlyGrows = (window->AutoFitFramesX > 0) || (window->AutoFitFramesY > 0); + } + + if (flags & ImGuiWindowFlags_NoBringToFrontOnFocus) + g.Windows.insert(g.Windows.begin(), window); // Quite slow but rare and only once + else + g.Windows.push_back(window); + return window; +} + +static void ApplySizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) +{ + ImGuiContext& g = *GImGui; + if (g.SetNextWindowSizeConstraint) + { + // Using -1,-1 on either X/Y axis to preserve the current size. + ImRect cr = g.SetNextWindowSizeConstraintRect; + new_size.x = (cr.Min.x >= 0 && cr.Max.x >= 0) ? ImClamp(new_size.x, cr.Min.x, cr.Max.x) : window->SizeFull.x; + new_size.y = (cr.Min.y >= 0 && cr.Max.y >= 0) ? ImClamp(new_size.y, cr.Min.y, cr.Max.y) : window->SizeFull.y; + if (g.SetNextWindowSizeConstraintCallback) + { + ImGuiSizeConstraintCallbackData data; + data.UserData = g.SetNextWindowSizeConstraintCallbackUserData; + data.Pos = window->Pos; + data.CurrentSize = window->SizeFull; + data.DesiredSize = new_size; + g.SetNextWindowSizeConstraintCallback(&data); + new_size = data.DesiredSize; + } + } + if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize))) + new_size = ImMax(new_size, g.Style.WindowMinSize); + window->SizeFull = new_size; +} + +// Push a new ImGui window to add widgets to. +// - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. +// - Begin/End can be called multiple times during the frame with the same window name to append content. +// - 'size_on_first_use' for a regular window denote the initial size for first-time creation (no saved data) and isn't that useful. Use SetNextWindowSize() prior to calling Begin() for more flexible window manipulation. +// - The window name is used as a unique identifier to preserve window information across frames (and save rudimentary information to the .ini file). +// You can use the "##" or "###" markers to use the same label with different id, or same id with different label. See documentation at the top of this file. +// - Return false when window is collapsed, so you can early out in your code. You always need to call ImGui::End() even if false is returned. +// - Passing 'bool* p_open' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed. +// - Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiSetCond_FirstUseEver) prior to calling Begin(). +bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) +{ + return ImGui::Begin(name, p_open, ImVec2(0.f, 0.f), -1.0f, flags); +} + +bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags) +{ + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + IM_ASSERT(name != NULL); // Window name required + IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() + IM_ASSERT(g.FrameCountEnded != g.FrameCount); // Called ImGui::Render() or ImGui::EndFrame() and haven't called ImGui::NewFrame() again yet + + if (flags & ImGuiWindowFlags_NoInputs) + flags |= ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; + + // Find or create + bool window_is_new = false; + ImGuiWindow* window = FindWindowByName(name); + if (!window) + { + window = CreateNewWindow(name, size_on_first_use, flags); + window_is_new = true; + } + + const int current_frame = ImGui::GetFrameCount(); + const bool first_begin_of_the_frame = (window->LastFrameActive != current_frame); + if (first_begin_of_the_frame) + window->Flags = (ImGuiWindowFlags)flags; + else + flags = window->Flags; + + // Add to stack + ImGuiWindow* parent_window = !g.CurrentWindowStack.empty() ? g.CurrentWindowStack.back() : NULL; + g.CurrentWindowStack.push_back(window); + SetCurrentWindow(window); + CheckStacksSize(window, true); + IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow)); + + bool window_was_active = (window->LastFrameActive == current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on + if (flags & ImGuiWindowFlags_Popup) + { + ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; + window_was_active &= (window->PopupId == popup_ref.PopupId); + window_was_active &= (window == popup_ref.Window); + popup_ref.Window = window; + g.CurrentPopupStack.push_back(popup_ref); + window->PopupId = popup_ref.PopupId; + } + + const bool window_appearing_after_being_hidden = (window->HiddenFrames == 1); + + // Process SetNextWindow***() calls + bool window_pos_set_by_api = false, window_size_set_by_api = false; + if (g.SetNextWindowPosCond) + { + const ImVec2 backup_cursor_pos = window->DC.CursorPos; // FIXME: not sure of the exact reason of this saving/restore anymore :( need to look into that. + if (!window_was_active || window_appearing_after_being_hidden) window->SetWindowPosAllowFlags |= ImGuiSetCond_Appearing; + window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0; + if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosVal - ImVec2(-FLT_MAX,-FLT_MAX)) < 0.001f) + { + window->SetWindowPosCenterWanted = true; // May be processed on the next frame if this is our first frame and we are measuring size + window->SetWindowPosAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing); + } + else + { + SetWindowPos(window, g.SetNextWindowPosVal, g.SetNextWindowPosCond); + } + window->DC.CursorPos = backup_cursor_pos; + g.SetNextWindowPosCond = 0; + } + if (g.SetNextWindowSizeCond) + { + if (!window_was_active || window_appearing_after_being_hidden) window->SetWindowSizeAllowFlags |= ImGuiSetCond_Appearing; + window_size_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0; + SetWindowSize(window, g.SetNextWindowSizeVal, g.SetNextWindowSizeCond); + g.SetNextWindowSizeCond = 0; + } + if (g.SetNextWindowContentSizeCond) + { + window->SizeContentsExplicit = g.SetNextWindowContentSizeVal; + g.SetNextWindowContentSizeCond = 0; + } + else if (first_begin_of_the_frame) + { + window->SizeContentsExplicit = ImVec2(0.0f, 0.0f); + } + if (g.SetNextWindowCollapsedCond) + { + if (!window_was_active || window_appearing_after_being_hidden) window->SetWindowCollapsedAllowFlags |= ImGuiSetCond_Appearing; + SetWindowCollapsed(window, g.SetNextWindowCollapsedVal, g.SetNextWindowCollapsedCond); + g.SetNextWindowCollapsedCond = 0; + } + if (g.SetNextWindowFocus) + { + ImGui::SetWindowFocus(); + g.SetNextWindowFocus = false; + } + + // Update known root window (if we are a child window, otherwise window == window->RootWindow) + int root_idx, root_non_popup_idx; + for (root_idx = g.CurrentWindowStack.Size - 1; root_idx > 0; root_idx--) + if (!(g.CurrentWindowStack[root_idx]->Flags & ImGuiWindowFlags_ChildWindow)) + break; + for (root_non_popup_idx = root_idx; root_non_popup_idx > 0; root_non_popup_idx--) + if (!(g.CurrentWindowStack[root_non_popup_idx]->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup))) + break; + window->ParentWindow = parent_window; + window->RootWindow = g.CurrentWindowStack[root_idx]; + window->RootNonPopupWindow = g.CurrentWindowStack[root_non_popup_idx]; // This is merely for displaying the TitleBgActive color. + + // When reusing window again multiple times a frame, just append content (don't need to setup again) + if (first_begin_of_the_frame) + { + window->Active = true; + window->IndexWithinParent = 0; + window->BeginCount = 0; + window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX); + window->LastFrameActive = current_frame; + window->IDStack.resize(1); + + // Clear draw list, setup texture, outer clipping rectangle + window->DrawList->Clear(); + window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); + ImRect fullscreen_rect(GetVisibleRect()); + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_ComboBox|ImGuiWindowFlags_Popup))) + PushClipRect(parent_window->ClipRect.Min, parent_window->ClipRect.Max, true); + else + PushClipRect(fullscreen_rect.Min, fullscreen_rect.Max, true); + + if (!window_was_active) + { + // Popup first latch mouse position, will position itself when it appears next frame + window->AutoPosLastDirection = -1; + if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) + window->PosFloat = g.IO.MousePos; + } + + // Collapse window by double-clicking on title bar + // At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing + if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse)) + { + ImRect title_bar_rect = window->TitleBarRect(); + if (g.HoveredWindow == window && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseDoubleClicked[0]) + { + window->Collapsed = !window->Collapsed; + if (!(flags & ImGuiWindowFlags_NoSavedSettings)) + MarkSettingsDirty(); + FocusWindow(window); + } + } + else + { + window->Collapsed = false; + } + + // SIZE + + // Save contents size from last frame for auto-fitting (unless explicitly specified) + window->SizeContents.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.x - window->Pos.x) + window->Scroll.x)); + window->SizeContents.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.y - window->Pos.y) + window->Scroll.y)); + + // Hide popup/tooltip window when first appearing while we measure size (because we recycle them) + if (window->HiddenFrames > 0) + window->HiddenFrames--; + if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0 && !window_was_active) + { + window->HiddenFrames = 1; + if (flags & ImGuiWindowFlags_AlwaysAutoResize) + { + if (!window_size_set_by_api) + window->Size = window->SizeFull = ImVec2(0.f, 0.f); + window->SizeContents = ImVec2(0.f, 0.f); + } + } + + // Lock window padding so that altering the ShowBorders flag for children doesn't have side-effects. + window->WindowPadding = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) ? ImVec2(0,0) : style.WindowPadding; + + // Calculate auto-fit size + ImVec2 size_auto_fit; + if ((flags & ImGuiWindowFlags_Tooltip) != 0) + { + // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. + size_auto_fit = window->SizeContents + window->WindowPadding - ImVec2(0.0f, style.ItemSpacing.y); + } + else + { + size_auto_fit = ImClamp(window->SizeContents + window->WindowPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); + + // Handling case of auto fit window not fitting in screen on one axis, we are growing auto fit size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. + if (size_auto_fit.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) + size_auto_fit.y += style.ScrollbarSize; + if (size_auto_fit.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) + size_auto_fit.x += style.ScrollbarSize; + size_auto_fit.y = ImMax(size_auto_fit.y - style.ItemSpacing.y, 0.0f); + } + + // Handle automatic resize + if (window->Collapsed) + { + // We still process initial auto-fit on collapsed windows to get a window width, + // But otherwise we don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed. + if (window->AutoFitFramesX > 0) + window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; + if (window->AutoFitFramesY > 0) + window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; + } + else + { + if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && !window_size_set_by_api) + { + window->SizeFull = size_auto_fit; + } + else if ((window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) && !window_size_set_by_api) + { + // Auto-fit only grows during the first few frames + if (window->AutoFitFramesX > 0) + window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; + if (window->AutoFitFramesY > 0) + window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; + if (!(flags & ImGuiWindowFlags_NoSavedSettings)) + MarkSettingsDirty(); + } + } + + // Apply minimum/maximum window size constraints and final size + ApplySizeFullWithConstraint(window, window->SizeFull); + window->Size = window->Collapsed ? window->TitleBarRect().GetSize() : window->SizeFull; + + // POSITION + + // Position child window + if (flags & ImGuiWindowFlags_ChildWindow) + { + window->IndexWithinParent = parent_window->DC.ChildWindows.Size; + parent_window->DC.ChildWindows.push_back(window); + } + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) + { + window->Pos = window->PosFloat = parent_window->DC.CursorPos; + window->Size = window->SizeFull = size_on_first_use; // NB: argument name 'size_on_first_use' misleading here, it's really just 'size' as provided by user passed via BeginChild()->Begin(). + } + + bool window_pos_center = false; + window_pos_center |= (window->SetWindowPosCenterWanted && window->HiddenFrames == 0); + window_pos_center |= ((flags & ImGuiWindowFlags_Modal) && !window_pos_set_by_api && window_appearing_after_being_hidden); + if (window_pos_center) + { + // Center (any sort of window) + SetWindowPos(ImMax(style.DisplaySafeAreaPadding, fullscreen_rect.GetCenter() - window->SizeFull * 0.5f)); + } + else if (flags & ImGuiWindowFlags_ChildMenu) + { + IM_ASSERT(window_pos_set_by_api); + ImRect rect_to_avoid; + if (parent_window->DC.MenuBarAppending) + rect_to_avoid = ImRect(-FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight(), FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight() + parent_window->MenuBarHeight()); + else + rect_to_avoid = ImRect(parent_window->Pos.x + style.ItemSpacing.x, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - style.ItemSpacing.x - parent_window->ScrollbarSizes.x, FLT_MAX); // We want some overlap to convey the relative depth of each popup (here hard-coded to 4) + window->PosFloat = FindBestPopupWindowPos(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); + } + else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_appearing_after_being_hidden) + { + ImRect rect_to_avoid(window->PosFloat.x - 1, window->PosFloat.y - 1, window->PosFloat.x + 1, window->PosFloat.y + 1); + window->PosFloat = FindBestPopupWindowPos(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); + } + + // Position tooltip (always follows mouse) + if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api) + { + ImRect rect_to_avoid(g.IO.MousePos.x - 16, g.IO.MousePos.y - 8, g.IO.MousePos.x + 24, g.IO.MousePos.y + 24); // FIXME: Completely hard-coded. Perhaps center on cursor hit-point instead? + window->PosFloat = FindBestPopupWindowPos(g.IO.MousePos, window->Size, &window->AutoPosLastDirection, rect_to_avoid); + if (window->AutoPosLastDirection == -1) + window->PosFloat = g.IO.MousePos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible. + } + + // Clamp position so it stays visible + if (!(flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Tooltip)) + { + if (!window_pos_set_by_api && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && g.IO.DisplaySize.x > 0.0f && g.IO.DisplaySize.y > 0.0f) // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. + { + ImVec2 padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding); + window->PosFloat = ImMax(window->PosFloat + window->Size, padding) - window->Size; + window->PosFloat = ImMin(window->PosFloat, g.IO.DisplaySize - padding); + } + } + window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); + + // Default item width. Make it proportional to window size if window manually resizes + if (window->Size.x > 0.0f && !(flags & ImGuiWindowFlags_Tooltip) && !(flags & ImGuiWindowFlags_AlwaysAutoResize)) + window->ItemWidthDefault = (float)(int)(window->Size.x * 0.65f); + else + window->ItemWidthDefault = (float)(int)(g.FontSize * 16.0f); + + // Prepare for focus requests + window->FocusIdxAllRequestCurrent = (window->FocusIdxAllRequestNext == INT_MAX || window->FocusIdxAllCounter == -1) ? INT_MAX : (window->FocusIdxAllRequestNext + (window->FocusIdxAllCounter+1)) % (window->FocusIdxAllCounter+1); + window->FocusIdxTabRequestCurrent = (window->FocusIdxTabRequestNext == INT_MAX || window->FocusIdxTabCounter == -1) ? INT_MAX : (window->FocusIdxTabRequestNext + (window->FocusIdxTabCounter+1)) % (window->FocusIdxTabCounter+1); + window->FocusIdxAllCounter = window->FocusIdxTabCounter = -1; + window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = INT_MAX; + + // Apply scrolling + if (window->ScrollTarget.x < FLT_MAX) + { + window->Scroll.x = window->ScrollTarget.x; + window->ScrollTarget.x = FLT_MAX; + } + if (window->ScrollTarget.y < FLT_MAX) + { + float center_ratio = window->ScrollTargetCenterRatio.y; + window->Scroll.y = window->ScrollTarget.y - ((1.0f - center_ratio) * (window->TitleBarHeight() + window->MenuBarHeight())) - (center_ratio * window->SizeFull.y); + window->ScrollTarget.y = FLT_MAX; + } + window->Scroll = ImMax(window->Scroll, ImVec2(0.0f, 0.0f)); + if (!window->Collapsed && !window->SkipItems) + window->Scroll = ImMin(window->Scroll, ImMax(ImVec2(0.0f, 0.0f), window->SizeContents - window->SizeFull + window->ScrollbarSizes)); + + // Modal window darkens what is behind them + if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) + window->DrawList->AddRectFilled(fullscreen_rect.Min, fullscreen_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio)); + + // Draw window + handle manual resize + ImRect title_bar_rect = window->TitleBarRect(); + const float window_rounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildWindowRounding : style.WindowRounding; + if (window->Collapsed) + { + // Draw title bar only + RenderFrame(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32(ImGuiCol_TitleBgCollapsed), true, window_rounding); + } + else + { + ImU32 resize_col = 0; + const float resize_corner_size = ImMax(g.FontSize * 1.35f, window_rounding + 1.0f + g.FontSize * 0.2f); + if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && !(flags & ImGuiWindowFlags_NoResize)) + { + // Manual resize + const ImVec2 br = window->Rect().GetBR(); + const ImRect resize_rect(br - ImVec2(resize_corner_size * 0.75f, resize_corner_size * 0.75f), br); + const ImGuiID resize_id = window->GetID("#RESIZE"); + bool hovered, held; + ButtonBehavior(resize_rect, resize_id, &hovered, &held, ImGuiButtonFlags_FlattenChilds); + resize_col = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); + + if (hovered || held) + g.MouseCursor = ImGuiMouseCursor_ResizeNWSE; + + if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0]) + { + // Manual auto-fit when double-clicking + ApplySizeFullWithConstraint(window, size_auto_fit); + if (!(flags & ImGuiWindowFlags_NoSavedSettings)) + MarkSettingsDirty(); + SetActiveID(0); + } + else if (held) + { + // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position + ApplySizeFullWithConstraint(window, (g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize()) - window->Pos); + if (!(flags & ImGuiWindowFlags_NoSavedSettings)) + MarkSettingsDirty(); + } + + window->Size = window->SizeFull; + title_bar_rect = window->TitleBarRect(); + } + + // Scrollbars + window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); + window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); + window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); + window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; + + // Window background + // Default alpha + ImGuiCol bg_color_idx = ImGuiCol_WindowBg; + if ((flags & ImGuiWindowFlags_ComboBox) != 0) + bg_color_idx = ImGuiCol_ComboBg; + else if ((flags & ImGuiWindowFlags_Tooltip) != 0 || (flags & ImGuiWindowFlags_Popup) != 0) + bg_color_idx = ImGuiCol_PopupBg; + else if ((flags & ImGuiWindowFlags_ChildWindow) != 0) + bg_color_idx = ImGuiCol_ChildWindowBg; + ImVec4 bg_color = style.Colors[bg_color_idx]; + if (bg_alpha >= 0.0f) + bg_color.w = bg_alpha; + bg_color.w *= style.Alpha; + if (bg_color.w > 0.0f) + window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, ColorConvertFloat4ToU32(bg_color), window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? 15 : 4|8); + + // Title bar + if (!(flags & ImGuiWindowFlags_NoTitleBar)) + window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32((g.FocusedWindow && window->RootNonPopupWindow == g.FocusedWindow->RootNonPopupWindow) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, 1|2); + + // Menu bar + if (flags & ImGuiWindowFlags_MenuBar) + { + ImRect menu_bar_rect = window->MenuBarRect(); + window->DrawList->AddRectFilled(menu_bar_rect.GetTL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, 1|2); + if (flags & ImGuiWindowFlags_ShowBorders) + window->DrawList->AddLine(menu_bar_rect.GetBL()-ImVec2(0,0), menu_bar_rect.GetBR()-ImVec2(0,0), GetColorU32(ImGuiCol_Border)); + } + + // Scrollbars + if (window->ScrollbarX) + Scrollbar(window, true); + if (window->ScrollbarY) + Scrollbar(window, false); + + // Render resize grip + // (after the input handling so we don't have a frame of latency) + if (!(flags & ImGuiWindowFlags_NoResize)) + { + const ImVec2 br = window->Rect().GetBR(); + window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window->BorderSize)); + window->DrawList->PathLineTo(br + ImVec2(-window->BorderSize, -resize_corner_size)); + window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window->BorderSize, br.y - window_rounding - window->BorderSize), window_rounding, 0, 3); + window->DrawList->PathFill(resize_col); + } + + // Borders + if (flags & ImGuiWindowFlags_ShowBorders) + { + window->DrawList->AddRect(window->Pos+ImVec2(1,1), window->Pos+window->Size+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), window_rounding); + window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding); + if (!(flags & ImGuiWindowFlags_NoTitleBar)) + window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,0), title_bar_rect.GetBR()-ImVec2(1,0), GetColorU32(ImGuiCol_Border)); + } + } + + // Update ContentsRegionMax. All the variable it depends on are set above in this function. + window->ContentsRegionRect.Min.x = -window->Scroll.x + window->WindowPadding.x; + window->ContentsRegionRect.Min.y = -window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight(); + window->ContentsRegionRect.Max.x = -window->Scroll.x - window->WindowPadding.x + (window->SizeContentsExplicit.x != 0.0f ? window->SizeContentsExplicit.x : (window->Size.x - window->ScrollbarSizes.x)); + window->ContentsRegionRect.Max.y = -window->Scroll.y - window->WindowPadding.y + (window->SizeContentsExplicit.y != 0.0f ? window->SizeContentsExplicit.y : (window->Size.y - window->ScrollbarSizes.y)); + + // Setup drawing context + window->DC.IndentX = 0.0f + window->WindowPadding.x - window->Scroll.x; + window->DC.GroupOffsetX = 0.0f; + window->DC.ColumnsOffsetX = 0.0f; + window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.IndentX + window->DC.ColumnsOffsetX, window->TitleBarHeight() + window->MenuBarHeight() + window->WindowPadding.y - window->Scroll.y); + window->DC.CursorPos = window->DC.CursorStartPos; + window->DC.CursorPosPrevLine = window->DC.CursorPos; + window->DC.CursorMaxPos = window->DC.CursorStartPos; + window->DC.CurrentLineHeight = window->DC.PrevLineHeight = 0.0f; + window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f; + window->DC.MenuBarAppending = false; + window->DC.MenuBarOffsetX = ImMax(window->WindowPadding.x, style.ItemSpacing.x); + window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; + window->DC.ChildWindows.resize(0); + window->DC.LayoutType = ImGuiLayoutType_Vertical; + window->DC.ItemWidth = window->ItemWidthDefault; + window->DC.TextWrapPos = -1.0f; // disabled + window->DC.AllowKeyboardFocus = true; + window->DC.ButtonRepeat = false; + window->DC.ItemWidthStack.resize(0); + window->DC.AllowKeyboardFocusStack.resize(0); + window->DC.ButtonRepeatStack.resize(0); + window->DC.TextWrapPosStack.resize(0); + window->DC.ColumnsCurrent = 0; + window->DC.ColumnsCount = 1; + window->DC.ColumnsStartPosY = window->DC.CursorPos.y; + window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.ColumnsStartPosY; + window->DC.TreeDepth = 0; + window->DC.StateStorage = &window->StateStorage; + window->DC.GroupStack.resize(0); + window->DC.ColorEditMode = ImGuiColorEditMode_UserSelect; + window->MenuColumns.Update(3, style.ItemSpacing.x, !window_was_active); + + if (window->AutoFitFramesX > 0) + window->AutoFitFramesX--; + if (window->AutoFitFramesY > 0) + window->AutoFitFramesY--; + + // New windows appears in front (we need to do that AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there) + if (!window_was_active && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) + if (!(flags & (ImGuiWindowFlags_ChildWindow|ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) + FocusWindow(window); + + // Title bar + if (!(flags & ImGuiWindowFlags_NoTitleBar)) + { + if (p_open != NULL) + { + const float pad = 2.0f; + const float rad = (window->TitleBarHeight() - pad*2.0f) * 0.5f; + if (CloseButton(window->GetID("#CLOSE"), window->Rect().GetTR() + ImVec2(-pad - rad, pad + rad), rad)) + *p_open = false; + } + + const ImVec2 text_size = CalcTextSize(name, NULL, true); + if (!(flags & ImGuiWindowFlags_NoCollapse)) + RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f, true); + + ImVec2 text_min = window->Pos + style.FramePadding; + ImVec2 text_max = window->Pos + ImVec2(window->Size.x - style.FramePadding.x, style.FramePadding.y*2 + text_size.y); + ImVec2 clip_max = ImVec2(window->Pos.x + window->Size.x - (p_open ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x), text_max.y); // Match the size of CloseWindowButton() + bool pad_left = (flags & ImGuiWindowFlags_NoCollapse) == 0; + bool pad_right = (p_open != NULL); + if (style.WindowTitleAlign & ImGuiAlign_Center) pad_right = pad_left; + if (pad_left) text_min.x += g.FontSize + style.ItemInnerSpacing.x; + if (pad_right) text_max.x -= g.FontSize + style.ItemInnerSpacing.x; + ImVec2 clip_min = ImVec2(text_min.x, window->Pos.y); + RenderTextClipped(text_min, text_max, name, NULL, &text_size, style.WindowTitleAlign, &clip_min, &clip_max); + } + + // Save clipped aabb so we can access it in constant-time in FindHoveredWindow() + window->WindowRectClipped = window->Rect(); + window->WindowRectClipped.Clip(window->ClipRect); + + // Pressing CTRL+C while holding on a window copy its content to the clipboard + // This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope. + // Maybe we can support CTRL+C on every element? + /* + if (g.ActiveId == move_id) + if (g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_C)) + ImGui::LogToClipboard(); + */ + } + + // Inner clipping rectangle + // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame + // Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior. + const ImRect title_bar_rect = window->TitleBarRect(); + const float border_size = window->BorderSize; + ImRect clip_rect; // Force round to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. + clip_rect.Min.x = ImFloor(0.5f + title_bar_rect.Min.x + ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); + clip_rect.Min.y = ImFloor(0.5f + title_bar_rect.Max.y + window->MenuBarHeight() + border_size); + clip_rect.Max.x = ImFloor(0.5f + window->Pos.x + window->Size.x - window->ScrollbarSizes.x - ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); + clip_rect.Max.y = ImFloor(0.5f + window->Pos.y + window->Size.y - window->ScrollbarSizes.y - border_size); + PushClipRect(clip_rect.Min, clip_rect.Max, true); + + // Clear 'accessed' flag last thing + if (first_begin_of_the_frame) + window->Accessed = false; + window->BeginCount++; + g.SetNextWindowSizeConstraint = false; + + // Child window can be out of sight and have "negative" clip windows. + // Mark them as collapsed so commands are skipped earlier (we can't manually collapse because they have no title bar). + if (flags & ImGuiWindowFlags_ChildWindow) + { + IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0); + window->Collapsed = parent_window && parent_window->Collapsed; + + if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) + window->Collapsed |= (window->WindowRectClipped.Min.x >= window->WindowRectClipped.Max.x || window->WindowRectClipped.Min.y >= window->WindowRectClipped.Max.y); + + // We also hide the window from rendering because we've already added its border to the command list. + // (we could perform the check earlier in the function but it is simpler at this point) + if (window->Collapsed) + window->Active = false; + } + if (style.Alpha <= 0.0f) + window->Active = false; + + // Return false if we don't intend to display anything to allow user to perform an early out optimization + window->SkipItems = (window->Collapsed || !window->Active) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0; + return !window->SkipItems; +} + +void ImGui::End() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + Columns(1, "#CloseColumns"); + PopClipRect(); // inner window clip rectangle + + // Stop logging + if (!(window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME: add more options for scope of logging + LogFinish(); + + // Pop + // NB: we don't clear 'window->RootWindow'. The pointer is allowed to live until the next call to Begin(). + g.CurrentWindowStack.pop_back(); + if (window->Flags & ImGuiWindowFlags_Popup) + g.CurrentPopupStack.pop_back(); + CheckStacksSize(window, false); + SetCurrentWindow(g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back()); +} + +// Vertical scrollbar +// The entire piece of code below is rather confusing because: +// - We handle absolute seeking (when first clicking outside the grab) and relative manipulation (afterward or when clicking inside the grab) +// - We store values as normalized ratio and in a form that allows the window content to change while we are holding on a scrollbar +// - We handle both horizontal and vertical scrollbars, which makes the terminology not ideal. +static void Scrollbar(ImGuiWindow* window, bool horizontal) +{ + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(horizontal ? "#SCROLLX" : "#SCROLLY"); + + // Render background + bool other_scrollbar = (horizontal ? window->ScrollbarY : window->ScrollbarX); + float other_scrollbar_size_w = other_scrollbar ? style.ScrollbarSize : 0.0f; + const ImRect window_rect = window->Rect(); + const float border_size = window->BorderSize; + ImRect bb = horizontal + ? ImRect(window->Pos.x + border_size, window_rect.Max.y - style.ScrollbarSize, window_rect.Max.x - other_scrollbar_size_w - border_size, window_rect.Max.y - border_size) + : ImRect(window_rect.Max.x - style.ScrollbarSize, window->Pos.y + border_size, window_rect.Max.x - border_size, window_rect.Max.y - other_scrollbar_size_w - border_size); + if (!horizontal) + bb.Min.y += window->TitleBarHeight() + ((window->Flags & ImGuiWindowFlags_MenuBar) ? window->MenuBarHeight() : 0.0f); + + float window_rounding = (window->Flags & ImGuiWindowFlags_ChildWindow) ? style.ChildWindowRounding : style.WindowRounding; + int window_rounding_corners; + if (horizontal) + window_rounding_corners = 8 | (other_scrollbar ? 0 : 4); + else + window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? 2 : 0) | (other_scrollbar ? 0 : 4); + window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_ScrollbarBg), window_rounding, window_rounding_corners); + bb.Reduce(ImVec2(ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f))); + + // V denote the main axis of the scrollbar + float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight(); + float scroll_v = horizontal ? window->Scroll.x : window->Scroll.y; + float win_size_avail_v = (horizontal ? window->Size.x : window->Size.y) - other_scrollbar_size_w; + float win_size_contents_v = horizontal ? window->SizeContents.x : window->SizeContents.y; + + // The grabable box size generally represent the amount visible (vs the total scrollable amount) + // But we maintain a minimum size in pixel to allow for the user to still aim inside. + const float grab_h_pixels = ImMin(ImMax(scrollbar_size_v * ImSaturate(win_size_avail_v / ImMax(win_size_contents_v, win_size_avail_v)), style.GrabMinSize), scrollbar_size_v); + const float grab_h_norm = grab_h_pixels / scrollbar_size_v; + + // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar(). + bool held = false; + bool hovered = false; + const bool previously_held = (g.ActiveId == id); + ImGui::ButtonBehavior(bb, id, &hovered, &held); + + float scroll_max = ImMax(1.0f, win_size_contents_v - win_size_avail_v); + float scroll_ratio = ImSaturate(scroll_v / scroll_max); + float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; + if (held && grab_h_norm < 1.0f) + { + float scrollbar_pos_v = horizontal ? bb.Min.x : bb.Min.y; + float mouse_pos_v = horizontal ? g.IO.MousePos.x : g.IO.MousePos.y; + float* click_delta_to_grab_center_v = horizontal ? &g.ScrollbarClickDeltaToGrabCenter.x : &g.ScrollbarClickDeltaToGrabCenter.y; + + // Click position in scrollbar normalized space (0.0f->1.0f) + const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v); + ImGui::SetHoveredID(id); + + bool seek_absolute = false; + if (!previously_held) + { + // On initial click calculate the distance between mouse and the center of the grab + if (clicked_v_norm >= grab_v_norm && clicked_v_norm <= grab_v_norm + grab_h_norm) + { + *click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm*0.5f; + } + else + { + seek_absolute = true; + *click_delta_to_grab_center_v = 0.0f; + } + } + + // Apply scroll + // It is ok to modify Scroll here because we are being called in Begin() after the calculation of SizeContents and before setting up our starting position + const float scroll_v_norm = ImSaturate((clicked_v_norm - *click_delta_to_grab_center_v - grab_h_norm*0.5f) / (1.0f - grab_h_norm)); + scroll_v = (float)(int)(0.5f + scroll_v_norm * scroll_max);//(win_size_contents_v - win_size_v)); + if (horizontal) + window->Scroll.x = scroll_v; + else + window->Scroll.y = scroll_v; + + // Update values for rendering + scroll_ratio = ImSaturate(scroll_v / scroll_max); + grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; + + // Update distance to grab now that we have seeked and saturated + if (seek_absolute) + *click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm*0.5f; + } + + // Render + const ImU32 grab_col = ImGui::GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab); + if (horizontal) + window->DrawList->AddRectFilled(ImVec2(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y), ImVec2(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, bb.Max.y), grab_col, style.ScrollbarRounding); + else + window->DrawList->AddRectFilled(ImVec2(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm)), ImVec2(bb.Max.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels), grab_col, style.ScrollbarRounding); +} + +// Moving window to front of display (which happens to be back of our sorted list) +void ImGui::FocusWindow(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + + // Always mark the window we passed as focused. This is used for keyboard interactions such as tabbing. + g.FocusedWindow = window; + + // Passing NULL allow to disable keyboard focus + if (!window) + return; + + // And move its root window to the top of the pile + if (window->RootWindow) + window = window->RootWindow; + + // Steal focus on active widgets + if (window->Flags & ImGuiWindowFlags_Popup) // FIXME: This statement should be unnecessary. Need further testing before removing it.. + if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != window) + SetActiveID(0); + + // Bring to front + if ((window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) || g.Windows.back() == window) + return; + for (int i = 0; i < g.Windows.Size; i++) + if (g.Windows[i] == window) + { + g.Windows.erase(g.Windows.begin() + i); + break; + } + g.Windows.push_back(window); +} + +void ImGui::PushItemWidth(float item_width) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ItemWidth = (item_width == 0.0f ? window->ItemWidthDefault : item_width); + window->DC.ItemWidthStack.push_back(window->DC.ItemWidth); +} + +static void PushMultiItemsWidths(int components, float w_full) +{ + ImGuiWindow* window = ImGui::GetCurrentWindow(); + const ImGuiStyle& style = GImGui->Style; + if (w_full <= 0.0f) + w_full = ImGui::CalcItemWidth(); + const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.ItemInnerSpacing.x) * (components-1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.ItemInnerSpacing.x) * (components-1))); + window->DC.ItemWidthStack.push_back(w_item_last); + for (int i = 0; i < components-1; i++) + window->DC.ItemWidthStack.push_back(w_item_one); + window->DC.ItemWidth = window->DC.ItemWidthStack.back(); +} + +void ImGui::PopItemWidth() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ItemWidthStack.pop_back(); + window->DC.ItemWidth = window->DC.ItemWidthStack.empty() ? window->ItemWidthDefault : window->DC.ItemWidthStack.back(); +} + +float ImGui::CalcItemWidth() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + float w = window->DC.ItemWidth; + if (w < 0.0f) + { + // Align to a right-side limit. We include 1 frame padding in the calculation because this is how the width is always used (we add 2 frame padding to it), but we could move that responsibility to the widget as well. + float width_to_right_edge = GetContentRegionAvail().x; + w = ImMax(1.0f, width_to_right_edge + w); + } + w = (float)(int)w; + return w; +} + +static void SetCurrentFont(ImFont* font) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(font && font->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? + IM_ASSERT(font->Scale > 0.0f); + g.Font = font; + g.FontBaseSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale; + g.FontSize = g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f; + g.FontTexUvWhitePixel = g.Font->ContainerAtlas->TexUvWhitePixel; +} + +void ImGui::PushFont(ImFont* font) +{ + ImGuiContext& g = *GImGui; + if (!font) + font = g.IO.Fonts->Fonts[0]; + SetCurrentFont(font); + g.FontStack.push_back(font); + g.CurrentWindow->DrawList->PushTextureID(font->ContainerAtlas->TexID); +} + +void ImGui::PopFont() +{ + ImGuiContext& g = *GImGui; + g.CurrentWindow->DrawList->PopTextureID(); + g.FontStack.pop_back(); + SetCurrentFont(g.FontStack.empty() ? g.IO.Fonts->Fonts[0] : g.FontStack.back()); +} + +void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.AllowKeyboardFocus = allow_keyboard_focus; + window->DC.AllowKeyboardFocusStack.push_back(allow_keyboard_focus); +} + +void ImGui::PopAllowKeyboardFocus() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.AllowKeyboardFocusStack.pop_back(); + window->DC.AllowKeyboardFocus = window->DC.AllowKeyboardFocusStack.empty() ? true : window->DC.AllowKeyboardFocusStack.back(); +} + +void ImGui::PushButtonRepeat(bool repeat) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ButtonRepeat = repeat; + window->DC.ButtonRepeatStack.push_back(repeat); +} + +void ImGui::PopButtonRepeat() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ButtonRepeatStack.pop_back(); + window->DC.ButtonRepeat = window->DC.ButtonRepeatStack.empty() ? false : window->DC.ButtonRepeatStack.back(); +} + +void ImGui::PushTextWrapPos(float wrap_pos_x) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.TextWrapPos = wrap_pos_x; + window->DC.TextWrapPosStack.push_back(wrap_pos_x); +} + +void ImGui::PopTextWrapPos() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.TextWrapPosStack.pop_back(); + window->DC.TextWrapPos = window->DC.TextWrapPosStack.empty() ? -1.0f : window->DC.TextWrapPosStack.back(); +} + +void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col) +{ + ImGuiContext& g = *GImGui; + ImGuiColMod backup; + backup.Col = idx; + backup.PreviousValue = g.Style.Colors[idx]; + g.ColorModifiers.push_back(backup); + g.Style.Colors[idx] = col; +} + +void ImGui::PopStyleColor(int count) +{ + ImGuiContext& g = *GImGui; + while (count > 0) + { + ImGuiColMod& backup = g.ColorModifiers.back(); + g.Style.Colors[backup.Col] = backup.PreviousValue; + g.ColorModifiers.pop_back(); + count--; + } +} + +static float* GetStyleVarFloatAddr(ImGuiStyleVar idx) +{ + ImGuiContext& g = *GImGui; + switch (idx) + { + case ImGuiStyleVar_Alpha: return &g.Style.Alpha; + case ImGuiStyleVar_WindowRounding: return &g.Style.WindowRounding; + case ImGuiStyleVar_ChildWindowRounding: return &g.Style.ChildWindowRounding; + case ImGuiStyleVar_FrameRounding: return &g.Style.FrameRounding; + case ImGuiStyleVar_IndentSpacing: return &g.Style.IndentSpacing; + case ImGuiStyleVar_GrabMinSize: return &g.Style.GrabMinSize; + } + return NULL; +} + +static ImVec2* GetStyleVarVec2Addr(ImGuiStyleVar idx) +{ + ImGuiContext& g = *GImGui; + switch (idx) + { + case ImGuiStyleVar_WindowPadding: return &g.Style.WindowPadding; + case ImGuiStyleVar_WindowMinSize: return &g.Style.WindowMinSize; + case ImGuiStyleVar_FramePadding: return &g.Style.FramePadding; + case ImGuiStyleVar_ItemSpacing: return &g.Style.ItemSpacing; + case ImGuiStyleVar_ItemInnerSpacing: return &g.Style.ItemInnerSpacing; + } + return NULL; +} + +void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) +{ + ImGuiContext& g = *GImGui; + float* pvar = GetStyleVarFloatAddr(idx); + IM_ASSERT(pvar != NULL); // Called function with wrong-type? Variable is not a float. + ImGuiStyleMod backup; + backup.Var = idx; + backup.PreviousValue = ImVec2(*pvar, 0.0f); + g.StyleModifiers.push_back(backup); + *pvar = val; +} + + +void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) +{ + ImGuiContext& g = *GImGui; + ImVec2* pvar = GetStyleVarVec2Addr(idx); + IM_ASSERT(pvar != NULL); // Called function with wrong-type? Variable is not a ImVec2. + ImGuiStyleMod backup; + backup.Var = idx; + backup.PreviousValue = *pvar; + g.StyleModifiers.push_back(backup); + *pvar = val; +} + +void ImGui::PopStyleVar(int count) +{ + ImGuiContext& g = *GImGui; + while (count > 0) + { + ImGuiStyleMod& backup = g.StyleModifiers.back(); + if (float* pvar_f = GetStyleVarFloatAddr(backup.Var)) + *pvar_f = backup.PreviousValue.x; + else if (ImVec2* pvar_v = GetStyleVarVec2Addr(backup.Var)) + *pvar_v = backup.PreviousValue; + g.StyleModifiers.pop_back(); + count--; + } +} + +const char* ImGui::GetStyleColName(ImGuiCol idx) +{ + // Create switch-case from enum with regexp: ImGuiCol_{.*}, --> case ImGuiCol_\1: return "\1"; + switch (idx) + { + case ImGuiCol_Text: return "Text"; + case ImGuiCol_TextDisabled: return "TextDisabled"; + case ImGuiCol_WindowBg: return "WindowBg"; + case ImGuiCol_ChildWindowBg: return "ChildWindowBg"; + case ImGuiCol_PopupBg: return "PopupBg"; + case ImGuiCol_Border: return "Border"; + case ImGuiCol_BorderShadow: return "BorderShadow"; + case ImGuiCol_FrameBg: return "FrameBg"; + case ImGuiCol_FrameBgHovered: return "FrameBgHovered"; + case ImGuiCol_FrameBgActive: return "FrameBgActive"; + case ImGuiCol_TitleBg: return "TitleBg"; + case ImGuiCol_TitleBgCollapsed: return "TitleBgCollapsed"; + case ImGuiCol_TitleBgActive: return "TitleBgActive"; + case ImGuiCol_MenuBarBg: return "MenuBarBg"; + case ImGuiCol_ScrollbarBg: return "ScrollbarBg"; + case ImGuiCol_ScrollbarGrab: return "ScrollbarGrab"; + case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered"; + case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive"; + case ImGuiCol_ComboBg: return "ComboBg"; + case ImGuiCol_CheckMark: return "CheckMark"; + case ImGuiCol_SliderGrab: return "SliderGrab"; + case ImGuiCol_SliderGrabActive: return "SliderGrabActive"; + case ImGuiCol_Button: return "Button"; + case ImGuiCol_ButtonHovered: return "ButtonHovered"; + case ImGuiCol_ButtonActive: return "ButtonActive"; + case ImGuiCol_Header: return "Header"; + case ImGuiCol_HeaderHovered: return "HeaderHovered"; + case ImGuiCol_HeaderActive: return "HeaderActive"; + case ImGuiCol_Column: return "Column"; + case ImGuiCol_ColumnHovered: return "ColumnHovered"; + case ImGuiCol_ColumnActive: return "ColumnActive"; + case ImGuiCol_ResizeGrip: return "ResizeGrip"; + case ImGuiCol_ResizeGripHovered: return "ResizeGripHovered"; + case ImGuiCol_ResizeGripActive: return "ResizeGripActive"; + case ImGuiCol_CloseButton: return "CloseButton"; + case ImGuiCol_CloseButtonHovered: return "CloseButtonHovered"; + case ImGuiCol_CloseButtonActive: return "CloseButtonActive"; + case ImGuiCol_PlotLines: return "PlotLines"; + case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered"; + case ImGuiCol_PlotHistogram: return "PlotHistogram"; + case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered"; + case ImGuiCol_TextSelectedBg: return "TextSelectedBg"; + case ImGuiCol_ModalWindowDarkening: return "ModalWindowDarkening"; + } + IM_ASSERT(0); + return "Unknown"; +} + +bool ImGui::IsWindowHovered() +{ + ImGuiContext& g = *GImGui; + return g.HoveredWindow == g.CurrentWindow && IsWindowContentHoverable(g.HoveredRootWindow); +} + +bool ImGui::IsWindowFocused() +{ + ImGuiContext& g = *GImGui; + return g.FocusedWindow == g.CurrentWindow; +} + +bool ImGui::IsRootWindowFocused() +{ + ImGuiContext& g = *GImGui; + return g.FocusedWindow == g.CurrentWindow->RootWindow; +} + +bool ImGui::IsRootWindowOrAnyChildFocused() +{ + ImGuiContext& g = *GImGui; + return g.FocusedWindow && g.FocusedWindow->RootWindow == g.CurrentWindow->RootWindow; +} + +bool ImGui::IsRootWindowOrAnyChildHovered() +{ + ImGuiContext& g = *GImGui; + return g.HoveredRootWindow && (g.HoveredRootWindow == g.CurrentWindow->RootWindow) && IsWindowContentHoverable(g.HoveredRootWindow); +} + +float ImGui::GetWindowWidth() +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->Size.x; +} + +float ImGui::GetWindowHeight() +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->Size.y; +} + +ImVec2 ImGui::GetWindowPos() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + return window->Pos; +} + +static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y) +{ + window->DC.CursorMaxPos.y += window->Scroll.y; + window->Scroll.y = new_scroll_y; + window->DC.CursorMaxPos.y -= window->Scroll.y; +} + +static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiSetCond cond) +{ + // Test condition (NB: bit 0 is always true) and clear flags for next time + if (cond && (window->SetWindowPosAllowFlags & cond) == 0) + return; + window->SetWindowPosAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing); + window->SetWindowPosCenterWanted = false; + + // Set + const ImVec2 old_pos = window->Pos; + window->PosFloat = pos; + window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); + window->DC.CursorPos += (window->Pos - old_pos); // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor + window->DC.CursorMaxPos += (window->Pos - old_pos); // And more importantly we need to adjust this so size calculation doesn't get affected. +} + +void ImGui::SetWindowPos(const ImVec2& pos, ImGuiSetCond cond) +{ + ImGuiWindow* window = GetCurrentWindow(); + SetWindowPos(window, pos, cond); +} + +void ImGui::SetWindowPos(const char* name, const ImVec2& pos, ImGuiSetCond cond) +{ + ImGuiWindow* window = FindWindowByName(name); + if (window) + SetWindowPos(window, pos, cond); +} + +ImVec2 ImGui::GetWindowSize() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->Size; +} + +static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiSetCond cond) +{ + // Test condition (NB: bit 0 is always true) and clear flags for next time + if (cond && (window->SetWindowSizeAllowFlags & cond) == 0) + return; + window->SetWindowSizeAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing); + + // Set + if (size.x > 0.0f) + { + window->AutoFitFramesX = 0; + window->SizeFull.x = size.x; + } + else + { + window->AutoFitFramesX = 2; + window->AutoFitOnlyGrows = false; + } + if (size.y > 0.0f) + { + window->AutoFitFramesY = 0; + window->SizeFull.y = size.y; + } + else + { + window->AutoFitFramesY = 2; + window->AutoFitOnlyGrows = false; + } +} + +void ImGui::SetWindowSize(const ImVec2& size, ImGuiSetCond cond) +{ + SetWindowSize(GImGui->CurrentWindow, size, cond); +} + +void ImGui::SetWindowSize(const char* name, const ImVec2& size, ImGuiSetCond cond) +{ + ImGuiWindow* window = FindWindowByName(name); + if (window) + SetWindowSize(window, size, cond); +} + +static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiSetCond cond) +{ + // Test condition (NB: bit 0 is always true) and clear flags for next time + if (cond && (window->SetWindowCollapsedAllowFlags & cond) == 0) + return; + window->SetWindowCollapsedAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing); + + // Set + window->Collapsed = collapsed; +} + +void ImGui::SetWindowCollapsed(bool collapsed, ImGuiSetCond cond) +{ + SetWindowCollapsed(GImGui->CurrentWindow, collapsed, cond); +} + +bool ImGui::IsWindowCollapsed() +{ + return GImGui->CurrentWindow->Collapsed; +} + +void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond) +{ + ImGuiWindow* window = FindWindowByName(name); + if (window) + SetWindowCollapsed(window, collapsed, cond); +} + +void ImGui::SetWindowFocus() +{ + FocusWindow(GImGui->CurrentWindow); +} + +void ImGui::SetWindowFocus(const char* name) +{ + if (name) + { + if (ImGuiWindow* window = FindWindowByName(name)) + FocusWindow(window); + } + else + { + FocusWindow(NULL); + } +} + +void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond) +{ + ImGuiContext& g = *GImGui; + g.SetNextWindowPosVal = pos; + g.SetNextWindowPosCond = cond ? cond : ImGuiSetCond_Always; +} + +void ImGui::SetNextWindowPosCenter(ImGuiSetCond cond) +{ + ImGuiContext& g = *GImGui; + g.SetNextWindowPosVal = ImVec2(-FLT_MAX, -FLT_MAX); + g.SetNextWindowPosCond = cond ? cond : ImGuiSetCond_Always; +} + +void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond) +{ + ImGuiContext& g = *GImGui; + g.SetNextWindowSizeVal = size; + g.SetNextWindowSizeCond = cond ? cond : ImGuiSetCond_Always; +} + +void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback, void* custom_callback_user_data) +{ + ImGuiContext& g = *GImGui; + g.SetNextWindowSizeConstraint = true; + g.SetNextWindowSizeConstraintRect = ImRect(size_min, size_max); + g.SetNextWindowSizeConstraintCallback = custom_callback; + g.SetNextWindowSizeConstraintCallbackUserData = custom_callback_user_data; +} + +void ImGui::SetNextWindowContentSize(const ImVec2& size) +{ + ImGuiContext& g = *GImGui; + g.SetNextWindowContentSizeVal = size; + g.SetNextWindowContentSizeCond = ImGuiSetCond_Always; +} + +void ImGui::SetNextWindowContentWidth(float width) +{ + ImGuiContext& g = *GImGui; + g.SetNextWindowContentSizeVal = ImVec2(width, g.SetNextWindowContentSizeCond ? g.SetNextWindowContentSizeVal.y : 0.0f); + g.SetNextWindowContentSizeCond = ImGuiSetCond_Always; +} + +void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond) +{ + ImGuiContext& g = *GImGui; + g.SetNextWindowCollapsedVal = collapsed; + g.SetNextWindowCollapsedCond = cond ? cond : ImGuiSetCond_Always; +} + +void ImGui::SetNextWindowFocus() +{ + ImGuiContext& g = *GImGui; + g.SetNextWindowFocus = true; +} + +// In window space (not screen space!) +ImVec2 ImGui::GetContentRegionMax() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + ImVec2 mx = window->ContentsRegionRect.Max; + if (window->DC.ColumnsCount != 1) + mx.x = GetColumnOffset(window->DC.ColumnsCurrent + 1) - window->WindowPadding.x; + return mx; +} + +ImVec2 ImGui::GetContentRegionAvail() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return GetContentRegionMax() - (window->DC.CursorPos - window->Pos); +} + +float ImGui::GetContentRegionAvailWidth() +{ + return GetContentRegionAvail().x; +} + +// In window space (not screen space!) +ImVec2 ImGui::GetWindowContentRegionMin() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->ContentsRegionRect.Min; +} + +ImVec2 ImGui::GetWindowContentRegionMax() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->ContentsRegionRect.Max; +} + +float ImGui::GetWindowContentRegionWidth() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->ContentsRegionRect.Max.x - window->ContentsRegionRect.Min.x; +} + +float ImGui::GetTextLineHeight() +{ + ImGuiContext& g = *GImGui; + return g.FontSize; +} + +float ImGui::GetTextLineHeightWithSpacing() +{ + ImGuiContext& g = *GImGui; + return g.FontSize + g.Style.ItemSpacing.y; +} + +float ImGui::GetItemsLineHeightWithSpacing() +{ + ImGuiContext& g = *GImGui; + return g.FontSize + g.Style.FramePadding.y * 2.0f + g.Style.ItemSpacing.y; +} + +ImDrawList* ImGui::GetWindowDrawList() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DrawList; +} + +ImFont* ImGui::GetFont() +{ + return GImGui->Font; +} + +float ImGui::GetFontSize() +{ + return GImGui->FontSize; +} + +ImVec2 ImGui::GetFontTexUvWhitePixel() +{ + return GImGui->FontTexUvWhitePixel; +} + +void ImGui::SetWindowFontScale(float scale) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + window->FontWindowScale = scale; + g.FontSize = window->CalcFontSize(); +} + +// User generally sees positions in window coordinates. Internally we store CursorPos in absolute screen coordinates because it is more convenient. +// Conversion happens as we pass the value to user, but it makes our naming convention confusing because GetCursorPos() == (DC.CursorPos - window.Pos). May want to rename 'DC.CursorPos'. +ImVec2 ImGui::GetCursorPos() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorPos - window->Pos + window->Scroll; +} + +float ImGui::GetCursorPosX() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorPos.x - window->Pos.x + window->Scroll.x; +} + +float ImGui::GetCursorPosY() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorPos.y - window->Pos.y + window->Scroll.y; +} + +void ImGui::SetCursorPos(const ImVec2& local_pos) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos = window->Pos - window->Scroll + local_pos; + window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); +} + +void ImGui::SetCursorPosX(float x) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + x; + window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPos.x); +} + +void ImGui::SetCursorPosY(float y) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos.y = window->Pos.y - window->Scroll.y + y; + window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); +} + +ImVec2 ImGui::GetCursorStartPos() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorStartPos - window->Pos; +} + +ImVec2 ImGui::GetCursorScreenPos() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorPos; +} + +void ImGui::SetCursorScreenPos(const ImVec2& screen_pos) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos = screen_pos; + window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); +} + +float ImGui::GetScrollX() +{ + return GImGui->CurrentWindow->Scroll.x; +} + +float ImGui::GetScrollY() +{ + return GImGui->CurrentWindow->Scroll.y; +} + +float ImGui::GetScrollMaxX() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->SizeContents.x - window->SizeFull.x - window->ScrollbarSizes.x; +} + +float ImGui::GetScrollMaxY() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->SizeContents.y - window->SizeFull.y - window->ScrollbarSizes.y; +} + +void ImGui::SetScrollX(float scroll_x) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->ScrollTarget.x = scroll_x; + window->ScrollTargetCenterRatio.x = 0.0f; +} + +void ImGui::SetScrollY(float scroll_y) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->ScrollTarget.y = scroll_y + window->TitleBarHeight() + window->MenuBarHeight(); // title bar height canceled out when using ScrollTargetRelY + window->ScrollTargetCenterRatio.y = 0.0f; +} + +void ImGui::SetScrollFromPosY(float pos_y, float center_y_ratio) +{ + // We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size + ImGuiWindow* window = GetCurrentWindow(); + IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f); + window->ScrollTarget.y = (float)(int)(pos_y + window->Scroll.y); + if (center_y_ratio <= 0.0f && window->ScrollTarget.y <= window->WindowPadding.y) // Minor hack to make "scroll to top" take account of WindowPadding, else it would scroll to (WindowPadding.y - ItemSpacing.y) + window->ScrollTarget.y = 0.0f; + window->ScrollTargetCenterRatio.y = center_y_ratio; +} + +// center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item. +void ImGui::SetScrollHere(float center_y_ratio) +{ + ImGuiWindow* window = GetCurrentWindow(); + float target_y = window->DC.CursorPosPrevLine.y + (window->DC.PrevLineHeight * center_y_ratio) + (GImGui->Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line. + SetScrollFromPosY(target_y - window->Pos.y, center_y_ratio); +} + +void ImGui::SetKeyboardFocusHere(int offset) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->FocusIdxAllRequestNext = window->FocusIdxAllCounter + 1 + offset; + window->FocusIdxTabRequestNext = INT_MAX; +} + +void ImGui::SetStateStorage(ImGuiStorage* tree) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.StateStorage = tree ? tree : &window->StateStorage; +} + +ImGuiStorage* ImGui::GetStateStorage() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.StateStorage; +} + +void ImGui::TextV(const char* fmt, va_list args) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + TextUnformatted(g.TempBuffer, text_end); +} + +void ImGui::Text(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + TextV(fmt, args); + va_end(args); +} + +void ImGui::TextColoredV(const ImVec4& col, const char* fmt, va_list args) +{ + PushStyleColor(ImGuiCol_Text, col); + TextV(fmt, args); + PopStyleColor(); +} + +void ImGui::TextColored(const ImVec4& col, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + TextColoredV(col, fmt, args); + va_end(args); +} + +void ImGui::TextDisabledV(const char* fmt, va_list args) +{ + PushStyleColor(ImGuiCol_Text, GImGui->Style.Colors[ImGuiCol_TextDisabled]); + TextV(fmt, args); + PopStyleColor(); +} + +void ImGui::TextDisabled(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + TextDisabledV(fmt, args); + va_end(args); +} + +void ImGui::TextWrappedV(const char* fmt, va_list args) +{ + bool need_wrap = (GImGui->CurrentWindow->DC.TextWrapPos < 0.0f); // Keep existing wrap position is one ia already set + if (need_wrap) PushTextWrapPos(0.0f); + TextV(fmt, args); + if (need_wrap) PopTextWrapPos(); +} + +void ImGui::TextWrapped(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + TextWrappedV(fmt, args); + va_end(args); +} + +void ImGui::TextUnformatted(const char* text, const char* text_end) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + IM_ASSERT(text != NULL); + const char* text_begin = text; + if (text_end == NULL) + text_end = text + strlen(text); // FIXME-OPT + + const float wrap_pos_x = window->DC.TextWrapPos; + const bool wrap_enabled = wrap_pos_x >= 0.0f; + if (text_end - text > 2000 && !wrap_enabled) + { + // Long text! + // Perform manual coarse clipping to optimize for long multi-line text + // From this point we will only compute the width of lines that are visible. Optimization only available when word-wrapping is disabled. + // We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line. + const char* line = text; + const float line_height = GetTextLineHeight(); + const ImVec2 text_pos = window->DC.CursorPos + ImVec2(0.0f, window->DC.CurrentLineTextBaseOffset); + const ImRect clip_rect = window->ClipRect; + ImVec2 text_size(0,0); + + if (text_pos.y <= clip_rect.Max.y) + { + ImVec2 pos = text_pos; + + // Lines to skip (can't skip when logging text) + if (!g.LogEnabled) + { + int lines_skippable = (int)((clip_rect.Min.y - text_pos.y) / line_height); + if (lines_skippable > 0) + { + int lines_skipped = 0; + while (line < text_end && lines_skipped < lines_skippable) + { + const char* line_end = strchr(line, '\n'); + if (!line_end) + line_end = text_end; + line = line_end + 1; + lines_skipped++; + } + pos.y += lines_skipped * line_height; + } + } + + // Lines to render + if (line < text_end) + { + ImRect line_rect(pos, pos + ImVec2(FLT_MAX, line_height)); + while (line < text_end) + { + const char* line_end = strchr(line, '\n'); + if (IsClippedEx(line_rect, NULL, false)) + break; + + const ImVec2 line_size = CalcTextSize(line, line_end, false); + text_size.x = ImMax(text_size.x, line_size.x); + RenderText(pos, line, line_end, false); + if (!line_end) + line_end = text_end; + line = line_end + 1; + line_rect.Min.y += line_height; + line_rect.Max.y += line_height; + pos.y += line_height; + } + + // Count remaining lines + int lines_skipped = 0; + while (line < text_end) + { + const char* line_end = strchr(line, '\n'); + if (!line_end) + line_end = text_end; + line = line_end + 1; + lines_skipped++; + } + pos.y += lines_skipped * line_height; + } + + text_size.y += (pos - text_pos).y; + } + + ImRect bb(text_pos, text_pos + text_size); + ItemSize(bb); + ItemAdd(bb, NULL); + } + else + { + const float wrap_width = wrap_enabled ? CalcWrapWidthForPos(window->DC.CursorPos, wrap_pos_x) : 0.0f; + const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width); + + // Account of baseline offset + ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrentLineTextBaseOffset); + ImRect bb(text_pos, text_pos + text_size); + ItemSize(text_size); + if (!ItemAdd(bb, NULL)) + return; + + // Render (we don't hide text after ## in this end-user function) + RenderTextWrapped(bb.Min, text_begin, text_end, wrap_width); + } +} + +void ImGui::AlignFirstTextHeightToWidgets() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + // Declare a dummy item size to that upcoming items that are smaller will center-align on the newly expanded line height. + ImGuiContext& g = *GImGui; + ItemSize(ImVec2(0, g.FontSize + g.Style.FramePadding.y*2), g.Style.FramePadding.y); + SameLine(0, 0); +} + +// Add a label+text combo aligned to other label+value widgets +void ImGui::LabelTextV(const char* label, const char* fmt, va_list args) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const float w = CalcItemWidth(); + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2)); + const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, NULL)) + return; + + // Render + const char* value_text_begin = &g.TempBuffer[0]; + const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + RenderTextClipped(value_bb.Min, value_bb.Max, value_text_begin, value_text_end, NULL, ImGuiAlign_VCenter); + if (label_size.x > 0.0f) + RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label); +} + +void ImGui::LabelText(const char* label, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + LabelTextV(label, fmt, args); + va_end(args); +} + +static inline bool IsWindowContentHoverable(ImGuiWindow* window) +{ + // An active popup disable hovering on other windows (apart from its own children) + ImGuiContext& g = *GImGui; + if (ImGuiWindow* focused_window = g.FocusedWindow) + if (ImGuiWindow* focused_root_window = focused_window->RootWindow) + if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) != 0 && focused_root_window->WasActive && focused_root_window != window->RootWindow) + return false; + + return true; +} + +bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + if (flags & ImGuiButtonFlags_Disabled) + { + if (out_hovered) *out_hovered = false; + if (out_held) *out_held = false; + if (g.ActiveId == id) SetActiveID(0); + return false; + } + + if ((flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick)) == 0) + flags |= ImGuiButtonFlags_PressedOnClickRelease; + + bool pressed = false; + bool hovered = IsHovered(bb, id, (flags & ImGuiButtonFlags_FlattenChilds) != 0); + if (hovered) + { + SetHoveredID(id); + if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) + { + // | CLICKING | HOLDING with ImGuiButtonFlags_Repeat + // PressedOnClickRelease | * | .. (NOT on release) <-- MOST COMMON! (*) only if both click/release were over bounds + // PressedOnClick | | .. + // PressedOnRelease | | .. (NOT on release) + // PressedOnDoubleClick | | .. + if ((flags & ImGuiButtonFlags_PressedOnClickRelease) && g.IO.MouseClicked[0]) + { + SetActiveID(id, window); // Hold on ID + FocusWindow(window); + g.ActiveIdClickOffset = g.IO.MousePos - bb.Min; + } + if (((flags & ImGuiButtonFlags_PressedOnClick) && g.IO.MouseClicked[0]) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDoubleClicked[0])) + { + pressed = true; + SetActiveID(0); + FocusWindow(window); + } + if ((flags & ImGuiButtonFlags_PressedOnRelease) && g.IO.MouseReleased[0]) + { + if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[0] >= g.IO.KeyRepeatDelay)) // Repeat mode trumps + pressed = true; + SetActiveID(0); + } + + // 'Repeat' mode acts when held regardless of _PressedOn flags (see table above). + // Relies on repeat logic of IsMouseClicked() but we may as well do it ourselves if we end up exposing finer RepeatDelay/RepeatRate settings. + if ((flags & ImGuiButtonFlags_Repeat) && g.ActiveId == id && g.IO.MouseDownDuration[0] > 0.0f && IsMouseClicked(0, true)) + pressed = true; + } + } + + bool held = false; + if (g.ActiveId == id) + { + if (g.IO.MouseDown[0]) + { + held = true; + } + else + { + if (hovered && (flags & ImGuiButtonFlags_PressedOnClickRelease)) + if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[0] >= g.IO.KeyRepeatDelay)) // Repeat mode trumps + pressed = true; + SetActiveID(0); + } + } + + // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one. + if (hovered && (flags & ImGuiButtonFlags_AllowOverlapMode) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0)) + hovered = pressed = held = false; + + if (out_hovered) *out_hovered = hovered; + if (out_held) *out_held = held; + + return pressed; +} + +bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + ImVec2 pos = window->DC.CursorPos; + if ((flags & ImGuiButtonFlags_AlignTextBaseLine) && style.FramePadding.y < window->DC.CurrentLineTextBaseOffset) + pos.y += window->DC.CurrentLineTextBaseOffset - style.FramePadding.y; + ImVec2 size = CalcItemSize(size_arg, label_size.x + style.FramePadding.x * 2.0f, label_size.y + style.FramePadding.y * 2.0f); + + const ImRect bb(pos, pos + size); + ItemSize(bb, style.FramePadding.y); + if (!ItemAdd(bb, &id)) + return false; + + if (window->DC.ButtonRepeat) flags |= ImGuiButtonFlags_Repeat; + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); + + // Render + const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); + RenderTextClipped(bb.Min, bb.Max, label, NULL, &label_size, ImGuiAlign_Center | ImGuiAlign_VCenter); + + // Automatically close popups + //if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup)) + // CloseCurrentPopup(); + + return pressed; +} + +bool ImGui::Button(const char* label, const ImVec2& size_arg) +{ + return ButtonEx(label, size_arg, 0); +} + +// Small buttons fits within text without additional vertical spacing. +bool ImGui::SmallButton(const char* label) +{ + ImGuiContext& g = *GImGui; + float backup_padding_y = g.Style.FramePadding.y; + g.Style.FramePadding.y = 0.0f; + bool pressed = ButtonEx(label, ImVec2(0,0), ImGuiButtonFlags_AlignTextBaseLine); + g.Style.FramePadding.y = backup_padding_y; + return pressed; +} + +// Tip: use ImGui::PushID()/PopID() to push indices or pointers in the ID stack. +// Then you can keep 'str_id' empty or the same for all your buttons (instead of creating a string based on a non-string id) +bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiID id = window->GetID(str_id); + ImVec2 size = CalcItemSize(size_arg, 0.0f, 0.0f); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + ItemSize(bb); + if (!ItemAdd(bb, &id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held); + + return pressed; +} + +// Upper-right button to close a window. +bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos, float radius) +{ + ImGuiWindow* window = GetCurrentWindow(); + + const ImRect bb(pos - ImVec2(radius,radius), pos + ImVec2(radius,radius)); + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held); + + // Render + const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton); + const ImVec2 center = bb.GetCenter(); + window->DrawList->AddCircleFilled(center, ImMax(2.0f, radius), col, 12); + + const float cross_extent = (radius * 0.7071f) - 1.0f; + if (hovered) + { + window->DrawList->AddLine(center + ImVec2(+cross_extent,+cross_extent), center + ImVec2(-cross_extent,-cross_extent), GetColorU32(ImGuiCol_Text)); + window->DrawList->AddLine(center + ImVec2(+cross_extent,-cross_extent), center + ImVec2(-cross_extent,+cross_extent), GetColorU32(ImGuiCol_Text)); + } + + return pressed; +} + +void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + if (border_col.w > 0.0f) + bb.Max += ImVec2(2,2); + ItemSize(bb); + if (!ItemAdd(bb, NULL)) + return; + + if (border_col.w > 0.0f) + { + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(border_col), 0.0f); + window->DrawList->AddImage(user_texture_id, bb.Min+ImVec2(1,1), bb.Max-ImVec2(1,1), uv0, uv1, GetColorU32(tint_col)); + } + else + { + window->DrawList->AddImage(user_texture_id, bb.Min, bb.Max, uv0, uv1, GetColorU32(tint_col)); + } +} + +// frame_padding < 0: uses FramePadding from style (default) +// frame_padding = 0: no framing +// frame_padding > 0: set framing size +// The color used are the button colors. +bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + + // Default to using texture ID as ID. User can still push string/integer prefixes. + // We could hash the size/uv to create a unique ID but that would prevent the user from animating UV. + PushID((void *)user_texture_id); + const ImGuiID id = window->GetID("#image"); + PopID(); + + const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : style.FramePadding; + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding*2); + const ImRect image_bb(window->DC.CursorPos + padding, window->DC.CursorPos + padding + size); + ItemSize(bb); + if (!ItemAdd(bb, &id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held); + + // Render + const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, style.FrameRounding)); + if (bg_col.w > 0.0f) + window->DrawList->AddRectFilled(image_bb.Min, image_bb.Max, GetColorU32(bg_col)); + window->DrawList->AddImage(user_texture_id, image_bb.Min, image_bb.Max, uv0, uv1, GetColorU32(tint_col)); + + return pressed; +} + +// Start logging ImGui output to TTY +void ImGui::LogToTTY(int max_depth) +{ + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + return; + ImGuiWindow* window = GetCurrentWindowRead(); + + g.LogEnabled = true; + g.LogFile = stdout; + g.LogStartDepth = window->DC.TreeDepth; + if (max_depth >= 0) + g.LogAutoExpandMaxDepth = max_depth; +} + +// Start logging ImGui output to given file +void ImGui::LogToFile(int max_depth, const char* filename) +{ + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + return; + ImGuiWindow* window = GetCurrentWindowRead(); + + if (!filename) + { + filename = g.IO.LogFilename; + if (!filename) + return; + } + + g.LogFile = fopen(filename, "ab"); + if (!g.LogFile) + { + IM_ASSERT(g.LogFile != NULL); // Consider this an error + return; + } + g.LogEnabled = true; + g.LogStartDepth = window->DC.TreeDepth; + if (max_depth >= 0) + g.LogAutoExpandMaxDepth = max_depth; +} + +// Start logging ImGui output to clipboard +void ImGui::LogToClipboard(int max_depth) +{ + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + return; + ImGuiWindow* window = GetCurrentWindowRead(); + + g.LogEnabled = true; + g.LogFile = NULL; + g.LogStartDepth = window->DC.TreeDepth; + if (max_depth >= 0) + g.LogAutoExpandMaxDepth = max_depth; +} + +void ImGui::LogFinish() +{ + ImGuiContext& g = *GImGui; + if (!g.LogEnabled) + return; + + LogText(IM_NEWLINE); + g.LogEnabled = false; + if (g.LogFile != NULL) + { + if (g.LogFile == stdout) + fflush(g.LogFile); + else + fclose(g.LogFile); + g.LogFile = NULL; + } + if (g.LogClipboard->size() > 1) + { + if (g.IO.SetClipboardTextFn) + g.IO.SetClipboardTextFn(g.LogClipboard->begin()); + g.LogClipboard->clear(); + } +} + +// Helper to display logging buttons +void ImGui::LogButtons() +{ + ImGuiContext& g = *GImGui; + + PushID("LogButtons"); + const bool log_to_tty = Button("Log To TTY"); SameLine(); + const bool log_to_file = Button("Log To File"); SameLine(); + const bool log_to_clipboard = Button("Log To Clipboard"); SameLine(); + PushItemWidth(80.0f); + PushAllowKeyboardFocus(false); + SliderInt("Depth", &g.LogAutoExpandMaxDepth, 0, 9, NULL); + PopAllowKeyboardFocus(); + PopItemWidth(); + PopID(); + + // Start logging at the end of the function so that the buttons don't appear in the log + if (log_to_tty) + LogToTTY(g.LogAutoExpandMaxDepth); + if (log_to_file) + LogToFile(g.LogAutoExpandMaxDepth, g.IO.LogFilename); + if (log_to_clipboard) + LogToClipboard(g.LogAutoExpandMaxDepth); +} + +bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) +{ + if (flags & ImGuiTreeNodeFlags_Leaf) + return true; + + // We only write to the tree storage if the user clicks (or explicitely use SetNextTreeNode*** functions) + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiStorage* storage = window->DC.StateStorage; + + bool is_open; + if (g.SetNextTreeNodeOpenCond != 0) + { + if (g.SetNextTreeNodeOpenCond & ImGuiSetCond_Always) + { + is_open = g.SetNextTreeNodeOpenVal; + storage->SetInt(id, is_open); + } + else + { + // We treat ImGuiSetCondition_Once and ImGuiSetCondition_FirstUseEver the same because tree node state are not saved persistently. + const int stored_value = storage->GetInt(id, -1); + if (stored_value == -1) + { + is_open = g.SetNextTreeNodeOpenVal; + storage->SetInt(id, is_open); + } + else + { + is_open = stored_value != 0; + } + } + g.SetNextTreeNodeOpenCond = 0; + } + else + { + is_open = storage->GetInt(id, (flags & ImGuiTreeNodeFlags_DefaultOpen) ? 1 : 0) != 0; + } + + // When logging is enabled, we automatically expand tree nodes (but *NOT* collapsing headers.. seems like sensible behavior). + // NB- If we are above max depth we still allow manually opened nodes to be logged. + if (g.LogEnabled && !(flags & ImGuiTreeNodeFlags_NoAutoOpenOnLog) && window->DC.TreeDepth < g.LogAutoExpandMaxDepth) + is_open = true; + + return is_open; +} + +bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0; + const ImVec2 padding = display_frame ? style.FramePadding : ImVec2(style.FramePadding.x, 0.0f); + + if (!label_end) + label_end = FindRenderedTextEnd(label); + const ImVec2 label_size = CalcTextSize(label, label_end, false); + + // We vertically grow up to current line height up the typical widget height. + const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset - padding.y); // Latch before ItemSize changes it + const float frame_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + style.FramePadding.y*2), label_size.y + padding.y*2); + ImRect bb = ImRect(window->DC.CursorPos, ImVec2(window->Pos.x + GetContentRegionMax().x, window->DC.CursorPos.y + frame_height)); + if (display_frame) + { + // Framed header expand a little outside the default padding + bb.Min.x -= (float)(int)(window->WindowPadding.x*0.5f) - 1; + bb.Max.x += (float)(int)(window->WindowPadding.x*0.5f) - 1; + } + + const float text_offset_x = (g.FontSize + (display_frame ? padding.x*3 : padding.x*2)); // Collapser arrow width + Spacing + const float text_width = g.FontSize + (label_size.x > 0.0f ? label_size.x + padding.x*2 : 0.0f); // Include collapser + ItemSize(ImVec2(text_width, frame_height), text_base_offset_y); + + // For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing + // (Ideally we'd want to add a flag for the user to specify we want want the hit test to be done up to the right side of the content or not) + const ImRect interact_bb = display_frame ? bb : ImRect(bb.Min.x, bb.Min.y, bb.Min.x + text_width + style.ItemSpacing.x*2, bb.Max.y); + bool is_open = TreeNodeBehaviorIsOpen(id, flags); + if (!ItemAdd(interact_bb, &id)) + { + if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) + TreePushRawID(id); + return is_open; + } + + // Flags that affects opening behavior: + // - 0(default) ..................... single-click anywhere to open + // - OpenOnDoubleClick .............. double-click anywhere to open + // - OpenOnArrow .................... single-click on arrow to open + // - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open + ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowOverlapMode) ? ImGuiButtonFlags_AllowOverlapMode : 0); + if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) + button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0); + bool hovered, held, pressed = ButtonBehavior(interact_bb, id, &hovered, &held, button_flags); + if (pressed && !(flags & ImGuiTreeNodeFlags_Leaf)) + { + bool toggled = !(flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick)); + if (flags & ImGuiTreeNodeFlags_OpenOnArrow) + toggled |= IsMouseHoveringRect(interact_bb.Min, ImVec2(interact_bb.Min.x + text_offset_x, interact_bb.Max.y)); + if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) + toggled |= g.IO.MouseDoubleClicked[0]; + if (toggled) + { + is_open = !is_open; + window->DC.StateStorage->SetInt(id, is_open); + } + } + if (flags & ImGuiTreeNodeFlags_AllowOverlapMode) + SetItemAllowOverlap(); + + // Render + const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); + const ImVec2 text_pos = bb.Min + ImVec2(text_offset_x, padding.y + text_base_offset_y); + if (display_frame) + { + // Framed type + RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); + RenderCollapseTriangle(bb.Min + padding + ImVec2(0.0f, text_base_offset_y), is_open, 1.0f, true); + if (g.LogEnabled) + { + // NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here. + const char log_prefix[] = "\n##"; + const char log_suffix[] = "##"; + LogRenderedText(text_pos, log_prefix, log_prefix+3); + RenderTextClipped(text_pos, bb.Max, label, label_end, &label_size); + LogRenderedText(text_pos, log_suffix+1, log_suffix+3); + } + else + { + RenderTextClipped(text_pos, bb.Max, label, label_end, &label_size); + } + } + else + { + // Unframed typed for tree nodes + if (hovered || (flags & ImGuiTreeNodeFlags_Selected)) + RenderFrame(bb.Min, bb.Max, col, false); + + if (flags & ImGuiTreeNodeFlags_Bullet) + RenderBullet(bb.Min + ImVec2(text_offset_x * 0.5f, g.FontSize*0.50f + text_base_offset_y)); + else if (!(flags & ImGuiTreeNodeFlags_Leaf)) + RenderCollapseTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open, 0.70f, false); + if (g.LogEnabled) + LogRenderedText(text_pos, ">"); + RenderText(text_pos, label, label_end, false); + } + + if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) + TreePushRawID(id); + return is_open; +} + +// CollapsingHeader returns true when opened but do not indent nor push into the ID stack (because of the ImGuiTreeNodeFlags_NoTreePushOnOpen flag). +// This is basically the same as calling TreeNodeEx(label, ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen). You can remove the _NoTreePushOnOpen flag if you want behavior closer to normal TreeNode(). +bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + return TreeNodeBehavior(window->GetID(label), flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen, label); +} + +bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + if (p_open && !*p_open) + return false; + + ImGuiID id = window->GetID(label); + bool is_open = TreeNodeBehavior(id, flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen | (p_open ? ImGuiTreeNodeFlags_AllowOverlapMode : 0), label); + if (p_open) + { + // Create a small overlapping close button // FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc. + ImGuiContext& g = *GImGui; + float button_sz = g.FontSize * 0.5f; + if (CloseButton(window->GetID((void*)(intptr_t)(id+1)), ImVec2(ImMin(window->DC.LastItemRect.Max.x, window->ClipRect.Max.x) - g.Style.FramePadding.x - button_sz, window->DC.LastItemRect.Min.y + g.Style.FramePadding.y + button_sz), button_sz)) + *p_open = false; + } + + return is_open; +} + +bool ImGui::TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + return TreeNodeBehavior(window->GetID(label), flags, label, NULL); +} + +bool ImGui::TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + return TreeNodeBehavior(window->GetID(str_id), flags, g.TempBuffer, label_end); +} + +bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + return TreeNodeBehavior(window->GetID(ptr_id), flags, g.TempBuffer, label_end); +} + +bool ImGui::TreeNodeV(const char* str_id, const char* fmt, va_list args) +{ + return TreeNodeExV(str_id, 0, fmt, args); +} + +bool ImGui::TreeNodeV(const void* ptr_id, const char* fmt, va_list args) +{ + return TreeNodeExV(ptr_id, 0, fmt, args); +} + +bool ImGui::TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + bool is_open = TreeNodeExV(str_id, flags, fmt, args); + va_end(args); + return is_open; +} + +bool ImGui::TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + bool is_open = TreeNodeExV(ptr_id, flags, fmt, args); + va_end(args); + return is_open; +} + +bool ImGui::TreeNode(const char* str_id, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + bool is_open = TreeNodeExV(str_id, 0, fmt, args); + va_end(args); + return is_open; +} + +bool ImGui::TreeNode(const void* ptr_id, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + bool is_open = TreeNodeExV(ptr_id, 0, fmt, args); + va_end(args); + return is_open; +} + +bool ImGui::TreeNode(const char* label) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + return TreeNodeBehavior(window->GetID(label), 0, label, NULL); +} + +void ImGui::TreeAdvanceToLabelPos() +{ + ImGuiContext& g = *GImGui; + g.CurrentWindow->DC.CursorPos.x += GetTreeNodeToLabelSpacing(); +} + +// Horizontal distance preceeding label when using TreeNode() or Bullet() +float ImGui::GetTreeNodeToLabelSpacing() +{ + ImGuiContext& g = *GImGui; + return g.FontSize + (g.Style.FramePadding.x * 2.0f); +} + +void ImGui::SetNextTreeNodeOpen(bool is_open, ImGuiSetCond cond) +{ + ImGuiContext& g = *GImGui; + g.SetNextTreeNodeOpenVal = is_open; + g.SetNextTreeNodeOpenCond = cond ? cond : ImGuiSetCond_Always; +} + +void ImGui::PushID(const char* str_id) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->IDStack.push_back(window->GetID(str_id)); +} + +void ImGui::PushID(const char* str_id_begin, const char* str_id_end) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->IDStack.push_back(window->GetID(str_id_begin, str_id_end)); +} + +void ImGui::PushID(const void* ptr_id) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->IDStack.push_back(window->GetID(ptr_id)); +} + +void ImGui::PushID(int int_id) +{ + const void* ptr_id = (void*)(intptr_t)int_id; + ImGuiWindow* window = GetCurrentWindow(); + window->IDStack.push_back(window->GetID(ptr_id)); +} + +void ImGui::PopID() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->IDStack.pop_back(); +} + +ImGuiID ImGui::GetID(const char* str_id) +{ + return GImGui->CurrentWindow->GetID(str_id); +} + +ImGuiID ImGui::GetID(const char* str_id_begin, const char* str_id_end) +{ + return GImGui->CurrentWindow->GetID(str_id_begin, str_id_end); +} + +ImGuiID ImGui::GetID(const void* ptr_id) +{ + return GImGui->CurrentWindow->GetID(ptr_id); +} + +void ImGui::Bullet() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const float line_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y*2), g.FontSize); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize, line_height)); + ItemSize(bb); + if (!ItemAdd(bb, NULL)) + { + SameLine(0, style.FramePadding.x*2); + return; + } + + // Render and stay on same line + RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f)); + SameLine(0, style.FramePadding.x*2); +} + +// Text with a little bullet aligned to the typical tree node. +void ImGui::BulletTextV(const char* fmt, va_list args) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + + const char* text_begin = g.TempBuffer; + const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + const ImVec2 label_size = CalcTextSize(text_begin, text_end, false); + const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset); // Latch before ItemSize changes it + const float line_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y*2), g.FontSize); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x*2) : 0.0f), ImMax(line_height, label_size.y))); // Empty text doesn't add padding + ItemSize(bb); + if (!ItemAdd(bb, NULL)) + return; + + // Render + RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f)); + RenderText(bb.Min+ImVec2(g.FontSize + style.FramePadding.x*2, text_base_offset_y), text_begin, text_end, false); +} + +void ImGui::BulletText(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + BulletTextV(fmt, args); + va_end(args); +} + +static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, const char* display_format, char* buf, int buf_size) +{ + if (data_type == ImGuiDataType_Int) + ImFormatString(buf, buf_size, display_format, *(int*)data_ptr); + else if (data_type == ImGuiDataType_Float) + ImFormatString(buf, buf_size, display_format, *(float*)data_ptr); +} + +static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, int decimal_precision, char* buf, int buf_size) +{ + if (data_type == ImGuiDataType_Int) + { + if (decimal_precision < 0) + ImFormatString(buf, buf_size, "%d", *(int*)data_ptr); + else + ImFormatString(buf, buf_size, "%.*d", decimal_precision, *(int*)data_ptr); + } + else if (data_type == ImGuiDataType_Float) + { + if (decimal_precision < 0) + ImFormatString(buf, buf_size, "%f", *(float*)data_ptr); // Ideally we'd have a minimum decimal precision of 1 to visually denote that it is a float, while hiding non-significant digits? + else + ImFormatString(buf, buf_size, "%.*f", decimal_precision, *(float*)data_ptr); + } +} + +static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* value1, const void* value2)// Store into value1 +{ + if (data_type == ImGuiDataType_Int) + { + if (op == '+') + *(int*)value1 = *(int*)value1 + *(const int*)value2; + else if (op == '-') + *(int*)value1 = *(int*)value1 - *(const int*)value2; + } + else if (data_type == ImGuiDataType_Float) + { + if (op == '+') + *(float*)value1 = *(float*)value1 + *(const float*)value2; + else if (op == '-') + *(float*)value1 = *(float*)value1 - *(const float*)value2; + } +} + +// User can input math operators (e.g. +100) to edit a numerical values. +static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format) +{ + while (ImCharIsSpace(*buf)) + buf++; + + // We don't support '-' op because it would conflict with inputing negative value. + // Instead you can use +-100 to subtract from an existing value + char op = buf[0]; + if (op == '+' || op == '*' || op == '/') + { + buf++; + while (ImCharIsSpace(*buf)) + buf++; + } + else + { + op = 0; + } + if (!buf[0]) + return false; + + if (data_type == ImGuiDataType_Int) + { + if (!scalar_format) + scalar_format = "%d"; + int* v = (int*)data_ptr; + const int old_v = *v; + int arg0 = *v; + if (op && sscanf(initial_value_buf, scalar_format, &arg0) < 1) + return false; + + // Store operand in a float so we can use fractional value for multipliers (*1.1), but constant always parsed as integer so we can fit big integers (e.g. 2000000003) past float precision + float arg1 = 0.0f; + if (op == '+') { if (sscanf(buf, "%f", &arg1) == 1) *v = (int)(arg0 + arg1); } // Add (use "+-" to subtract) + else if (op == '*') { if (sscanf(buf, "%f", &arg1) == 1) *v = (int)(arg0 * arg1); } // Multiply + else if (op == '/') { if (sscanf(buf, "%f", &arg1) == 1 && arg1 != 0.0f) *v = (int)(arg0 / arg1); }// Divide + else { if (sscanf(buf, scalar_format, &arg0) == 1) *v = arg0; } // Assign constant + return (old_v != *v); + } + else if (data_type == ImGuiDataType_Float) + { + // For floats we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in + scalar_format = "%f"; + float* v = (float*)data_ptr; + const float old_v = *v; + float arg0 = *v; + if (op && sscanf(initial_value_buf, scalar_format, &arg0) < 1) + return false; + + float arg1 = 0.0f; + if (sscanf(buf, scalar_format, &arg1) < 1) + return false; + if (op == '+') { *v = arg0 + arg1; } // Add (use "+-" to subtract) + else if (op == '*') { *v = arg0 * arg1; } // Multiply + else if (op == '/') { if (arg1 != 0.0f) *v = arg0 / arg1; } // Divide + else { *v = arg1; } // Assign constant + return (old_v != *v); + } + + return false; +} + +// Create text input in place of a slider (when CTRL+Clicking on slider) +bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + // Our replacement widget will override the focus ID (registered previously to allow for a TAB focus to happen) + SetActiveID(g.ScalarAsInputTextId, window); + SetHoveredID(0); + FocusableItemUnregister(window); + + char buf[32]; + DataTypeFormatString(data_type, data_ptr, decimal_precision, buf, IM_ARRAYSIZE(buf)); + bool text_value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), aabb.GetSize(), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll); + if (g.ScalarAsInputTextId == 0) + { + // First frame + IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID (else we'd need to store them both, which is also possible) + g.ScalarAsInputTextId = g.ActiveId; + SetHoveredID(id); + } + else if (g.ActiveId != g.ScalarAsInputTextId) + { + // Release + g.ScalarAsInputTextId = 0; + } + if (text_value_changed) + return DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, NULL); + return false; +} + +// Parse display precision back from the display format string +int ImGui::ParseFormatPrecision(const char* fmt, int default_precision) +{ + int precision = default_precision; + while ((fmt = strchr(fmt, '%')) != NULL) + { + fmt++; + if (fmt[0] == '%') { fmt++; continue; } // Ignore "%%" + while (*fmt >= '0' && *fmt <= '9') + fmt++; + if (*fmt == '.') + { + precision = atoi(fmt + 1); + if (precision < 0 || precision > 10) + precision = default_precision; + } + break; + } + return precision; +} + +float ImGui::RoundScalar(float value, int decimal_precision) +{ + // Round past decimal precision + // So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0 + // FIXME: Investigate better rounding methods + static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f }; + float min_step = (decimal_precision >= 0 && decimal_precision < 10) ? min_steps[decimal_precision] : powf(10.0f, (float)-decimal_precision); + bool negative = value < 0.0f; + value = fabsf(value); + float remainder = fmodf(value, min_step); + if (remainder <= min_step*0.5f) + value -= remainder; + else + value += (min_step - remainder); + return negative ? -value : value; +} + +bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + const ImGuiStyle& style = g.Style; + + // Draw frame + RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + + const bool is_non_linear = fabsf(power - 1.0f) > 0.0001f; + const bool is_horizontal = (flags & ImGuiSliderFlags_Vertical) == 0; + + const float grab_padding = 2.0f; + const float slider_sz = is_horizontal ? (frame_bb.GetWidth() - grab_padding * 2.0f) : (frame_bb.GetHeight() - grab_padding * 2.0f); + float grab_sz; + if (decimal_precision > 0) + grab_sz = ImMin(style.GrabMinSize, slider_sz); + else + grab_sz = ImMin(ImMax(1.0f * (slider_sz / (v_max-v_min+1.0f)), style.GrabMinSize), slider_sz); // Integer sliders, if possible have the grab size represent 1 unit + const float slider_usable_sz = slider_sz - grab_sz; + const float slider_usable_pos_min = (is_horizontal ? frame_bb.Min.x : frame_bb.Min.y) + grab_padding + grab_sz*0.5f; + const float slider_usable_pos_max = (is_horizontal ? frame_bb.Max.x : frame_bb.Max.y) - grab_padding - grab_sz*0.5f; + + // For logarithmic sliders that cross over sign boundary we want the exponential increase to be symmetric around 0.0f + float linear_zero_pos = 0.0f; // 0.0->1.0f + if (v_min * v_max < 0.0f) + { + // Different sign + const float linear_dist_min_to_0 = powf(fabsf(0.0f - v_min), 1.0f/power); + const float linear_dist_max_to_0 = powf(fabsf(v_max - 0.0f), 1.0f/power); + linear_zero_pos = linear_dist_min_to_0 / (linear_dist_min_to_0+linear_dist_max_to_0); + } + else + { + // Same sign + linear_zero_pos = v_min < 0.0f ? 1.0f : 0.0f; + } + + // Process clicking on the slider + bool value_changed = false; + if (g.ActiveId == id) + { + if (g.IO.MouseDown[0]) + { + const float mouse_abs_pos = is_horizontal ? g.IO.MousePos.x : g.IO.MousePos.y; + float normalized_pos = ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f); + if (!is_horizontal) + normalized_pos = 1.0f - normalized_pos; + + float new_value; + if (is_non_linear) + { + // Account for logarithmic scale on both sides of the zero + if (normalized_pos < linear_zero_pos) + { + // Negative: rescale to the negative range before powering + float a = 1.0f - (normalized_pos / linear_zero_pos); + a = powf(a, power); + new_value = ImLerp(ImMin(v_max,0.0f), v_min, a); + } + else + { + // Positive: rescale to the positive range before powering + float a; + if (fabsf(linear_zero_pos - 1.0f) > 1.e-6f) + a = (normalized_pos - linear_zero_pos) / (1.0f - linear_zero_pos); + else + a = normalized_pos; + a = powf(a, power); + new_value = ImLerp(ImMax(v_min,0.0f), v_max, a); + } + } + else + { + // Linear slider + new_value = ImLerp(v_min, v_max, normalized_pos); + } + + // Round past decimal precision + new_value = RoundScalar(new_value, decimal_precision); + if (*v != new_value) + { + *v = new_value; + value_changed = true; + } + } + else + { + SetActiveID(0); + } + } + + // Calculate slider grab positioning + float grab_t; + if (is_non_linear) + { + float v_clamped = ImClamp(*v, v_min, v_max); + if (v_clamped < 0.0f) + { + const float f = 1.0f - (v_clamped - v_min) / (ImMin(0.0f,v_max) - v_min); + grab_t = (1.0f - powf(f, 1.0f/power)) * linear_zero_pos; + } + else + { + const float f = (v_clamped - ImMax(0.0f,v_min)) / (v_max - ImMax(0.0f,v_min)); + grab_t = linear_zero_pos + powf(f, 1.0f/power) * (1.0f - linear_zero_pos); + } + } + else + { + // Linear slider + grab_t = (ImClamp(*v, v_min, v_max) - v_min) / (v_max - v_min); + } + + // Draw + if (!is_horizontal) + grab_t = 1.0f - grab_t; + const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); + ImRect grab_bb; + if (is_horizontal) + grab_bb = ImRect(ImVec2(grab_pos - grab_sz*0.5f, frame_bb.Min.y + grab_padding), ImVec2(grab_pos + grab_sz*0.5f, frame_bb.Max.y - grab_padding)); + else + grab_bb = ImRect(ImVec2(frame_bb.Min.x + grab_padding, grab_pos - grab_sz*0.5f), ImVec2(frame_bb.Max.x - grab_padding, grab_pos + grab_sz*0.5f)); + window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding); + + return value_changed; +} + +// Use power!=1.0 for logarithmic sliders. +// Adjust display_format to decorate the value with a prefix or a suffix. +// "%.3f" 1.234 +// "%5.2f secs" 01.23 secs +// "Gold: %.0f" Gold: 1 +bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format, float power) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const float w = CalcItemWidth(); + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f)); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + + // NB- we don't call ItemSize() yet because we may turn into a text edit box below + if (!ItemAdd(total_bb, &id)) + { + ItemSize(total_bb, style.FramePadding.y); + return false; + } + + const bool hovered = IsHovered(frame_bb, id); + if (hovered) + SetHoveredID(id); + + if (!display_format) + display_format = "%.3f"; + int decimal_precision = ParseFormatPrecision(display_format, 3); + + // Tabbing or CTRL-clicking on Slider turns it into an input box + bool start_text_input = false; + const bool tab_focus_requested = FocusableItemRegister(window, g.ActiveId == id); + if (tab_focus_requested || (hovered && g.IO.MouseClicked[0])) + { + SetActiveID(id, window); + FocusWindow(window); + + if (tab_focus_requested || g.IO.KeyCtrl) + { + start_text_input = true; + g.ScalarAsInputTextId = 0; + } + } + if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) + return InputScalarAsWidgetReplacement(frame_bb, label, ImGuiDataType_Float, v, id, decimal_precision); + + ItemSize(total_bb, style.FramePadding.y); + + // Actual slider behavior + render grab + const bool value_changed = SliderBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision); + + // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. + char value_buf[64]; + const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); + RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImGuiAlign_Center|ImGuiAlign_VCenter); + + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + + return value_changed; +} + +bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format, float power) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size); + const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + + ItemSize(bb, style.FramePadding.y); + if (!ItemAdd(frame_bb, &id)) + return false; + + const bool hovered = IsHovered(frame_bb, id); + if (hovered) + SetHoveredID(id); + + if (!display_format) + display_format = "%.3f"; + int decimal_precision = ParseFormatPrecision(display_format, 3); + + if (hovered && g.IO.MouseClicked[0]) + { + SetActiveID(id, window); + FocusWindow(window); + } + + // Actual slider behavior + render grab + bool value_changed = SliderBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision, ImGuiSliderFlags_Vertical); + + // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. + // For the vertical slider we allow centered text to overlap the frame padding + char value_buf[64]; + char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); + RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImGuiAlign_Center); + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + + return value_changed; +} + +bool ImGui::SliderAngle(const char* label, float* v_rad, float v_degrees_min, float v_degrees_max) +{ + float v_deg = (*v_rad) * 360.0f / (2*IM_PI); + bool value_changed = SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, "%.0f deg", 1.0f); + *v_rad = v_deg * (2*IM_PI) / 360.0f; + return value_changed; +} + +bool ImGui::SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format) +{ + if (!display_format) + display_format = "%.0f"; + float v_f = (float)*v; + bool value_changed = SliderFloat(label, &v_f, (float)v_min, (float)v_max, display_format, 1.0f); + *v = (int)v_f; + return value_changed; +} + +bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format) +{ + if (!display_format) + display_format = "%.0f"; + float v_f = (float)*v; + bool value_changed = VSliderFloat(label, size, &v_f, (float)v_min, (float)v_max, display_format, 1.0f); + *v = (int)v_f; + return value_changed; +} + +// Add multiple sliders on 1 line for compact edition of multiple components +bool ImGui::SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components); + for (int i = 0; i < components; i++) + { + PushID(i); + value_changed |= SliderFloat("##v", &v[i], v_min, v_max, display_format, power); + SameLine(0, g.Style.ItemInnerSpacing.x); + PopID(); + PopItemWidth(); + } + PopID(); + + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); + + return value_changed; +} + +bool ImGui::SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format, float power) +{ + return SliderFloatN(label, v, 2, v_min, v_max, display_format, power); +} + +bool ImGui::SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format, float power) +{ + return SliderFloatN(label, v, 3, v_min, v_max, display_format, power); +} + +bool ImGui::SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format, float power) +{ + return SliderFloatN(label, v, 4, v_min, v_max, display_format, power); +} + +bool ImGui::SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components); + for (int i = 0; i < components; i++) + { + PushID(i); + value_changed |= SliderInt("##v", &v[i], v_min, v_max, display_format); + SameLine(0, g.Style.ItemInnerSpacing.x); + PopID(); + PopItemWidth(); + } + PopID(); + + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); + + return value_changed; +} + +bool ImGui::SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format) +{ + return SliderIntN(label, v, 2, v_min, v_max, display_format); +} + +bool ImGui::SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format) +{ + return SliderIntN(label, v, 3, v_min, v_max, display_format); +} + +bool ImGui::SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format) +{ + return SliderIntN(label, v, 4, v_min, v_max, display_format); +} + +bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power) +{ + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + + // Draw frame + const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); + RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding); + + bool value_changed = false; + + // Process clicking on the drag + if (g.ActiveId == id) + { + if (g.IO.MouseDown[0]) + { + if (g.ActiveIdIsJustActivated) + { + // Lock current value on click + g.DragCurrentValue = *v; + g.DragLastMouseDelta = ImVec2(0.f, 0.f); + } + + float v_cur = g.DragCurrentValue; + const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f); + if (fabsf(mouse_drag_delta.x - g.DragLastMouseDelta.x) > 0.0f) + { + float speed = v_speed; + if (speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX) + speed = (v_max - v_min) * g.DragSpeedDefaultRatio; + if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f) + speed = speed * g.DragSpeedScaleFast; + if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) + speed = speed * g.DragSpeedScaleSlow; + + float delta = (mouse_drag_delta.x - g.DragLastMouseDelta.x) * speed; + if (fabsf(power - 1.0f) > 0.001f) + { + // Logarithmic curve on both side of 0.0 + float v0_abs = v_cur >= 0.0f ? v_cur : -v_cur; + float v0_sign = v_cur >= 0.0f ? 1.0f : -1.0f; + float v1 = powf(v0_abs, 1.0f / power) + (delta * v0_sign); + float v1_abs = v1 >= 0.0f ? v1 : -v1; + float v1_sign = v1 >= 0.0f ? 1.0f : -1.0f; // Crossed sign line + v_cur = powf(v1_abs, power) * v0_sign * v1_sign; // Reapply sign + } + else + { + v_cur += delta; + } + g.DragLastMouseDelta.x = mouse_drag_delta.x; + + // Clamp + if (v_min < v_max) + v_cur = ImClamp(v_cur, v_min, v_max); + g.DragCurrentValue = v_cur; + } + + // Round to user desired precision, then apply + v_cur = RoundScalar(v_cur, decimal_precision); + if (*v != v_cur) + { + *v = v_cur; + value_changed = true; + } + } + else + { + SetActiveID(0); + } + } + + return value_changed; +} + +bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const float w = CalcItemWidth(); + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f)); + const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + + // NB- we don't call ItemSize() yet because we may turn into a text edit box below + if (!ItemAdd(total_bb, &id)) + { + ItemSize(total_bb, style.FramePadding.y); + return false; + } + + const bool hovered = IsHovered(frame_bb, id); + if (hovered) + SetHoveredID(id); + + if (!display_format) + display_format = "%.3f"; + int decimal_precision = ParseFormatPrecision(display_format, 3); + + // Tabbing or CTRL-clicking on Drag turns it into an input box + bool start_text_input = false; + const bool tab_focus_requested = FocusableItemRegister(window, g.ActiveId == id); + if (tab_focus_requested || (hovered && (g.IO.MouseClicked[0] | g.IO.MouseDoubleClicked[0]))) + { + SetActiveID(id, window); + FocusWindow(window); + + if (tab_focus_requested || g.IO.KeyCtrl || g.IO.MouseDoubleClicked[0]) + { + start_text_input = true; + g.ScalarAsInputTextId = 0; + } + } + if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) + return InputScalarAsWidgetReplacement(frame_bb, label, ImGuiDataType_Float, v, id, decimal_precision); + + // Actual drag behavior + ItemSize(total_bb, style.FramePadding.y); + const bool value_changed = DragBehavior(frame_bb, id, v, v_speed, v_min, v_max, decimal_precision, power); + + // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. + char value_buf[64]; + const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); + RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImGuiAlign_Center|ImGuiAlign_VCenter); + + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); + + return value_changed; +} + +bool ImGui::DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components); + for (int i = 0; i < components; i++) + { + PushID(i); + value_changed |= DragFloat("##v", &v[i], v_speed, v_min, v_max, display_format, power); + SameLine(0, g.Style.ItemInnerSpacing.x); + PopID(); + PopItemWidth(); + } + PopID(); + + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); + + return value_changed; +} + +bool ImGui::DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + return DragFloatN(label, v, 2, v_speed, v_min, v_max, display_format, power); +} + +bool ImGui::DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + return DragFloatN(label, v, 3, v_speed, v_min, v_max, display_format, power); +} + +bool ImGui::DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* display_format, float power) +{ + return DragFloatN(label, v, 4, v_speed, v_min, v_max, display_format, power); +} + +bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const char* display_format, const char* display_format_max, float power) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + PushID(label); + BeginGroup(); + PushMultiItemsWidths(2); + + bool value_changed = DragFloat("##min", v_current_min, v_speed, (v_min >= v_max) ? -FLT_MAX : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format, power); + PopItemWidth(); + SameLine(0, g.Style.ItemInnerSpacing.x); + value_changed |= DragFloat("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? FLT_MAX : v_max, display_format_max ? display_format_max : display_format, power); + PopItemWidth(); + SameLine(0, g.Style.ItemInnerSpacing.x); + + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); + PopID(); + + return value_changed; +} + +// NB: v_speed is float to allow adjusting the drag speed with more precision +bool ImGui::DragInt(const char* label, int* v, float v_speed, int v_min, int v_max, const char* display_format) +{ + if (!display_format) + display_format = "%.0f"; + float v_f = (float)*v; + bool value_changed = DragFloat(label, &v_f, v_speed, (float)v_min, (float)v_max, display_format); + *v = (int)v_f; + return value_changed; +} + +bool ImGui::DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components); + for (int i = 0; i < components; i++) + { + PushID(i); + value_changed |= DragInt("##v", &v[i], v_speed, v_min, v_max, display_format); + SameLine(0, g.Style.ItemInnerSpacing.x); + PopID(); + PopItemWidth(); + } + PopID(); + + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); + + return value_changed; +} + +bool ImGui::DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* display_format) +{ + return DragIntN(label, v, 2, v_speed, v_min, v_max, display_format); +} + +bool ImGui::DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* display_format) +{ + return DragIntN(label, v, 3, v_speed, v_min, v_max, display_format); +} + +bool ImGui::DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* display_format) +{ + return DragIntN(label, v, 4, v_speed, v_min, v_max, display_format); +} + +bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const char* display_format, const char* display_format_max) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + PushID(label); + BeginGroup(); + PushMultiItemsWidths(2); + + bool value_changed = DragInt("##min", v_current_min, v_speed, (v_min >= v_max) ? INT_MIN : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format); + PopItemWidth(); + SameLine(0, g.Style.ItemInnerSpacing.x); + value_changed |= DragInt("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? INT_MAX : v_max, display_format_max ? display_format_max : display_format); + PopItemWidth(); + SameLine(0, g.Style.ItemInnerSpacing.x); + + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); + PopID(); + + return value_changed; +} + +void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + if (graph_size.x == 0.0f) + graph_size.x = CalcItemWidth(); + if (graph_size.y == 0.0f) + graph_size.y = label_size.y + (style.FramePadding.y * 2); + + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y)); + const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, NULL)) + return; + + // Determine scale from values if not specified + if (scale_min == FLT_MAX || scale_max == FLT_MAX) + { + float v_min = FLT_MAX; + float v_max = -FLT_MAX; + for (int i = 0; i < values_count; i++) + { + const float v = values_getter(data, i); + v_min = ImMin(v_min, v); + v_max = ImMax(v_max, v); + } + if (scale_min == FLT_MAX) + scale_min = v_min; + if (scale_max == FLT_MAX) + scale_max = v_max; + } + + RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + + int res_w = ImMin((int)graph_size.x, values_count) + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0); + int item_count = values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0); + + // Tooltip on hover + int v_hovered = -1; + if (IsHovered(inner_bb, 0)) + { + const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.9999f); + const int v_idx = (int)(t * item_count); + IM_ASSERT(v_idx >= 0 && v_idx < values_count); + + const float v0 = values_getter(data, (v_idx + values_offset) % values_count); + const float v1 = values_getter(data, (v_idx + 1 + values_offset) % values_count); + if (plot_type == ImGuiPlotType_Lines) + SetTooltip("%d: %8.4g\n%d: %8.4g", v_idx, v0, v_idx+1, v1); + else if (plot_type == ImGuiPlotType_Histogram) + SetTooltip("%d: %8.4g", v_idx, v0); + v_hovered = v_idx; + } + + const float t_step = 1.0f / (float)res_w; + + float v0 = values_getter(data, (0 + values_offset) % values_count); + float t0 = 0.0f; + ImVec2 tp0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) / (scale_max - scale_min)) ); // Point in the normalized space of our target rectangle + + const ImU32 col_base = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram); + const ImU32 col_hovered = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered); + + for (int n = 0; n < res_w; n++) + { + const float t1 = t0 + t_step; + const int v1_idx = (int)(t0 * item_count + 0.5f); + IM_ASSERT(v1_idx >= 0 && v1_idx < values_count); + const float v1 = values_getter(data, (v1_idx + values_offset + 1) % values_count); + const ImVec2 tp1 = ImVec2( t1, 1.0f - ImSaturate((v1 - scale_min) / (scale_max - scale_min)) ); + + // NB: Draw calls are merged together by the DrawList system. Still, we should render our batch are lower level to save a bit of CPU. + ImVec2 pos0 = ImLerp(inner_bb.Min, inner_bb.Max, tp0); + ImVec2 pos1 = ImLerp(inner_bb.Min, inner_bb.Max, (plot_type == ImGuiPlotType_Lines) ? tp1 : ImVec2(tp1.x, 1.0f)); + if (plot_type == ImGuiPlotType_Lines) + { + window->DrawList->AddLine(pos0, pos1, v_hovered == v1_idx ? col_hovered : col_base); + } + else if (plot_type == ImGuiPlotType_Histogram) + { + if (pos1.x >= pos0.x + 2.0f) + pos1.x -= 1.0f; + window->DrawList->AddRectFilled(pos0, pos1, v_hovered == v1_idx ? col_hovered : col_base); + } + + t0 = t1; + tp0 = tp1; + } + + // Text overlay + if (overlay_text) + RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, overlay_text, NULL, NULL, ImGuiAlign_Center); + + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); +} + +struct ImGuiPlotArrayGetterData +{ + const float* Values; + int Stride; + + ImGuiPlotArrayGetterData(const float* values, int stride) { Values = values; Stride = stride; } +}; + +static float Plot_ArrayGetter(void* data, int idx) +{ + ImGuiPlotArrayGetterData* plot_data = (ImGuiPlotArrayGetterData*)data; + const float v = *(float*)(void*)((unsigned char*)plot_data->Values + (size_t)idx * plot_data->Stride); + return v; +} + +void ImGui::PlotLines(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride) +{ + ImGuiPlotArrayGetterData data(values, stride); + PlotEx(ImGuiPlotType_Lines, label, &Plot_ArrayGetter, (void*)&data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); +} + +void ImGui::PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) +{ + PlotEx(ImGuiPlotType_Lines, label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); +} + +void ImGui::PlotHistogram(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride) +{ + ImGuiPlotArrayGetterData data(values, stride); + PlotEx(ImGuiPlotType_Histogram, label, &Plot_ArrayGetter, (void*)&data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); +} + +void ImGui::PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) +{ + PlotEx(ImGuiPlotType_Histogram, label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); +} + +// size_arg (for each axis) < 0.0f: align to end, 0.0f: auto, > 0.0f: specified size +void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* overlay) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + + ImVec2 pos = window->DC.CursorPos; + ImRect bb(pos, pos + CalcItemSize(size_arg, CalcItemWidth(), g.FontSize + style.FramePadding.y*2.0f)); + ItemSize(bb, style.FramePadding.y); + if (!ItemAdd(bb, NULL)) + return; + + // Render + fraction = ImSaturate(fraction); + RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + bb.Reduce(ImVec2(window->BorderSize, window->BorderSize)); + const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y); + RenderFrame(bb.Min, fill_br, GetColorU32(ImGuiCol_PlotHistogram), false, style.FrameRounding); + + // Default displaying the fraction as percentage string, but user can override it + char overlay_buf[32]; + if (!overlay) + { + ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction*100+0.01f); + overlay = overlay_buf; + } + + ImVec2 overlay_size = CalcTextSize(overlay, NULL); + if (overlay_size.x > 0.0f) + RenderTextClipped(ImVec2(ImClamp(fill_br.x + style.ItemSpacing.x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImGuiAlign_Left|ImGuiAlign_VCenter, &bb.Min, &bb.Max); +} + +bool ImGui::Checkbox(const char* label, bool* v) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2, label_size.y + style.FramePadding.y*2)); + ItemSize(check_bb, style.FramePadding.y); + + ImRect total_bb = check_bb; + if (label_size.x > 0) + SameLine(0, style.ItemInnerSpacing.x); + const ImRect text_bb(window->DC.CursorPos + ImVec2(0,style.FramePadding.y), window->DC.CursorPos + ImVec2(0,style.FramePadding.y) + label_size); + if (label_size.x > 0) + { + ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); + total_bb = ImRect(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max)); + } + + if (!ItemAdd(total_bb, &id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(total_bb, id, &hovered, &held); + if (pressed) + *v = !(*v); + + RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); + if (*v) + { + const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight()); + const float pad = ImMax(1.0f, (float)(int)(check_sz / 6.0f)); + window->DrawList->AddRectFilled(check_bb.Min+ImVec2(pad,pad), check_bb.Max-ImVec2(pad,pad), GetColorU32(ImGuiCol_CheckMark), style.FrameRounding); + } + + if (g.LogEnabled) + LogRenderedText(text_bb.GetTL(), *v ? "[x]" : "[ ]"); + if (label_size.x > 0.0f) + RenderText(text_bb.GetTL(), label); + + return pressed; +} + +bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value) +{ + bool v = ((*flags & flags_value) == flags_value); + bool pressed = Checkbox(label, &v); + if (pressed) + { + if (v) + *flags |= flags_value; + else + *flags &= ~flags_value; + } + + return pressed; +} + +bool ImGui::RadioButton(const char* label, bool active) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2-1, label_size.y + style.FramePadding.y*2-1)); + ItemSize(check_bb, style.FramePadding.y); + + ImRect total_bb = check_bb; + if (label_size.x > 0) + SameLine(0, style.ItemInnerSpacing.x); + const ImRect text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + label_size); + if (label_size.x > 0) + { + ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); + total_bb.Add(text_bb); + } + + if (!ItemAdd(total_bb, &id)) + return false; + + ImVec2 center = check_bb.GetCenter(); + center.x = (float)(int)center.x + 0.5f; + center.y = (float)(int)center.y + 0.5f; + const float radius = check_bb.GetHeight() * 0.5f; + + bool hovered, held; + bool pressed = ButtonBehavior(total_bb, id, &hovered, &held); + + window->DrawList->AddCircleFilled(center, radius, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), 16); + if (active) + { + const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight()); + const float pad = ImMax(1.0f, (float)(int)(check_sz / 6.0f)); + window->DrawList->AddCircleFilled(center, radius-pad, GetColorU32(ImGuiCol_CheckMark), 16); + } + + if (window->Flags & ImGuiWindowFlags_ShowBorders) + { + window->DrawList->AddCircle(center+ImVec2(1,1), radius, GetColorU32(ImGuiCol_BorderShadow), 16); + window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16); + } + + if (g.LogEnabled) + LogRenderedText(text_bb.GetTL(), active ? "(x)" : "( )"); + if (label_size.x > 0.0f) + RenderText(text_bb.GetTL(), label); + + return pressed; +} + +bool ImGui::RadioButton(const char* label, int* v, int v_button) +{ + const bool pressed = RadioButton(label, *v == v_button); + if (pressed) + { + *v = v_button; + } + return pressed; +} + +static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end) +{ + int line_count = 0; + const char* s = text_begin; + while (char c = *s++) // We are only matching for \n so we can ignore UTF-8 decoding + if (c == '\n') + line_count++; + s--; + if (s[0] != '\n' && s[0] != '\r') + line_count++; + *out_text_end = s; + return line_count; +} + +static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining, ImVec2* out_offset, bool stop_on_new_line) +{ + ImFont* font = GImGui->Font; + const float line_height = GImGui->FontSize; + const float scale = line_height / font->FontSize; + + ImVec2 text_size = ImVec2(0,0); + float line_width = 0.0f; + + const ImWchar* s = text_begin; + while (s < text_end) + { + unsigned int c = (unsigned int)(*s++); + if (c == '\n') + { + text_size.x = ImMax(text_size.x, line_width); + text_size.y += line_height; + line_width = 0.0f; + if (stop_on_new_line) + break; + continue; + } + if (c == '\r') + continue; + + const float char_width = font->GetCharAdvance((unsigned short)c) * scale; + line_width += char_width; + } + + if (text_size.x < line_width) + text_size.x = line_width; + + if (out_offset) + *out_offset = ImVec2(line_width, text_size.y + line_height); // offset allow for the possibility of sitting after a trailing \n + + if (line_width > 0 || text_size.y == 0.0f) // whereas size.y will ignore the trailing \n + text_size.y += line_height; + + if (remaining) + *remaining = s; + + return text_size; +} + +// Wrapper for stb_textedit.h to edit text (our wrapper is for: statically sized buffer, single-line, wchar characters. InputText converts between UTF-8 and wchar) +namespace ImGuiStb +{ + +static int STB_TEXTEDIT_STRINGLEN(const STB_TEXTEDIT_STRING* obj) { return obj->CurLenW; } +static ImWchar STB_TEXTEDIT_GETCHAR(const STB_TEXTEDIT_STRING* obj, int idx) { return obj->Text[idx]; } +static float STB_TEXTEDIT_GETWIDTH(STB_TEXTEDIT_STRING* obj, int line_start_idx, int char_idx) { ImWchar c = obj->Text[line_start_idx+char_idx]; if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; return GImGui->Font->GetCharAdvance(c) * (GImGui->FontSize / GImGui->Font->FontSize); } +static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x10000 ? 0 : key; } +static ImWchar STB_TEXTEDIT_NEWLINE = '\n'; +static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* obj, int line_start_idx) +{ + const ImWchar* text = obj->Text.Data; + const ImWchar* text_remaining = NULL; + const ImVec2 size = InputTextCalcTextSizeW(text + line_start_idx, text + obj->CurLenW, &text_remaining, NULL, true); + r->x0 = 0.0f; + r->x1 = size.x; + r->baseline_y_delta = size.y; + r->ymin = 0.0f; + r->ymax = size.y; + r->num_chars = (int)(text_remaining - (text + line_start_idx)); +} + +static bool is_separator(unsigned int c) { return ImCharIsSpace(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; } +static int is_word_boundary_from_right(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (is_separator( obj->Text[idx-1] ) && !is_separator( obj->Text[idx] ) ) : 1; } +static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; } +#ifdef __APPLE__ // FIXME: Move setting to IO structure +static int is_word_boundary_from_left(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (!is_separator( obj->Text[idx-1] ) && is_separator( obj->Text[idx] ) ) : 1; } +static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; } +#else +static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; } +#endif +#define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h +#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_IMPL + +static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n) +{ + ImWchar* dst = obj->Text.Data + pos; + + // We maintain our buffer length in both UTF-8 and wchar formats + obj->CurLenA -= ImTextCountUtf8BytesFromStr(dst, dst + n); + obj->CurLenW -= n; + + // Offset remaining text + const ImWchar* src = obj->Text.Data + pos + n; + while (ImWchar c = *src++) + *dst++ = c; + *dst = '\0'; +} + +static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const ImWchar* new_text, int new_text_len) +{ + const int text_len = obj->CurLenW; + IM_ASSERT(pos <= text_len); + if (new_text_len + text_len + 1 > obj->Text.Size) + return false; + + const int new_text_len_utf8 = ImTextCountUtf8BytesFromStr(new_text, new_text + new_text_len); + if (new_text_len_utf8 + obj->CurLenA + 1 > obj->BufSizeA) + return false; + + ImWchar* text = obj->Text.Data; + if (pos != text_len) + memmove(text + pos + new_text_len, text + pos, (size_t)(text_len - pos) * sizeof(ImWchar)); + memcpy(text + pos, new_text, (size_t)new_text_len * sizeof(ImWchar)); + + obj->CurLenW += new_text_len; + obj->CurLenA += new_text_len_utf8; + obj->Text[obj->CurLenW] = '\0'; + + return true; +} + +// We don't use an enum so we can build even with conflicting symbols (if another user of stb_textedit.h leak their STB_TEXTEDIT_K_* symbols) +#define STB_TEXTEDIT_K_LEFT 0x10000 // keyboard input to move cursor left +#define STB_TEXTEDIT_K_RIGHT 0x10001 // keyboard input to move cursor right +#define STB_TEXTEDIT_K_UP 0x10002 // keyboard input to move cursor up +#define STB_TEXTEDIT_K_DOWN 0x10003 // keyboard input to move cursor down +#define STB_TEXTEDIT_K_LINESTART 0x10004 // keyboard input to move cursor to start of line +#define STB_TEXTEDIT_K_LINEEND 0x10005 // keyboard input to move cursor to end of line +#define STB_TEXTEDIT_K_TEXTSTART 0x10006 // keyboard input to move cursor to start of text +#define STB_TEXTEDIT_K_TEXTEND 0x10007 // keyboard input to move cursor to end of text +#define STB_TEXTEDIT_K_DELETE 0x10008 // keyboard input to delete selection or character under cursor +#define STB_TEXTEDIT_K_BACKSPACE 0x10009 // keyboard input to delete selection or character left of cursor +#define STB_TEXTEDIT_K_UNDO 0x1000A // keyboard input to perform undo +#define STB_TEXTEDIT_K_REDO 0x1000B // keyboard input to perform redo +#define STB_TEXTEDIT_K_WORDLEFT 0x1000C // keyboard input to move cursor left one word +#define STB_TEXTEDIT_K_WORDRIGHT 0x1000D // keyboard input to move cursor right one word +#define STB_TEXTEDIT_K_SHIFT 0x20000 + +#define STB_TEXTEDIT_IMPLEMENTATION +#include "stb_textedit.h" + +} + +void ImGuiTextEditState::OnKeyPressed(int key) +{ + stb_textedit_key(this, &StbState, key); + CursorFollow = true; + CursorAnimReset(); +} + +// Public API to manipulate UTF-8 text +// We expose UTF-8 to the user (unlike the STB_TEXTEDIT_* functions which are manipulating wchar) +// FIXME: The existence of this rarely exercised code path is a bit of a nuisance. +void ImGuiTextEditCallbackData::DeleteChars(int pos, int bytes_count) +{ + IM_ASSERT(pos + bytes_count <= BufTextLen); + char* dst = Buf + pos; + const char* src = Buf + pos + bytes_count; + while (char c = *src++) + *dst++ = c; + *dst = '\0'; + + if (CursorPos + bytes_count >= pos) + CursorPos -= bytes_count; + else if (CursorPos >= pos) + CursorPos = pos; + SelectionStart = SelectionEnd = CursorPos; + BufDirty = true; + BufTextLen -= bytes_count; +} + +void ImGuiTextEditCallbackData::InsertChars(int pos, const char* new_text, const char* new_text_end) +{ + const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)strlen(new_text); + if (new_text_len + BufTextLen + 1 >= BufSize) + return; + + if (BufTextLen != pos) + memmove(Buf + pos + new_text_len, Buf + pos, (size_t)(BufTextLen - pos)); + memcpy(Buf + pos, new_text, (size_t)new_text_len * sizeof(char)); + Buf[BufTextLen + new_text_len] = '\0'; + + if (CursorPos >= pos) + CursorPos += new_text_len; + SelectionStart = SelectionEnd = CursorPos; + BufDirty = true; + BufTextLen += new_text_len; +} + +// Return false to discard a character. +static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) +{ + unsigned int c = *p_char; + + if (c < 128 && c != ' ' && !isprint((int)(c & 0xFF))) + { + bool pass = false; + pass |= (c == '\n' && (flags & ImGuiInputTextFlags_Multiline)); + pass |= (c == '\t' && (flags & ImGuiInputTextFlags_AllowTabInput)); + if (!pass) + return false; + } + + if (c >= 0xE000 && c <= 0xF8FF) // Filter private Unicode range. I don't imagine anybody would want to input them. GLFW on OSX seems to send private characters for special keys like arrow keys. + return false; + + if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank)) + { + if (flags & ImGuiInputTextFlags_CharsDecimal) + if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/')) + return false; + + if (flags & ImGuiInputTextFlags_CharsHexadecimal) + if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) + return false; + + if (flags & ImGuiInputTextFlags_CharsUppercase) + if (c >= 'a' && c <= 'z') + *p_char = (c += (unsigned int)('A'-'a')); + + if (flags & ImGuiInputTextFlags_CharsNoBlank) + if (ImCharIsSpace(c)) + return false; + } + + if (flags & ImGuiInputTextFlags_CallbackCharFilter) + { + ImGuiTextEditCallbackData callback_data; + memset(&callback_data, 0, sizeof(ImGuiTextEditCallbackData)); + callback_data.EventFlag = ImGuiInputTextFlags_CallbackCharFilter; + callback_data.EventChar = (ImWchar)c; + callback_data.Flags = flags; + callback_data.UserData = user_data; + if (callback(&callback_data) != 0) + return false; + *p_char = callback_data.EventChar; + if (!callback_data.EventChar) + return false; + } + + return true; +} + +// Edit a string of text +// NB: when active, hold on a privately held copy of the text (and apply back to 'buf'). So changing 'buf' while active has no effect. +// FIXME: Rather messy function partly because we are doing UTF8 > u16 > UTF8 conversions on the go to more easily handle stb_textedit calls. Ideally we should stay in UTF-8 all the time. See https://github.com/nothings/stb/issues/188 +bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackHistory) && (flags & ImGuiInputTextFlags_Multiline))); // Can't use both together (they both use up/down keys) + IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackCompletion) && (flags & ImGuiInputTextFlags_AllowTabInput))); // Can't use both together (they both use tab key) + + ImGuiContext& g = *GImGui; + const ImGuiIO& io = g.IO; + const ImGuiStyle& style = g.Style; + + const ImGuiID id = window->GetID(label); + const bool is_multiline = (flags & ImGuiInputTextFlags_Multiline) != 0; + const bool is_editable = (flags & ImGuiInputTextFlags_ReadOnly) == 0; + const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0; + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? GetTextLineHeight() * 8.0f : label_size.y) + style.FramePadding.y*2.0f); // Arbitrary default of 8 lines high for multi-line + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f)); + + ImGuiWindow* draw_window = window; + if (is_multiline) + { + BeginGroup(); + if (!BeginChildFrame(id, frame_bb.GetSize())) + { + EndChildFrame(); + EndGroup(); + return false; + } + draw_window = GetCurrentWindow(); + size.x -= draw_window->ScrollbarSizes.x; + } + else + { + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, &id)) + return false; + } + + // Password pushes a temporary font with only a fallback glyph + if (is_password) + { + const ImFont::Glyph* glyph = g.Font->FindGlyph('*'); + ImFont* password_font = &g.InputTextPasswordFont; + password_font->FontSize = g.Font->FontSize; + password_font->Scale = g.Font->Scale; + password_font->DisplayOffset = g.Font->DisplayOffset; + password_font->Ascent = g.Font->Ascent; + password_font->Descent = g.Font->Descent; + password_font->ContainerAtlas = g.Font->ContainerAtlas; + password_font->FallbackGlyph = glyph; + password_font->FallbackXAdvance = glyph->XAdvance; + IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexXAdvance.empty() && password_font->IndexLookup.empty()); + PushFont(password_font); + } + + // NB: we are only allowed to access 'edit_state' if we are the active widget. + ImGuiTextEditState& edit_state = g.InputTextState; + + const bool focus_requested = FocusableItemRegister(window, g.ActiveId == id, (flags & (ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_AllowTabInput)) == 0); // Using completion callback disable keyboard tabbing + const bool focus_requested_by_code = focus_requested && (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent); + const bool focus_requested_by_tab = focus_requested && !focus_requested_by_code; + + const bool hovered = IsHovered(frame_bb, id); + if (hovered) + { + SetHoveredID(id); + g.MouseCursor = ImGuiMouseCursor_TextInput; + } + const bool user_clicked = hovered && io.MouseClicked[0]; + const bool user_scrolled = is_multiline && g.ActiveId == 0 && edit_state.Id == id && g.ActiveIdPreviousFrame == draw_window->GetIDNoKeepAlive("#SCROLLY"); + + bool select_all = (g.ActiveId != id) && (flags & ImGuiInputTextFlags_AutoSelectAll) != 0; + if (focus_requested || user_clicked || user_scrolled) + { + if (g.ActiveId != id) + { + // Start edition + // Take a copy of the initial buffer value (both in original UTF-8 format and converted to wchar) + // From the moment we focused we are ignoring the content of 'buf' (unless we are in read-only mode) + const int prev_len_w = edit_state.CurLenW; + edit_state.Text.resize(buf_size+1); // wchar count <= UTF-8 count. we use +1 to make sure that .Data isn't NULL so it doesn't crash. + edit_state.InitialText.resize(buf_size+1); // UTF-8. we use +1 to make sure that .Data isn't NULL so it doesn't crash. + ImStrncpy(edit_state.InitialText.Data, buf, edit_state.InitialText.Size); + const char* buf_end = NULL; + edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, buf, NULL, &buf_end); + edit_state.CurLenA = (int)(buf_end - buf); // We can't get the result from ImFormatString() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8. + edit_state.CursorAnimReset(); + + // Preserve cursor position and undo/redo stack if we come back to same widget + // FIXME: We should probably compare the whole buffer to be on the safety side. Comparing buf (utf8) and edit_state.Text (wchar). + const bool recycle_state = (edit_state.Id == id) && (prev_len_w == edit_state.CurLenW); + if (recycle_state) + { + // Recycle existing cursor/selection/undo stack but clamp position + // Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler. + edit_state.CursorClamp(); + } + else + { + edit_state.Id = id; + edit_state.ScrollX = 0.0f; + stb_textedit_initialize_state(&edit_state.StbState, !is_multiline); + if (!is_multiline && focus_requested_by_code) + select_all = true; + } + if (flags & ImGuiInputTextFlags_AlwaysInsertMode) + edit_state.StbState.insert_mode = true; + if (!is_multiline && (focus_requested_by_tab || (user_clicked && io.KeyCtrl))) + select_all = true; + } + SetActiveID(id, window); + FocusWindow(window); + } + else if (io.MouseClicked[0]) + { + // Release focus when we click outside + if (g.ActiveId == id) + SetActiveID(0); + } + + bool value_changed = false; + bool enter_pressed = false; + + if (g.ActiveId == id) + { + if (!is_editable && !g.ActiveIdIsJustActivated) + { + // When read-only we always use the live data passed to the function + edit_state.Text.resize(buf_size+1); + const char* buf_end = NULL; + edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, buf, NULL, &buf_end); + edit_state.CurLenA = (int)(buf_end - buf); + edit_state.CursorClamp(); + } + + edit_state.BufSizeA = buf_size; + + // Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget. + // Down the line we should have a cleaner library-wide concept of Selected vs Active. + g.ActiveIdAllowOverlap = !io.MouseDown[0]; + + // Edit in progress + const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX; + const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize*0.5f)); + + const bool osx_double_click_selects_words = io.OSXBehaviors; // OS X style: Double click selects by word instead of selecting whole text + if (select_all || (hovered && !osx_double_click_selects_words && io.MouseDoubleClicked[0])) + { + edit_state.SelectAll(); + edit_state.SelectedAllMouseLock = true; + } + else if (hovered && osx_double_click_selects_words && io.MouseDoubleClicked[0]) + { + // Select a word only, OS X style (by simulating keystrokes) + edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT); + edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT); + } + else if (io.MouseClicked[0] && !edit_state.SelectedAllMouseLock) + { + stb_textedit_click(&edit_state, &edit_state.StbState, mouse_x, mouse_y); + edit_state.CursorAnimReset(); + } + else if (io.MouseDown[0] && !edit_state.SelectedAllMouseLock && (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f)) + { + stb_textedit_drag(&edit_state, &edit_state.StbState, mouse_x, mouse_y); + edit_state.CursorAnimReset(); + edit_state.CursorFollow = true; + } + if (edit_state.SelectedAllMouseLock && !io.MouseDown[0]) + edit_state.SelectedAllMouseLock = false; + + if (io.InputCharacters[0]) + { + // Process text input (before we check for Return because using some IME will effectively send a Return?) + // We ignore CTRL inputs, but need to allow CTRL+ALT as some keyboards (e.g. German) use AltGR - which is Alt+Ctrl - to input certain characters. + if (!(io.KeyCtrl && !io.KeyAlt) && is_editable) + { + for (int n = 0; n < IM_ARRAYSIZE(io.InputCharacters) && io.InputCharacters[n]; n++) + if (unsigned int c = (unsigned int)io.InputCharacters[n]) + { + // Insert character if they pass filtering + if (!InputTextFilterCharacter(&c, flags, callback, user_data)) + continue; + edit_state.OnKeyPressed((int)c); + } + } + + // Consume characters + memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); + } + + // Handle various key-presses + bool cancel_edit = false; + const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0); + const bool is_shortcut_key_only = (io.OSXBehaviors ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl + const bool is_wordmove_key_down = io.OSXBehaviors ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl + const bool is_startend_key_down = io.OSXBehaviors && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End + + if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Delete) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Backspace) && is_editable) + { + if (!edit_state.HasSelection()) + { + if (is_wordmove_key_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT|STB_TEXTEDIT_K_SHIFT); + else if (io.OSXBehaviors && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); + } + edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); + } + else if (IsKeyPressedMap(ImGuiKey_Enter)) + { + bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; + if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl)) + { + SetActiveID(0); + enter_pressed = true; + } + else if (is_editable) + { + unsigned int c = '\n'; // Insert new line + if (InputTextFilterCharacter(&c, flags, callback, user_data)) + edit_state.OnKeyPressed((int)c); + } + } + else if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressedMap(ImGuiKey_Tab) && !io.KeyCtrl && !io.KeyShift && !io.KeyAlt && is_editable) + { + unsigned int c = '\t'; // Insert TAB + if (InputTextFilterCharacter(&c, flags, callback, user_data)) + edit_state.OnKeyPressed((int)c); + } + else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveID(0); cancel_edit = true; } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } + else if (is_shortcut_key_only && !is_password && ((IsKeyPressedMap(ImGuiKey_X) && is_editable) || IsKeyPressedMap(ImGuiKey_C)) && (!is_multiline || edit_state.HasSelection())) + { + // Cut, Copy + const bool cut = IsKeyPressedMap(ImGuiKey_X); + if (cut && !edit_state.HasSelection()) + edit_state.SelectAll(); + + if (io.SetClipboardTextFn) + { + const int ib = edit_state.HasSelection() ? ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end) : 0; + const int ie = edit_state.HasSelection() ? ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end) : edit_state.CurLenW; + edit_state.TempTextBuffer.resize((ie-ib) * 4 + 1); + ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data+ib, edit_state.Text.Data+ie); + io.SetClipboardTextFn(edit_state.TempTextBuffer.Data); + } + + if (cut) + { + edit_state.CursorFollow = true; + stb_textedit_cut(&edit_state, &edit_state.StbState); + } + } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_V) && is_editable) + { + // Paste + if (const char* clipboard = io.GetClipboardTextFn ? io.GetClipboardTextFn() : NULL) + { + // Filter pasted buffer + const int clipboard_len = (int)strlen(clipboard); + ImWchar* clipboard_filtered = (ImWchar*)ImGui::MemAlloc((clipboard_len+1) * sizeof(ImWchar)); + int clipboard_filtered_len = 0; + for (const char* s = clipboard; *s; ) + { + unsigned int c; + s += ImTextCharFromUtf8(&c, s, NULL); + if (c == 0) + break; + if (c >= 0x10000 || !InputTextFilterCharacter(&c, flags, callback, user_data)) + continue; + clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c; + } + clipboard_filtered[clipboard_filtered_len] = 0; + if (clipboard_filtered_len > 0) // If everything was filtered, ignore the pasting operation + { + stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len); + edit_state.CursorFollow = true; + } + ImGui::MemFree(clipboard_filtered); + } + } + + if (cancel_edit) + { + // Restore initial value + if (is_editable) + { + ImStrncpy(buf, edit_state.InitialText.Data, buf_size); + value_changed = true; + } + } + else + { + // Apply new value immediately - copy modified buffer back + // Note that as soon as the input box is active, the in-widget value gets priority over any underlying modification of the input buffer + // FIXME: We actually always render 'buf' when calling DrawList->AddText, making the comment above incorrect. + // FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks. + if (is_editable) + { + edit_state.TempTextBuffer.resize(edit_state.Text.Size * 4); + ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data, NULL); + } + + // User callback + if ((flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackAlways)) != 0) + { + IM_ASSERT(callback != NULL); + + // The reason we specify the usage semantic (Completion/History) is that Completion needs to disable keyboard TABBING at the moment. + ImGuiInputTextFlags event_flag = 0; + ImGuiKey event_key = ImGuiKey_COUNT; + if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && IsKeyPressedMap(ImGuiKey_Tab)) + { + event_flag = ImGuiInputTextFlags_CallbackCompletion; + event_key = ImGuiKey_Tab; + } + else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_UpArrow)) + { + event_flag = ImGuiInputTextFlags_CallbackHistory; + event_key = ImGuiKey_UpArrow; + } + else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_DownArrow)) + { + event_flag = ImGuiInputTextFlags_CallbackHistory; + event_key = ImGuiKey_DownArrow; + } + else if (flags & ImGuiInputTextFlags_CallbackAlways) + event_flag = ImGuiInputTextFlags_CallbackAlways; + + if (event_flag) + { + ImGuiTextEditCallbackData callback_data; + memset(&callback_data, 0, sizeof(ImGuiTextEditCallbackData)); + callback_data.EventFlag = event_flag; + callback_data.Flags = flags; + callback_data.UserData = user_data; + callback_data.ReadOnly = !is_editable; + + callback_data.EventKey = event_key; + callback_data.Buf = edit_state.TempTextBuffer.Data; + callback_data.BufTextLen = edit_state.CurLenA; + callback_data.BufSize = edit_state.BufSizeA; + callback_data.BufDirty = false; + + // We have to convert from wchar-positions to UTF-8-positions, which can be pretty slow (an incentive to ditch the ImWchar buffer, see https://github.com/nothings/stb/issues/188) + ImWchar* text = edit_state.Text.Data; + const int utf8_cursor_pos = callback_data.CursorPos = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.cursor); + const int utf8_selection_start = callback_data.SelectionStart = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.select_start); + const int utf8_selection_end = callback_data.SelectionEnd = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.select_end); + + // Call user code + callback(&callback_data); + + // Read back what user may have modified + IM_ASSERT(callback_data.Buf == edit_state.TempTextBuffer.Data); // Invalid to modify those fields + IM_ASSERT(callback_data.BufSize == edit_state.BufSizeA); + IM_ASSERT(callback_data.Flags == flags); + if (callback_data.CursorPos != utf8_cursor_pos) edit_state.StbState.cursor = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.CursorPos); + if (callback_data.SelectionStart != utf8_selection_start) edit_state.StbState.select_start = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionStart); + if (callback_data.SelectionEnd != utf8_selection_end) edit_state.StbState.select_end = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); + if (callback_data.BufDirty) + { + IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text! + edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, callback_data.Buf, NULL); + edit_state.CurLenA = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen() + edit_state.CursorAnimReset(); + } + } + } + + // Copy back to user buffer + if (is_editable && strcmp(edit_state.TempTextBuffer.Data, buf) != 0) + { + ImStrncpy(buf, edit_state.TempTextBuffer.Data, buf_size); + value_changed = true; + } + } + } + + // Render + // Select which buffer we are going to display. When ImGuiInputTextFlags_NoLiveEdit is set 'buf' might still be the old value. We set buf to NULL to prevent accidental usage from now on. + const char* buf_display = (g.ActiveId == id && is_editable) ? edit_state.TempTextBuffer.Data : buf; buf = NULL; + + if (!is_multiline) + RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + + const ImVec4 clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + size.x, frame_bb.Min.y + size.y); // Not using frame_bb.Max because we have adjusted size + ImVec2 render_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding; + ImVec2 text_size(0.f, 0.f); + const bool is_currently_scrolling = (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetIDNoKeepAlive("#SCROLLY")); + if (g.ActiveId == id || is_currently_scrolling) + { + edit_state.CursorAnim += io.DeltaTime; + + // This is going to be messy. We need to: + // - Display the text (this alone can be more easily clipped) + // - Handle scrolling, highlight selection, display cursor (those all requires some form of 1d->2d cursor position calculation) + // - Measure text height (for scrollbar) + // We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort) + // FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8. + const ImWchar* text_begin = edit_state.Text.Data; + ImVec2 cursor_offset, select_start_offset; + + { + // Count lines + find lines numbers straddling 'cursor' and 'select_start' position. + const ImWchar* searches_input_ptr[2]; + searches_input_ptr[0] = text_begin + edit_state.StbState.cursor; + searches_input_ptr[1] = NULL; + int searches_remaining = 1; + int searches_result_line_number[2] = { -1, -999 }; + if (edit_state.StbState.select_start != edit_state.StbState.select_end) + { + searches_input_ptr[1] = text_begin + ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end); + searches_result_line_number[1] = -1; + searches_remaining++; + } + + // Iterate all lines to find our line numbers + // In multi-line mode, we never exit the loop until all lines are counted, so add one extra to the searches_remaining counter. + searches_remaining += is_multiline ? 1 : 0; + int line_count = 0; + for (const ImWchar* s = text_begin; *s != 0; s++) + if (*s == '\n') + { + line_count++; + if (searches_result_line_number[0] == -1 && s >= searches_input_ptr[0]) { searches_result_line_number[0] = line_count; if (--searches_remaining <= 0) break; } + if (searches_result_line_number[1] == -1 && s >= searches_input_ptr[1]) { searches_result_line_number[1] = line_count; if (--searches_remaining <= 0) break; } + } + line_count++; + if (searches_result_line_number[0] == -1) searches_result_line_number[0] = line_count; + if (searches_result_line_number[1] == -1) searches_result_line_number[1] = line_count; + + // Calculate 2d position by finding the beginning of the line and measuring distance + cursor_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[0], text_begin), searches_input_ptr[0]).x; + cursor_offset.y = searches_result_line_number[0] * g.FontSize; + if (searches_result_line_number[1] >= 0) + { + select_start_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[1], text_begin), searches_input_ptr[1]).x; + select_start_offset.y = searches_result_line_number[1] * g.FontSize; + } + + // Calculate text height + if (is_multiline) + text_size = ImVec2(size.x, line_count * g.FontSize); + } + + // Scroll + if (edit_state.CursorFollow) + { + // Horizontal scroll in chunks of quarter width + if (!(flags & ImGuiInputTextFlags_NoHorizontalScroll)) + { + const float scroll_increment_x = size.x * 0.25f; + if (cursor_offset.x < edit_state.ScrollX) + edit_state.ScrollX = (float)(int)ImMax(0.0f, cursor_offset.x - scroll_increment_x); + else if (cursor_offset.x - size.x >= edit_state.ScrollX) + edit_state.ScrollX = (float)(int)(cursor_offset.x - size.x + scroll_increment_x); + } + else + { + edit_state.ScrollX = 0.0f; + } + + // Vertical scroll + if (is_multiline) + { + float scroll_y = draw_window->Scroll.y; + if (cursor_offset.y - g.FontSize < scroll_y) + scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize); + else if (cursor_offset.y - size.y >= scroll_y) + scroll_y = cursor_offset.y - size.y; + draw_window->DC.CursorPos.y += (draw_window->Scroll.y - scroll_y); // To avoid a frame of lag + draw_window->Scroll.y = scroll_y; + render_pos.y = draw_window->DC.CursorPos.y; + } + } + edit_state.CursorFollow = false; + const ImVec2 render_scroll = ImVec2(edit_state.ScrollX, 0.0f); + + // Draw selection + if (edit_state.StbState.select_start != edit_state.StbState.select_end) + { + const ImWchar* text_selected_begin = text_begin + ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end); + const ImWchar* text_selected_end = text_begin + ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end); + + float bg_offy_up = is_multiline ? 0.0f : -1.0f; // FIXME: those offsets should be part of the style? they don't play so well with multi-line selection. + float bg_offy_dn = is_multiline ? 0.0f : 2.0f; + ImU32 bg_color = GetColorU32(ImGuiCol_TextSelectedBg); + ImVec2 rect_pos = render_pos + select_start_offset - render_scroll; + for (const ImWchar* p = text_selected_begin; p < text_selected_end; ) + { + if (rect_pos.y > clip_rect.w + g.FontSize) + break; + if (rect_pos.y < clip_rect.y) + { + while (p < text_selected_end) + if (*p++ == '\n') + break; + } + else + { + ImVec2 rect_size = InputTextCalcTextSizeW(p, text_selected_end, &p, NULL, true); + if (rect_size.x <= 0.0f) rect_size.x = (float)(int)(g.Font->GetCharAdvance((unsigned short)' ') * 0.50f); // So we can see selected empty lines + ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos +ImVec2(rect_size.x, bg_offy_dn)); + rect.Clip(clip_rect); + if (rect.Overlaps(clip_rect)) + draw_window->DrawList->AddRectFilled(rect.Min, rect.Max, bg_color); + } + rect_pos.x = render_pos.x - render_scroll.x; + rect_pos.y += g.FontSize; + } + } + + draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos - render_scroll, GetColorU32(ImGuiCol_Text), buf_display, buf_display + edit_state.CurLenA, 0.0f, is_multiline ? NULL : &clip_rect); + + // Draw blinking cursor + bool cursor_is_visible = (g.InputTextState.CursorAnim <= 0.0f) || fmodf(g.InputTextState.CursorAnim, 1.20f) <= 0.80f; + ImVec2 cursor_screen_pos = render_pos + cursor_offset - render_scroll; + ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y-g.FontSize+0.5f, cursor_screen_pos.x+1.0f, cursor_screen_pos.y-1.5f); + if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect)) + draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_Text)); + + // Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.) + if (is_editable) + g.OsImePosRequest = ImVec2(cursor_screen_pos.x - 1, cursor_screen_pos.y - g.FontSize); + } + else + { + // Render text only + const char* buf_end = NULL; + if (is_multiline) + text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_end) * g.FontSize); // We don't need width + draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos, GetColorU32(ImGuiCol_Text), buf_display, buf_end, 0.0f, is_multiline ? NULL : &clip_rect); + } + + if (is_multiline) + { + Dummy(text_size + ImVec2(0.0f, g.FontSize)); // Always add room to scroll an extra line + EndChildFrame(); + EndGroup(); + if (g.ActiveId == id || is_currently_scrolling) // Set LastItemId which was lost by EndChild/EndGroup, so user can use IsItemActive() + window->DC.LastItemId = g.ActiveId; + } + + if (is_password) + PopFont(); + + // Log as text + if (g.LogEnabled && !is_password) + LogRenderedText(render_pos, buf_display, NULL); + + if (label_size.x > 0) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + + if ((flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0) + return enter_pressed; + else + return value_changed; +} + +bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) +{ + IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline() + return InputTextEx(label, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data); +} + +bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) +{ + return InputTextEx(label, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data); +} + +// NB: scalar_format here must be a simple "%xx" format string with no prefix/suffix (unlike the Drag/Slider functions "display_format" argument) +bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + BeginGroup(); + PushID(label); + const ImVec2 button_sz = ImVec2(g.FontSize, g.FontSize) + style.FramePadding*2.0f; + if (step_ptr) + PushItemWidth(ImMax(1.0f, CalcItemWidth() - (button_sz.x + style.ItemInnerSpacing.x)*2)); + + char buf[64]; + DataTypeFormatString(data_type, data_ptr, scalar_format, buf, IM_ARRAYSIZE(buf)); + + bool value_changed = false; + if (!(extra_flags & ImGuiInputTextFlags_CharsHexadecimal)) + extra_flags |= ImGuiInputTextFlags_CharsDecimal; + extra_flags |= ImGuiInputTextFlags_AutoSelectAll; + if (InputText("", buf, IM_ARRAYSIZE(buf), extra_flags)) + value_changed = DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, scalar_format); + + // Step buttons + if (step_ptr) + { + PopItemWidth(); + SameLine(0, style.ItemInnerSpacing.x); + if (ButtonEx("-", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) + { + DataTypeApplyOp(data_type, '-', data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr); + value_changed = true; + } + SameLine(0, style.ItemInnerSpacing.x); + if (ButtonEx("+", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) + { + DataTypeApplyOp(data_type, '+', data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr); + value_changed = true; + } + } + PopID(); + + if (label_size.x > 0) + { + SameLine(0, style.ItemInnerSpacing.x); + RenderText(ImVec2(window->DC.CursorPos.x, window->DC.CursorPos.y + style.FramePadding.y), label); + ItemSize(label_size, style.FramePadding.y); + } + EndGroup(); + + return value_changed; +} + +bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, int decimal_precision, ImGuiInputTextFlags extra_flags) +{ + char display_format[16]; + if (decimal_precision < 0) + strcpy(display_format, "%f"); // Ideally we'd have a minimum decimal precision of 1 to visually denote that this is a float, while hiding non-significant digits? %f doesn't have a minimum of 1 + else + ImFormatString(display_format, 16, "%%.%df", decimal_precision); + return InputScalarEx(label, ImGuiDataType_Float, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), display_format, extra_flags); +} + +bool ImGui::InputInt(const char* label, int* v, int step, int step_fast, ImGuiInputTextFlags extra_flags) +{ + // Hexadecimal input provided as a convenience but the flag name is awkward. Typically you'd use InputText() to parse your own data, if you want to handle prefixes. + const char* scalar_format = (extra_flags & ImGuiInputTextFlags_CharsHexadecimal) ? "%08X" : "%d"; + return InputScalarEx(label, ImGuiDataType_Int, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), scalar_format, extra_flags); +} + +bool ImGui::InputFloatN(const char* label, float* v, int components, int decimal_precision, ImGuiInputTextFlags extra_flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components); + for (int i = 0; i < components; i++) + { + PushID(i); + value_changed |= InputFloat("##v", &v[i], 0, 0, decimal_precision, extra_flags); + SameLine(0, g.Style.ItemInnerSpacing.x); + PopID(); + PopItemWidth(); + } + PopID(); + + window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y); + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); + + return value_changed; +} + +bool ImGui::InputFloat2(const char* label, float v[2], int decimal_precision, ImGuiInputTextFlags extra_flags) +{ + return InputFloatN(label, v, 2, decimal_precision, extra_flags); +} + +bool ImGui::InputFloat3(const char* label, float v[3], int decimal_precision, ImGuiInputTextFlags extra_flags) +{ + return InputFloatN(label, v, 3, decimal_precision, extra_flags); +} + +bool ImGui::InputFloat4(const char* label, float v[4], int decimal_precision, ImGuiInputTextFlags extra_flags) +{ + return InputFloatN(label, v, 4, decimal_precision, extra_flags); +} + +bool ImGui::InputIntN(const char* label, int* v, int components, ImGuiInputTextFlags extra_flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components); + for (int i = 0; i < components; i++) + { + PushID(i); + value_changed |= InputInt("##v", &v[i], 0, 0, extra_flags); + SameLine(0, g.Style.ItemInnerSpacing.x); + PopID(); + PopItemWidth(); + } + PopID(); + + window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y); + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); + + return value_changed; +} + +bool ImGui::InputInt2(const char* label, int v[2], ImGuiInputTextFlags extra_flags) +{ + return InputIntN(label, v, 2, extra_flags); +} + +bool ImGui::InputInt3(const char* label, int v[3], ImGuiInputTextFlags extra_flags) +{ + return InputIntN(label, v, 3, extra_flags); +} + +bool ImGui::InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_flags) +{ + return InputIntN(label, v, 4, extra_flags); +} + +static bool Items_ArrayGetter(void* data, int idx, const char** out_text) +{ + const char** items = (const char**)data; + if (out_text) + *out_text = items[idx]; + return true; +} + +static bool Items_SingleStringGetter(void* data, int idx, const char** out_text) +{ + // FIXME-OPT: we could pre-compute the indices to fasten this. But only 1 active combo means the waste is limited. + const char* items_separated_by_zeros = (const char*)data; + int items_count = 0; + const char* p = items_separated_by_zeros; + while (*p) + { + if (idx == items_count) + break; + p += strlen(p) + 1; + items_count++; + } + if (!*p) + return false; + if (out_text) + *out_text = p; + return true; +} + +// Combo box helper allowing to pass an array of strings. +bool ImGui::Combo(const char* label, int* current_item, const char** items, int items_count, int height_in_items) +{ + const bool value_changed = Combo(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_in_items); + return value_changed; +} + +// Combo box helper allowing to pass all items in a single string. +bool ImGui::Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items) +{ + int items_count = 0; + const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this, or at least only when combo is open + while (*p) + { + p += strlen(p) + 1; + items_count++; + } + bool value_changed = Combo(label, current_item, Items_SingleStringGetter, (void*)items_separated_by_zeros, items_count, height_in_items); + return value_changed; +} + +// Combo box function. +bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const float w = CalcItemWidth(); + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f)); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, &id)) + return false; + + const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f); + const bool hovered = IsHovered(frame_bb, id); + bool popup_open = IsPopupOpen(id); + bool popup_opened_now = false; + + const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); + RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING + RenderCollapseTriangle(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y) + style.FramePadding, true); + + if (*current_item >= 0 && *current_item < items_count) + { + const char* item_text; + if (items_getter(data, *current_item, &item_text)) + RenderTextClipped(frame_bb.Min + style.FramePadding, value_bb.Max, item_text, NULL, NULL); + } + + if (label_size.x > 0) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + + if (hovered) + { + SetHoveredID(id); + if (g.IO.MouseClicked[0]) + { + SetActiveID(0); + if (IsPopupOpen(id)) + { + ClosePopup(id); + } + else + { + FocusWindow(window); + OpenPopup(label); + popup_open = popup_opened_now = true; + } + } + } + + bool value_changed = false; + if (IsPopupOpen(id)) + { + // Size default to hold ~7 items + if (height_in_items < 0) + height_in_items = 7; + + float popup_height = (label_size.y + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3); + float popup_y1 = frame_bb.Max.y; + float popup_y2 = ImClamp(popup_y1 + popup_height, popup_y1, g.IO.DisplaySize.y - style.DisplaySafeAreaPadding.y); + if ((popup_y2 - popup_y1) < ImMin(popup_height, frame_bb.Min.y - style.DisplaySafeAreaPadding.y)) + { + // Position our combo ABOVE because there's more space to fit! (FIXME: Handle in Begin() or use a shared helper. We have similar code in Begin() for popup placement) + popup_y1 = ImClamp(frame_bb.Min.y - popup_height, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); + popup_y2 = frame_bb.Min.y; + } + ImRect popup_rect(ImVec2(frame_bb.Min.x, popup_y1), ImVec2(frame_bb.Max.x, popup_y2)); + SetNextWindowPos(popup_rect.Min); + SetNextWindowSize(popup_rect.GetSize()); + PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); + + const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); + if (BeginPopupEx(label, flags)) + { + // Display items + Spacing(); + for (int i = 0; i < items_count; i++) + { + PushID((void*)(intptr_t)i); + const bool item_selected = (i == *current_item); + const char* item_text; + if (!items_getter(data, i, &item_text)) + item_text = "*Unknown item*"; + if (Selectable(item_text, item_selected)) + { + SetActiveID(0); + value_changed = true; + *current_item = i; + } + if (item_selected && popup_opened_now) + SetScrollHere(); + PopID(); + } + EndPopup(); + } + PopStyleVar(); + } + return value_changed; +} + +// Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image. +// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID. +bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size_arg) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1) + PopClipRect(); + + ImGuiID id = window->GetID(label); + ImVec2 label_size = CalcTextSize(label, NULL, true); + ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y); + ImVec2 pos = window->DC.CursorPos; + pos.y += window->DC.CurrentLineTextBaseOffset; + ImRect bb(pos, pos + size); + ItemSize(bb); + + // Fill horizontal space. + ImVec2 window_padding = window->WindowPadding; + float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x : GetContentRegionMax().x; + float w_draw = ImMax(label_size.x, window->Pos.x + max_x - window_padding.x - window->DC.CursorPos.x); + ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size_arg.y != 0.0f ? size_arg.y : size.y); + ImRect bb_with_spacing(pos, pos + size_draw); + if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth)) + bb_with_spacing.Max.x += window_padding.x; + + // Selectables are tightly packed together, we extend the box to cover spacing between selectable. + float spacing_L = (float)(int)(style.ItemSpacing.x * 0.5f); + float spacing_U = (float)(int)(style.ItemSpacing.y * 0.5f); + float spacing_R = style.ItemSpacing.x - spacing_L; + float spacing_D = style.ItemSpacing.y - spacing_U; + bb_with_spacing.Min.x -= spacing_L; + bb_with_spacing.Min.y -= spacing_U; + bb_with_spacing.Max.x += spacing_R; + bb_with_spacing.Max.y += spacing_D; + if (!ItemAdd(bb_with_spacing, &id)) + { + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1) + PushColumnClipRect(); + return false; + } + + ImGuiButtonFlags button_flags = 0; + if (flags & ImGuiSelectableFlags_Menu) button_flags |= ImGuiButtonFlags_PressedOnClick; + if (flags & ImGuiSelectableFlags_MenuItem) button_flags |= ImGuiButtonFlags_PressedOnClick|ImGuiButtonFlags_PressedOnRelease; + if (flags & ImGuiSelectableFlags_Disabled) button_flags |= ImGuiButtonFlags_Disabled; + if (flags & ImGuiSelectableFlags_AllowDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick; + bool hovered, held; + bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, button_flags); + if (flags & ImGuiSelectableFlags_Disabled) + selected = false; + + // Render + if (hovered || selected) + { + const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); + RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, 0.0f); + } + + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1) + { + PushColumnClipRect(); + bb_with_spacing.Max.x -= (GetContentRegionMax().x - max_x); + } + + if (flags & ImGuiSelectableFlags_Disabled) PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); + RenderTextClipped(bb.Min, bb_with_spacing.Max, label, NULL, &label_size); + if (flags & ImGuiSelectableFlags_Disabled) PopStyleColor(); + + // Automatically close popups + if (pressed && !(flags & ImGuiSelectableFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup)) + CloseCurrentPopup(); + return pressed; +} + +bool ImGui::Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags, const ImVec2& size_arg) +{ + if (Selectable(label, *p_selected, flags, size_arg)) + { + *p_selected = !*p_selected; + return true; + } + return false; +} + +// Helper to calculate the size of a listbox and display a label on the right. +// Tip: To have a list filling the entire window width, PushItemWidth(-1) and pass an empty label "##empty" +bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = GetStyle(); + const ImGuiID id = GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + // Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. + ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y); + ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y)); + ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); + ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + window->DC.LastItemRect = bb; + + BeginGroup(); + if (label_size.x > 0) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + + BeginChildFrame(id, frame_bb.GetSize()); + return true; +} + +bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_items) +{ + // Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. + // However we don't add +0.40f if items_count <= height_in_items. It is slightly dodgy, because it means a dynamic list of items will make the widget resize occasionally when it crosses that size. + // I am expecting that someone will come and complain about this behavior in a remote future, then we can advise on a better solution. + if (height_in_items < 0) + height_in_items = ImMin(items_count, 7); + float height_in_items_f = height_in_items < items_count ? (height_in_items + 0.40f) : (height_in_items + 0.00f); + + // We include ItemSpacing.y so that a list sized for the exact number of items doesn't make a scrollbar appears. We could also enforce that by passing a flag to BeginChild(). + ImVec2 size; + size.x = 0.0f; + size.y = GetTextLineHeightWithSpacing() * height_in_items_f + GetStyle().ItemSpacing.y; + return ListBoxHeader(label, size); +} + +void ImGui::ListBoxFooter() +{ + ImGuiWindow* parent_window = GetParentWindow(); + const ImRect bb = parent_window->DC.LastItemRect; + const ImGuiStyle& style = GetStyle(); + + EndChildFrame(); + + // Redeclare item size so that it includes the label (we have stored the full size in LastItemRect) + // We call SameLine() to restore DC.CurrentLine* data + SameLine(); + parent_window->DC.CursorPos = bb.Min; + ItemSize(bb, style.FramePadding.y); + EndGroup(); +} + +bool ImGui::ListBox(const char* label, int* current_item, const char** items, int items_count, int height_items) +{ + const bool value_changed = ListBox(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_items); + return value_changed; +} + +bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items) +{ + if (!ListBoxHeader(label, items_count, height_in_items)) + return false; + + // Assume all items have even height (= 1 line of text). If you need items of different or variable sizes you can create a custom version of ListBox() in your code without using the clipper. + bool value_changed = false; + ImGuiListClipper clipper(items_count, GetTextLineHeightWithSpacing()); + while (clipper.Step()) + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + { + const bool item_selected = (i == *current_item); + const char* item_text; + if (!items_getter(data, i, &item_text)) + item_text = "*Unknown item*"; + + PushID(i); + if (Selectable(item_text, item_selected)) + { + *current_item = i; + value_changed = true; + } + PopID(); + } + ListBoxFooter(); + return value_changed; +} + +bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, bool enabled) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + ImVec2 pos = window->DC.CursorPos; + ImVec2 label_size = CalcTextSize(label, NULL, true); + ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); + float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame + float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); + + bool pressed = Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (enabled ? 0 : ImGuiSelectableFlags_Disabled), ImVec2(w, 0.0f)); + if (shortcut_size.x > 0.0f) + { + PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); + RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); + PopStyleColor(); + } + + if (selected) + RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled)); + + return pressed; +} + +bool ImGui::MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled) +{ + if (MenuItem(label, shortcut, p_selected ? *p_selected : false, enabled)) + { + if (p_selected) + *p_selected = !*p_selected; + return true; + } + return false; +} + +bool ImGui::BeginMainMenuBar() +{ + ImGuiContext& g = *GImGui; + SetNextWindowPos(ImVec2(0.0f, 0.0f)); + SetNextWindowSize(ImVec2(g.IO.DisplaySize.x, g.FontBaseSize + g.Style.FramePadding.y * 2.0f)); + PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0,0)); + if (!Begin("##MainMenuBar", NULL, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_MenuBar) + || !BeginMenuBar()) + { + End(); + PopStyleVar(2); + return false; + } + g.CurrentWindow->DC.MenuBarOffsetX += g.Style.DisplaySafeAreaPadding.x; + return true; +} + +void ImGui::EndMainMenuBar() +{ + EndMenuBar(); + End(); + PopStyleVar(2); +} + +bool ImGui::BeginMenuBar() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + if (!(window->Flags & ImGuiWindowFlags_MenuBar)) + return false; + + IM_ASSERT(!window->DC.MenuBarAppending); + BeginGroup(); // Save position + PushID("##menubar"); + ImRect rect = window->MenuBarRect(); + PushClipRect(ImVec2(ImFloor(rect.Min.x+0.5f), ImFloor(rect.Min.y + window->BorderSize + 0.5f)), ImVec2(ImFloor(rect.Max.x+0.5f), ImFloor(rect.Max.y+0.5f)), false); + window->DC.CursorPos = ImVec2(rect.Min.x + window->DC.MenuBarOffsetX, rect.Min.y);// + g.Style.FramePadding.y); + window->DC.LayoutType = ImGuiLayoutType_Horizontal; + window->DC.MenuBarAppending = true; + AlignFirstTextHeightToWidgets(); + return true; +} + +void ImGui::EndMenuBar() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + IM_ASSERT(window->Flags & ImGuiWindowFlags_MenuBar); + IM_ASSERT(window->DC.MenuBarAppending); + PopClipRect(); + PopID(); + window->DC.MenuBarOffsetX = window->DC.CursorPos.x - window->MenuBarRect().Min.x; + window->DC.GroupStack.back().AdvanceCursor = false; + EndGroup(); + window->DC.LayoutType = ImGuiLayoutType_Vertical; + window->DC.MenuBarAppending = false; +} + +bool ImGui::BeginMenu(const char* label, bool enabled) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + + ImVec2 label_size = CalcTextSize(label, NULL, true); + ImGuiWindow* backed_focused_window = g.FocusedWindow; + + bool pressed; + bool menu_is_open = IsPopupOpen(id); + bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##menus")); + if (menuset_is_open) + g.FocusedWindow = window; + + ImVec2 popup_pos, pos = window->DC.CursorPos; + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) + { + popup_pos = ImVec2(pos.x - window->WindowPadding.x, pos.y - style.FramePadding.y + window->MenuBarHeight()); + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); + PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); + float w = label_size.x; + pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); + PopStyleVar(); + SameLine(); + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); + } + else + { + popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); + float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame + float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); + pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); + if (!enabled) PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); + RenderCollapseTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), false); + if (!enabled) PopStyleColor(); + } + + bool hovered = enabled && IsHovered(window->DC.LastItemRect, id); + if (menuset_is_open) + g.FocusedWindow = backed_focused_window; + + bool want_open = false, want_close = false; + if (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) + { + // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive. + bool moving_within_opened_triangle = false; + if (g.HoveredWindow == window && g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentWindow == window) + { + if (ImGuiWindow* next_window = g.OpenPopupStack[g.CurrentPopupStack.Size].Window) + { + ImRect next_window_rect = next_window->Rect(); + ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta; + ImVec2 tb = (window->Pos.x < next_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR(); + ImVec2 tc = (window->Pos.x < next_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR(); + float extra = ImClamp(fabsf(ta.x - tb.x) * 0.30f, 5.0f, 30.0f); // add a bit of extra slack. + ta.x += (window->Pos.x < next_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues + tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -100.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale? + tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f); + moving_within_opened_triangle = ImIsPointInTriangle(g.IO.MousePos, ta, tb, tc); + //window->DrawList->PushClipRectFullScreen(); window->DrawList->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? 0x80008000 : 0x80000080); window->DrawList->PopClipRect(); // Debug + } + } + + want_close = (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_within_opened_triangle); + want_open = (!menu_is_open && hovered && !moving_within_opened_triangle) || (!menu_is_open && hovered && pressed); + } + else if (menu_is_open && pressed && menuset_is_open) // menu-bar: click open menu to close + { + want_close = true; + want_open = menu_is_open = false; + } + else if (pressed || (hovered && menuset_is_open && !menu_is_open)) // menu-bar: first click to open, then hover to open others + want_open = true; + if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }' + want_close = true; + if (want_close && IsPopupOpen(id)) + ClosePopupToLevel(GImGui->CurrentPopupStack.Size); + + if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.CurrentPopupStack.Size) + { + // Don't recycle same menu level in the same frame, first close the other menu and yield for a frame. + OpenPopup(label); + return false; + } + + menu_is_open |= want_open; + if (want_open) + OpenPopup(label); + + if (menu_is_open) + { + SetNextWindowPos(popup_pos, ImGuiSetCond_Always); + ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); + menu_is_open = BeginPopupEx(label, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + } + + return menu_is_open; +} + +void ImGui::EndMenu() +{ + EndPopup(); +} + +// A little colored square. Return true when clicked. +// FIXME: May want to display/ignore the alpha component in the color display? Yet show it in the tooltip. +bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_border) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID("#colorbutton"); + const float square_size = g.FontSize; + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(square_size + style.FramePadding.y*2, square_size + (small_height ? 0 : style.FramePadding.y*2))); + ItemSize(bb, small_height ? 0.0f : style.FramePadding.y); + if (!ItemAdd(bb, &id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held); + RenderFrame(bb.Min, bb.Max, GetColorU32(col), outline_border, style.FrameRounding); + + if (hovered) + SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col.x, col.y, col.z, col.w, IM_F32_TO_INT8_SAT(col.x), IM_F32_TO_INT8_SAT(col.y), IM_F32_TO_INT8_SAT(col.z), IM_F32_TO_INT8_SAT(col.z)); + + return pressed; +} + +bool ImGui::ColorEdit3(const char* label, float col[3]) +{ + float col4[4]; + col4[0] = col[0]; + col4[1] = col[1]; + col4[2] = col[2]; + col4[3] = 1.0f; + const bool value_changed = ColorEdit4(label, col4, false); + col[0] = col4[0]; + col[1] = col4[1]; + col[2] = col4[2]; + return value_changed; +} + +// Edit colors components (each component in 0.0f..1.0f range +// Use CTRL-Click to input value and TAB to go to next item. +bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const float w_full = CalcItemWidth(); + const float square_sz = (g.FontSize + style.FramePadding.y * 2.0f); + + ImGuiColorEditMode edit_mode = window->DC.ColorEditMode; + if (edit_mode == ImGuiColorEditMode_UserSelect || edit_mode == ImGuiColorEditMode_UserSelectShowButton) + edit_mode = g.ColorEditModeStorage.GetInt(id, 0) % 3; + + float f[4] = { col[0], col[1], col[2], col[3] }; + if (edit_mode == ImGuiColorEditMode_HSV) + ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); + + int i[4] = { IM_F32_TO_INT8_UNBOUND(f[0]), IM_F32_TO_INT8_UNBOUND(f[1]), IM_F32_TO_INT8_UNBOUND(f[2]), IM_F32_TO_INT8_UNBOUND(f[3]) }; + + int components = alpha ? 4 : 3; + bool value_changed = false; + + BeginGroup(); + PushID(label); + + const bool hsv = (edit_mode == 1); + switch (edit_mode) + { + case ImGuiColorEditMode_RGB: + case ImGuiColorEditMode_HSV: + { + // RGB/HSV 0..255 Sliders + const float w_items_all = w_full - (square_sz + style.ItemInnerSpacing.x); + const float w_item_one = ImMax(1.0f, (float)(int)((w_items_all - (style.ItemInnerSpacing.x) * (components-1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.ItemInnerSpacing.x) * (components-1))); + + const bool hide_prefix = (w_item_one <= CalcTextSize("M:999").x); + const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; + const char* fmt_table[3][4] = + { + { "%3.0f", "%3.0f", "%3.0f", "%3.0f" }, + { "R:%3.0f", "G:%3.0f", "B:%3.0f", "A:%3.0f" }, + { "H:%3.0f", "S:%3.0f", "V:%3.0f", "A:%3.0f" } + }; + const char** fmt = hide_prefix ? fmt_table[0] : hsv ? fmt_table[2] : fmt_table[1]; + + PushItemWidth(w_item_one); + for (int n = 0; n < components; n++) + { + if (n > 0) + SameLine(0, style.ItemInnerSpacing.x); + if (n + 1 == components) + PushItemWidth(w_item_last); + value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, 255, fmt[n]); + } + PopItemWidth(); + PopItemWidth(); + } + break; + case ImGuiColorEditMode_HEX: + { + // RGB Hexadecimal Input + const float w_slider_all = w_full - square_sz; + char buf[64]; + if (alpha) + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", i[0], i[1], i[2], i[3]); + else + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", i[0], i[1], i[2]); + PushItemWidth(w_slider_all - style.ItemInnerSpacing.x); + if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase)) + { + value_changed |= true; + char* p = buf; + while (*p == '#' || ImCharIsSpace(*p)) + p++; + i[0] = i[1] = i[2] = i[3] = 0; + if (alpha) + sscanf(p, "%02X%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2], (unsigned int*)&i[3]); // Treat at unsigned (%X is unsigned) + else + sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]); + } + PopItemWidth(); + } + break; + } + + SameLine(0, style.ItemInnerSpacing.x); + + const ImVec4 col_display(col[0], col[1], col[2], 1.0f); + if (ColorButton(col_display)) + g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away! + + // Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here + if (IsItemHovered()) + SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col[0], col[1], col[2], col[3], IM_F32_TO_INT8_SAT(col[0]), IM_F32_TO_INT8_SAT(col[1]), IM_F32_TO_INT8_SAT(col[2]), IM_F32_TO_INT8_SAT(col[3])); + + if (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton) + { + SameLine(0, style.ItemInnerSpacing.x); + const char* button_titles[3] = { "RGB", "HSV", "HEX" }; + if (ButtonEx(button_titles[edit_mode], ImVec2(0,0), ImGuiButtonFlags_DontClosePopups)) + g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away! + } + + const char* label_display_end = FindRenderedTextEnd(label); + if (label != label_display_end) + { + SameLine(0, (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton) ? -1.0f : style.ItemInnerSpacing.x); + TextUnformatted(label, label_display_end); + } + + // Convert back + for (int n = 0; n < 4; n++) + f[n] = i[n] / 255.0f; + if (edit_mode == 1) + ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]); + + if (value_changed) + { + col[0] = f[0]; + col[1] = f[1]; + col[2] = f[2]; + if (alpha) + col[3] = f[3]; + } + + PopID(); + EndGroup(); + + return value_changed; +} + +void ImGui::ColorEditMode(ImGuiColorEditMode mode) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ColorEditMode = mode; +} + +// Horizontal separating line. +void ImGui::Separator() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + if (window->DC.ColumnsCount > 1) + PopClipRect(); + + float x1 = window->Pos.x; + float x2 = window->Pos.x + window->Size.x; + if (!window->DC.GroupStack.empty()) + x1 += window->DC.IndentX; + + const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y)); + ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit // FIXME: Height should be 1.0f not 0.0f ? + if (!ItemAdd(bb, NULL)) + { + if (window->DC.ColumnsCount > 1) + PushColumnClipRect(); + return; + } + + window->DrawList->AddLine(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border)); + + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + LogText(IM_NEWLINE "--------------------------------"); + + if (window->DC.ColumnsCount > 1) + { + PushColumnClipRect(); + window->DC.ColumnsCellMinY = window->DC.CursorPos.y; + } +} + +void ImGui::Spacing() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + ItemSize(ImVec2(0,0)); +} + +void ImGui::Dummy(const ImVec2& size) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + ItemSize(bb); + ItemAdd(bb, NULL); +} + +bool ImGui::IsRectVisible(const ImVec2& size) +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size)); +} + +bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->ClipRect.Overlaps(ImRect(rect_min, rect_max)); +} + +// Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) +void ImGui::BeginGroup() +{ + ImGuiWindow* window = GetCurrentWindow(); + + window->DC.GroupStack.resize(window->DC.GroupStack.Size + 1); + ImGuiGroupData& group_data = window->DC.GroupStack.back(); + group_data.BackupCursorPos = window->DC.CursorPos; + group_data.BackupCursorMaxPos = window->DC.CursorMaxPos; + group_data.BackupIndentX = window->DC.IndentX; + group_data.BackupCurrentLineHeight = window->DC.CurrentLineHeight; + group_data.BackupCurrentLineTextBaseOffset = window->DC.CurrentLineTextBaseOffset; + group_data.BackupLogLinePosY = window->DC.LogLinePosY; + group_data.AdvanceCursor = true; + + window->DC.GroupOffsetX = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffsetX; + window->DC.IndentX = window->DC.GroupOffsetX; + window->DC.CursorMaxPos = window->DC.CursorPos; + window->DC.CurrentLineHeight = 0.0f; + window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; +} + +void ImGui::EndGroup() +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGuiStyle& style = GetStyle(); + + IM_ASSERT(!window->DC.GroupStack.empty()); // Mismatched BeginGroup()/EndGroup() calls + + ImGuiGroupData& group_data = window->DC.GroupStack.back(); + + ImRect group_bb(group_data.BackupCursorPos, window->DC.CursorMaxPos); + group_bb.Max.y -= style.ItemSpacing.y; // Cancel out last vertical spacing because we are adding one ourselves. + group_bb.Max = ImMax(group_bb.Min, group_bb.Max); + + window->DC.CursorPos = group_data.BackupCursorPos; + window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, window->DC.CursorMaxPos); + window->DC.CurrentLineHeight = group_data.BackupCurrentLineHeight; + window->DC.CurrentLineTextBaseOffset = group_data.BackupCurrentLineTextBaseOffset; + window->DC.IndentX = group_data.BackupIndentX; + window->DC.GroupOffsetX = window->DC.IndentX; + window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; + + if (group_data.AdvanceCursor) + { + window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.PrevLineTextBaseOffset, group_data.BackupCurrentLineTextBaseOffset); // FIXME: Incorrect, we should grab the base offset from the *first line* of the group but it is hard to obtain now. + ItemSize(group_bb.GetSize(), group_data.BackupCurrentLineTextBaseOffset); + ItemAdd(group_bb, NULL); + } + + window->DC.GroupStack.pop_back(); + + //window->DrawList->AddRect(group_bb.Min, group_bb.Max, 0xFFFF00FF); // Debug +} + +// Gets back to previous line and continue with horizontal layout +// pos_x == 0 : follow right after previous item +// pos_x != 0 : align to specified x position (relative to window/group left) +// spacing_w < 0 : use default spacing if pos_x == 0, no spacing if pos_x != 0 +// spacing_w >= 0 : enforce spacing amount +void ImGui::SameLine(float pos_x, float spacing_w) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + if (pos_x != 0.0f) + { + if (spacing_w < 0.0f) spacing_w = 0.0f; + window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + pos_x + spacing_w + window->DC.GroupOffsetX + window->DC.ColumnsOffsetX; + window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; + } + else + { + if (spacing_w < 0.0f) spacing_w = g.Style.ItemSpacing.x; + window->DC.CursorPos.x = window->DC.CursorPosPrevLine.x + spacing_w; + window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; + } + window->DC.CurrentLineHeight = window->DC.PrevLineHeight; + window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset; +} + +void ImGui::NewLine() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + if (window->DC.CurrentLineHeight > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height. + ItemSize(ImVec2(0,0)); + else + ItemSize(ImVec2(0.0f, GImGui->FontSize)); +} + +void ImGui::NextColumn() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems || window->DC.ColumnsCount <= 1) + return; + + ImGuiContext& g = *GImGui; + PopItemWidth(); + PopClipRect(); + + window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); + if (++window->DC.ColumnsCurrent < window->DC.ColumnsCount) + { + // Columns 1+ cancel out IndentX + window->DC.ColumnsOffsetX = GetColumnOffset(window->DC.ColumnsCurrent) - window->DC.IndentX + g.Style.ItemSpacing.x; + window->DrawList->ChannelsSetCurrent(window->DC.ColumnsCurrent); + } + else + { + window->DC.ColumnsCurrent = 0; + window->DC.ColumnsOffsetX = 0.0f; + window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY; + window->DrawList->ChannelsSetCurrent(0); + } + window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); + window->DC.CursorPos.y = window->DC.ColumnsCellMinY; + window->DC.CurrentLineHeight = 0.0f; + window->DC.CurrentLineTextBaseOffset = 0.0f; + + PushColumnClipRect(); + PushItemWidth(GetColumnWidth() * 0.65f); // FIXME: Move on columns setup +} + +int ImGui::GetColumnIndex() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.ColumnsCurrent; +} + +int ImGui::GetColumnsCount() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.ColumnsCount; +} + +static float GetDraggedColumnOffset(int column_index) +{ + // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing + // window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning. + ImGuiContext& g = *GImGui; + ImGuiWindow* window = ImGui::GetCurrentWindowRead(); + IM_ASSERT(column_index > 0); // We cannot drag column 0. If you get this assert you may have a conflict between the ID of your columns and another widgets. + IM_ASSERT(g.ActiveId == window->DC.ColumnsSetId + ImGuiID(column_index)); + + float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x - window->Pos.x; + x = ImClamp(x, ImGui::GetColumnOffset(column_index-1)+g.Style.ColumnsMinSpacing, ImGui::GetColumnOffset(column_index+1)-g.Style.ColumnsMinSpacing); + + return (float)(int)x; +} + +float ImGui::GetColumnOffset(int column_index) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindowRead(); + if (column_index < 0) + column_index = window->DC.ColumnsCurrent; + + if (g.ActiveId) + { + const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); + if (g.ActiveId == column_id) + return GetDraggedColumnOffset(column_index); + } + + IM_ASSERT(column_index < window->DC.ColumnsData.Size); + const float t = window->DC.ColumnsData[column_index].OffsetNorm; + const float x_offset = window->DC.ColumnsMinX + t * (window->DC.ColumnsMaxX - window->DC.ColumnsMinX); + return (float)(int)x_offset; +} + +void ImGui::SetColumnOffset(int column_index, float offset) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (column_index < 0) + column_index = window->DC.ColumnsCurrent; + + IM_ASSERT(column_index < window->DC.ColumnsData.Size); + const float t = (offset - window->DC.ColumnsMinX) / (window->DC.ColumnsMaxX - window->DC.ColumnsMinX); + window->DC.ColumnsData[column_index].OffsetNorm = t; + + const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); + window->DC.StateStorage->SetFloat(column_id, t); +} + +float ImGui::GetColumnWidth(int column_index) +{ + ImGuiWindow* window = GetCurrentWindowRead(); + if (column_index < 0) + column_index = window->DC.ColumnsCurrent; + + float w = GetColumnOffset(column_index+1) - GetColumnOffset(column_index); + return w; +} + +static void PushColumnClipRect(int column_index) +{ + ImGuiWindow* window = ImGui::GetCurrentWindow(); + if (column_index < 0) + column_index = window->DC.ColumnsCurrent; + + float x1 = ImFloor(0.5f + window->Pos.x + ImGui::GetColumnOffset(column_index) - 1.0f); + float x2 = ImFloor(0.5f + window->Pos.x + ImGui::GetColumnOffset(column_index+1) - 1.0f); + ImGui::PushClipRect(ImVec2(x1,-FLT_MAX), ImVec2(x2,+FLT_MAX), true); +} + +void ImGui::Columns(int columns_count, const char* id, bool border) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + IM_ASSERT(columns_count >= 1); + + if (window->DC.ColumnsCount != 1) + { + if (window->DC.ColumnsCurrent != 0) + ItemSize(ImVec2(0,0)); // Advance to column 0 + PopItemWidth(); + PopClipRect(); + window->DrawList->ChannelsMerge(); + + window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); + window->DC.CursorPos.y = window->DC.ColumnsCellMaxY; + } + + // Draw columns borders and handle resize at the time of "closing" a columns set + if (window->DC.ColumnsCount != columns_count && window->DC.ColumnsCount != 1 && window->DC.ColumnsShowBorders && !window->SkipItems) + { + const float y1 = window->DC.ColumnsStartPosY; + const float y2 = window->DC.CursorPos.y; + for (int i = 1; i < window->DC.ColumnsCount; i++) + { + float x = window->Pos.x + GetColumnOffset(i); + const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(i); + const ImRect column_rect(ImVec2(x-4,y1),ImVec2(x+4,y2)); + if (IsClippedEx(column_rect, &column_id, false)) + continue; + + bool hovered, held; + ButtonBehavior(column_rect, column_id, &hovered, &held); + if (hovered || held) + g.MouseCursor = ImGuiMouseCursor_ResizeEW; + + // Draw before resize so our items positioning are in sync with the line being drawn + const ImU32 col = GetColorU32(held ? ImGuiCol_ColumnActive : hovered ? ImGuiCol_ColumnHovered : ImGuiCol_Column); + const float xi = (float)(int)x; + window->DrawList->AddLine(ImVec2(xi, y1+1.0f), ImVec2(xi, y2), col); + + if (held) + { + if (g.ActiveIdIsJustActivated) + g.ActiveIdClickOffset.x -= 4; // Store from center of column line (we used a 8 wide rect for columns clicking) + x = GetDraggedColumnOffset(i); + SetColumnOffset(i, x); + } + } + } + + // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. + // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer. + PushID(0x11223347 + (id ? 0 : columns_count)); + window->DC.ColumnsSetId = window->GetID(id ? id : "columns"); + PopID(); + + // Set state for first column + window->DC.ColumnsCurrent = 0; + window->DC.ColumnsCount = columns_count; + window->DC.ColumnsShowBorders = border; + + const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : window->Size.x; + window->DC.ColumnsMinX = window->DC.IndentX; // Lock our horizontal range + window->DC.ColumnsMaxX = content_region_width - window->Scroll.x - ((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; + window->DC.ColumnsStartPosY = window->DC.CursorPos.y; + window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.CursorPos.y; + window->DC.ColumnsOffsetX = 0.0f; + window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); + + if (window->DC.ColumnsCount != 1) + { + // Cache column offsets + window->DC.ColumnsData.resize(columns_count + 1); + for (int column_index = 0; column_index < columns_count + 1; column_index++) + { + const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); + KeepAliveID(column_id); + const float default_t = column_index / (float)window->DC.ColumnsCount; + const float t = window->DC.StateStorage->GetFloat(column_id, default_t); // Cheaply store our floating point value inside the integer (could store an union into the map?) + window->DC.ColumnsData[column_index].OffsetNorm = t; + } + window->DrawList->ChannelsSplit(window->DC.ColumnsCount); + PushColumnClipRect(); + PushItemWidth(GetColumnWidth() * 0.65f); + } + else + { + window->DC.ColumnsData.resize(0); + } +} + +void ImGui::Indent(float indent_w) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + window->DC.IndentX += (indent_w > 0.0f) ? indent_w : g.Style.IndentSpacing; + window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX; +} + +void ImGui::Unindent(float indent_w) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + window->DC.IndentX -= (indent_w > 0.0f) ? indent_w : g.Style.IndentSpacing; + window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX; +} + +void ImGui::TreePush(const char* str_id) +{ + ImGuiWindow* window = GetCurrentWindow(); + Indent(); + window->DC.TreeDepth++; + PushID(str_id ? str_id : "#TreePush"); +} + +void ImGui::TreePush(const void* ptr_id) +{ + ImGuiWindow* window = GetCurrentWindow(); + Indent(); + window->DC.TreeDepth++; + PushID(ptr_id ? ptr_id : (const void*)"#TreePush"); +} + +void ImGui::TreePushRawID(ImGuiID id) +{ + ImGuiWindow* window = GetCurrentWindow(); + Indent(); + window->DC.TreeDepth++; + window->IDStack.push_back(id); +} + +void ImGui::TreePop() +{ + ImGuiWindow* window = GetCurrentWindow(); + Unindent(); + window->DC.TreeDepth--; + PopID(); +} + +void ImGui::Value(const char* prefix, bool b) +{ + Text("%s: %s", prefix, (b ? "true" : "false")); +} + +void ImGui::Value(const char* prefix, int v) +{ + Text("%s: %d", prefix, v); +} + +void ImGui::Value(const char* prefix, unsigned int v) +{ + Text("%s: %d", prefix, v); +} + +void ImGui::Value(const char* prefix, float v, const char* float_format) +{ + if (float_format) + { + char fmt[64]; + ImFormatString(fmt, IM_ARRAYSIZE(fmt), "%%s: %s", float_format); + Text(fmt, prefix, v); + } + else + { + Text("%s: %.3f", prefix, v); + } +} + +// FIXME: May want to remove those helpers? +void ImGui::ValueColor(const char* prefix, const ImVec4& v) +{ + Text("%s: (%.2f,%.2f,%.2f,%.2f)", prefix, v.x, v.y, v.z, v.w); + SameLine(); + ColorButton(v, true); +} + +void ImGui::ValueColor(const char* prefix, ImU32 v) +{ + Text("%s: %08X", prefix, v); + SameLine(); + + ImVec4 col; + col.x = (float)((v >> 0) & 0xFF) / 255.0f; + col.y = (float)((v >> 8) & 0xFF) / 255.0f; + col.z = (float)((v >> 16) & 0xFF) / 255.0f; + col.w = (float)((v >> 24) & 0xFF) / 255.0f; + ColorButton(col, true); +} + +//----------------------------------------------------------------------------- +// PLATFORM DEPENDANT HELPERS +//----------------------------------------------------------------------------- + +#if defined(_WIN32) && !defined(_WINDOWS_) && (!defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS) || !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS)) +#undef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#include +#endif + +// Win32 API clipboard implementation +#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS) + +#ifdef _MSC_VER +#pragma comment(lib, "user32") +#endif + +static const char* GetClipboardTextFn_DefaultImpl() +{ + static ImVector buf_local; + buf_local.clear(); + if (!OpenClipboard(NULL)) + return NULL; + HANDLE wbuf_handle = GetClipboardData(CF_UNICODETEXT); + if (wbuf_handle == NULL) + return NULL; + if (ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle)) + { + int buf_len = ImTextCountUtf8BytesFromStr(wbuf_global, NULL) + 1; + buf_local.resize(buf_len); + ImTextStrToUtf8(buf_local.Data, buf_len, wbuf_global, NULL); + } + GlobalUnlock(wbuf_handle); + CloseClipboard(); + return buf_local.Data; +} + +static void SetClipboardTextFn_DefaultImpl(const char* text) +{ + if (!OpenClipboard(NULL)) + return; + const int wbuf_length = ImTextCountCharsFromUtf8(text, NULL) + 1; + HGLOBAL wbuf_handle = GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)wbuf_length * sizeof(ImWchar)); + if (wbuf_handle == NULL) + return; + ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle); + ImTextStrFromUtf8(wbuf_global, wbuf_length, text, NULL); + GlobalUnlock(wbuf_handle); + EmptyClipboard(); + SetClipboardData(CF_UNICODETEXT, wbuf_handle); + CloseClipboard(); +} + +#else + +// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers +static const char* GetClipboardTextFn_DefaultImpl() +{ + return GImGui->PrivateClipboard; +} + +// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers +static void SetClipboardTextFn_DefaultImpl(const char* text) +{ + ImGuiContext& g = *GImGui; + if (g.PrivateClipboard) + { + ImGui::MemFree(g.PrivateClipboard); + g.PrivateClipboard = NULL; + } + const char* text_end = text + strlen(text); + g.PrivateClipboard = (char*)ImGui::MemAlloc((size_t)(text_end - text) + 1); + memcpy(g.PrivateClipboard, text, (size_t)(text_end - text)); + g.PrivateClipboard[(int)(text_end - text)] = 0; +} + +#endif + +// Win32 API IME support (for Asian languages, etc.) +#if defined(_WIN32) && !defined(__GNUC__) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS) + +#include +#ifdef _MSC_VER +#pragma comment(lib, "imm32") +#endif + +static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y) +{ + // Notify OS Input Method Editor of text input position + if (HWND hwnd = (HWND)GImGui->IO.ImeWindowHandle) + if (HIMC himc = ImmGetContext(hwnd)) + { + COMPOSITIONFORM cf; + cf.ptCurrentPos.x = x; + cf.ptCurrentPos.y = y; + cf.dwStyle = CFS_FORCE_POSITION; + ImmSetCompositionWindow(himc, &cf); + } +} + +#else + +static void ImeSetInputScreenPosFn_DefaultImpl(int, int) {} + +#endif + +//----------------------------------------------------------------------------- +// HELP +//----------------------------------------------------------------------------- + +void ImGui::ShowMetricsWindow(bool* p_open) +{ + if (ImGui::Begin("ImGui Metrics", p_open)) + { + ImGui::Text("ImGui %s", ImGui::GetVersion()); + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::Text("%d vertices, %d indices (%d triangles)", ImGui::GetIO().MetricsRenderVertices, ImGui::GetIO().MetricsRenderIndices, ImGui::GetIO().MetricsRenderIndices / 3); + ImGui::Text("%d allocations", ImGui::GetIO().MetricsAllocs); + static bool show_clip_rects = true; + ImGui::Checkbox("Show clipping rectangles when hovering a ImDrawCmd", &show_clip_rects); + ImGui::Separator(); + + struct Funcs + { + static void NodeDrawList(ImDrawList* draw_list, const char* label) + { + bool node_open = ImGui::TreeNode(draw_list, "%s: '%s' %d vtx, %d indices, %d cmds", label, draw_list->_OwnerName ? draw_list->_OwnerName : "", draw_list->VtxBuffer.Size, draw_list->IdxBuffer.Size, draw_list->CmdBuffer.Size); + if (draw_list == ImGui::GetWindowDrawList()) + { + ImGui::SameLine(); + ImGui::TextColored(ImColor(255,100,100), "CURRENTLY APPENDING"); // Can't display stats for active draw list! (we don't have the data double-buffered) + if (node_open) ImGui::TreePop(); + return; + } + if (!node_open) + return; + + ImDrawList* overlay_draw_list = &GImGui->OverlayDrawList; // Render additional visuals into the top-most draw list + overlay_draw_list->PushClipRectFullScreen(); + int elem_offset = 0; + for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++) + { + if (pcmd->UserCallback) + { + ImGui::BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData); + continue; + } + ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; + bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "Draw %-4d %s vtx, tex = %p, clip_rect = (%.0f,%.0f)..(%.0f,%.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); + if (show_clip_rects && ImGui::IsItemHovered()) + { + ImRect clip_rect = pcmd->ClipRect; + ImRect vtxs_rect; + for (int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++) + vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos); + clip_rect.Floor(); overlay_draw_list->AddRect(clip_rect.Min, clip_rect.Max, IM_COL32(255,255,0,255)); + vtxs_rect.Floor(); overlay_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, IM_COL32(255,0,255,255)); + } + if (!pcmd_node_open) + continue; + ImGuiListClipper clipper(pcmd->ElemCount/3); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible. + while (clipper.Step()) + for (int prim = clipper.DisplayStart, vtx_i = elem_offset + clipper.DisplayStart*3; prim < clipper.DisplayEnd; prim++) + { + char buf[300], *buf_p = buf; + ImVec2 triangles_pos[3]; + for (int n = 0; n < 3; n++, vtx_i++) + { + ImDrawVert& v = draw_list->VtxBuffer[idx_buffer ? idx_buffer[vtx_i] : vtx_i]; + triangles_pos[n] = v.pos; + buf_p += sprintf(buf_p, "%s %04d { pos = (%8.2f,%8.2f), uv = (%.6f,%.6f), col = %08X }\n", (n == 0) ? "vtx" : " ", vtx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col); + } + ImGui::Selectable(buf, false); + if (ImGui::IsItemHovered()) + overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f, false); // Add triangle without AA, more readable for large-thin triangle + } + ImGui::TreePop(); + } + overlay_draw_list->PopClipRect(); + ImGui::TreePop(); + } + + static void NodeWindows(ImVector& windows, const char* label) + { + if (!ImGui::TreeNode(label, "%s (%d)", label, windows.Size)) + return; + for (int i = 0; i < windows.Size; i++) + Funcs::NodeWindow(windows[i], "Window"); + ImGui::TreePop(); + } + + static void NodeWindow(ImGuiWindow* window, const char* label) + { + if (!ImGui::TreeNode(window, "%s '%s', %d @ 0x%p", label, window->Name, window->Active || window->WasActive, window)) + return; + NodeDrawList(window->DrawList, "DrawList"); + ImGui::BulletText("Size: (%.1f,%.1f), SizeContents (%.1f,%.1f)", window->Size.x, window->Size.y, window->SizeContents.x, window->SizeContents.y); + ImGui::BulletText("Scroll: (%.2f,%.2f)", window->Scroll.x, window->Scroll.y); + if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); + if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); + ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair)); + ImGui::TreePop(); + } + }; + + ImGuiContext& g = *GImGui; // Access private state + Funcs::NodeWindows(g.Windows, "Windows"); + if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", g.RenderDrawLists[0].Size)) + { + for (int i = 0; i < g.RenderDrawLists[0].Size; i++) + Funcs::NodeDrawList(g.RenderDrawLists[0][i], "DrawList"); + ImGui::TreePop(); + } + if (ImGui::TreeNode("Popups", "Open Popups Stack (%d)", g.OpenPopupStack.Size)) + { + for (int i = 0; i < g.OpenPopupStack.Size; i++) + { + ImGuiWindow* window = g.OpenPopupStack[i].Window; + ImGui::BulletText("PopupID: %08x, Window: '%s'%s%s", g.OpenPopupStack[i].PopupId, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? " ChildWindow" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? " ChildMenu" : ""); + } + ImGui::TreePop(); + } + if (ImGui::TreeNode("Basic state")) + { + ImGui::Text("FocusedWindow: '%s'", g.FocusedWindow ? g.FocusedWindow->Name : "NULL"); + ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); + ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); + ImGui::Text("HoveredID: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not + ImGui::Text("ActiveID: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame); + ImGui::TreePop(); + } + } + ImGui::End(); +} + +//----------------------------------------------------------------------------- + +// Include imgui_user.inl at the end of imgui.cpp to access private data/functions that aren't exposed. +// Prefer just including imgui_internal.h from your code rather than using this define. If a declaration is missing from imgui_internal.h add it or request it on the github. +#ifdef IMGUI_INCLUDE_IMGUI_USER_INL +#include "imgui_user.inl" +#endif + +//----------------------------------------------------------------------------- diff --git a/CameraParameterEstimation/apps/basics/extern/imgui/imgui.h b/CameraParameterEstimation/apps/basics/extern/imgui/imgui.h new file mode 100644 index 0000000..b85eaef --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/imgui/imgui.h @@ -0,0 +1,1396 @@ +// dear imgui, v1.50 WIP +// (headers) + +// See imgui.cpp file for documentation. +// See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. +// Read 'Programmer guide' in imgui.cpp for notes on how to setup ImGui in your codebase. +// Get latest version at https://github.com/ocornut/imgui + +#pragma once + +#if !defined(IMGUI_DISABLE_INCLUDE_IMCONFIG_H) || defined(IMGUI_INCLUDE_IMCONFIG_H) +#include "imconfig.h" // User-editable configuration file +#endif +#include // FLT_MAX +#include // va_list +#include // ptrdiff_t, NULL +#include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp + +#define IMGUI_VERSION "1.50 WIP" + +// Define attributes of all API symbols declarations, e.g. for DLL under Windows. +#ifndef IMGUI_API +#define IMGUI_API +#endif + +// Define assertion handler. +#ifndef IM_ASSERT +#include +#define IM_ASSERT(_EXPR) assert(_EXPR) +#endif + +// Some compilers support applying printf-style warnings to user functions. +#if defined(__clang__) || defined(__GNUC__) +#define IM_PRINTFARGS(FMT) __attribute__((format(printf, FMT, (FMT+1)))) +#else +#define IM_PRINTFARGS(FMT) +#endif + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wold-style-cast" +#endif + +// Forward declarations +struct ImDrawChannel; // Temporary storage for outputting drawing commands out of order, used by ImDrawList::ChannelsSplit() +struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call) +struct ImDrawData; // All draw command lists required to render the frame +struct ImDrawList; // A single draw command list (generally one per window) +struct ImDrawVert; // A single vertex (20 bytes by default, override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT) +struct ImFont; // Runtime data for a single font within a parent ImFontAtlas +struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF font loader +struct ImFontConfig; // Configuration data when adding a font or merging fonts +struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 +struct ImGuiIO; // Main configuration and I/O between your application and ImGui +struct ImGuiOnceUponAFrame; // Simple helper for running a block of code not more than once a frame, used by IMGUI_ONCE_UPON_A_FRAME macro +struct ImGuiStorage; // Simple custom key value storage +struct ImGuiStyle; // Runtime data for styling/colors +struct ImGuiTextFilter; // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" +struct ImGuiTextBuffer; // Text buffer for logging/accumulating text +struct ImGuiTextEditCallbackData; // Shared state of ImGui::InputText() when using custom ImGuiTextEditCallback (rare/advanced use) +struct ImGuiSizeConstraintCallbackData;// Structure used to constraint window size in custom ways when using custom ImGuiSizeConstraintCallback (rare/advanced use) +struct ImGuiListClipper; // Helper to manually clip large list of items +struct ImGuiContext; // ImGui context (opaque) + +// Typedefs and Enumerations (declared as int for compatibility and to not pollute the top of this file) +typedef unsigned int ImU32; // 32-bit unsigned integer (typically used to store packed colors) +typedef unsigned int ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) +typedef unsigned short ImWchar; // character for keyboard input/display +typedef void* ImTextureID; // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) +typedef int ImGuiCol; // a color identifier for styling // enum ImGuiCol_ +typedef int ImGuiStyleVar; // a variable identifier for styling // enum ImGuiStyleVar_ +typedef int ImGuiKey; // a key identifier (ImGui-side enum) // enum ImGuiKey_ +typedef int ImGuiAlign; // alignment // enum ImGuiAlign_ +typedef int ImGuiColorEditMode; // color edit mode for ColorEdit*() // enum ImGuiColorEditMode_ +typedef int ImGuiMouseCursor; // a mouse cursor identifier // enum ImGuiMouseCursor_ +typedef int ImGuiWindowFlags; // window flags for Begin*() // enum ImGuiWindowFlags_ +typedef int ImGuiSetCond; // condition flags for Set*() // enum ImGuiSetCond_ +typedef int ImGuiInputTextFlags; // flags for InputText*() // enum ImGuiInputTextFlags_ +typedef int ImGuiSelectableFlags; // flags for Selectable() // enum ImGuiSelectableFlags_ +typedef int ImGuiTreeNodeFlags; // flags for TreeNode*(), Collapsing*() // enum ImGuiTreeNodeFlags_ +typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); +typedef void (*ImGuiSizeConstraintCallback)(ImGuiSizeConstraintCallbackData* data); + +// Others helpers at bottom of the file: +// class ImVector<> // Lightweight std::vector like class. +// IMGUI_ONCE_UPON_A_FRAME // Execute a block of code once per frame only (convenient for creating UI within deep-nested code that runs multiple times) + +struct ImVec2 +{ + float x, y; + ImVec2() { x = y = 0.0f; } + ImVec2(float _x, float _y) { x = _x; y = _y; } +#ifdef IM_VEC2_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec2. + IM_VEC2_CLASS_EXTRA +#endif +}; + +struct ImVec4 +{ + float x, y, z, w; + ImVec4() { x = y = z = w = 0.0f; } + ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; } +#ifdef IM_VEC4_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec4. + IM_VEC4_CLASS_EXTRA +#endif +}; + +// ImGui end-user API +// In a namespace so that user can add extra functions in a separate file (e.g. Value() helpers for your vector or common types) +namespace ImGui +{ + // Main + IMGUI_API ImGuiIO& GetIO(); + IMGUI_API ImGuiStyle& GetStyle(); + IMGUI_API ImDrawData* GetDrawData(); // same value as passed to your io.RenderDrawListsFn() function. valid after Render() and until the next call to NewFrame() + IMGUI_API void NewFrame(); // start a new ImGui frame, you can submit any command from this point until NewFrame()/Render(). + IMGUI_API void Render(); // ends the ImGui frame, finalize rendering data, then call your io.RenderDrawListsFn() function if set. + IMGUI_API void Shutdown(); + IMGUI_API void ShowUserGuide(); // help block + IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // style editor block. you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style) + IMGUI_API void ShowTestWindow(bool* p_open = NULL); // test window demonstrating ImGui features + IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // metrics window for debugging ImGui + + // Window + IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_open' creates a widget on the upper-right to close the window (which sets your bool to false). + IMGUI_API bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE. this is the older/longer API. the extra parameters aren't very relevant. call SetNextWindowSize() instead if you want to set a window size. For regular windows, 'size_on_first_use' only applies to the first time EVER the window is created and probably not what you want! might obsolete this API eventually. + IMGUI_API void End(); // finish appending to current window, pop it off the window stack. + IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400). + IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // " + IMGUI_API void EndChild(); + IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates + IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos() + IMGUI_API float GetContentRegionAvailWidth(); // + IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min (roughly (0,0)-Scroll), in window coordinates + IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates + IMGUI_API float GetWindowContentRegionWidth(); // + IMGUI_API ImDrawList* GetWindowDrawList(); // get rendering command-list if you want to append your own draw primitives + IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (useful if you want to do your own drawing via the DrawList api) + IMGUI_API ImVec2 GetWindowSize(); // get current window size + IMGUI_API float GetWindowWidth(); + IMGUI_API float GetWindowHeight(); + IMGUI_API bool IsWindowCollapsed(); + IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows + + IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // set next window position. call before Begin() + IMGUI_API void SetNextWindowPosCenter(ImGuiSetCond cond = 0); // set next window position to be centered on screen. call before Begin() + IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() + IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Use callback to apply non-trivial programmatic constraints. + IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (enforce the range of scrollbars). set axis to 0.0f to leave it automatic. call before Begin() + IMGUI_API void SetNextWindowContentWidth(float width); // set next window content width (enforce the range of horizontal scrollbar). call before Begin() + IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // set next window collapsed state. call before Begin() + IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin() + IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects. + IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0,0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects. + IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed(). + IMGUI_API void SetWindowFocus(); // (not recommended) set current window to be focused / front-most. prefer using SetNextWindowFocus(). + IMGUI_API void SetWindowPos(const char* name, const ImVec2& pos, ImGuiSetCond cond = 0); // set named window position. + IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiSetCond cond = 0); // set named window size. set axis to 0.0f to force an auto-fit on this axis. + IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond = 0); // set named window collapsed state + IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / front-most. use NULL to remove focus. + + IMGUI_API float GetScrollX(); // get scrolling amount [0..GetScrollMaxX()] + IMGUI_API float GetScrollY(); // get scrolling amount [0..GetScrollMaxY()] + IMGUI_API float GetScrollMaxX(); // get maximum scrolling amount ~~ ContentSize.X - WindowSize.X + IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.Y - WindowSize.Y + IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0..GetScrollMaxX()] + IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()] + IMGUI_API void SetScrollHere(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. + IMGUI_API void SetScrollFromPosY(float pos_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position valid. use GetCursorPos() or GetCursorStartPos()+offset to get valid positions. + IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use negative 'offset' to access previous widgets. + IMGUI_API void SetStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it) + IMGUI_API ImGuiStorage* GetStateStorage(); + + // Parameters stacks (shared) + IMGUI_API void PushFont(ImFont* font); // use NULL as a shortcut to push default font + IMGUI_API void PopFont(); + IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col); + IMGUI_API void PopStyleColor(int count = 1); + IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); + IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); + IMGUI_API void PopStyleVar(int count = 1); + IMGUI_API ImFont* GetFont(); // get current font + IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied + IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API + IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier + IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied + + // Parameters stacks (current window) + IMGUI_API void PushItemWidth(float item_width); // width of items for the common item+label case, pixels. 0.0f = default to ~2/3 of windows width, >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side) + IMGUI_API void PopItemWidth(); + IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position + IMGUI_API void PushTextWrapPos(float wrap_pos_x = 0.0f); // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space + IMGUI_API void PopTextWrapPos(); + IMGUI_API void PushAllowKeyboardFocus(bool v); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets + IMGUI_API void PopAllowKeyboardFocus(); + IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (uses io.KeyRepeatDelay/io.KeyRepeatRate for now). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame. + IMGUI_API void PopButtonRepeat(); + + // Cursor / Layout + IMGUI_API void Separator(); // horizontal line + IMGUI_API void SameLine(float pos_x = 0.0f, float spacing_w = -1.0f); // call between widgets or groups to layout them horizontally + IMGUI_API void NewLine(); // undo a SameLine() + IMGUI_API void Spacing(); // add vertical spacing + IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size + IMGUI_API void Indent(float indent_w = 0.0f); // move content position toward the right, by style.IndentSpacing or indent_w if >0 + IMGUI_API void Unindent(float indent_w = 0.0f); // move content position back to the left, by style.IndentSpacing or indent_w if >0 + IMGUI_API void BeginGroup(); // lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) + IMGUI_API void EndGroup(); + IMGUI_API ImVec2 GetCursorPos(); // cursor position is relative to window position + IMGUI_API float GetCursorPosX(); // " + IMGUI_API float GetCursorPosY(); // " + IMGUI_API void SetCursorPos(const ImVec2& local_pos); // " + IMGUI_API void SetCursorPosX(float x); // " + IMGUI_API void SetCursorPosY(float y); // " + IMGUI_API ImVec2 GetCursorStartPos(); // initial cursor position + IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute screen coordinates [0..io.DisplaySize] (useful to work with ImDrawList API) + IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute screen coordinates [0..io.DisplaySize] + IMGUI_API void AlignFirstTextHeightToWidgets(); // call once if the first item on the line is a Text() item and you want to vertically lower it to match subsequent (bigger) widgets + IMGUI_API float GetTextLineHeight(); // height of font == GetWindowFontSize() + IMGUI_API float GetTextLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of text == GetWindowFontSize() + GetStyle().ItemSpacing.y + IMGUI_API float GetItemsLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of standard height widgets == GetWindowFontSize() + GetStyle().FramePadding.y*2 + GetStyle().ItemSpacing.y + + // Columns + // You can also use SameLine(pos_x) for simplified columning. The columns API is still work-in-progress and rather lacking. + IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); // setup number of columns. use an identifier to distinguish multiple column sets. close with Columns(1). + IMGUI_API void NextColumn(); // next column + IMGUI_API int GetColumnIndex(); // get current column index + IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetcolumnsCount() inclusive. column 0 is usually 0.0f and not resizable unless you call this + IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column + IMGUI_API float GetColumnWidth(int column_index = -1); // column width (== GetColumnOffset(GetColumnIndex()+1) - GetColumnOffset(GetColumnOffset()) + IMGUI_API int GetColumnsCount(); // number of columns (what was passed to Columns()) + + // ID scopes + // If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them. + // You can also use the "##foobar" syntax within widget label to distinguish them from each others. Read "A primer on the use of labels/IDs" in the FAQ for more details. + IMGUI_API void PushID(const char* str_id); // push identifier into the ID stack. IDs are hash of the *entire* stack! + IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); + IMGUI_API void PushID(const void* ptr_id); + IMGUI_API void PushID(int int_id); + IMGUI_API void PopID(); + IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). useful if you want to query into ImGuiStorage yourself. otherwise rarely needed + IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end); + IMGUI_API ImGuiID GetID(const void* ptr_id); + + // Widgets + IMGUI_API void Text(const char* fmt, ...) IM_PRINTFARGS(1); + IMGUI_API void TextV(const char* fmt, va_list args); + IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...) IM_PRINTFARGS(2); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor(); + IMGUI_API void TextColoredV(const ImVec4& col, const char* fmt, va_list args); + IMGUI_API void TextDisabled(const char* fmt, ...) IM_PRINTFARGS(1); // shortcut for PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); Text(fmt, ...); PopStyleColor(); + IMGUI_API void TextDisabledV(const char* fmt, va_list args); + IMGUI_API void TextWrapped(const char* fmt, ...) IM_PRINTFARGS(1); // shortcut for PushTextWrapPos(0.0f); Text(fmt, ...); PopTextWrapPos();. Note that this won't work on an auto-resizing window if there's no other widgets to extend the window width, yoy may need to set a size using SetNextWindowSize(). + IMGUI_API void TextWrappedV(const char* fmt, va_list args); + IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, recommended for long chunks of text + IMGUI_API void LabelText(const char* label, const char* fmt, ...) IM_PRINTFARGS(2); // display text+label aligned the same way as value+label widgets + IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args); + IMGUI_API void Bullet(); // draw a small circle and keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses + IMGUI_API void BulletText(const char* fmt, ...) IM_PRINTFARGS(1); // shortcut for Bullet()+Text() + IMGUI_API void BulletTextV(const char* fmt, va_list args); + IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0)); // button + IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) + IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); + IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); + IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding + IMGUI_API bool Checkbox(const char* label, bool* v); + IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value); + IMGUI_API bool RadioButton(const char* label, bool active); + IMGUI_API bool RadioButton(const char* label, int* v, int v_button); + IMGUI_API bool Combo(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1); + IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items = -1); // separate items with \0, end item-list with \0\0 + IMGUI_API bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); + IMGUI_API bool ColorButton(const ImVec4& col, bool small_height = false, bool outline_border = true); + IMGUI_API bool ColorEdit3(const char* label, float col[3]); // Hint: 'float col[3]' function argument is same as 'float* col'. You can pass address of first element out of a contiguous set, e.g. &myvector.x + IMGUI_API bool ColorEdit4(const char* label, float col[4], bool show_alpha = true); // " + IMGUI_API void ColorEditMode(ImGuiColorEditMode mode); // FIXME-OBSOLETE: This is inconsistent with most of the API and will be obsoleted/replaced. + IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); + IMGUI_API void PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); + IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); + IMGUI_API void PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); + IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-1,0), const char* overlay = NULL); + + // Widgets: Drags (tip: ctrl+click on a drag box to input with keyboard. manually input values aren't clamped, can go off-bounds) + // For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, remember than a 'float v[3]' function argument is the same as 'float* v'. You can pass address of your first element out of a contiguous set, e.g. &myvector.x + IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound + IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", const char* display_format_max = NULL, float power = 1.0f); + IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); // If v_min >= v_max we have no bound + IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); + IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); + IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); + IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f", const char* display_format_max = NULL); + + // Widgets: Input with Keyboard + IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0,0), ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputFloat2(const char* label, float v[2], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputFloat3(const char* label, float v[3], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputFloat4(const char* label, float v[4], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100, ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputInt2(const char* label, int v[2], ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputInt3(const char* label, int v[3], ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_flags = 0); + + // Widgets: Sliders (tip: ctrl+click on a slider to input with keyboard. manually input values aren't clamped, can go off-bounds) + IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix. Use power!=1.0 for logarithmic sliders + IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool SliderAngle(const char* label, float* v_rad, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f); + IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f"); + IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format = "%.0f"); + IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format = "%.0f"); + IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format = "%.0f"); + IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f"); + + // Widgets: Trees + IMGUI_API bool TreeNode(const char* label); // if returning 'true' the node is open and the tree id is pushed into the id stack. user is responsible for calling TreePop(). + IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_PRINTFARGS(2); // read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet(). + IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_PRINTFARGS(2); // " + IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args); // " + IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args); // " + IMGUI_API bool TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags = 0); + IMGUI_API bool TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_PRINTFARGS(3); + IMGUI_API bool TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_PRINTFARGS(3); + IMGUI_API bool TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args); + IMGUI_API bool TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args); + IMGUI_API void TreePush(const char* str_id = NULL); // ~ Indent()+PushId(). Already called by TreeNode() when returning true, but you can call Push/Pop yourself for layout purpose + IMGUI_API void TreePush(const void* ptr_id = NULL); // " + IMGUI_API void TreePop(); // ~ Unindent()+PopId() + IMGUI_API void TreeAdvanceToLabelPos(); // advance cursor x position by GetTreeNodeToLabelSpacing() + IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceeding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode + IMGUI_API void SetNextTreeNodeOpen(bool is_open, ImGuiSetCond cond = 0); // set next TreeNode/CollapsingHeader open state. + IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop(). + IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header + + // Widgets: Selectable / Lists + IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height + IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); + IMGUI_API bool ListBox(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1); + IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); + IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards. + IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // " + IMGUI_API void ListBoxFooter(); // terminate the scrolling region + + // Widgets: Value() Helpers. Output single value in "name: value" format (tip: freely declare more in your code to handle your types. you can add functions to the ImGui namespace) + IMGUI_API void Value(const char* prefix, bool b); + IMGUI_API void Value(const char* prefix, int v); + IMGUI_API void Value(const char* prefix, unsigned int v); + IMGUI_API void Value(const char* prefix, float v, const char* float_format = NULL); + IMGUI_API void ValueColor(const char* prefix, const ImVec4& v); + IMGUI_API void ValueColor(const char* prefix, ImU32 v); + + // Tooltips + IMGUI_API void SetTooltip(const char* fmt, ...) IM_PRINTFARGS(1); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins + IMGUI_API void SetTooltipV(const char* fmt, va_list args); + IMGUI_API void BeginTooltip(); // use to create full-featured tooltip windows that aren't just text + IMGUI_API void EndTooltip(); + + // Menus + IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar. only call EndMainMenuBar() if this returns true! + IMGUI_API void EndMainMenuBar(); + IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set). only call EndMenuBar() if this returns true! + IMGUI_API void EndMenuBar(); + IMGUI_API bool BeginMenu(const char* label, bool enabled = true); // create a sub-menu entry. only call EndMenu() if this returns true! + IMGUI_API void EndMenu(); + IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. shortcuts are displayed for convenience but not processed by ImGui at the moment + IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL + + // Popups + IMGUI_API void OpenPopup(const char* str_id); // mark popup as open. popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). + IMGUI_API bool BeginPopup(const char* str_id); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true! + IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (can't close them by clicking outside) + IMGUI_API bool BeginPopupContextItem(const char* str_id, int mouse_button = 1); // helper to open and begin popup when clicked on last item. read comments in .cpp! + IMGUI_API bool BeginPopupContextWindow(bool also_over_items = true, const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on current window. + IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (no window). + IMGUI_API void EndPopup(); + IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. + + // Logging: all text output from interface is redirected to tty/file/clipboard. By default, tree nodes are automatically opened during logging. + IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty + IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL); // start logging to file + IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard + IMGUI_API void LogFinish(); // stop logging (close file, etc.) + IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard + IMGUI_API void LogText(const char* fmt, ...) IM_PRINTFARGS(1); // pass text data straight to log (without being displayed) + + // Clipping + IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); + IMGUI_API void PopClipRect(); + + // Utilities + IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse? + IMGUI_API bool IsItemHoveredRect(); // was the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this + IMGUI_API bool IsItemActive(); // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) + IMGUI_API bool IsItemClicked(int mouse_button = 0); // was the last item clicked? (e.g. button/node just clicked on) + IMGUI_API bool IsItemVisible(); // was the last item visible? (aka not out of sight due to clipping/scrolling.) + IMGUI_API bool IsAnyItemHovered(); + IMGUI_API bool IsAnyItemActive(); + IMGUI_API ImVec2 GetItemRectMin(); // get bounding rect of last item in screen space + IMGUI_API ImVec2 GetItemRectMax(); // " + IMGUI_API ImVec2 GetItemRectSize(); // " + IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. + IMGUI_API bool IsWindowHovered(); // is current window hovered and hoverable (not blocked by a popup) (differentiate child windows from each others) + IMGUI_API bool IsWindowFocused(); // is current window focused + IMGUI_API bool IsRootWindowFocused(); // is current root window focused (root = top-most parent of a child, otherwise self) + IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused + IMGUI_API bool IsRootWindowOrAnyChildHovered(); // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup) + IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. + IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. + IMGUI_API bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window + IMGUI_API float GetTime(); + IMGUI_API int GetFrameCount(); + IMGUI_API const char* GetStyleColName(ImGuiCol idx); + IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items + IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); + IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can. + + IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags extra_flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame + IMGUI_API void EndChildFrame(); + + IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in); + IMGUI_API ImU32 ColorConvertFloat4ToU32(const ImVec4& in); + IMGUI_API void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v); + IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b); + + // Inputs + IMGUI_API int GetKeyIndex(ImGuiKey key); // map ImGuiKey_* values into user's key index. == io.KeyMap[key] + IMGUI_API bool IsKeyDown(int key_index); // key_index into the keys_down[] array, imgui doesn't know the semantic of each entry, uses your own indices! + IMGUI_API bool IsKeyPressed(int key_index, bool repeat = true); // uses user's key indices as stored in the keys_down[] array. if repeat=true. uses io.KeyRepeatDelay / KeyRepeatRate + IMGUI_API bool IsKeyReleased(int key_index); // " + IMGUI_API bool IsMouseDown(int button); // is mouse button held + IMGUI_API bool IsMouseClicked(int button, bool repeat = false); // did mouse button clicked (went from !Down to Down) + IMGUI_API bool IsMouseDoubleClicked(int button); // did mouse button double-clicked. a double-click returns false in IsMouseClicked(). uses io.MouseDoubleClickTime. + IMGUI_API bool IsMouseReleased(int button); // did mouse button released (went from Down to !Down) + IMGUI_API bool IsMouseHoveringWindow(); // is mouse hovering current window ("window" in API names always refer to current window). disregarding of any consideration of being blocked by a popup. (unlike IsWindowHovered() this will return true even if the window is blocked because of a popup) + IMGUI_API bool IsMouseHoveringAnyWindow(); // is mouse hovering any visible window + IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true); // is mouse hovering given bounding rect (in screen space). clipped by current clipping settings. disregarding of consideration of focus/window ordering/blocked by a popup. + IMGUI_API bool IsMouseDragging(int button = 0, float lock_threshold = -1.0f); // is mouse dragging. if lock_threshold < -1.0f uses io.MouseDraggingThreshold + IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls + IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve backup of mouse positioning at the time of opening popup we have BeginPopup() into + IMGUI_API ImVec2 GetMouseDragDelta(int button = 0, float lock_threshold = -1.0f); // dragging amount since clicking. if lock_threshold < -1.0f uses io.MouseDraggingThreshold + IMGUI_API void ResetMouseDragDelta(int button = 0); // + IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you + IMGUI_API void SetMouseCursor(ImGuiMouseCursor type); // set desired cursor type + IMGUI_API void CaptureKeyboardFromApp(bool capture = true); // manually override io.WantCaptureKeyboard flag next frame (said flag is entirely left for your application handle). e.g. force capture keyboard when your widget is being hovered. + IMGUI_API void CaptureMouseFromApp(bool capture = true); // manually override io.WantCaptureMouse flag next frame (said flag is entirely left for your application handle). + + // Helpers functions to access functions pointers in ImGui::GetIO() + IMGUI_API void* MemAlloc(size_t sz); + IMGUI_API void MemFree(void* ptr); + IMGUI_API const char* GetClipboardText(); + IMGUI_API void SetClipboardText(const char* text); + + // Internal context access - if you want to use multiple context, share context between modules (e.g. DLL). There is a default context created and active by default. + // All contexts share a same ImFontAtlas by default. If you want different font atlas, you can new() them and overwrite the GetIO().Fonts variable of an ImGui context. + IMGUI_API const char* GetVersion(); + IMGUI_API ImGuiContext* CreateContext(void* (*malloc_fn)(size_t) = NULL, void (*free_fn)(void*) = NULL); + IMGUI_API void DestroyContext(ImGuiContext* ctx); + IMGUI_API ImGuiContext* GetCurrentContext(); + IMGUI_API void SetCurrentContext(ImGuiContext* ctx); + + // Obsolete (will be removed) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1<<5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ + static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ + static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+ + static inline void SetScrollPosHere() { SetScrollHere(); } // OBSOLETE 1.42+ + static inline bool GetWindowCollapsed() { return ImGui::IsWindowCollapsed(); } // OBSOLETE 1.39+ + static inline bool IsRectClipped(const ImVec2& size) { return !IsRectVisible(size); } // OBSOLETE 1.39+ +#endif + +} // namespace ImGui + +// Flags for ImGui::Begin() +enum ImGuiWindowFlags_ +{ + // Default: 0 + ImGuiWindowFlags_NoTitleBar = 1 << 0, // Disable title-bar + ImGuiWindowFlags_NoResize = 1 << 1, // Disable user resizing with the lower-right grip + ImGuiWindowFlags_NoMove = 1 << 2, // Disable user moving the window + ImGuiWindowFlags_NoScrollbar = 1 << 3, // Disable scrollbars (window can still scroll with mouse or programatically) + ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel + ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it + ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame + ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items + ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file + ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs + ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar + ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, // Allow horizontal scrollbar to appear (off by default). You may use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section. + ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12, // Disable taking focus when transitioning from hidden to visible state + ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, // Disable bringing window to front when taking focus (e.g. clicking on it or programatically giving it focus) + ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y) + ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x) + ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient) + // [Internal] + ImGuiWindowFlags_ChildWindow = 1 << 20, // Don't use! For internal use by BeginChild() + ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 21, // Don't use! For internal use by BeginChild() + ImGuiWindowFlags_ChildWindowAutoFitY = 1 << 22, // Don't use! For internal use by BeginChild() + ImGuiWindowFlags_ComboBox = 1 << 23, // Don't use! For internal use by ComboBox() + ImGuiWindowFlags_Tooltip = 1 << 24, // Don't use! For internal use by BeginTooltip() + ImGuiWindowFlags_Popup = 1 << 25, // Don't use! For internal use by BeginPopup() + ImGuiWindowFlags_Modal = 1 << 26, // Don't use! For internal use by BeginPopupModal() + ImGuiWindowFlags_ChildMenu = 1 << 27 // Don't use! For internal use by BeginMenu() +}; + +// Flags for ImGui::InputText() +enum ImGuiInputTextFlags_ +{ + // Default: 0 + ImGuiInputTextFlags_CharsDecimal = 1 << 0, // Allow 0123456789.+-*/ + ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, // Allow 0123456789ABCDEFabcdef + ImGuiInputTextFlags_CharsUppercase = 1 << 2, // Turn a..z into A..Z + ImGuiInputTextFlags_CharsNoBlank = 1 << 3, // Filter out spaces, tabs + ImGuiInputTextFlags_AutoSelectAll = 1 << 4, // Select entire text when first taking mouse focus + ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to when the value was modified) + ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Call user function on pressing TAB (for completion handling) + ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Call user function on pressing Up/Down arrows (for history handling) + ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Call user function every time. User code may query cursor position, modify text buffer. + ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character. + ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field + ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, allow exiting edition by pressing Enter. Ctrl+Enter to add new line (by default adds new lines with Enter). + ImGuiInputTextFlags_NoHorizontalScroll = 1 << 12, // Disable following the cursor horizontally + ImGuiInputTextFlags_AlwaysInsertMode = 1 << 13, // Insert mode + ImGuiInputTextFlags_ReadOnly = 1 << 14, // Read-only mode + ImGuiInputTextFlags_Password = 1 << 15, // Password mode, display all characters as '*' + // [Internal] + ImGuiInputTextFlags_Multiline = 1 << 20 // For internal use by InputTextMultiline() +}; + +// Flags for ImGui::TreeNodeEx(), ImGui::CollapsingHeader*() +enum ImGuiTreeNodeFlags_ +{ + ImGuiTreeNodeFlags_Selected = 1 << 0, // Draw as selected + ImGuiTreeNodeFlags_Framed = 1 << 1, // Full colored frame (e.g. for CollapsingHeader) + ImGuiTreeNodeFlags_AllowOverlapMode = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one + ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, // Don't do a TreePush() when open (e.g. for CollapsingHeader) = no extra indent nor pushing on ID stack + ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes) + ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, // Default node to be open + ImGuiTreeNodeFlags_OpenOnDoubleClick = 1 << 6, // Need double-click to open node + ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open. + ImGuiTreeNodeFlags_Leaf = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes). + ImGuiTreeNodeFlags_Bullet = 1 << 9, // Display a bullet instead of arrow + //ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 10, // FIXME: TODO: Extend hit box horizontally even if not framed + //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 11, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible + ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoAutoOpenOnLog +}; + +// Flags for ImGui::Selectable() +enum ImGuiSelectableFlags_ +{ + // Default: 0 + ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window + ImGuiSelectableFlags_SpanAllColumns = 1 << 1, // Selectable frame can span all columns (text will still fit in current column) + ImGuiSelectableFlags_AllowDoubleClick = 1 << 2 // Generate press events on double clicks too +}; + +// User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array +enum ImGuiKey_ +{ + ImGuiKey_Tab, // for tabbing through fields + ImGuiKey_LeftArrow, // for text edit + ImGuiKey_RightArrow,// for text edit + ImGuiKey_UpArrow, // for text edit + ImGuiKey_DownArrow, // for text edit + ImGuiKey_PageUp, + ImGuiKey_PageDown, + ImGuiKey_Home, // for text edit + ImGuiKey_End, // for text edit + ImGuiKey_Delete, // for text edit + ImGuiKey_Backspace, // for text edit + ImGuiKey_Enter, // for text edit + ImGuiKey_Escape, // for text edit + ImGuiKey_A, // for text edit CTRL+A: select all + ImGuiKey_C, // for text edit CTRL+C: copy + ImGuiKey_V, // for text edit CTRL+V: paste + ImGuiKey_X, // for text edit CTRL+X: cut + ImGuiKey_Y, // for text edit CTRL+Y: redo + ImGuiKey_Z, // for text edit CTRL+Z: undo + ImGuiKey_COUNT +}; + +// Enumeration for PushStyleColor() / PopStyleColor() +enum ImGuiCol_ +{ + ImGuiCol_Text, + ImGuiCol_TextDisabled, + ImGuiCol_WindowBg, // Background of normal windows + ImGuiCol_ChildWindowBg, // Background of child windows + ImGuiCol_PopupBg, // Background of popups, menus, tooltips windows + ImGuiCol_Border, + ImGuiCol_BorderShadow, + ImGuiCol_FrameBg, // Background of checkbox, radio button, plot, slider, text input + ImGuiCol_FrameBgHovered, + ImGuiCol_FrameBgActive, + ImGuiCol_TitleBg, + ImGuiCol_TitleBgCollapsed, + ImGuiCol_TitleBgActive, + ImGuiCol_MenuBarBg, + ImGuiCol_ScrollbarBg, + ImGuiCol_ScrollbarGrab, + ImGuiCol_ScrollbarGrabHovered, + ImGuiCol_ScrollbarGrabActive, + ImGuiCol_ComboBg, + ImGuiCol_CheckMark, + ImGuiCol_SliderGrab, + ImGuiCol_SliderGrabActive, + ImGuiCol_Button, + ImGuiCol_ButtonHovered, + ImGuiCol_ButtonActive, + ImGuiCol_Header, + ImGuiCol_HeaderHovered, + ImGuiCol_HeaderActive, + ImGuiCol_Column, + ImGuiCol_ColumnHovered, + ImGuiCol_ColumnActive, + ImGuiCol_ResizeGrip, + ImGuiCol_ResizeGripHovered, + ImGuiCol_ResizeGripActive, + ImGuiCol_CloseButton, + ImGuiCol_CloseButtonHovered, + ImGuiCol_CloseButtonActive, + ImGuiCol_PlotLines, + ImGuiCol_PlotLinesHovered, + ImGuiCol_PlotHistogram, + ImGuiCol_PlotHistogramHovered, + ImGuiCol_TextSelectedBg, + ImGuiCol_ModalWindowDarkening, // darken entire screen when a modal window is active + ImGuiCol_COUNT +}; + +// Enumeration for PushStyleVar() / PopStyleVar() +// NB: the enum only refers to fields of ImGuiStyle() which makes sense to be pushed/poped in UI code. Feel free to add others. +enum ImGuiStyleVar_ +{ + ImGuiStyleVar_Alpha, // float + ImGuiStyleVar_WindowPadding, // ImVec2 + ImGuiStyleVar_WindowRounding, // float + ImGuiStyleVar_WindowMinSize, // ImVec2 + ImGuiStyleVar_ChildWindowRounding, // float + ImGuiStyleVar_FramePadding, // ImVec2 + ImGuiStyleVar_FrameRounding, // float + ImGuiStyleVar_ItemSpacing, // ImVec2 + ImGuiStyleVar_ItemInnerSpacing, // ImVec2 + ImGuiStyleVar_IndentSpacing, // float + ImGuiStyleVar_GrabMinSize // float +}; + +enum ImGuiAlign_ +{ + ImGuiAlign_Left = 1 << 0, + ImGuiAlign_Center = 1 << 1, + ImGuiAlign_Right = 1 << 2, + ImGuiAlign_Top = 1 << 3, + ImGuiAlign_VCenter = 1 << 4, + ImGuiAlign_Default = ImGuiAlign_Left | ImGuiAlign_Top +}; + +// Enumeration for ColorEditMode() +// FIXME-OBSOLETE: Will be replaced by future color/picker api +enum ImGuiColorEditMode_ +{ + ImGuiColorEditMode_UserSelect = -2, + ImGuiColorEditMode_UserSelectShowButton = -1, + ImGuiColorEditMode_RGB = 0, + ImGuiColorEditMode_HSV = 1, + ImGuiColorEditMode_HEX = 2 +}; + +// Enumeration for GetMouseCursor() +enum ImGuiMouseCursor_ +{ + ImGuiMouseCursor_Arrow = 0, + ImGuiMouseCursor_TextInput, // When hovering over InputText, etc. + ImGuiMouseCursor_Move, // Unused + ImGuiMouseCursor_ResizeNS, // Unused + ImGuiMouseCursor_ResizeEW, // When hovering over a column + ImGuiMouseCursor_ResizeNESW, // Unused + ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window + ImGuiMouseCursor_Count_ +}; + +// Condition flags for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions +// All those functions treat 0 as a shortcut to ImGuiSetCond_Always +enum ImGuiSetCond_ +{ + ImGuiSetCond_Always = 1 << 0, // Set the variable + ImGuiSetCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call with succeed) + ImGuiSetCond_FirstUseEver = 1 << 2, // Set the variable if the window has no saved data (if doesn't exist in the .ini file) + ImGuiSetCond_Appearing = 1 << 3 // Set the variable if the window is appearing after being hidden/inactive (or the first time) +}; + +struct ImGuiStyle +{ + float Alpha; // Global alpha applies to everything in ImGui + ImVec2 WindowPadding; // Padding within a window + ImVec2 WindowMinSize; // Minimum window size + float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + ImGuiAlign WindowTitleAlign; // Alignment for title bar text + float ChildWindowRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows + ImVec2 FramePadding; // Padding within a framed rectangle (used by most widgets) + float FrameRounding; // Radius of frame corners rounding. Set to 0.0f to have rectangular frame (used by most widgets). + ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines + ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) + ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! + float IndentSpacing; // Horizontal indentation when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). + float ColumnsMinSpacing; // Minimum horizontal spacing between two columns + float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar + float ScrollbarRounding; // Radius of grab corners for scrollbar + float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar + float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. + ImVec2 DisplayWindowPadding; // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows. + ImVec2 DisplaySafeAreaPadding; // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. + bool AntiAliasedLines; // Enable anti-aliasing on lines/borders. Disable if you are really tight on CPU/GPU. + bool AntiAliasedShapes; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) + float CurveTessellationTol; // Tessellation tolerance. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. + ImVec4 Colors[ImGuiCol_COUNT]; + + IMGUI_API ImGuiStyle(); +}; + +// This is where your app communicate with ImGui. Access via ImGui::GetIO(). +// Read 'Programmer guide' section in .cpp file for general usage. +struct ImGuiIO +{ + //------------------------------------------------------------------ + // Settings (fill once) // Default value: + //------------------------------------------------------------------ + + ImVec2 DisplaySize; // // Display size, in pixels. For clamping windows positions. + float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. + float IniSavingRate; // = 5.0f // Maximum time between saving positions/sizes to .ini file, in seconds. + const char* IniFilename; // = "imgui.ini" // Path to .ini file. NULL to disable .ini saving. + const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified). + float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds. + float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. + float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging + int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array + float KeyRepeatDelay; // = 0.250f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.). + float KeyRepeatRate; // = 0.020f // When holding a key/button, rate at which it repeats, in seconds. + void* UserData; // = NULL // Store your own data for retrieval by callbacks. + + ImFontAtlas* Fonts; // // Load and assemble one or more fonts into a single tightly packed texture. Output to Fonts array. + float FontGlobalScale; // = 1.0f // Global scale all fonts + bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel. + ImVec2 DisplayFramebufferScale; // = (1.0f,1.0f) // For retina display or other situations where window coordinates are different from framebuffer coordinates. User storage only, presently not used by ImGui. + ImVec2 DisplayVisibleMin; // (0.0f,0.0f) // If you use DisplaySize as a virtual space larger than your screen, set DisplayVisibleMin/Max to the visible area. + ImVec2 DisplayVisibleMax; // (0.0f,0.0f) // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize + + // Advanced/subtle behaviors + bool OSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl + + //------------------------------------------------------------------ + // User Functions + //------------------------------------------------------------------ + + // Rendering function, will be called in Render(). + // Alternatively you can keep this to NULL and call GetDrawData() after Render() to get the same pointer. + // See example applications if you are unsure of how to implement this. + void (*RenderDrawListsFn)(ImDrawData* data); + + // Optional: access OS clipboard + // (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures) + const char* (*GetClipboardTextFn)(); + void (*SetClipboardTextFn)(const char* text); + + // Optional: override memory allocations. MemFreeFn() may be called with a NULL pointer. + // (default to posix malloc/free) + void* (*MemAllocFn)(size_t sz); + void (*MemFreeFn)(void* ptr); + + // Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME in Windows) + // (default to use native imm32 api on Windows) + void (*ImeSetInputScreenPosFn)(int x, int y); + void* ImeWindowHandle; // (Windows) Set this to your HWND to get automatic IME cursor positioning. + + //------------------------------------------------------------------ + // Input - Fill before calling NewFrame() + //------------------------------------------------------------------ + + ImVec2 MousePos; // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + bool MouseDown[5]; // Mouse buttons: left, right, middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. + float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text. + bool MouseDrawCursor; // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). + bool KeyCtrl; // Keyboard modifier pressed: Control + bool KeyShift; // Keyboard modifier pressed: Shift + bool KeyAlt; // Keyboard modifier pressed: Alt + bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows + bool KeysDown[512]; // Keyboard keys that are pressed (in whatever storage order you naturally have access to keyboard data) + ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper. + + // Functions + IMGUI_API void AddInputCharacter(ImWchar c); // Helper to add a new character into InputCharacters[] + IMGUI_API void AddInputCharactersUTF8(const char* utf8_chars); // Helper to add new characters into InputCharacters[] from an UTF-8 string + inline void ClearInputCharacters() { InputCharacters[0] = 0; } // Helper to clear the text input buffer + + //------------------------------------------------------------------ + // Output - Retrieve after calling NewFrame(), you can use them to discard inputs or hide them from the rest of your application + //------------------------------------------------------------------ + + bool WantCaptureMouse; // Mouse is hovering a window or widget is active (= ImGui will use your mouse input) + bool WantCaptureKeyboard; // Widget is active (= ImGui will use your keyboard input) + bool WantTextInput; // Some text input widget is active, which will read input characters from the InputCharacters array. + float Framerate; // Framerate estimation, in frame per second. Rolling average estimation based on IO.DeltaTime over 120 frames + int MetricsAllocs; // Number of active memory allocations + int MetricsRenderVertices; // Vertices output during last call to Render() + int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3 + int MetricsActiveWindows; // Number of visible windows (exclude child windows) + + //------------------------------------------------------------------ + // [Internal] ImGui will maintain those fields for you + //------------------------------------------------------------------ + + ImVec2 MousePosPrev; // Previous mouse position + ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are negative to allow mouse enabling/disabling. + bool MouseClicked[5]; // Mouse button went from !Down to Down + ImVec2 MouseClickedPos[5]; // Position at time of clicking + float MouseClickedTime[5]; // Time of last click (used to figure out double-click) + bool MouseDoubleClicked[5]; // Has mouse button been double-clicked? + bool MouseReleased[5]; // Mouse button went from Down to !Down + bool MouseDownOwned[5]; // Track if button was clicked inside a window. We don't request mouse capture from the application if click started outside ImGui bounds. + float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked) + float MouseDownDurationPrev[5]; // Previous time the mouse button has been down + float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the click point + float KeysDownDuration[512]; // Duration the keyboard key has been down (0.0f == just pressed) + float KeysDownDurationPrev[512]; // Previous duration the key has been down + + IMGUI_API ImGuiIO(); +}; + +//----------------------------------------------------------------------------- +// Helpers +//----------------------------------------------------------------------------- + +// Lightweight std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug). +// Our implementation does NOT call c++ constructors because we don't use them in ImGui. Don't use this class as a straight std::vector replacement in your code! +template +class ImVector +{ +public: + int Size; + int Capacity; + T* Data; + + typedef T value_type; + typedef value_type* iterator; + typedef const value_type* const_iterator; + + ImVector() { Size = Capacity = 0; Data = NULL; } + ~ImVector() { if (Data) ImGui::MemFree(Data); } + + inline bool empty() const { return Size == 0; } + inline int size() const { return Size; } + inline int capacity() const { return Capacity; } + + inline value_type& operator[](int i) { IM_ASSERT(i < Size); return Data[i]; } + inline const value_type& operator[](int i) const { IM_ASSERT(i < Size); return Data[i]; } + + inline void clear() { if (Data) { Size = Capacity = 0; ImGui::MemFree(Data); Data = NULL; } } + inline iterator begin() { return Data; } + inline const_iterator begin() const { return Data; } + inline iterator end() { return Data + Size; } + inline const_iterator end() const { return Data + Size; } + inline value_type& front() { IM_ASSERT(Size > 0); return Data[0]; } + inline const value_type& front() const { IM_ASSERT(Size > 0); return Data[0]; } + inline value_type& back() { IM_ASSERT(Size > 0); return Data[Size-1]; } + inline const value_type& back() const { IM_ASSERT(Size > 0); return Data[Size-1]; } + inline void swap(ImVector& rhs) { int rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; int rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; } + + inline int _grow_capacity(int new_size) { int new_capacity = Capacity ? (Capacity + Capacity/2) : 8; return new_capacity > new_size ? new_capacity : new_size; } + + inline void resize(int new_size) { if (new_size > Capacity) reserve(_grow_capacity(new_size)); Size = new_size; } + inline void reserve(int new_capacity) + { + if (new_capacity <= Capacity) return; + T* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(value_type)); + if (Data) + memcpy(new_data, Data, (size_t)Size * sizeof(value_type)); + ImGui::MemFree(Data); + Data = new_data; + Capacity = new_capacity; + } + + inline void push_back(const value_type& v) { if (Size == Capacity) reserve(_grow_capacity(Size+1)); Data[Size++] = v; } + inline void pop_back() { IM_ASSERT(Size > 0); Size--; } + + inline iterator erase(const_iterator it) { IM_ASSERT(it >= Data && it < Data+Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; } + inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; } +}; + +// Helper: execute a block of code at maximum once a frame +// Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. +// Usage: +// IMGUI_ONCE_UPON_A_FRAME +// { +// // code block will be executed one per frame +// } +// Attention! the macro expands into 2 statement so make sure you don't use it within e.g. an if() statement without curly braces. +#define IMGUI_ONCE_UPON_A_FRAME static ImGuiOnceUponAFrame imgui_oaf##__LINE__; if (imgui_oaf##__LINE__) +struct ImGuiOnceUponAFrame +{ + ImGuiOnceUponAFrame() { RefFrame = -1; } + mutable int RefFrame; + operator bool() const { int current_frame = ImGui::GetFrameCount(); if (RefFrame == current_frame) return false; RefFrame = current_frame; return true; } +}; + +// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" +struct ImGuiTextFilter +{ + struct TextRange + { + const char* b; + const char* e; + + TextRange() { b = e = NULL; } + TextRange(const char* _b, const char* _e) { b = _b; e = _e; } + const char* begin() const { return b; } + const char* end() const { return e; } + bool empty() const { return b == e; } + char front() const { return *b; } + static bool is_blank(char c) { return c == ' ' || c == '\t'; } + void trim_blanks() { while (b < e && is_blank(*b)) b++; while (e > b && is_blank(*(e-1))) e--; } + IMGUI_API void split(char separator, ImVector& out); + }; + + char InputBuf[256]; + ImVector Filters; + int CountGrep; + + ImGuiTextFilter(const char* default_filter = ""); + ~ImGuiTextFilter() {} + void Clear() { InputBuf[0] = 0; Build(); } + bool Draw(const char* label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build + bool PassFilter(const char* text, const char* text_end = NULL) const; + bool IsActive() const { return !Filters.empty(); } + IMGUI_API void Build(); +}; + +// Helper: Text buffer for logging/accumulating text +struct ImGuiTextBuffer +{ + ImVector Buf; + + ImGuiTextBuffer() { Buf.push_back(0); } + inline char operator[](int i) { return Buf.Data[i]; } + const char* begin() const { return &Buf.front(); } + const char* end() const { return &Buf.back(); } // Buf is zero-terminated, so end() will point on the zero-terminator + int size() const { return Buf.Size - 1; } + bool empty() { return Buf.Size <= 1; } + void clear() { Buf.clear(); Buf.push_back(0); } + const char* c_str() const { return Buf.Data; } + IMGUI_API void append(const char* fmt, ...) IM_PRINTFARGS(2); + IMGUI_API void appendv(const char* fmt, va_list args); +}; + +// Helper: Simple Key->value storage +// - Store collapse state for a tree (Int 0/1) +// - Store color edit options (Int using values in ImGuiColorEditMode enum). +// - Custom user storage for temporary values. +// Typically you don't have to worry about this since a storage is held within each Window. +// Declare your own storage if: +// - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state). +// - You want to store custom debug data easily without adding or editing structures in your code. +// Types are NOT stored, so it is up to you to make sure your Key don't collide with different types. +struct ImGuiStorage +{ + struct Pair + { + ImGuiID key; + union { int val_i; float val_f; void* val_p; }; + Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; } + Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; } + Pair(ImGuiID _key, void* _val_p) { key = _key; val_p = _val_p; } + }; + ImVector Data; + + // - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N) + // - Set***() functions find pair, insertion on demand if missing. + // - Sorted insertion is costly, paid once. A typical frame shouldn't need to insert any new pair. + IMGUI_API void Clear(); + IMGUI_API int GetInt(ImGuiID key, int default_val = 0) const; + IMGUI_API void SetInt(ImGuiID key, int val); + IMGUI_API bool GetBool(ImGuiID key, bool default_val = false) const; + IMGUI_API void SetBool(ImGuiID key, bool val); + IMGUI_API float GetFloat(ImGuiID key, float default_val = 0.0f) const; + IMGUI_API void SetFloat(ImGuiID key, float val); + IMGUI_API void* GetVoidPtr(ImGuiID key) const; // default_val is NULL + IMGUI_API void SetVoidPtr(ImGuiID key, void* val); + + // - Get***Ref() functions finds pair, insert on demand if missing, return pointer. Useful if you intend to do Get+Set. + // - References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer. + // - A typical use case where this is convenient: + // float* pvar = ImGui::GetFloatRef(key); ImGui::SliderFloat("var", pvar, 0, 100.0f); some_var += *pvar; + // - You can also use this to quickly create temporary editable values during a session of using Edit&Continue, without restarting your application. + IMGUI_API int* GetIntRef(ImGuiID key, int default_val = 0); + IMGUI_API bool* GetBoolRef(ImGuiID key, bool default_val = false); + IMGUI_API float* GetFloatRef(ImGuiID key, float default_val = 0.0f); + IMGUI_API void** GetVoidPtrRef(ImGuiID key, void* default_val = NULL); + + // Use on your own storage if you know only integer are being stored (open/close all tree nodes) + IMGUI_API void SetAllInt(int val); +}; + +// Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used and the corresponding callback is triggered. +struct ImGuiTextEditCallbackData +{ + ImGuiInputTextFlags EventFlag; // One of ImGuiInputTextFlags_Callback* // Read-only + ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only + void* UserData; // What user passed to InputText() // Read-only + bool ReadOnly; // Read-only mode // Read-only + + // CharFilter event: + ImWchar EventChar; // Character input // Read-write (replace character or set to zero) + + // Completion,History,Always events: + // If you modify the buffer contents make sure you update 'BufTextLen' and set 'BufDirty' to true. + ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only + char* Buf; // Current text buffer // Read-write (pointed data only, can't replace the actual pointer) + int BufTextLen; // Current text length in bytes // Read-write + int BufSize; // Maximum text length in bytes // Read-only + bool BufDirty; // Set if you modify Buf/BufTextLen!! // Write + int CursorPos; // // Read-write + int SelectionStart; // // Read-write (== to SelectionEnd when no selection) + int SelectionEnd; // // Read-write + + // NB: Helper functions for text manipulation. Calling those function loses selection. + void DeleteChars(int pos, int bytes_count); + void InsertChars(int pos, const char* text, const char* text_end = NULL); + bool HasSelection() const { return SelectionStart != SelectionEnd; } +}; + +// Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin(). +// NB: For basic min/max size constraint on each axis you don't need to use the callback! The SetNextWindowSizeConstraints() parameters are enough. +struct ImGuiSizeConstraintCallbackData +{ + void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraints() + ImVec2 Pos; // Read-only. Window position, for reference. + ImVec2 CurrentSize; // Read-only. Current window size. + ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing. +}; + +// ImColor() helper to implicity converts colors to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float) +// Prefer using IM_COL32() macros if you want a guaranteed compile-time ImU32 for usage with ImDrawList API. +// Avoid storing ImColor! Store either u32 of ImVec4. This is not a full-featured color class. +// None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats. +struct ImColor +{ + ImVec4 Value; + + ImColor() { Value.x = Value.y = Value.z = Value.w = 0.0f; } + ImColor(int r, int g, int b, int a = 255) { float sc = 1.0f/255.0f; Value.x = (float)r * sc; Value.y = (float)g * sc; Value.z = (float)b * sc; Value.w = (float)a * sc; } + ImColor(ImU32 rgba) { float sc = 1.0f/255.0f; Value.x = (float)(rgba&0xFF) * sc; Value.y = (float)((rgba>>8)&0xFF) * sc; Value.z = (float)((rgba>>16)&0xFF) * sc; Value.w = (float)(rgba >> 24) * sc; } + ImColor(float r, float g, float b, float a = 1.0f) { Value.x = r; Value.y = g; Value.z = b; Value.w = a; } + ImColor(const ImVec4& col) { Value = col; } + inline operator ImU32() const { return ImGui::ColorConvertFloat4ToU32(Value); } + inline operator ImVec4() const { return Value; } + + inline void SetHSV(float h, float s, float v, float a = 1.0f){ ImGui::ColorConvertHSVtoRGB(h, s, v, Value.x, Value.y, Value.z); Value.w = a; } + + static ImColor HSV(float h, float s, float v, float a = 1.0f) { float r,g,b; ImGui::ColorConvertHSVtoRGB(h, s, v, r, g, b); return ImColor(r,g,b,a); } +}; + +// Helper: Manually clip large list of items. +// If you are submitting lots of evenly spaced items and you have a random access to the list, you can perform coarse clipping based on visibility to save yourself from processing those items at all. +// The clipper calculates the range of visible items and advance the cursor to compensate for the non-visible items we have skipped. +// ImGui already clip items based on their bounds but it needs to measure text size to do so. Coarse clipping before submission makes this cost and your own data fetching/submission cost null. +// Usage: +// ImGuiListClipper clipper(1000); // we have 1000 elements, evenly spaced. +// while (clipper.Step()) +// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) +// ImGui::Text("line number %d", i); +// - Step 0: the clipper let you process the first element, regardless of it being visible or not, so we can measure the element height (step skipped if we passed a known height as second arg to constructor). +// - Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element. +// - (Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user call Step(). Does nothing and switch to Step 3.) +// - Step 3: the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), advance the cursor to the end of the list and then returns 'false' to end the loop. +struct ImGuiListClipper +{ + float StartPosY; + float ItemsHeight; + int ItemsCount, StepNo, DisplayStart, DisplayEnd; + + // items_count: Use -1 to ignore (you can call Begin later). Use INT_MAX if you don't know how many items you have (in which case the cursor won't be advanced in the final step). + // items_height: Use -1.0f to be calculated automatically on first step. Otherwise pass in the distance between your items, typically GetTextLineHeightWithSpacing() or GetItemsLineHeightWithSpacing(). + // If you don't specify an items_height, you NEED to call Step(). If you specify items_height you may call the old Begin()/End() api directly, but prefer calling Step(). + ImGuiListClipper(int items_count = -1, float items_height = -1.0f) { Begin(items_count, items_height); } // NB: Begin() initialize every fields (as we allow user to call Begin/End multiple times on a same instance if they want). + ~ImGuiListClipper() { IM_ASSERT(ItemsCount == -1); } // Assert if user forgot to call End() or Step() until false. + + IMGUI_API bool Step(); // Call until it returns false. The DisplayStart/DisplayEnd fields will be set and you can process/draw those items. + IMGUI_API void Begin(int items_count, float items_height = -1.0f); // Automatically called by constructor if you passed 'items_count' or by Step() in Step 1. + IMGUI_API void End(); // Automatically called on the last call of Step() that returns false. +}; + +//----------------------------------------------------------------------------- +// Draw List +// Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList. +//----------------------------------------------------------------------------- + +// Helpers macros to generate 32-bits encoded colors +#define IM_COL32(R,G,B,A) (((ImU32)(A)<<24) | ((ImU32)(B)<<16) | ((ImU32)(G)<<8) | ((ImU32)(R))) +#define IM_COL32_WHITE (0xFFFFFFFF) +#define IM_COL32_BLACK (0xFF000000) +#define IM_COL32_BLACK_TRANS (0x00000000) // Transparent black + +// Draw callbacks for advanced uses. +// NB- You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering (you can poke into the draw list for that) +// Draw callback may be useful for example, A) Change your GPU render state, B) render a complex 3D scene inside a UI element (without an intermediate texture/render target), etc. +// The expected behavior from your rendering function is 'if (cmd.UserCallback != NULL) cmd.UserCallback(parent_list, cmd); else RenderTriangles()' +typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* cmd); + +// Typically, 1 command = 1 gpu draw call (unless command is a callback) +struct ImDrawCmd +{ + unsigned int ElemCount; // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[]. + ImVec4 ClipRect; // Clipping rectangle (x1, y1, x2, y2) + ImTextureID TextureId; // User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions. Ignore if never using images or multiple fonts atlas. + ImDrawCallback UserCallback; // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally. + void* UserCallbackData; // The draw callback code can access this. + + ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = -8192.0f; ClipRect.z = ClipRect.w = +8192.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; } +}; + +// Vertex index (override with '#define ImDrawIdx unsigned int' inside in imconfig.h) +#ifndef ImDrawIdx +typedef unsigned short ImDrawIdx; +#endif + +// Vertex layout +#ifndef IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT +struct ImDrawVert +{ + ImVec2 pos; + ImVec2 uv; + ImU32 col; +}; +#else +// You can override the vertex format layout by defining IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT in imconfig.h +// The code expect ImVec2 pos (8 bytes), ImVec2 uv (8 bytes), ImU32 col (4 bytes), but you can re-order them or add other fields as needed to simplify integration in your engine. +// The type has to be described within the macro (you can either declare the struct or use a typedef) +IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT; +#endif + +// Draw channels are used by the Columns API to "split" the render list into different channels while building, so items of each column can be batched together. +// You can also use them to simulate drawing layers and submit primitives in a different order than how they will be rendered. +struct ImDrawChannel +{ + ImVector CmdBuffer; + ImVector IdxBuffer; +}; + +// Draw command list +// This is the low-level list of polygons that ImGui functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering. +// At the moment, each ImGui window contains its own ImDrawList but they could potentially be merged in the future. +// If you want to add custom rendering within a window, you can use ImGui::GetWindowDrawList() to access the current draw list and add your own primitives. +// You can interleave normal ImGui:: calls and adding primitives to the current draw list. +// All positions are in screen coordinates (0,0=top-left, 1 pixel per unit). Primitives are always added to the list and not culled (culling is done at render time and at a higher-level by ImGui:: functions). +struct ImDrawList +{ + // This is what you have to render + ImVector CmdBuffer; // Commands. Typically 1 command = 1 gpu draw call. + ImVector IdxBuffer; // Index buffer. Each command consume ImDrawCmd::ElemCount of those + ImVector VtxBuffer; // Vertex buffer. + + // [Internal, used while building lists] + const char* _OwnerName; // Pointer to owner window's name (if any) for debugging + unsigned int _VtxCurrentIdx; // [Internal] == VtxBuffer.Size + ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) + ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) + ImVector _ClipRectStack; // [Internal] + ImVector _TextureIdStack; // [Internal] + ImVector _Path; // [Internal] current path building + int _ChannelsCurrent; // [Internal] current channel number (0) + int _ChannelsCount; // [Internal] number of active channels (1+) + ImVector _Channels; // [Internal] draw channels for columns API (not resized down so _ChannelsCount may be smaller than _Channels.Size) + + ImDrawList() { _OwnerName = NULL; Clear(); } + ~ImDrawList() { ClearFreeMemory(); } + IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) + IMGUI_API void PushClipRectFullScreen(); + IMGUI_API void PopClipRect(); + IMGUI_API void PushTextureID(const ImTextureID& texture_id); + IMGUI_API void PopTextureID(); + + // Primitives + IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F, float thickness = 1.0f); // a: upper-left, b: lower-right + IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F); // a: upper-left, b: lower-right + IMGUI_API void AddRectFilledMultiColor(const ImVec2& a, const ImVec2& b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left); + IMGUI_API void AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col); + IMGUI_API void AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); + IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12, float thickness = 1.0f); + IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); + IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); + IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); + IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), ImU32 col = 0xFFFFFFFF); + IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness, bool anti_aliased); + IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col, bool anti_aliased); + IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); + + // Stateful path API, add points then finish with PathFill() or PathStroke() + inline void PathClear() { _Path.resize(0); } + inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } + inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); } + inline void PathFill(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col, true); PathClear(); } + inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness, true); PathClear(); } + IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10); + IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle + IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0); + IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, int rounding_corners = 0x0F); + + // Channels + // - Use to simulate layers. By switching channels to can render out-of-order (e.g. submit foreground primitives before background primitives) + // - Use to minimize draw calls (e.g. if going back-and-forth between multiple non-overlapping clipping rectangles, prefer to append into separate channels then merge at the end) + IMGUI_API void ChannelsSplit(int channels_count); + IMGUI_API void ChannelsMerge(); + IMGUI_API void ChannelsSetCurrent(int channel_index); + + // Advanced + IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles. + IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible + + // Internal helpers + // NB: all primitives needs to be reserved via PrimReserve() beforehand! + IMGUI_API void Clear(); + IMGUI_API void ClearFreeMemory(); + IMGUI_API void PrimReserve(int idx_count, int vtx_count); + IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); // Axis aligned rectangle (composed of two triangles) + IMGUI_API void PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col); + IMGUI_API void PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col); + inline void PrimWriteVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col){ _VtxWritePtr->pos = pos; _VtxWritePtr->uv = uv; _VtxWritePtr->col = col; _VtxWritePtr++; _VtxCurrentIdx++; } + inline void PrimWriteIdx(ImDrawIdx idx) { *_IdxWritePtr = idx; _IdxWritePtr++; } + inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); } + IMGUI_API void UpdateClipRect(); + IMGUI_API void UpdateTextureID(); +}; + +// All draw data to render an ImGui frame +struct ImDrawData +{ + bool Valid; // Only valid after Render() is called and before the next NewFrame() is called. + ImDrawList** CmdLists; + int CmdListsCount; + int TotalVtxCount; // For convenience, sum of all cmd_lists vtx_buffer.Size + int TotalIdxCount; // For convenience, sum of all cmd_lists idx_buffer.Size + + // Functions + ImDrawData() { Valid = false; CmdLists = NULL; CmdListsCount = TotalVtxCount = TotalIdxCount = 0; } + IMGUI_API void DeIndexAllBuffers(); // For backward compatibility: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering! + IMGUI_API void ScaleClipRects(const ImVec2& sc); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than ImGui expects, or if there is a difference between your window resolution and framebuffer resolution. +}; + +struct ImFontConfig +{ + void* FontData; // // TTF data + int FontDataSize; // // TTF data size + bool FontDataOwnedByAtlas; // true // TTF data ownership taken by the container ImFontAtlas (will delete memory itself). Set to true + int FontNo; // 0 // Index of font within TTF file + float SizePixels; // // Size in pixels for rasterizer + int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis. + bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. + ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs + const ImWchar* GlyphRanges; // // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. + bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). + bool MergeGlyphCenterV; // false // When merging (multiple ImFontInput for one ImFont), vertically center new glyphs instead of aligning their baseline + + // [Internal] + char Name[32]; // Name (strictly for debugging) + ImFont* DstFont; + + IMGUI_API ImFontConfig(); +}; + +// Load and rasterize multiple TTF fonts into a same texture. +// Sharing a texture for multiple fonts allows us to reduce the number of draw calls during rendering. +// We also add custom graphic data into the texture that serves for ImGui. +// 1. (Optional) Call AddFont*** functions. If you don't call any, the default font will be loaded for you. +// 2. Call GetTexDataAsAlpha8() or GetTexDataAsRGBA32() to build and retrieve pixels data. +// 3. Upload the pixels data into a texture within your graphics system. +// 4. Call SetTexID(my_tex_id); and pass the pointer/identifier to your texture. This value will be passed back to you during rendering to identify the texture. +// 5. Call ClearTexData() to free textures memory on the heap. +// NB: If you use a 'glyph_ranges' array you need to make sure that your array persist up until the ImFont is cleared. We only copy the pointer, not the data. +struct ImFontAtlas +{ + IMGUI_API ImFontAtlas(); + IMGUI_API ~ImFontAtlas(); + IMGUI_API ImFont* AddFont(const ImFontConfig* font_cfg); + IMGUI_API ImFont* AddFontDefault(const ImFontConfig* font_cfg = NULL); + IMGUI_API ImFont* AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); + IMGUI_API ImFont* AddFontFromMemoryTTF(void* ttf_data, int ttf_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // Transfer ownership of 'ttf_data' to ImFontAtlas, will be deleted after Build() + IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_ttf_data, int compressed_ttf_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_ttf_data' still owned by caller. Compress with binary_to_compressed_c.cpp + IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_ttf_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 paramaeter + IMGUI_API void ClearTexData(); // Clear the CPU-side texture data. Saves RAM once the texture has been copied to graphics memory. + IMGUI_API void ClearInputData(); // Clear the input TTF data (inc sizes, glyph ranges) + IMGUI_API void ClearFonts(); // Clear the ImGui-side font data (glyphs storage, UV coordinates) + IMGUI_API void Clear(); // Clear all + + // Retrieve texture data + // User is in charge of copying the pixels into graphics memory, then call SetTextureUserID() + // After loading the texture into your graphic system, store your texture handle in 'TexID' (ignore if you aren't using multiple fonts nor images) + // RGBA32 format is provided for convenience and high compatibility, but note that all RGB pixels are white, so 75% of the memory is wasted. + // Pitch = Width * BytesPerPixels + IMGUI_API void GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 1 byte per-pixel + IMGUI_API void GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 4 bytes-per-pixel + void SetTexID(void* id) { TexID = id; } + + // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list) + // NB: Make sure that your string are UTF-8 and NOT in your local code page. See FAQ for details. + IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin + IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters + IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs + IMGUI_API const ImWchar* GetGlyphRangesChinese(); // Japanese + full set of about 21000 CJK Unified Ideographs + IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters + IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters + + // Members + // (Access texture data via GetTexData*() calls which will setup a default font for you.) + void* TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It ia passed back to you during rendering. + unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight + unsigned int* TexPixelsRGBA32; // 4 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight * 4 + int TexWidth; // Texture width calculated during Build(). + int TexHeight; // Texture height calculated during Build(). + int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. + ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel + ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. + + // Private + ImVector ConfigData; // Internal data + IMGUI_API bool Build(); // Build pixels data. This is automatically for you by the GetTexData*** functions. + IMGUI_API void RenderCustomTexData(int pass, void* rects); +}; + +// Font runtime data and rendering +// ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32(). +struct ImFont +{ + struct Glyph + { + ImWchar Codepoint; + float XAdvance; + float X0, Y0, X1, Y1; + float U0, V0, U1, V1; // Texture coordinates + }; + + // Members: Hot ~62/78 bytes + float FontSize; // // Height of characters, set during loading (don't change after loading) + float Scale; // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale() + ImVec2 DisplayOffset; // = (0.f,1.f) // Offset font rendering by xx pixels + ImVector Glyphs; // // All glyphs. + ImVector IndexXAdvance; // // Sparse. Glyphs->XAdvance in a directly indexable way (more cache-friendly, for CalcTextSize functions which are often bottleneck in large UI). + ImVector IndexLookup; // // Sparse. Index glyphs by Unicode code-point. + const Glyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) + float FallbackXAdvance; // == FallbackGlyph->XAdvance + ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar() + + // Members: Cold ~18/26 bytes + short ConfigDataCount; // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont. + ImFontConfig* ConfigData; // // Pointer within ContainerAtlas->ConfigData + ImFontAtlas* ContainerAtlas; // // What we has been loaded into + float Ascent, Descent; // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] + + // Methods + IMGUI_API ImFont(); + IMGUI_API ~ImFont(); + IMGUI_API void Clear(); + IMGUI_API void BuildLookupTable(); + IMGUI_API const Glyph* FindGlyph(ImWchar c) const; + IMGUI_API void SetFallbackChar(ImWchar c); + float GetCharAdvance(ImWchar c) const { return ((int)c < IndexXAdvance.Size) ? IndexXAdvance[(int)c] : FallbackXAdvance; } + bool IsLoaded() const { return ContainerAtlas != NULL; } + + // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. + // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. + IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 + IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; + IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const; + IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const; + + // Private + IMGUI_API void GrowIndex(int new_size); + IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built. +}; + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + +//---- Include imgui_user.h at the end of imgui.h +//---- So you can include code that extends ImGui using any of the types declared above. +//---- (also convenient for user to only explicitly include vanilla imgui.h) +#ifdef IMGUI_INCLUDE_IMGUI_USER_H +#include "imgui_user.h" +#endif diff --git a/CameraParameterEstimation/apps/basics/extern/imgui/imgui_demo.cpp b/CameraParameterEstimation/apps/basics/extern/imgui/imgui_demo.cpp new file mode 100644 index 0000000..0d9dbbc --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/imgui/imgui_demo.cpp @@ -0,0 +1,2566 @@ +// dear imgui, v1.50 WIP +// (demo code) + +// Don't remove this file from your project! It is useful reference code that you can execute. +// You can call ImGui::ShowTestWindow() in your code to learn about various features of ImGui. +// Everything in this file will be stripped out by the linker if you don't call ImGui::ShowTestWindow(). + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "imgui.h" +#include // toupper, isprint +#include // sqrtf, powf, cosf, sinf, floorf, ceilf +#include // vsnprintf, sscanf, printf +#include // NULL, malloc, free, qsort, atoi +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen +#define snprintf _snprintf +#endif +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning : 'xx' is deprecated: The POSIX name for this item.. // for strdup used in demo code (so user can copy & paste the code) +#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int' +#pragma clang diagnostic ignored "-Wformat-security" // warning : warning: format string is not a string literal +#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. +#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier // +#elif defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size +#pragma GCC diagnostic ignored "-Wformat-security" // warning : format string is not a string literal (potentially insecure) +#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value +#endif + +// Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n. +#ifdef _WIN32 +#define IM_NEWLINE "\r\n" +#else +#define IM_NEWLINE "\n" +#endif + +#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) +#define IM_MAX(_A,_B) (((_A) >= (_B)) ? (_A) : (_B)) + +//----------------------------------------------------------------------------- +// DEMO CODE +//----------------------------------------------------------------------------- + +#ifndef IMGUI_DISABLE_TEST_WINDOWS + +static void ShowExampleAppConsole(bool* p_open); +static void ShowExampleAppLog(bool* p_open); +static void ShowExampleAppLayout(bool* p_open); +static void ShowExampleAppPropertyEditor(bool* p_open); +static void ShowExampleAppLongText(bool* p_open); +static void ShowExampleAppAutoResize(bool* p_open); +static void ShowExampleAppConstrainedResize(bool* p_open); +static void ShowExampleAppFixedOverlay(bool* p_open); +static void ShowExampleAppManipulatingWindowTitle(bool* p_open); +static void ShowExampleAppCustomRendering(bool* p_open); +static void ShowExampleAppMainMenuBar(); +static void ShowExampleMenuFile(); + +static void ShowHelpMarker(const char* desc) +{ + ImGui::TextDisabled("(?)"); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip(desc); +} + +void ImGui::ShowUserGuide() +{ + ImGui::BulletText("Double-click on title bar to collapse window."); + ImGui::BulletText("Click and drag on lower right corner to resize window."); + ImGui::BulletText("Click and drag on any empty space to move window."); + ImGui::BulletText("Mouse Wheel to scroll."); + if (ImGui::GetIO().FontAllowUserScaling) + ImGui::BulletText("CTRL+Mouse Wheel to zoom window contents."); + ImGui::BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields."); + ImGui::BulletText("CTRL+Click on a slider or drag box to input text."); + ImGui::BulletText( + "While editing text:\n" + "- Hold SHIFT or use mouse to select text\n" + "- CTRL+Left/Right to word jump\n" + "- CTRL+A or double-click to select all\n" + "- CTRL+X,CTRL+C,CTRL+V clipboard\n" + "- CTRL+Z,CTRL+Y undo/redo\n" + "- ESCAPE to revert\n" + "- You can apply arithmetic operators +,*,/ on numerical values.\n" + " Use +- to subtract.\n"); +} + +// Demonstrate most ImGui features (big function!) +void ImGui::ShowTestWindow(bool* p_open) +{ + // Examples apps + static bool show_app_main_menu_bar = false; + static bool show_app_console = false; + static bool show_app_log = false; + static bool show_app_layout = false; + static bool show_app_property_editor = false; + static bool show_app_long_text = false; + static bool show_app_auto_resize = false; + static bool show_app_constrained_resize = false; + static bool show_app_fixed_overlay = false; + static bool show_app_manipulating_window_title = false; + static bool show_app_custom_rendering = false; + static bool show_app_style_editor = false; + + static bool show_app_metrics = false; + static bool show_app_about = false; + + if (show_app_main_menu_bar) ShowExampleAppMainMenuBar(); + if (show_app_console) ShowExampleAppConsole(&show_app_console); + if (show_app_log) ShowExampleAppLog(&show_app_log); + if (show_app_layout) ShowExampleAppLayout(&show_app_layout); + if (show_app_property_editor) ShowExampleAppPropertyEditor(&show_app_property_editor); + if (show_app_long_text) ShowExampleAppLongText(&show_app_long_text); + if (show_app_auto_resize) ShowExampleAppAutoResize(&show_app_auto_resize); + if (show_app_constrained_resize) ShowExampleAppConstrainedResize(&show_app_constrained_resize); + if (show_app_fixed_overlay) ShowExampleAppFixedOverlay(&show_app_fixed_overlay); + if (show_app_manipulating_window_title) ShowExampleAppManipulatingWindowTitle(&show_app_manipulating_window_title); + if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering); + + if (show_app_metrics) ImGui::ShowMetricsWindow(&show_app_metrics); + if (show_app_style_editor) { ImGui::Begin("Style Editor", &show_app_style_editor); ImGui::ShowStyleEditor(); ImGui::End(); } + if (show_app_about) + { + ImGui::Begin("About ImGui", &show_app_about, ImGuiWindowFlags_AlwaysAutoResize); + ImGui::Text("dear imgui, %s", ImGui::GetVersion()); + ImGui::Separator(); + ImGui::Text("By Omar Cornut and all github contributors."); + ImGui::Text("ImGui is licensed under the MIT License, see LICENSE for more information."); + ImGui::End(); + } + + static bool no_titlebar = false; + static bool no_border = true; + static bool no_resize = false; + static bool no_move = false; + static bool no_scrollbar = false; + static bool no_collapse = false; + static bool no_menu = false; + + // Demonstrate the various window flags. Typically you would just use the default. + ImGuiWindowFlags window_flags = 0; + if (no_titlebar) window_flags |= ImGuiWindowFlags_NoTitleBar; + if (!no_border) window_flags |= ImGuiWindowFlags_ShowBorders; + if (no_resize) window_flags |= ImGuiWindowFlags_NoResize; + if (no_move) window_flags |= ImGuiWindowFlags_NoMove; + if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar; + if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; + if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar; + ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiSetCond_FirstUseEver); + if (!ImGui::Begin("ImGui Demo", p_open, window_flags)) + { + // Early out if the window is collapsed, as an optimization. + ImGui::End(); + return; + } + + //ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f); // 2/3 of the space for widget and 1/3 for labels + ImGui::PushItemWidth(-140); // Right align, keep 140 pixels for labels + + ImGui::Text("Dear ImGui says hello."); + + // Menu + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("Menu")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Examples")) + { + ImGui::MenuItem("Main menu bar", NULL, &show_app_main_menu_bar); + ImGui::MenuItem("Console", NULL, &show_app_console); + ImGui::MenuItem("Log", NULL, &show_app_log); + ImGui::MenuItem("Simple layout", NULL, &show_app_layout); + ImGui::MenuItem("Property editor", NULL, &show_app_property_editor); + ImGui::MenuItem("Long text display", NULL, &show_app_long_text); + ImGui::MenuItem("Auto-resizing window", NULL, &show_app_auto_resize); + ImGui::MenuItem("Constrained-resizing window", NULL, &show_app_constrained_resize); + ImGui::MenuItem("Simple overlay", NULL, &show_app_fixed_overlay); + ImGui::MenuItem("Manipulating window title", NULL, &show_app_manipulating_window_title); + ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Help")) + { + ImGui::MenuItem("Metrics", NULL, &show_app_metrics); + ImGui::MenuItem("Style Editor", NULL, &show_app_style_editor); + ImGui::MenuItem("About ImGui", NULL, &show_app_about); + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + + ImGui::Spacing(); + if (ImGui::CollapsingHeader("Help")) + { + ImGui::TextWrapped("This window is being created by the ShowTestWindow() function. Please refer to the code for programming reference.\n\nUser Guide:"); + ImGui::ShowUserGuide(); + } + + if (ImGui::CollapsingHeader("Window options")) + { + ImGui::Checkbox("No titlebar", &no_titlebar); ImGui::SameLine(150); + ImGui::Checkbox("No border", &no_border); ImGui::SameLine(300); + ImGui::Checkbox("No resize", &no_resize); + ImGui::Checkbox("No move", &no_move); ImGui::SameLine(150); + ImGui::Checkbox("No scrollbar", &no_scrollbar); ImGui::SameLine(300); + ImGui::Checkbox("No collapse", &no_collapse); + ImGui::Checkbox("No menu", &no_menu); + + if (ImGui::TreeNode("Style")) + { + ImGui::ShowStyleEditor(); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Logging")) + { + ImGui::TextWrapped("The logging API redirects all text output so you can easily capture the content of a window or a block. Tree nodes can be automatically expanded. You can also call ImGui::LogText() to output directly to the log without a visual output."); + ImGui::LogButtons(); + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Widgets")) + { + if (ImGui::TreeNode("Trees")) + { + if (ImGui::TreeNode("Basic trees")) + { + for (int i = 0; i < 5; i++) + if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", i)) + { + ImGui::Text("blah blah"); + ImGui::SameLine(); + if (ImGui::SmallButton("print")) printf("Child %d pressed", i); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Advanced, with Selectable nodes")) + { + ShowHelpMarker("This is a more standard looking tree with selectable nodes.\nClick to select, CTRL+Click to toggle, click on arrows or double-click to open."); + static bool align_label_with_current_x_position = false; + ImGui::Checkbox("Align label with current X position)", &align_label_with_current_x_position); + ImGui::Text("Hello!"); + if (align_label_with_current_x_position) + ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing()); + + static int selection_mask = (1 << 2); // Dumb representation of what may be user-side selection state. You may carry selection state inside or outside your objects in whatever format you see fit. + int node_clicked = -1; // Temporary storage of what node we have clicked to process selection at the end of the loop. May be a pointer to your own node type, etc. + ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, ImGui::GetFontSize()*3); // Increase spacing to differentiate leaves from expanded contents. + for (int i = 0; i < 6; i++) + { + // Disable the default open on single-click behavior and pass in Selected flag according to our selection state. + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ((selection_mask & (1 << i)) ? ImGuiTreeNodeFlags_Selected : 0); + if (i < 3) + { + // Node + bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", i); + if (ImGui::IsItemClicked()) + node_clicked = i; + if (node_open) + { + ImGui::Text("Blah blah\nBlah Blah"); + ImGui::TreePop(); + } + } + else + { + // Leaf: The only reason we have a TreeNode at all is to allow selection of the leaf. Otherwise we can use BulletText() or TreeAdvanceToLabelPos()+Text(). + ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen, "Selectable Leaf %d", i); + if (ImGui::IsItemClicked()) + node_clicked = i; + } + } + if (node_clicked != -1) + { + // Update selection state. Process outside of tree loop to avoid visual inconsistencies during the clicking-frame. + if (ImGui::GetIO().KeyCtrl) + selection_mask ^= (1 << node_clicked); // CTRL+click to toggle + else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, this commented bit preserve selection when clicking on item that is part of the selection + selection_mask = (1 << node_clicked); // Click to single-select + } + ImGui::PopStyleVar(); + if (align_label_with_current_x_position) + ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing()); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Collapsing Headers")) + { + static bool closable_group = true; + if (ImGui::CollapsingHeader("Header")) + { + ImGui::Checkbox("Enable extra group", &closable_group); + for (int i = 0; i < 5; i++) + ImGui::Text("Some content %d", i); + } + if (ImGui::CollapsingHeader("Header with a close button", &closable_group)) + { + for (int i = 0; i < 5; i++) + ImGui::Text("More content %d", i); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Bullets")) + { + ImGui::BulletText("Bullet point 1"); + ImGui::BulletText("Bullet point 2\nOn multiple lines"); + ImGui::Bullet(); ImGui::Text("Bullet point 3 (two calls)"); + ImGui::Bullet(); ImGui::SmallButton("Button"); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Colored Text")) + { + // Using shortcut. You can use PushStyleColor()/PopStyleColor() for more flexibility. + ImGui::TextColored(ImVec4(1.0f,0.0f,1.0f,1.0f), "Pink"); + ImGui::TextColored(ImVec4(1.0f,1.0f,0.0f,1.0f), "Yellow"); + ImGui::TextDisabled("Disabled"); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Word Wrapping")) + { + // Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility. + ImGui::TextWrapped("This text should automatically wrap on the edge of the window. The current implementation for text wrapping follows simple rules suitable for English and possibly other languages."); + ImGui::Spacing(); + + static float wrap_width = 200.0f; + ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f"); + + ImGui::Text("Test paragraph 1:"); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), 0xFFFF00FF); + ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); + ImGui::Text("lazy dog. This paragraph is made to fit within %.0f pixels. The quick brown fox jumps over the lazy dog.", wrap_width); + ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), 0xFF00FFFF); + ImGui::PopTextWrapPos(); + + ImGui::Text("Test paragraph 2:"); + pos = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), 0xFFFF00FF); + ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); + ImGui::Text("aaaaaaaa bbbbbbbb, cccccccc,dddddddd. eeeeeeee ffffffff. gggggggg!hhhhhhhh"); + ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), 0xFF00FFFF); + ImGui::PopTextWrapPos(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("UTF-8 Text")) + { + // UTF-8 test with Japanese characters + // (needs a suitable font, try Arial Unicode or M+ fonts http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html) + // Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature') + // However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants. + // In your own application be reasonable and use UTF-8 in source or retrieve the data from file system! + // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application. + ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges."); + ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); + ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)"); + static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"; + ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf)); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Images")) + { + ImGui::TextWrapped("Below we are displaying the font texture (which is the only texture we have access to in this demo). Use the 'ImTextureID' type as storage to pass pointers or identifier to your own texture data. Hover the texture for a zoomed view!"); + ImVec2 tex_screen_pos = ImGui::GetCursorScreenPos(); + float tex_w = (float)ImGui::GetIO().Fonts->TexWidth; + float tex_h = (float)ImGui::GetIO().Fonts->TexHeight; + ImTextureID tex_id = ImGui::GetIO().Fonts->TexID; + ImGui::Text("%.0fx%.0f", tex_w, tex_h); + ImGui::Image(tex_id, ImVec2(tex_w, tex_h), ImVec2(0,0), ImVec2(1,1), ImColor(255,255,255,255), ImColor(255,255,255,128)); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + float focus_sz = 32.0f; + float focus_x = ImGui::GetMousePos().x - tex_screen_pos.x - focus_sz * 0.5f; if (focus_x < 0.0f) focus_x = 0.0f; else if (focus_x > tex_w - focus_sz) focus_x = tex_w - focus_sz; + float focus_y = ImGui::GetMousePos().y - tex_screen_pos.y - focus_sz * 0.5f; if (focus_y < 0.0f) focus_y = 0.0f; else if (focus_y > tex_h - focus_sz) focus_y = tex_h - focus_sz; + ImGui::Text("Min: (%.2f, %.2f)", focus_x, focus_y); + ImGui::Text("Max: (%.2f, %.2f)", focus_x + focus_sz, focus_y + focus_sz); + ImVec2 uv0 = ImVec2((focus_x) / tex_w, (focus_y) / tex_h); + ImVec2 uv1 = ImVec2((focus_x + focus_sz) / tex_w, (focus_y + focus_sz) / tex_h); + ImGui::Image(tex_id, ImVec2(128,128), uv0, uv1, ImColor(255,255,255,255), ImColor(255,255,255,128)); + ImGui::EndTooltip(); + } + ImGui::TextWrapped("And now some textured buttons.."); + static int pressed_count = 0; + for (int i = 0; i < 8; i++) + { + ImGui::PushID(i); + int frame_padding = -1 + i; // -1 = uses default padding + if (ImGui::ImageButton(tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/tex_w,32/tex_h), frame_padding, ImColor(0,0,0,255))) + pressed_count += 1; + ImGui::PopID(); + ImGui::SameLine(); + } + ImGui::NewLine(); + ImGui::Text("Pressed %d times.", pressed_count); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Selectables")) + { + if (ImGui::TreeNode("Basic")) + { + static bool selected[4] = { false, true, false, false }; + ImGui::Selectable("1. I am selectable", &selected[0]); + ImGui::Selectable("2. I am selectable", &selected[1]); + ImGui::Text("3. I am not selectable"); + ImGui::Selectable("4. I am selectable", &selected[2]); + if (ImGui::Selectable("5. I am double clickable", selected[3], ImGuiSelectableFlags_AllowDoubleClick)) + if (ImGui::IsMouseDoubleClicked(0)) + selected[3] = !selected[3]; + ImGui::TreePop(); + } + if (ImGui::TreeNode("Rendering more text into the same block")) + { + static bool selected[3] = { false, false, false }; + ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); + ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(300); ImGui::Text("12,345 bytes"); + ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); + ImGui::TreePop(); + } + if (ImGui::TreeNode("In columns")) + { + ImGui::Columns(3, NULL, false); + static bool selected[16] = { 0 }; + for (int i = 0; i < 16; i++) + { + char label[32]; sprintf(label, "Item %d", i); + if (ImGui::Selectable(label, &selected[i])) {} + ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::TreePop(); + } + if (ImGui::TreeNode("Grid")) + { + static bool selected[16] = { true, false, false, false, false, true, false, false, false, false, true, false, false, false, false, true }; + for (int i = 0; i < 16; i++) + { + ImGui::PushID(i); + if (ImGui::Selectable("Sailor", &selected[i], 0, ImVec2(50,50))) + { + int x = i % 4, y = i / 4; + if (x > 0) selected[i - 1] ^= 1; + if (x < 3) selected[i + 1] ^= 1; + if (y > 0) selected[i - 4] ^= 1; + if (y < 3) selected[i + 4] ^= 1; + } + if ((i % 4) < 3) ImGui::SameLine(); + ImGui::PopID(); + } + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Filtered Text Input")) + { + static char buf1[64] = ""; ImGui::InputText("default", buf1, 64); + static char buf2[64] = ""; ImGui::InputText("decimal", buf2, 64, ImGuiInputTextFlags_CharsDecimal); + static char buf3[64] = ""; ImGui::InputText("hexadecimal", buf3, 64, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase); + static char buf4[64] = ""; ImGui::InputText("uppercase", buf4, 64, ImGuiInputTextFlags_CharsUppercase); + static char buf5[64] = ""; ImGui::InputText("no blank", buf5, 64, ImGuiInputTextFlags_CharsNoBlank); + struct TextFilters { static int FilterImGuiLetters(ImGuiTextEditCallbackData* data) { if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) return 0; return 1; } }; + static char buf6[64] = ""; ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); + + ImGui::Text("Password input"); + static char bufpass[64] = "password123"; + ImGui::InputText("password", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); + ImGui::SameLine(); ShowHelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); + ImGui::InputText("password (clear)", bufpass, 64, ImGuiInputTextFlags_CharsNoBlank); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Multi-line Text Input")) + { + static bool read_only = false; + static char text[1024*16] = + "/*\n" + " The Pentium F00F bug, shorthand for F0 0F C7 C8,\n" + " the hexadecimal encoding of one offending instruction,\n" + " more formally, the invalid operand with locked CMPXCHG8B\n" + " instruction bug, is a design flaw in the majority of\n" + " Intel Pentium, Pentium MMX, and Pentium OverDrive\n" + " processors (all in the P5 microarchitecture).\n" + "*/\n\n" + "label:\n" + "\tlock cmpxchg8b eax\n"; + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); + ImGui::Checkbox("Read-only", &read_only); + ImGui::PopStyleVar(); + ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-1.0f, ImGui::GetTextLineHeight() * 16), ImGuiInputTextFlags_AllowTabInput | (read_only ? ImGuiInputTextFlags_ReadOnly : 0)); + ImGui::TreePop(); + } + + static bool a=false; + if (ImGui::Button("Button")) { printf("Clicked\n"); a ^= 1; } + if (a) + { + ImGui::SameLine(); + ImGui::Text("Thanks for clicking me!"); + } + + static bool check = true; + ImGui::Checkbox("checkbox", &check); + + static int e = 0; + ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine(); + ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine(); + ImGui::RadioButton("radio c", &e, 2); + + // Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style. + for (int i = 0; i < 7; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleColor(ImGuiCol_Button, ImColor::HSV(i/7.0f, 0.6f, 0.6f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImColor::HSV(i/7.0f, 0.7f, 0.7f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImColor::HSV(i/7.0f, 0.8f, 0.8f)); + ImGui::Button("Click"); + ImGui::PopStyleColor(3); + ImGui::PopID(); + } + + ImGui::Text("Hover over me"); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("I am a tooltip"); + + ImGui::SameLine(); + ImGui::Text("- or me"); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text("I am a fancy tooltip"); + static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; + ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr)); + ImGui::EndTooltip(); + } + + // Testing IMGUI_ONCE_UPON_A_FRAME macro + //for (int i = 0; i < 5; i++) + //{ + // IMGUI_ONCE_UPON_A_FRAME + // { + // ImGui::Text("This will be displayed only once."); + // } + //} + + ImGui::Separator(); + + ImGui::LabelText("label", "Value"); + + static int item = 1; + ImGui::Combo("combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); // Combo using values packed in a single constant string (for really quick combo) + + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK" }; + static int item2 = -1; + ImGui::Combo("combo scroll", &item2, items, IM_ARRAYSIZE(items)); // Combo using proper array. You can also pass a callback to retrieve array value, no need to create/copy an array just for that. + + { + static char str0[128] = "Hello, world!"; + static int i0=123; + static float f0=0.001f; + ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); + ImGui::SameLine(); ShowHelpMarker("Hold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n"); + + ImGui::InputInt("input int", &i0); + ImGui::SameLine(); ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n"); + + ImGui::InputFloat("input float", &f0, 0.01f, 1.0f); + + static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; + ImGui::InputFloat3("input float3", vec4a); + } + + { + static int i1=50, i2=42; + ImGui::DragInt("drag int", &i1, 1); + ImGui::SameLine(); ShowHelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input value."); + + ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%"); + + static float f1=1.00f, f2=0.0067f; + ImGui::DragFloat("drag float", &f1, 0.005f); + ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns"); + } + + { + static int i1=0; + ImGui::SliderInt("slider int", &i1, -1, 3); + ImGui::SameLine(); ShowHelpMarker("CTRL+click to input value."); + + static float f1=0.123f, f2=0.0f; + ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); + ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f); + static float angle = 0.0f; + ImGui::SliderAngle("slider angle", &angle); + } + + static float col1[3] = { 1.0f,0.0f,0.2f }; + static float col2[4] = { 0.4f,0.7f,0.0f,0.5f }; + ImGui::ColorEdit3("color 1", col1); + ImGui::SameLine(); ShowHelpMarker("Click on the colored square to change edit mode.\nCTRL+click on individual component to input value.\n"); + + ImGui::ColorEdit4("color 2", col2); + + const char* listbox_items[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon" }; + static int listbox_item_current = 1; + ImGui::ListBox("listbox\n(single select)", &listbox_item_current, listbox_items, IM_ARRAYSIZE(listbox_items), 4); + + //static int listbox_item_current2 = 2; + //ImGui::PushItemWidth(-1); + //ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4); + //ImGui::PopItemWidth(); + + if (ImGui::TreeNode("Range Widgets")) + { + ImGui::Unindent(); + + static float begin = 10, end = 90; + static int begin_i = 100, end_i = 1000; + ImGui::DragFloatRange2("range", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%"); + ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %.0f units", "Max: %.0f units"); + + ImGui::Indent(); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Multi-component Widgets")) + { + ImGui::Unindent(); + + static float vec4f[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; + static int vec4i[4] = { 1, 5, 100, 255 }; + + ImGui::InputFloat2("input float2", vec4f); + ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f); + ImGui::DragInt2("drag int2", vec4i, 1, 0, 255); + ImGui::InputInt2("input int2", vec4i); + ImGui::SliderInt2("slider int2", vec4i, 0, 255); + ImGui::Spacing(); + + ImGui::InputFloat3("input float3", vec4f); + ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f); + ImGui::DragInt3("drag int3", vec4i, 1, 0, 255); + ImGui::InputInt3("input int3", vec4i); + ImGui::SliderInt3("slider int3", vec4i, 0, 255); + ImGui::Spacing(); + + ImGui::InputFloat4("input float4", vec4f); + ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f); + ImGui::InputInt4("input int4", vec4i); + ImGui::DragInt4("drag int4", vec4i, 1, 0, 255); + ImGui::SliderInt4("slider int4", vec4i, 0, 255); + + ImGui::Indent(); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Vertical Sliders")) + { + ImGui::Unindent(); + const float spacing = 4; + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing, spacing)); + + static int int_value = 0; + ImGui::VSliderInt("##int", ImVec2(18,160), &int_value, 0, 5); + ImGui::SameLine(); + + static float values[7] = { 0.0f, 0.60f, 0.35f, 0.9f, 0.70f, 0.20f, 0.0f }; + ImGui::PushID("set1"); + for (int i = 0; i < 7; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleColor(ImGuiCol_FrameBg, ImColor::HSV(i/7.0f, 0.5f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImColor::HSV(i/7.0f, 0.6f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImColor::HSV(i/7.0f, 0.7f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImColor::HSV(i/7.0f, 0.9f, 0.9f)); + ImGui::VSliderFloat("##v", ImVec2(18,160), &values[i], 0.0f, 1.0f, ""); + if (ImGui::IsItemActive() || ImGui::IsItemHovered()) + ImGui::SetTooltip("%.3f", values[i]); + ImGui::PopStyleColor(4); + ImGui::PopID(); + } + ImGui::PopID(); + + ImGui::SameLine(); + ImGui::PushID("set2"); + static float values2[4] = { 0.20f, 0.80f, 0.40f, 0.25f }; + const int rows = 3; + const ImVec2 small_slider_size(18, (160.0f-(rows-1)*spacing)/rows); + for (int nx = 0; nx < 4; nx++) + { + if (nx > 0) ImGui::SameLine(); + ImGui::BeginGroup(); + for (int ny = 0; ny < rows; ny++) + { + ImGui::PushID(nx*rows+ny); + ImGui::VSliderFloat("##v", small_slider_size, &values2[nx], 0.0f, 1.0f, ""); + if (ImGui::IsItemActive() || ImGui::IsItemHovered()) + ImGui::SetTooltip("%.3f", values2[nx]); + ImGui::PopID(); + } + ImGui::EndGroup(); + } + ImGui::PopID(); + + ImGui::SameLine(); + ImGui::PushID("set3"); + for (int i = 0; i < 4; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40); + ImGui::VSliderFloat("##v", ImVec2(40,160), &values[i], 0.0f, 1.0f, "%.2f\nsec"); + ImGui::PopStyleVar(); + ImGui::PopID(); + } + ImGui::PopID(); + ImGui::PopStyleVar(); + + ImGui::Indent(); + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Graphs widgets")) + { + static bool animate = true; + ImGui::Checkbox("Animate", &animate); + + static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; + ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); + + // Create a dummy array of contiguous float values to plot + // Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float and the sizeof() of your structure in the Stride parameter. + static float values[90] = { 0 }; + static int values_offset = 0; + if (animate) + { + static float refresh_time = ImGui::GetTime(); // Create dummy data at fixed 60 hz rate for the demo + for (; ImGui::GetTime() > refresh_time + 1.0f/60.0f; refresh_time += 1.0f/60.0f) + { + static float phase = 0.0f; + values[values_offset] = cosf(phase); + values_offset = (values_offset+1) % IM_ARRAYSIZE(values); + phase += 0.10f*values_offset; + } + } + ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80)); + ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,80)); + + // Use functions to generate output + // FIXME: This is rather awkward because current plot API only pass in indices. We probably want an API passing floats and user provide sample rate/count. + struct Funcs + { + static float Sin(void*, int i) { return sinf(i * 0.1f); } + static float Saw(void*, int i) { return (i & 1) ? 1.0f : 0.0f; } + }; + static int func_type = 0, display_count = 70; + ImGui::Separator(); + ImGui::PushItemWidth(100); ImGui::Combo("func", &func_type, "Sin\0Saw\0"); ImGui::PopItemWidth(); + ImGui::SameLine(); + ImGui::SliderInt("Sample count", &display_count, 1, 500); + float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw; + ImGui::PlotLines("Lines", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80)); + ImGui::PlotHistogram("Histogram", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80)); + ImGui::Separator(); + + // Animate a simple progress bar + static float progress = 0.0f, progress_dir = 1.0f; + if (animate) + { + progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime; + if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; } + if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; } + } + + // Typically we would use ImVec2(-1.0f,0.0f) to use all available width, or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth. + ImGui::ProgressBar(progress, ImVec2(0.0f,0.0f)); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::Text("Progress Bar"); + + float progress_saturated = (progress < 0.0f) ? 0.0f : (progress > 1.0f) ? 1.0f : progress; + char buf[32]; + sprintf(buf, "%d/%d", (int)(progress_saturated*1753), 1753); + ImGui::ProgressBar(progress, ImVec2(0.f,0.f), buf); + } + + if (ImGui::CollapsingHeader("Layout")) + { + if (ImGui::TreeNode("Child regions")) + { + ImGui::Text("Without border"); + static int line = 50; + bool goto_line = ImGui::Button("Goto"); + ImGui::SameLine(); + ImGui::PushItemWidth(100); + goto_line |= ImGui::InputInt("##Line", &line, 0, 0, ImGuiInputTextFlags_EnterReturnsTrue); + ImGui::PopItemWidth(); + ImGui::BeginChild("Sub1", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f,300), false, ImGuiWindowFlags_HorizontalScrollbar); + for (int i = 0; i < 100; i++) + { + ImGui::Text("%04d: scrollable region", i); + if (goto_line && line == i) + ImGui::SetScrollHere(); + } + if (goto_line && line >= 100) + ImGui::SetScrollHere(); + ImGui::EndChild(); + + ImGui::SameLine(); + + ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, 5.0f); + ImGui::BeginChild("Sub2", ImVec2(0,300), true); + ImGui::Text("With border"); + ImGui::Columns(2); + for (int i = 0; i < 100; i++) + { + if (i == 50) + ImGui::NextColumn(); + char buf[32]; + sprintf(buf, "%08x", i*5731); + ImGui::Button(buf, ImVec2(-1.0f, 0.0f)); + } + ImGui::EndChild(); + ImGui::PopStyleVar(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Widgets Width")) + { + static float f = 0.0f; + ImGui::Text("PushItemWidth(100)"); + ImGui::SameLine(); ShowHelpMarker("Fixed width."); + ImGui::PushItemWidth(100); + ImGui::DragFloat("float##1", &f); + ImGui::PopItemWidth(); + + ImGui::Text("PushItemWidth(GetWindowWidth() * 0.5f)"); + ImGui::SameLine(); ShowHelpMarker("Half of window width."); + ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f); + ImGui::DragFloat("float##2", &f); + ImGui::PopItemWidth(); + + ImGui::Text("PushItemWidth(GetContentRegionAvailWidth() * 0.5f)"); + ImGui::SameLine(); ShowHelpMarker("Half of available width.\n(~ right-cursor_pos)\n(works within a column set)"); + ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth() * 0.5f); + ImGui::DragFloat("float##3", &f); + ImGui::PopItemWidth(); + + ImGui::Text("PushItemWidth(-100)"); + ImGui::SameLine(); ShowHelpMarker("Align to right edge minus 100"); + ImGui::PushItemWidth(-100); + ImGui::DragFloat("float##4", &f); + ImGui::PopItemWidth(); + + ImGui::Text("PushItemWidth(-1)"); + ImGui::SameLine(); ShowHelpMarker("Align to right edge"); + ImGui::PushItemWidth(-1); + ImGui::DragFloat("float##5", &f); + ImGui::PopItemWidth(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Basic Horizontal Layout")) + { + ImGui::TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceeding item)"); + + // Text + ImGui::Text("Two items: Hello"); ImGui::SameLine(); + ImGui::TextColored(ImVec4(1,1,0,1), "Sailor"); + + // Adjust spacing + ImGui::Text("More spacing: Hello"); ImGui::SameLine(0, 20); + ImGui::TextColored(ImVec4(1,1,0,1), "Sailor"); + + // Button + ImGui::AlignFirstTextHeightToWidgets(); + ImGui::Text("Normal buttons"); ImGui::SameLine(); + ImGui::Button("Banana"); ImGui::SameLine(); + ImGui::Button("Apple"); ImGui::SameLine(); + ImGui::Button("Corniflower"); + + // Button + ImGui::Text("Small buttons"); ImGui::SameLine(); + ImGui::SmallButton("Like this one"); ImGui::SameLine(); + ImGui::Text("can fit within a text block."); + + // Aligned to arbitrary position. Easy/cheap column. + ImGui::Text("Aligned"); + ImGui::SameLine(150); ImGui::Text("x=150"); + ImGui::SameLine(300); ImGui::Text("x=300"); + ImGui::Text("Aligned"); + ImGui::SameLine(150); ImGui::SmallButton("x=150"); + ImGui::SameLine(300); ImGui::SmallButton("x=300"); + + // Checkbox + static bool c1=false,c2=false,c3=false,c4=false; + ImGui::Checkbox("My", &c1); ImGui::SameLine(); + ImGui::Checkbox("Tailor", &c2); ImGui::SameLine(); + ImGui::Checkbox("Is", &c3); ImGui::SameLine(); + ImGui::Checkbox("Rich", &c4); + + // Various + static float f0=1.0f, f1=2.0f, f2=3.0f; + ImGui::PushItemWidth(80); + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD" }; + static int item = -1; + ImGui::Combo("Combo", &item, items, IM_ARRAYSIZE(items)); ImGui::SameLine(); + ImGui::SliderFloat("X", &f0, 0.0f,5.0f); ImGui::SameLine(); + ImGui::SliderFloat("Y", &f1, 0.0f,5.0f); ImGui::SameLine(); + ImGui::SliderFloat("Z", &f2, 0.0f,5.0f); + ImGui::PopItemWidth(); + + ImGui::PushItemWidth(80); + ImGui::Text("Lists:"); + static int selection[4] = { 0, 1, 2, 3 }; + for (int i = 0; i < 4; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::ListBox("", &selection[i], items, IM_ARRAYSIZE(items)); + ImGui::PopID(); + //if (ImGui::IsItemHovered()) ImGui::SetTooltip("ListBox %d hovered", i); + } + ImGui::PopItemWidth(); + + // Dummy + ImVec2 sz(30,30); + ImGui::Button("A", sz); ImGui::SameLine(); + ImGui::Dummy(sz); ImGui::SameLine(); + ImGui::Button("B", sz); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Groups")) + { + ImGui::TextWrapped("(Using ImGui::BeginGroup()/EndGroup() to layout items. BeginGroup() basically locks the horizontal position. EndGroup() bundles the whole group so that you can use functions such as IsItemHovered() on it.)"); + ImGui::BeginGroup(); + { + ImGui::BeginGroup(); + ImGui::Button("AAA"); + ImGui::SameLine(); + ImGui::Button("BBB"); + ImGui::SameLine(); + ImGui::BeginGroup(); + ImGui::Button("CCC"); + ImGui::Button("DDD"); + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Group hovered"); + ImGui::SameLine(); + ImGui::Button("EEE"); + ImGui::EndGroup(); + } + // Capture the group size and create widgets using the same size + ImVec2 size = ImGui::GetItemRectSize(); + const float values[5] = { 0.5f, 0.20f, 0.80f, 0.60f, 0.25f }; + ImGui::PlotHistogram("##values", values, IM_ARRAYSIZE(values), 0, NULL, 0.0f, 1.0f, size); + + ImGui::Button("ACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f,size.y)); + ImGui::SameLine(); + ImGui::Button("REACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f,size.y)); + ImGui::EndGroup(); + ImGui::SameLine(); + + ImGui::Button("LEVERAGE\nBUZZWORD", size); + ImGui::SameLine(); + + ImGui::ListBoxHeader("List", size); + ImGui::Selectable("Selected", true); + ImGui::Selectable("Not Selected", false); + ImGui::ListBoxFooter(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Text Baseline Alignment")) + { + ImGui::TextWrapped("(This is testing the vertical alignment that occurs on text to keep it at the same baseline as widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets)"); + + ImGui::Text("One\nTwo\nThree"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Text("Banana"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("One\nTwo\nThree"); + + ImGui::Button("HOP##1"); ImGui::SameLine(); + ImGui::Text("Banana"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Button("HOP##2"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Button("TEST##1"); ImGui::SameLine(); + ImGui::Text("TEST"); ImGui::SameLine(); + ImGui::SmallButton("TEST##2"); + + ImGui::AlignFirstTextHeightToWidgets(); // If your line starts with text, call this to align it to upcoming widgets. + ImGui::Text("Text aligned to Widget"); ImGui::SameLine(); + ImGui::Button("Widget##1"); ImGui::SameLine(); + ImGui::Text("Widget"); ImGui::SameLine(); + ImGui::SmallButton("Widget##2"); + + // Tree + const float spacing = ImGui::GetStyle().ItemInnerSpacing.x; + ImGui::Button("Button##1"); + ImGui::SameLine(0.0f, spacing); + if (ImGui::TreeNode("Node##1")) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data + + ImGui::AlignFirstTextHeightToWidgets(); // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. Otherwise you can use SmallButton (smaller fit). + bool node_open = ImGui::TreeNode("Node##2"); // Common mistake to avoid: if we want to SameLine after TreeNode we need to do it before we add child content. + ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2"); + if (node_open) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data + + // Bullet + ImGui::Button("Button##3"); + ImGui::SameLine(0.0f, spacing); + ImGui::BulletText("Bullet text"); + + ImGui::AlignFirstTextHeightToWidgets(); + ImGui::BulletText("Node"); + ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##4"); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Scrolling")) + { + ImGui::TextWrapped("(Use SetScrollHere() or SetScrollFromPosY() to scroll to a given position.)"); + static bool track = true; + static int track_line = 50, scroll_to_px = 200; + ImGui::Checkbox("Track", &track); + ImGui::PushItemWidth(100); + ImGui::SameLine(130); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line %.0f"); + bool scroll_to = ImGui::Button("Scroll To"); + ImGui::SameLine(130); scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "y = %.0f px"); + ImGui::PopItemWidth(); + if (scroll_to) track = false; + + for (int i = 0; i < 5; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::BeginGroup(); + ImGui::Text("%s", i == 0 ? "Top" : i == 1 ? "25%" : i == 2 ? "Center" : i == 3 ? "75%" : "Bottom"); + ImGui::BeginChild(ImGui::GetID((void*)(intptr_t)i), ImVec2(ImGui::GetWindowWidth() * 0.17f, 200.0f), true); + if (scroll_to) + ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_px, i * 0.25f); + for (int line = 0; line < 100; line++) + { + if (track && line == track_line) + { + ImGui::TextColored(ImColor(255,255,0), "Line %d", line); + ImGui::SetScrollHere(i * 0.25f); // 0.0f:top, 0.5f:center, 1.0f:bottom + } + else + { + ImGui::Text("Line %d", line); + } + } + ImGui::EndChild(); + ImGui::EndGroup(); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Horizontal Scrolling")) + { + ImGui::Bullet(); ImGui::TextWrapped("Horizontal scrolling for a window has to be enabled explicitly via the ImGuiWindowFlags_HorizontalScrollbar flag."); + ImGui::Bullet(); ImGui::TextWrapped("You may want to explicitly specify content width by calling SetNextWindowContentWidth() before Begin()."); + static int lines = 7; + ImGui::SliderInt("Lines", &lines, 1, 15); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 1.0f)); + ImGui::BeginChild("scrolling", ImVec2(0, ImGui::GetItemsLineHeightWithSpacing()*7 + 30), true, ImGuiWindowFlags_HorizontalScrollbar); + for (int line = 0; line < lines; line++) + { + // Display random stuff + int num_buttons = 10 + ((line & 1) ? line * 9 : line * 3); + for (int n = 0; n < num_buttons; n++) + { + if (n > 0) ImGui::SameLine(); + ImGui::PushID(n + line * 1000); + char num_buf[16]; + const char* label = (!(n%15)) ? "FizzBuzz" : (!(n%3)) ? "Fizz" : (!(n%5)) ? "Buzz" : (sprintf(num_buf, "%d", n), num_buf); + float hue = n*0.05f; + ImGui::PushStyleColor(ImGuiCol_Button, ImColor::HSV(hue, 0.6f, 0.6f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImColor::HSV(hue, 0.7f, 0.7f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImColor::HSV(hue, 0.8f, 0.8f)); + ImGui::Button(label, ImVec2(40.0f + sinf((float)(line + n)) * 20.0f, 0.0f)); + ImGui::PopStyleColor(3); + ImGui::PopID(); + } + } + ImGui::EndChild(); + ImGui::PopStyleVar(2); + float scroll_x_delta = 0.0f; + ImGui::SmallButton("<<"); if (ImGui::IsItemActive()) scroll_x_delta = -ImGui::GetIO().DeltaTime * 1000.0f; + ImGui::SameLine(); ImGui::Text("Scroll from code"); ImGui::SameLine(); + ImGui::SmallButton(">>"); if (ImGui::IsItemActive()) scroll_x_delta = +ImGui::GetIO().DeltaTime * 1000.0f; + if (scroll_x_delta != 0.0f) + { + ImGui::BeginChild("scrolling"); // Demonstrate a trick: you can use Begin to set yourself in the context of another window (here we are already out of your child window) + ImGui::SetScrollX(ImGui::GetScrollX() + scroll_x_delta); + ImGui::End(); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Clipping")) + { + static ImVec2 size(100, 100), offset(50, 20); + ImGui::TextWrapped("On a per-widget basis we are occasionally clipping text CPU-side if it won't fit in its frame. Otherwise we are doing coarser clipping + passing a scissor rectangle to the renderer. The system is designed to try minimizing both execution and CPU/GPU rendering cost."); + ImGui::DragFloat2("size", (float*)&size, 0.5f, 0.0f, 200.0f, "%.0f"); + ImGui::TextWrapped("(Click and drag)"); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImVec4 clip_rect(pos.x, pos.y, pos.x+size.x, pos.y+size.y); + ImGui::InvisibleButton("##dummy", size); + if (ImGui::IsItemActive() && ImGui::IsMouseDragging()) { offset.x += ImGui::GetIO().MouseDelta.x; offset.y += ImGui::GetIO().MouseDelta.y; } + ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x+size.x,pos.y+size.y), ImColor(90,90,120,255)); + ImGui::GetWindowDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize()*2.0f, ImVec2(pos.x+offset.x,pos.y+offset.y), ImColor(255,255,255,255), "Line 1 hello\nLine 2 clip me!", NULL, 0.0f, &clip_rect); + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Popups & Modal windows")) + { + if (ImGui::TreeNode("Popups")) + { + ImGui::TextWrapped("When a popup is active, it inhibits interacting with windows that are behind the popup. Clicking outside the popup closes it."); + + static int selected_fish = -1; + const char* names[] = { "Bream", "Haddock", "Mackerel", "Pollock", "Tilefish" }; + static bool toggles[] = { true, false, false, false, false }; + + if (ImGui::Button("Select..")) + ImGui::OpenPopup("select"); + ImGui::SameLine(); + ImGui::Text(selected_fish == -1 ? "" : names[selected_fish]); + if (ImGui::BeginPopup("select")) + { + ImGui::Text("Aquarium"); + ImGui::Separator(); + for (int i = 0; i < IM_ARRAYSIZE(names); i++) + if (ImGui::Selectable(names[i])) + selected_fish = i; + ImGui::EndPopup(); + } + + if (ImGui::Button("Toggle..")) + ImGui::OpenPopup("toggle"); + if (ImGui::BeginPopup("toggle")) + { + for (int i = 0; i < IM_ARRAYSIZE(names); i++) + ImGui::MenuItem(names[i], "", &toggles[i]); + if (ImGui::BeginMenu("Sub-menu")) + { + ImGui::MenuItem("Click me"); + ImGui::EndMenu(); + } + + ImGui::Separator(); + ImGui::Text("Tooltip here"); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("I am a tooltip over a popup"); + + if (ImGui::Button("Stacked Popup")) + ImGui::OpenPopup("another popup"); + if (ImGui::BeginPopup("another popup")) + { + for (int i = 0; i < IM_ARRAYSIZE(names); i++) + ImGui::MenuItem(names[i], "", &toggles[i]); + if (ImGui::BeginMenu("Sub-menu")) + { + ImGui::MenuItem("Click me"); + ImGui::EndMenu(); + } + ImGui::EndPopup(); + } + ImGui::EndPopup(); + } + + if (ImGui::Button("Popup Menu..")) + ImGui::OpenPopup("popup from button"); + if (ImGui::BeginPopup("popup from button")) + { + ShowExampleMenuFile(); + ImGui::EndPopup(); + } + + ImGui::Spacing(); + ImGui::TextWrapped("Below we are testing adding menu items to a regular window. It's rather unusual but should work!"); + ImGui::Separator(); + // NB: As a quirk in this very specific example, we want to differentiate the parent of this menu from the parent of the various popup menus above. + // To do so we are encloding the items in a PushID()/PopID() block to make them two different menusets. If we don't, opening any popup above and hovering our menu here + // would open it. This is because once a menu is active, we allow to switch to a sibling menu by just hovering on it, which is the desired behavior for regular menus. + ImGui::PushID("foo"); + ImGui::MenuItem("Menu item", "CTRL+M"); + if (ImGui::BeginMenu("Menu inside a regular window")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + ImGui::PopID(); + ImGui::Separator(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Context menus")) + { + static float value = 0.5f; + ImGui::Text("Value = %.3f (<-- right-click here)", value); + if (ImGui::BeginPopupContextItem("item context menu")) + { + if (ImGui::Selectable("Set to zero")) value = 0.0f; + if (ImGui::Selectable("Set to PI")) value = 3.1415f; + ImGui::EndPopup(); + } + + static ImVec4 color = ImColor(0.8f, 0.5f, 1.0f, 1.0f); + ImGui::ColorButton(color); + if (ImGui::BeginPopupContextItem("color context menu")) + { + ImGui::Text("Edit color"); + ImGui::ColorEdit3("##edit", (float*)&color); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + ImGui::SameLine(); ImGui::Text("(<-- right-click here)"); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Modals")) + { + ImGui::TextWrapped("Modal windows are like popups but the user cannot close them by clicking outside the window."); + + if (ImGui::Button("Delete..")) + ImGui::OpenPopup("Delete?"); + if (ImGui::BeginPopupModal("Delete?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n"); + ImGui::Separator(); + + //static int dummy_i = 0; + //ImGui::Combo("Combo", &dummy_i, "Delete\0Delete harder\0"); + + static bool dont_ask_me_next_time = false; + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); + ImGui::Checkbox("Don't ask me next time", &dont_ask_me_next_time); + ImGui::PopStyleVar(); + + if (ImGui::Button("OK", ImVec2(120,0))) { ImGui::CloseCurrentPopup(); } + ImGui::SameLine(); + if (ImGui::Button("Cancel", ImVec2(120,0))) { ImGui::CloseCurrentPopup(); } + ImGui::EndPopup(); + } + + if (ImGui::Button("Stacked modals..")) + ImGui::OpenPopup("Stacked 1"); + if (ImGui::BeginPopupModal("Stacked 1")) + { + ImGui::Text("Hello from Stacked The First"); + + if (ImGui::Button("Another one..")) + ImGui::OpenPopup("Stacked 2"); + if (ImGui::BeginPopupModal("Stacked 2")) + { + ImGui::Text("Hello from Stacked The Second"); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Columns")) + { + // Basic columns + if (ImGui::TreeNode("Basic")) + { + ImGui::Text("Without border:"); + ImGui::Columns(3, "mycolumns3", false); // 3-ways, no border + ImGui::Separator(); + for (int n = 0; n < 14; n++) + { + char label[32]; + sprintf(label, "Item %d", n); + if (ImGui::Selectable(label)) {} + //if (ImGui::Button(label, ImVec2(-1,0))) {} + ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::Separator(); + + ImGui::Text("With border:"); + ImGui::Columns(4, "mycolumns"); // 4-ways, with border + ImGui::Separator(); + ImGui::Text("ID"); ImGui::NextColumn(); + ImGui::Text("Name"); ImGui::NextColumn(); + ImGui::Text("Path"); ImGui::NextColumn(); + ImGui::Text("Flags"); ImGui::NextColumn(); + ImGui::Separator(); + const char* names[3] = { "One", "Two", "Three" }; + const char* paths[3] = { "/path/one", "/path/two", "/path/three" }; + static int selected = -1; + for (int i = 0; i < 3; i++) + { + char label[32]; + sprintf(label, "%04d", i); + if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns)) + selected = i; + ImGui::NextColumn(); + ImGui::Text(names[i]); ImGui::NextColumn(); + ImGui::Text(paths[i]); ImGui::NextColumn(); + ImGui::Text("...."); ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::Separator(); + ImGui::TreePop(); + } + + // Scrolling columns + /* + if (ImGui::TreeNode("Scrolling")) + { + ImGui::BeginChild("##header", ImVec2(0, ImGui::GetTextLineHeightWithSpacing()+ImGui::GetStyle().ItemSpacing.y)); + ImGui::Columns(3); + ImGui::Text("ID"); ImGui::NextColumn(); + ImGui::Text("Name"); ImGui::NextColumn(); + ImGui::Text("Path"); ImGui::NextColumn(); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::EndChild(); + ImGui::BeginChild("##scrollingregion", ImVec2(0, 60)); + ImGui::Columns(3); + for (int i = 0; i < 10; i++) + { + ImGui::Text("%04d", i); ImGui::NextColumn(); + ImGui::Text("Foobar"); ImGui::NextColumn(); + ImGui::Text("/path/foobar/%04d/", i); ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::EndChild(); + ImGui::TreePop(); + } + */ + + // Create multiple items in a same cell before switching to next column + if (ImGui::TreeNode("Mixed items")) + { + ImGui::Columns(3, "mixed"); + ImGui::Separator(); + + ImGui::Text("Hello"); + ImGui::Button("Banana"); + ImGui::NextColumn(); + + ImGui::Text("ImGui"); + ImGui::Button("Apple"); + static float foo = 1.0f; + ImGui::InputFloat("red", &foo, 0.05f, 0, 3); + ImGui::Text("An extra line here."); + ImGui::NextColumn(); + + ImGui::Text("Sailor"); + ImGui::Button("Corniflower"); + static float bar = 1.0f; + ImGui::InputFloat("blue", &bar, 0.05f, 0, 3); + ImGui::NextColumn(); + + if (ImGui::CollapsingHeader("Category A")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category B")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category C")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::TreePop(); + } + + // Word wrapping + if (ImGui::TreeNode("Word-wrapping")) + { + ImGui::Columns(2, "word-wrapping"); + ImGui::Separator(); + ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); + ImGui::TextWrapped("Hello Left"); + ImGui::NextColumn(); + ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); + ImGui::TextWrapped("Hello Right"); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Borders")) + { + static bool h_borders = true; + static bool v_borders = true; + ImGui::Checkbox("horizontal", &h_borders); + ImGui::SameLine(); + ImGui::Checkbox("vertical", &v_borders); + ImGui::Columns(4, NULL, v_borders); + if (h_borders) ImGui::Separator(); + for (int i = 0; i < 8; i++) + { + ImGui::Text("%c%c%c", 'a'+i, 'a'+i, 'a'+i); + ImGui::NextColumn(); + } + ImGui::Columns(1); + if (h_borders) ImGui::Separator(); + ImGui::TreePop(); + } + + bool node_open = ImGui::TreeNode("Tree within single cell"); + ImGui::SameLine(); ShowHelpMarker("NB: Tree node must be poped before ending the cell.\nThere's no storage of state per-cell."); + if (node_open) + { + ImGui::Columns(2, "tree items"); + ImGui::Separator(); + if (ImGui::TreeNode("Hello")) { ImGui::BulletText("Sailor"); ImGui::TreePop(); } ImGui::NextColumn(); + if (ImGui::TreeNode("Bonjour")) { ImGui::BulletText("Marin"); ImGui::TreePop(); } ImGui::NextColumn(); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Filtering")) + { + static ImGuiTextFilter filter; + ImGui::Text("Filter usage:\n" + " \"\" display all lines\n" + " \"xxx\" display lines containing \"xxx\"\n" + " \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n" + " \"-xxx\" hide lines containing \"xxx\""); + filter.Draw(); + const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" }; + for (int i = 0; i < IM_ARRAYSIZE(lines); i++) + if (filter.PassFilter(lines[i])) + ImGui::BulletText("%s", lines[i]); + } + + if (ImGui::CollapsingHeader("Keyboard, Mouse & Focus")) + { + if (ImGui::TreeNode("Tabbing")) + { + ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields."); + static char buf[32] = "dummy"; + ImGui::InputText("1", buf, IM_ARRAYSIZE(buf)); + ImGui::InputText("2", buf, IM_ARRAYSIZE(buf)); + ImGui::InputText("3", buf, IM_ARRAYSIZE(buf)); + ImGui::PushAllowKeyboardFocus(false); + ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf)); + //ImGui::SameLine(); ShowHelperMarker("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets."); + ImGui::PopAllowKeyboardFocus(); + ImGui::InputText("5", buf, IM_ARRAYSIZE(buf)); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Focus from code")) + { + bool focus_1 = ImGui::Button("Focus on 1"); ImGui::SameLine(); + bool focus_2 = ImGui::Button("Focus on 2"); ImGui::SameLine(); + bool focus_3 = ImGui::Button("Focus on 3"); + int has_focus = 0; + static char buf[128] = "click on a button to set focus"; + + if (focus_1) ImGui::SetKeyboardFocusHere(); + ImGui::InputText("1", buf, IM_ARRAYSIZE(buf)); + if (ImGui::IsItemActive()) has_focus = 1; + + if (focus_2) ImGui::SetKeyboardFocusHere(); + ImGui::InputText("2", buf, IM_ARRAYSIZE(buf)); + if (ImGui::IsItemActive()) has_focus = 2; + + ImGui::PushAllowKeyboardFocus(false); + if (focus_3) ImGui::SetKeyboardFocusHere(); + ImGui::InputText("3 (tab skip)", buf, IM_ARRAYSIZE(buf)); + if (ImGui::IsItemActive()) has_focus = 3; + ImGui::PopAllowKeyboardFocus(); + if (has_focus) + ImGui::Text("Item with focus: %d", has_focus); + else + ImGui::Text("Item with focus: "); + ImGui::TextWrapped("Cursor & selection are preserved when refocusing last used item in code."); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Dragging")) + { + ImGui::TextWrapped("You can use ImGui::GetItemActiveDragDelta() to query for the dragged amount on any widget."); + ImGui::Button("Drag Me"); + if (ImGui::IsItemActive()) + { + // Draw a line between the button and the mouse cursor + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + draw_list->PushClipRectFullScreen(); + draw_list->AddLine(ImGui::CalcItemRectClosestPoint(ImGui::GetIO().MousePos, true, -2.0f), ImGui::GetIO().MousePos, ImColor(ImGui::GetStyle().Colors[ImGuiCol_Button]), 4.0f); + draw_list->PopClipRect(); + ImVec2 value_raw = ImGui::GetMouseDragDelta(0, 0.0f); + ImVec2 value_with_lock_threshold = ImGui::GetMouseDragDelta(0); + ImVec2 mouse_delta = ImGui::GetIO().MouseDelta; + ImGui::SameLine(); ImGui::Text("Raw (%.1f, %.1f), WithLockThresold (%.1f, %.1f), MouseDelta (%.1f, %.1f)", value_raw.x, value_raw.y, value_with_lock_threshold.x, value_with_lock_threshold.y, mouse_delta.x, mouse_delta.y); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Keyboard & Mouse State")) + { + ImGuiIO& io = ImGui::GetIO(); + + ImGui::Text("MousePos: (%g, %g)", io.MousePos.x, io.MousePos.y); + ImGui::Text("Mouse down:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (io.MouseDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); } + ImGui::Text("Mouse clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } + ImGui::Text("Mouse dbl-clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDoubleClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } + ImGui::Text("Mouse released:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseReleased(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } + ImGui::Text("MouseWheel: %.1f", io.MouseWheel); + + ImGui::Text("Keys down:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (io.KeysDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("%d (%.02f secs)", i, io.KeysDownDuration[i]); } + ImGui::Text("Keys pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyPressed(i)) { ImGui::SameLine(); ImGui::Text("%d", i); } + ImGui::Text("Keys release:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyReleased(i)) { ImGui::SameLine(); ImGui::Text("%d", i); } + ImGui::Text("KeyMods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : ""); + + ImGui::Text("WantCaptureMouse: %s", io.WantCaptureMouse ? "true" : "false"); + ImGui::Text("WantCaptureKeyboard: %s", io.WantCaptureKeyboard ? "true" : "false"); + ImGui::Text("WantTextInput: %s", io.WantTextInput ? "true" : "false"); + + ImGui::Button("Hovering me sets the\nkeyboard capture flag"); + if (ImGui::IsItemHovered()) + ImGui::CaptureKeyboardFromApp(true); + ImGui::SameLine(); + ImGui::Button("Holding me clears the\nthe keyboard capture flag"); + if (ImGui::IsItemActive()) + ImGui::CaptureKeyboardFromApp(false); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Mouse cursors")) + { + ImGui::TextWrapped("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. You can also set io.MouseDrawCursor to ask ImGui to render the cursor for you in software."); + ImGui::Checkbox("io.MouseDrawCursor", &ImGui::GetIO().MouseDrawCursor); + ImGui::Text("Hover to see mouse cursors:"); + for (int i = 0; i < ImGuiMouseCursor_Count_; i++) + { + char label[32]; + sprintf(label, "Mouse cursor %d", i); + ImGui::Bullet(); ImGui::Selectable(label, false); + if (ImGui::IsItemHovered()) + ImGui::SetMouseCursor(i); + } + ImGui::TreePop(); + } + } + + ImGui::End(); +} + +void ImGui::ShowStyleEditor(ImGuiStyle* ref) +{ + ImGuiStyle& style = ImGui::GetStyle(); + + // You can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it compares to the default style) + const ImGuiStyle default_style; // Default style + if (ImGui::Button("Revert Style")) + style = ref ? *ref : default_style; + + if (ref) + { + ImGui::SameLine(); + if (ImGui::Button("Save Style")) + *ref = style; + } + + ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.55f); + + if (ImGui::TreeNode("Rendering")) + { + ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); + ImGui::Checkbox("Anti-aliased shapes", &style.AntiAliasedShapes); + ImGui::PushItemWidth(100); + ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, NULL, 2.0f); + if (style.CurveTessellationTol < 0.0f) style.CurveTessellationTol = 0.10f; + ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero. + ImGui::PopItemWidth(); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Sizes")) + { + ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 16.0f, "%.0f"); + ImGui::SliderFloat("ChildWindowRounding", &style.ChildWindowRounding, 0.0f, 16.0f, "%.0f"); + ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 16.0f, "%.0f"); + ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 10.0f, "%.0f"); + ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f, "%.0f"); + ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f, "%.0f"); + ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 16.0f, "%.0f"); + ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f"); + ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 16.0f, "%.0f"); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Colors")) + { + static int output_dest = 0; + static bool output_only_modified = false; + if (ImGui::Button("Copy Colors")) + { + if (output_dest == 0) + ImGui::LogToClipboard(); + else + ImGui::LogToTTY(); + ImGui::LogText("ImGuiStyle& style = ImGui::GetStyle();" IM_NEWLINE); + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + const ImVec4& col = style.Colors[i]; + const char* name = ImGui::GetStyleColName(i); + if (!output_only_modified || memcmp(&col, (ref ? &ref->Colors[i] : &default_style.Colors[i]), sizeof(ImVec4)) != 0) + ImGui::LogText("style.Colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, name, 22 - (int)strlen(name), "", col.x, col.y, col.z, col.w); + } + ImGui::LogFinish(); + } + ImGui::SameLine(); ImGui::PushItemWidth(120); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0"); ImGui::PopItemWidth(); + ImGui::SameLine(); ImGui::Checkbox("Only Modified Fields", &output_only_modified); + + static ImGuiColorEditMode edit_mode = ImGuiColorEditMode_RGB; + ImGui::RadioButton("RGB", &edit_mode, ImGuiColorEditMode_RGB); + ImGui::SameLine(); + ImGui::RadioButton("HSV", &edit_mode, ImGuiColorEditMode_HSV); + ImGui::SameLine(); + ImGui::RadioButton("HEX", &edit_mode, ImGuiColorEditMode_HEX); + //ImGui::Text("Tip: Click on colored square to change edit mode."); + + static ImGuiTextFilter filter; + filter.Draw("Filter colors", 200); + + ImGui::BeginChild("#colors", ImVec2(0, 300), true, ImGuiWindowFlags_AlwaysVerticalScrollbar); + ImGui::PushItemWidth(-160); + ImGui::ColorEditMode(edit_mode); + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + const char* name = ImGui::GetStyleColName(i); + if (!filter.PassFilter(name)) + continue; + ImGui::PushID(i); + ImGui::ColorEdit4(name, (float*)&style.Colors[i], true); + if (memcmp(&style.Colors[i], (ref ? &ref->Colors[i] : &default_style.Colors[i]), sizeof(ImVec4)) != 0) + { + ImGui::SameLine(); if (ImGui::Button("Revert")) style.Colors[i] = ref ? ref->Colors[i] : default_style.Colors[i]; + if (ref) { ImGui::SameLine(); if (ImGui::Button("Save")) ref->Colors[i] = style.Colors[i]; } + } + ImGui::PopID(); + } + ImGui::PopItemWidth(); + ImGui::EndChild(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Fonts", "Fonts (%d)", ImGui::GetIO().Fonts->Fonts.Size)) + { + ImGui::SameLine(); ShowHelpMarker("Tip: Load fonts with io.Fonts->AddFontFromFileTTF()\nbefore calling io.Fonts->GetTex* functions."); + ImFontAtlas* atlas = ImGui::GetIO().Fonts; + if (ImGui::TreeNode("Atlas texture", "Atlas texture (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight)) + { + ImGui::Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0,0), ImVec2(1,1), ImColor(255,255,255,255), ImColor(255,255,255,128)); + ImGui::TreePop(); + } + ImGui::PushItemWidth(100); + for (int i = 0; i < atlas->Fonts.Size; i++) + { + ImFont* font = atlas->Fonts[i]; + ImGui::BulletText("Font %d: \'%s\', %.2f px, %d glyphs", i, font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size); + ImGui::TreePush((void*)(intptr_t)i); + if (i > 0) { ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) { atlas->Fonts[i] = atlas->Fonts[0]; atlas->Fonts[0] = font; } } + ImGui::PushFont(font); + ImGui::Text("The quick brown fox jumps over the lazy dog"); + ImGui::PopFont(); + if (ImGui::TreeNode("Details")) + { + ImGui::DragFloat("font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale only this font + ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent); + ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar); + for (int config_i = 0; config_i < font->ConfigDataCount; config_i++) + { + ImFontConfig* cfg = &font->ConfigData[config_i]; + ImGui::BulletText("Input %d: \'%s\'\nOversample: (%d,%d), PixelSnapH: %d", config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH); + } + ImGui::TreePop(); + } + ImGui::TreePop(); + } + static float window_scale = 1.0f; + ImGui::DragFloat("this window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale only this window + ImGui::DragFloat("global scale", &ImGui::GetIO().FontGlobalScale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale everything + ImGui::PopItemWidth(); + ImGui::SetWindowFontScale(window_scale); + ImGui::TreePop(); + } + + ImGui::PopItemWidth(); +} + +static void ShowExampleAppMainMenuBar() +{ + if (ImGui::BeginMainMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Edit")) + { + if (ImGui::MenuItem("Undo", "CTRL+Z")) {} + if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {} // Disabled item + ImGui::Separator(); + if (ImGui::MenuItem("Cut", "CTRL+X")) {} + if (ImGui::MenuItem("Copy", "CTRL+C")) {} + if (ImGui::MenuItem("Paste", "CTRL+V")) {} + ImGui::EndMenu(); + } + ImGui::EndMainMenuBar(); + } +} + +static void ShowExampleMenuFile() +{ + ImGui::MenuItem("(dummy menu)", NULL, false, false); + if (ImGui::MenuItem("New")) {} + if (ImGui::MenuItem("Open", "Ctrl+O")) {} + if (ImGui::BeginMenu("Open Recent")) + { + ImGui::MenuItem("fish_hat.c"); + ImGui::MenuItem("fish_hat.inl"); + ImGui::MenuItem("fish_hat.h"); + if (ImGui::BeginMenu("More..")) + { + ImGui::MenuItem("Hello"); + ImGui::MenuItem("Sailor"); + if (ImGui::BeginMenu("Recurse..")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } + if (ImGui::MenuItem("Save", "Ctrl+S")) {} + if (ImGui::MenuItem("Save As..")) {} + ImGui::Separator(); + if (ImGui::BeginMenu("Options")) + { + static bool enabled = true; + ImGui::MenuItem("Enabled", "", &enabled); + ImGui::BeginChild("child", ImVec2(0, 60), true); + for (int i = 0; i < 10; i++) + ImGui::Text("Scrolling Text %d", i); + ImGui::EndChild(); + static float f = 0.5f; + static int n = 0; + ImGui::SliderFloat("Value", &f, 0.0f, 1.0f); + ImGui::InputFloat("Input", &f, 0.1f); + ImGui::Combo("Combo", &n, "Yes\0No\0Maybe\0\0"); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Colors")) + { + for (int i = 0; i < ImGuiCol_COUNT; i++) + ImGui::MenuItem(ImGui::GetStyleColName((ImGuiCol)i)); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Disabled", false)) // Disabled + { + IM_ASSERT(0); + } + if (ImGui::MenuItem("Checked", NULL, true)) {} + if (ImGui::MenuItem("Quit", "Alt+F4")) {} +} + +static void ShowExampleAppAutoResize(bool* p_open) +{ + if (!ImGui::Begin("Example: Auto-resizing window", p_open, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::End(); + return; + } + + static int lines = 10; + ImGui::Text("Window will resize every-frame to the size of its content.\nNote that you probably don't want to query the window size to\noutput your content because that would create a feedback loop."); + ImGui::SliderInt("Number of lines", &lines, 1, 20); + for (int i = 0; i < lines; i++) + ImGui::Text("%*sThis is line %d", i*4, "", i); // Pad with space to extend size horizontally + ImGui::End(); +} + +static void ShowExampleAppConstrainedResize(bool* p_open) +{ + struct CustomConstraints // Helper functions to demonstrate programmatic constraints + { + static void Square(ImGuiSizeConstraintCallbackData* data) { data->DesiredSize = ImVec2(IM_MAX(data->DesiredSize.x, data->DesiredSize.y), IM_MAX(data->DesiredSize.x, data->DesiredSize.y)); } + static void Step(ImGuiSizeConstraintCallbackData* data) { float step = (float)(int)(intptr_t)data->UserData; data->DesiredSize = ImVec2((int)(data->DesiredSize.x / step + 0.5f) * step, (int)(data->DesiredSize.y / step + 0.5f) * step); } + }; + + static int type = 0; + if (type == 0) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 0), ImVec2(-1, FLT_MAX)); // Vertical only + if (type == 1) ImGui::SetNextWindowSizeConstraints(ImVec2(0, -1), ImVec2(FLT_MAX, -1)); // Horizontal only + if (type == 2) ImGui::SetNextWindowSizeConstraints(ImVec2(100, 100), ImVec2(FLT_MAX, FLT_MAX)); // Width > 100, Height > 100 + if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(300, 0), ImVec2(400, FLT_MAX)); // Width 300-400 + if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square + if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)100);// Fixed Step + + if (ImGui::Begin("Example: Constrained Resize", p_open)) + { + const char* desc[] = + { + "Resize vertical only", + "Resize horizontal only", + "Width > 100, Height > 100", + "Width 300-400", + "Custom: Always Square", + "Custom: Fixed Steps (100)", + }; + ImGui::Combo("Constraint", &type, desc, IM_ARRAYSIZE(desc)); + if (ImGui::Button("200x200")) ImGui::SetWindowSize(ImVec2(200,200)); ImGui::SameLine(); + if (ImGui::Button("500x500")) ImGui::SetWindowSize(ImVec2(500,500)); ImGui::SameLine(); + if (ImGui::Button("800x200")) ImGui::SetWindowSize(ImVec2(800,200)); + for (int i = 0; i < 10; i++) + ImGui::Text("Hello, sailor! Making this line long enough for the example."); + } + ImGui::End(); +} + +static void ShowExampleAppFixedOverlay(bool* p_open) +{ + ImGui::SetNextWindowPos(ImVec2(10,10)); + if (!ImGui::Begin("Example: Fixed Overlay", p_open, ImVec2(0,0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) + { + ImGui::End(); + return; + } + ImGui::Text("Simple overlay\non the top-left side of the screen."); + ImGui::Separator(); + ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); + ImGui::End(); +} + +static void ShowExampleAppManipulatingWindowTitle(bool*) +{ + // By default, Windows are uniquely identified by their title. + // You can use the "##" and "###" markers to manipulate the display/ID. Read FAQ at the top of this file! + + // Using "##" to display same title but have unique identifier. + ImGui::SetNextWindowPos(ImVec2(100,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Same title as another window##1"); + ImGui::Text("This is window 1.\nMy title is the same as window 2, but my identifier is unique."); + ImGui::End(); + + ImGui::SetNextWindowPos(ImVec2(100,200), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Same title as another window##2"); + ImGui::Text("This is window 2.\nMy title is the same as window 1, but my identifier is unique."); + ImGui::End(); + + // Using "###" to display a changing title but keep a static identifier "AnimatedTitle" + char buf[128]; + sprintf(buf, "Animated title %c %d###AnimatedTitle", "|/-\\"[(int)(ImGui::GetTime()/0.25f)&3], rand()); + ImGui::SetNextWindowPos(ImVec2(100,300), ImGuiSetCond_FirstUseEver); + ImGui::Begin(buf); + ImGui::Text("This window has a changing title."); + ImGui::End(); +} + +static void ShowExampleAppCustomRendering(bool* p_open) +{ + ImGui::SetNextWindowSize(ImVec2(350,560), ImGuiSetCond_FirstUseEver); + if (!ImGui::Begin("Example: Custom rendering", p_open)) + { + ImGui::End(); + return; + } + + // Tip: If you do a lot of custom rendering, you probably want to use your own geometrical types and benefit of overloaded operators, etc. + // Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your types and ImVec2/ImVec4. + // ImGui defines overloaded operators but they are internal to imgui.cpp and not exposed outside (to avoid messing with your types) + // In this example we are not using the maths operators! + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + // Primitives + ImGui::Text("Primitives"); + static float sz = 36.0f; + static ImVec4 col = ImVec4(1.0f,1.0f,0.4f,1.0f); + ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f"); + ImGui::ColorEdit3("Color", &col.x); + { + const ImVec2 p = ImGui::GetCursorScreenPos(); + const ImU32 col32 = ImColor(col); + float x = p.x + 4.0f, y = p.y + 4.0f, spacing = 8.0f; + for (int n = 0; n < 2; n++) + { + float thickness = (n == 0) ? 1.0f : 4.0f; + draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 20, thickness); x += sz+spacing; + draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 0.0f, ~0, thickness); x += sz+spacing; + draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ~0, thickness); x += sz+spacing; + draw_list->AddTriangle(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32, thickness); x += sz+spacing; + draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y ), col32, thickness); x += sz+spacing; + draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, thickness); x += sz+spacing; + draw_list->AddLine(ImVec2(x, y), ImVec2(x, y+sz), col32, thickness); x += spacing; + draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x+sz*1.3f,y+sz*0.3f), ImVec2(x+sz-sz*1.3f,y+sz-sz*0.3f), ImVec2(x+sz, y+sz), col32, thickness); + x = p.x + 4; + y += sz+spacing; + } + draw_list->AddCircleFilled(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 32); x += sz+spacing; + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32); x += sz+spacing; + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f); x += sz+spacing; + draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32); x += sz+spacing; + draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x+sz, y+sz), ImColor(0,0,0), ImColor(255,0,0), ImColor(255,255,0), ImColor(0,255,0)); + ImGui::Dummy(ImVec2((sz+spacing)*8, (sz+spacing)*3)); + } + ImGui::Separator(); + { + static ImVector points; + static bool adding_line = false; + ImGui::Text("Canvas example"); + if (ImGui::Button("Clear")) points.clear(); + if (points.Size >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } } + ImGui::Text("Left-click and drag to add lines,\nRight-click to undo"); + + // Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered() + // However you can draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos(). + // If you only use the ImDrawList API, you can notify the owner window of its extends by using SetCursorPos(max). + ImVec2 canvas_pos = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates! + ImVec2 canvas_size = ImGui::GetContentRegionAvail(); // Resize canvas to what's available + if (canvas_size.x < 50.0f) canvas_size.x = 50.0f; + if (canvas_size.y < 50.0f) canvas_size.y = 50.0f; + draw_list->AddRectFilledMultiColor(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), ImColor(50,50,50), ImColor(50,50,60), ImColor(60,60,70), ImColor(50,50,60)); + draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), ImColor(255,255,255)); + + bool adding_preview = false; + ImGui::InvisibleButton("canvas", canvas_size); + if (ImGui::IsItemHovered()) + { + ImVec2 mouse_pos_in_canvas = ImVec2(ImGui::GetIO().MousePos.x - canvas_pos.x, ImGui::GetIO().MousePos.y - canvas_pos.y); + if (!adding_line && ImGui::IsMouseClicked(0)) + { + points.push_back(mouse_pos_in_canvas); + adding_line = true; + } + if (adding_line) + { + adding_preview = true; + points.push_back(mouse_pos_in_canvas); + if (!ImGui::GetIO().MouseDown[0]) + adding_line = adding_preview = false; + } + if (ImGui::IsMouseClicked(1) && !points.empty()) + { + adding_line = adding_preview = false; + points.pop_back(); + points.pop_back(); + } + } + draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y)); // clip lines within the canvas (if we resize it, etc.) + for (int i = 0; i < points.Size - 1; i += 2) + draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i+1].x, canvas_pos.y + points[i+1].y), 0xFF00FFFF, 2.0f); + draw_list->PopClipRect(); + if (adding_preview) + points.pop_back(); + } + ImGui::End(); +} + +// For the console example, here we are using a more C++ like approach of declaring a class to hold the data and the functions. +struct ExampleAppConsole +{ + char InputBuf[256]; + ImVector Items; + bool ScrollToBottom; + ImVector History; + int HistoryPos; // -1: new line, 0..History.Size-1 browsing history. + ImVector Commands; + + ExampleAppConsole() + { + ClearLog(); + memset(InputBuf, 0, sizeof(InputBuf)); + HistoryPos = -1; + Commands.push_back("HELP"); + Commands.push_back("HISTORY"); + Commands.push_back("CLEAR"); + Commands.push_back("CLASSIFY"); // "classify" is here to provide an example of "C"+[tab] completing to "CL" and displaying matches. + AddLog("Welcome to ImGui!"); + } + ~ExampleAppConsole() + { + ClearLog(); + for (int i = 0; i < History.Size; i++) + free(History[i]); + } + + // Portable helpers + static int Stricmp(const char* str1, const char* str2) { int d; while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } return d; } + static int Strnicmp(const char* str1, const char* str2, int n) { int d = 0; while (n > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; n--; } return d; } + static char* Strdup(const char *str) { size_t len = strlen(str) + 1; void* buff = malloc(len); return (char*)memcpy(buff, (const void*)str, len); } + + void ClearLog() + { + for (int i = 0; i < Items.Size; i++) + free(Items[i]); + Items.clear(); + ScrollToBottom = true; + } + + void AddLog(const char* fmt, ...) IM_PRINTFARGS(2) + { + char buf[1024]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); + buf[IM_ARRAYSIZE(buf)-1] = 0; + va_end(args); + Items.push_back(Strdup(buf)); + ScrollToBottom = true; + } + + void Draw(const char* title, bool* p_open) + { + ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver); + if (!ImGui::Begin(title, p_open)) + { + ImGui::End(); + return; + } + + ImGui::TextWrapped("This example implements a console with basic coloring, completion and history. A more elaborate implementation may want to store entries along with extra data such as timestamp, emitter, etc."); + ImGui::TextWrapped("Enter 'HELP' for help, press TAB to use text completion."); + + // TODO: display items starting from the bottom + + if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine(); + if (ImGui::SmallButton("Add Dummy Error")) AddLog("[error] something went wrong"); ImGui::SameLine(); + if (ImGui::SmallButton("Clear")) ClearLog(); ImGui::SameLine(); + if (ImGui::SmallButton("Scroll to bottom")) ScrollToBottom = true; + //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); } + + ImGui::Separator(); + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); + static ImGuiTextFilter filter; + filter.Draw("Filter (\"incl,-excl\") (\"error\")", 180); + ImGui::PopStyleVar(); + ImGui::Separator(); + + ImGui::BeginChild("ScrollingRegion", ImVec2(0,-ImGui::GetItemsLineHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar); + if (ImGui::BeginPopupContextWindow()) + { + if (ImGui::Selectable("Clear")) ClearLog(); + ImGui::EndPopup(); + } + + // Display every line as a separate entry so we can change their color or add custom widgets. If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end()); + // NB- if you have thousands of entries this approach may be too inefficient and may require user-side clipping to only process visible items. + // You can seek and display only the lines that are visible using the ImGuiListClipper helper, if your elements are evenly spaced and you have cheap random access to the elements. + // To use the clipper we could replace the 'for (int i = 0; i < Items.Size; i++)' loop with: + // ImGuiListClipper clipper(Items.Size); + // while (clipper.Step()) + // for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + // However take note that you can not use this code as is if a filter is active because it breaks the 'cheap random-access' property. We would need random-access on the post-filtered list. + // A typical application wanting coarse clipping and filtering may want to pre-compute an array of indices that passed the filtering test, recomputing this array when user changes the filter, + // and appending newly elements as they are inserted. This is left as a task to the user until we can manage to improve this example code! + // If your items are of variable size you may want to implement code similar to what ImGuiListClipper does. Or split your data into fixed height items to allow random-seeking into your list. + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4,1)); // Tighten spacing + for (int i = 0; i < Items.Size; i++) + { + const char* item = Items[i]; + if (!filter.PassFilter(item)) + continue; + ImVec4 col = ImVec4(1.0f,1.0f,1.0f,1.0f); // A better implementation may store a type per-item. For the sample let's just parse the text. + if (strstr(item, "[error]")) col = ImColor(1.0f,0.4f,0.4f,1.0f); + else if (strncmp(item, "# ", 2) == 0) col = ImColor(1.0f,0.78f,0.58f,1.0f); + ImGui::PushStyleColor(ImGuiCol_Text, col); + ImGui::TextUnformatted(item); + ImGui::PopStyleColor(); + } + if (ScrollToBottom) + ImGui::SetScrollHere(); + ScrollToBottom = false; + ImGui::PopStyleVar(); + ImGui::EndChild(); + ImGui::Separator(); + + // Command-line + if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), ImGuiInputTextFlags_EnterReturnsTrue|ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_CallbackHistory, &TextEditCallbackStub, (void*)this)) + { + char* input_end = InputBuf+strlen(InputBuf); + while (input_end > InputBuf && input_end[-1] == ' ') input_end--; *input_end = 0; + if (InputBuf[0]) + ExecCommand(InputBuf); + strcpy(InputBuf, ""); + } + + // Demonstrate keeping auto focus on the input box + if (ImGui::IsItemHovered() || (ImGui::IsRootWindowOrAnyChildFocused() && !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0))) + ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget + + ImGui::End(); + } + + void ExecCommand(const char* command_line) + { + AddLog("# %s\n", command_line); + + // Insert into history. First find match and delete it so it can be pushed to the back. This isn't trying to be smart or optimal. + HistoryPos = -1; + for (int i = History.Size-1; i >= 0; i--) + if (Stricmp(History[i], command_line) == 0) + { + free(History[i]); + History.erase(History.begin() + i); + break; + } + History.push_back(Strdup(command_line)); + + // Process command + if (Stricmp(command_line, "CLEAR") == 0) + { + ClearLog(); + } + else if (Stricmp(command_line, "HELP") == 0) + { + AddLog("Commands:"); + for (int i = 0; i < Commands.Size; i++) + AddLog("- %s", Commands[i]); + } + else if (Stricmp(command_line, "HISTORY") == 0) + { + for (int i = History.Size >= 10 ? History.Size - 10 : 0; i < History.Size; i++) + AddLog("%3d: %s\n", i, History[i]); + } + else + { + AddLog("Unknown command: '%s'\n", command_line); + } + } + + static int TextEditCallbackStub(ImGuiTextEditCallbackData* data) // In C++11 you are better off using lambdas for this sort of forwarding callbacks + { + ExampleAppConsole* console = (ExampleAppConsole*)data->UserData; + return console->TextEditCallback(data); + } + + int TextEditCallback(ImGuiTextEditCallbackData* data) + { + //AddLog("cursor: %d, selection: %d-%d", data->CursorPos, data->SelectionStart, data->SelectionEnd); + switch (data->EventFlag) + { + case ImGuiInputTextFlags_CallbackCompletion: + { + // Example of TEXT COMPLETION + + // Locate beginning of current word + const char* word_end = data->Buf + data->CursorPos; + const char* word_start = word_end; + while (word_start > data->Buf) + { + const char c = word_start[-1]; + if (c == ' ' || c == '\t' || c == ',' || c == ';') + break; + word_start--; + } + + // Build a list of candidates + ImVector candidates; + for (int i = 0; i < Commands.Size; i++) + if (Strnicmp(Commands[i], word_start, (int)(word_end-word_start)) == 0) + candidates.push_back(Commands[i]); + + if (candidates.Size == 0) + { + // No match + AddLog("No match for \"%.*s\"!\n", (int)(word_end-word_start), word_start); + } + else if (candidates.Size == 1) + { + // Single match. Delete the beginning of the word and replace it entirely so we've got nice casing + data->DeleteChars((int)(word_start-data->Buf), (int)(word_end-word_start)); + data->InsertChars(data->CursorPos, candidates[0]); + data->InsertChars(data->CursorPos, " "); + } + else + { + // Multiple matches. Complete as much as we can, so inputing "C" will complete to "CL" and display "CLEAR" and "CLASSIFY" + int match_len = (int)(word_end - word_start); + for (;;) + { + int c = 0; + bool all_candidates_matches = true; + for (int i = 0; i < candidates.Size && all_candidates_matches; i++) + if (i == 0) + c = toupper(candidates[i][match_len]); + else if (c != toupper(candidates[i][match_len])) + all_candidates_matches = false; + if (!all_candidates_matches) + break; + match_len++; + } + + if (match_len > 0) + { + data->DeleteChars((int)(word_start - data->Buf), (int)(word_end-word_start)); + data->InsertChars(data->CursorPos, candidates[0], candidates[0] + match_len); + } + + // List matches + AddLog("Possible matches:\n"); + for (int i = 0; i < candidates.Size; i++) + AddLog("- %s\n", candidates[i]); + } + + break; + } + case ImGuiInputTextFlags_CallbackHistory: + { + // Example of HISTORY + const int prev_history_pos = HistoryPos; + if (data->EventKey == ImGuiKey_UpArrow) + { + if (HistoryPos == -1) + HistoryPos = History.Size - 1; + else if (HistoryPos > 0) + HistoryPos--; + } + else if (data->EventKey == ImGuiKey_DownArrow) + { + if (HistoryPos != -1) + if (++HistoryPos >= History.Size) + HistoryPos = -1; + } + + // A better implementation would preserve the data on the current input line along with cursor position. + if (prev_history_pos != HistoryPos) + { + data->CursorPos = data->SelectionStart = data->SelectionEnd = data->BufTextLen = (int)snprintf(data->Buf, (size_t)data->BufSize, "%s", (HistoryPos >= 0) ? History[HistoryPos] : ""); + data->BufDirty = true; + } + } + } + return 0; + } +}; + +static void ShowExampleAppConsole(bool* p_open) +{ + static ExampleAppConsole console; + console.Draw("Example: Console", p_open); +} + +// Usage: +// static ExampleAppLog my_log; +// my_log.AddLog("Hello %d world\n", 123); +// my_log.Draw("title"); +struct ExampleAppLog +{ + ImGuiTextBuffer Buf; + ImGuiTextFilter Filter; + ImVector LineOffsets; // Index to lines offset + bool ScrollToBottom; + + void Clear() { Buf.clear(); LineOffsets.clear(); } + + void AddLog(const char* fmt, ...) IM_PRINTFARGS(2) + { + int old_size = Buf.size(); + va_list args; + va_start(args, fmt); + Buf.appendv(fmt, args); + va_end(args); + for (int new_size = Buf.size(); old_size < new_size; old_size++) + if (Buf[old_size] == '\n') + LineOffsets.push_back(old_size); + ScrollToBottom = true; + } + + void Draw(const char* title, bool* p_open = NULL) + { + ImGui::SetNextWindowSize(ImVec2(500,400), ImGuiSetCond_FirstUseEver); + ImGui::Begin(title, p_open); + if (ImGui::Button("Clear")) Clear(); + ImGui::SameLine(); + bool copy = ImGui::Button("Copy"); + ImGui::SameLine(); + Filter.Draw("Filter", -100.0f); + ImGui::Separator(); + ImGui::BeginChild("scrolling", ImVec2(0,0), false, ImGuiWindowFlags_HorizontalScrollbar); + if (copy) ImGui::LogToClipboard(); + + if (Filter.IsActive()) + { + const char* buf_begin = Buf.begin(); + const char* line = buf_begin; + for (int line_no = 0; line != NULL; line_no++) + { + const char* line_end = (line_no < LineOffsets.Size) ? buf_begin + LineOffsets[line_no] : NULL; + if (Filter.PassFilter(line, line_end)) + ImGui::TextUnformatted(line, line_end); + line = line_end && line_end[1] ? line_end + 1 : NULL; + } + } + else + { + ImGui::TextUnformatted(Buf.begin()); + } + + if (ScrollToBottom) + ImGui::SetScrollHere(1.0f); + ScrollToBottom = false; + ImGui::EndChild(); + ImGui::End(); + } +}; + +static void ShowExampleAppLog(bool* p_open) +{ + static ExampleAppLog log; + + // Demo fill + static float last_time = -1.0f; + float time = ImGui::GetTime(); + if (time - last_time >= 0.3f) + { + const char* random_words[] = { "system", "info", "warning", "error", "fatal", "notice", "log" }; + log.AddLog("[%s] Hello, time is %.1f, rand() %d\n", random_words[rand() % IM_ARRAYSIZE(random_words)], time, (int)rand()); + last_time = time; + } + + log.Draw("Example: Log", p_open); +} + +static void ShowExampleAppLayout(bool* p_open) +{ + ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiSetCond_FirstUseEver); + if (ImGui::Begin("Example: Layout", p_open, ImGuiWindowFlags_MenuBar)) + { + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + if (ImGui::MenuItem("Close")) *p_open = false; + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + + // left + static int selected = 0; + ImGui::BeginChild("left pane", ImVec2(150, 0), true); + for (int i = 0; i < 100; i++) + { + char label[128]; + sprintf(label, "MyObject %d", i); + if (ImGui::Selectable(label, selected == i)) + selected = i; + } + ImGui::EndChild(); + ImGui::SameLine(); + + // right + ImGui::BeginGroup(); + ImGui::BeginChild("item view", ImVec2(0, -ImGui::GetItemsLineHeightWithSpacing())); // Leave room for 1 line below us + ImGui::Text("MyObject: %d", selected); + ImGui::Separator(); + ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); + ImGui::EndChild(); + ImGui::BeginChild("buttons"); + if (ImGui::Button("Revert")) {} + ImGui::SameLine(); + if (ImGui::Button("Save")) {} + ImGui::EndChild(); + ImGui::EndGroup(); + } + ImGui::End(); +} + +static void ShowExampleAppPropertyEditor(bool* p_open) +{ + ImGui::SetNextWindowSize(ImVec2(430,450), ImGuiSetCond_FirstUseEver); + if (!ImGui::Begin("Example: Property editor", p_open)) + { + ImGui::End(); + return; + } + + ShowHelpMarker("This example shows how you may implement a property editor using two columns.\nAll objects/fields data are dummies here.\nRemember that in many simple cases, you can use ImGui::SameLine(xxx) to position\nyour cursor horizontally instead of using the Columns() API."); + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2,2)); + ImGui::Columns(2); + ImGui::Separator(); + + struct funcs + { + static void ShowDummyObject(const char* prefix, int uid) + { + ImGui::PushID(uid); // Use object uid as identifier. Most commonly you could also use the object pointer as a base ID. + ImGui::AlignFirstTextHeightToWidgets(); // Text and Tree nodes are less high than regular widgets, here we add vertical spacing to make the tree lines equal high. + bool node_open = ImGui::TreeNode("Object", "%s_%u", prefix, uid); + ImGui::NextColumn(); + ImGui::AlignFirstTextHeightToWidgets(); + ImGui::Text("my sailor is rich"); + ImGui::NextColumn(); + if (node_open) + { + static float dummy_members[8] = { 0.0f,0.0f,1.0f,3.1416f,100.0f,999.0f }; + for (int i = 0; i < 8; i++) + { + ImGui::PushID(i); // Use field index as identifier. + if (i < 2) + { + ShowDummyObject("Child", 424242); + } + else + { + ImGui::AlignFirstTextHeightToWidgets(); + // Here we use a Selectable (instead of Text) to highlight on hover + //ImGui::Text("Field_%d", i); + char label[32]; + sprintf(label, "Field_%d", i); + ImGui::Bullet(); + ImGui::Selectable(label); + ImGui::NextColumn(); + ImGui::PushItemWidth(-1); + if (i >= 5) + ImGui::InputFloat("##value", &dummy_members[i], 1.0f); + else + ImGui::DragFloat("##value", &dummy_members[i], 0.01f); + ImGui::PopItemWidth(); + ImGui::NextColumn(); + } + ImGui::PopID(); + } + ImGui::TreePop(); + } + ImGui::PopID(); + } + }; + + // Iterate dummy objects with dummy members (all the same data) + for (int obj_i = 0; obj_i < 3; obj_i++) + funcs::ShowDummyObject("Object", obj_i); + + ImGui::Columns(1); + ImGui::Separator(); + ImGui::PopStyleVar(); + ImGui::End(); +} + +static void ShowExampleAppLongText(bool* p_open) +{ + ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver); + if (!ImGui::Begin("Example: Long text display", p_open)) + { + ImGui::End(); + return; + } + + static int test_type = 0; + static ImGuiTextBuffer log; + static int lines = 0; + ImGui::Text("Printing unusually long amount of text."); + ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped manually\0Multiple calls to Text(), not clipped\0"); + ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size()); + if (ImGui::Button("Clear")) { log.clear(); lines = 0; } + ImGui::SameLine(); + if (ImGui::Button("Add 1000 lines")) + { + for (int i = 0; i < 1000; i++) + log.append("%i The quick brown fox jumps over the lazy dog\n", lines+i); + lines += 1000; + } + ImGui::BeginChild("Log"); + switch (test_type) + { + case 0: + // Single call to TextUnformatted() with a big buffer + ImGui::TextUnformatted(log.begin(), log.end()); + break; + case 1: + { + // Multiple calls to Text(), manually coarsely clipped - demonstrate how to use the ImGuiListClipper helper. + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); + ImGuiListClipper clipper(lines); + while (clipper.Step()) + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + ImGui::Text("%i The quick brown fox jumps over the lazy dog", i); + ImGui::PopStyleVar(); + break; + } + case 2: + // Multiple calls to Text(), not clipped (slow) + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); + for (int i = 0; i < lines; i++) + ImGui::Text("%i The quick brown fox jumps over the lazy dog", i); + ImGui::PopStyleVar(); + break; + } + ImGui::EndChild(); + ImGui::End(); +} + +// End of Demo code +#else + +void ImGui::ShowTestWindow(bool*) {} +void ImGui::ShowUserGuide() {} +void ImGui::ShowStyleEditor(ImGuiStyle*) {} + +#endif diff --git a/CameraParameterEstimation/apps/basics/extern/imgui/imgui_draw.cpp b/CameraParameterEstimation/apps/basics/extern/imgui/imgui_draw.cpp new file mode 100644 index 0000000..4554929 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/imgui/imgui_draw.cpp @@ -0,0 +1,2390 @@ +// dear imgui, v1.50 WIP +// (drawing and font code) + +// Contains implementation for +// - ImDrawList +// - ImDrawData +// - ImFontAtlas +// - ImFont +// - Default font data + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "imgui.h" +#define IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_PLACEMENT_NEW +#include "imgui_internal.h" + +#include // vsnprintf, sscanf, printf +#if !defined(alloca) +#ifdef _WIN32 +#include // alloca +#elif (defined(__FreeBSD__) || defined(FreeBSD_kernel) || defined(__DragonFly__)) && !defined(__GLIBC__) +#include // alloca. FreeBSD uses stdlib.h unless GLIBC +#else +#include // alloca +#endif +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff) +#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen +#define snprintf _snprintf +#endif + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. +#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok. +#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. +#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // +#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier // +#elif defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used +#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value +#endif + +//------------------------------------------------------------------------- +// STB libraries implementation +//------------------------------------------------------------------------- + +//#define IMGUI_STB_NAMESPACE ImGuiStb +//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION +//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION + +#ifdef IMGUI_STB_NAMESPACE +namespace IMGUI_STB_NAMESPACE +{ +#endif + +#ifdef _MSC_VER +#pragma warning (push) +#pragma warning (disable: 4456) // declaration of 'xx' hides previous local declaration +#endif + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. +#pragma clang diagnostic ignored "-Wunused-function" +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" // warning: comparison is always true due to limited range of data type [-Wtype-limits] +#endif + +#define STBRP_ASSERT(x) IM_ASSERT(x) +#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION +#define STBRP_STATIC +#define STB_RECT_PACK_IMPLEMENTATION +#endif +#include "stb_rect_pack.h" + +#define STBTT_malloc(x,u) ((void)(u), ImGui::MemAlloc(x)) +#define STBTT_free(x,u) ((void)(u), ImGui::MemFree(x)) +#define STBTT_assert(x) IM_ASSERT(x) +#ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION +#define STBTT_STATIC +#define STB_TRUETYPE_IMPLEMENTATION +#else +#define STBTT_DEF extern +#endif +#include "stb_truetype.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#ifdef _MSC_VER +#pragma warning (pop) +#endif + +#ifdef IMGUI_STB_NAMESPACE +} // namespace ImGuiStb +using namespace IMGUI_STB_NAMESPACE; +#endif + +//----------------------------------------------------------------------------- +// ImDrawList +//----------------------------------------------------------------------------- + +static const ImVec4 GNullClipRect(-8192.0f, -8192.0f, +8192.0f, +8192.0f); // Large values that are easy to encode in a few bits+shift + +void ImDrawList::Clear() +{ + CmdBuffer.resize(0); + IdxBuffer.resize(0); + VtxBuffer.resize(0); + _VtxCurrentIdx = 0; + _VtxWritePtr = NULL; + _IdxWritePtr = NULL; + _ClipRectStack.resize(0); + _TextureIdStack.resize(0); + _Path.resize(0); + _ChannelsCurrent = 0; + _ChannelsCount = 1; + // NB: Do not clear channels so our allocations are re-used after the first frame. +} + +void ImDrawList::ClearFreeMemory() +{ + CmdBuffer.clear(); + IdxBuffer.clear(); + VtxBuffer.clear(); + _VtxCurrentIdx = 0; + _VtxWritePtr = NULL; + _IdxWritePtr = NULL; + _ClipRectStack.clear(); + _TextureIdStack.clear(); + _Path.clear(); + _ChannelsCurrent = 0; + _ChannelsCount = 1; + for (int i = 0; i < _Channels.Size; i++) + { + if (i == 0) memset(&_Channels[0], 0, sizeof(_Channels[0])); // channel 0 is a copy of CmdBuffer/IdxBuffer, don't destruct again + _Channels[i].CmdBuffer.clear(); + _Channels[i].IdxBuffer.clear(); + } + _Channels.clear(); +} + +// Use macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug mode +#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : GNullClipRect) +#define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : NULL) + +void ImDrawList::AddDrawCmd() +{ + ImDrawCmd draw_cmd; + draw_cmd.ClipRect = GetCurrentClipRect(); + draw_cmd.TextureId = GetCurrentTextureId(); + + IM_ASSERT(draw_cmd.ClipRect.x <= draw_cmd.ClipRect.z && draw_cmd.ClipRect.y <= draw_cmd.ClipRect.w); + CmdBuffer.push_back(draw_cmd); +} + +void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) +{ + ImDrawCmd* current_cmd = CmdBuffer.Size ? &CmdBuffer.back() : NULL; + if (!current_cmd || current_cmd->ElemCount != 0 || current_cmd->UserCallback != NULL) + { + AddDrawCmd(); + current_cmd = &CmdBuffer.back(); + } + current_cmd->UserCallback = callback; + current_cmd->UserCallbackData = callback_data; + + AddDrawCmd(); // Force a new command after us (see comment below) +} + +// Our scheme may appears a bit unusual, basically we want the most-common calls AddLine AddRect etc. to not have to perform any check so we always have a command ready in the stack. +// The cost of figuring out if a new command has to be added or if we can merge is paid in those Update** functions only. +void ImDrawList::UpdateClipRect() +{ + // If current command is used with different settings we need to add a new command + const ImVec4 curr_clip_rect = GetCurrentClipRect(); + ImDrawCmd* curr_cmd = CmdBuffer.Size > 0 ? &CmdBuffer.Data[CmdBuffer.Size-1] : NULL; + if (!curr_cmd || (curr_cmd->ElemCount != 0 && memcmp(&curr_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) != 0) || curr_cmd->UserCallback != NULL) + { + AddDrawCmd(); + return; + } + + // Try to merge with previous command if it matches, else use current command + ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL; + if (curr_cmd->ElemCount == 0 && prev_cmd && memcmp(&prev_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) == 0 && prev_cmd->TextureId == GetCurrentTextureId() && prev_cmd->UserCallback == NULL) + CmdBuffer.pop_back(); + else + curr_cmd->ClipRect = curr_clip_rect; +} + +void ImDrawList::UpdateTextureID() +{ + // If current command is used with different settings we need to add a new command + const ImTextureID curr_texture_id = GetCurrentTextureId(); + ImDrawCmd* curr_cmd = CmdBuffer.Size ? &CmdBuffer.back() : NULL; + if (!curr_cmd || (curr_cmd->ElemCount != 0 && curr_cmd->TextureId != curr_texture_id) || curr_cmd->UserCallback != NULL) + { + AddDrawCmd(); + return; + } + + // Try to merge with previous command if it matches, else use current command + ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL; + if (prev_cmd && prev_cmd->TextureId == curr_texture_id && memcmp(&prev_cmd->ClipRect, &GetCurrentClipRect(), sizeof(ImVec4)) == 0 && prev_cmd->UserCallback == NULL) + CmdBuffer.pop_back(); + else + curr_cmd->TextureId = curr_texture_id; +} + +#undef GetCurrentClipRect +#undef GetCurrentTextureId + +// Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) +void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_current_clip_rect) +{ + ImVec4 cr(cr_min.x, cr_min.y, cr_max.x, cr_max.y); + if (intersect_with_current_clip_rect && _ClipRectStack.Size) + { + ImVec4 current = _ClipRectStack.Data[_ClipRectStack.Size-1]; + if (cr.x < current.x) cr.x = current.x; + if (cr.y < current.y) cr.y = current.y; + if (cr.z > current.z) cr.z = current.z; + if (cr.w > current.w) cr.w = current.w; + } + cr.z = ImMax(cr.x, cr.z); + cr.w = ImMax(cr.y, cr.w); + + _ClipRectStack.push_back(cr); + UpdateClipRect(); +} + +void ImDrawList::PushClipRectFullScreen() +{ + PushClipRect(ImVec2(GNullClipRect.x, GNullClipRect.y), ImVec2(GNullClipRect.z, GNullClipRect.w)); + //PushClipRect(GetVisibleRect()); // FIXME-OPT: This would be more correct but we're not supposed to access ImGuiContext from here? +} + +void ImDrawList::PopClipRect() +{ + IM_ASSERT(_ClipRectStack.Size > 0); + _ClipRectStack.pop_back(); + UpdateClipRect(); +} + +void ImDrawList::PushTextureID(const ImTextureID& texture_id) +{ + _TextureIdStack.push_back(texture_id); + UpdateTextureID(); +} + +void ImDrawList::PopTextureID() +{ + IM_ASSERT(_TextureIdStack.Size > 0); + _TextureIdStack.pop_back(); + UpdateTextureID(); +} + +void ImDrawList::ChannelsSplit(int channels_count) +{ + IM_ASSERT(_ChannelsCurrent == 0 && _ChannelsCount == 1); + int old_channels_count = _Channels.Size; + if (old_channels_count < channels_count) + _Channels.resize(channels_count); + _ChannelsCount = channels_count; + + // _Channels[] (24 bytes each) hold storage that we'll swap with this->_CmdBuffer/_IdxBuffer + // The content of _Channels[0] at this point doesn't matter. We clear it to make state tidy in a debugger but we don't strictly need to. + // When we switch to the next channel, we'll copy _CmdBuffer/_IdxBuffer into _Channels[0] and then _Channels[1] into _CmdBuffer/_IdxBuffer + memset(&_Channels[0], 0, sizeof(ImDrawChannel)); + for (int i = 1; i < channels_count; i++) + { + if (i >= old_channels_count) + { + IM_PLACEMENT_NEW(&_Channels[i]) ImDrawChannel(); + } + else + { + _Channels[i].CmdBuffer.resize(0); + _Channels[i].IdxBuffer.resize(0); + } + if (_Channels[i].CmdBuffer.Size == 0) + { + ImDrawCmd draw_cmd; + draw_cmd.ClipRect = _ClipRectStack.back(); + draw_cmd.TextureId = _TextureIdStack.back(); + _Channels[i].CmdBuffer.push_back(draw_cmd); + } + } +} + +void ImDrawList::ChannelsMerge() +{ + // Note that we never use or rely on channels.Size because it is merely a buffer that we never shrink back to 0 to keep all sub-buffers ready for use. + if (_ChannelsCount <= 1) + return; + + ChannelsSetCurrent(0); + if (CmdBuffer.Size && CmdBuffer.back().ElemCount == 0) + CmdBuffer.pop_back(); + + int new_cmd_buffer_count = 0, new_idx_buffer_count = 0; + for (int i = 1; i < _ChannelsCount; i++) + { + ImDrawChannel& ch = _Channels[i]; + if (ch.CmdBuffer.Size && ch.CmdBuffer.back().ElemCount == 0) + ch.CmdBuffer.pop_back(); + new_cmd_buffer_count += ch.CmdBuffer.Size; + new_idx_buffer_count += ch.IdxBuffer.Size; + } + CmdBuffer.resize(CmdBuffer.Size + new_cmd_buffer_count); + IdxBuffer.resize(IdxBuffer.Size + new_idx_buffer_count); + + ImDrawCmd* cmd_write = CmdBuffer.Data + CmdBuffer.Size - new_cmd_buffer_count; + _IdxWritePtr = IdxBuffer.Data + IdxBuffer.Size - new_idx_buffer_count; + for (int i = 1; i < _ChannelsCount; i++) + { + ImDrawChannel& ch = _Channels[i]; + if (int sz = ch.CmdBuffer.Size) { memcpy(cmd_write, ch.CmdBuffer.Data, sz * sizeof(ImDrawCmd)); cmd_write += sz; } + if (int sz = ch.IdxBuffer.Size) { memcpy(_IdxWritePtr, ch.IdxBuffer.Data, sz * sizeof(ImDrawIdx)); _IdxWritePtr += sz; } + } + AddDrawCmd(); + _ChannelsCount = 1; +} + +void ImDrawList::ChannelsSetCurrent(int idx) +{ + IM_ASSERT(idx < _ChannelsCount); + if (_ChannelsCurrent == idx) return; + memcpy(&_Channels.Data[_ChannelsCurrent].CmdBuffer, &CmdBuffer, sizeof(CmdBuffer)); // copy 12 bytes, four times + memcpy(&_Channels.Data[_ChannelsCurrent].IdxBuffer, &IdxBuffer, sizeof(IdxBuffer)); + _ChannelsCurrent = idx; + memcpy(&CmdBuffer, &_Channels.Data[_ChannelsCurrent].CmdBuffer, sizeof(CmdBuffer)); + memcpy(&IdxBuffer, &_Channels.Data[_ChannelsCurrent].IdxBuffer, sizeof(IdxBuffer)); + _IdxWritePtr = IdxBuffer.Data + IdxBuffer.Size; +} + +// NB: this can be called with negative count for removing primitives (as long as the result does not underflow) +void ImDrawList::PrimReserve(int idx_count, int vtx_count) +{ + ImDrawCmd& draw_cmd = CmdBuffer.Data[CmdBuffer.Size-1]; + draw_cmd.ElemCount += idx_count; + + int vtx_buffer_size = VtxBuffer.Size; + VtxBuffer.resize(vtx_buffer_size + vtx_count); + _VtxWritePtr = VtxBuffer.Data + vtx_buffer_size; + + int idx_buffer_size = IdxBuffer.Size; + IdxBuffer.resize(idx_buffer_size + idx_count); + _IdxWritePtr = IdxBuffer.Data + idx_buffer_size; +} + +// Fully unrolled with inline call to keep our debug builds decently fast. +void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col) +{ + ImVec2 b(c.x, a.y), d(a.x, c.y), uv(GImGui->FontTexUvWhitePixel); + ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; + _IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2); + _IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3); + _VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos = d; _VtxWritePtr[3].uv = uv; _VtxWritePtr[3].col = col; + _VtxWritePtr += 4; + _VtxCurrentIdx += 4; + _IdxWritePtr += 6; +} + +void ImDrawList::PrimRectUV(const ImVec2& a, const ImVec2& c, const ImVec2& uv_a, const ImVec2& uv_c, ImU32 col) +{ + ImVec2 b(c.x, a.y), d(a.x, c.y), uv_b(uv_c.x, uv_a.y), uv_d(uv_a.x, uv_c.y); + ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; + _IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2); + _IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3); + _VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv_a; _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv_b; _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv_c; _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos = d; _VtxWritePtr[3].uv = uv_d; _VtxWritePtr[3].col = col; + _VtxWritePtr += 4; + _VtxCurrentIdx += 4; + _IdxWritePtr += 6; +} + +void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col) +{ + ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; + _IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2); + _IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3); + _VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv_a; _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv_b; _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv_c; _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos = d; _VtxWritePtr[3].uv = uv_d; _VtxWritePtr[3].col = col; + _VtxWritePtr += 4; + _VtxCurrentIdx += 4; + _IdxWritePtr += 6; +} + +// TODO: Thickness anti-aliased lines cap are missing their AA fringe. +void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, bool closed, float thickness, bool anti_aliased) +{ + if (points_count < 2) + return; + + const ImVec2 uv = GImGui->FontTexUvWhitePixel; + anti_aliased &= GImGui->Style.AntiAliasedLines; + //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug + + int count = points_count; + if (!closed) + count = points_count-1; + + const bool thick_line = thickness > 1.0f; + if (anti_aliased) + { + // Anti-aliased stroke + const float AA_SIZE = 1.0f; + const ImU32 col_trans = col & 0x00ffffff; + + const int idx_count = thick_line ? count*18 : count*12; + const int vtx_count = thick_line ? points_count*4 : points_count*3; + PrimReserve(idx_count, vtx_count); + + // Temporary buffer + ImVec2* temp_normals = (ImVec2*)alloca(points_count * (thick_line ? 5 : 3) * sizeof(ImVec2)); + ImVec2* temp_points = temp_normals + points_count; + + for (int i1 = 0; i1 < count; i1++) + { + const int i2 = (i1+1) == points_count ? 0 : i1+1; + ImVec2 diff = points[i2] - points[i1]; + diff *= ImInvLength(diff, 1.0f); + temp_normals[i1].x = diff.y; + temp_normals[i1].y = -diff.x; + } + if (!closed) + temp_normals[points_count-1] = temp_normals[points_count-2]; + + if (!thick_line) + { + if (!closed) + { + temp_points[0] = points[0] + temp_normals[0] * AA_SIZE; + temp_points[1] = points[0] - temp_normals[0] * AA_SIZE; + temp_points[(points_count-1)*2+0] = points[points_count-1] + temp_normals[points_count-1] * AA_SIZE; + temp_points[(points_count-1)*2+1] = points[points_count-1] - temp_normals[points_count-1] * AA_SIZE; + } + + // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. + unsigned int idx1 = _VtxCurrentIdx; + for (int i1 = 0; i1 < count; i1++) + { + const int i2 = (i1+1) == points_count ? 0 : i1+1; + unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+3; + + // Average normals + ImVec2 dm = (temp_normals[i1] + temp_normals[i2]) * 0.5f; + float dmr2 = dm.x*dm.x + dm.y*dm.y; + if (dmr2 > 0.000001f) + { + float scale = 1.0f / dmr2; + if (scale > 100.0f) scale = 100.0f; + dm *= scale; + } + dm *= AA_SIZE; + temp_points[i2*2+0] = points[i2] + dm; + temp_points[i2*2+1] = points[i2] - dm; + + // Add indexes + _IdxWritePtr[0] = (ImDrawIdx)(idx2+0); _IdxWritePtr[1] = (ImDrawIdx)(idx1+0); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2); + _IdxWritePtr[3] = (ImDrawIdx)(idx1+2); _IdxWritePtr[4] = (ImDrawIdx)(idx2+2); _IdxWritePtr[5] = (ImDrawIdx)(idx2+0); + _IdxWritePtr[6] = (ImDrawIdx)(idx2+1); _IdxWritePtr[7] = (ImDrawIdx)(idx1+1); _IdxWritePtr[8] = (ImDrawIdx)(idx1+0); + _IdxWritePtr[9] = (ImDrawIdx)(idx1+0); _IdxWritePtr[10]= (ImDrawIdx)(idx2+0); _IdxWritePtr[11]= (ImDrawIdx)(idx2+1); + _IdxWritePtr += 12; + + idx1 = idx2; + } + + // Add vertexes + for (int i = 0; i < points_count; i++) + { + _VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos = temp_points[i*2+0]; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; + _VtxWritePtr[2].pos = temp_points[i*2+1]; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col_trans; + _VtxWritePtr += 3; + } + } + else + { + const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f; + if (!closed) + { + temp_points[0] = points[0] + temp_normals[0] * (half_inner_thickness + AA_SIZE); + temp_points[1] = points[0] + temp_normals[0] * (half_inner_thickness); + temp_points[2] = points[0] - temp_normals[0] * (half_inner_thickness); + temp_points[3] = points[0] - temp_normals[0] * (half_inner_thickness + AA_SIZE); + temp_points[(points_count-1)*4+0] = points[points_count-1] + temp_normals[points_count-1] * (half_inner_thickness + AA_SIZE); + temp_points[(points_count-1)*4+1] = points[points_count-1] + temp_normals[points_count-1] * (half_inner_thickness); + temp_points[(points_count-1)*4+2] = points[points_count-1] - temp_normals[points_count-1] * (half_inner_thickness); + temp_points[(points_count-1)*4+3] = points[points_count-1] - temp_normals[points_count-1] * (half_inner_thickness + AA_SIZE); + } + + // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. + unsigned int idx1 = _VtxCurrentIdx; + for (int i1 = 0; i1 < count; i1++) + { + const int i2 = (i1+1) == points_count ? 0 : i1+1; + unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+4; + + // Average normals + ImVec2 dm = (temp_normals[i1] + temp_normals[i2]) * 0.5f; + float dmr2 = dm.x*dm.x + dm.y*dm.y; + if (dmr2 > 0.000001f) + { + float scale = 1.0f / dmr2; + if (scale > 100.0f) scale = 100.0f; + dm *= scale; + } + ImVec2 dm_out = dm * (half_inner_thickness + AA_SIZE); + ImVec2 dm_in = dm * half_inner_thickness; + temp_points[i2*4+0] = points[i2] + dm_out; + temp_points[i2*4+1] = points[i2] + dm_in; + temp_points[i2*4+2] = points[i2] - dm_in; + temp_points[i2*4+3] = points[i2] - dm_out; + + // Add indexes + _IdxWritePtr[0] = (ImDrawIdx)(idx2+1); _IdxWritePtr[1] = (ImDrawIdx)(idx1+1); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2); + _IdxWritePtr[3] = (ImDrawIdx)(idx1+2); _IdxWritePtr[4] = (ImDrawIdx)(idx2+2); _IdxWritePtr[5] = (ImDrawIdx)(idx2+1); + _IdxWritePtr[6] = (ImDrawIdx)(idx2+1); _IdxWritePtr[7] = (ImDrawIdx)(idx1+1); _IdxWritePtr[8] = (ImDrawIdx)(idx1+0); + _IdxWritePtr[9] = (ImDrawIdx)(idx1+0); _IdxWritePtr[10] = (ImDrawIdx)(idx2+0); _IdxWritePtr[11] = (ImDrawIdx)(idx2+1); + _IdxWritePtr[12] = (ImDrawIdx)(idx2+2); _IdxWritePtr[13] = (ImDrawIdx)(idx1+2); _IdxWritePtr[14] = (ImDrawIdx)(idx1+3); + _IdxWritePtr[15] = (ImDrawIdx)(idx1+3); _IdxWritePtr[16] = (ImDrawIdx)(idx2+3); _IdxWritePtr[17] = (ImDrawIdx)(idx2+2); + _IdxWritePtr += 18; + + idx1 = idx2; + } + + // Add vertexes + for (int i = 0; i < points_count; i++) + { + _VtxWritePtr[0].pos = temp_points[i*4+0]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col_trans; + _VtxWritePtr[1].pos = temp_points[i*4+1]; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos = temp_points[i*4+2]; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos = temp_points[i*4+3]; _VtxWritePtr[3].uv = uv; _VtxWritePtr[3].col = col_trans; + _VtxWritePtr += 4; + } + } + _VtxCurrentIdx += (ImDrawIdx)vtx_count; + } + else + { + // Non Anti-aliased Stroke + const int idx_count = count*6; + const int vtx_count = count*4; // FIXME-OPT: Not sharing edges + PrimReserve(idx_count, vtx_count); + + for (int i1 = 0; i1 < count; i1++) + { + const int i2 = (i1+1) == points_count ? 0 : i1+1; + const ImVec2& p1 = points[i1]; + const ImVec2& p2 = points[i2]; + ImVec2 diff = p2 - p1; + diff *= ImInvLength(diff, 1.0f); + + const float dx = diff.x * (thickness * 0.5f); + const float dy = diff.y * (thickness * 0.5f); + _VtxWritePtr[0].pos.x = p1.x + dy; _VtxWritePtr[0].pos.y = p1.y - dx; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos.x = p2.x + dy; _VtxWritePtr[1].pos.y = p2.y - dx; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos.x = p2.x - dy; _VtxWritePtr[2].pos.y = p2.y + dx; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos.x = p1.x - dy; _VtxWritePtr[3].pos.y = p1.y + dx; _VtxWritePtr[3].uv = uv; _VtxWritePtr[3].col = col; + _VtxWritePtr += 4; + + _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx+1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx+2); + _IdxWritePtr[3] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[4] = (ImDrawIdx)(_VtxCurrentIdx+2); _IdxWritePtr[5] = (ImDrawIdx)(_VtxCurrentIdx+3); + _IdxWritePtr += 6; + _VtxCurrentIdx += 4; + } + } +} + +void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col, bool anti_aliased) +{ + const ImVec2 uv = GImGui->FontTexUvWhitePixel; + anti_aliased &= GImGui->Style.AntiAliasedShapes; + //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug + + if (anti_aliased) + { + // Anti-aliased Fill + const float AA_SIZE = 1.0f; + const ImU32 col_trans = col & 0x00ffffff; + const int idx_count = (points_count-2)*3 + points_count*6; + const int vtx_count = (points_count*2); + PrimReserve(idx_count, vtx_count); + + // Add indexes for fill + unsigned int vtx_inner_idx = _VtxCurrentIdx; + unsigned int vtx_outer_idx = _VtxCurrentIdx+1; + for (int i = 2; i < points_count; i++) + { + _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx+((i-1)<<1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_inner_idx+(i<<1)); + _IdxWritePtr += 3; + } + + // Compute normals + ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2)); + for (int i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) + { + const ImVec2& p0 = points[i0]; + const ImVec2& p1 = points[i1]; + ImVec2 diff = p1 - p0; + diff *= ImInvLength(diff, 1.0f); + temp_normals[i0].x = diff.y; + temp_normals[i0].y = -diff.x; + } + + for (int i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) + { + // Average normals + const ImVec2& n0 = temp_normals[i0]; + const ImVec2& n1 = temp_normals[i1]; + ImVec2 dm = (n0 + n1) * 0.5f; + float dmr2 = dm.x*dm.x + dm.y*dm.y; + if (dmr2 > 0.000001f) + { + float scale = 1.0f / dmr2; + if (scale > 100.0f) scale = 100.0f; + dm *= scale; + } + dm *= AA_SIZE * 0.5f; + + // Add vertices + _VtxWritePtr[0].pos = (points[i1] - dm); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner + _VtxWritePtr[1].pos = (points[i1] + dm); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer + _VtxWritePtr += 2; + + // Add indexes for fringes + _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx+(i1<<1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx+(i0<<1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx+(i0<<1)); + _IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx+(i0<<1)); _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx+(i1<<1)); _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx+(i1<<1)); + _IdxWritePtr += 6; + } + _VtxCurrentIdx += (ImDrawIdx)vtx_count; + } + else + { + // Non Anti-aliased Fill + const int idx_count = (points_count-2)*3; + const int vtx_count = points_count; + PrimReserve(idx_count, vtx_count); + for (int i = 0; i < vtx_count; i++) + { + _VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; + _VtxWritePtr++; + } + for (int i = 2; i < points_count; i++) + { + _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx+i-1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx+i); + _IdxWritePtr += 3; + } + _VtxCurrentIdx += (ImDrawIdx)vtx_count; + } +} + +void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int amin, int amax) +{ + static ImVec2 circle_vtx[12]; + static bool circle_vtx_builds = false; + const int circle_vtx_count = IM_ARRAYSIZE(circle_vtx); + if (!circle_vtx_builds) + { + for (int i = 0; i < circle_vtx_count; i++) + { + const float a = ((float)i / (float)circle_vtx_count) * 2*IM_PI; + circle_vtx[i].x = cosf(a); + circle_vtx[i].y = sinf(a); + } + circle_vtx_builds = true; + } + + if (amin > amax) return; + if (radius == 0.0f) + { + _Path.push_back(centre); + } + else + { + _Path.reserve(_Path.Size + (amax - amin + 1)); + for (int a = amin; a <= amax; a++) + { + const ImVec2& c = circle_vtx[a % circle_vtx_count]; + _Path.push_back(ImVec2(centre.x + c.x * radius, centre.y + c.y * radius)); + } + } +} + +void ImDrawList::PathArcTo(const ImVec2& centre, float radius, float amin, float amax, int num_segments) +{ + if (radius == 0.0f) + _Path.push_back(centre); + _Path.reserve(_Path.Size + (num_segments + 1)); + for (int i = 0; i <= num_segments; i++) + { + const float a = amin + ((float)i / (float)num_segments) * (amax - amin); + _Path.push_back(ImVec2(centre.x + cosf(a) * radius, centre.y + sinf(a) * radius)); + } +} + +static void PathBezierToCasteljau(ImVector* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level) +{ + float dx = x4 - x1; + float dy = y4 - y1; + float d2 = ((x2 - x4) * dy - (y2 - y4) * dx); + float d3 = ((x3 - x4) * dy - (y3 - y4) * dx); + d2 = (d2 >= 0) ? d2 : -d2; + d3 = (d3 >= 0) ? d3 : -d3; + if ((d2+d3) * (d2+d3) < tess_tol * (dx*dx + dy*dy)) + { + path->push_back(ImVec2(x4, y4)); + } + else if (level < 10) + { + float x12 = (x1+x2)*0.5f, y12 = (y1+y2)*0.5f; + float x23 = (x2+x3)*0.5f, y23 = (y2+y3)*0.5f; + float x34 = (x3+x4)*0.5f, y34 = (y3+y4)*0.5f; + float x123 = (x12+x23)*0.5f, y123 = (y12+y23)*0.5f; + float x234 = (x23+x34)*0.5f, y234 = (y23+y34)*0.5f; + float x1234 = (x123+x234)*0.5f, y1234 = (y123+y234)*0.5f; + + PathBezierToCasteljau(path, x1,y1, x12,y12, x123,y123, x1234,y1234, tess_tol, level+1); + PathBezierToCasteljau(path, x1234,y1234, x234,y234, x34,y34, x4,y4, tess_tol, level+1); + } +} + +void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments) +{ + ImVec2 p1 = _Path.back(); + if (num_segments == 0) + { + // Auto-tessellated + PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, GImGui->Style.CurveTessellationTol, 0); + } + else + { + float t_step = 1.0f / (float)num_segments; + for (int i_step = 1; i_step <= num_segments; i_step++) + { + float t = t_step * i_step; + float u = 1.0f - t; + float w1 = u*u*u; + float w2 = 3*u*u*t; + float w3 = 3*u*t*t; + float w4 = t*t*t; + _Path.push_back(ImVec2(w1*p1.x + w2*p2.x + w3*p3.x + w4*p4.x, w1*p1.y + w2*p2.y + w3*p3.y + w4*p4.y)); + } + } +} + +void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int rounding_corners) +{ + float r = rounding; + r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f ) - 1.0f); + r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f ) - 1.0f); + + if (r <= 0.0f || rounding_corners == 0) + { + PathLineTo(a); + PathLineTo(ImVec2(b.x,a.y)); + PathLineTo(b); + PathLineTo(ImVec2(a.x,b.y)); + } + else + { + const float r0 = (rounding_corners & 1) ? r : 0.0f; + const float r1 = (rounding_corners & 2) ? r : 0.0f; + const float r2 = (rounding_corners & 4) ? r : 0.0f; + const float r3 = (rounding_corners & 8) ? r : 0.0f; + PathArcToFast(ImVec2(a.x+r0,a.y+r0), r0, 6, 9); + PathArcToFast(ImVec2(b.x-r1,a.y+r1), r1, 9, 12); + PathArcToFast(ImVec2(b.x-r2,b.y-r2), r2, 0, 3); + PathArcToFast(ImVec2(a.x+r3,b.y-r3), r3, 3, 6); + } +} + +void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness) +{ + if ((col >> 24) == 0) + return; + PathLineTo(a + ImVec2(0.5f,0.5f)); + PathLineTo(b + ImVec2(0.5f,0.5f)); + PathStroke(col, false, thickness); +} + +// a: upper-left, b: lower-right. we don't render 1 px sized rectangles properly. +void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners, float thickness) +{ + if ((col >> 24) == 0) + return; + PathRect(a + ImVec2(0.5f,0.5f), b - ImVec2(0.5f,0.5f), rounding, rounding_corners); + PathStroke(col, true, thickness); +} + +void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners) +{ + if ((col >> 24) == 0) + return; + if (rounding > 0.0f) + { + PathRect(a, b, rounding, rounding_corners); + PathFill(col); + } + else + { + PrimReserve(6, 4); + PrimRect(a, b, col); + } +} + +void ImDrawList::AddRectFilledMultiColor(const ImVec2& a, const ImVec2& c, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left) +{ + if (((col_upr_left | col_upr_right | col_bot_right | col_bot_left) >> 24) == 0) + return; + + const ImVec2 uv = GImGui->FontTexUvWhitePixel; + PrimReserve(6, 4); + PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+1)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+2)); + PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+2)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+3)); + PrimWriteVtx(a, uv, col_upr_left); + PrimWriteVtx(ImVec2(c.x, a.y), uv, col_upr_right); + PrimWriteVtx(c, uv, col_bot_right); + PrimWriteVtx(ImVec2(a.x, c.y), uv, col_bot_left); +} + +void ImDrawList::AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness) +{ + if ((col >> 24) == 0) + return; + + PathLineTo(a); + PathLineTo(b); + PathLineTo(c); + PathLineTo(d); + PathStroke(col, true, thickness); +} + +void ImDrawList::AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col) +{ + if ((col >> 24) == 0) + return; + + PathLineTo(a); + PathLineTo(b); + PathLineTo(c); + PathLineTo(d); + PathFill(col); +} + +void ImDrawList::AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness) +{ + if ((col >> 24) == 0) + return; + + PathLineTo(a); + PathLineTo(b); + PathLineTo(c); + PathStroke(col, true, thickness); +} + +void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col) +{ + if ((col >> 24) == 0) + return; + + PathLineTo(a); + PathLineTo(b); + PathLineTo(c); + PathFill(col); +} + +void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments, float thickness) +{ + if ((col >> 24) == 0) + return; + + const float a_max = IM_PI*2.0f * ((float)num_segments - 1.0f) / (float)num_segments; + PathArcTo(centre, radius-0.5f, 0.0f, a_max, num_segments); + PathStroke(col, true, thickness); +} + +void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments) +{ + if ((col >> 24) == 0) + return; + + const float a_max = IM_PI*2.0f * ((float)num_segments - 1.0f) / (float)num_segments; + PathArcTo(centre, radius, 0.0f, a_max, num_segments); + PathFill(col); +} + +void ImDrawList::AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments) +{ + if ((col >> 24) == 0) + return; + + PathLineTo(pos0); + PathBezierCurveTo(cp0, cp1, pos1, num_segments); + PathStroke(col, false, thickness); +} + +void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect) +{ + if ((col >> 24) == 0) + return; + + if (text_end == NULL) + text_end = text_begin + strlen(text_begin); + if (text_begin == text_end) + return; + + // Note: This is one of the few instance of breaking the encapsulation of ImDrawList, as we pull this from ImGui state, but it is just SO useful. + // Might just move Font/FontSize to ImDrawList? + if (font == NULL) + font = GImGui->Font; + if (font_size == 0.0f) + font_size = GImGui->FontSize; + + IM_ASSERT(font->ContainerAtlas->TexID == _TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. + + ImVec4 clip_rect = _ClipRectStack.back(); + if (cpu_fine_clip_rect) + { + clip_rect.x = ImMax(clip_rect.x, cpu_fine_clip_rect->x); + clip_rect.y = ImMax(clip_rect.y, cpu_fine_clip_rect->y); + clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z); + clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w); + } + font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL); +} + +void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end) +{ + AddText(GImGui->Font, GImGui->FontSize, pos, col, text_begin, text_end); +} + +void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0, const ImVec2& uv1, ImU32 col) +{ + if ((col >> 24) == 0) + return; + + // FIXME-OPT: This is wasting draw calls. + const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back(); + if (push_texture_id) + PushTextureID(user_texture_id); + + PrimReserve(6, 4); + PrimRectUV(a, b, uv0, uv1, col); + + if (push_texture_id) + PopTextureID(); +} + +//----------------------------------------------------------------------------- +// ImDrawData +//----------------------------------------------------------------------------- + +// For backward compatibility: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering! +void ImDrawData::DeIndexAllBuffers() +{ + ImVector new_vtx_buffer; + TotalVtxCount = TotalIdxCount = 0; + for (int i = 0; i < CmdListsCount; i++) + { + ImDrawList* cmd_list = CmdLists[i]; + if (cmd_list->IdxBuffer.empty()) + continue; + new_vtx_buffer.resize(cmd_list->IdxBuffer.Size); + for (int j = 0; j < cmd_list->IdxBuffer.Size; j++) + new_vtx_buffer[j] = cmd_list->VtxBuffer[cmd_list->IdxBuffer[j]]; + cmd_list->VtxBuffer.swap(new_vtx_buffer); + cmd_list->IdxBuffer.resize(0); + TotalVtxCount += cmd_list->VtxBuffer.Size; + } +} + +// Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than ImGui expects, or if there is a difference between your window resolution and framebuffer resolution. +void ImDrawData::ScaleClipRects(const ImVec2& scale) +{ + for (int i = 0; i < CmdListsCount; i++) + { + ImDrawList* cmd_list = CmdLists[i]; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + ImDrawCmd* cmd = &cmd_list->CmdBuffer[cmd_i]; + cmd->ClipRect = ImVec4(cmd->ClipRect.x * scale.x, cmd->ClipRect.y * scale.y, cmd->ClipRect.z * scale.x, cmd->ClipRect.w * scale.y); + } + } +} + +//----------------------------------------------------------------------------- +// ImFontAtlas +//----------------------------------------------------------------------------- + +ImFontConfig::ImFontConfig() +{ + FontData = NULL; + FontDataSize = 0; + FontDataOwnedByAtlas = true; + FontNo = 0; + SizePixels = 0.0f; + OversampleH = 3; + OversampleV = 1; + PixelSnapH = false; + GlyphExtraSpacing = ImVec2(0.0f, 0.0f); + GlyphRanges = NULL; + MergeMode = false; + MergeGlyphCenterV = false; + DstFont = NULL; + memset(Name, 0, sizeof(Name)); +} + +ImFontAtlas::ImFontAtlas() +{ + TexID = NULL; + TexPixelsAlpha8 = NULL; + TexPixelsRGBA32 = NULL; + TexWidth = TexHeight = TexDesiredWidth = 0; + TexUvWhitePixel = ImVec2(0, 0); +} + +ImFontAtlas::~ImFontAtlas() +{ + Clear(); +} + +void ImFontAtlas::ClearInputData() +{ + for (int i = 0; i < ConfigData.Size; i++) + if (ConfigData[i].FontData && ConfigData[i].FontDataOwnedByAtlas) + { + ImGui::MemFree(ConfigData[i].FontData); + ConfigData[i].FontData = NULL; + } + + // When clearing this we lose access to the font name and other information used to build the font. + for (int i = 0; i < Fonts.Size; i++) + if (Fonts[i]->ConfigData >= ConfigData.Data && Fonts[i]->ConfigData < ConfigData.Data + ConfigData.Size) + { + Fonts[i]->ConfigData = NULL; + Fonts[i]->ConfigDataCount = 0; + } + ConfigData.clear(); +} + +void ImFontAtlas::ClearTexData() +{ + if (TexPixelsAlpha8) + ImGui::MemFree(TexPixelsAlpha8); + if (TexPixelsRGBA32) + ImGui::MemFree(TexPixelsRGBA32); + TexPixelsAlpha8 = NULL; + TexPixelsRGBA32 = NULL; +} + +void ImFontAtlas::ClearFonts() +{ + for (int i = 0; i < Fonts.Size; i++) + { + Fonts[i]->~ImFont(); + ImGui::MemFree(Fonts[i]); + } + Fonts.clear(); +} + +void ImFontAtlas::Clear() +{ + ClearInputData(); + ClearTexData(); + ClearFonts(); +} + +void ImFontAtlas::GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel) +{ + // Build atlas on demand + if (TexPixelsAlpha8 == NULL) + { + if (ConfigData.empty()) + AddFontDefault(); + Build(); + } + + *out_pixels = TexPixelsAlpha8; + if (out_width) *out_width = TexWidth; + if (out_height) *out_height = TexHeight; + if (out_bytes_per_pixel) *out_bytes_per_pixel = 1; +} + +void ImFontAtlas::GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel) +{ + // Convert to RGBA32 format on demand + // Although it is likely to be the most commonly used format, our font rendering is 1 channel / 8 bpp + if (!TexPixelsRGBA32) + { + unsigned char* pixels; + GetTexDataAsAlpha8(&pixels, NULL, NULL); + TexPixelsRGBA32 = (unsigned int*)ImGui::MemAlloc((size_t)(TexWidth * TexHeight * 4)); + const unsigned char* src = pixels; + unsigned int* dst = TexPixelsRGBA32; + for (int n = TexWidth * TexHeight; n > 0; n--) + *dst++ = ((unsigned int)(*src++) << 24) | 0x00FFFFFF; + } + + *out_pixels = (unsigned char*)TexPixelsRGBA32; + if (out_width) *out_width = TexWidth; + if (out_height) *out_height = TexHeight; + if (out_bytes_per_pixel) *out_bytes_per_pixel = 4; +} + +ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg) +{ + IM_ASSERT(font_cfg->FontData != NULL && font_cfg->FontDataSize > 0); + IM_ASSERT(font_cfg->SizePixels > 0.0f); + + // Create new font + if (!font_cfg->MergeMode) + { + ImFont* font = (ImFont*)ImGui::MemAlloc(sizeof(ImFont)); + IM_PLACEMENT_NEW(font) ImFont(); + Fonts.push_back(font); + } + + ConfigData.push_back(*font_cfg); + ImFontConfig& new_font_cfg = ConfigData.back(); + if (!new_font_cfg.DstFont) + new_font_cfg.DstFont = Fonts.back(); + if (!new_font_cfg.FontDataOwnedByAtlas) + { + new_font_cfg.FontData = ImGui::MemAlloc(new_font_cfg.FontDataSize); + new_font_cfg.FontDataOwnedByAtlas = true; + memcpy(new_font_cfg.FontData, font_cfg->FontData, (size_t)new_font_cfg.FontDataSize); + } + + // Invalidate texture + ClearTexData(); + return new_font_cfg.DstFont; +} + +// Default font TTF is compressed with stb_compress then base85 encoded (see extra_fonts/binary_to_compressed_c.cpp for encoder) +static unsigned int stb_decompress_length(unsigned char *input); +static unsigned int stb_decompress(unsigned char *output, unsigned char *i, unsigned int length); +static const char* GetDefaultCompressedFontDataTTFBase85(); +static unsigned int Decode85Byte(char c) { return c >= '\\' ? c-36 : c-35; } +static void Decode85(const unsigned char* src, unsigned char* dst) +{ + while (*src) + { + unsigned int tmp = Decode85Byte(src[0]) + 85*(Decode85Byte(src[1]) + 85*(Decode85Byte(src[2]) + 85*(Decode85Byte(src[3]) + 85*Decode85Byte(src[4])))); + dst[0] = ((tmp >> 0) & 0xFF); dst[1] = ((tmp >> 8) & 0xFF); dst[2] = ((tmp >> 16) & 0xFF); dst[3] = ((tmp >> 24) & 0xFF); // We can't assume little-endianess. + src += 5; + dst += 4; + } +} + +// Load embedded ProggyClean.ttf at size 13, disable oversampling +ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template) +{ + ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); + if (!font_cfg_template) + { + font_cfg.OversampleH = font_cfg.OversampleV = 1; + font_cfg.PixelSnapH = true; + } + if (font_cfg.Name[0] == '\0') strcpy(font_cfg.Name, ""); + + const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85(); + ImFont* font = AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, 13.0f, &font_cfg, GetGlyphRangesDefault()); + return font; +} + +ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) +{ + int data_size = 0; + void* data = ImLoadFileToMemory(filename, "rb", &data_size, 0); + if (!data) + { + IM_ASSERT(0); // Could not load file. + return NULL; + } + ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); + if (font_cfg.Name[0] == '\0') + { + // Store a short copy of filename into into the font name for convenience + const char* p; + for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {} + snprintf(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s", p); + } + return AddFontFromMemoryTTF(data, data_size, size_pixels, &font_cfg, glyph_ranges); +} + +// NBM Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build(). +ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* ttf_data, int ttf_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) +{ + ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); + IM_ASSERT(font_cfg.FontData == NULL); + font_cfg.FontData = ttf_data; + font_cfg.FontDataSize = ttf_size; + font_cfg.SizePixels = size_pixels; + if (glyph_ranges) + font_cfg.GlyphRanges = glyph_ranges; + return AddFont(&font_cfg); +} + +ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_data, int compressed_ttf_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) +{ + const unsigned int buf_decompressed_size = stb_decompress_length((unsigned char*)compressed_ttf_data); + unsigned char* buf_decompressed_data = (unsigned char *)ImGui::MemAlloc(buf_decompressed_size); + stb_decompress(buf_decompressed_data, (unsigned char*)compressed_ttf_data, (unsigned int)compressed_ttf_size); + + ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); + IM_ASSERT(font_cfg.FontData == NULL); + font_cfg.FontDataOwnedByAtlas = true; + return AddFontFromMemoryTTF(buf_decompressed_data, (int)buf_decompressed_size, size_pixels, &font_cfg, glyph_ranges); +} + +ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges) +{ + int compressed_ttf_size = (((int)strlen(compressed_ttf_data_base85) + 4) / 5) * 4; + void* compressed_ttf = ImGui::MemAlloc((size_t)compressed_ttf_size); + Decode85((const unsigned char*)compressed_ttf_data_base85, (unsigned char*)compressed_ttf); + ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges); + ImGui::MemFree(compressed_ttf); + return font; +} + +bool ImFontAtlas::Build() +{ + IM_ASSERT(ConfigData.Size > 0); + + TexID = NULL; + TexWidth = TexHeight = 0; + TexUvWhitePixel = ImVec2(0, 0); + ClearTexData(); + + struct ImFontTempBuildData + { + stbtt_fontinfo FontInfo; + stbrp_rect* Rects; + stbtt_pack_range* Ranges; + int RangesCount; + }; + ImFontTempBuildData* tmp_array = (ImFontTempBuildData*)ImGui::MemAlloc((size_t)ConfigData.Size * sizeof(ImFontTempBuildData)); + + // Initialize font information early (so we can error without any cleanup) + count glyphs + int total_glyph_count = 0; + int total_glyph_range_count = 0; + for (int input_i = 0; input_i < ConfigData.Size; input_i++) + { + ImFontConfig& cfg = ConfigData[input_i]; + ImFontTempBuildData& tmp = tmp_array[input_i]; + + IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == this)); + const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); + IM_ASSERT(font_offset >= 0); + if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) + return false; + + // Count glyphs + if (!cfg.GlyphRanges) + cfg.GlyphRanges = GetGlyphRangesDefault(); + for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2) + { + total_glyph_count += (in_range[1] - in_range[0]) + 1; + total_glyph_range_count++; + } + } + + // Start packing. We need a known width for the skyline algorithm. Using a cheap heuristic here to decide of width. User can override TexDesiredWidth if they wish. + // After packing is done, width shouldn't matter much, but some API/GPU have texture size limitations and increasing width can decrease height. + TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyph_count > 4000) ? 4096 : (total_glyph_count > 2000) ? 2048 : (total_glyph_count > 1000) ? 1024 : 512; + TexHeight = 0; + const int max_tex_height = 1024*32; + stbtt_pack_context spc; + stbtt_PackBegin(&spc, NULL, TexWidth, max_tex_height, 0, 1, NULL); + + // Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values). + ImVector extra_rects; + RenderCustomTexData(0, &extra_rects); + stbtt_PackSetOversampling(&spc, 1, 1); + stbrp_pack_rects((stbrp_context*)spc.pack_info, &extra_rects[0], extra_rects.Size); + for (int i = 0; i < extra_rects.Size; i++) + if (extra_rects[i].was_packed) + TexHeight = ImMax(TexHeight, extra_rects[i].y + extra_rects[i].h); + + // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0) + int buf_packedchars_n = 0, buf_rects_n = 0, buf_ranges_n = 0; + stbtt_packedchar* buf_packedchars = (stbtt_packedchar*)ImGui::MemAlloc(total_glyph_count * sizeof(stbtt_packedchar)); + stbrp_rect* buf_rects = (stbrp_rect*)ImGui::MemAlloc(total_glyph_count * sizeof(stbrp_rect)); + stbtt_pack_range* buf_ranges = (stbtt_pack_range*)ImGui::MemAlloc(total_glyph_range_count * sizeof(stbtt_pack_range)); + memset(buf_packedchars, 0, total_glyph_count * sizeof(stbtt_packedchar)); + memset(buf_rects, 0, total_glyph_count * sizeof(stbrp_rect)); // Unnecessary but let's clear this for the sake of sanity. + memset(buf_ranges, 0, total_glyph_range_count * sizeof(stbtt_pack_range)); + + // First font pass: pack all glyphs (no rendering at this point, we are working with rectangles in an infinitely tall texture at this point) + for (int input_i = 0; input_i < ConfigData.Size; input_i++) + { + ImFontConfig& cfg = ConfigData[input_i]; + ImFontTempBuildData& tmp = tmp_array[input_i]; + + // Setup ranges + int glyph_count = 0; + int glyph_ranges_count = 0; + for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2) + { + glyph_count += (in_range[1] - in_range[0]) + 1; + glyph_ranges_count++; + } + tmp.Ranges = buf_ranges + buf_ranges_n; + tmp.RangesCount = glyph_ranges_count; + buf_ranges_n += glyph_ranges_count; + for (int i = 0; i < glyph_ranges_count; i++) + { + const ImWchar* in_range = &cfg.GlyphRanges[i * 2]; + stbtt_pack_range& range = tmp.Ranges[i]; + range.font_size = cfg.SizePixels; + range.first_unicode_codepoint_in_range = in_range[0]; + range.num_chars = (in_range[1] - in_range[0]) + 1; + range.chardata_for_range = buf_packedchars + buf_packedchars_n; + buf_packedchars_n += range.num_chars; + } + + // Pack + tmp.Rects = buf_rects + buf_rects_n; + buf_rects_n += glyph_count; + stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV); + int n = stbtt_PackFontRangesGatherRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects); + stbrp_pack_rects((stbrp_context*)spc.pack_info, tmp.Rects, n); + + // Extend texture height + for (int i = 0; i < n; i++) + if (tmp.Rects[i].was_packed) + TexHeight = ImMax(TexHeight, tmp.Rects[i].y + tmp.Rects[i].h); + } + IM_ASSERT(buf_rects_n == total_glyph_count); + IM_ASSERT(buf_packedchars_n == total_glyph_count); + IM_ASSERT(buf_ranges_n == total_glyph_range_count); + + // Create texture + TexHeight = ImUpperPowerOfTwo(TexHeight); + TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(TexWidth * TexHeight); + memset(TexPixelsAlpha8, 0, TexWidth * TexHeight); + spc.pixels = TexPixelsAlpha8; + spc.height = TexHeight; + + // Second pass: render characters + for (int input_i = 0; input_i < ConfigData.Size; input_i++) + { + ImFontConfig& cfg = ConfigData[input_i]; + ImFontTempBuildData& tmp = tmp_array[input_i]; + stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV); + stbtt_PackFontRangesRenderIntoRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects); + tmp.Rects = NULL; + } + + // End packing + stbtt_PackEnd(&spc); + ImGui::MemFree(buf_rects); + buf_rects = NULL; + + // Third pass: setup ImFont and glyphs for runtime + for (int input_i = 0; input_i < ConfigData.Size; input_i++) + { + ImFontConfig& cfg = ConfigData[input_i]; + ImFontTempBuildData& tmp = tmp_array[input_i]; + ImFont* dst_font = cfg.DstFont; + + float font_scale = stbtt_ScaleForPixelHeight(&tmp.FontInfo, cfg.SizePixels); + int unscaled_ascent, unscaled_descent, unscaled_line_gap; + stbtt_GetFontVMetrics(&tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap); + + float ascent = unscaled_ascent * font_scale; + float descent = unscaled_descent * font_scale; + if (!cfg.MergeMode) + { + dst_font->ContainerAtlas = this; + dst_font->ConfigData = &cfg; + dst_font->ConfigDataCount = 0; + dst_font->FontSize = cfg.SizePixels; + dst_font->Ascent = ascent; + dst_font->Descent = descent; + dst_font->Glyphs.resize(0); + } + dst_font->ConfigDataCount++; + float off_y = (cfg.MergeMode && cfg.MergeGlyphCenterV) ? (ascent - dst_font->Ascent) * 0.5f : 0.0f; + + dst_font->FallbackGlyph = NULL; // Always clear fallback so FindGlyph can return NULL. It will be set again in BuildLookupTable() + for (int i = 0; i < tmp.RangesCount; i++) + { + stbtt_pack_range& range = tmp.Ranges[i]; + for (int char_idx = 0; char_idx < range.num_chars; char_idx += 1) + { + const stbtt_packedchar& pc = range.chardata_for_range[char_idx]; + if (!pc.x0 && !pc.x1 && !pc.y0 && !pc.y1) + continue; + + const int codepoint = range.first_unicode_codepoint_in_range + char_idx; + if (cfg.MergeMode && dst_font->FindGlyph((unsigned short)codepoint)) + continue; + + stbtt_aligned_quad q; + float dummy_x = 0.0f, dummy_y = 0.0f; + stbtt_GetPackedQuad(range.chardata_for_range, TexWidth, TexHeight, char_idx, &dummy_x, &dummy_y, &q, 0); + + dst_font->Glyphs.resize(dst_font->Glyphs.Size + 1); + ImFont::Glyph& glyph = dst_font->Glyphs.back(); + glyph.Codepoint = (ImWchar)codepoint; + glyph.X0 = q.x0; glyph.Y0 = q.y0; glyph.X1 = q.x1; glyph.Y1 = q.y1; + glyph.U0 = q.s0; glyph.V0 = q.t0; glyph.U1 = q.s1; glyph.V1 = q.t1; + glyph.Y0 += (float)(int)(dst_font->Ascent + off_y + 0.5f); + glyph.Y1 += (float)(int)(dst_font->Ascent + off_y + 0.5f); + glyph.XAdvance = (pc.xadvance + cfg.GlyphExtraSpacing.x); // Bake spacing into XAdvance + if (cfg.PixelSnapH) + glyph.XAdvance = (float)(int)(glyph.XAdvance + 0.5f); + } + } + cfg.DstFont->BuildLookupTable(); + } + + // Cleanup temporaries + ImGui::MemFree(buf_packedchars); + ImGui::MemFree(buf_ranges); + ImGui::MemFree(tmp_array); + + // Render into our custom data block + RenderCustomTexData(1, &extra_rects); + + return true; +} + +void ImFontAtlas::RenderCustomTexData(int pass, void* p_rects) +{ + // A work of art lies ahead! (. = white layer, X = black layer, others are blank) + // The white texels on the top left are the ones we'll use everywhere in ImGui to render filled shapes. + const int TEX_DATA_W = 90; + const int TEX_DATA_H = 27; + const char texture_data[TEX_DATA_W*TEX_DATA_H+1] = + { + "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX" + "..- -X.....X- X.X - X.X -X.....X - X.....X" + "--- -XXX.XXX- X...X - X...X -X....X - X....X" + "X - X.X - X.....X - X.....X -X...X - X...X" + "XX - X.X -X.......X- X.......X -X..X.X - X.X..X" + "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X" + "X..X - X.X - X.X - X.X -XX X.X - X.X XX" + "X...X - X.X - X.X - XX X.X XX - X.X - X.X " + "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X " + "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X " + "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X " + "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X " + "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X " + "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X " + "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X " + "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X " + "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX " + "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------" + "X.X X..X - -X.......X- X.......X - XX XX - " + "XX X..X - - X.....X - X.....X - X.X X.X - " + " X..X - X...X - X...X - X..X X..X - " + " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - " + "------------ - X - X -X.....................X- " + " ----------------------------------- X...XXXXXXXXXXXXX...X - " + " - X..X X..X - " + " - X.X X.X - " + " - XX XX - " + }; + + ImVector& rects = *(ImVector*)p_rects; + if (pass == 0) + { + // Request rectangles + stbrp_rect r; + memset(&r, 0, sizeof(r)); + r.w = (TEX_DATA_W*2)+1; + r.h = TEX_DATA_H+1; + rects.push_back(r); + } + else if (pass == 1) + { + // Render/copy pixels + const stbrp_rect& r = rects[0]; + for (int y = 0, n = 0; y < TEX_DATA_H; y++) + for (int x = 0; x < TEX_DATA_W; x++, n++) + { + const int offset0 = (int)(r.x + x) + (int)(r.y + y) * TexWidth; + const int offset1 = offset0 + 1 + TEX_DATA_W; + TexPixelsAlpha8[offset0] = texture_data[n] == '.' ? 0xFF : 0x00; + TexPixelsAlpha8[offset1] = texture_data[n] == 'X' ? 0xFF : 0x00; + } + const ImVec2 tex_uv_scale(1.0f / TexWidth, 1.0f / TexHeight); + TexUvWhitePixel = ImVec2((r.x + 0.5f) * tex_uv_scale.x, (r.y + 0.5f) * tex_uv_scale.y); + + // Setup mouse cursors + const ImVec2 cursor_datas[ImGuiMouseCursor_Count_][3] = + { + // Pos ........ Size ......... Offset ...... + { ImVec2(0,3), ImVec2(12,19), ImVec2( 0, 0) }, // ImGuiMouseCursor_Arrow + { ImVec2(13,0), ImVec2(7,16), ImVec2( 4, 8) }, // ImGuiMouseCursor_TextInput + { ImVec2(31,0), ImVec2(23,23), ImVec2(11,11) }, // ImGuiMouseCursor_Move + { ImVec2(21,0), ImVec2( 9,23), ImVec2( 5,11) }, // ImGuiMouseCursor_ResizeNS + { ImVec2(55,18),ImVec2(23, 9), ImVec2(11, 5) }, // ImGuiMouseCursor_ResizeEW + { ImVec2(73,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNESW + { ImVec2(55,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNWSE + }; + + for (int type = 0; type < ImGuiMouseCursor_Count_; type++) + { + ImGuiMouseCursorData& cursor_data = GImGui->MouseCursorData[type]; + ImVec2 pos = cursor_datas[type][0] + ImVec2((float)r.x, (float)r.y); + const ImVec2 size = cursor_datas[type][1]; + cursor_data.Type = type; + cursor_data.Size = size; + cursor_data.HotOffset = cursor_datas[type][2]; + cursor_data.TexUvMin[0] = (pos) * tex_uv_scale; + cursor_data.TexUvMax[0] = (pos + size) * tex_uv_scale; + pos.x += TEX_DATA_W+1; + cursor_data.TexUvMin[1] = (pos) * tex_uv_scale; + cursor_data.TexUvMax[1] = (pos + size) * tex_uv_scale; + } + } +} + +// Retrieve list of range (2 int per range, values are inclusive) +const ImWchar* ImFontAtlas::GetGlyphRangesDefault() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0, + }; + return &ranges[0]; +} + +const ImWchar* ImFontAtlas::GetGlyphRangesKorean() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x3131, 0x3163, // Korean alphabets + 0xAC00, 0xD79D, // Korean characters + 0, + }; + return &ranges[0]; +} + +const ImWchar* ImFontAtlas::GetGlyphRangesChinese() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x3000, 0x30FF, // Punctuations, Hiragana, Katakana + 0x31F0, 0x31FF, // Katakana Phonetic Extensions + 0xFF00, 0xFFEF, // Half-width characters + 0x4e00, 0x9FAF, // CJK Ideograms + 0, + }; + return &ranges[0]; +} + +const ImWchar* ImFontAtlas::GetGlyphRangesJapanese() +{ + // Store the 1946 ideograms code points as successive offsets from the initial unicode codepoint 0x4E00. Each offset has an implicit +1. + // This encoding helps us reduce the source code size. + static const short offsets_from_0x4E00[] = + { + -1,0,1,3,0,0,0,0,1,0,5,1,1,0,7,4,6,10,0,1,9,9,7,1,3,19,1,10,7,1,0,1,0,5,1,0,6,4,2,6,0,0,12,6,8,0,3,5,0,1,0,9,0,0,8,1,1,3,4,5,13,0,0,8,2,17, + 4,3,1,1,9,6,0,0,0,2,1,3,2,22,1,9,11,1,13,1,3,12,0,5,9,2,0,6,12,5,3,12,4,1,2,16,1,1,4,6,5,3,0,6,13,15,5,12,8,14,0,0,6,15,3,6,0,18,8,1,6,14,1, + 5,4,12,24,3,13,12,10,24,0,0,0,1,0,1,1,2,9,10,2,2,0,0,3,3,1,0,3,8,0,3,2,4,4,1,6,11,10,14,6,15,3,4,15,1,0,0,5,2,2,0,0,1,6,5,5,6,0,3,6,5,0,0,1,0, + 11,2,2,8,4,7,0,10,0,1,2,17,19,3,0,2,5,0,6,2,4,4,6,1,1,11,2,0,3,1,2,1,2,10,7,6,3,16,0,8,24,0,0,3,1,1,3,0,1,6,0,0,0,2,0,1,5,15,0,1,0,0,2,11,19, + 1,4,19,7,6,5,1,0,0,0,0,5,1,0,1,9,0,0,5,0,2,0,1,0,3,0,11,3,0,2,0,0,0,0,0,9,3,6,4,12,0,14,0,0,29,10,8,0,14,37,13,0,31,16,19,0,8,30,1,20,8,3,48, + 21,1,0,12,0,10,44,34,42,54,11,18,82,0,2,1,2,12,1,0,6,2,17,2,12,7,0,7,17,4,2,6,24,23,8,23,39,2,16,23,1,0,5,1,2,15,14,5,6,2,11,0,8,6,2,2,2,14, + 20,4,15,3,4,11,10,10,2,5,2,1,30,2,1,0,0,22,5,5,0,3,1,5,4,1,0,0,2,2,21,1,5,1,2,16,2,1,3,4,0,8,4,0,0,5,14,11,2,16,1,13,1,7,0,22,15,3,1,22,7,14, + 22,19,11,24,18,46,10,20,64,45,3,2,0,4,5,0,1,4,25,1,0,0,2,10,0,0,0,1,0,1,2,0,0,9,1,2,0,0,0,2,5,2,1,1,5,5,8,1,1,1,5,1,4,9,1,3,0,1,0,1,1,2,0,0, + 2,0,1,8,22,8,1,0,0,0,0,4,2,1,0,9,8,5,0,9,1,30,24,2,6,4,39,0,14,5,16,6,26,179,0,2,1,1,0,0,0,5,2,9,6,0,2,5,16,7,5,1,1,0,2,4,4,7,15,13,14,0,0, + 3,0,1,0,0,0,2,1,6,4,5,1,4,9,0,3,1,8,0,0,10,5,0,43,0,2,6,8,4,0,2,0,0,9,6,0,9,3,1,6,20,14,6,1,4,0,7,2,3,0,2,0,5,0,3,1,0,3,9,7,0,3,4,0,4,9,1,6,0, + 9,0,0,2,3,10,9,28,3,6,2,4,1,2,32,4,1,18,2,0,3,1,5,30,10,0,2,2,2,0,7,9,8,11,10,11,7,2,13,7,5,10,0,3,40,2,0,1,6,12,0,4,5,1,5,11,11,21,4,8,3,7, + 8,8,33,5,23,0,0,19,8,8,2,3,0,6,1,1,1,5,1,27,4,2,5,0,3,5,6,3,1,0,3,1,12,5,3,3,2,0,7,7,2,1,0,4,0,1,1,2,0,10,10,6,2,5,9,7,5,15,15,21,6,11,5,20, + 4,3,5,5,2,5,0,2,1,0,1,7,28,0,9,0,5,12,5,5,18,30,0,12,3,3,21,16,25,32,9,3,14,11,24,5,66,9,1,2,0,5,9,1,5,1,8,0,8,3,3,0,1,15,1,4,8,1,2,7,0,7,2, + 8,3,7,5,3,7,10,2,1,0,0,2,25,0,6,4,0,10,0,4,2,4,1,12,5,38,4,0,4,1,10,5,9,4,0,14,4,2,5,18,20,21,1,3,0,5,0,7,0,3,7,1,3,1,1,8,1,0,0,0,3,2,5,2,11, + 6,0,13,1,3,9,1,12,0,16,6,2,1,0,2,1,12,6,13,11,2,0,28,1,7,8,14,13,8,13,0,2,0,5,4,8,10,2,37,42,19,6,6,7,4,14,11,18,14,80,7,6,0,4,72,12,36,27, + 7,7,0,14,17,19,164,27,0,5,10,7,3,13,6,14,0,2,2,5,3,0,6,13,0,0,10,29,0,4,0,3,13,0,3,1,6,51,1,5,28,2,0,8,0,20,2,4,0,25,2,10,13,10,0,16,4,0,1,0, + 2,1,7,0,1,8,11,0,0,1,2,7,2,23,11,6,6,4,16,2,2,2,0,22,9,3,3,5,2,0,15,16,21,2,9,20,15,15,5,3,9,1,0,0,1,7,7,5,4,2,2,2,38,24,14,0,0,15,5,6,24,14, + 5,5,11,0,21,12,0,3,8,4,11,1,8,0,11,27,7,2,4,9,21,59,0,1,39,3,60,62,3,0,12,11,0,3,30,11,0,13,88,4,15,5,28,13,1,4,48,17,17,4,28,32,46,0,16,0, + 18,11,1,8,6,38,11,2,6,11,38,2,0,45,3,11,2,7,8,4,30,14,17,2,1,1,65,18,12,16,4,2,45,123,12,56,33,1,4,3,4,7,0,0,0,3,2,0,16,4,2,4,2,0,7,4,5,2,26, + 2,25,6,11,6,1,16,2,6,17,77,15,3,35,0,1,0,5,1,0,38,16,6,3,12,3,3,3,0,9,3,1,3,5,2,9,0,18,0,25,1,3,32,1,72,46,6,2,7,1,3,14,17,0,28,1,40,13,0,20, + 15,40,6,38,24,12,43,1,1,9,0,12,6,0,6,2,4,19,3,7,1,48,0,9,5,0,5,6,9,6,10,15,2,11,19,3,9,2,0,1,10,1,27,8,1,3,6,1,14,0,26,0,27,16,3,4,9,6,2,23, + 9,10,5,25,2,1,6,1,1,48,15,9,15,14,3,4,26,60,29,13,37,21,1,6,4,0,2,11,22,23,16,16,2,2,1,3,0,5,1,6,4,0,0,4,0,0,8,3,0,2,5,0,7,1,7,3,13,2,4,10, + 3,0,2,31,0,18,3,0,12,10,4,1,0,7,5,7,0,5,4,12,2,22,10,4,2,15,2,8,9,0,23,2,197,51,3,1,1,4,13,4,3,21,4,19,3,10,5,40,0,4,1,1,10,4,1,27,34,7,21, + 2,17,2,9,6,4,2,3,0,4,2,7,8,2,5,1,15,21,3,4,4,2,2,17,22,1,5,22,4,26,7,0,32,1,11,42,15,4,1,2,5,0,19,3,1,8,6,0,10,1,9,2,13,30,8,2,24,17,19,1,4, + 4,25,13,0,10,16,11,39,18,8,5,30,82,1,6,8,18,77,11,13,20,75,11,112,78,33,3,0,0,60,17,84,9,1,1,12,30,10,49,5,32,158,178,5,5,6,3,3,1,3,1,4,7,6, + 19,31,21,0,2,9,5,6,27,4,9,8,1,76,18,12,1,4,0,3,3,6,3,12,2,8,30,16,2,25,1,5,5,4,3,0,6,10,2,3,1,0,5,1,19,3,0,8,1,5,2,6,0,0,0,19,1,2,0,5,1,2,5, + 1,3,7,0,4,12,7,3,10,22,0,9,5,1,0,2,20,1,1,3,23,30,3,9,9,1,4,191,14,3,15,6,8,50,0,1,0,0,4,0,0,1,0,2,4,2,0,2,3,0,2,0,2,2,8,7,0,1,1,1,3,3,17,11, + 91,1,9,3,2,13,4,24,15,41,3,13,3,1,20,4,125,29,30,1,0,4,12,2,21,4,5,5,19,11,0,13,11,86,2,18,0,7,1,8,8,2,2,22,1,2,6,5,2,0,1,2,8,0,2,0,5,2,1,0, + 2,10,2,0,5,9,2,1,2,0,1,0,4,0,0,10,2,5,3,0,6,1,0,1,4,4,33,3,13,17,3,18,6,4,7,1,5,78,0,4,1,13,7,1,8,1,0,35,27,15,3,0,0,0,1,11,5,41,38,15,22,6, + 14,14,2,1,11,6,20,63,5,8,27,7,11,2,2,40,58,23,50,54,56,293,8,8,1,5,1,14,0,1,12,37,89,8,8,8,2,10,6,0,0,0,4,5,2,1,0,1,1,2,7,0,3,3,0,4,6,0,3,2, + 19,3,8,0,0,0,4,4,16,0,4,1,5,1,3,0,3,4,6,2,17,10,10,31,6,4,3,6,10,126,7,3,2,2,0,9,0,0,5,20,13,0,15,0,6,0,2,5,8,64,50,3,2,12,2,9,0,0,11,8,20, + 109,2,18,23,0,0,9,61,3,0,28,41,77,27,19,17,81,5,2,14,5,83,57,252,14,154,263,14,20,8,13,6,57,39,38, + }; + static ImWchar base_ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x3000, 0x30FF, // Punctuations, Hiragana, Katakana + 0x31F0, 0x31FF, // Katakana Phonetic Extensions + 0xFF00, 0xFFEF, // Half-width characters + }; + static bool full_ranges_unpacked = false; + static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(offsets_from_0x4E00)*2 + 1]; + if (!full_ranges_unpacked) + { + // Unpack + int codepoint = 0x4e00; + memcpy(full_ranges, base_ranges, sizeof(base_ranges)); + ImWchar* dst = full_ranges + IM_ARRAYSIZE(base_ranges);; + for (int n = 0; n < IM_ARRAYSIZE(offsets_from_0x4E00); n++, dst += 2) + dst[0] = dst[1] = (ImWchar)(codepoint += (offsets_from_0x4E00[n] + 1)); + dst[0] = 0; + full_ranges_unpacked = true; + } + return &full_ranges[0]; +} + +const ImWchar* ImFontAtlas::GetGlyphRangesCyrillic() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x0400, 0x052F, // Cyrillic + Cyrillic Supplement + 0x2DE0, 0x2DFF, // Cyrillic Extended-A + 0xA640, 0xA69F, // Cyrillic Extended-B + 0, + }; + return &ranges[0]; +} + +const ImWchar* ImFontAtlas::GetGlyphRangesThai() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + 0x0E00, 0x0E7F, // Thai + 0, + }; + return &ranges[0]; +} + +//----------------------------------------------------------------------------- +// ImFont +//----------------------------------------------------------------------------- + +ImFont::ImFont() +{ + Scale = 1.0f; + FallbackChar = (ImWchar)'?'; + Clear(); +} + +ImFont::~ImFont() +{ + // Invalidate active font so that the user gets a clear crash instead of a dangling pointer. + // If you want to delete fonts you need to do it between Render() and NewFrame(). + // FIXME-CLEANUP + /* + ImGuiContext& g = *GImGui; + if (g.Font == this) + g.Font = NULL; + */ + Clear(); +} + +void ImFont::Clear() +{ + FontSize = 0.0f; + DisplayOffset = ImVec2(0.0f, 1.0f); + ConfigData = NULL; + ConfigDataCount = 0; + Ascent = Descent = 0.0f; + ContainerAtlas = NULL; + Glyphs.clear(); + FallbackGlyph = NULL; + FallbackXAdvance = 0.0f; + IndexXAdvance.clear(); + IndexLookup.clear(); +} + +void ImFont::BuildLookupTable() +{ + int max_codepoint = 0; + for (int i = 0; i != Glyphs.Size; i++) + max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint); + + IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved + IndexXAdvance.clear(); + IndexLookup.clear(); + GrowIndex(max_codepoint + 1); + for (int i = 0; i < Glyphs.Size; i++) + { + int codepoint = (int)Glyphs[i].Codepoint; + IndexXAdvance[codepoint] = Glyphs[i].XAdvance; + IndexLookup[codepoint] = (unsigned short)i; + } + + // Create a glyph to handle TAB + // FIXME: Needs proper TAB handling but it needs to be contextualized (or we could arbitrary say that each string starts at "column 0" ?) + if (FindGlyph((unsigned short)' ')) + { + if (Glyphs.back().Codepoint != '\t') // So we can call this function multiple times + Glyphs.resize(Glyphs.Size + 1); + ImFont::Glyph& tab_glyph = Glyphs.back(); + tab_glyph = *FindGlyph((unsigned short)' '); + tab_glyph.Codepoint = '\t'; + tab_glyph.XAdvance *= 4; + IndexXAdvance[(int)tab_glyph.Codepoint] = (float)tab_glyph.XAdvance; + IndexLookup[(int)tab_glyph.Codepoint] = (unsigned short)(Glyphs.Size-1); + } + + FallbackGlyph = NULL; + FallbackGlyph = FindGlyph(FallbackChar); + FallbackXAdvance = FallbackGlyph ? FallbackGlyph->XAdvance : 0.0f; + for (int i = 0; i < max_codepoint + 1; i++) + if (IndexXAdvance[i] < 0.0f) + IndexXAdvance[i] = FallbackXAdvance; +} + +void ImFont::SetFallbackChar(ImWchar c) +{ + FallbackChar = c; + BuildLookupTable(); +} + +void ImFont::GrowIndex(int new_size) +{ + IM_ASSERT(IndexXAdvance.Size == IndexLookup.Size); + int old_size = IndexLookup.Size; + if (new_size <= old_size) + return; + IndexXAdvance.resize(new_size); + IndexLookup.resize(new_size); + for (int i = old_size; i < new_size; i++) + { + IndexXAdvance[i] = -1.0f; + IndexLookup[i] = (unsigned short)-1; + } +} + +void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst) +{ + IM_ASSERT(IndexLookup.Size > 0); // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function. + int index_size = IndexLookup.Size; + + if (dst < index_size && IndexLookup.Data[dst] == (unsigned short)-1 && !overwrite_dst) // 'dst' already exists + return; + if (src >= index_size && dst >= index_size) // both 'dst' and 'src' don't exist -> no-op + return; + + GrowIndex(dst + 1); + IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (unsigned short)-1; + IndexXAdvance[dst] = (src < index_size) ? IndexXAdvance.Data[src] : 1.0f; +} + +const ImFont::Glyph* ImFont::FindGlyph(unsigned short c) const +{ + if (c < IndexLookup.Size) + { + const unsigned short i = IndexLookup[c]; + if (i != (unsigned short)-1) + return &Glyphs.Data[i]; + } + return FallbackGlyph; +} + +const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const +{ + // Simple word-wrapping for English, not full-featured. Please submit failing cases! + // FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.) + + // For references, possible wrap point marked with ^ + // "aaa bbb, ccc,ddd. eee fff. ggg!" + // ^ ^ ^ ^ ^__ ^ ^ + + // List of hardcoded separators: .,;!?'" + + // Skip extra blanks after a line returns (that includes not counting them in width computation) + // e.g. "Hello world" --> "Hello" "World" + + // Cut words that cannot possibly fit within one line. + // e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish" + + float line_width = 0.0f; + float word_width = 0.0f; + float blank_width = 0.0f; + + const char* word_end = text; + const char* prev_word_end = NULL; + bool inside_word = true; + + const char* s = text; + while (s < text_end) + { + unsigned int c = (unsigned int)*s; + const char* next_s; + if (c < 0x80) + next_s = s + 1; + else + next_s = s + ImTextCharFromUtf8(&c, s, text_end); + if (c == 0) + break; + + if (c < 32) + { + if (c == '\n') + { + line_width = word_width = blank_width = 0.0f; + inside_word = true; + s = next_s; + continue; + } + if (c == '\r') + { + s = next_s; + continue; + } + } + + const float char_width = ((int)c < IndexXAdvance.Size) ? IndexXAdvance[(int)c] * scale : FallbackXAdvance; + if (ImCharIsSpace(c)) + { + if (inside_word) + { + line_width += blank_width; + blank_width = 0.0f; + } + blank_width += char_width; + inside_word = false; + } + else + { + word_width += char_width; + if (inside_word) + { + word_end = next_s; + } + else + { + prev_word_end = word_end; + line_width += word_width + blank_width; + word_width = blank_width = 0.0f; + } + + // Allow wrapping after punctuation. + inside_word = !(c == '.' || c == ',' || c == ';' || c == '!' || c == '?' || c == '\"'); + } + + // We ignore blank width at the end of the line (they can be skipped) + if (line_width + word_width >= wrap_width) + { + // Words that cannot possibly fit within an entire line will be cut anywhere. + if (word_width < wrap_width) + s = prev_word_end ? prev_word_end : word_end; + break; + } + + s = next_s; + } + + return s; +} + +ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) const +{ + if (!text_end) + text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this. + + const float line_height = size; + const float scale = size / FontSize; + + ImVec2 text_size = ImVec2(0,0); + float line_width = 0.0f; + + const bool word_wrap_enabled = (wrap_width > 0.0f); + const char* word_wrap_eol = NULL; + + const char* s = text_begin; + while (s < text_end) + { + if (word_wrap_enabled) + { + // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. + if (!word_wrap_eol) + { + word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - line_width); + if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. + word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below + } + + if (s >= word_wrap_eol) + { + if (text_size.x < line_width) + text_size.x = line_width; + text_size.y += line_height; + line_width = 0.0f; + word_wrap_eol = NULL; + + // Wrapping skips upcoming blanks + while (s < text_end) + { + const char c = *s; + if (ImCharIsSpace(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } + } + continue; + } + } + + // Decode and advance source + const char* prev_s = s; + unsigned int c = (unsigned int)*s; + if (c < 0x80) + { + s += 1; + } + else + { + s += ImTextCharFromUtf8(&c, s, text_end); + if (c == 0) + break; + } + + if (c < 32) + { + if (c == '\n') + { + text_size.x = ImMax(text_size.x, line_width); + text_size.y += line_height; + line_width = 0.0f; + continue; + } + if (c == '\r') + continue; + } + + const float char_width = ((int)c < IndexXAdvance.Size ? IndexXAdvance[(int)c] : FallbackXAdvance) * scale; + if (line_width + char_width >= max_width) + { + s = prev_s; + break; + } + + line_width += char_width; + } + + if (text_size.x < line_width) + text_size.x = line_width; + + if (line_width > 0 || text_size.y == 0.0f) + text_size.y += line_height; + + if (remaining) + *remaining = s; + + return text_size; +} + +void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const +{ + if (c == ' ' || c == '\t' || c == '\n' || c == '\r') // Match behavior of RenderText(), those 4 codepoints are hard-coded. + return; + if (const Glyph* glyph = FindGlyph(c)) + { + float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; + pos.x = (float)(int)pos.x + DisplayOffset.x; + pos.y = (float)(int)pos.y + DisplayOffset.y; + ImVec2 pos_tl(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale); + ImVec2 pos_br(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale); + draw_list->PrimReserve(6, 4); + draw_list->PrimRectUV(pos_tl, pos_br, ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); + } +} + +void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const +{ + if (!text_end) + text_end = text_begin + strlen(text_begin); + + // Align to be pixel perfect + pos.x = (float)(int)pos.x + DisplayOffset.x; + pos.y = (float)(int)pos.y + DisplayOffset.y; + float x = pos.x; + float y = pos.y; + if (y > clip_rect.w) + return; + + const float scale = size / FontSize; + const float line_height = FontSize * scale; + const bool word_wrap_enabled = (wrap_width > 0.0f); + const char* word_wrap_eol = NULL; + + // Skip non-visible lines + const char* s = text_begin; + if (!word_wrap_enabled && y + line_height < clip_rect.y) + while (s < text_end && *s != '\n') // Fast-forward to next line + s++; + + // Reserve vertices for remaining worse case (over-reserving is useful and easily amortized) + const int vtx_count_max = (int)(text_end - s) * 4; + const int idx_count_max = (int)(text_end - s) * 6; + const int idx_expected_size = draw_list->IdxBuffer.Size + idx_count_max; + draw_list->PrimReserve(idx_count_max, vtx_count_max); + + ImDrawVert* vtx_write = draw_list->_VtxWritePtr; + ImDrawIdx* idx_write = draw_list->_IdxWritePtr; + unsigned int vtx_current_idx = draw_list->_VtxCurrentIdx; + + while (s < text_end) + { + if (word_wrap_enabled) + { + // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. + if (!word_wrap_eol) + { + word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - pos.x)); + if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. + word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below + } + + if (s >= word_wrap_eol) + { + x = pos.x; + y += line_height; + word_wrap_eol = NULL; + + // Wrapping skips upcoming blanks + while (s < text_end) + { + const char c = *s; + if (ImCharIsSpace(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } + } + continue; + } + } + + // Decode and advance source + unsigned int c = (unsigned int)*s; + if (c < 0x80) + { + s += 1; + } + else + { + s += ImTextCharFromUtf8(&c, s, text_end); + if (c == 0) + break; + } + + if (c < 32) + { + if (c == '\n') + { + x = pos.x; + y += line_height; + + if (y > clip_rect.w) + break; + if (!word_wrap_enabled && y + line_height < clip_rect.y) + while (s < text_end && *s != '\n') // Fast-forward to next line + s++; + continue; + } + if (c == '\r') + continue; + } + + float char_width = 0.0f; + if (const Glyph* glyph = FindGlyph((unsigned short)c)) + { + char_width = glyph->XAdvance * scale; + + // Arbitrarily assume that both space and tabs are empty glyphs as an optimization + if (c != ' ' && c != '\t') + { + // We don't do a second finer clipping test on the Y axis as we've already skipped anything before clip_rect.y and exit once we pass clip_rect.w + float x1 = x + glyph->X0 * scale; + float x2 = x + glyph->X1 * scale; + float y1 = y + glyph->Y0 * scale; + float y2 = y + glyph->Y1 * scale; + if (x1 <= clip_rect.z && x2 >= clip_rect.x) + { + // Render a character + float u1 = glyph->U0; + float v1 = glyph->V0; + float u2 = glyph->U1; + float v2 = glyph->V1; + + // CPU side clipping used to fit text in their frame when the frame is too small. Only does clipping for axis aligned quads. + if (cpu_fine_clip) + { + if (x1 < clip_rect.x) + { + u1 = u1 + (1.0f - (x2 - clip_rect.x) / (x2 - x1)) * (u2 - u1); + x1 = clip_rect.x; + } + if (y1 < clip_rect.y) + { + v1 = v1 + (1.0f - (y2 - clip_rect.y) / (y2 - y1)) * (v2 - v1); + y1 = clip_rect.y; + } + if (x2 > clip_rect.z) + { + u2 = u1 + ((clip_rect.z - x1) / (x2 - x1)) * (u2 - u1); + x2 = clip_rect.z; + } + if (y2 > clip_rect.w) + { + v2 = v1 + ((clip_rect.w - y1) / (y2 - y1)) * (v2 - v1); + y2 = clip_rect.w; + } + if (y1 >= y2) + { + x += char_width; + continue; + } + } + + // We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug build. + // Inlined here: + { + idx_write[0] = (ImDrawIdx)(vtx_current_idx); idx_write[1] = (ImDrawIdx)(vtx_current_idx+1); idx_write[2] = (ImDrawIdx)(vtx_current_idx+2); + idx_write[3] = (ImDrawIdx)(vtx_current_idx); idx_write[4] = (ImDrawIdx)(vtx_current_idx+2); idx_write[5] = (ImDrawIdx)(vtx_current_idx+3); + vtx_write[0].pos.x = x1; vtx_write[0].pos.y = y1; vtx_write[0].col = col; vtx_write[0].uv.x = u1; vtx_write[0].uv.y = v1; + vtx_write[1].pos.x = x2; vtx_write[1].pos.y = y1; vtx_write[1].col = col; vtx_write[1].uv.x = u2; vtx_write[1].uv.y = v1; + vtx_write[2].pos.x = x2; vtx_write[2].pos.y = y2; vtx_write[2].col = col; vtx_write[2].uv.x = u2; vtx_write[2].uv.y = v2; + vtx_write[3].pos.x = x1; vtx_write[3].pos.y = y2; vtx_write[3].col = col; vtx_write[3].uv.x = u1; vtx_write[3].uv.y = v2; + vtx_write += 4; + vtx_current_idx += 4; + idx_write += 6; + } + } + } + } + + x += char_width; + } + + // Give back unused vertices + draw_list->VtxBuffer.resize((int)(vtx_write - draw_list->VtxBuffer.Data)); + draw_list->IdxBuffer.resize((int)(idx_write - draw_list->IdxBuffer.Data)); + draw_list->CmdBuffer[draw_list->CmdBuffer.Size-1].ElemCount -= (idx_expected_size - draw_list->IdxBuffer.Size); + draw_list->_VtxWritePtr = vtx_write; + draw_list->_IdxWritePtr = idx_write; + draw_list->_VtxCurrentIdx = (unsigned int)draw_list->VtxBuffer.Size; +} + +//----------------------------------------------------------------------------- +// DEFAULT FONT DATA +//----------------------------------------------------------------------------- +// Compressed with stb_compress() then converted to a C array. +// Use the program in extra_fonts/binary_to_compressed_c.cpp to create the array from a TTF file. +// Decompression from stb.h (public domain) by Sean Barrett https://github.com/nothings/stb/blob/master/stb.h +//----------------------------------------------------------------------------- + +static unsigned int stb_decompress_length(unsigned char *input) +{ + return (input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]; +} + +static unsigned char *stb__barrier, *stb__barrier2, *stb__barrier3, *stb__barrier4; +static unsigned char *stb__dout; +static void stb__match(unsigned char *data, unsigned int length) +{ + // INVERSE of memmove... write each byte before copying the next... + IM_ASSERT (stb__dout + length <= stb__barrier); + if (stb__dout + length > stb__barrier) { stb__dout += length; return; } + if (data < stb__barrier4) { stb__dout = stb__barrier+1; return; } + while (length--) *stb__dout++ = *data++; +} + +static void stb__lit(unsigned char *data, unsigned int length) +{ + IM_ASSERT (stb__dout + length <= stb__barrier); + if (stb__dout + length > stb__barrier) { stb__dout += length; return; } + if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; } + memcpy(stb__dout, data, length); + stb__dout += length; +} + +#define stb__in2(x) ((i[x] << 8) + i[(x)+1]) +#define stb__in3(x) ((i[x] << 16) + stb__in2((x)+1)) +#define stb__in4(x) ((i[x] << 24) + stb__in3((x)+1)) + +static unsigned char *stb_decompress_token(unsigned char *i) +{ + if (*i >= 0x20) { // use fewer if's for cases that expand small + if (*i >= 0x80) stb__match(stb__dout-i[1]-1, i[0] - 0x80 + 1), i += 2; + else if (*i >= 0x40) stb__match(stb__dout-(stb__in2(0) - 0x4000 + 1), i[2]+1), i += 3; + else /* *i >= 0x20 */ stb__lit(i+1, i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1); + } else { // more ifs for cases that expand large, since overhead is amortized + if (*i >= 0x18) stb__match(stb__dout-(stb__in3(0) - 0x180000 + 1), i[3]+1), i += 4; + else if (*i >= 0x10) stb__match(stb__dout-(stb__in3(0) - 0x100000 + 1), stb__in2(3)+1), i += 5; + else if (*i >= 0x08) stb__lit(i+2, stb__in2(0) - 0x0800 + 1), i += 2 + (stb__in2(0) - 0x0800 + 1); + else if (*i == 0x07) stb__lit(i+3, stb__in2(1) + 1), i += 3 + (stb__in2(1) + 1); + else if (*i == 0x06) stb__match(stb__dout-(stb__in3(1)+1), i[4]+1), i += 5; + else if (*i == 0x04) stb__match(stb__dout-(stb__in3(1)+1), stb__in2(4)+1), i += 6; + } + return i; +} + +static unsigned int stb_adler32(unsigned int adler32, unsigned char *buffer, unsigned int buflen) +{ + const unsigned long ADLER_MOD = 65521; + unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16; + unsigned long blocklen, i; + + blocklen = buflen % 5552; + while (buflen) { + for (i=0; i + 7 < blocklen; i += 8) { + s1 += buffer[0], s2 += s1; + s1 += buffer[1], s2 += s1; + s1 += buffer[2], s2 += s1; + s1 += buffer[3], s2 += s1; + s1 += buffer[4], s2 += s1; + s1 += buffer[5], s2 += s1; + s1 += buffer[6], s2 += s1; + s1 += buffer[7], s2 += s1; + + buffer += 8; + } + + for (; i < blocklen; ++i) + s1 += *buffer++, s2 += s1; + + s1 %= ADLER_MOD, s2 %= ADLER_MOD; + buflen -= blocklen; + blocklen = 5552; + } + return (unsigned int)(s2 << 16) + (unsigned int)s1; +} + +static unsigned int stb_decompress(unsigned char *output, unsigned char *i, unsigned int length) +{ + unsigned int olen; + if (stb__in4(0) != 0x57bC0000) return 0; + if (stb__in4(4) != 0) return 0; // error! stream is > 4GB + olen = stb_decompress_length(i); + stb__barrier2 = i; + stb__barrier3 = i+length; + stb__barrier = output + olen; + stb__barrier4 = output; + i += 16; + + stb__dout = output; + for (;;) { + unsigned char *old_i = i; + i = stb_decompress_token(i); + if (i == old_i) { + if (*i == 0x05 && i[1] == 0xfa) { + IM_ASSERT(stb__dout == output + olen); + if (stb__dout != output + olen) return 0; + if (stb_adler32(1, output, olen) != (unsigned int) stb__in4(2)) + return 0; + return olen; + } else { + IM_ASSERT(0); /* NOTREACHED */ + return 0; + } + } + IM_ASSERT(stb__dout <= output + olen); + if (stb__dout > output + olen) + return 0; + } +} + +//----------------------------------------------------------------------------- +// ProggyClean.ttf +// Copyright (c) 2004, 2005 Tristan Grimmer +// MIT license (see License.txt in http://www.upperbounds.net/download/ProggyClean.ttf.zip) +// Download and more information at http://upperbounds.net +//----------------------------------------------------------------------------- +// File: 'ProggyClean.ttf' (41208 bytes) +// Exported using binary_to_compressed_c.cpp +//----------------------------------------------------------------------------- +static const char proggy_clean_ttf_compressed_data_base85[11980+1] = + "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/" + "2*>]b(MC;$jPfY.;h^`IWM9Qo#t'X#(v#Y9w0#1D$CIf;W'#pWUPXOuxXuU(H9M(1=Ke$$'5F%)]0^#0X@U.a$FBjVQTSDgEKnIS7EM9>ZY9w0#L;>>#Mx&4Mvt//L[MkA#W@lK.N'[0#7RL_&#w+F%HtG9M#XL`N&.,GM4Pg;--VsM.M0rJfLH2eTM`*oJMHRC`N" + "kfimM2J,W-jXS:)r0wK#@Fge$U>`w'N7G#$#fB#$E^$#:9:hk+eOe--6x)F7*E%?76%^GMHePW-Z5l'&GiF#$956:rS?dA#fiK:)Yr+`�j@'DbG&#^$PG.Ll+DNa&VZ>1i%h1S9u5o@YaaW$e+bROPOpxTO7Stwi1::iB1q)C_=dV26J;2,]7op$]uQr@_V7$q^%lQwtuHY]=DX,n3L#0PHDO4f9>dC@O>HBuKPpP*E,N+b3L#lpR/MrTEH.IAQk.a>D[.e;mc." + "x]Ip.PH^'/aqUO/$1WxLoW0[iLAw=4h(9.`G" + "CRUxHPeR`5Mjol(dUWxZa(>STrPkrJiWx`5U7F#.g*jrohGg`cg:lSTvEY/EV_7H4Q9[Z%cnv;JQYZ5q.l7Zeas:HOIZOB?Ggv:[7MI2k).'2($5FNP&EQ(,)" + "U]W]+fh18.vsai00);D3@4ku5P?DP8aJt+;qUM]=+b'8@;mViBKx0DE[-auGl8:PJ&Dj+M6OC]O^((##]`0i)drT;-7X`=-H3[igUnPG-NZlo.#k@h#=Ork$m>a>$-?Tm$UV(?#P6YY#" + "'/###xe7q.73rI3*pP/$1>s9)W,JrM7SN]'/4C#v$U`0#V.[0>xQsH$fEmPMgY2u7Kh(G%siIfLSoS+MK2eTM$=5,M8p`A.;_R%#u[K#$x4AG8.kK/HSB==-'Ie/QTtG?-.*^N-4B/ZM" + "_3YlQC7(p7q)&](`6_c)$/*JL(L-^(]$wIM`dPtOdGA,U3:w2M-0+WomX2u7lqM2iEumMTcsF?-aT=Z-97UEnXglEn1K-bnEO`gu" + "Ft(c%=;Am_Qs@jLooI&NX;]0#j4#F14;gl8-GQpgwhrq8'=l_f-b49'UOqkLu7-##oDY2L(te+Mch&gLYtJ,MEtJfLh'x'M=$CS-ZZ%P]8bZ>#S?YY#%Q&q'3^Fw&?D)UDNrocM3A76/" + "/oL?#h7gl85[qW/NDOk%16ij;+:1a'iNIdb-ou8.P*w,v5#EI$TWS>Pot-R*H'-SEpA:g)f+O$%%`kA#G=8RMmG1&O`>to8bC]T&$,n.LoO>29sp3dt-52U%VM#q7'DHpg+#Z9%H[Ket`e;)f#Km8&+DC$I46>#Kr]]u-[=99tts1.qb#q72g1WJO81q+eN'03'eM>&1XxY-caEnO" + "j%2n8)),?ILR5^.Ibn<-X-Mq7[a82Lq:F&#ce+S9wsCK*x`569E8ew'He]h:sI[2LM$[guka3ZRd6:t%IG:;$%YiJ:Nq=?eAw;/:nnDq0(CYcMpG)qLN4$##&J-XTt,%OVU4)S1+R-#dg0/Nn?Ku1^0f$B*P:Rowwm-`0PKjYDDM'3]d39VZHEl4,.j']Pk-M.h^&:0FACm$maq-&sgw0t7/6(^xtk%" + "LuH88Fj-ekm>GA#_>568x6(OFRl-IZp`&b,_P'$MhLbxfc$mj`,O;&%W2m`Zh:/)Uetw:aJ%]K9h:TcF]u_-Sj9,VK3M.*'&0D[Ca]J9gp8,kAW]" + "%(?A%R$f<->Zts'^kn=-^@c4%-pY6qI%J%1IGxfLU9CP8cbPlXv);C=b),<2mOvP8up,UVf3839acAWAW-W?#ao/^#%KYo8fRULNd2.>%m]UK:n%r$'sw]J;5pAoO_#2mO3n,'=H5(et" + "Hg*`+RLgv>=4U8guD$I%D:W>-r5V*%j*W:Kvej.Lp$'?;++O'>()jLR-^u68PHm8ZFWe+ej8h:9r6L*0//c&iH&R8pRbA#Kjm%upV1g:" + "a_#Ur7FuA#(tRh#.Y5K+@?3<-8m0$PEn;J:rh6?I6uG<-`wMU'ircp0LaE_OtlMb&1#6T.#FDKu#1Lw%u%+GM+X'e?YLfjM[VO0MbuFp7;>Q&#WIo)0@F%q7c#4XAXN-U&VBpqB>0ie&jhZ[?iLR@@_AvA-iQC(=ksRZRVp7`.=+NpBC%rh&3]R:8XDmE5^V8O(x<-+k?'(^](H.aREZSi,#1:[IXaZFOm<-ui#qUq2$##Ri;u75OK#(RtaW-K-F`S+cF]uN`-KMQ%rP/Xri.LRcB##=YL3BgM/3M" + "D?@f&1'BW-)Ju#bmmWCMkk&#TR`C,5d>g)F;t,4:@_l8G/5h4vUd%&%950:VXD'QdWoY-F$BtUwmfe$YqL'8(PWX(" + "P?^@Po3$##`MSs?DWBZ/S>+4%>fX,VWv/w'KD`LP5IbH;rTV>n3cEK8U#bX]l-/V+^lj3;vlMb&[5YQ8#pekX9JP3XUC72L,,?+Ni&co7ApnO*5NK,((W-i:$,kp'UDAO(G0Sq7MVjJs" + "bIu)'Z,*[>br5fX^:FPAWr-m2KgLQ_nN6'8uTGT5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q" + "h4CB/5OvmA&,Q&QbUoi$a_%3M01H)4x7I^&KQVgtFnV+;[Pc>[m4k//,]1?#`VY[Jr*3&&slRfLiVZJ:]?=K3Sw=[$=uRB?3xk48@aege0jT6'N#(q%.O=?2S]u*(m<-" + "V8J'(1)G][68hW$5'q[GC&5j`TE?m'esFGNRM)j,ffZ?-qx8;->g4t*:CIP/[Qap7/9'#(1sao7w-.qNUdkJ)tCF&#B^;xGvn2r9FEPFFFcL@.iFNkTve$m%#QvQS8U@)2Z+3K:AKM5i" + "sZ88+dKQ)W6>J%CL`.d*(B`-n8D9oK-XV1q['-5k'cAZ69e;D_?$ZPP&s^+7])$*$#@QYi9,5P r+$%CE=68>K8r0=dSC%%(@p7" + ".m7jilQ02'0-VWAgTlGW'b)Tq7VT9q^*^$$.:&N@@" + "$&)WHtPm*5_rO0&e%K&#-30j(E4#'Zb.o/(Tpm$>K'f@[PvFl,hfINTNU6u'0pao7%XUp9]5.>%h`8_=VYbxuel.NTSsJfLacFu3B'lQSu/m6-Oqem8T+oE--$0a/k]uj9EwsG>%veR*" + "hv^BFpQj:K'#SJ,sB-'#](j.Lg92rTw-*n%@/;39rrJF,l#qV%OrtBeC6/,;qB3ebNW[?,Hqj2L.1NP&GjUR=1D8QaS3Up&@*9wP?+lo7b?@%'k4`p0Z$22%K3+iCZj?XJN4Nm&+YF]u" + "@-W$U%VEQ/,,>>#)D#%8cY#YZ?=,`Wdxu/ae&#" + "w6)R89tI#6@s'(6Bf7a&?S=^ZI_kS&ai`&=tE72L_D,;^R)7[$so8lKN%5/$(vdfq7+ebA#" + "u1p]ovUKW&Y%q]'>$1@-[xfn$7ZTp7mM,G,Ko7a&Gu%G[RMxJs[0MM%wci.LFDK)(%:_i2B5CsR8&9Z&#=mPEnm0f`<&c)QL5uJ#%u%lJj+D-r;BoFDoS97h5g)E#o:&S4weDF,9^Hoe`h*L+_a*NrLW-1pG_&2UdB8" + "6e%B/:=>)N4xeW.*wft-;$'58-ESqr#U`'6AQ]m&6/`Z>#S?YY#Vc;r7U2&326d=w&H####?TZ`*4?&.MK?LP8Vxg>$[QXc%QJv92.(Db*B)gb*BM9dM*hJMAo*c&#" + "b0v=Pjer]$gG&JXDf->'StvU7505l9$AFvgYRI^&<^b68?j#q9QX4SM'RO#&sL1IM.rJfLUAj221]d##DW=m83u5;'bYx,*Sl0hL(W;;$doB&O/TQ:(Z^xBdLjLV#*8U_72Lh+2Q8Cj0i:6hp&$C/:p(HK>T8Y[gHQ4`4)'$Ab(Nof%V'8hL&#SfD07&6D@M.*J:;$-rv29'M]8qMv-tLp,'886iaC=Hb*YJoKJ,(j%K=H`K.v9HggqBIiZu'QvBT.#=)0ukruV&.)3=(^1`o*Pj4<-#MJ+gLq9-##@HuZPN0]u:h7.T..G:;$/Usj(T7`Q8tT72LnYl<-qx8;-HV7Q-&Xdx%1a,hC=0u+HlsV>nuIQL-5" + "_>@kXQtMacfD.m-VAb8;IReM3$wf0''hra*so568'Ip&vRs849'MRYSp%:t:h5qSgwpEr$B>Q,;s(C#$)`svQuF$##-D,##,g68@2[T;.XSdN9Qe)rpt._K-#5wF)sP'##p#C0c%-Gb%" + "hd+<-j'Ai*x&&HMkT]C'OSl##5RG[JXaHN;d'uA#x._U;.`PU@(Z3dt4r152@:v,'R.Sj'w#0<-;kPI)FfJ&#AYJ&#//)>-k=m=*XnK$>=)72L]0I%>.G690a:$##<,);?;72#?x9+d;" + "^V'9;jY@;)br#q^YQpx:X#Te$Z^'=-=bGhLf:D6&bNwZ9-ZD#n^9HhLMr5G;']d&6'wYmTFmLq9wI>P(9mI[>kC-ekLC/R&CH+s'B;K-M6$EB%is00:" + "+A4[7xks.LrNk0&E)wILYF@2L'0Nb$+pv<(2.768/FrY&h$^3i&@+G%JT'<-,v`3;_)I9M^AE]CN?Cl2AZg+%4iTpT3$U4O]GKx'm9)b@p7YsvK3w^YR-" + "CdQ*:Ir<($u&)#(&?L9Rg3H)4fiEp^iI9O8KnTj,]H?D*r7'M;PwZ9K0E^k&-cpI;.p/6_vwoFMV<->#%Xi.LxVnrU(4&8/P+:hLSKj$#U%]49t'I:rgMi'FL@a:0Y-uA[39',(vbma*" + "hU%<-SRF`Tt:542R_VV$p@[p8DV[A,?1839FWdFTi1O*H&#(AL8[_P%.M>v^-))qOT*F5Cq0`Ye%+$B6i:7@0IXSsDiWP,##P`%/L-" + "S(qw%sf/@%#B6;/U7K]uZbi^Oc^2n%t<)'mEVE''n`WnJra$^TKvX5B>;_aSEK',(hwa0:i4G?.Bci.(X[?b*($,=-n<.Q%`(X=?+@Am*Js0&=3bh8K]mL69=Lb,OcZV/);TTm8VI;?%OtJ<(b4mq7M6:u?KRdFl*:xP?Yb.5)%w_I?7uk5JC+FS(m#i'k.'a0i)9<7b'fs'59hq$*5Uhv##pi^8+hIEBF`nvo`;'l0.^S1<-wUK2/Coh58KKhLj" + "M=SO*rfO`+qC`W-On.=AJ56>>i2@2LH6A:&5q`?9I3@@'04&p2/LVa*T-4<-i3;M9UvZd+N7>b*eIwg:CC)c<>nO&#$(>.Z-I&J(Q0Hd5Q%7Co-b`-cP)hI;*_F]u`Rb[.j8_Q/<&>uu+VsH$sM9TA%?)(vmJ80),P7E>)tjD%2L=-t#fK[%`v=Q8WlA2);Sa" + ">gXm8YB`1d@K#n]76-a$U,mF%Ul:#/'xoFM9QX-$.QN'>" + "[%$Z$uF6pA6Ki2O5:8w*vP1<-1`[G,)-m#>0`P&#eb#.3i)rtB61(o'$?X3B2Qft^ae_5tKL9MUe9b*sLEQ95C&`=G?@Mj=wh*'3E>=-<)Gt*Iw)'QG:`@I" + "wOf7&]1i'S01B+Ev/Nac#9S;=;YQpg_6U`*kVY39xK,[/6Aj7:'1Bm-_1EYfa1+o&o4hp7KN_Q(OlIo@S%;jVdn0'1h19w,WQhLI)3S#f$2(eb,jr*b;3Vw]*7NH%$c4Vs,eD9>XW8?N]o+(*pgC%/72LV-uW%iewS8W6m2rtCpo'RS1R84=@paTKt)>=%&1[)*vp'u+x,VrwN;&]kuO9JDbg=pO$J*.jVe;u'm0dr9l,<*wMK*Oe=g8lV_KEBFkO'oU]^=[-792#ok,)" + "i]lR8qQ2oA8wcRCZ^7w/Njh;?.stX?Q1>S1q4Bn$)K1<-rGdO'$Wr.Lc.CG)$/*JL4tNR/,SVO3,aUw'DJN:)Ss;wGn9A32ijw%FL+Z0Fn.U9;reSq)bmI32U==5ALuG&#Vf1398/pVo" + "1*c-(aY168o<`JsSbk-,1N;$>0:OUas(3:8Z972LSfF8eb=c-;>SPw7.6hn3m`9^Xkn(r.qS[0;T%&Qc=+STRxX'q1BNk3&*eu2;&8q$&x>Q#Q7^Tf+6<(d%ZVmj2bDi%.3L2n+4W'$P" + "iDDG)g,r%+?,$@?uou5tSe2aN_AQU*'IAO" + "URQ##V^Fv-XFbGM7Fl(N<3DhLGF%q.1rC$#:T__&Pi68%0xi_&[qFJ(77j_&JWoF.V735&T,[R*:xFR*K5>>#`bW-?4Ne_&6Ne_&6Ne_&n`kr-#GJcM6X;uM6X;uM(.a..^2TkL%oR(#" + ";u.T%fAr%4tJ8&><1=GHZ_+m9/#H1F^R#SC#*N=BA9(D?v[UiFY>>^8p,KKF.W]L29uLkLlu/+4T" + "w$)F./^n3+rlo+DB;5sIYGNk+i1t-69Jg--0pao7Sm#K)pdHW&;LuDNH@H>#/X-TI(;P>#,Gc>#0Su>#4`1?#8lC?#xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4^Rh%Sflr-k'MS.o?.5/sWel/wpEM0%3'/1)K^f1-d>G21&v(35>V`39V7A4=onx4" + "A1OY5EI0;6Ibgr6M$HS7Q<)58C5w,;WoA*#[%T*#`1g*#d=#+#hI5+#lUG+#pbY+#tnl+#x$),#&1;,#*=M,#.I`,#2Ur,#6b.-#;w[H#iQtA#m^0B#qjBB#uvTB##-hB#'9$C#+E6C#" + "/QHC#3^ZC#7jmC#;v)D#?,)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP" + "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5o,^<-28ZI'O?;xp" + "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#"; + +static const char* GetDefaultCompressedFontDataTTFBase85() +{ + return proggy_clean_ttf_compressed_data_base85; +} diff --git a/CameraParameterEstimation/apps/basics/extern/imgui/imgui_internal.h b/CameraParameterEstimation/apps/basics/extern/imgui/imgui_internal.h new file mode 100644 index 0000000..dc02f71 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/imgui/imgui_internal.h @@ -0,0 +1,753 @@ +// dear imgui, v1.50 WIP +// (internals) + +// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! +// Implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators) +// #define IMGUI_DEFINE_MATH_OPERATORS + +#pragma once + +#ifndef IMGUI_VERSION +#error Must include imgui.h before imgui_internal.h +#endif + +#include // FILE* +#include // sqrtf, fabsf, fmodf, powf, floorf, ceilf, cosf, sinf + +#ifdef _MSC_VER +#pragma warning (push) +#pragma warning (disable: 4251) // class 'xxx' needs to have dll-interface to be used by clients of struct 'xxx' // when IMGUI_API is set to__declspec(dllexport) +#endif + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h +#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h +#pragma clang diagnostic ignored "-Wold-style-cast" +#endif + +//----------------------------------------------------------------------------- +// Forward Declarations +//----------------------------------------------------------------------------- + +struct ImRect; +struct ImGuiColMod; +struct ImGuiStyleMod; +struct ImGuiGroupData; +struct ImGuiSimpleColumns; +struct ImGuiDrawContext; +struct ImGuiTextEditState; +struct ImGuiIniData; +struct ImGuiMouseCursorData; +struct ImGuiPopupRef; +struct ImGuiWindow; + +typedef int ImGuiLayoutType; // enum ImGuiLayoutType_ +typedef int ImGuiButtonFlags; // enum ImGuiButtonFlags_ +typedef int ImGuiTreeNodeFlags; // enum ImGuiTreeNodeFlags_ +typedef int ImGuiSliderFlags; // enum ImGuiSliderFlags_ + +//------------------------------------------------------------------------- +// STB libraries +//------------------------------------------------------------------------- + +namespace ImGuiStb +{ + +#undef STB_TEXTEDIT_STRING +#undef STB_TEXTEDIT_CHARTYPE +#define STB_TEXTEDIT_STRING ImGuiTextEditState +#define STB_TEXTEDIT_CHARTYPE ImWchar +#define STB_TEXTEDIT_GETWIDTH_NEWLINE -1.0f +#include "stb_textedit.h" + +} // namespace ImGuiStb + +//----------------------------------------------------------------------------- +// Context +//----------------------------------------------------------------------------- + +extern IMGUI_API ImGuiContext* GImGui; // current implicit ImGui context pointer + +//----------------------------------------------------------------------------- +// Helpers +//----------------------------------------------------------------------------- + +#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) +#define IM_PI 3.14159265358979323846f + +// Helpers: UTF-8 <> wchar +IMGUI_API int ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end); // return output UTF-8 bytes count +IMGUI_API int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end); // return input UTF-8 bytes count +IMGUI_API int ImTextStrFromUtf8(ImWchar* buf, int buf_size, const char* in_text, const char* in_text_end, const char** in_remaining = NULL); // return input UTF-8 bytes count +IMGUI_API int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end); // return number of UTF-8 code-points (NOT bytes count) +IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end); // return number of bytes to express string as UTF-8 code-points + +// Helpers: Misc +IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings +IMGUI_API void* ImLoadFileToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0); +IMGUI_API bool ImIsPointInTriangle(const ImVec2& p, const ImVec2& a, const ImVec2& b, const ImVec2& c); +static inline bool ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; } +static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } + +// Helpers: String +IMGUI_API int ImStricmp(const char* str1, const char* str2); +IMGUI_API int ImStrnicmp(const char* str1, const char* str2, int count); +IMGUI_API char* ImStrdup(const char* str); +IMGUI_API int ImStrlenW(const ImWchar* str); +IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line +IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); +IMGUI_API int ImFormatString(char* buf, int buf_size, const char* fmt, ...) IM_PRINTFARGS(3); +IMGUI_API int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args); + +// Helpers: Math +// We are keeping those not leaking to the user by default, in the case the user has implicit cast operators between ImVec2 and its own types (when IM_VEC2_CLASS_EXTRA is defined) +#ifdef IMGUI_DEFINE_MATH_OPERATORS +static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x*rhs, lhs.y*rhs); } +static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x/rhs, lhs.y/rhs); } +static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x+rhs.x, lhs.y+rhs.y); } +static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x-rhs.x, lhs.y-rhs.y); } +static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x*rhs.x, lhs.y*rhs.y); } +static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x/rhs.x, lhs.y/rhs.y); } +static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; } +static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } +static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } +static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } +static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x-rhs.x, lhs.y-rhs.y, lhs.z-rhs.z, lhs.w-rhs.w); } +#endif + +static inline int ImMin(int lhs, int rhs) { return lhs < rhs ? lhs : rhs; } +static inline int ImMax(int lhs, int rhs) { return lhs >= rhs ? lhs : rhs; } +static inline float ImMin(float lhs, float rhs) { return lhs < rhs ? lhs : rhs; } +static inline float ImMax(float lhs, float rhs) { return lhs >= rhs ? lhs : rhs; } +static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(ImMin(lhs.x,rhs.x), ImMin(lhs.y,rhs.y)); } +static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(ImMax(lhs.x,rhs.x), ImMax(lhs.y,rhs.y)); } +static inline int ImClamp(int v, int mn, int mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } +static inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } +static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) { return ImVec2(ImClamp(f.x,mn.x,mx.x), ImClamp(f.y,mn.y,mx.y)); } +static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } +static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; } +static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); } +static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; } +static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; } +static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / sqrtf(d); return fail_value; } +static inline float ImFloor(float f) { return (float)(int)f; } +static inline ImVec2 ImFloor(ImVec2 v) { return ImVec2((float)(int)v.x, (float)(int)v.y); } + +// We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax. +// Defining a custom placement new() with a dummy parameter allows us to bypass including which on some platforms complains when user has disabled exceptions. +#ifdef IMGUI_DEFINE_PLACEMENT_NEW +struct ImPlacementNewDummy {}; +inline void* operator new(size_t, ImPlacementNewDummy, void* ptr) { return ptr; } +inline void operator delete(void*, ImPlacementNewDummy, void*) {} +#define IM_PLACEMENT_NEW(_PTR) new(ImPlacementNewDummy(), _PTR) +#endif + +//----------------------------------------------------------------------------- +// Types +//----------------------------------------------------------------------------- + +enum ImGuiButtonFlags_ +{ + ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat + ImGuiButtonFlags_PressedOnClickRelease = 1 << 1, // (default) return pressed on click+release on same item (default if no PressedOn** flag is set) + ImGuiButtonFlags_PressedOnClick = 1 << 2, // return pressed on click (default requires click+release) + ImGuiButtonFlags_PressedOnRelease = 1 << 3, // return pressed on release (default requires click+release) + ImGuiButtonFlags_PressedOnDoubleClick = 1 << 4, // return pressed on double-click (default requires click+release) + ImGuiButtonFlags_FlattenChilds = 1 << 5, // allow interaction even if a child window is overlapping + ImGuiButtonFlags_DontClosePopups = 1 << 6, // disable automatically closing parent popup on press + ImGuiButtonFlags_Disabled = 1 << 7, // disable interaction + ImGuiButtonFlags_AlignTextBaseLine = 1 << 8, // vertically align button to match text baseline - ButtonEx() only + ImGuiButtonFlags_NoKeyModifiers = 1 << 9, // disable interaction if a key modifier is held + ImGuiButtonFlags_AllowOverlapMode = 1 << 10 // require previous frame HoveredId to either match id or be null before being usable +}; + +enum ImGuiSliderFlags_ +{ + ImGuiSliderFlags_Vertical = 1 << 0 +}; + +enum ImGuiSelectableFlagsPrivate_ +{ + // NB: need to be in sync with last value of ImGuiSelectableFlags_ + ImGuiSelectableFlags_Menu = 1 << 3, + ImGuiSelectableFlags_MenuItem = 1 << 4, + ImGuiSelectableFlags_Disabled = 1 << 5, + ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 6 +}; + +// FIXME: this is in development, not exposed/functional as a generic feature yet. +enum ImGuiLayoutType_ +{ + ImGuiLayoutType_Vertical, + ImGuiLayoutType_Horizontal +}; + +enum ImGuiPlotType +{ + ImGuiPlotType_Lines, + ImGuiPlotType_Histogram +}; + +enum ImGuiDataType +{ + ImGuiDataType_Int, + ImGuiDataType_Float +}; + +// 2D axis aligned bounding-box +// NB: we can't rely on ImVec2 math operators being available here +struct IMGUI_API ImRect +{ + ImVec2 Min; // Upper-left + ImVec2 Max; // Lower-right + + ImRect() : Min(FLT_MAX,FLT_MAX), Max(-FLT_MAX,-FLT_MAX) {} + ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {} + ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {} + ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {} + + ImVec2 GetCenter() const { return ImVec2((Min.x+Max.x)*0.5f, (Min.y+Max.y)*0.5f); } + ImVec2 GetSize() const { return ImVec2(Max.x-Min.x, Max.y-Min.y); } + float GetWidth() const { return Max.x-Min.x; } + float GetHeight() const { return Max.y-Min.y; } + ImVec2 GetTL() const { return Min; } // Top-left + ImVec2 GetTR() const { return ImVec2(Max.x, Min.y); } // Top-right + ImVec2 GetBL() const { return ImVec2(Min.x, Max.y); } // Bottom-left + ImVec2 GetBR() const { return Max; } // Bottom-right + bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; } + bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x < Max.x && r.Max.y < Max.y; } + bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; } + void Add(const ImVec2& rhs) { if (Min.x > rhs.x) Min.x = rhs.x; if (Min.y > rhs.y) Min.y = rhs.y; if (Max.x < rhs.x) Max.x = rhs.x; if (Max.y < rhs.y) Max.y = rhs.y; } + void Add(const ImRect& rhs) { if (Min.x > rhs.Min.x) Min.x = rhs.Min.x; if (Min.y > rhs.Min.y) Min.y = rhs.Min.y; if (Max.x < rhs.Max.x) Max.x = rhs.Max.x; if (Max.y < rhs.Max.y) Max.y = rhs.Max.y; } + void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } + void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } + void Reduce(const ImVec2& amount) { Min.x += amount.x; Min.y += amount.y; Max.x -= amount.x; Max.y -= amount.y; } + void Clip(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; } + void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } + ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const + { + if (!on_edge && Contains(p)) + return p; + if (p.x > Max.x) p.x = Max.x; + else if (p.x < Min.x) p.x = Min.x; + if (p.y > Max.y) p.y = Max.y; + else if (p.y < Min.y) p.y = Min.y; + return p; + } +}; + +// Stacked color modifier, backup of modified data so we can restore it +struct ImGuiColMod +{ + ImGuiCol Col; + ImVec4 PreviousValue; +}; + +// Stacked style modifier, backup of modified data so we can restore it +struct ImGuiStyleMod +{ + ImGuiStyleVar Var; + ImVec2 PreviousValue; +}; + +// Stacked data for BeginGroup()/EndGroup() +struct ImGuiGroupData +{ + ImVec2 BackupCursorPos; + ImVec2 BackupCursorMaxPos; + float BackupIndentX; + float BackupCurrentLineHeight; + float BackupCurrentLineTextBaseOffset; + float BackupLogLinePosY; + bool AdvanceCursor; +}; + +// Per column data for Columns() +struct ImGuiColumnData +{ + float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) + //float IndentX; +}; + +// Simple column measurement currently used for MenuItem() only. This is very short-sighted/throw-away code and NOT a generic helper. +struct IMGUI_API ImGuiSimpleColumns +{ + int Count; + float Spacing; + float Width, NextWidth; + float Pos[8], NextWidths[8]; + + ImGuiSimpleColumns(); + void Update(int count, float spacing, bool clear); + float DeclColumns(float w0, float w1, float w2); + float CalcExtraSpace(float avail_w); +}; + +// Internal state of the currently focused/edited text input box +struct IMGUI_API ImGuiTextEditState +{ + ImGuiID Id; // widget id owning the text state + ImVector Text; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer. + ImVector InitialText; // backup of end-user buffer at the time of focus (in UTF-8, unaltered) + ImVector TempTextBuffer; + int CurLenA, CurLenW; // we need to maintain our buffer length in both UTF-8 and wchar format. + int BufSizeA; // end-user buffer size + float ScrollX; + ImGuiStb::STB_TexteditState StbState; + float CursorAnim; + bool CursorFollow; + bool SelectedAllMouseLock; + + ImGuiTextEditState() { memset(this, 0, sizeof(*this)); } + void CursorAnimReset() { CursorAnim = -0.30f; } // After a user-input the cursor stays on for a while without blinking + void CursorClamp() { StbState.cursor = ImMin(StbState.cursor, CurLenW); StbState.select_start = ImMin(StbState.select_start, CurLenW); StbState.select_end = ImMin(StbState.select_end, CurLenW); } + bool HasSelection() const { return StbState.select_start != StbState.select_end; } + void ClearSelection() { StbState.select_start = StbState.select_end = StbState.cursor; } + void SelectAll() { StbState.select_start = 0; StbState.select_end = CurLenW; StbState.cursor = StbState.select_end; StbState.has_preferred_x = false; } + void OnKeyPressed(int key); +}; + +// Data saved in imgui.ini file +struct ImGuiIniData +{ + char* Name; + ImGuiID Id; + ImVec2 Pos; + ImVec2 Size; + bool Collapsed; +}; + +// Mouse cursor data (used when io.MouseDrawCursor is set) +struct ImGuiMouseCursorData +{ + ImGuiMouseCursor Type; + ImVec2 HotOffset; + ImVec2 Size; + ImVec2 TexUvMin[2]; + ImVec2 TexUvMax[2]; +}; + +// Storage for current popup stack +struct ImGuiPopupRef +{ + ImGuiID PopupId; // Set on OpenPopup() + ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() + ImGuiWindow* ParentWindow; // Set on OpenPopup() + ImGuiID ParentMenuSet; // Set on OpenPopup() + ImVec2 MousePosOnOpen; // Copy of mouse position at the time of opening popup + + ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; } +}; + +// Main state for ImGui +struct ImGuiContext +{ + bool Initialized; + ImGuiIO IO; + ImGuiStyle Style; + ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() + float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize() + float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Size of characters. + ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvWhitePixel + + float Time; + int FrameCount; + int FrameCountEnded; + int FrameCountRendered; + ImVector Windows; + ImVector WindowsSortBuffer; + ImGuiWindow* CurrentWindow; // Being drawn into + ImVector CurrentWindowStack; + ImGuiWindow* FocusedWindow; // Will catch keyboard inputs + ImGuiWindow* HoveredWindow; // Will catch mouse inputs + ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only) + ImGuiID HoveredId; // Hovered widget + bool HoveredIdAllowOverlap; + ImGuiID HoveredIdPreviousFrame; + ImGuiID ActiveId; // Active widget + ImGuiID ActiveIdPreviousFrame; + bool ActiveIdIsAlive; + bool ActiveIdIsJustActivated; // Set at the time of activation for one frame + bool ActiveIdAllowOverlap; // Set only by active widget + ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) + ImGuiWindow* ActiveIdWindow; + ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. + ImGuiID MovedWindowMoveId; // == MovedWindow->RootWindow->MoveId + ImVector Settings; // .ini Settings + float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero + ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() + ImVector StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() + ImVector FontStack; // Stack for PushFont()/PopFont() + ImVector OpenPopupStack; // Which popups are open (persistent) + ImVector CurrentPopupStack; // Which level of BeginPopup() we are in (reset every frame) + + // Storage for SetNexWindow** and SetNextTreeNode*** functions + ImVec2 SetNextWindowPosVal; + ImVec2 SetNextWindowSizeVal; + ImVec2 SetNextWindowContentSizeVal; + bool SetNextWindowCollapsedVal; + ImGuiSetCond SetNextWindowPosCond; + ImGuiSetCond SetNextWindowSizeCond; + ImGuiSetCond SetNextWindowContentSizeCond; + ImGuiSetCond SetNextWindowCollapsedCond; + ImRect SetNextWindowSizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true + ImGuiSizeConstraintCallback SetNextWindowSizeConstraintCallback; + void* SetNextWindowSizeConstraintCallbackUserData; + bool SetNextWindowSizeConstraint; + bool SetNextWindowFocus; + bool SetNextTreeNodeOpenVal; + ImGuiSetCond SetNextTreeNodeOpenCond; + + // Render + ImDrawData RenderDrawData; // Main ImDrawData instance to pass render information to the user + ImVector RenderDrawLists[3]; + float ModalWindowDarkeningRatio; + ImDrawList OverlayDrawList; // Optional software render of mouse cursors, if io.MouseDrawCursor is set + a few debug overlays + ImGuiMouseCursor MouseCursor; + ImGuiMouseCursorData MouseCursorData[ImGuiMouseCursor_Count_]; + + // Widget state + ImGuiTextEditState InputTextState; + ImFont InputTextPasswordFont; + ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. + ImGuiStorage ColorEditModeStorage; // Store user selection of color edit mode + float DragCurrentValue; // Currently dragged value, always float, not rounded by end-user precision settings + ImVec2 DragLastMouseDelta; + float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio + float DragSpeedScaleSlow; + float DragSpeedScaleFast; + ImVec2 ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage? + char Tooltip[1024]; + char* PrivateClipboard; // If no custom clipboard handler is defined + ImVec2 OsImePosRequest, OsImePosSet; // Cursor position request & last passed to the OS Input Method Editor + + // Logging + bool LogEnabled; + FILE* LogFile; // If != NULL log to stdout/ file + ImGuiTextBuffer* LogClipboard; // Else log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. + int LogStartDepth; + int LogAutoExpandMaxDepth; + + // Misc + float FramerateSecPerFrame[120]; // calculate estimate of framerate for user + int FramerateSecPerFrameIdx; + float FramerateSecPerFrameAccum; + int CaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags + int CaptureKeyboardNextFrame; + char TempBuffer[1024*3+1]; // temporary text buffer + + ImGuiContext() + { + Initialized = false; + Font = NULL; + FontSize = FontBaseSize = 0.0f; + FontTexUvWhitePixel = ImVec2(0.0f, 0.0f); + + Time = 0.0f; + FrameCount = 0; + FrameCountEnded = FrameCountRendered = -1; + CurrentWindow = NULL; + FocusedWindow = NULL; + HoveredWindow = NULL; + HoveredRootWindow = NULL; + HoveredId = 0; + HoveredIdAllowOverlap = false; + HoveredIdPreviousFrame = 0; + ActiveId = 0; + ActiveIdPreviousFrame = 0; + ActiveIdIsAlive = false; + ActiveIdIsJustActivated = false; + ActiveIdAllowOverlap = false; + ActiveIdClickOffset = ImVec2(-1,-1); + ActiveIdWindow = NULL; + MovedWindow = NULL; + MovedWindowMoveId = 0; + SettingsDirtyTimer = 0.0f; + + SetNextWindowPosVal = ImVec2(0.0f, 0.0f); + SetNextWindowSizeVal = ImVec2(0.0f, 0.0f); + SetNextWindowCollapsedVal = false; + SetNextWindowPosCond = 0; + SetNextWindowSizeCond = 0; + SetNextWindowContentSizeCond = 0; + SetNextWindowCollapsedCond = 0; + SetNextWindowFocus = false; + SetNextWindowSizeConstraintCallback = NULL; + SetNextWindowSizeConstraintCallbackUserData = NULL; + SetNextTreeNodeOpenVal = false; + SetNextTreeNodeOpenCond = 0; + + ScalarAsInputTextId = 0; + DragCurrentValue = 0.0f; + DragLastMouseDelta = ImVec2(0.0f, 0.0f); + DragSpeedDefaultRatio = 1.0f / 100.0f; + DragSpeedScaleSlow = 0.01f; + DragSpeedScaleFast = 10.0f; + ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f); + memset(Tooltip, 0, sizeof(Tooltip)); + PrivateClipboard = NULL; + OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f); + + ModalWindowDarkeningRatio = 0.0f; + OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging + MouseCursor = ImGuiMouseCursor_Arrow; + memset(MouseCursorData, 0, sizeof(MouseCursorData)); + + LogEnabled = false; + LogFile = NULL; + LogClipboard = NULL; + LogStartDepth = 0; + LogAutoExpandMaxDepth = 2; + + memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); + FramerateSecPerFrameIdx = 0; + FramerateSecPerFrameAccum = 0.0f; + CaptureMouseNextFrame = CaptureKeyboardNextFrame = -1; + memset(TempBuffer, 0, sizeof(TempBuffer)); + } +}; + +// Transient per-window data, reset at the beginning of the frame +// FIXME: That's theory, in practice the delimitation between ImGuiWindow and ImGuiDrawContext is quite tenuous and could be reconsidered. +struct IMGUI_API ImGuiDrawContext +{ + ImVec2 CursorPos; + ImVec2 CursorPosPrevLine; + ImVec2 CursorStartPos; + ImVec2 CursorMaxPos; // Implicitly calculate the size of our contents, always extending. Saved into window->SizeContents at the end of the frame + float CurrentLineHeight; + float CurrentLineTextBaseOffset; + float PrevLineHeight; + float PrevLineTextBaseOffset; + float LogLinePosY; + int TreeDepth; + ImGuiID LastItemId; + ImRect LastItemRect; + bool LastItemHoveredAndUsable; // Item rectangle is hovered, and its window is currently interactable with (not blocked by a popup preventing access to the window) + bool LastItemHoveredRect; // Item rectangle is hovered, but its window may or not be currently interactable with (might be blocked by a popup preventing access to the window) + bool MenuBarAppending; + float MenuBarOffsetX; + ImVector ChildWindows; + ImGuiStorage* StateStorage; + ImGuiLayoutType LayoutType; + + // We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings. + float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window + float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f] + bool AllowKeyboardFocus; // == AllowKeyboardFocusStack.back() [empty == true] + bool ButtonRepeat; // == ButtonRepeatStack.back() [empty == false] + ImVector ItemWidthStack; + ImVector TextWrapPosStack; + ImVector AllowKeyboardFocusStack; + ImVector ButtonRepeatStack; + ImVectorGroupStack; + ImGuiColorEditMode ColorEditMode; + int StackSizesBackup[6]; // Store size of various stacks for asserting + + float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) + float GroupOffsetX; + float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. + int ColumnsCurrent; + int ColumnsCount; + float ColumnsMinX; + float ColumnsMaxX; + float ColumnsStartPosY; + float ColumnsCellMinY; + float ColumnsCellMaxY; + bool ColumnsShowBorders; + ImGuiID ColumnsSetId; + ImVector ColumnsData; + + ImGuiDrawContext() + { + CursorPos = CursorPosPrevLine = CursorStartPos = CursorMaxPos = ImVec2(0.0f, 0.0f); + CurrentLineHeight = PrevLineHeight = 0.0f; + CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f; + LogLinePosY = -1.0f; + TreeDepth = 0; + LastItemId = 0; + LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f); + LastItemHoveredAndUsable = LastItemHoveredRect = false; + MenuBarAppending = false; + MenuBarOffsetX = 0.0f; + StateStorage = NULL; + LayoutType = ImGuiLayoutType_Vertical; + ItemWidth = 0.0f; + ButtonRepeat = false; + AllowKeyboardFocus = true; + TextWrapPos = -1.0f; + ColorEditMode = ImGuiColorEditMode_RGB; + memset(StackSizesBackup, 0, sizeof(StackSizesBackup)); + + IndentX = 0.0f; + ColumnsOffsetX = 0.0f; + ColumnsCurrent = 0; + ColumnsCount = 1; + ColumnsMinX = ColumnsMaxX = 0.0f; + ColumnsStartPosY = 0.0f; + ColumnsCellMinY = ColumnsCellMaxY = 0.0f; + ColumnsShowBorders = true; + ColumnsSetId = 0; + } +}; + +// Windows data +struct IMGUI_API ImGuiWindow +{ + char* Name; + ImGuiID ID; // == ImHash(Name) + ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_ + int IndexWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0. + ImVec2 PosFloat; + ImVec2 Pos; // Position rounded-up to nearest pixel + ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) + ImVec2 SizeFull; // Size when non collapsed + ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame + ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize() + ImRect ContentsRegionRect; // Maximum visible content position in window coordinates. ~~ (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis + ImVec2 WindowPadding; // Window padding at the time of begin. We need to lock it, in particular manipulation of the ShowBorder would have an effect + ImGuiID MoveId; // == window->GetID("#MOVE") + ImVec2 Scroll; + ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change) + ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered + bool ScrollbarX, ScrollbarY; + ImVec2 ScrollbarSizes; + float BorderSize; + bool Active; // Set to true on Begin() + bool WasActive; + bool Accessed; // Set to true when any widget access the current window + bool Collapsed; // Set when collapsing window to become only title-bar + bool SkipItems; // == Visible && !Collapsed + int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) + ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) + int AutoFitFramesX, AutoFitFramesY; + bool AutoFitOnlyGrows; + int AutoPosLastDirection; + int HiddenFrames; + int SetWindowPosAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowPos() call will succeed with this particular flag. + int SetWindowSizeAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowSize() call will succeed with this particular flag. + int SetWindowCollapsedAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowCollapsed() call will succeed with this particular flag. + bool SetWindowPosCenterWanted; + + ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame + ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack + ImRect ClipRect; // = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2. + ImRect WindowRectClipped; // = WindowRect just after setup in Begin(). == window->Rect() for root window. + int LastFrameActive; + float ItemWidthDefault; + ImGuiSimpleColumns MenuColumns; // Simplified columns storage for menu items + ImGuiStorage StateStorage; + float FontWindowScale; // Scale multiplier per-window + ImDrawList* DrawList; + ImGuiWindow* RootWindow; // If we are a child window, this is pointing to the first non-child parent window. Else point to ourself. + ImGuiWindow* RootNonPopupWindow; // If we are a child window, this is pointing to the first non-child non-popup parent window. Else point to ourself. + ImGuiWindow* ParentWindow; // If we are a child window, this is pointing to our parent window. Else point to NULL. + + // Navigation / Focus + int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister() + int FocusIdxTabCounter; // (same, but only count widgets which you can Tab through) + int FocusIdxAllRequestCurrent; // Item being requested for focus + int FocusIdxTabRequestCurrent; // Tab-able item being requested for focus + int FocusIdxAllRequestNext; // Item being requested for focus, for next update (relies on layout to be stable between the frame pressing TAB and the next frame) + int FocusIdxTabRequestNext; // " + +public: + ImGuiWindow(const char* name); + ~ImGuiWindow(); + + ImGuiID GetID(const char* str, const char* str_end = NULL); + ImGuiID GetID(const void* ptr); + ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL); + + ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x+Size.x, Pos.y+Size.y); } + float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; } + float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; } + ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); } + float MenuBarHeight() const { return (Flags & ImGuiWindowFlags_MenuBar) ? CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f : 0.0f; } + ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); } +}; + +//----------------------------------------------------------------------------- +// Internal API +// No guarantee of forward compatibility here. +//----------------------------------------------------------------------------- + +namespace ImGui +{ + // We should always have a CurrentWindow in the stack (there is an implicit "Debug" window) + // If this ever crash because g.CurrentWindow is NULL it means that either + // - ImGui::NewFrame() has never been called, which is illegal. + // - You are calling ImGui functions after ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal. + inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; } + inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->Accessed = true; return g.CurrentWindow; } + IMGUI_API ImGuiWindow* GetParentWindow(); + IMGUI_API ImGuiWindow* FindWindowByName(const char* name); + IMGUI_API void FocusWindow(ImGuiWindow* window); + + IMGUI_API void EndFrame(); // Ends the ImGui frame. Automatically called by Render()! you most likely don't need to ever call that yourself directly. If you don't need to render you can call EndFrame() but you'll have wasted CPU already. If you don't need to render, don't create any windows instead! + + IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); + IMGUI_API void SetHoveredID(ImGuiID id); + IMGUI_API void KeepAliveID(ImGuiID id); + + IMGUI_API void ItemSize(const ImVec2& size, float text_offset_y = 0.0f); + IMGUI_API void ItemSize(const ImRect& bb, float text_offset_y = 0.0f); + IMGUI_API bool ItemAdd(const ImRect& bb, const ImGuiID* id); + IMGUI_API bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged); + IMGUI_API bool IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs = false); + IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, bool is_active, bool tab_stop = true); // Return true if focus is requested + IMGUI_API void FocusableItemUnregister(ImGuiWindow* window); + IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); + IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); + + IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing); + + // NB: All position are in absolute pixels coordinates (not window coordinates) + // FIXME: All those functions are a mess and needs to be refactored into something decent. Avoid use outside of imgui.cpp! + // We need: a sort of symbol library, preferably baked into font atlas when possible + decent text rendering helpers. + IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); + IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); + IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, ImGuiAlign align = ImGuiAlign_Default, const ImVec2* clip_min = NULL, const ImVec2* clip_max = NULL); + IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); + IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool is_open, float scale = 1.0f, bool shadow = false); + IMGUI_API void RenderBullet(ImVec2 pos); + IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col); + IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. + + IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); + IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0); + IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius); + + IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags = 0); + IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power); + IMGUI_API bool SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format); + + IMGUI_API bool DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power); + IMGUI_API bool DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power); + IMGUI_API bool DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format); + + IMGUI_API bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputFloatN(const char* label, float* v, int components, int decimal_precision, ImGuiInputTextFlags extra_flags); + IMGUI_API bool InputIntN(const char* label, int* v, int components, ImGuiInputTextFlags extra_flags); + IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags); + IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision); + + IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL); + IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging + IMGUI_API void TreePushRawID(ImGuiID id); + + IMGUI_API void PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size); + + IMGUI_API int ParseFormatPrecision(const char* fmt, int default_value); + IMGUI_API float RoundScalar(float value, int decimal_precision); + +} // namespace ImGui + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#ifdef _MSC_VER +#pragma warning (pop) +#endif diff --git a/CameraParameterEstimation/apps/basics/extern/imgui/stb_rect_pack.h b/CameraParameterEstimation/apps/basics/extern/imgui/stb_rect_pack.h new file mode 100644 index 0000000..fafd889 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/imgui/stb_rect_pack.h @@ -0,0 +1,573 @@ +// stb_rect_pack.h - v0.08 - public domain - rectangle packing +// Sean Barrett 2014 +// +// Useful for e.g. packing rectangular textures into an atlas. +// Does not do rotation. +// +// Not necessarily the awesomest packing method, but better than +// the totally naive one in stb_truetype (which is primarily what +// this is meant to replace). +// +// Has only had a few tests run, may have issues. +// +// More docs to come. +// +// No memory allocations; uses qsort() and assert() from stdlib. +// Can override those by defining STBRP_SORT and STBRP_ASSERT. +// +// This library currently uses the Skyline Bottom-Left algorithm. +// +// Please note: better rectangle packers are welcome! Please +// implement them to the same API, but with a different init +// function. +// +// Credits +// +// Library +// Sean Barrett +// Minor features +// Martins Mozeiko +// Bugfixes / warning fixes +// Jeremy Jaussaud +// +// Version history: +// +// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0) +// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0) +// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort +// 0.05: added STBRP_ASSERT to allow replacing assert +// 0.04: fixed minor bug in STBRP_LARGE_RECTS support +// 0.01: initial release +// +// LICENSE +// +// This software is in the public domain. Where that dedication is not +// recognized, you are granted a perpetual, irrevocable license to copy, +// distribute, and modify this file as you see fit. + +////////////////////////////////////////////////////////////////////////////// +// +// INCLUDE SECTION +// + +#ifndef STB_INCLUDE_STB_RECT_PACK_H +#define STB_INCLUDE_STB_RECT_PACK_H + +#define STB_RECT_PACK_VERSION 1 + +#ifdef STBRP_STATIC +#define STBRP_DEF static +#else +#define STBRP_DEF extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct stbrp_context stbrp_context; +typedef struct stbrp_node stbrp_node; +typedef struct stbrp_rect stbrp_rect; + +#ifdef STBRP_LARGE_RECTS +typedef int stbrp_coord; +#else +typedef unsigned short stbrp_coord; +#endif + +STBRP_DEF void stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); +// Assign packed locations to rectangles. The rectangles are of type +// 'stbrp_rect' defined below, stored in the array 'rects', and there +// are 'num_rects' many of them. +// +// Rectangles which are successfully packed have the 'was_packed' flag +// set to a non-zero value and 'x' and 'y' store the minimum location +// on each axis (i.e. bottom-left in cartesian coordinates, top-left +// if you imagine y increasing downwards). Rectangles which do not fit +// have the 'was_packed' flag set to 0. +// +// You should not try to access the 'rects' array from another thread +// while this function is running, as the function temporarily reorders +// the array while it executes. +// +// To pack into another rectangle, you need to call stbrp_init_target +// again. To continue packing into the same rectangle, you can call +// this function again. Calling this multiple times with multiple rect +// arrays will probably produce worse packing results than calling it +// a single time with the full rectangle array, but the option is +// available. + +struct stbrp_rect +{ + // reserved for your use: + int id; + + // input: + stbrp_coord w, h; + + // output: + stbrp_coord x, y; + int was_packed; // non-zero if valid packing + +}; // 16 bytes, nominally + + +STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); +// Initialize a rectangle packer to: +// pack a rectangle that is 'width' by 'height' in dimensions +// using temporary storage provided by the array 'nodes', which is 'num_nodes' long +// +// You must call this function every time you start packing into a new target. +// +// There is no "shutdown" function. The 'nodes' memory must stay valid for +// the following stbrp_pack_rects() call (or calls), but can be freed after +// the call (or calls) finish. +// +// Note: to guarantee best results, either: +// 1. make sure 'num_nodes' >= 'width' +// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' +// +// If you don't do either of the above things, widths will be quantized to multiples +// of small integers to guarantee the algorithm doesn't run out of temporary storage. +// +// If you do #2, then the non-quantized algorithm will be used, but the algorithm +// may run out of temporary storage and be unable to pack some rectangles. + +STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem); +// Optionally call this function after init but before doing any packing to +// change the handling of the out-of-temp-memory scenario, described above. +// If you call init again, this will be reset to the default (false). + + +STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic); +// Optionally select which packing heuristic the library should use. Different +// heuristics will produce better/worse results for different data sets. +// If you call init again, this will be reset to the default. + +enum +{ + STBRP_HEURISTIC_Skyline_default=0, + STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, + STBRP_HEURISTIC_Skyline_BF_sortHeight +}; + + +////////////////////////////////////////////////////////////////////////////// +// +// the details of the following structures don't matter to you, but they must +// be visible so you can handle the memory allocations for them + +struct stbrp_node +{ + stbrp_coord x,y; + stbrp_node *next; +}; + +struct stbrp_context +{ + int width; + int height; + int align; + int init_mode; + int heuristic; + int num_nodes; + stbrp_node *active_head; + stbrp_node *free_head; + stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' +}; + +#ifdef __cplusplus +} +#endif + +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// IMPLEMENTATION SECTION +// + +#ifdef STB_RECT_PACK_IMPLEMENTATION +#ifndef STBRP_SORT +#include +#define STBRP_SORT qsort +#endif + +#ifndef STBRP_ASSERT +#include +#define STBRP_ASSERT assert +#endif + +enum +{ + STBRP__INIT_skyline = 1 +}; + +STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic) +{ + switch (context->init_mode) { + case STBRP__INIT_skyline: + STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); + context->heuristic = heuristic; + break; + default: + STBRP_ASSERT(0); + } +} + +STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem) +{ + if (allow_out_of_mem) + // if it's ok to run out of memory, then don't bother aligning them; + // this gives better packing, but may fail due to OOM (even though + // the rectangles easily fit). @TODO a smarter approach would be to only + // quantize once we've hit OOM, then we could get rid of this parameter. + context->align = 1; + else { + // if it's not ok to run out of memory, then quantize the widths + // so that num_nodes is always enough nodes. + // + // I.e. num_nodes * align >= width + // align >= width / num_nodes + // align = ceil(width/num_nodes) + + context->align = (context->width + context->num_nodes-1) / context->num_nodes; + } +} + +STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) +{ + int i; +#ifndef STBRP_LARGE_RECTS + STBRP_ASSERT(width <= 0xffff && height <= 0xffff); +#endif + + for (i=0; i < num_nodes-1; ++i) + nodes[i].next = &nodes[i+1]; + nodes[i].next = NULL; + context->init_mode = STBRP__INIT_skyline; + context->heuristic = STBRP_HEURISTIC_Skyline_default; + context->free_head = &nodes[0]; + context->active_head = &context->extra[0]; + context->width = width; + context->height = height; + context->num_nodes = num_nodes; + stbrp_setup_allow_out_of_mem(context, 0); + + // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) + context->extra[0].x = 0; + context->extra[0].y = 0; + context->extra[0].next = &context->extra[1]; + context->extra[1].x = (stbrp_coord) width; +#ifdef STBRP_LARGE_RECTS + context->extra[1].y = (1<<30); +#else + context->extra[1].y = 65535; +#endif + context->extra[1].next = NULL; +} + +// find minimum y position if it starts at x1 +static int stbrp__skyline_find_min_y(stbrp_context *, stbrp_node *first, int x0, int width, int *pwaste) +{ + //(void)c; + stbrp_node *node = first; + int x1 = x0 + width; + int min_y, visited_width, waste_area; + STBRP_ASSERT(first->x <= x0); + + #if 0 + // skip in case we're past the node + while (node->next->x <= x0) + ++node; + #else + STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency + #endif + + STBRP_ASSERT(node->x <= x0); + + min_y = 0; + waste_area = 0; + visited_width = 0; + while (node->x < x1) { + if (node->y > min_y) { + // raise min_y higher. + // we've accounted for all waste up to min_y, + // but we'll now add more waste for everything we've visted + waste_area += visited_width * (node->y - min_y); + min_y = node->y; + // the first time through, visited_width might be reduced + if (node->x < x0) + visited_width += node->next->x - x0; + else + visited_width += node->next->x - node->x; + } else { + // add waste area + int under_width = node->next->x - node->x; + if (under_width + visited_width > width) + under_width = width - visited_width; + waste_area += under_width * (min_y - node->y); + visited_width += under_width; + } + node = node->next; + } + + *pwaste = waste_area; + return min_y; +} + +typedef struct +{ + int x,y; + stbrp_node **prev_link; +} stbrp__findresult; + +static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height) +{ + int best_waste = (1<<30), best_x, best_y = (1 << 30); + stbrp__findresult fr; + stbrp_node **prev, *node, *tail, **best = NULL; + + // align to multiple of c->align + width = (width + c->align - 1); + width -= width % c->align; + STBRP_ASSERT(width % c->align == 0); + + node = c->active_head; + prev = &c->active_head; + while (node->x + width <= c->width) { + int y,waste; + y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); + if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL + // bottom left + if (y < best_y) { + best_y = y; + best = prev; + } + } else { + // best-fit + if (y + height <= c->height) { + // can only use it if it first vertically + if (y < best_y || (y == best_y && waste < best_waste)) { + best_y = y; + best_waste = waste; + best = prev; + } + } + } + prev = &node->next; + node = node->next; + } + + best_x = (best == NULL) ? 0 : (*best)->x; + + // if doing best-fit (BF), we also have to try aligning right edge to each node position + // + // e.g, if fitting + // + // ____________________ + // |____________________| + // + // into + // + // | | + // | ____________| + // |____________| + // + // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned + // + // This makes BF take about 2x the time + + if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { + tail = c->active_head; + node = c->active_head; + prev = &c->active_head; + // find first node that's admissible + while (tail->x < width) + tail = tail->next; + while (tail) { + int xpos = tail->x - width; + int y,waste; + STBRP_ASSERT(xpos >= 0); + // find the left position that matches this + while (node->next->x <= xpos) { + prev = &node->next; + node = node->next; + } + STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); + y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); + if (y + height < c->height) { + if (y <= best_y) { + if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { + best_x = xpos; + STBRP_ASSERT(y <= best_y); + best_y = y; + best_waste = waste; + best = prev; + } + } + } + tail = tail->next; + } + } + + fr.prev_link = best; + fr.x = best_x; + fr.y = best_y; + return fr; +} + +static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height) +{ + // find best position according to heuristic + stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); + stbrp_node *node, *cur; + + // bail if: + // 1. it failed + // 2. the best node doesn't fit (we don't always check this) + // 3. we're out of memory + if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { + res.prev_link = NULL; + return res; + } + + // on success, create new node + node = context->free_head; + node->x = (stbrp_coord) res.x; + node->y = (stbrp_coord) (res.y + height); + + context->free_head = node->next; + + // insert the new node into the right starting point, and + // let 'cur' point to the remaining nodes needing to be + // stiched back in + + cur = *res.prev_link; + if (cur->x < res.x) { + // preserve the existing one, so start testing with the next one + stbrp_node *next = cur->next; + cur->next = node; + cur = next; + } else { + *res.prev_link = node; + } + + // from here, traverse cur and free the nodes, until we get to one + // that shouldn't be freed + while (cur->next && cur->next->x <= res.x + width) { + stbrp_node *next = cur->next; + // move the current node to the free list + cur->next = context->free_head; + context->free_head = cur; + cur = next; + } + + // stitch the list back in + node->next = cur; + + if (cur->x < res.x + width) + cur->x = (stbrp_coord) (res.x + width); + +#ifdef _DEBUG + cur = context->active_head; + while (cur->x < context->width) { + STBRP_ASSERT(cur->x < cur->next->x); + cur = cur->next; + } + STBRP_ASSERT(cur->next == NULL); + + { + stbrp_node *L1 = NULL, *L2 = NULL; + int count=0; + cur = context->active_head; + while (cur) { + L1 = cur; + cur = cur->next; + ++count; + } + cur = context->free_head; + while (cur) { + L2 = cur; + cur = cur->next; + ++count; + } + STBRP_ASSERT(count == context->num_nodes+2); + } +#endif + + return res; +} + +static int rect_height_compare(const void *a, const void *b) +{ + stbrp_rect *p = (stbrp_rect *) a; + stbrp_rect *q = (stbrp_rect *) b; + if (p->h > q->h) + return -1; + if (p->h < q->h) + return 1; + return (p->w > q->w) ? -1 : (p->w < q->w); +} + +static int rect_width_compare(const void *a, const void *b) +{ + stbrp_rect *p = (stbrp_rect *) a; + stbrp_rect *q = (stbrp_rect *) b; + if (p->w > q->w) + return -1; + if (p->w < q->w) + return 1; + return (p->h > q->h) ? -1 : (p->h < q->h); +} + +static int rect_original_order(const void *a, const void *b) +{ + stbrp_rect *p = (stbrp_rect *) a; + stbrp_rect *q = (stbrp_rect *) b; + return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); +} + +#ifdef STBRP_LARGE_RECTS +#define STBRP__MAXVAL 0xffffffff +#else +#define STBRP__MAXVAL 0xffff +#endif + +STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) +{ + int i; + + // we use the 'was_packed' field internally to allow sorting/unsorting + for (i=0; i < num_rects; ++i) { + rects[i].was_packed = i; + #ifndef STBRP_LARGE_RECTS + STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff); + #endif + } + + // sort according to heuristic + STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); + + for (i=0; i < num_rects; ++i) { + if (rects[i].w == 0 || rects[i].h == 0) { + rects[i].x = rects[i].y = 0; // empty rect needs no space + } else { + stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); + if (fr.prev_link) { + rects[i].x = (stbrp_coord) fr.x; + rects[i].y = (stbrp_coord) fr.y; + } else { + rects[i].x = rects[i].y = STBRP__MAXVAL; + } + } + } + + // unsort + STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); + + // set was_packed flags + for (i=0; i < num_rects; ++i) + rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); +} +#endif diff --git a/CameraParameterEstimation/apps/basics/extern/imgui/stb_textedit.h b/CameraParameterEstimation/apps/basics/extern/imgui/stb_textedit.h new file mode 100644 index 0000000..2dddefe --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/imgui/stb_textedit.h @@ -0,0 +1,1320 @@ +// [ImGui] this is a slightly modified version of stb_truetype.h 1.8 +// [ImGui] - fixed a state corruption/crash bug in stb_text_redo and stb_textedit_discard_redo (#715) +// [ImGui] - fixed a crash bug in stb_textedit_discard_redo (#681) +// [ImGui] - fixed some minor warnings +// [ImGui] - added STB_TEXTEDIT_MOVEWORDLEFT/STB_TEXTEDIT_MOVEWORDRIGHT custom handler (#473) + +// stb_textedit.h - v1.8 - public domain - Sean Barrett +// Development of this library was sponsored by RAD Game Tools +// +// This C header file implements the guts of a multi-line text-editing +// widget; you implement display, word-wrapping, and low-level string +// insertion/deletion, and stb_textedit will map user inputs into +// insertions & deletions, plus updates to the cursor position, +// selection state, and undo state. +// +// It is intended for use in games and other systems that need to build +// their own custom widgets and which do not have heavy text-editing +// requirements (this library is not recommended for use for editing large +// texts, as its performance does not scale and it has limited undo). +// +// Non-trivial behaviors are modelled after Windows text controls. +// +// +// LICENSE +// +// This software is dual-licensed to the public domain and under the following +// license: you are granted a perpetual, irrevocable license to copy, modify, +// publish, and distribute this file as you see fit. +// +// +// DEPENDENCIES +// +// Uses the C runtime function 'memmove', which you can override +// by defining STB_TEXTEDIT_memmove before the implementation. +// Uses no other functions. Performs no runtime allocations. +// +// +// VERSION HISTORY +// +// 1.8 (2016-04-02) better keyboard handling when mouse button is down +// 1.7 (2015-09-13) change y range handling in case baseline is non-0 +// 1.6 (2015-04-15) allow STB_TEXTEDIT_memmove +// 1.5 (2014-09-10) add support for secondary keys for OS X +// 1.4 (2014-08-17) fix signed/unsigned warnings +// 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary +// 1.2 (2014-05-27) fix some RAD types that had crept into the new code +// 1.1 (2013-12-15) move-by-word (requires STB_TEXTEDIT_IS_SPACE ) +// 1.0 (2012-07-26) improve documentation, initial public release +// 0.3 (2012-02-24) bugfixes, single-line mode; insert mode +// 0.2 (2011-11-28) fixes to undo/redo +// 0.1 (2010-07-08) initial version +// +// ADDITIONAL CONTRIBUTORS +// +// Ulf Winklemann: move-by-word in 1.1 +// Fabian Giesen: secondary key inputs in 1.5 +// Martins Mozeiko: STB_TEXTEDIT_memmove +// +// Bugfixes: +// Scott Graham +// Daniel Keller +// Omar Cornut +// +// USAGE +// +// This file behaves differently depending on what symbols you define +// before including it. +// +// +// Header-file mode: +// +// If you do not define STB_TEXTEDIT_IMPLEMENTATION before including this, +// it will operate in "header file" mode. In this mode, it declares a +// single public symbol, STB_TexteditState, which encapsulates the current +// state of a text widget (except for the string, which you will store +// separately). +// +// To compile in this mode, you must define STB_TEXTEDIT_CHARTYPE to a +// primitive type that defines a single character (e.g. char, wchar_t, etc). +// +// To save space or increase undo-ability, you can optionally define the +// following things that are used by the undo system: +// +// STB_TEXTEDIT_POSITIONTYPE small int type encoding a valid cursor position +// STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow +// STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer +// +// If you don't define these, they are set to permissive types and +// moderate sizes. The undo system does no memory allocations, so +// it grows STB_TexteditState by the worst-case storage which is (in bytes): +// +// [4 + sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT +// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT +// +// +// Implementation mode: +// +// If you define STB_TEXTEDIT_IMPLEMENTATION before including this, it +// will compile the implementation of the text edit widget, depending +// on a large number of symbols which must be defined before the include. +// +// The implementation is defined only as static functions. You will then +// need to provide your own APIs in the same file which will access the +// static functions. +// +// The basic concept is that you provide a "string" object which +// behaves like an array of characters. stb_textedit uses indices to +// refer to positions in the string, implicitly representing positions +// in the displayed textedit. This is true for both plain text and +// rich text; even with rich text stb_truetype interacts with your +// code as if there was an array of all the displayed characters. +// +// Symbols that must be the same in header-file and implementation mode: +// +// STB_TEXTEDIT_CHARTYPE the character type +// STB_TEXTEDIT_POSITIONTYPE small type that a valid cursor position +// STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow +// STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer +// +// Symbols you must define for implementation mode: +// +// STB_TEXTEDIT_STRING the type of object representing a string being edited, +// typically this is a wrapper object with other data you need +// +// STB_TEXTEDIT_STRINGLEN(obj) the length of the string (ideally O(1)) +// STB_TEXTEDIT_LAYOUTROW(&r,obj,n) returns the results of laying out a line of characters +// starting from character #n (see discussion below) +// STB_TEXTEDIT_GETWIDTH(obj,n,i) returns the pixel delta from the xpos of the i'th character +// to the xpos of the i+1'th char for a line of characters +// starting at character #n (i.e. accounts for kerning +// with previous char) +// STB_TEXTEDIT_KEYTOTEXT(k) maps a keyboard input to an insertable character +// (return type is int, -1 means not valid to insert) +// STB_TEXTEDIT_GETCHAR(obj,i) returns the i'th character of obj, 0-based +// STB_TEXTEDIT_NEWLINE the character returned by _GETCHAR() we recognize +// as manually wordwrapping for end-of-line positioning +// +// STB_TEXTEDIT_DELETECHARS(obj,i,n) delete n characters starting at i +// STB_TEXTEDIT_INSERTCHARS(obj,i,c*,n) insert n characters at i (pointed to by STB_TEXTEDIT_CHARTYPE*) +// +// STB_TEXTEDIT_K_SHIFT a power of two that is or'd in to a keyboard input to represent the shift key +// +// STB_TEXTEDIT_K_LEFT keyboard input to move cursor left +// STB_TEXTEDIT_K_RIGHT keyboard input to move cursor right +// STB_TEXTEDIT_K_UP keyboard input to move cursor up +// STB_TEXTEDIT_K_DOWN keyboard input to move cursor down +// STB_TEXTEDIT_K_LINESTART keyboard input to move cursor to start of line // e.g. HOME +// STB_TEXTEDIT_K_LINEEND keyboard input to move cursor to end of line // e.g. END +// STB_TEXTEDIT_K_TEXTSTART keyboard input to move cursor to start of text // e.g. ctrl-HOME +// STB_TEXTEDIT_K_TEXTEND keyboard input to move cursor to end of text // e.g. ctrl-END +// STB_TEXTEDIT_K_DELETE keyboard input to delete selection or character under cursor +// STB_TEXTEDIT_K_BACKSPACE keyboard input to delete selection or character left of cursor +// STB_TEXTEDIT_K_UNDO keyboard input to perform undo +// STB_TEXTEDIT_K_REDO keyboard input to perform redo +// +// Optional: +// STB_TEXTEDIT_K_INSERT keyboard input to toggle insert mode +// STB_TEXTEDIT_IS_SPACE(ch) true if character is whitespace (e.g. 'isspace'), +// required for default WORDLEFT/WORDRIGHT handlers +// STB_TEXTEDIT_MOVEWORDLEFT(obj,i) custom handler for WORDLEFT, returns index to move cursor to +// STB_TEXTEDIT_MOVEWORDRIGHT(obj,i) custom handler for WORDRIGHT, returns index to move cursor to +// STB_TEXTEDIT_K_WORDLEFT keyboard input to move cursor left one word // e.g. ctrl-LEFT +// STB_TEXTEDIT_K_WORDRIGHT keyboard input to move cursor right one word // e.g. ctrl-RIGHT +// STB_TEXTEDIT_K_LINESTART2 secondary keyboard input to move cursor to start of line +// STB_TEXTEDIT_K_LINEEND2 secondary keyboard input to move cursor to end of line +// STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text +// STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text +// +// Todo: +// STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page +// STB_TEXTEDIT_K_PGDOWN keyboard input to move cursor down a page +// +// Keyboard input must be encoded as a single integer value; e.g. a character code +// and some bitflags that represent shift states. to simplify the interface, SHIFT must +// be a bitflag, so we can test the shifted state of cursor movements to allow selection, +// i.e. (STB_TEXTED_K_RIGHT|STB_TEXTEDIT_K_SHIFT) should be shifted right-arrow. +// +// You can encode other things, such as CONTROL or ALT, in additional bits, and +// then test for their presence in e.g. STB_TEXTEDIT_K_WORDLEFT. For example, +// my Windows implementations add an additional CONTROL bit, and an additional KEYDOWN +// bit. Then all of the STB_TEXTEDIT_K_ values bitwise-or in the KEYDOWN bit, +// and I pass both WM_KEYDOWN and WM_CHAR events to the "key" function in the +// API below. The control keys will only match WM_KEYDOWN events because of the +// keydown bit I add, and STB_TEXTEDIT_KEYTOTEXT only tests for the KEYDOWN +// bit so it only decodes WM_CHAR events. +// +// STB_TEXTEDIT_LAYOUTROW returns information about the shape of one displayed +// row of characters assuming they start on the i'th character--the width and +// the height and the number of characters consumed. This allows this library +// to traverse the entire layout incrementally. You need to compute word-wrapping +// here. +// +// Each textfield keeps its own insert mode state, which is not how normal +// applications work. To keep an app-wide insert mode, update/copy the +// "insert_mode" field of STB_TexteditState before/after calling API functions. +// +// API +// +// void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) +// +// void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) +// void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) +// int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +// int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len) +// void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int key) +// +// Each of these functions potentially updates the string and updates the +// state. +// +// initialize_state: +// set the textedit state to a known good default state when initially +// constructing the textedit. +// +// click: +// call this with the mouse x,y on a mouse down; it will update the cursor +// and reset the selection start/end to the cursor point. the x,y must +// be relative to the text widget, with (0,0) being the top left. +// +// drag: +// call this with the mouse x,y on a mouse drag/up; it will update the +// cursor and the selection end point +// +// cut: +// call this to delete the current selection; returns true if there was +// one. you should FIRST copy the current selection to the system paste buffer. +// (To copy, just copy the current selection out of the string yourself.) +// +// paste: +// call this to paste text at the current cursor point or over the current +// selection if there is one. +// +// key: +// call this for keyboard inputs sent to the textfield. you can use it +// for "key down" events or for "translated" key events. if you need to +// do both (as in Win32), or distinguish Unicode characters from control +// inputs, set a high bit to distinguish the two; then you can define the +// various definitions like STB_TEXTEDIT_K_LEFT have the is-key-event bit +// set, and make STB_TEXTEDIT_KEYTOCHAR check that the is-key-event bit is +// clear. +// +// When rendering, you can read the cursor position and selection state from +// the STB_TexteditState. +// +// +// Notes: +// +// This is designed to be usable in IMGUI, so it allows for the possibility of +// running in an IMGUI that has NOT cached the multi-line layout. For this +// reason, it provides an interface that is compatible with computing the +// layout incrementally--we try to make sure we make as few passes through +// as possible. (For example, to locate the mouse pointer in the text, we +// could define functions that return the X and Y positions of characters +// and binary search Y and then X, but if we're doing dynamic layout this +// will run the layout algorithm many times, so instead we manually search +// forward in one pass. Similar logic applies to e.g. up-arrow and +// down-arrow movement.) +// +// If it's run in a widget that *has* cached the layout, then this is less +// efficient, but it's not horrible on modern computers. But you wouldn't +// want to edit million-line files with it. + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//// +//// Header-file mode +//// +//// + +#ifndef INCLUDE_STB_TEXTEDIT_H +#define INCLUDE_STB_TEXTEDIT_H + +//////////////////////////////////////////////////////////////////////// +// +// STB_TexteditState +// +// Definition of STB_TexteditState which you should store +// per-textfield; it includes cursor position, selection state, +// and undo state. +// + +#ifndef STB_TEXTEDIT_UNDOSTATECOUNT +#define STB_TEXTEDIT_UNDOSTATECOUNT 99 +#endif +#ifndef STB_TEXTEDIT_UNDOCHARCOUNT +#define STB_TEXTEDIT_UNDOCHARCOUNT 999 +#endif +#ifndef STB_TEXTEDIT_CHARTYPE +#define STB_TEXTEDIT_CHARTYPE int +#endif +#ifndef STB_TEXTEDIT_POSITIONTYPE +#define STB_TEXTEDIT_POSITIONTYPE int +#endif + +typedef struct +{ + // private data + STB_TEXTEDIT_POSITIONTYPE where; + short insert_length; + short delete_length; + short char_storage; +} StbUndoRecord; + +typedef struct +{ + // private data + StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT]; + STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT]; + short undo_point, redo_point; + short undo_char_point, redo_char_point; +} StbUndoState; + +typedef struct +{ + ///////////////////// + // + // public data + // + + int cursor; + // position of the text cursor within the string + + int select_start; // selection start point + int select_end; + // selection start and end point in characters; if equal, no selection. + // note that start may be less than or greater than end (e.g. when + // dragging the mouse, start is where the initial click was, and you + // can drag in either direction) + + unsigned char insert_mode; + // each textfield keeps its own insert mode state. to keep an app-wide + // insert mode, copy this value in/out of the app state + + ///////////////////// + // + // private data + // + unsigned char cursor_at_end_of_line; // not implemented yet + unsigned char initialized; + unsigned char has_preferred_x; + unsigned char single_line; + unsigned char padding1, padding2, padding3; + float preferred_x; // this determines where the cursor up/down tries to seek to along x + StbUndoState undostate; +} STB_TexteditState; + + +//////////////////////////////////////////////////////////////////////// +// +// StbTexteditRow +// +// Result of layout query, used by stb_textedit to determine where +// the text in each row is. + +// result of layout query +typedef struct +{ + float x0,x1; // starting x location, end x location (allows for align=right, etc) + float baseline_y_delta; // position of baseline relative to previous row's baseline + float ymin,ymax; // height of row above and below baseline + int num_chars; +} StbTexteditRow; +#endif //INCLUDE_STB_TEXTEDIT_H + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//// +//// Implementation mode +//// +//// + + +// implementation isn't include-guarded, since it might have indirectly +// included just the "header" portion +#ifdef STB_TEXTEDIT_IMPLEMENTATION + +#ifndef STB_TEXTEDIT_memmove +#include +#define STB_TEXTEDIT_memmove memmove +#endif + + +///////////////////////////////////////////////////////////////////////////// +// +// Mouse input handling +// + +// traverse the layout to locate the nearest character to a display position +static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y) +{ + StbTexteditRow r; + int n = STB_TEXTEDIT_STRINGLEN(str); + float base_y = 0, prev_x; + int i=0, k; + + r.x0 = r.x1 = 0; + r.ymin = r.ymax = 0; + r.num_chars = 0; + + // search rows to find one that straddles 'y' + while (i < n) { + STB_TEXTEDIT_LAYOUTROW(&r, str, i); + if (r.num_chars <= 0) + return n; + + if (i==0 && y < base_y + r.ymin) + return 0; + + if (y < base_y + r.ymax) + break; + + i += r.num_chars; + base_y += r.baseline_y_delta; + } + + // below all text, return 'after' last character + if (i >= n) + return n; + + // check if it's before the beginning of the line + if (x < r.x0) + return i; + + // check if it's before the end of the line + if (x < r.x1) { + // search characters in row for one that straddles 'x' + k = i; + prev_x = r.x0; + for (i=0; i < r.num_chars; ++i) { + float w = STB_TEXTEDIT_GETWIDTH(str, k, i); + if (x < prev_x+w) { + if (x < prev_x+w/2) + return k+i; + else + return k+i+1; + } + prev_x += w; + } + // shouldn't happen, but if it does, fall through to end-of-line case + } + + // if the last character is a newline, return that. otherwise return 'after' the last character + if (STB_TEXTEDIT_GETCHAR(str, i+r.num_chars-1) == STB_TEXTEDIT_NEWLINE) + return i+r.num_chars-1; + else + return i+r.num_chars; +} + +// API click: on mouse down, move the cursor to the clicked location, and reset the selection +static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) +{ + state->cursor = stb_text_locate_coord(str, x, y); + state->select_start = state->cursor; + state->select_end = state->cursor; + state->has_preferred_x = 0; +} + +// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location +static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) +{ + int p = stb_text_locate_coord(str, x, y); + if (state->select_start == state->select_end) + state->select_start = state->cursor; + state->cursor = state->select_end = p; +} + +///////////////////////////////////////////////////////////////////////////// +// +// Keyboard input handling +// + +// forward declarations +static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state); +static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state); +static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length); +static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length); +static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length); + +typedef struct +{ + float x,y; // position of n'th character + float height; // height of line + int first_char, length; // first char of row, and length + int prev_first; // first char of previous row +} StbFindState; + +// find the x/y location of a character, and remember info about the previous row in +// case we get a move-up event (for page up, we'll have to rescan) +static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line) +{ + StbTexteditRow r; + int prev_start = 0; + int z = STB_TEXTEDIT_STRINGLEN(str); + int i=0, first; + + if (n == z) { + // if it's at the end, then find the last line -- simpler than trying to + // explicitly handle this case in the regular code + if (single_line) { + STB_TEXTEDIT_LAYOUTROW(&r, str, 0); + find->y = 0; + find->first_char = 0; + find->length = z; + find->height = r.ymax - r.ymin; + find->x = r.x1; + } else { + find->y = 0; + find->x = 0; + find->height = 1; + while (i < z) { + STB_TEXTEDIT_LAYOUTROW(&r, str, i); + prev_start = i; + i += r.num_chars; + } + find->first_char = i; + find->length = 0; + find->prev_first = prev_start; + } + return; + } + + // search rows to find the one that straddles character n + find->y = 0; + + for(;;) { + STB_TEXTEDIT_LAYOUTROW(&r, str, i); + if (n < i + r.num_chars) + break; + prev_start = i; + i += r.num_chars; + find->y += r.baseline_y_delta; + } + + find->first_char = first = i; + find->length = r.num_chars; + find->height = r.ymax - r.ymin; + find->prev_first = prev_start; + + // now scan to find xpos + find->x = r.x0; + i = 0; + for (i=0; first+i < n; ++i) + find->x += STB_TEXTEDIT_GETWIDTH(str, first, i); +} + +#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end) + +// make the selection/cursor state valid if client altered the string +static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + int n = STB_TEXTEDIT_STRINGLEN(str); + if (STB_TEXT_HAS_SELECTION(state)) { + if (state->select_start > n) state->select_start = n; + if (state->select_end > n) state->select_end = n; + // if clamping forced them to be equal, move the cursor to match + if (state->select_start == state->select_end) + state->cursor = state->select_start; + } + if (state->cursor > n) state->cursor = n; +} + +// delete characters while updating undo +static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len) +{ + stb_text_makeundo_delete(str, state, where, len); + STB_TEXTEDIT_DELETECHARS(str, where, len); + state->has_preferred_x = 0; +} + +// delete the section +static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + stb_textedit_clamp(str, state); + if (STB_TEXT_HAS_SELECTION(state)) { + if (state->select_start < state->select_end) { + stb_textedit_delete(str, state, state->select_start, state->select_end - state->select_start); + state->select_end = state->cursor = state->select_start; + } else { + stb_textedit_delete(str, state, state->select_end, state->select_start - state->select_end); + state->select_start = state->cursor = state->select_end; + } + state->has_preferred_x = 0; + } +} + +// canoncialize the selection so start <= end +static void stb_textedit_sortselection(STB_TexteditState *state) +{ + if (state->select_end < state->select_start) { + int temp = state->select_end; + state->select_end = state->select_start; + state->select_start = temp; + } +} + +// move cursor to first character of selection +static void stb_textedit_move_to_first(STB_TexteditState *state) +{ + if (STB_TEXT_HAS_SELECTION(state)) { + stb_textedit_sortselection(state); + state->cursor = state->select_start; + state->select_end = state->select_start; + state->has_preferred_x = 0; + } +} + +// move cursor to last character of selection +static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + if (STB_TEXT_HAS_SELECTION(state)) { + stb_textedit_sortselection(state); + stb_textedit_clamp(str, state); + state->cursor = state->select_end; + state->select_start = state->select_end; + state->has_preferred_x = 0; + } +} + +#ifdef STB_TEXTEDIT_IS_SPACE +static int is_word_boundary( STB_TEXTEDIT_STRING *_str, int _idx ) +{ + return _idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str,_idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str, _idx) ) ) : 1; +} + +#ifndef STB_TEXTEDIT_MOVEWORDLEFT +static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *_str, int c ) +{ + while( c >= 0 && !is_word_boundary( _str, c ) ) + --c; + + if( c < 0 ) + c = 0; + + return c; +} +#define STB_TEXTEDIT_MOVEWORDLEFT stb_textedit_move_to_word_previous +#endif + +#ifndef STB_TEXTEDIT_MOVEWORDRIGHT +static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *_str, int c ) +{ + const int len = STB_TEXTEDIT_STRINGLEN(_str); + while( c < len && !is_word_boundary( _str, c ) ) + ++c; + + if( c > len ) + c = len; + + return c; +} +#define STB_TEXTEDIT_MOVEWORDRIGHT stb_textedit_move_to_word_next +#endif + +#endif + +// update selection and cursor to match each other +static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state) +{ + if (!STB_TEXT_HAS_SELECTION(state)) + state->select_start = state->select_end = state->cursor; + else + state->cursor = state->select_end; +} + +// API cut: delete selection +static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + if (STB_TEXT_HAS_SELECTION(state)) { + stb_textedit_delete_selection(str,state); // implicity clamps + state->has_preferred_x = 0; + return 1; + } + return 0; +} + +// API paste: replace existing selection with passed-in text +static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len) +{ + STB_TEXTEDIT_CHARTYPE *text = (STB_TEXTEDIT_CHARTYPE *) ctext; + // if there's a selection, the paste should delete it + stb_textedit_clamp(str, state); + stb_textedit_delete_selection(str,state); + // try to insert the characters + if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) { + stb_text_makeundo_insert(state, state->cursor, len); + state->cursor += len; + state->has_preferred_x = 0; + return 1; + } + // remove the undo since we didn't actually insert the characters + if (state->undostate.undo_point) + --state->undostate.undo_point; + return 0; +} + +// API key: process a keyboard input +static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int key) +{ +retry: + switch (key) { + default: { + int c = STB_TEXTEDIT_KEYTOTEXT(key); + if (c > 0) { + STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c; + + // can't add newline in single-line mode + if (c == '\n' && state->single_line) + break; + + if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) { + stb_text_makeundo_replace(str, state, state->cursor, 1, 1); + STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1); + if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { + ++state->cursor; + state->has_preferred_x = 0; + } + } else { + stb_textedit_delete_selection(str,state); // implicity clamps + if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { + stb_text_makeundo_insert(state, state->cursor, 1); + ++state->cursor; + state->has_preferred_x = 0; + } + } + } + break; + } + +#ifdef STB_TEXTEDIT_K_INSERT + case STB_TEXTEDIT_K_INSERT: + state->insert_mode = !state->insert_mode; + break; +#endif + + case STB_TEXTEDIT_K_UNDO: + stb_text_undo(str, state); + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_REDO: + stb_text_redo(str, state); + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_LEFT: + // if currently there's a selection, move cursor to start of selection + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_first(state); + else + if (state->cursor > 0) + --state->cursor; + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_RIGHT: + // if currently there's a selection, move cursor to end of selection + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_last(str, state); + else + ++state->cursor; + stb_textedit_clamp(str, state); + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_LEFT | STB_TEXTEDIT_K_SHIFT: + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + // move selection left + if (state->select_end > 0) + --state->select_end; + state->cursor = state->select_end; + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_MOVEWORDLEFT + case STB_TEXTEDIT_K_WORDLEFT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_first(state); + else { + state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor-1); + stb_textedit_clamp( str, state ); + } + break; + + case STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT: + if( !STB_TEXT_HAS_SELECTION( state ) ) + stb_textedit_prep_selection_at_cursor(state); + + state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor-1); + state->select_end = state->cursor; + + stb_textedit_clamp( str, state ); + break; +#endif + +#ifdef STB_TEXTEDIT_MOVEWORDRIGHT + case STB_TEXTEDIT_K_WORDRIGHT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_last(str, state); + else { + state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor+1); + stb_textedit_clamp( str, state ); + } + break; + + case STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT: + if( !STB_TEXT_HAS_SELECTION( state ) ) + stb_textedit_prep_selection_at_cursor(state); + + state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor+1); + state->select_end = state->cursor; + + stb_textedit_clamp( str, state ); + break; +#endif + + case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT: + stb_textedit_prep_selection_at_cursor(state); + // move selection right + ++state->select_end; + stb_textedit_clamp(str, state); + state->cursor = state->select_end; + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_DOWN: + case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + StbTexteditRow row; + int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; + + if (state->single_line) { + // on windows, up&down in single-line behave like left&right + key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT); + goto retry; + } + + if (sel) + stb_textedit_prep_selection_at_cursor(state); + else if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_last(str,state); + + // compute current position of cursor point + stb_textedit_clamp(str, state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + + // now find character position down a row + if (find.length) { + float goal_x = state->has_preferred_x ? state->preferred_x : find.x; + float x; + int start = find.first_char + find.length; + state->cursor = start; + STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); + x = row.x0; + for (i=0; i < row.num_chars; ++i) { + float dx = STB_TEXTEDIT_GETWIDTH(str, start, i); + #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE + if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) + break; + #endif + x += dx; + if (x > goal_x) + break; + ++state->cursor; + } + stb_textedit_clamp(str, state); + + state->has_preferred_x = 1; + state->preferred_x = goal_x; + + if (sel) + state->select_end = state->cursor; + } + break; + } + + case STB_TEXTEDIT_K_UP: + case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + StbTexteditRow row; + int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; + + if (state->single_line) { + // on windows, up&down become left&right + key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT); + goto retry; + } + + if (sel) + stb_textedit_prep_selection_at_cursor(state); + else if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_first(state); + + // compute current position of cursor point + stb_textedit_clamp(str, state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + + // can only go up if there's a previous row + if (find.prev_first != find.first_char) { + // now find character position up a row + float goal_x = state->has_preferred_x ? state->preferred_x : find.x; + float x; + state->cursor = find.prev_first; + STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); + x = row.x0; + for (i=0; i < row.num_chars; ++i) { + float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i); + #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE + if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) + break; + #endif + x += dx; + if (x > goal_x) + break; + ++state->cursor; + } + stb_textedit_clamp(str, state); + + state->has_preferred_x = 1; + state->preferred_x = goal_x; + + if (sel) + state->select_end = state->cursor; + } + break; + } + + case STB_TEXTEDIT_K_DELETE: + case STB_TEXTEDIT_K_DELETE | STB_TEXTEDIT_K_SHIFT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_delete_selection(str, state); + else { + int n = STB_TEXTEDIT_STRINGLEN(str); + if (state->cursor < n) + stb_textedit_delete(str, state, state->cursor, 1); + } + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_BACKSPACE: + case STB_TEXTEDIT_K_BACKSPACE | STB_TEXTEDIT_K_SHIFT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_delete_selection(str, state); + else { + stb_textedit_clamp(str, state); + if (state->cursor > 0) { + stb_textedit_delete(str, state, state->cursor-1, 1); + --state->cursor; + } + } + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_K_TEXTSTART2 + case STB_TEXTEDIT_K_TEXTSTART2: +#endif + case STB_TEXTEDIT_K_TEXTSTART: + state->cursor = state->select_start = state->select_end = 0; + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_K_TEXTEND2 + case STB_TEXTEDIT_K_TEXTEND2: +#endif + case STB_TEXTEDIT_K_TEXTEND: + state->cursor = STB_TEXTEDIT_STRINGLEN(str); + state->select_start = state->select_end = 0; + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_K_TEXTSTART2 + case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT: +#endif + case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT: + stb_textedit_prep_selection_at_cursor(state); + state->cursor = state->select_end = 0; + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_K_TEXTEND2 + case STB_TEXTEDIT_K_TEXTEND2 | STB_TEXTEDIT_K_SHIFT: +#endif + case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT: + stb_textedit_prep_selection_at_cursor(state); + state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str); + state->has_preferred_x = 0; + break; + + +#ifdef STB_TEXTEDIT_K_LINESTART2 + case STB_TEXTEDIT_K_LINESTART2: +#endif + case STB_TEXTEDIT_K_LINESTART: { + StbFindState find; + stb_textedit_clamp(str, state); + stb_textedit_move_to_first(state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + state->cursor = find.first_char; + state->has_preferred_x = 0; + break; + } + +#ifdef STB_TEXTEDIT_K_LINEEND2 + case STB_TEXTEDIT_K_LINEEND2: +#endif + case STB_TEXTEDIT_K_LINEEND: { + StbFindState find; + stb_textedit_clamp(str, state); + stb_textedit_move_to_first(state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + + state->has_preferred_x = 0; + state->cursor = find.first_char + find.length; + if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE) + --state->cursor; + break; + } + +#ifdef STB_TEXTEDIT_K_LINESTART2 + case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT: +#endif + case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + state->cursor = state->select_end = find.first_char; + state->has_preferred_x = 0; + break; + } + +#ifdef STB_TEXTEDIT_K_LINEEND2 + case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT: +#endif + case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + state->has_preferred_x = 0; + state->cursor = find.first_char + find.length; + if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE) + --state->cursor; + state->select_end = state->cursor; + break; + } + +// @TODO: +// STB_TEXTEDIT_K_PGUP - move cursor up a page +// STB_TEXTEDIT_K_PGDOWN - move cursor down a page + } +} + +///////////////////////////////////////////////////////////////////////////// +// +// Undo processing +// +// @OPTIMIZE: the undo/redo buffer should be circular + +static void stb_textedit_flush_redo(StbUndoState *state) +{ + state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; + state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; +} + +// discard the oldest entry in the undo list +static void stb_textedit_discard_undo(StbUndoState *state) +{ + if (state->undo_point > 0) { + // if the 0th undo state has characters, clean those up + if (state->undo_rec[0].char_storage >= 0) { + int n = state->undo_rec[0].insert_length, i; + // delete n characters from all other records + state->undo_char_point = state->undo_char_point - (short) n; // vsnet05 + STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) ((size_t)state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE))); + for (i=0; i < state->undo_point; ++i) + if (state->undo_rec[i].char_storage >= 0) + state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it + } + --state->undo_point; + STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) ((size_t)state->undo_point*sizeof(state->undo_rec[0]))); + } +} + +// discard the oldest entry in the redo list--it's bad if this +// ever happens, but because undo & redo have to store the actual +// characters in different cases, the redo character buffer can +// fill up even though the undo buffer didn't +static void stb_textedit_discard_redo(StbUndoState *state) +{ + int k = STB_TEXTEDIT_UNDOSTATECOUNT-1; + + if (state->redo_point <= k) { + // if the k'th undo state has characters, clean those up + if (state->undo_rec[k].char_storage >= 0) { + int n = state->undo_rec[k].insert_length, i; + // delete n characters from all other records + state->redo_char_point = state->redo_char_point + (short) n; // vsnet05 + STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((size_t)(STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE))); + for (i=state->redo_point; i < k; ++i) + if (state->undo_rec[i].char_storage >= 0) + state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05 + } + STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point, state->undo_rec + state->redo_point-1, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]))); + ++state->redo_point; + } +} + +static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numchars) +{ + // any time we create a new undo record, we discard redo + stb_textedit_flush_redo(state); + + // if we have no free records, we have to make room, by sliding the + // existing records down + if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT) + stb_textedit_discard_undo(state); + + // if the characters to store won't possibly fit in the buffer, we can't undo + if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) { + state->undo_point = 0; + state->undo_char_point = 0; + return NULL; + } + + // if we don't have enough free characters in the buffer, we have to make room + while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT) + stb_textedit_discard_undo(state); + + return &state->undo_rec[state->undo_point++]; +} + +static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len) +{ + StbUndoRecord *r = stb_text_create_undo_record(state, insert_len); + if (r == NULL) + return NULL; + + r->where = pos; + r->insert_length = (short) insert_len; + r->delete_length = (short) delete_len; + + if (insert_len == 0) { + r->char_storage = -1; + return NULL; + } else { + r->char_storage = state->undo_char_point; + state->undo_char_point = state->undo_char_point + (short) insert_len; + return &state->undo_char[r->char_storage]; + } +} + +static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + StbUndoState *s = &state->undostate; + StbUndoRecord u, *r; + if (s->undo_point == 0) + return; + + // we need to do two things: apply the undo record, and create a redo record + u = s->undo_rec[s->undo_point-1]; + r = &s->undo_rec[s->redo_point-1]; + r->char_storage = -1; + + r->insert_length = u.delete_length; + r->delete_length = u.insert_length; + r->where = u.where; + + if (u.delete_length) { + // if the undo record says to delete characters, then the redo record will + // need to re-insert the characters that get deleted, so we need to store + // them. + + // there are three cases: + // there's enough room to store the characters + // characters stored for *redoing* don't leave room for redo + // characters stored for *undoing* don't leave room for redo + // if the last is true, we have to bail + + if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) { + // the undo records take up too much character space; there's no space to store the redo characters + r->insert_length = 0; + } else { + int i; + + // there's definitely room to store the characters eventually + while (s->undo_char_point + u.delete_length > s->redo_char_point) { + // there's currently not enough room, so discard a redo record + stb_textedit_discard_redo(s); + // should never happen: + if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) + return; + } + r = &s->undo_rec[s->redo_point-1]; + + r->char_storage = s->redo_char_point - u.delete_length; + s->redo_char_point = s->redo_char_point - (short) u.delete_length; + + // now save the characters + for (i=0; i < u.delete_length; ++i) + s->undo_char[r->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u.where + i); + } + + // now we can carry out the deletion + STB_TEXTEDIT_DELETECHARS(str, u.where, u.delete_length); + } + + // check type of recorded action: + if (u.insert_length) { + // easy case: was a deletion, so we need to insert n characters + STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length); + s->undo_char_point -= u.insert_length; + } + + state->cursor = u.where + u.insert_length; + + s->undo_point--; + s->redo_point--; +} + +static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + StbUndoState *s = &state->undostate; + StbUndoRecord *u, r; + if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) + return; + + // we need to do two things: apply the redo record, and create an undo record + u = &s->undo_rec[s->undo_point]; + r = s->undo_rec[s->redo_point]; + + // we KNOW there must be room for the undo record, because the redo record + // was derived from an undo record + + u->delete_length = r.insert_length; + u->insert_length = r.delete_length; + u->where = r.where; + u->char_storage = -1; + + if (r.delete_length) { + // the redo record requires us to delete characters, so the undo record + // needs to store the characters + + if (s->undo_char_point + u->insert_length > s->redo_char_point) { + u->insert_length = 0; + u->delete_length = 0; + } else { + int i; + u->char_storage = s->undo_char_point; + s->undo_char_point = s->undo_char_point + u->insert_length; + + // now save the characters + for (i=0; i < u->insert_length; ++i) + s->undo_char[u->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u->where + i); + } + + STB_TEXTEDIT_DELETECHARS(str, r.where, r.delete_length); + } + + if (r.insert_length) { + // easy case: need to insert n characters + STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length); + s->redo_char_point += r.insert_length; + } + + state->cursor = r.where + r.insert_length; + + s->undo_point++; + s->redo_point++; +} + +static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length) +{ + stb_text_createundo(&state->undostate, where, 0, length); +} + +static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length) +{ + int i; + STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0); + if (p) { + for (i=0; i < length; ++i) + p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); + } +} + +static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length) +{ + int i; + STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length); + if (p) { + for (i=0; i < old_length; ++i) + p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); + } +} + +// reset the state to default +static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_line) +{ + state->undostate.undo_point = 0; + state->undostate.undo_char_point = 0; + state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; + state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; + state->select_end = state->select_start = 0; + state->cursor = 0; + state->has_preferred_x = 0; + state->preferred_x = 0; + state->cursor_at_end_of_line = 0; + state->initialized = 1; + state->single_line = (unsigned char) is_single_line; + state->insert_mode = 0; +} + +// API initialize +static void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) +{ + stb_textedit_clear_state(state, is_single_line); +} +#endif//STB_TEXTEDIT_IMPLEMENTATION diff --git a/CameraParameterEstimation/apps/basics/extern/imgui/stb_truetype.h b/CameraParameterEstimation/apps/basics/extern/imgui/stb_truetype.h new file mode 100644 index 0000000..e6dae97 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/imgui/stb_truetype.h @@ -0,0 +1,3263 @@ +// stb_truetype.h - v1.10 - public domain +// authored from 2009-2015 by Sean Barrett / RAD Game Tools +// +// This library processes TrueType files: +// parse files +// extract glyph metrics +// extract glyph shapes +// render glyphs to one-channel bitmaps with antialiasing (box filter) +// +// Todo: +// non-MS cmaps +// crashproof on bad data +// hinting? (no longer patented) +// cleartype-style AA? +// optimize: use simple memory allocator for intermediates +// optimize: build edge-list directly from curves +// optimize: rasterize directly from curves? +// +// ADDITIONAL CONTRIBUTORS +// +// Mikko Mononen: compound shape support, more cmap formats +// Tor Andersson: kerning, subpixel rendering +// +// Misc other: +// Ryan Gordon +// Simon Glass +// +// Bug/warning reports/fixes: +// "Zer" on mollyrocket (with fix) +// Cass Everitt +// stoiko (Haemimont Games) +// Brian Hook +// Walter van Niftrik +// David Gow +// David Given +// Ivan-Assen Ivanov +// Anthony Pesch +// Johan Duparc +// Hou Qiming +// Fabian "ryg" Giesen +// Martins Mozeiko +// Cap Petschulat +// Omar Cornut +// github:aloucks +// Peter LaValle +// Sergey Popov +// Giumo X. Clanjor +// Higor Euripedes +// Thomas Fields +// Derek Vinyard +// +// VERSION HISTORY +// +// 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef +// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly +// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges +// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; +// variant PackFontRanges to pack and render in separate phases; +// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?); +// fixed an assert() bug in the new rasterizer +// replace assert() with STBTT_assert() in new rasterizer +// 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine) +// also more precise AA rasterizer, except if shapes overlap +// remove need for STBTT_sort +// 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC +// 1.04 (2015-04-15) typo in example +// 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes +// +// Full history can be found at the end of this file. +// +// LICENSE +// +// This software is dual-licensed to the public domain and under the following +// license: you are granted a perpetual, irrevocable license to copy, modify, +// publish, and distribute this file as you see fit. +// +// USAGE +// +// Include this file in whatever places neeed to refer to it. In ONE C/C++ +// file, write: +// #define STB_TRUETYPE_IMPLEMENTATION +// before the #include of this file. This expands out the actual +// implementation into that C/C++ file. +// +// To make the implementation private to the file that generates the implementation, +// #define STBTT_STATIC +// +// Simple 3D API (don't ship this, but it's fine for tools and quick start) +// stbtt_BakeFontBitmap() -- bake a font to a bitmap for use as texture +// stbtt_GetBakedQuad() -- compute quad to draw for a given char +// +// Improved 3D API (more shippable): +// #include "stb_rect_pack.h" -- optional, but you really want it +// stbtt_PackBegin() +// stbtt_PackSetOversample() -- for improved quality on small fonts +// stbtt_PackFontRanges() -- pack and renders +// stbtt_PackEnd() +// stbtt_GetPackedQuad() +// +// "Load" a font file from a memory buffer (you have to keep the buffer loaded) +// stbtt_InitFont() +// stbtt_GetFontOffsetForIndex() -- use for TTC font collections +// +// Render a unicode codepoint to a bitmap +// stbtt_GetCodepointBitmap() -- allocates and returns a bitmap +// stbtt_MakeCodepointBitmap() -- renders into bitmap you provide +// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be +// +// Character advance/positioning +// stbtt_GetCodepointHMetrics() +// stbtt_GetFontVMetrics() +// stbtt_GetCodepointKernAdvance() +// +// Starting with version 1.06, the rasterizer was replaced with a new, +// faster and generally-more-precise rasterizer. The new rasterizer more +// accurately measures pixel coverage for anti-aliasing, except in the case +// where multiple shapes overlap, in which case it overestimates the AA pixel +// coverage. Thus, anti-aliasing of intersecting shapes may look wrong. If +// this turns out to be a problem, you can re-enable the old rasterizer with +// #define STBTT_RASTERIZER_VERSION 1 +// which will incur about a 15% speed hit. +// +// ADDITIONAL DOCUMENTATION +// +// Immediately after this block comment are a series of sample programs. +// +// After the sample programs is the "header file" section. This section +// includes documentation for each API function. +// +// Some important concepts to understand to use this library: +// +// Codepoint +// Characters are defined by unicode codepoints, e.g. 65 is +// uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is +// the hiragana for "ma". +// +// Glyph +// A visual character shape (every codepoint is rendered as +// some glyph) +// +// Glyph index +// A font-specific integer ID representing a glyph +// +// Baseline +// Glyph shapes are defined relative to a baseline, which is the +// bottom of uppercase characters. Characters extend both above +// and below the baseline. +// +// Current Point +// As you draw text to the screen, you keep track of a "current point" +// which is the origin of each character. The current point's vertical +// position is the baseline. Even "baked fonts" use this model. +// +// Vertical Font Metrics +// The vertical qualities of the font, used to vertically position +// and space the characters. See docs for stbtt_GetFontVMetrics. +// +// Font Size in Pixels or Points +// The preferred interface for specifying font sizes in stb_truetype +// is to specify how tall the font's vertical extent should be in pixels. +// If that sounds good enough, skip the next paragraph. +// +// Most font APIs instead use "points", which are a common typographic +// measurement for describing font size, defined as 72 points per inch. +// stb_truetype provides a point API for compatibility. However, true +// "per inch" conventions don't make much sense on computer displays +// since they different monitors have different number of pixels per +// inch. For example, Windows traditionally uses a convention that +// there are 96 pixels per inch, thus making 'inch' measurements have +// nothing to do with inches, and thus effectively defining a point to +// be 1.333 pixels. Additionally, the TrueType font data provides +// an explicit scale factor to scale a given font's glyphs to points, +// but the author has observed that this scale factor is often wrong +// for non-commercial fonts, thus making fonts scaled in points +// according to the TrueType spec incoherently sized in practice. +// +// ADVANCED USAGE +// +// Quality: +// +// - Use the functions with Subpixel at the end to allow your characters +// to have subpixel positioning. Since the font is anti-aliased, not +// hinted, this is very import for quality. (This is not possible with +// baked fonts.) +// +// - Kerning is now supported, and if you're supporting subpixel rendering +// then kerning is worth using to give your text a polished look. +// +// Performance: +// +// - Convert Unicode codepoints to glyph indexes and operate on the glyphs; +// if you don't do this, stb_truetype is forced to do the conversion on +// every call. +// +// - There are a lot of memory allocations. We should modify it to take +// a temp buffer and allocate from the temp buffer (without freeing), +// should help performance a lot. +// +// NOTES +// +// The system uses the raw data found in the .ttf file without changing it +// and without building auxiliary data structures. This is a bit inefficient +// on little-endian systems (the data is big-endian), but assuming you're +// caching the bitmaps or glyph shapes this shouldn't be a big deal. +// +// It appears to be very hard to programmatically determine what font a +// given file is in a general way. I provide an API for this, but I don't +// recommend it. +// +// +// SOURCE STATISTICS (based on v0.6c, 2050 LOC) +// +// Documentation & header file 520 LOC \___ 660 LOC documentation +// Sample code 140 LOC / +// Truetype parsing 620 LOC ---- 620 LOC TrueType +// Software rasterization 240 LOC \ . +// Curve tesselation 120 LOC \__ 550 LOC Bitmap creation +// Bitmap management 100 LOC / +// Baked bitmap interface 70 LOC / +// Font name matching & access 150 LOC ---- 150 +// C runtime library abstraction 60 LOC ---- 60 +// +// +// PERFORMANCE MEASUREMENTS FOR 1.06: +// +// 32-bit 64-bit +// Previous release: 8.83 s 7.68 s +// Pool allocations: 7.72 s 6.34 s +// Inline sort : 6.54 s 5.65 s +// New rasterizer : 5.63 s 5.00 s + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +//// +//// SAMPLE PROGRAMS +//// +// +// Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless +// +#if 0 +#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation +#include "stb_truetype.h" + +unsigned char ttf_buffer[1<<20]; +unsigned char temp_bitmap[512*512]; + +stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs +GLuint ftex; + +void my_stbtt_initfont(void) +{ + fread(ttf_buffer, 1, 1<<20, fopen("c:/windows/fonts/times.ttf", "rb")); + stbtt_BakeFontBitmap(ttf_buffer,0, 32.0, temp_bitmap,512,512, 32,96, cdata); // no guarantee this fits! + // can free ttf_buffer at this point + glGenTextures(1, &ftex); + glBindTexture(GL_TEXTURE_2D, ftex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap); + // can free temp_bitmap at this point + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +} + +void my_stbtt_print(float x, float y, char *text) +{ + // assume orthographic projection with units = screen pixels, origin at top left + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, ftex); + glBegin(GL_QUADS); + while (*text) { + if (*text >= 32 && *text < 128) { + stbtt_aligned_quad q; + stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9 + glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0); + glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0); + glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1); + glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y1); + } + ++text; + } + glEnd(); +} +#endif +// +// +////////////////////////////////////////////////////////////////////////////// +// +// Complete program (this compiles): get a single bitmap, print as ASCII art +// +#if 0 +#include +#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation +#include "stb_truetype.h" + +char ttf_buffer[1<<25]; + +int main(int argc, char **argv) +{ + stbtt_fontinfo font; + unsigned char *bitmap; + int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20); + + fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb")); + + stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0)); + bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0); + + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) + putchar(" .:ioVM@"[bitmap[j*w+i]>>5]); + putchar('\n'); + } + return 0; +} +#endif +// +// Output: +// +// .ii. +// @@@@@@. +// V@Mio@@o +// :i. V@V +// :oM@@M +// :@@@MM@M +// @@o o@M +// :@@. M@M +// @@@o@@@@ +// :M@@V:@@. +// +////////////////////////////////////////////////////////////////////////////// +// +// Complete program: print "Hello World!" banner, with bugs +// +#if 0 +char buffer[24<<20]; +unsigned char screen[20][79]; + +int main(int arg, char **argv) +{ + stbtt_fontinfo font; + int i,j,ascent,baseline,ch=0; + float scale, xpos=2; // leave a little padding in case the character extends left + char *text = "Heljo World!"; // intentionally misspelled to show 'lj' brokenness + + fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb")); + stbtt_InitFont(&font, buffer, 0); + + scale = stbtt_ScaleForPixelHeight(&font, 15); + stbtt_GetFontVMetrics(&font, &ascent,0,0); + baseline = (int) (ascent*scale); + + while (text[ch]) { + int advance,lsb,x0,y0,x1,y1; + float x_shift = xpos - (float) floor(xpos); + stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb); + stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale,scale,x_shift,0, &x0,&y0,&x1,&y1); + stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(int) xpos + x0], x1-x0,y1-y0, 79, scale,scale,x_shift,0, text[ch]); + // note that this stomps the old data, so where character boxes overlap (e.g. 'lj') it's wrong + // because this API is really for baking character bitmaps into textures. if you want to render + // a sequence of characters, you really need to render each bitmap to a temp buffer, then + // "alpha blend" that into the working buffer + xpos += (advance * scale); + if (text[ch+1]) + xpos += scale*stbtt_GetCodepointKernAdvance(&font, text[ch],text[ch+1]); + ++ch; + } + + for (j=0; j < 20; ++j) { + for (i=0; i < 78; ++i) + putchar(" .:ioVM@"[screen[j][i]>>5]); + putchar('\n'); + } + + return 0; +} +#endif + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +//// +//// INTEGRATION WITH YOUR CODEBASE +//// +//// The following sections allow you to supply alternate definitions +//// of C library functions used by stb_truetype. + +#ifdef STB_TRUETYPE_IMPLEMENTATION + // #define your own (u)stbtt_int8/16/32 before including to override this + #ifndef stbtt_uint8 + typedef unsigned char stbtt_uint8; + typedef signed char stbtt_int8; + typedef unsigned short stbtt_uint16; + typedef signed short stbtt_int16; + typedef unsigned int stbtt_uint32; + typedef signed int stbtt_int32; + #endif + + typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1]; + typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1]; + + // #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h + #ifndef STBTT_ifloor + #include + #define STBTT_ifloor(x) ((int) floor(x)) + #define STBTT_iceil(x) ((int) ceil(x)) + #endif + + #ifndef STBTT_sqrt + #include + #define STBTT_sqrt(x) sqrt(x) + #endif + + #ifndef STBTT_fabs + #include + #define STBTT_fabs(x) fabs(x) + #endif + + // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h + #ifndef STBTT_malloc + #include + #define STBTT_malloc(x,u) ((void)(u),malloc(x)) + #define STBTT_free(x,u) ((void)(u),free(x)) + #endif + + #ifndef STBTT_assert + #include + #define STBTT_assert(x) assert(x) + #endif + + #ifndef STBTT_strlen + #include + #define STBTT_strlen(x) strlen(x) + #endif + + #ifndef STBTT_memcpy + #include + #define STBTT_memcpy memcpy + #define STBTT_memset memset + #endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +//// +//// INTERFACE +//// +//// + +#ifndef __STB_INCLUDE_STB_TRUETYPE_H__ +#define __STB_INCLUDE_STB_TRUETYPE_H__ + +#ifdef STBTT_STATIC +#define STBTT_DEF static +#else +#define STBTT_DEF extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// TEXTURE BAKING API +// +// If you use this API, you only have to call two functions ever. +// + +typedef struct +{ + unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap + float xoff,yoff,xadvance; +} stbtt_bakedchar; + +STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) + float pixel_height, // height of font in pixels + unsigned char *pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar *chardata); // you allocate this, it's num_chars long +// if return is positive, the first unused row of the bitmap +// if return is negative, returns the negative of the number of characters that fit +// if return is 0, no characters fit and no rows were used +// This uses a very crappy packing. + +typedef struct +{ + float x0,y0,s0,t0; // top-left + float x1,y1,s1,t1; // bottom-right +} stbtt_aligned_quad; + +STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above + int char_index, // character to display + float *xpos, float *ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad *q, // output: quad to draw + int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier +// Call GetBakedQuad with char_index = 'character - first_char', and it +// creates the quad you need to draw and advances the current position. +// +// The coordinate system used assumes y increases downwards. +// +// Characters will extend both above and below the current position; +// see discussion of "BASELINE" above. +// +// It's inefficient; you might want to c&p it and optimize it. + + + +////////////////////////////////////////////////////////////////////////////// +// +// NEW TEXTURE BAKING API +// +// This provides options for packing multiple fonts into one atlas, not +// perfectly but better than nothing. + +typedef struct +{ + unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap + float xoff,yoff,xadvance; + float xoff2,yoff2; +} stbtt_packedchar; + +typedef struct stbtt_pack_context stbtt_pack_context; +typedef struct stbtt_fontinfo stbtt_fontinfo; +#ifndef STB_RECT_PACK_VERSION +typedef struct stbrp_rect stbrp_rect; +#endif + +STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); +// Initializes a packing context stored in the passed-in stbtt_pack_context. +// Future calls using this context will pack characters into the bitmap passed +// in here: a 1-channel bitmap that is weight x height. stride_in_bytes is +// the distance from one row to the next (or 0 to mean they are packed tightly +// together). "padding" is the amount of padding to leave between each +// character (normally you want '1' for bitmaps you'll use as textures with +// bilinear filtering). +// +// Returns 0 on failure, 1 on success. + +STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc); +// Cleans up the packing context and frees all memory. + +#define STBTT_POINT_SIZE(x) (-(x)) + +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, + int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range); +// Creates character bitmaps from the font_index'th font found in fontdata (use +// font_index=0 if you don't know what that is). It creates num_chars_in_range +// bitmaps for characters with unicode values starting at first_unicode_char_in_range +// and increasing. Data for how to render them is stored in chardata_for_range; +// pass these to stbtt_GetPackedQuad to get back renderable quads. +// +// font_size is the full height of the character from ascender to descender, +// as computed by stbtt_ScaleForPixelHeight. To use a point size as computed +// by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE() +// and pass that result as 'font_size': +// ..., 20 , ... // font max minus min y is 20 pixels tall +// ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall + +typedef struct +{ + float font_size; + int first_unicode_codepoint_in_range; // if non-zero, then the chars are continuous, and this is the first codepoint + int *array_of_unicode_codepoints; // if non-zero, then this is an array of unicode codepoints + int num_chars; + stbtt_packedchar *chardata_for_range; // output + unsigned char h_oversample, v_oversample; // don't set these, they're used internally +} stbtt_pack_range; + +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); +// Creates character bitmaps from multiple ranges of characters stored in +// ranges. This will usually create a better-packed bitmap than multiple +// calls to stbtt_PackFontRange. Note that you can call this multiple +// times within a single PackBegin/PackEnd. + +STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); +// Oversampling a font increases the quality by allowing higher-quality subpixel +// positioning, and is especially valuable at smaller text sizes. +// +// This function sets the amount of oversampling for all following calls to +// stbtt_PackFontRange(s) or stbtt_PackFontRangesGatherRects for a given +// pack context. The default (no oversampling) is achieved by h_oversample=1 +// and v_oversample=1. The total number of pixels required is +// h_oversample*v_oversample larger than the default; for example, 2x2 +// oversampling requires 4x the storage of 1x1. For best results, render +// oversampled textures with bilinear filtering. Look at the readme in +// stb/tests/oversample for information about oversampled fonts +// +// To use with PackFontRangesGather etc., you must set it before calls +// call to PackFontRangesGatherRects. + +STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above + int char_index, // character to display + float *xpos, float *ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad *q, // output: quad to draw + int align_to_integer); + +STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); +STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects); +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); +// Calling these functions in sequence is roughly equivalent to calling +// stbtt_PackFontRanges(). If you more control over the packing of multiple +// fonts, or if you want to pack custom data into a font texture, take a look +// at the source to of stbtt_PackFontRanges() and create a custom version +// using these functions, e.g. call GatherRects multiple times, +// building up a single array of rects, then call PackRects once, +// then call RenderIntoRects repeatedly. This may result in a +// better packing than calling PackFontRanges multiple times +// (or it may not). + +// this is an opaque structure that you shouldn't mess with which holds +// all the context needed from PackBegin to PackEnd. +struct stbtt_pack_context { + void *user_allocator_context; + void *pack_info; + int width; + int height; + int stride_in_bytes; + int padding; + unsigned int h_oversample, v_oversample; + unsigned char *pixels; + void *nodes; +}; + +////////////////////////////////////////////////////////////////////////////// +// +// FONT LOADING +// +// + +STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); +// Each .ttf/.ttc file may have more than one font. Each font has a sequential +// index number starting from 0. Call this function to get the font offset for +// a given index; it returns -1 if the index is out of range. A regular .ttf +// file will only define one font and it always be at offset 0, so it will +// return '0' for index 0, and -1 for all other indices. You can just skip +// this step if you know it's that kind of font. + + +// The following structure is defined publically so you can declare one on +// the stack or as a global or etc, but you should treat it as opaque. +struct stbtt_fontinfo +{ + void * userdata; + unsigned char * data; // pointer to .ttf file + int fontstart; // offset of start of font + + int numGlyphs; // number of glyphs, needed for range checking + + int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf + int index_map; // a cmap mapping for our chosen character encoding + int indexToLocFormat; // format needed to map from glyph index to glyph +}; + +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); +// Given an offset into the file that defines a font, this function builds +// the necessary cached info for the rest of the system. You must allocate +// the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't +// need to do anything special to free it, because the contents are pure +// value data with no additional data structures. Returns 0 on failure. + + +////////////////////////////////////////////////////////////////////////////// +// +// CHARACTER TO GLYPH-INDEX CONVERSIOn + +STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint); +// If you're going to perform multiple operations on the same character +// and you want a speed-up, call this function with the character you're +// going to process, then use glyph-based functions instead of the +// codepoint-based functions. + + +////////////////////////////////////////////////////////////////////////////// +// +// CHARACTER PROPERTIES +// + +STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels); +// computes a scale factor to produce a font whose "height" is 'pixels' tall. +// Height is measured as the distance from the highest ascender to the lowest +// descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics +// and computing: +// scale = pixels / (ascent - descent) +// so if you prefer to measure height by the ascent only, use a similar calculation. + +STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels); +// computes a scale factor to produce a font whose EM size is mapped to +// 'pixels' tall. This is probably what traditional APIs compute, but +// I'm not positive. + +STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap); +// ascent is the coordinate above the baseline the font extends; descent +// is the coordinate below the baseline the font extends (i.e. it is typically negative) +// lineGap is the spacing between one row's descent and the next row's ascent... +// so you should advance the vertical position by "*ascent - *descent + *lineGap" +// these are expressed in unscaled coordinates, so you must multiply by +// the scale factor for a given size + +STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1); +// the bounding box around all possible characters + +STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing); +// leftSideBearing is the offset from the current horizontal position to the left edge of the character +// advanceWidth is the offset from the current horizontal position to the next horizontal position +// these are expressed in unscaled coordinates + +STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2); +// an additional amount to add to the 'advance' value between ch1 and ch2 + +STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1); +// Gets the bounding box of the visible part of the glyph, in unscaled coordinates + +STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing); +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2); +STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); +// as above, but takes one or more glyph indices for greater efficiency + + +////////////////////////////////////////////////////////////////////////////// +// +// GLYPH SHAPES (you probably don't need these, but they have to go before +// the bitmaps for C declaration-order reasons) +// + +#ifndef STBTT_vmove // you can predefine these to use different values (but why?) + enum { + STBTT_vmove=1, + STBTT_vline, + STBTT_vcurve + }; +#endif + +#ifndef stbtt_vertex // you can predefine this to use different values + // (we share this with other code at RAD) + #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file + typedef struct + { + stbtt_vertex_type x,y,cx,cy; + unsigned char type,padding; + } stbtt_vertex; +#endif + +STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index); +// returns non-zero if nothing is drawn for this glyph + +STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices); +STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices); +// returns # of vertices and fills *vertices with the pointer to them +// these are expressed in "unscaled" coordinates +// +// The shape is a series of countours. Each one starts with +// a STBTT_moveto, then consists of a series of mixed +// STBTT_lineto and STBTT_curveto segments. A lineto +// draws a line from previous endpoint to its x,y; a curveto +// draws a quadratic bezier from previous endpoint to +// its x,y, using cx,cy as the bezier control point. + +STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); +// frees the data allocated above + +////////////////////////////////////////////////////////////////////////////// +// +// BITMAP RENDERING +// + +STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata); +// frees the bitmap allocated below + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); +// allocates a large-enough single-channel 8bpp bitmap and renders the +// specified character/glyph at the specified scale into it, with +// antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque). +// *width & *height are filled out with the width & height of the bitmap, +// which is stored left-to-right, top-to-bottom. +// +// xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff); +// the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel +// shift for the character + +STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); +// the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap +// in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap +// is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the +// width and height and positioning info for it first. + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); +// same as stbtt_MakeCodepointBitmap, but you can specify a subpixel +// shift for the character + +STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); +// get the bbox of the bitmap centered around the glyph origin; so the +// bitmap width is ix1-ix0, height is iy1-iy0, and location to place +// the bitmap top left is (leftSideBearing*scale,iy0). +// (Note that the bitmap uses y-increases-down, but the shape uses +// y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.) + +STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); +// same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel +// shift for the character + +// the following functions are equivalent to the above functions, but operate +// on glyph indices instead of Unicode codepoints (for efficiency) +STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); +STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); +STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); +STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); + + +// @TODO: don't expose this structure +typedef struct +{ + int w,h,stride; + unsigned char *pixels; +} stbtt__bitmap; + +// rasterize a shape with quadratic beziers into a bitmap +STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, // 1-channel bitmap to draw into + float flatness_in_pixels, // allowable error of curve in pixels + stbtt_vertex *vertices, // array of vertices defining shape + int num_verts, // number of vertices in above array + float scale_x, float scale_y, // scale applied to input vertices + float shift_x, float shift_y, // translation applied to input vertices + int x_off, int y_off, // another translation applied to input + int invert, // if non-zero, vertically flip shape + void *userdata); // context for to STBTT_MALLOC + +////////////////////////////////////////////////////////////////////////////// +// +// Finding the right font... +// +// You should really just solve this offline, keep your own tables +// of what font is what, and don't try to get it out of the .ttf file. +// That's because getting it out of the .ttf file is really hard, because +// the names in the file can appear in many possible encodings, in many +// possible languages, and e.g. if you need a case-insensitive comparison, +// the details of that depend on the encoding & language in a complex way +// (actually underspecified in truetype, but also gigantic). +// +// But you can use the provided functions in two possible ways: +// stbtt_FindMatchingFont() will use *case-sensitive* comparisons on +// unicode-encoded names to try to find the font you want; +// you can run this before calling stbtt_InitFont() +// +// stbtt_GetFontNameString() lets you get any of the various strings +// from the file yourself and do your own comparisons on them. +// You have to have called stbtt_InitFont() first. + + +STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags); +// returns the offset (not index) of the font that matches, or -1 if none +// if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold". +// if you use any other flag, use a font name like "Arial"; this checks +// the 'macStyle' header field; i don't know if fonts set this consistently +#define STBTT_MACSTYLE_DONTCARE 0 +#define STBTT_MACSTYLE_BOLD 1 +#define STBTT_MACSTYLE_ITALIC 2 +#define STBTT_MACSTYLE_UNDERSCORE 4 +#define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0 + +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2); +// returns 1/0 whether the first string interpreted as utf8 is identical to +// the second string interpreted as big-endian utf16... useful for strings from next func + +STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID); +// returns the string (which may be big-endian double byte, e.g. for unicode) +// and puts the length in bytes in *length. +// +// some of the values for the IDs are below; for more see the truetype spec: +// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html +// http://www.microsoft.com/typography/otspec/name.htm + +enum { // platformID + STBTT_PLATFORM_ID_UNICODE =0, + STBTT_PLATFORM_ID_MAC =1, + STBTT_PLATFORM_ID_ISO =2, + STBTT_PLATFORM_ID_MICROSOFT =3 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_UNICODE + STBTT_UNICODE_EID_UNICODE_1_0 =0, + STBTT_UNICODE_EID_UNICODE_1_1 =1, + STBTT_UNICODE_EID_ISO_10646 =2, + STBTT_UNICODE_EID_UNICODE_2_0_BMP=3, + STBTT_UNICODE_EID_UNICODE_2_0_FULL=4 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT + STBTT_MS_EID_SYMBOL =0, + STBTT_MS_EID_UNICODE_BMP =1, + STBTT_MS_EID_SHIFTJIS =2, + STBTT_MS_EID_UNICODE_FULL =10 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes + STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4, + STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5, + STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6, + STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7 +}; + +enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... + // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs + STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410, + STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411, + STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412, + STBTT_MS_LANG_FRENCH =0x040c, STBTT_MS_LANG_RUSSIAN =0x0419, + STBTT_MS_LANG_GERMAN =0x0407, STBTT_MS_LANG_SPANISH =0x0409, + STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D +}; + +enum { // languageID for STBTT_PLATFORM_ID_MAC + STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11, + STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23, + STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32, + STBTT_MAC_LANG_FRENCH =1 , STBTT_MAC_LANG_SPANISH =6 , + STBTT_MAC_LANG_GERMAN =2 , STBTT_MAC_LANG_SWEDISH =5 , + STBTT_MAC_LANG_HEBREW =10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33, + STBTT_MAC_LANG_ITALIAN =3 , STBTT_MAC_LANG_CHINESE_TRAD =19 +}; + +#ifdef __cplusplus +} +#endif + +#endif // __STB_INCLUDE_STB_TRUETYPE_H__ + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +//// +//// IMPLEMENTATION +//// +//// + +#ifdef STB_TRUETYPE_IMPLEMENTATION + +#ifndef STBTT_MAX_OVERSAMPLE +#define STBTT_MAX_OVERSAMPLE 8 +#endif + +#if STBTT_MAX_OVERSAMPLE > 255 +#error "STBTT_MAX_OVERSAMPLE cannot be > 255" +#endif + +typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1]; + +#ifndef STBTT_RASTERIZER_VERSION +#define STBTT_RASTERIZER_VERSION 2 +#endif + +////////////////////////////////////////////////////////////////////////// +// +// accessors to parse data from file +// + +// on platforms that don't allow misaligned reads, if we want to allow +// truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE + +#define ttBYTE(p) (* (stbtt_uint8 *) (p)) +#define ttCHAR(p) (* (stbtt_int8 *) (p)) +#define ttFixed(p) ttLONG(p) + +#if defined(STB_TRUETYPE_BIGENDIAN) && !defined(ALLOW_UNALIGNED_TRUETYPE) + + #define ttUSHORT(p) (* (stbtt_uint16 *) (p)) + #define ttSHORT(p) (* (stbtt_int16 *) (p)) + #define ttULONG(p) (* (stbtt_uint32 *) (p)) + #define ttLONG(p) (* (stbtt_int32 *) (p)) + +#else + + static stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } + static stbtt_int16 ttSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } + static stbtt_uint32 ttULONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } + static stbtt_int32 ttLONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } + +#endif + +#define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) +#define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3]) + +static int stbtt__isfont(const stbtt_uint8 *font) +{ + // check the version number + if (stbtt_tag4(font, '1',0,0,0)) return 1; // TrueType 1 + if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this! + if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF + if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0 + return 0; +} + +// @OPTIMIZE: binary search +static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag) +{ + stbtt_int32 num_tables = ttUSHORT(data+fontstart+4); + stbtt_uint32 tabledir = fontstart + 12; + stbtt_int32 i; + for (i=0; i < num_tables; ++i) { + stbtt_uint32 loc = tabledir + 16*i; + if (stbtt_tag(data+loc+0, tag)) + return ttULONG(data+loc+8); + } + return 0; +} + +STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, int index) +{ + // if it's just a font, there's only one valid index + if (stbtt__isfont(font_collection)) + return index == 0 ? 0 : -1; + + // check if it's a TTC + if (stbtt_tag(font_collection, "ttcf")) { + // version 1? + if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) { + stbtt_int32 n = ttLONG(font_collection+8); + if (index >= n) + return -1; + return ttULONG(font_collection+12+index*4); + } + } + return -1; +} + +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, int fontstart) +{ + stbtt_uint8 *data = (stbtt_uint8 *) data2; + stbtt_uint32 cmap, t; + stbtt_int32 i,numTables; + + info->data = data; + info->fontstart = fontstart; + + cmap = stbtt__find_table(data, fontstart, "cmap"); // required + info->loca = stbtt__find_table(data, fontstart, "loca"); // required + info->head = stbtt__find_table(data, fontstart, "head"); // required + info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required + info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required + info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required + info->kern = stbtt__find_table(data, fontstart, "kern"); // not required + if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx) + return 0; + + t = stbtt__find_table(data, fontstart, "maxp"); + if (t) + info->numGlyphs = ttUSHORT(data+t+4); + else + info->numGlyphs = 0xffff; + + // find a cmap encoding table we understand *now* to avoid searching + // later. (todo: could make this installable) + // the same regardless of glyph. + numTables = ttUSHORT(data + cmap + 2); + info->index_map = 0; + for (i=0; i < numTables; ++i) { + stbtt_uint32 encoding_record = cmap + 4 + 8 * i; + // find an encoding we understand: + switch(ttUSHORT(data+encoding_record)) { + case STBTT_PLATFORM_ID_MICROSOFT: + switch (ttUSHORT(data+encoding_record+2)) { + case STBTT_MS_EID_UNICODE_BMP: + case STBTT_MS_EID_UNICODE_FULL: + // MS/Unicode + info->index_map = cmap + ttULONG(data+encoding_record+4); + break; + } + break; + case STBTT_PLATFORM_ID_UNICODE: + // Mac/iOS has these + // all the encodingIDs are unicode, so we don't bother to check it + info->index_map = cmap + ttULONG(data+encoding_record+4); + break; + } + } + if (info->index_map == 0) + return 0; + + info->indexToLocFormat = ttUSHORT(data+info->head + 50); + return 1; +} + +STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint) +{ + stbtt_uint8 *data = info->data; + stbtt_uint32 index_map = info->index_map; + + stbtt_uint16 format = ttUSHORT(data + index_map + 0); + if (format == 0) { // apple byte encoding + stbtt_int32 bytes = ttUSHORT(data + index_map + 2); + if (unicode_codepoint < bytes-6) + return ttBYTE(data + index_map + 6 + unicode_codepoint); + return 0; + } else if (format == 6) { + stbtt_uint32 first = ttUSHORT(data + index_map + 6); + stbtt_uint32 count = ttUSHORT(data + index_map + 8); + if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count) + return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2); + return 0; + } else if (format == 2) { + STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean + return 0; + } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges + stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1; + stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1; + stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10); + stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1; + + // do a binary search of the segments + stbtt_uint32 endCount = index_map + 14; + stbtt_uint32 search = endCount; + + if (unicode_codepoint > 0xffff) + return 0; + + // they lie from endCount .. endCount + segCount + // but searchRange is the nearest power of two, so... + if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2)) + search += rangeShift*2; + + // now decrement to bias correctly to find smallest + search -= 2; + while (entrySelector) { + stbtt_uint16 end; + searchRange >>= 1; + end = ttUSHORT(data + search + searchRange*2); + if (unicode_codepoint > end) + search += searchRange*2; + --entrySelector; + } + search += 2; + + { + stbtt_uint16 offset, start; + stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1); + + STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item)); + start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item); + if (unicode_codepoint < start) + return 0; + + offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item); + if (offset == 0) + return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item)); + + return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item); + } + } else if (format == 12 || format == 13) { + stbtt_uint32 ngroups = ttULONG(data+index_map+12); + stbtt_int32 low,high; + low = 0; high = (stbtt_int32)ngroups; + // Binary search the right group. + while (low < high) { + stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high + stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12); + stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4); + if ((stbtt_uint32) unicode_codepoint < start_char) + high = mid; + else if ((stbtt_uint32) unicode_codepoint > end_char) + low = mid+1; + else { + stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8); + if (format == 12) + return start_glyph + unicode_codepoint-start_char; + else // format == 13 + return start_glyph; + } + } + return 0; // not found + } + // @TODO + STBTT_assert(0); + return 0; +} + +STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices) +{ + return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices); +} + +static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy) +{ + v->type = type; + v->x = (stbtt_int16) x; + v->y = (stbtt_int16) y; + v->cx = (stbtt_int16) cx; + v->cy = (stbtt_int16) cy; +} + +static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) +{ + int g1,g2; + + if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range + if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format + + if (info->indexToLocFormat == 0) { + g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2; + g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2; + } else { + g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4); + g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4); + } + + return g1==g2 ? -1 : g1; // if length is 0, return -1 +} + +STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) +{ + int g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 0; + + if (x0) *x0 = ttSHORT(info->data + g + 2); + if (y0) *y0 = ttSHORT(info->data + g + 4); + if (x1) *x1 = ttSHORT(info->data + g + 6); + if (y1) *y1 = ttSHORT(info->data + g + 8); + return 1; +} + +STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1) +{ + return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1); +} + +STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index) +{ + stbtt_int16 numberOfContours; + int g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 1; + numberOfContours = ttSHORT(info->data + g); + return numberOfContours == 0; +} + +static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_off, int start_off, + stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy) +{ + if (start_off) { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy); + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx,sy,scx,scy); + } else { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0); + } + return num_vertices; +} + +STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +{ + stbtt_int16 numberOfContours; + stbtt_uint8 *endPtsOfContours; + stbtt_uint8 *data = info->data; + stbtt_vertex *vertices=0; + int num_vertices=0; + int g = stbtt__GetGlyfOffset(info, glyph_index); + + *pvertices = NULL; + + if (g < 0) return 0; + + numberOfContours = ttSHORT(data + g); + + if (numberOfContours > 0) { + stbtt_uint8 flags=0,flagcount; + stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0; + stbtt_int32 x,y,cx,cy,sx,sy, scx,scy; + stbtt_uint8 *points; + endPtsOfContours = (data + g + 10); + ins = ttUSHORT(data + g + 10 + numberOfContours * 2); + points = data + g + 10 + numberOfContours * 2 + 2 + ins; + + n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2); + + m = n + 2*numberOfContours; // a loose bound on how many vertices we might need + vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata); + if (vertices == 0) + return 0; + + next_move = 0; + flagcount=0; + + // in first pass, we load uninterpreted data into the allocated array + // above, shifted to the end of the array so we won't overwrite it when + // we create our final data starting from the front + + off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated + + // first load flags + + for (i=0; i < n; ++i) { + if (flagcount == 0) { + flags = *points++; + if (flags & 8) + flagcount = *points++; + } else + --flagcount; + vertices[off+i].type = flags; + } + + // now load x coordinates + x=0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + if (flags & 2) { + stbtt_int16 dx = *points++; + x += (flags & 16) ? dx : -dx; // ??? + } else { + if (!(flags & 16)) { + x = x + (stbtt_int16) (points[0]*256 + points[1]); + points += 2; + } + } + vertices[off+i].x = (stbtt_int16) x; + } + + // now load y coordinates + y=0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + if (flags & 4) { + stbtt_int16 dy = *points++; + y += (flags & 32) ? dy : -dy; // ??? + } else { + if (!(flags & 32)) { + y = y + (stbtt_int16) (points[0]*256 + points[1]); + points += 2; + } + } + vertices[off+i].y = (stbtt_int16) y; + } + + // now convert them to our format + num_vertices=0; + sx = sy = cx = cy = scx = scy = 0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + x = (stbtt_int16) vertices[off+i].x; + y = (stbtt_int16) vertices[off+i].y; + + if (next_move == i) { + if (i != 0) + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); + + // now start the new one + start_off = !(flags & 1); + if (start_off) { + // if we start off with an off-curve point, then when we need to find a point on the curve + // where we can start, and we need to save some state for when we wraparound. + scx = x; + scy = y; + if (!(vertices[off+i+1].type & 1)) { + // next point is also a curve point, so interpolate an on-point curve + sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1; + sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1; + } else { + // otherwise just use the next point as our start point + sx = (stbtt_int32) vertices[off+i+1].x; + sy = (stbtt_int32) vertices[off+i+1].y; + ++i; // we're using point i+1 as the starting point, so skip it + } + } else { + sx = x; + sy = y; + } + stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,sx,sy,0,0); + was_off = 0; + next_move = 1 + ttUSHORT(endPtsOfContours+j*2); + ++j; + } else { + if (!(flags & 1)) { // if it's a curve + if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy); + cx = x; + cy = y; + was_off = 1; + } else { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0); + was_off = 0; + } + } + } + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); + } else if (numberOfContours == -1) { + // Compound shapes. + int more = 1; + stbtt_uint8 *comp = data + g + 10; + num_vertices = 0; + vertices = 0; + while (more) { + stbtt_uint16 flags, gidx; + int comp_num_verts = 0, i; + stbtt_vertex *comp_verts = 0, *tmp = 0; + float mtx[6] = {1,0,0,1,0,0}, m, n; + + flags = ttSHORT(comp); comp+=2; + gidx = ttSHORT(comp); comp+=2; + + if (flags & 2) { // XY values + if (flags & 1) { // shorts + mtx[4] = ttSHORT(comp); comp+=2; + mtx[5] = ttSHORT(comp); comp+=2; + } else { + mtx[4] = ttCHAR(comp); comp+=1; + mtx[5] = ttCHAR(comp); comp+=1; + } + } + else { + // @TODO handle matching point + STBTT_assert(0); + } + if (flags & (1<<3)) { // WE_HAVE_A_SCALE + mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[1] = mtx[2] = 0; + } else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE + mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[1] = mtx[2] = 0; + mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; + } else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO + mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[1] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[2] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; + } + + // Find transformation scales. + m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); + n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); + + // Get indexed glyph. + comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts); + if (comp_num_verts > 0) { + // Transform vertices. + for (i = 0; i < comp_num_verts; ++i) { + stbtt_vertex* v = &comp_verts[i]; + stbtt_vertex_type x,y; + x=v->x; y=v->y; + v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); + v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); + x=v->cx; y=v->cy; + v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); + v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); + } + // Append vertices. + tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata); + if (!tmp) { + if (vertices) STBTT_free(vertices, info->userdata); + if (comp_verts) STBTT_free(comp_verts, info->userdata); + return 0; + } + if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); + STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex)); + if (vertices) STBTT_free(vertices, info->userdata); + vertices = tmp; + STBTT_free(comp_verts, info->userdata); + num_vertices += comp_num_verts; + } + // More components ? + more = flags & (1<<5); + } + } else if (numberOfContours < 0) { + // @TODO other compound variations? + STBTT_assert(0); + } else { + // numberOfCounters == 0, do nothing + } + + *pvertices = vertices; + return num_vertices; +} + +STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing) +{ + stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34); + if (glyph_index < numOfLongHorMetrics) { + if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index); + if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2); + } else { + if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1)); + if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics)); + } +} + +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +{ + stbtt_uint8 *data = info->data + info->kern; + stbtt_uint32 needle, straw; + int l, r, m; + + // we only look at the first table. it must be 'horizontal' and format 0. + if (!info->kern) + return 0; + if (ttUSHORT(data+2) < 1) // number of tables, need at least 1 + return 0; + if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format + return 0; + + l = 0; + r = ttUSHORT(data+10) - 1; + needle = glyph1 << 16 | glyph2; + while (l <= r) { + m = (l + r) >> 1; + straw = ttULONG(data+18+(m*6)); // note: unaligned read + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else + return ttSHORT(data+22+(m*6)); + } + return 0; +} + +STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) +{ + if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs + return 0; + return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2)); +} + +STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing) +{ + stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing); +} + +STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap) +{ + if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4); + if (descent) *descent = ttSHORT(info->data+info->hhea + 6); + if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8); +} + +STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1) +{ + *x0 = ttSHORT(info->data + info->head + 36); + *y0 = ttSHORT(info->data + info->head + 38); + *x1 = ttSHORT(info->data + info->head + 40); + *y1 = ttSHORT(info->data + info->head + 42); +} + +STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height) +{ + int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6); + return (float) height / fheight; +} + +STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels) +{ + int unitsPerEm = ttUSHORT(info->data + info->head + 18); + return pixels / unitsPerEm; +} + +STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) +{ + STBTT_free(v, info->userdata); +} + +////////////////////////////////////////////////////////////////////////////// +// +// antialiasing software rasterizer +// + +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + int x0=0,y0=0,x1,y1; // =0 suppresses compiler warning + if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) { + // e.g. space character + if (ix0) *ix0 = 0; + if (iy0) *iy0 = 0; + if (ix1) *ix1 = 0; + if (iy1) *iy1 = 0; + } else { + // move to integral bboxes (treating pixels as little squares, what pixels get touched)? + if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x); + if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y); + if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x); + if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y); + } +} + +STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1); +} + +STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1); +} + +STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1); +} + +////////////////////////////////////////////////////////////////////////////// +// +// Rasterizer + +typedef struct stbtt__hheap_chunk +{ + struct stbtt__hheap_chunk *next; +} stbtt__hheap_chunk; + +typedef struct stbtt__hheap +{ + struct stbtt__hheap_chunk *head; + void *first_free; + int num_remaining_in_head_chunk; +} stbtt__hheap; + +static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata) +{ + if (hh->first_free) { + void *p = hh->first_free; + hh->first_free = * (void **) p; + return p; + } else { + if (hh->num_remaining_in_head_chunk == 0) { + int count = (size < 32 ? 2000 : size < 128 ? 800 : 100); + stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata); + if (c == NULL) + return NULL; + c->next = hh->head; + hh->head = c; + hh->num_remaining_in_head_chunk = count; + } + --hh->num_remaining_in_head_chunk; + return (char *) (hh->head) + size * hh->num_remaining_in_head_chunk; + } +} + +static void stbtt__hheap_free(stbtt__hheap *hh, void *p) +{ + *(void **) p = hh->first_free; + hh->first_free = p; +} + +static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata) +{ + stbtt__hheap_chunk *c = hh->head; + while (c) { + stbtt__hheap_chunk *n = c->next; + STBTT_free(c, userdata); + c = n; + } +} + +typedef struct stbtt__edge { + float x0,y0, x1,y1; + int invert; +} stbtt__edge; + + +typedef struct stbtt__active_edge +{ + struct stbtt__active_edge *next; + #if STBTT_RASTERIZER_VERSION==1 + int x,dx; + float ey; + int direction; + #elif STBTT_RASTERIZER_VERSION==2 + float fx,fdx,fdy; + float direction; + float sy; + float ey; + #else + #error "Unrecognized value of STBTT_RASTERIZER_VERSION" + #endif +} stbtt__active_edge; + +#if STBTT_RASTERIZER_VERSION == 1 +#define STBTT_FIXSHIFT 10 +#define STBTT_FIX (1 << STBTT_FIXSHIFT) +#define STBTT_FIXMASK (STBTT_FIX-1) + +static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) +{ + stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); + if (!z) return z; + + // round dx down to avoid overshooting + if (dxdy < 0) + z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); + else + z->dx = STBTT_ifloor(STBTT_FIX * dxdy); + + z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); // use z->dx so when we offset later it's by the same amount + z->x -= off_x * STBTT_FIX; + + z->ey = e->y1; + z->next = 0; + z->direction = e->invert ? 1 : -1; + return z; +} +#elif STBTT_RASTERIZER_VERSION == 2 +static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) +{ + stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); + //STBTT_assert(e->y0 <= start_point); + if (!z) return z; + z->fdx = dxdy; + z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f; + z->fx = e->x0 + dxdy * (start_point - e->y0); + z->fx -= off_x; + z->direction = e->invert ? 1.0f : -1.0f; + z->sy = e->y0; + z->ey = e->y1; + z->next = 0; + return z; +} +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + +#if STBTT_RASTERIZER_VERSION == 1 +// note: this routine clips fills that extend off the edges... ideally this +// wouldn't happen, but it could happen if the truetype glyph bounding boxes +// are wrong, or if the user supplies a too-small bitmap +static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight) +{ + // non-zero winding fill + int x0=0, w=0; + + while (e) { + if (w == 0) { + // if we're currently at zero, we need to record the edge start point + x0 = e->x; w += e->direction; + } else { + int x1 = e->x; w += e->direction; + // if we went to zero, we need to draw + if (w == 0) { + int i = x0 >> STBTT_FIXSHIFT; + int j = x1 >> STBTT_FIXSHIFT; + + if (i < len && j >= 0) { + if (i == j) { + // x0,x1 are the same pixel, so compute combined coverage + scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> STBTT_FIXSHIFT); + } else { + if (i >= 0) // add antialiasing for x0 + scanline[i] = scanline[i] + (stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT); + else + i = -1; // clip + + if (j < len) // add antialiasing for x1 + scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT); + else + j = len; // clip + + for (++i; i < j; ++i) // fill pixels between x0 and x1 + scanline[i] = scanline[i] + (stbtt_uint8) max_weight; + } + } + } + } + + e = e->next; + } +} + +static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) +{ + stbtt__hheap hh = { 0, 0, 0 }; + stbtt__active_edge *active = NULL; + int y,j=0; + int max_weight = (255 / vsubsample); // weight per vertical scanline + int s; // vertical subsample index + unsigned char scanline_data[512], *scanline; + + if (result->w > 512) + scanline = (unsigned char *) STBTT_malloc(result->w, userdata); + else + scanline = scanline_data; + + y = off_y * vsubsample; + e[n].y0 = (off_y + result->h) * (float) vsubsample + 1; + + while (j < result->h) { + STBTT_memset(scanline, 0, result->w); + for (s=0; s < vsubsample; ++s) { + // find center of pixel for this scanline + float scan_y = y + 0.5f; + stbtt__active_edge **step = &active; + + // update all active edges; + // remove all active edges that terminate before the center of this scanline + while (*step) { + stbtt__active_edge * z = *step; + if (z->ey <= scan_y) { + *step = z->next; // delete from list + STBTT_assert(z->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } else { + z->x += z->dx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + } + + // resort the list if needed + for(;;) { + int changed=0; + step = &active; + while (*step && (*step)->next) { + if ((*step)->x > (*step)->next->x) { + stbtt__active_edge *t = *step; + stbtt__active_edge *q = t->next; + + t->next = q->next; + q->next = t; + *step = q; + changed = 1; + } + step = &(*step)->next; + } + if (!changed) break; + } + + // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline + while (e->y0 <= scan_y) { + if (e->y1 > scan_y) { + stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata); + if (z != NULL) { + // find insertion point + if (active == NULL) + active = z; + else if (z->x < active->x) { + // insert at front + z->next = active; + active = z; + } else { + // find thing to insert AFTER + stbtt__active_edge *p = active; + while (p->next && p->next->x < z->x) + p = p->next; + // at this point, p->next->x is NOT < z->x + z->next = p->next; + p->next = z; + } + } + } + ++e; + } + + // now process all active edges in XOR fashion + if (active) + stbtt__fill_active_edges(scanline, result->w, active, max_weight); + + ++y; + } + STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w); + ++j; + } + + stbtt__hheap_cleanup(&hh, userdata); + + if (scanline != scanline_data) + STBTT_free(scanline, userdata); +} + +#elif STBTT_RASTERIZER_VERSION == 2 + +// the edge passed in here does not cross the vertical line at x or the vertical line at x+1 +// (i.e. it has already been clipped to those) +static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1) +{ + if (y0 == y1) return; + STBTT_assert(y0 < y1); + STBTT_assert(e->sy <= e->ey); + if (y0 > e->ey) return; + if (y1 < e->sy) return; + if (y0 < e->sy) { + x0 += (x1-x0) * (e->sy - y0) / (y1-y0); + y0 = e->sy; + } + if (y1 > e->ey) { + x1 += (x1-x0) * (e->ey - y1) / (y1-y0); + y1 = e->ey; + } + + if (x0 == x) + STBTT_assert(x1 <= x+1); + else if (x0 == x+1) + STBTT_assert(x1 >= x); + else if (x0 <= x) + STBTT_assert(x1 <= x); + else if (x0 >= x+1) + STBTT_assert(x1 >= x+1); + else + STBTT_assert(x1 >= x && x1 <= x+1); + + if (x0 <= x && x1 <= x) + scanline[x] += e->direction * (y1-y0); + else if (x0 >= x+1 && x1 >= x+1) + ; + else { + STBTT_assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1); + scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); // coverage = 1 - average x position + } +} + +static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top) +{ + float y_bottom = y_top+1; + + while (e) { + // brute force every pixel + + // compute intersection points with top & bottom + STBTT_assert(e->ey >= y_top); + + if (e->fdx == 0) { + float x0 = e->fx; + if (x0 < len) { + if (x0 >= 0) { + stbtt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom); + stbtt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom); + } else { + stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom); + } + } + } else { + float x0 = e->fx; + float dx = e->fdx; + float xb = x0 + dx; + float x_top, x_bottom; + float sy0,sy1; + float dy = e->fdy; + STBTT_assert(e->sy <= y_bottom && e->ey >= y_top); + + // compute endpoints of line segment clipped to this scanline (if the + // line segment starts on this scanline. x0 is the intersection of the + // line with y_top, but that may be off the line segment. + if (e->sy > y_top) { + x_top = x0 + dx * (e->sy - y_top); + sy0 = e->sy; + } else { + x_top = x0; + sy0 = y_top; + } + if (e->ey < y_bottom) { + x_bottom = x0 + dx * (e->ey - y_top); + sy1 = e->ey; + } else { + x_bottom = xb; + sy1 = y_bottom; + } + + if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) { + // from here on, we don't have to range check x values + + if ((int) x_top == (int) x_bottom) { + float height; + // simple case, only spans one pixel + int x = (int) x_top; + height = sy1 - sy0; + STBTT_assert(x >= 0 && x < len); + scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height; + scanline_fill[x] += e->direction * height; // everything right of this pixel is filled + } else { + int x,x1,x2; + float y_crossing, step, sign, area; + // covers 2+ pixels + if (x_top > x_bottom) { + // flip scanline vertically; signed area is the same + float t; + sy0 = y_bottom - (sy0 - y_top); + sy1 = y_bottom - (sy1 - y_top); + t = sy0, sy0 = sy1, sy1 = t; + t = x_bottom, x_bottom = x_top, x_top = t; + dx = -dx; + dy = -dy; + t = x0, x0 = xb, xb = t; + } + + x1 = (int) x_top; + x2 = (int) x_bottom; + // compute intersection with y axis at x1+1 + y_crossing = (x1+1 - x0) * dy + y_top; + + sign = e->direction; + // area of the rectangle covered from y0..y_crossing + area = sign * (y_crossing-sy0); + // area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) + scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2); + + step = sign * dy; + for (x = x1+1; x < x2; ++x) { + scanline[x] += area + step/2; + area += step; + } + y_crossing += dy * (x2 - (x1+1)); + + STBTT_assert(STBTT_fabs(area) <= 1.01f); + + scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing); + + scanline_fill[x2] += sign * (sy1-sy0); + } + } else { + // if edge goes outside of box we're drawing, we require + // clipping logic. since this does not match the intended use + // of this library, we use a different, very slow brute + // force implementation + int x; + for (x=0; x < len; ++x) { + // cases: + // + // there can be up to two intersections with the pixel. any intersection + // with left or right edges can be handled by splitting into two (or three) + // regions. intersections with top & bottom do not necessitate case-wise logic. + // + // the old way of doing this found the intersections with the left & right edges, + // then used some simple logic to produce up to three segments in sorted order + // from top-to-bottom. however, this had a problem: if an x edge was epsilon + // across the x border, then the corresponding y position might not be distinct + // from the other y segment, and it might ignored as an empty segment. to avoid + // that, we need to explicitly produce segments based on x positions. + + // rename variables to clear pairs + float y0 = y_top; + float x1 = (float) (x); + float x2 = (float) (x+1); + float x3 = xb; + float y3 = y_bottom; + float y1,y2; + + // x = e->x + e->dx * (y-y_top) + // (y-y_top) = (x - e->x) / e->dx + // y = (x - e->x) / e->dx + y_top + y1 = (x - x0) / dx + y_top; + y2 = (x+1 - x0) / dx + y_top; + + if (x0 < x1 && x3 > x2) { // three segments descending down-right + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else if (x3 < x1 && x0 > x2) { // three segments descending down-left + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x0 < x1 && x3 > x1) { // two segments across x, down-right + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x3 < x1 && x0 > x1) { // two segments across x, down-left + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x0 < x2 && x3 > x2) { // two segments across x+1, down-right + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else if (x3 < x2 && x0 > x2) { // two segments across x+1, down-left + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else { // one segment + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x3,y3); + } + } + } + } + e = e->next; + } +} + +// directly AA rasterize edges w/o supersampling +static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) +{ + (void)vsubsample; + stbtt__hheap hh = { 0, 0, 0 }; + stbtt__active_edge *active = NULL; + int y,j=0, i; + float scanline_data[129], *scanline, *scanline2; + + if (result->w > 64) + scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata); + else + scanline = scanline_data; + + scanline2 = scanline + result->w; + + y = off_y; + e[n].y0 = (float) (off_y + result->h) + 1; + + while (j < result->h) { + // find center of pixel for this scanline + float scan_y_top = y + 0.0f; + float scan_y_bottom = y + 1.0f; + stbtt__active_edge **step = &active; + + STBTT_memset(scanline , 0, result->w*sizeof(scanline[0])); + STBTT_memset(scanline2, 0, (result->w+1)*sizeof(scanline[0])); + + // update all active edges; + // remove all active edges that terminate before the top of this scanline + while (*step) { + stbtt__active_edge * z = *step; + if (z->ey <= scan_y_top) { + *step = z->next; // delete from list + STBTT_assert(z->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } else { + step = &((*step)->next); // advance through list + } + } + + // insert all edges that start before the bottom of this scanline + while (e->y0 <= scan_y_bottom) { + if (e->y0 != e->y1) { + stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); + if (z != NULL) { + STBTT_assert(z->ey >= scan_y_top); + // insert at front + z->next = active; + active = z; + } + } + ++e; + } + + // now process all active edges + if (active) + stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top); + + { + float sum = 0; + for (i=0; i < result->w; ++i) { + float k; + int m; + sum += scanline2[i]; + k = scanline[i] + sum; + k = (float) STBTT_fabs(k)*255 + 0.5f; + m = (int) k; + if (m > 255) m = 255; + result->pixels[j*result->stride + i] = (unsigned char) m; + } + } + // advance all the edges + step = &active; + while (*step) { + stbtt__active_edge *z = *step; + z->fx += z->fdx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + + ++y; + ++j; + } + + stbtt__hheap_cleanup(&hh, userdata); + + if (scanline != scanline_data) + STBTT_free(scanline, userdata); +} +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + +#define STBTT__COMPARE(a,b) ((a)->y0 < (b)->y0) + +static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n) +{ + int i,j; + for (i=1; i < n; ++i) { + stbtt__edge t = p[i], *a = &t; + j = i; + while (j > 0) { + stbtt__edge *b = &p[j-1]; + int c = STBTT__COMPARE(a,b); + if (!c) break; + p[j] = p[j-1]; + --j; + } + if (i != j) + p[j] = t; + } +} + +static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n) +{ + /* threshhold for transitioning to insertion sort */ + while (n > 12) { + stbtt__edge t; + int c01,c12,c,m,i,j; + + /* compute median of three */ + m = n >> 1; + c01 = STBTT__COMPARE(&p[0],&p[m]); + c12 = STBTT__COMPARE(&p[m],&p[n-1]); + /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ + if (c01 != c12) { + /* otherwise, we'll need to swap something else to middle */ + int z; + c = STBTT__COMPARE(&p[0],&p[n-1]); + /* 0>mid && midn => n; 0 0 */ + /* 0n: 0>n => 0; 0 n */ + z = (c == c12) ? 0 : n-1; + t = p[z]; + p[z] = p[m]; + p[m] = t; + } + /* now p[m] is the median-of-three */ + /* swap it to the beginning so it won't move around */ + t = p[0]; + p[0] = p[m]; + p[m] = t; + + /* partition loop */ + i=1; + j=n-1; + for(;;) { + /* handling of equality is crucial here */ + /* for sentinels & efficiency with duplicates */ + for (;;++i) { + if (!STBTT__COMPARE(&p[i], &p[0])) break; + } + for (;;--j) { + if (!STBTT__COMPARE(&p[0], &p[j])) break; + } + /* make sure we haven't crossed */ + if (i >= j) break; + t = p[i]; + p[i] = p[j]; + p[j] = t; + + ++i; + --j; + } + /* recurse on smaller side, iterate on larger */ + if (j < (n-i)) { + stbtt__sort_edges_quicksort(p,j); + p = p+i; + n = n-i; + } else { + stbtt__sort_edges_quicksort(p+i, n-i); + n = j; + } + } +} + +static void stbtt__sort_edges(stbtt__edge *p, int n) +{ + stbtt__sort_edges_quicksort(p, n); + stbtt__sort_edges_ins_sort(p, n); +} + +typedef struct +{ + float x,y; +} stbtt__point; + +static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata) +{ + float y_scale_inv = invert ? -scale_y : scale_y; + stbtt__edge *e; + int n,i,j,k,m; +#if STBTT_RASTERIZER_VERSION == 1 + int vsubsample = result->h < 8 ? 15 : 5; +#elif STBTT_RASTERIZER_VERSION == 2 + int vsubsample = 1; +#else + #error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + // vsubsample should divide 255 evenly; otherwise we won't reach full opacity + + // now we have to blow out the windings into explicit edge lists + n = 0; + for (i=0; i < windings; ++i) + n += wcount[i]; + + e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel + if (e == 0) return; + n = 0; + + m=0; + for (i=0; i < windings; ++i) { + stbtt__point *p = pts + m; + m += wcount[i]; + j = wcount[i]-1; + for (k=0; k < wcount[i]; j=k++) { + int a=k,b=j; + // skip the edge if horizontal + if (p[j].y == p[k].y) + continue; + // add edge from j to k to the list + e[n].invert = 0; + if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) { + e[n].invert = 1; + a=j,b=k; + } + e[n].x0 = p[a].x * scale_x + shift_x; + e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample; + e[n].x1 = p[b].x * scale_x + shift_x; + e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample; + ++n; + } + } + + // now sort the edges by their highest point (should snap to integer, and then by x) + //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); + stbtt__sort_edges(e, n); + + // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule + stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); + + STBTT_free(e, userdata); +} + +static void stbtt__add_point(stbtt__point *points, int n, float x, float y) +{ + if (!points) return; // during first pass, it's unallocated + points[n].x = x; + points[n].y = y; +} + +// tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching +static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n) +{ + // midpoint + float mx = (x0 + 2*x1 + x2)/4; + float my = (y0 + 2*y1 + y2)/4; + // versus directly drawn line + float dx = (x0+x2)/2 - mx; + float dy = (y0+y2)/2 - my; + if (n > 16) // 65536 segments on one curve better be enough! + return 1; + if (dx*dx+dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA + stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1); + stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1); + } else { + stbtt__add_point(points, *num_points,x2,y2); + *num_points = *num_points+1; + } + return 1; +} + +// returns number of contours +static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) +{ + stbtt__point *points=0; + int num_points=0; + + float objspace_flatness_squared = objspace_flatness * objspace_flatness; + int i,n=0,start=0, pass; + + // count how many "moves" there are to get the contour count + for (i=0; i < num_verts; ++i) + if (vertices[i].type == STBTT_vmove) + ++n; + + *num_contours = n; + if (n == 0) return 0; + + *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata); + + if (*contour_lengths == 0) { + *num_contours = 0; + return 0; + } + + // make two passes through the points so we don't need to realloc + for (pass=0; pass < 2; ++pass) { + float x=0,y=0; + if (pass == 1) { + points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata); + if (points == NULL) goto error; + } + num_points = 0; + n= -1; + for (i=0; i < num_verts; ++i) { + switch (vertices[i].type) { + case STBTT_vmove: + // start the next contour + if (n >= 0) + (*contour_lengths)[n] = num_points - start; + ++n; + start = num_points; + + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x,y); + break; + case STBTT_vline: + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x, y); + break; + case STBTT_vcurve: + stbtt__tesselate_curve(points, &num_points, x,y, + vertices[i].cx, vertices[i].cy, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x, y = vertices[i].y; + break; + } + } + (*contour_lengths)[n] = num_points - start; + } + + return points; +error: + STBTT_free(points, userdata); + STBTT_free(*contour_lengths, userdata); + *contour_lengths = 0; + *num_contours = 0; + return NULL; +} + +STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata) +{ + float scale = scale_x > scale_y ? scale_y : scale_x; + int winding_count, *winding_lengths; + stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); + if (windings) { + stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); + STBTT_free(winding_lengths, userdata); + STBTT_free(windings, userdata); + } +} + +STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata) +{ + STBTT_free(bitmap, userdata); +} + +STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff) +{ + int ix0,iy0,ix1,iy1; + stbtt__bitmap gbm; + stbtt_vertex *vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + + if (scale_x == 0) scale_x = scale_y; + if (scale_y == 0) { + if (scale_x == 0) { + STBTT_free(vertices, info->userdata); + return NULL; + } + scale_y = scale_x; + } + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1); + + // now we get the size + gbm.w = (ix1 - ix0); + gbm.h = (iy1 - iy0); + gbm.pixels = NULL; // in case we error + + if (width ) *width = gbm.w; + if (height) *height = gbm.h; + if (xoff ) *xoff = ix0; + if (yoff ) *yoff = iy0; + + if (gbm.w && gbm.h) { + gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata); + if (gbm.pixels) { + gbm.stride = gbm.w; + + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); + } + } + STBTT_free(vertices, info->userdata); + return gbm.pixels; +} + +STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff); +} + +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph) +{ + int ix0,iy0; + stbtt_vertex *vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + stbtt__bitmap gbm; + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0); + gbm.pixels = output; + gbm.w = out_w; + gbm.h = out_h; + gbm.stride = out_stride; + + if (gbm.w && gbm.h) + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata); + + STBTT_free(vertices, info->userdata); +} + +STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph) +{ + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph); +} + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); +} + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint) +{ + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint)); +} + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff); +} + +STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint) +{ + stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint); +} + +////////////////////////////////////////////////////////////////////////////// +// +// bitmap baking +// +// This is SUPER-CRAPPY packing to keep source code small + +STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) + float pixel_height, // height of font in pixels + unsigned char *pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar *chardata) +{ + float scale; + int x,y,bottom_y, i; + stbtt_fontinfo f; + f.userdata = NULL; + if (!stbtt_InitFont(&f, data, offset)) + return -1; + STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + x=y=1; + bottom_y = 1; + + scale = stbtt_ScaleForPixelHeight(&f, pixel_height); + + for (i=0; i < num_chars; ++i) { + int advance, lsb, x0,y0,x1,y1,gw,gh; + int g = stbtt_FindGlyphIndex(&f, first_char + i); + stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb); + stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1); + gw = x1-x0; + gh = y1-y0; + if (x + gw + 1 >= pw) + y = bottom_y, x = 1; // advance to next row + if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row + return -i; + STBTT_assert(x+gw < pw); + STBTT_assert(y+gh < ph); + stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g); + chardata[i].x0 = (stbtt_int16) x; + chardata[i].y0 = (stbtt_int16) y; + chardata[i].x1 = (stbtt_int16) (x + gw); + chardata[i].y1 = (stbtt_int16) (y + gh); + chardata[i].xadvance = scale * advance; + chardata[i].xoff = (float) x0; + chardata[i].yoff = (float) y0; + x = x + gw + 1; + if (y+gh+1 > bottom_y) + bottom_y = y+gh+1; + } + return bottom_y; +} + +STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) +{ + float d3d_bias = opengl_fillrule ? 0 : -0.5f; + float ipw = 1.0f / pw, iph = 1.0f / ph; + stbtt_bakedchar *b = chardata + char_index; + int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f); + int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f); + + q->x0 = round_x + d3d_bias; + q->y0 = round_y + d3d_bias; + q->x1 = round_x + b->x1 - b->x0 + d3d_bias; + q->y1 = round_y + b->y1 - b->y0 + d3d_bias; + + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; + + *xpos += b->xadvance; +} + +////////////////////////////////////////////////////////////////////////////// +// +// rectangle packing replacement routines if you don't have stb_rect_pack.h +// + +#ifndef STB_RECT_PACK_VERSION +#ifdef _MSC_VER +#define STBTT__NOTUSED(v) (void)(v) +#else +#define STBTT__NOTUSED(v) (void)sizeof(v) +#endif + +typedef int stbrp_coord; + +//////////////////////////////////////////////////////////////////////////////////// +// // +// // +// COMPILER WARNING ?!?!? // +// // +// // +// if you get a compile warning due to these symbols being defined more than // +// once, move #include "stb_rect_pack.h" before #include "stb_truetype.h" // +// // +//////////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + int width,height; + int x,y,bottom_y; +} stbrp_context; + +typedef struct +{ + unsigned char x; +} stbrp_node; + +struct stbrp_rect +{ + stbrp_coord x,y; + int id,w,h,was_packed; +}; + +static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes) +{ + con->width = pw; + con->height = ph; + con->x = 0; + con->y = 0; + con->bottom_y = 0; + STBTT__NOTUSED(nodes); + STBTT__NOTUSED(num_nodes); +} + +static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) +{ + int i; + for (i=0; i < num_rects; ++i) { + if (con->x + rects[i].w > con->width) { + con->x = 0; + con->y = con->bottom_y; + } + if (con->y + rects[i].h > con->height) + break; + rects[i].x = con->x; + rects[i].y = con->y; + rects[i].was_packed = 1; + con->x += rects[i].w; + if (con->y + rects[i].h > con->bottom_y) + con->bottom_y = con->y + rects[i].h; + } + for ( ; i < num_rects; ++i) + rects[i].was_packed = 0; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// bitmap baking +// +// This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If +// stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy. + +STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context) +{ + stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context); + int num_nodes = pw - padding; + stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context); + + if (context == NULL || nodes == NULL) { + if (context != NULL) STBTT_free(context, alloc_context); + if (nodes != NULL) STBTT_free(nodes , alloc_context); + return 0; + } + + spc->user_allocator_context = alloc_context; + spc->width = pw; + spc->height = ph; + spc->pixels = pixels; + spc->pack_info = context; + spc->nodes = nodes; + spc->padding = padding; + spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; + spc->h_oversample = 1; + spc->v_oversample = 1; + + stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); + + if (pixels) + STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + + return 1; +} + +STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc) +{ + STBTT_free(spc->nodes , spc->user_allocator_context); + STBTT_free(spc->pack_info, spc->user_allocator_context); +} + +STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample) +{ + STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE); + STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE); + if (h_oversample <= STBTT_MAX_OVERSAMPLE) + spc->h_oversample = h_oversample; + if (v_oversample <= STBTT_MAX_OVERSAMPLE) + spc->v_oversample = v_oversample; +} + +#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1) + +static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) +{ + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_w = w - kernel_width; + int j; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze + for (j=0; j < h; ++j) { + int i; + unsigned int total; + STBTT_memset(buffer, 0, kernel_width); + + total = 0; + + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch (kernel_width) { + case 2: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 2); + } + break; + case 3: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 3); + } + break; + case 4: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 4); + } + break; + case 5: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 5); + } + break; + default: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / kernel_width); + } + break; + } + + for (; i < w; ++i) { + STBTT_assert(pixels[i] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i] = (unsigned char) (total / kernel_width); + } + + pixels += stride_in_bytes; + } +} + +static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) +{ + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_h = h - kernel_width; + int j; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze + for (j=0; j < w; ++j) { + int i; + unsigned int total; + STBTT_memset(buffer, 0, kernel_width); + + total = 0; + + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch (kernel_width) { + case 2: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 2); + } + break; + case 3: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 3); + } + break; + case 4: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 4); + } + break; + case 5: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 5); + } + break; + default: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); + } + break; + } + + for (; i < h; ++i) { + STBTT_assert(pixels[i*stride_in_bytes] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); + } + + pixels += 1; + } +} + +static float stbtt__oversample_shift(int oversample) +{ + if (!oversample) + return 0.0f; + + // The prefilter is a box filter of width "oversample", + // which shifts phase by (oversample - 1)/2 pixels in + // oversampled space. We want to shift in the opposite + // direction to counter this. + return (float)-(oversample - 1) / (2.0f * (float)oversample); +} + +// rects array must be big enough to accommodate all characters in the given ranges +STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) +{ + int i,j,k; + + k=0; + for (i=0; i < num_ranges; ++i) { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); + ranges[i].h_oversample = (unsigned char) spc->h_oversample; + ranges[i].v_oversample = (unsigned char) spc->v_oversample; + for (j=0; j < ranges[i].num_chars; ++j) { + int x0,y0,x1,y1; + int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; + int glyph = stbtt_FindGlyphIndex(info, codepoint); + stbtt_GetGlyphBitmapBoxSubpixel(info,glyph, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0,0, + &x0,&y0,&x1,&y1); + rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1); + rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1); + ++k; + } + } + + return k; +} + +// rects array must be big enough to accommodate all characters in the given ranges +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) +{ + int i,j,k, return_value = 1; + + // save current values + int old_h_over = spc->h_oversample; + int old_v_over = spc->v_oversample; + + k = 0; + for (i=0; i < num_ranges; ++i) { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); + float recip_h,recip_v,sub_x,sub_y; + spc->h_oversample = ranges[i].h_oversample; + spc->v_oversample = ranges[i].v_oversample; + recip_h = 1.0f / spc->h_oversample; + recip_v = 1.0f / spc->v_oversample; + sub_x = stbtt__oversample_shift(spc->h_oversample); + sub_y = stbtt__oversample_shift(spc->v_oversample); + for (j=0; j < ranges[i].num_chars; ++j) { + stbrp_rect *r = &rects[k]; + if (r->was_packed) { + stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; + int advance, lsb, x0,y0,x1,y1; + int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; + int glyph = stbtt_FindGlyphIndex(info, codepoint); + stbrp_coord pad = (stbrp_coord) spc->padding; + + // pad on left and top + r->x += pad; + r->y += pad; + r->w -= pad; + r->h -= pad; + stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb); + stbtt_GetGlyphBitmapBox(info, glyph, + scale * spc->h_oversample, + scale * spc->v_oversample, + &x0,&y0,&x1,&y1); + stbtt_MakeGlyphBitmapSubpixel(info, + spc->pixels + r->x + r->y*spc->stride_in_bytes, + r->w - spc->h_oversample+1, + r->h - spc->v_oversample+1, + spc->stride_in_bytes, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0,0, + glyph); + + if (spc->h_oversample > 1) + stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->h_oversample); + + if (spc->v_oversample > 1) + stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->v_oversample); + + bc->x0 = (stbtt_int16) r->x; + bc->y0 = (stbtt_int16) r->y; + bc->x1 = (stbtt_int16) (r->x + r->w); + bc->y1 = (stbtt_int16) (r->y + r->h); + bc->xadvance = scale * advance; + bc->xoff = (float) x0 * recip_h + sub_x; + bc->yoff = (float) y0 * recip_v + sub_y; + bc->xoff2 = (x0 + r->w) * recip_h + sub_x; + bc->yoff2 = (y0 + r->h) * recip_v + sub_y; + } else { + return_value = 0; // if any fail, report failure + } + + ++k; + } + } + + // restore original values + spc->h_oversample = old_h_over; + spc->v_oversample = old_v_over; + + return return_value; +} + +STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects) +{ + stbrp_pack_rects((stbrp_context *) spc->pack_info, rects, num_rects); +} + +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) +{ + stbtt_fontinfo info; + int i,j,n, return_value = 1; + //stbrp_context *context = (stbrp_context *) spc->pack_info; + stbrp_rect *rects; + + // flag all characters as NOT packed + for (i=0; i < num_ranges; ++i) + for (j=0; j < ranges[i].num_chars; ++j) + ranges[i].chardata_for_range[j].x0 = + ranges[i].chardata_for_range[j].y0 = + ranges[i].chardata_for_range[j].x1 = + ranges[i].chardata_for_range[j].y1 = 0; + + n = 0; + for (i=0; i < num_ranges; ++i) + n += ranges[i].num_chars; + + rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); + if (rects == NULL) + return 0; + + info.userdata = spc->user_allocator_context; + stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index)); + + n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); + + stbtt_PackFontRangesPackRects(spc, rects, n); + + return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); + + STBTT_free(rects, spc->user_allocator_context); + return return_value; +} + +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, + int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) +{ + stbtt_pack_range range; + range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range; + range.array_of_unicode_codepoints = NULL; + range.num_chars = num_chars_in_range; + range.chardata_for_range = chardata_for_range; + range.font_size = font_size; + return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); +} + +STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) +{ + float ipw = 1.0f / pw, iph = 1.0f / ph; + stbtt_packedchar *b = chardata + char_index; + + if (align_to_integer) { + float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f); + float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5f); + q->x0 = x; + q->y0 = y; + q->x1 = x + b->xoff2 - b->xoff; + q->y1 = y + b->yoff2 - b->yoff; + } else { + q->x0 = *xpos + b->xoff; + q->y0 = *ypos + b->yoff; + q->x1 = *xpos + b->xoff2; + q->y1 = *ypos + b->yoff2; + } + + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; + + *xpos += b->xadvance; +} + + +////////////////////////////////////////////////////////////////////////////// +// +// font name matching -- recommended not to use this +// + +// check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string +static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2) +{ + stbtt_int32 i=0; + + // convert utf16 to utf8 and compare the results while converting + while (len2) { + stbtt_uint16 ch = s2[0]*256 + s2[1]; + if (ch < 0x80) { + if (i >= len1) return -1; + if (s1[i++] != ch) return -1; + } else if (ch < 0x800) { + if (i+1 >= len1) return -1; + if (s1[i++] != 0xc0 + (ch >> 6)) return -1; + if (s1[i++] != 0x80 + (ch & 0x3f)) return -1; + } else if (ch >= 0xd800 && ch < 0xdc00) { + stbtt_uint32 c; + stbtt_uint16 ch2 = s2[2]*256 + s2[3]; + if (i+3 >= len1) return -1; + c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000; + if (s1[i++] != 0xf0 + (c >> 18)) return -1; + if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((c ) & 0x3f)) return -1; + s2 += 2; // plus another 2 below + len2 -= 2; + } else if (ch >= 0xdc00 && ch < 0xe000) { + return -1; + } else { + if (i+2 >= len1) return -1; + if (s1[i++] != 0xe0 + (ch >> 12)) return -1; + if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((ch ) & 0x3f)) return -1; + } + s2 += 2; + len2 -= 2; + } + return i; +} + +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) +{ + return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8*) s1, len1, (const stbtt_uint8*) s2, len2); +} + +// returns results in whatever encoding you request... but note that 2-byte encodings +// will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare +STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID) +{ + stbtt_int32 i,count,stringOffset; + stbtt_uint8 *fc = font->data; + stbtt_uint32 offset = font->fontstart; + stbtt_uint32 nm = stbtt__find_table(fc, offset, "name"); + if (!nm) return NULL; + + count = ttUSHORT(fc+nm+2); + stringOffset = nm + ttUSHORT(fc+nm+4); + for (i=0; i < count; ++i) { + stbtt_uint32 loc = nm + 6 + 12 * i; + if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2) + && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) { + *length = ttUSHORT(fc+loc+8); + return (const char *) (fc+stringOffset+ttUSHORT(fc+loc+10)); + } + } + return NULL; +} + +static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id) +{ + stbtt_int32 i; + stbtt_int32 count = ttUSHORT(fc+nm+2); + stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4); + + for (i=0; i < count; ++i) { + stbtt_uint32 loc = nm + 6 + 12 * i; + stbtt_int32 id = ttUSHORT(fc+loc+6); + if (id == target_id) { + // find the encoding + stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4); + + // is this a Unicode encoding? + if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) { + stbtt_int32 slen = ttUSHORT(fc+loc+8); + stbtt_int32 off = ttUSHORT(fc+loc+10); + + // check if there's a prefix match + stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen); + if (matchlen >= 0) { + // check for target_id+1 immediately following, with same encoding & language + if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) { + slen = ttUSHORT(fc+loc+12+8); + off = ttUSHORT(fc+loc+12+10); + if (slen == 0) { + if (matchlen == nlen) + return 1; + } else if (matchlen < nlen && name[matchlen] == ' ') { + ++matchlen; + if (stbtt_CompareUTF8toUTF16_bigendian((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen)) + return 1; + } + } else { + // if nothing immediately following + if (matchlen == nlen) + return 1; + } + } + } + + // @TODO handle other encodings + } + } + return 0; +} + +static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags) +{ + stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name); + stbtt_uint32 nm,hd; + if (!stbtt__isfont(fc+offset)) return 0; + + // check italics/bold/underline flags in macStyle... + if (flags) { + hd = stbtt__find_table(fc, offset, "head"); + if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0; + } + + nm = stbtt__find_table(fc, offset, "name"); + if (!nm) return 0; + + if (flags) { + // if we checked the macStyle flags, then just check the family and ignore the subfamily + if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } else { + if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } + + return 0; +} + +STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *name_utf8, stbtt_int32 flags) +{ + stbtt_int32 i; + for (i=0;;++i) { + stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i); + if (off < 0) return off; + if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags)) + return off; + } +} + +#endif // STB_TRUETYPE_IMPLEMENTATION + + +// FULL VERSION HISTORY +// +// 1.10 (2016-04-02) allow user-defined fabs() replacement +// fix memory leak if fontsize=0.0 +// fix warning from duplicate typedef +// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges +// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges +// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; +// allow PackFontRanges to pack and render in separate phases; +// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?); +// fixed an assert() bug in the new rasterizer +// replace assert() with STBTT_assert() in new rasterizer +// 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine) +// also more precise AA rasterizer, except if shapes overlap +// remove need for STBTT_sort +// 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC +// 1.04 (2015-04-15) typo in example +// 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes +// 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++ +// 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match +// non-oversampled; STBTT_POINT_SIZE for packed case only +// 1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling +// 0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg) +// 0.9 (2014-08-07) support certain mac/iOS fonts without an MS platformID +// 0.8b (2014-07-07) fix a warning +// 0.8 (2014-05-25) fix a few more warnings +// 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back +// 0.6c (2012-07-24) improve documentation +// 0.6b (2012-07-20) fix a few more warnings +// 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels, +// stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty +// 0.5 (2011-12-09) bugfixes: +// subpixel glyph renderer computed wrong bounding box +// first vertex of shape can be off-curve (FreeSans) +// 0.4b (2011-12-03) fixed an error in the font baking example +// 0.4 (2011-12-01) kerning, subpixel rendering (tor) +// bugfixes for: +// codepoint-to-glyph conversion using table fmt=12 +// codepoint-to-glyph conversion using table fmt=4 +// stbtt_GetBakedQuad with non-square texture (Zer) +// updated Hello World! sample to use kerning and subpixel +// fixed some warnings +// 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM) +// userdata, malloc-from-userdata, non-zero fill (stb) +// 0.2 (2009-03-11) Fix unsigned/signed char warnings +// 0.1 (2009-03-09) First public release +// diff --git a/CameraParameterEstimation/apps/basics/extern/lodepng.h b/CameraParameterEstimation/apps/basics/extern/lodepng.h new file mode 100644 index 0000000..6a8639a --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/lodepng.h @@ -0,0 +1,1769 @@ +// This file is a slight modification of original LodePNG library, where +// the C++ interface has been disabled and the source is included as inline +// file, to enable header-only inclusion. +// Modifications by Maciej Halber + +/* +LodePNG version 20160501 + +Copyright (c) 2005-2016 Lode Vandevenne + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#ifndef LODEPNG_H +#define LODEPNG_H + +#include /*for size_t*/ + +extern const char* LODEPNG_VERSION_STRING; + +/* +The following #defines are used to create code sections. They can be disabled +to disable code sections, which can give faster compile time and smaller binary. +The "NO_COMPILE" defines are designed to be used to pass as defines to the +compiler command to disable them without modifying this header, e.g. +-DLODEPNG_NO_COMPILE_ZLIB for gcc. +In addition to those below, you can also define LODEPNG_NO_COMPILE_CRC to +allow implementing a custom lodepng_crc32. +*/ +/*deflate & zlib. If disabled, you must specify alternative zlib functions in +the custom_zlib field of the compress and decompress settings*/ +#ifndef LODEPNG_NO_COMPILE_ZLIB +#define LODEPNG_COMPILE_ZLIB +#endif +/*png encoder and png decoder*/ +#ifndef LODEPNG_NO_COMPILE_PNG +#define LODEPNG_COMPILE_PNG +#endif +/*deflate&zlib decoder and png decoder*/ +#ifndef LODEPNG_NO_COMPILE_DECODER +#define LODEPNG_COMPILE_DECODER +#endif +/*deflate&zlib encoder and png encoder*/ +#ifndef LODEPNG_NO_COMPILE_ENCODER +#define LODEPNG_COMPILE_ENCODER +#endif +/*the optional built in harddisk file loading and saving functions*/ +#ifndef LODEPNG_NO_COMPILE_DISK +#define LODEPNG_COMPILE_DISK +#endif +/*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/ +#ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS +#define LODEPNG_COMPILE_ANCILLARY_CHUNKS +#endif +/*ability to convert error numerical codes to English text string*/ +#ifndef LODEPNG_NO_COMPILE_ERROR_TEXT +#define LODEPNG_COMPILE_ERROR_TEXT +#endif +/*Compile the default allocators (C's free, malloc and realloc). If you disable this, +you can define the functions lodepng_free, lodepng_malloc and lodepng_realloc in your +source files with custom allocators.*/ +#ifndef LODEPNG_NO_COMPILE_ALLOCATORS +#define LODEPNG_COMPILE_ALLOCATORS +#endif +/*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/ +// NOTE(maciej) : C++ interface should be completly disabled +#ifdef __cplusplus +#ifndef LODEPNG_NO_COMPILE_CPP +// #define LODEPNG_COMPILE_CPP +#endif +#endif + +#ifdef LODEPNG_COMPILE_CPP +#include +#include +#endif /*LODEPNG_COMPILE_CPP*/ + +#ifdef LODEPNG_COMPILE_PNG +/*The PNG color types (also used for raw).*/ +typedef enum LodePNGColorType +{ + LCT_GREY = 0, /*greyscale: 1,2,4,8,16 bit*/ + LCT_RGB = 2, /*RGB: 8,16 bit*/ + LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/ + LCT_GREY_ALPHA = 4, /*greyscale with alpha: 8,16 bit*/ + LCT_RGBA = 6 /*RGB with alpha: 8,16 bit*/ +} LodePNGColorType; + +#ifdef LODEPNG_COMPILE_DECODER +/* +Converts PNG data in memory to raw pixel data. +out: Output parameter. Pointer to buffer that will contain the raw pixel data. + After decoding, its size is w * h * (bytes per pixel) bytes larger than + initially. Bytes per pixel depends on colortype and bitdepth. + Must be freed after usage with free(*out). + Note: for 16-bit per channel colors, uses big endian format like PNG does. +w: Output parameter. Pointer to width of pixel data. +h: Output parameter. Pointer to height of pixel data. +in: Memory buffer with the PNG file. +insize: size of the in buffer. +colortype: the desired color type for the raw output image. See explanation on PNG color types. +bitdepth: the desired bit depth for the raw output image. See explanation on PNG color types. +Return value: LodePNG error code (0 means no error). +*/ + +unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, + const unsigned char* in, size_t insize, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_decode_memory, but always decodes to 32-bit RGBA raw image*/ +unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, + const unsigned char* in, size_t insize); + +/*Same as lodepng_decode_memory, but always decodes to 24-bit RGB raw image*/ +unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, + const unsigned char* in, size_t insize); + +#ifdef LODEPNG_COMPILE_DISK +/* +Load PNG from disk, from file with given name. +Same as the other decode functions, but instead takes a filename as input. +*/ +unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, + const char* filename, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image.*/ +unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, + const char* filename); + +/*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image.*/ +unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, + const char* filename); +#endif /*LODEPNG_COMPILE_DISK*/ +#endif /*LODEPNG_COMPILE_DECODER*/ + + +#ifdef LODEPNG_COMPILE_ENCODER +/* +Converts raw pixel data into a PNG image in memory. The colortype and bitdepth + of the output PNG image cannot be chosen, they are automatically determined + by the colortype, bitdepth and content of the input pixel data. + Note: for 16-bit per channel colors, needs big endian format like PNG does. +out: Output parameter. Pointer to buffer that will contain the PNG image data. + Must be freed after usage with free(*out). +outsize: Output parameter. Pointer to the size in bytes of the out buffer. +image: The raw pixel data to encode. The size of this buffer should be + w * h * (bytes per pixel), bytes per pixel depends on colortype and bitdepth. +w: width of the raw pixel data in pixels. +h: height of the raw pixel data in pixels. +colortype: the color type of the raw input image. See explanation on PNG color types. +bitdepth: the bit depth of the raw input image. See explanation on PNG color types. +Return value: LodePNG error code (0 means no error). +*/ +unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_encode_memory, but always encodes from 32-bit RGBA raw image.*/ +unsigned lodepng_encode32(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h); + +/*Same as lodepng_encode_memory, but always encodes from 24-bit RGB raw image.*/ +unsigned lodepng_encode24(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h); + +#ifdef LODEPNG_COMPILE_DISK +/* +Converts raw pixel data into a PNG file on disk. +Same as the other encode functions, but instead takes a filename as output. +NOTE: This overwrites existing files without warning! +*/ +unsigned lodepng_encode_file(const char* filename, + const unsigned char* image, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image.*/ +unsigned lodepng_encode32_file(const char* filename, + const unsigned char* image, unsigned w, unsigned h); + +/*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image.*/ +unsigned lodepng_encode24_file(const char* filename, + const unsigned char* image, unsigned w, unsigned h); +#endif /*LODEPNG_COMPILE_DISK*/ +#endif /*LODEPNG_COMPILE_ENCODER*/ + + +#ifdef LODEPNG_COMPILE_CPP +namespace lodepng +{ +#ifdef LODEPNG_COMPILE_DECODER +/*Same as lodepng_decode_memory, but decodes to an std::vector. The colortype +is the format to output the pixels to. Default is RGBA 8-bit per channel.*/ +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + const unsigned char* in, size_t insize, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + const std::vector& in, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#ifdef LODEPNG_COMPILE_DISK +/* +Converts PNG file from disk to raw pixel data in memory. +Same as the other decode functions, but instead takes a filename as input. +*/ +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + const std::string& filename, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_DECODER */ + +#ifdef LODEPNG_COMPILE_ENCODER +/*Same as lodepng_encode_memory, but encodes to an std::vector. colortype +is that of the raw input data. The output PNG color type will be auto chosen.*/ +unsigned encode(std::vector& out, + const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +unsigned encode(std::vector& out, + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#ifdef LODEPNG_COMPILE_DISK +/* +Converts 32-bit RGBA raw pixel data into a PNG file on disk. +Same as the other encode functions, but instead takes a filename as output. +NOTE: This overwrites existing files without warning! +*/ +unsigned encode(const std::string& filename, + const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +unsigned encode(const std::string& filename, + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_ENCODER */ +} /* namespace lodepng */ +#endif /*LODEPNG_COMPILE_CPP*/ +#endif /*LODEPNG_COMPILE_PNG*/ + +#ifdef LODEPNG_COMPILE_ERROR_TEXT +/*Returns an English description of the numerical error code.*/ +const char* lodepng_error_text(unsigned code); +#endif /*LODEPNG_COMPILE_ERROR_TEXT*/ + +#ifdef LODEPNG_COMPILE_DECODER +/*Settings for zlib decompression*/ +typedef struct LodePNGDecompressSettings LodePNGDecompressSettings; +struct LodePNGDecompressSettings +{ + unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/ + + /*use custom zlib decoder instead of built in one (default: null)*/ + unsigned (*custom_zlib)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGDecompressSettings*); + /*use custom deflate decoder instead of built in one (default: null) + if custom_zlib is used, custom_deflate is ignored since only the built in + zlib function will call custom_deflate*/ + unsigned (*custom_inflate)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGDecompressSettings*); + + const void* custom_context; /*optional custom settings for custom functions*/ +}; + +extern const LodePNGDecompressSettings lodepng_default_decompress_settings; +void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/* +Settings for zlib compression. Tweaking these settings tweaks the balance +between speed and compression ratio. +*/ +typedef struct LodePNGCompressSettings LodePNGCompressSettings; +struct LodePNGCompressSettings /*deflate = compress*/ +{ + /*LZ77 related settings*/ + unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/ + unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/ + unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/ + unsigned minmatch; /*mininum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/ + unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/ + unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/ + + /*use custom zlib encoder instead of built in one (default: null)*/ + unsigned (*custom_zlib)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGCompressSettings*); + /*use custom deflate encoder instead of built in one (default: null) + if custom_zlib is used, custom_deflate is ignored since only the built in + zlib function will call custom_deflate*/ + unsigned (*custom_deflate)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGCompressSettings*); + + const void* custom_context; /*optional custom settings for custom functions*/ +}; + +extern const LodePNGCompressSettings lodepng_default_compress_settings; +void lodepng_compress_settings_init(LodePNGCompressSettings* settings); +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_PNG +/* +Color mode of an image. Contains all information required to decode the pixel +bits to RGBA colors. This information is the same as used in the PNG file +format, and is used both for PNG and raw image data in LodePNG. +*/ +typedef struct LodePNGColorMode +{ + /*header (IHDR)*/ + LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/ + unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/ + + /* + palette (PLTE and tRNS) + + Dynamically allocated with the colors of the palette, including alpha. + When encoding a PNG, to store your colors in the palette of the LodePNGColorMode, first use + lodepng_palette_clear, then for each color use lodepng_palette_add. + If you encode an image without alpha with palette, don't forget to put value 255 in each A byte of the palette. + + When decoding, by default you can ignore this palette, since LodePNG already + fills the palette colors in the pixels of the raw RGBA output. + + The palette is only supported for color type 3. + */ + unsigned char* palette; /*palette in RGBARGBA... order. When allocated, must be either 0, or have size 1024*/ + size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/ + + /* + transparent color key (tRNS) + + This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit. + For greyscale PNGs, r, g and b will all 3 be set to the same. + + When decoding, by default you can ignore this information, since LodePNG sets + pixels with this key to transparent already in the raw RGBA output. + + The color key is only supported for color types 0 and 2. + */ + unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/ + unsigned key_r; /*red/greyscale component of color key*/ + unsigned key_g; /*green component of color key*/ + unsigned key_b; /*blue component of color key*/ +} LodePNGColorMode; + +/*init, cleanup and copy functions to use with this struct*/ +void lodepng_color_mode_init(LodePNGColorMode* info); +void lodepng_color_mode_cleanup(LodePNGColorMode* info); +/*return value is error code (0 means no error)*/ +unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source); + +void lodepng_palette_clear(LodePNGColorMode* info); +/*add 1 color to the palette*/ +unsigned lodepng_palette_add(LodePNGColorMode* info, + unsigned char r, unsigned char g, unsigned char b, unsigned char a); + +/*get the total amount of bits per pixel, based on colortype and bitdepth in the struct*/ +unsigned lodepng_get_bpp(const LodePNGColorMode* info); +/*get the amount of color channels used, based on colortype in the struct. +If a palette is used, it counts as 1 channel.*/ +unsigned lodepng_get_channels(const LodePNGColorMode* info); +/*is it a greyscale type? (only colortype 0 or 4)*/ +unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info); +/*has it got an alpha channel? (only colortype 2 or 6)*/ +unsigned lodepng_is_alpha_type(const LodePNGColorMode* info); +/*has it got a palette? (only colortype 3)*/ +unsigned lodepng_is_palette_type(const LodePNGColorMode* info); +/*only returns true if there is a palette and there is a value in the palette with alpha < 255. +Loops through the palette to check this.*/ +unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info); +/* +Check if the given color info indicates the possibility of having non-opaque pixels in the PNG image. +Returns true if the image can have translucent or invisible pixels (it still be opaque if it doesn't use such pixels). +Returns false if the image can only have opaque pixels. +In detail, it returns true only if it's a color type with alpha, or has a palette with non-opaque values, +or if "key_defined" is true. +*/ +unsigned lodepng_can_have_alpha(const LodePNGColorMode* info); +/*Returns the byte size of a raw image buffer with given width, height and color mode*/ +size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color); + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +/*The information of a Time chunk in PNG.*/ +typedef struct LodePNGTime +{ + unsigned year; /*2 bytes used (0-65535)*/ + unsigned month; /*1-12*/ + unsigned day; /*1-31*/ + unsigned hour; /*0-23*/ + unsigned minute; /*0-59*/ + unsigned second; /*0-60 (to allow for leap seconds)*/ +} LodePNGTime; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +/*Information about the PNG image, except pixels, width and height.*/ +typedef struct LodePNGInfo +{ + /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/ + unsigned compression_method;/*compression method of the original file. Always 0.*/ + unsigned filter_method; /*filter method of the original file*/ + unsigned interlace_method; /*interlace method of the original file*/ + LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/ + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /* + suggested background color chunk (bKGD) + This color uses the same color mode as the PNG (except alpha channel), which can be 1-bit to 16-bit. + + For greyscale PNGs, r, g and b will all 3 be set to the same. When encoding + the encoder writes the red one. For palette PNGs: When decoding, the RGB value + will be stored, not a palette index. But when encoding, specify the index of + the palette in background_r, the other two are then ignored. + + The decoder does not use this background color to edit the color of pixels. + */ + unsigned background_defined; /*is a suggested background color given?*/ + unsigned background_r; /*red component of suggested background color*/ + unsigned background_g; /*green component of suggested background color*/ + unsigned background_b; /*blue component of suggested background color*/ + + /* + non-international text chunks (tEXt and zTXt) + + The char** arrays each contain num strings. The actual messages are in + text_strings, while text_keys are keywords that give a short description what + the actual text represents, e.g. Title, Author, Description, or anything else. + + A keyword is minimum 1 character and maximum 79 characters long. It's + discouraged to use a single line length longer than 79 characters for texts. + + Don't allocate these text buffers yourself. Use the init/cleanup functions + correctly and use lodepng_add_text and lodepng_clear_text. + */ + size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/ + char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/ + char** text_strings; /*the actual text*/ + + /* + international text chunks (iTXt) + Similar to the non-international text chunks, but with additional strings + "langtags" and "transkeys". + */ + size_t itext_num; /*the amount of international texts in this PNG*/ + char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/ + char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/ + char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/ + char** itext_strings; /*the actual international text - UTF-8 string*/ + + /*time chunk (tIME)*/ + unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/ + LodePNGTime time; + + /*phys chunk (pHYs)*/ + unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/ + unsigned phys_x; /*pixels per unit in x direction*/ + unsigned phys_y; /*pixels per unit in y direction*/ + unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/ + + /* + unknown chunks + There are 3 buffers, one for each position in the PNG where unknown chunks can appear + each buffer contains all unknown chunks for that position consecutively + The 3 buffers are the unknown chunks between certain critical chunks: + 0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND + Do not allocate or traverse this data yourself. Use the chunk traversing functions declared + later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct. + */ + unsigned char* unknown_chunks_data[3]; + size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} LodePNGInfo; + +/*init, cleanup and copy functions to use with this struct*/ +void lodepng_info_init(LodePNGInfo* info); +void lodepng_info_cleanup(LodePNGInfo* info); +/*return value is error code (0 means no error)*/ +unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source); + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/ +unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/ + +void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/ +unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, + const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +/* +Converts raw buffer from one color type to another color type, based on +LodePNGColorMode structs to describe the input and output color type. +See the reference manual at the end of this header file to see which color conversions are supported. +return value = LodePNG error code (0 if all went ok, an error if the conversion isn't supported) +The out buffer must have size (w * h * bpp + 7) / 8, where bpp is the bits per pixel +of the output color type (lodepng_get_bpp). +For < 8 bpp images, there should not be padding bits at the end of scanlines. +For 16-bit per channel colors, uses big endian format like PNG does. +Return value is LodePNG error code +*/ +unsigned lodepng_convert(unsigned char* out, const unsigned char* in, + const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, + unsigned w, unsigned h); + +#ifdef LODEPNG_COMPILE_DECODER +/* +Settings for the decoder. This contains settings for the PNG and the Zlib +decoder, but not the Info settings from the Info structs. +*/ +typedef struct LodePNGDecoderSettings +{ + LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/ + + unsigned ignore_crc; /*ignore CRC checksums*/ + + unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/ + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/ + /*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/ + unsigned remember_unknown_chunks; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} LodePNGDecoderSettings; + +void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/ +typedef enum LodePNGFilterStrategy +{ + /*every filter at zero*/ + LFS_ZERO, + /*Use filter that gives minimum sum, as described in the official PNG filter heuristic.*/ + LFS_MINSUM, + /*Use the filter type that gives smallest Shannon entropy for this scanline. Depending + on the image, this is better or worse than minsum.*/ + LFS_ENTROPY, + /* + Brute-force-search PNG filters by compressing each filter for each scanline. + Experimental, very slow, and only rarely gives better compression than MINSUM. + */ + LFS_BRUTE_FORCE, + /*use predefined_filters buffer: you specify the filter type for each scanline*/ + LFS_PREDEFINED +} LodePNGFilterStrategy; + +/*Gives characteristics about the colors of the image, which helps decide which color model to use for encoding. +Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/ +typedef struct LodePNGColorProfile +{ + unsigned colored; /*not greyscale*/ + unsigned key; /*if true, image is not opaque. Only if true and alpha is false, color key is possible.*/ + unsigned short key_r; /*these values are always in 16-bit bitdepth in the profile*/ + unsigned short key_g; + unsigned short key_b; + unsigned alpha; /*alpha channel or alpha palette required*/ + unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16.*/ + unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order*/ + unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for greyscale only. 16 if 16-bit per channel required.*/ +} LodePNGColorProfile; + +void lodepng_color_profile_init(LodePNGColorProfile* profile); + +/*Get a LodePNGColorProfile of the image.*/ +unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, + const unsigned char* image, unsigned w, unsigned h, + const LodePNGColorMode* mode_in); +/*The function LodePNG uses internally to decide the PNG color with auto_convert. +Chooses an optimal color model, e.g. grey if only grey pixels, palette if < 256 colors, ...*/ +unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, + const unsigned char* image, unsigned w, unsigned h, + const LodePNGColorMode* mode_in); + +/*Settings for the encoder.*/ +typedef struct LodePNGEncoderSettings +{ + LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/ + + unsigned auto_convert; /*automatically choose output PNG color type. Default: true*/ + + /*If true, follows the official PNG heuristic: if the PNG uses a palette or lower than + 8 bit depth, set all filters to zero. Otherwise use the filter_strategy. Note that to + completely follow the official PNG heuristic, filter_palette_zero must be true and + filter_strategy must be LFS_MINSUM*/ + unsigned filter_palette_zero; + /*Which filter strategy to use when not using zeroes due to filter_palette_zero. + Set filter_palette_zero to 0 to ensure always using your chosen strategy. Default: LFS_MINSUM*/ + LodePNGFilterStrategy filter_strategy; + /*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with + the same length as the amount of scanlines in the image, and each value must <= 5. You + have to cleanup this buffer, LodePNG will never free it. Don't forget that filter_palette_zero + must be set to 0 to ensure this is also used on palette or low bitdepth images.*/ + const unsigned char* predefined_filters; + + /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). + If colortype is 3, PLTE is _always_ created.*/ + unsigned force_palette; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*add LodePNG identifier and version as a text chunk, for debugging*/ + unsigned add_id; + /*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/ + unsigned text_compression; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} LodePNGEncoderSettings; + +void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings); +#endif /*LODEPNG_COMPILE_ENCODER*/ + + +#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) +/*The settings, state and information for extended encoding and decoding.*/ +typedef struct LodePNGState +{ +#ifdef LODEPNG_COMPILE_DECODER + LodePNGDecoderSettings decoder; /*the decoding settings*/ +#endif /*LODEPNG_COMPILE_DECODER*/ +#ifdef LODEPNG_COMPILE_ENCODER + LodePNGEncoderSettings encoder; /*the encoding settings*/ +#endif /*LODEPNG_COMPILE_ENCODER*/ + LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/ + LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ + unsigned error; +#ifdef LODEPNG_COMPILE_CPP + /* For the lodepng::State subclass. */ + virtual ~LodePNGState(){} +#endif +} LodePNGState; + +/*init, cleanup and copy functions to use with this struct*/ +void lodepng_state_init(LodePNGState* state); +void lodepng_state_cleanup(LodePNGState* state); +void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source); +#endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ + +#ifdef LODEPNG_COMPILE_DECODER +/* +Same as lodepng_decode_memory, but uses a LodePNGState to allow custom settings and +getting much more information about the PNG image and color mode. +*/ +unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, + LodePNGState* state, + const unsigned char* in, size_t insize); + +/* +Read the PNG header, but not the actual data. This returns only the information +that is in the header chunk of the PNG, such as width, height and color type. The +information is placed in the info_png field of the LodePNGState. +*/ +unsigned lodepng_inspect(unsigned* w, unsigned* h, + LodePNGState* state, + const unsigned char* in, size_t insize); +#endif /*LODEPNG_COMPILE_DECODER*/ + + +#ifdef LODEPNG_COMPILE_ENCODER +/*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/ +unsigned lodepng_encode(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h, + LodePNGState* state); +#endif /*LODEPNG_COMPILE_ENCODER*/ + +/* +The lodepng_chunk functions are normally not needed, except to traverse the +unknown chunks stored in the LodePNGInfo struct, or add new ones to it. +It also allows traversing the chunks of an encoded PNG file yourself. + +PNG standard chunk naming conventions: +First byte: uppercase = critical, lowercase = ancillary +Second byte: uppercase = public, lowercase = private +Third byte: must be uppercase +Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy +*/ + +/* +Gets the length of the data of the chunk. Total chunk length has 12 bytes more. +There must be at least 4 bytes to read from. If the result value is too large, +it may be corrupt data. +*/ +unsigned lodepng_chunk_length(const unsigned char* chunk); + +/*puts the 4-byte type in null terminated string*/ +void lodepng_chunk_type(char type[5], const unsigned char* chunk); + +/*check if the type is the given type*/ +unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type); + +/*0: it's one of the critical chunk types, 1: it's an ancillary chunk (see PNG standard)*/ +unsigned char lodepng_chunk_ancillary(const unsigned char* chunk); + +/*0: public, 1: private (see PNG standard)*/ +unsigned char lodepng_chunk_private(const unsigned char* chunk); + +/*0: the chunk is unsafe to copy, 1: the chunk is safe to copy (see PNG standard)*/ +unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk); + +/*get pointer to the data of the chunk, where the input points to the header of the chunk*/ +unsigned char* lodepng_chunk_data(unsigned char* chunk); +const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk); + +/*returns 0 if the crc is correct, 1 if it's incorrect (0 for OK as usual!)*/ +unsigned lodepng_chunk_check_crc(const unsigned char* chunk); + +/*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/ +void lodepng_chunk_generate_crc(unsigned char* chunk); + +/*iterate to next chunks. don't use on IEND chunk, as there is no next chunk then*/ +unsigned char* lodepng_chunk_next(unsigned char* chunk); +const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk); + +/* +Appends chunk to the data in out. The given chunk should already have its chunk header. +The out variable and outlength are updated to reflect the new reallocated buffer. +Returns error code (0 if it went ok) +*/ +unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk); + +/* +Appends new chunk to out. The chunk to append is given by giving its length, type +and data separately. The type is a 4-letter string. +The out variable and outlength are updated to reflect the new reallocated buffer. +Returne error code (0 if it went ok) +*/ +unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, + const char* type, const unsigned char* data); + + +/*Calculate CRC32 of buffer*/ +unsigned lodepng_crc32(const unsigned char* buf, size_t len); +#endif /*LODEPNG_COMPILE_PNG*/ + + +#ifdef LODEPNG_COMPILE_ZLIB +/* +This zlib part can be used independently to zlib compress and decompress a +buffer. It cannot be used to create gzip files however, and it only supports the +part of zlib that is required for PNG, it does not support dictionaries. +*/ + +#ifdef LODEPNG_COMPILE_DECODER +/*Inflate a buffer. Inflate is the decompression step of deflate. Out buffer must be freed after use.*/ +unsigned lodepng_inflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings); + +/* +Decompresses Zlib data. Reallocates the out buffer and appends the data. The +data must be according to the zlib specification. +Either, *out must be NULL and *outsize must be 0, or, *out must be a valid +buffer and *outsize its size in bytes. out must be freed by user after usage. +*/ +unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/* +Compresses data with Zlib. Reallocates the out buffer and appends the data. +Zlib adds a small header and trailer around the deflate data. +The data is output in the format of the zlib specification. +Either, *out must be NULL and *outsize must be 0, or, *out must be a valid +buffer and *outsize its size in bytes. out must be freed by user after usage. +*/ +unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings); + +/* +Find length-limited Huffman code for given frequencies. This function is in the +public interface only for tests, it's used internally by lodepng_deflate. +*/ +unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, + size_t numcodes, unsigned maxbitlen); + +/*Compress a buffer with deflate. See RFC 1951. Out buffer must be freed after use.*/ +unsigned lodepng_deflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings); + +#endif /*LODEPNG_COMPILE_ENCODER*/ +#endif /*LODEPNG_COMPILE_ZLIB*/ + +#ifdef LODEPNG_COMPILE_DISK +/* +Load a file from disk into buffer. The function allocates the out buffer, and +after usage you should free it. +out: output parameter, contains pointer to loaded buffer. +outsize: output parameter, size of the allocated out buffer +filename: the path to the file to load +return value: error code (0 means ok) +*/ +unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename); + +/* +Save a file from buffer to disk. Warning, if it exists, this function overwrites +the file without warning! +buffer: the buffer to write +buffersize: size of the buffer to write +filename: the path to the file to save to +return value: error code (0 means ok) +*/ +unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename); +#endif /*LODEPNG_COMPILE_DISK*/ + +#ifdef LODEPNG_COMPILE_CPP +/* The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. */ +namespace lodepng +{ +#ifdef LODEPNG_COMPILE_PNG +class State : public LodePNGState +{ + public: + State(); + State(const State& other); + virtual ~State(); + State& operator=(const State& other); +}; + +#ifdef LODEPNG_COMPILE_DECODER +/* Same as other lodepng::decode, but using a State for more settings and information. */ +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + State& state, + const unsigned char* in, size_t insize); +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + State& state, + const std::vector& in); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/* Same as other lodepng::encode, but using a State for more settings and information. */ +unsigned encode(std::vector& out, + const unsigned char* in, unsigned w, unsigned h, + State& state); +unsigned encode(std::vector& out, + const std::vector& in, unsigned w, unsigned h, + State& state); +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_DISK +/* +Load a file from disk into an std::vector. +return value: error code (0 means ok) +*/ +unsigned load_file(std::vector& buffer, const std::string& filename); + +/* +Save the binary data in an std::vector to a file on disk. The file is overwritten +without warning. +*/ +unsigned save_file(const std::vector& buffer, const std::string& filename); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_PNG */ + +#ifdef LODEPNG_COMPILE_ZLIB +#ifdef LODEPNG_COMPILE_DECODER +/* Zlib-decompress an unsigned char buffer */ +unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, + const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); + +/* Zlib-decompress an std::vector */ +unsigned decompress(std::vector& out, const std::vector& in, + const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); +#endif /* LODEPNG_COMPILE_DECODER */ + +#ifdef LODEPNG_COMPILE_ENCODER +/* Zlib-compress an unsigned char buffer */ +unsigned compress(std::vector& out, const unsigned char* in, size_t insize, + const LodePNGCompressSettings& settings = lodepng_default_compress_settings); + +/* Zlib-compress an std::vector */ +unsigned compress(std::vector& out, const std::vector& in, + const LodePNGCompressSettings& settings = lodepng_default_compress_settings); +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_ZLIB */ +} /* namespace lodepng */ +#endif /*LODEPNG_COMPILE_CPP*/ + +/* +TODO: +[.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often +[.] check compatibility with various compilers - done but needs to be redone for every newer version +[X] converting color to 16-bit per channel types +[ ] read all public PNG chunk types (but never let the color profile and gamma ones touch RGB values) +[ ] make sure encoder generates no chunks with size > (2^31)-1 +[ ] partial decoding (stream processing) +[X] let the "isFullyOpaque" function check color keys and transparent palettes too +[X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl" +[ ] don't stop decoding on errors like 69, 57, 58 (make warnings) +[ ] make warnings like: oob palette, checksum fail, data after iend, wrong/unknown crit chunk, no null terminator in text, ... +[ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes +[ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ... +[ ] allow user to give data (void*) to custom allocator +*/ + +#endif /*LODEPNG_H inclusion guard*/ + +/* +LodePNG Documentation +--------------------- + +0. table of contents +-------------------- + + 1. about + 1.1. supported features + 1.2. features not supported + 2. C and C++ version + 3. security + 4. decoding + 5. encoding + 6. color conversions + 6.1. PNG color types + 6.2. color conversions + 6.3. padding bits + 6.4. A note about 16-bits per channel and endianness + 7. error values + 8. chunks and PNG editing + 9. compiler support + 10. examples + 10.1. decoder C++ example + 10.2. decoder C example + 11. state settings reference + 12. changes + 13. contact information + + +1. about +-------- + +PNG is a file format to store raster images losslessly with good compression, +supporting different color types and alpha channel. + +LodePNG is a PNG codec according to the Portable Network Graphics (PNG) +Specification (Second Edition) - W3C Recommendation 10 November 2003. + +The specifications used are: + +*) Portable Network Graphics (PNG) Specification (Second Edition): + http://www.w3.org/TR/2003/REC-PNG-20031110 +*) RFC 1950 ZLIB Compressed Data Format version 3.3: + http://www.gzip.org/zlib/rfc-zlib.html +*) RFC 1951 DEFLATE Compressed Data Format Specification ver 1.3: + http://www.gzip.org/zlib/rfc-deflate.html + +The most recent version of LodePNG can currently be found at +http://lodev.org/lodepng/ + +LodePNG works both in C (ISO C90) and C++, with a C++ wrapper that adds +extra functionality. + +LodePNG exists out of two files: +-lodepng.h: the header file for both C and C++ +-lodepng.c(pp): give it the name lodepng.c or lodepng.cpp (or .cc) depending on your usage + +If you want to start using LodePNG right away without reading this doc, get the +examples from the LodePNG website to see how to use it in code, or check the +smaller examples in chapter 13 here. + +LodePNG is simple but only supports the basic requirements. To achieve +simplicity, the following design choices were made: There are no dependencies +on any external library. There are functions to decode and encode a PNG with +a single function call, and extended versions of these functions taking a +LodePNGState struct allowing to specify or get more information. By default +the colors of the raw image are always RGB or RGBA, no matter what color type +the PNG file uses. To read and write files, there are simple functions to +convert the files to/from buffers in memory. + +This all makes LodePNG suitable for loading textures in games, demos and small +programs, ... It's less suitable for full fledged image editors, loading PNGs +over network (it requires all the image data to be available before decoding can +begin), life-critical systems, ... + +1.1. supported features +----------------------- + +The following features are supported by the decoder: + +*) decoding of PNGs with any color type, bit depth and interlace mode, to a 24- or 32-bit color raw image, + or the same color type as the PNG +*) encoding of PNGs, from any raw image to 24- or 32-bit color, or the same color type as the raw image +*) Adam7 interlace and deinterlace for any color type +*) loading the image from harddisk or decoding it from a buffer from other sources than harddisk +*) support for alpha channels, including RGBA color model, translucent palettes and color keying +*) zlib decompression (inflate) +*) zlib compression (deflate) +*) CRC32 and ADLER32 checksums +*) handling of unknown chunks, allowing making a PNG editor that stores custom and unknown chunks. +*) the following chunks are supported (generated/interpreted) by both encoder and decoder: + IHDR: header information + PLTE: color palette + IDAT: pixel data + IEND: the final chunk + tRNS: transparency for palettized images + tEXt: textual information + zTXt: compressed textual information + iTXt: international textual information + bKGD: suggested background color + pHYs: physical dimensions + tIME: modification time + +1.2. features not supported +--------------------------- + +The following features are _not_ supported: + +*) some features needed to make a conformant PNG-Editor might be still missing. +*) partial loading/stream processing. All data must be available and is processed in one call. +*) The following public chunks are not supported but treated as unknown chunks by LodePNG + cHRM, gAMA, iCCP, sRGB, sBIT, hIST, sPLT + Some of these are not supported on purpose: LodePNG wants to provide the RGB values + stored in the pixels, not values modified by system dependent gamma or color models. + + +2. C and C++ version +-------------------- + +The C version uses buffers allocated with alloc that you need to free() +yourself. You need to use init and cleanup functions for each struct whenever +using a struct from the C version to avoid exploits and memory leaks. + +The C++ version has extra functions with std::vectors in the interface and the +lodepng::State class which is a LodePNGState with constructor and destructor. + +These files work without modification for both C and C++ compilers because all +the additional C++ code is in "#ifdef __cplusplus" blocks that make C-compilers +ignore it, and the C code is made to compile both with strict ISO C90 and C++. + +To use the C++ version, you need to rename the source file to lodepng.cpp +(instead of lodepng.c), and compile it with a C++ compiler. + +To use the C version, you need to rename the source file to lodepng.c (instead +of lodepng.cpp), and compile it with a C compiler. + + +3. Security +----------- + +Even if carefully designed, it's always possible that LodePNG contains possible +exploits. If you discover one, please let me know, and it will be fixed. + +When using LodePNG, care has to be taken with the C version of LodePNG, as well +as the C-style structs when working with C++. The following conventions are used +for all C-style structs: + +-if a struct has a corresponding init function, always call the init function when making a new one +-if a struct has a corresponding cleanup function, call it before the struct disappears to avoid memory leaks +-if a struct has a corresponding copy function, use the copy function instead of "=". + The destination must also be inited already. + + +4. Decoding +----------- + +Decoding converts a PNG compressed image to a raw pixel buffer. + +Most documentation on using the decoder is at its declarations in the header +above. For C, simple decoding can be done with functions such as +lodepng_decode32, and more advanced decoding can be done with the struct +LodePNGState and lodepng_decode. For C++, all decoding can be done with the +various lodepng::decode functions, and lodepng::State can be used for advanced +features. + +When using the LodePNGState, it uses the following fields for decoding: +*) LodePNGInfo info_png: it stores extra information about the PNG (the input) in here +*) LodePNGColorMode info_raw: here you can say what color mode of the raw image (the output) you want to get +*) LodePNGDecoderSettings decoder: you can specify a few extra settings for the decoder to use + +LodePNGInfo info_png +-------------------- + +After decoding, this contains extra information of the PNG image, except the actual +pixels, width and height because these are already gotten directly from the decoder +functions. + +It contains for example the original color type of the PNG image, text comments, +suggested background color, etc... More details about the LodePNGInfo struct are +at its declaration documentation. + +LodePNGColorMode info_raw +------------------------- + +When decoding, here you can specify which color type you want +the resulting raw image to be. If this is different from the colortype of the +PNG, then the decoder will automatically convert the result. This conversion +always works, except if you want it to convert a color PNG to greyscale or to +a palette with missing colors. + +By default, 32-bit color is used for the result. + +LodePNGDecoderSettings decoder +------------------------------ + +The settings can be used to ignore the errors created by invalid CRC and Adler32 +chunks, and to disable the decoding of tEXt chunks. + +There's also a setting color_convert, true by default. If false, no conversion +is done, the resulting data will be as it was in the PNG (after decompression) +and you'll have to puzzle the colors of the pixels together yourself using the +color type information in the LodePNGInfo. + + +5. Encoding +----------- + +Encoding converts a raw pixel buffer to a PNG compressed image. + +Most documentation on using the encoder is at its declarations in the header +above. For C, simple encoding can be done with functions such as +lodepng_encode32, and more advanced decoding can be done with the struct +LodePNGState and lodepng_encode. For C++, all encoding can be done with the +various lodepng::encode functions, and lodepng::State can be used for advanced +features. + +Like the decoder, the encoder can also give errors. However it gives less errors +since the encoder input is trusted, the decoder input (a PNG image that could +be forged by anyone) is not trusted. + +When using the LodePNGState, it uses the following fields for encoding: +*) LodePNGInfo info_png: here you specify how you want the PNG (the output) to be. +*) LodePNGColorMode info_raw: here you say what color type of the raw image (the input) has +*) LodePNGEncoderSettings encoder: you can specify a few settings for the encoder to use + +LodePNGInfo info_png +-------------------- + +When encoding, you use this the opposite way as when decoding: for encoding, +you fill in the values you want the PNG to have before encoding. By default it's +not needed to specify a color type for the PNG since it's automatically chosen, +but it's possible to choose it yourself given the right settings. + +The encoder will not always exactly match the LodePNGInfo struct you give, +it tries as close as possible. Some things are ignored by the encoder. The +encoder uses, for example, the following settings from it when applicable: +colortype and bitdepth, text chunks, time chunk, the color key, the palette, the +background color, the interlace method, unknown chunks, ... + +When encoding to a PNG with colortype 3, the encoder will generate a PLTE chunk. +If the palette contains any colors for which the alpha channel is not 255 (so +there are translucent colors in the palette), it'll add a tRNS chunk. + +LodePNGColorMode info_raw +------------------------- + +You specify the color type of the raw image that you give to the input here, +including a possible transparent color key and palette you happen to be using in +your raw image data. + +By default, 32-bit color is assumed, meaning your input has to be in RGBA +format with 4 bytes (unsigned chars) per pixel. + +LodePNGEncoderSettings encoder +------------------------------ + +The following settings are supported (some are in sub-structs): +*) auto_convert: when this option is enabled, the encoder will +automatically choose the smallest possible color mode (including color key) that +can encode the colors of all pixels without information loss. +*) btype: the block type for LZ77. 0 = uncompressed, 1 = fixed huffman tree, + 2 = dynamic huffman tree (best compression). Should be 2 for proper + compression. +*) use_lz77: whether or not to use LZ77 for compressed block types. Should be + true for proper compression. +*) windowsize: the window size used by the LZ77 encoder (1 - 32768). Has value + 2048 by default, but can be set to 32768 for better, but slow, compression. +*) force_palette: if colortype is 2 or 6, you can make the encoder write a PLTE + chunk if force_palette is true. This can used as suggested palette to convert + to by viewers that don't support more than 256 colors (if those still exist) +*) add_id: add text chunk "Encoder: LodePNG " to the image. +*) text_compression: default 1. If 1, it'll store texts as zTXt instead of tEXt chunks. + zTXt chunks use zlib compression on the text. This gives a smaller result on + large texts but a larger result on small texts (such as a single program name). + It's all tEXt or all zTXt though, there's no separate setting per text yet. + + +6. color conversions +-------------------- + +An important thing to note about LodePNG, is that the color type of the PNG, and +the color type of the raw image, are completely independent. By default, when +you decode a PNG, you get the result as a raw image in the color type you want, +no matter whether the PNG was encoded with a palette, greyscale or RGBA color. +And if you encode an image, by default LodePNG will automatically choose the PNG +color type that gives good compression based on the values of colors and amount +of colors in the image. It can be configured to let you control it instead as +well, though. + +To be able to do this, LodePNG does conversions from one color mode to another. +It can convert from almost any color type to any other color type, except the +following conversions: RGB to greyscale is not supported, and converting to a +palette when the palette doesn't have a required color is not supported. This is +not supported on purpose: this is information loss which requires a color +reduction algorithm that is beyong the scope of a PNG encoder (yes, RGB to grey +is easy, but there are multiple ways if you want to give some channels more +weight). + +By default, when decoding, you get the raw image in 32-bit RGBA or 24-bit RGB +color, no matter what color type the PNG has. And by default when encoding, +LodePNG automatically picks the best color model for the output PNG, and expects +the input image to be 32-bit RGBA or 24-bit RGB. So, unless you want to control +the color format of the images yourself, you can skip this chapter. + +6.1. PNG color types +-------------------- + +A PNG image can have many color types, ranging from 1-bit color to 64-bit color, +as well as palettized color modes. After the zlib decompression and unfiltering +in the PNG image is done, the raw pixel data will have that color type and thus +a certain amount of bits per pixel. If you want the output raw image after +decoding to have another color type, a conversion is done by LodePNG. + +The PNG specification gives the following color types: + +0: greyscale, bit depths 1, 2, 4, 8, 16 +2: RGB, bit depths 8 and 16 +3: palette, bit depths 1, 2, 4 and 8 +4: greyscale with alpha, bit depths 8 and 16 +6: RGBA, bit depths 8 and 16 + +Bit depth is the amount of bits per pixel per color channel. So the total amount +of bits per pixel is: amount of channels * bitdepth. + +6.2. color conversions +---------------------- + +As explained in the sections about the encoder and decoder, you can specify +color types and bit depths in info_png and info_raw to change the default +behaviour. + +If, when decoding, you want the raw image to be something else than the default, +you need to set the color type and bit depth you want in the LodePNGColorMode, +or the parameters colortype and bitdepth of the simple decoding function. + +If, when encoding, you use another color type than the default in the raw input +image, you need to specify its color type and bit depth in the LodePNGColorMode +of the raw image, or use the parameters colortype and bitdepth of the simple +encoding function. + +If, when encoding, you don't want LodePNG to choose the output PNG color type +but control it yourself, you need to set auto_convert in the encoder settings +to false, and specify the color type you want in the LodePNGInfo of the +encoder (including palette: it can generate a palette if auto_convert is true, +otherwise not). + +If the input and output color type differ (whether user chosen or auto chosen), +LodePNG will do a color conversion, which follows the rules below, and may +sometimes result in an error. + +To avoid some confusion: +-the decoder converts from PNG to raw image +-the encoder converts from raw image to PNG +-the colortype and bitdepth in LodePNGColorMode info_raw, are those of the raw image +-the colortype and bitdepth in the color field of LodePNGInfo info_png, are those of the PNG +-when encoding, the color type in LodePNGInfo is ignored if auto_convert + is enabled, it is automatically generated instead +-when decoding, the color type in LodePNGInfo is set by the decoder to that of the original + PNG image, but it can be ignored since the raw image has the color type you requested instead +-if the color type of the LodePNGColorMode and PNG image aren't the same, a conversion + between the color types is done if the color types are supported. If it is not + supported, an error is returned. If the types are the same, no conversion is done. +-even though some conversions aren't supported, LodePNG supports loading PNGs from any + colortype and saving PNGs to any colortype, sometimes it just requires preparing + the raw image correctly before encoding. +-both encoder and decoder use the same color converter. + +Non supported color conversions: +-color to greyscale: no error is thrown, but the result will look ugly because +only the red channel is taken +-anything to palette when that palette does not have that color in it: in this +case an error is thrown + +Supported color conversions: +-anything to 8-bit RGB, 8-bit RGBA, 16-bit RGB, 16-bit RGBA +-any grey or grey+alpha, to grey or grey+alpha +-anything to a palette, as long as the palette has the requested colors in it +-removing alpha channel +-higher to smaller bitdepth, and vice versa + +If you want no color conversion to be done (e.g. for speed or control): +-In the encoder, you can make it save a PNG with any color type by giving the +raw color mode and LodePNGInfo the same color mode, and setting auto_convert to +false. +-In the decoder, you can make it store the pixel data in the same color type +as the PNG has, by setting the color_convert setting to false. Settings in +info_raw are then ignored. + +The function lodepng_convert does the color conversion. It is available in the +interface but normally isn't needed since the encoder and decoder already call +it. + +6.3. padding bits +----------------- + +In the PNG file format, if a less than 8-bit per pixel color type is used and the scanlines +have a bit amount that isn't a multiple of 8, then padding bits are used so that each +scanline starts at a fresh byte. But that is NOT true for the LodePNG raw input and output. +The raw input image you give to the encoder, and the raw output image you get from the decoder +will NOT have these padding bits, e.g. in the case of a 1-bit image with a width +of 7 pixels, the first pixel of the second scanline will the the 8th bit of the first byte, +not the first bit of a new byte. + +6.4. A note about 16-bits per channel and endianness +---------------------------------------------------- + +LodePNG uses unsigned char arrays for 16-bit per channel colors too, just like +for any other color format. The 16-bit values are stored in big endian (most +significant byte first) in these arrays. This is the opposite order of the +little endian used by x86 CPU's. + +LodePNG always uses big endian because the PNG file format does so internally. +Conversions to other formats than PNG uses internally are not supported by +LodePNG on purpose, there are myriads of formats, including endianness of 16-bit +colors, the order in which you store R, G, B and A, and so on. Supporting and +converting to/from all that is outside the scope of LodePNG. + +This may mean that, depending on your use case, you may want to convert the big +endian output of LodePNG to little endian with a for loop. This is certainly not +always needed, many applications and libraries support big endian 16-bit colors +anyway, but it means you cannot simply cast the unsigned char* buffer to an +unsigned short* buffer on x86 CPUs. + + +7. error values +--------------- + +All functions in LodePNG that return an error code, return 0 if everything went +OK, or a non-zero code if there was an error. + +The meaning of the LodePNG error values can be retrieved with the function +lodepng_error_text: given the numerical error code, it returns a description +of the error in English as a string. + +Check the implementation of lodepng_error_text to see the meaning of each code. + + +8. chunks and PNG editing +------------------------- + +If you want to add extra chunks to a PNG you encode, or use LodePNG for a PNG +editor that should follow the rules about handling of unknown chunks, or if your +program is able to read other types of chunks than the ones handled by LodePNG, +then that's possible with the chunk functions of LodePNG. + +A PNG chunk has the following layout: + +4 bytes length +4 bytes type name +length bytes data +4 bytes CRC + +8.1. iterating through chunks +----------------------------- + +If you have a buffer containing the PNG image data, then the first chunk (the +IHDR chunk) starts at byte number 8 of that buffer. The first 8 bytes are the +signature of the PNG and are not part of a chunk. But if you start at byte 8 +then you have a chunk, and can check the following things of it. + +NOTE: none of these functions check for memory buffer boundaries. To avoid +exploits, always make sure the buffer contains all the data of the chunks. +When using lodepng_chunk_next, make sure the returned value is within the +allocated memory. + +unsigned lodepng_chunk_length(const unsigned char* chunk): + +Get the length of the chunk's data. The total chunk length is this length + 12. + +void lodepng_chunk_type(char type[5], const unsigned char* chunk): +unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type): + +Get the type of the chunk or compare if it's a certain type + +unsigned char lodepng_chunk_critical(const unsigned char* chunk): +unsigned char lodepng_chunk_private(const unsigned char* chunk): +unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk): + +Check if the chunk is critical in the PNG standard (only IHDR, PLTE, IDAT and IEND are). +Check if the chunk is private (public chunks are part of the standard, private ones not). +Check if the chunk is safe to copy. If it's not, then, when modifying data in a critical +chunk, unsafe to copy chunks of the old image may NOT be saved in the new one if your +program doesn't handle that type of unknown chunk. + +unsigned char* lodepng_chunk_data(unsigned char* chunk): +const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk): + +Get a pointer to the start of the data of the chunk. + +unsigned lodepng_chunk_check_crc(const unsigned char* chunk): +void lodepng_chunk_generate_crc(unsigned char* chunk): + +Check if the crc is correct or generate a correct one. + +unsigned char* lodepng_chunk_next(unsigned char* chunk): +const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk): + +Iterate to the next chunk. This works if you have a buffer with consecutive chunks. Note that these +functions do no boundary checking of the allocated data whatsoever, so make sure there is enough +data available in the buffer to be able to go to the next chunk. + +unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk): +unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, + const char* type, const unsigned char* data): + +These functions are used to create new chunks that are appended to the data in *out that has +length *outlength. The append function appends an existing chunk to the new data. The create +function creates a new chunk with the given parameters and appends it. Type is the 4-letter +name of the chunk. + +8.2. chunks in info_png +----------------------- + +The LodePNGInfo struct contains fields with the unknown chunk in it. It has 3 +buffers (each with size) to contain 3 types of unknown chunks: +the ones that come before the PLTE chunk, the ones that come between the PLTE +and the IDAT chunks, and the ones that come after the IDAT chunks. +It's necessary to make the distionction between these 3 cases because the PNG +standard forces to keep the ordering of unknown chunks compared to the critical +chunks, but does not force any other ordering rules. + +info_png.unknown_chunks_data[0] is the chunks before PLTE +info_png.unknown_chunks_data[1] is the chunks after PLTE, before IDAT +info_png.unknown_chunks_data[2] is the chunks after IDAT + +The chunks in these 3 buffers can be iterated through and read by using the same +way described in the previous subchapter. + +When using the decoder to decode a PNG, you can make it store all unknown chunks +if you set the option settings.remember_unknown_chunks to 1. By default, this +option is off (0). + +The encoder will always encode unknown chunks that are stored in the info_png. +If you need it to add a particular chunk that isn't known by LodePNG, you can +use lodepng_chunk_append or lodepng_chunk_create to the chunk data in +info_png.unknown_chunks_data[x]. + +Chunks that are known by LodePNG should not be added in that way. E.g. to make +LodePNG add a bKGD chunk, set background_defined to true and add the correct +parameters there instead. + + +9. compiler support +------------------- + +No libraries other than the current standard C library are needed to compile +LodePNG. For the C++ version, only the standard C++ library is needed on top. +Add the files lodepng.c(pp) and lodepng.h to your project, include +lodepng.h where needed, and your program can read/write PNG files. + +It is compatible with C90 and up, and C++03 and up. + +If performance is important, use optimization when compiling! For both the +encoder and decoder, this makes a large difference. + +Make sure that LodePNG is compiled with the same compiler of the same version +and with the same settings as the rest of the program, or the interfaces with +std::vectors and std::strings in C++ can be incompatible. + +CHAR_BITS must be 8 or higher, because LodePNG uses unsigned chars for octets. + +*) gcc and g++ + +LodePNG is developed in gcc so this compiler is natively supported. It gives no +warnings with compiler options "-Wall -Wextra -pedantic -ansi", with gcc and g++ +version 4.7.1 on Linux, 32-bit and 64-bit. + +*) Clang + +Fully supported and warning-free. + +*) Mingw + +The Mingw compiler (a port of gcc for Windows) should be fully supported by +LodePNG. + +*) Visual Studio and Visual C++ Express Edition + +LodePNG should be warning-free with warning level W4. Two warnings were disabled +with pragmas though: warning 4244 about implicit conversions, and warning 4996 +where it wants to use a non-standard function fopen_s instead of the standard C +fopen. + +Visual Studio may want "stdafx.h" files to be included in each source file and +give an error "unexpected end of file while looking for precompiled header". +This is not standard C++ and will not be added to the stock LodePNG. You can +disable it for lodepng.cpp only by right clicking it, Properties, C/C++, +Precompiled Headers, and set it to Not Using Precompiled Headers there. + +NOTE: Modern versions of VS should be fully supported, but old versions, e.g. +VS6, are not guaranteed to work. + +*) Compilers on Macintosh + +LodePNG has been reported to work both with gcc and LLVM for Macintosh, both for +C and C++. + +*) Other Compilers + +If you encounter problems on any compilers, feel free to let me know and I may +try to fix it if the compiler is modern and standards complient. + + +10. examples +------------ + +This decoder example shows the most basic usage of LodePNG. More complex +examples can be found on the LodePNG website. + +10.1. decoder C++ example +------------------------- + +#include "lodepng.h" +#include + +int main(int argc, char *argv[]) +{ + const char* filename = argc > 1 ? argv[1] : "test.png"; + + //load and decode + std::vector image; + unsigned width, height; + unsigned error = lodepng::decode(image, width, height, filename); + + //if there's an error, display it + if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; + + //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... +} + +10.2. decoder C example +----------------------- + +#include "lodepng.h" + +int main(int argc, char *argv[]) +{ + unsigned error; + unsigned char* image; + size_t width, height; + const char* filename = argc > 1 ? argv[1] : "test.png"; + + error = lodepng_decode32_file(&image, &width, &height, filename); + + if(error) printf("decoder error %u: %s\n", error, lodepng_error_text(error)); + + / * use image here * / + + free(image); + return 0; +} + +11. state settings reference +---------------------------- + +A quick reference of some settings to set on the LodePNGState + +For decoding: + +state.decoder.zlibsettings.ignore_adler32: ignore ADLER32 checksums +state.decoder.zlibsettings.custom_...: use custom inflate function +state.decoder.ignore_crc: ignore CRC checksums +state.decoder.color_convert: convert internal PNG color to chosen one +state.decoder.read_text_chunks: whether to read in text metadata chunks +state.decoder.remember_unknown_chunks: whether to read in unknown chunks +state.info_raw.colortype: desired color type for decoded image +state.info_raw.bitdepth: desired bit depth for decoded image +state.info_raw....: more color settings, see struct LodePNGColorMode +state.info_png....: no settings for decoder but ouput, see struct LodePNGInfo + +For encoding: + +state.encoder.zlibsettings.btype: disable compression by setting it to 0 +state.encoder.zlibsettings.use_lz77: use LZ77 in compression +state.encoder.zlibsettings.windowsize: tweak LZ77 windowsize +state.encoder.zlibsettings.minmatch: tweak min LZ77 length to match +state.encoder.zlibsettings.nicematch: tweak LZ77 match where to stop searching +state.encoder.zlibsettings.lazymatching: try one more LZ77 matching +state.encoder.zlibsettings.custom_...: use custom deflate function +state.encoder.auto_convert: choose optimal PNG color type, if 0 uses info_png +state.encoder.filter_palette_zero: PNG filter strategy for palette +state.encoder.filter_strategy: PNG filter strategy to encode with +state.encoder.force_palette: add palette even if not encoding to one +state.encoder.add_id: add LodePNG identifier and version as a text chunk +state.encoder.text_compression: use compressed text chunks for metadata +state.info_raw.colortype: color type of raw input image you provide +state.info_raw.bitdepth: bit depth of raw input image you provide +state.info_raw: more color settings, see struct LodePNGColorMode +state.info_png.color.colortype: desired color type if auto_convert is false +state.info_png.color.bitdepth: desired bit depth if auto_convert is false +state.info_png.color....: more color settings, see struct LodePNGColorMode +state.info_png....: more PNG related settings, see struct LodePNGInfo + + +12. changes +----------- + +The version number of LodePNG is the date of the change given in the format +yyyymmdd. + +Some changes aren't backwards compatible. Those are indicated with a (!) +symbol. + +*) 18 apr 2016: Changed qsort to custom stable sort (for platforms w/o qsort). +*) 09 apr 2016: Fixed colorkey usage detection, and better file loading (within + the limits of pure C90). +*) 08 dec 2015: Made load_file function return error if file can't be opened. +*) 24 okt 2015: Bugfix with decoding to palette output. +*) 18 apr 2015: Boundary PM instead of just package-merge for faster encoding. +*) 23 aug 2014: Reduced needless memory usage of decoder. +*) 28 jun 2014: Removed fix_png setting, always support palette OOB for + simplicity. Made ColorProfile public. +*) 09 jun 2014: Faster encoder by fixing hash bug and more zeros optimization. +*) 22 dec 2013: Power of two windowsize required for optimization. +*) 15 apr 2013: Fixed bug with LAC_ALPHA and color key. +*) 25 mar 2013: Added an optional feature to ignore some PNG errors (fix_png). +*) 11 mar 2013 (!): Bugfix with custom free. Changed from "my" to "lodepng_" + prefix for the custom allocators and made it possible with a new #define to + use custom ones in your project without needing to change lodepng's code. +*) 28 jan 2013: Bugfix with color key. +*) 27 okt 2012: Tweaks in text chunk keyword length error handling. +*) 8 okt 2012 (!): Added new filter strategy (entropy) and new auto color mode. + (no palette). Better deflate tree encoding. New compression tweak settings. + Faster color conversions while decoding. Some internal cleanups. +*) 23 sep 2012: Reduced warnings in Visual Studio a little bit. +*) 1 sep 2012 (!): Removed #define's for giving custom (de)compression functions + and made it work with function pointers instead. +*) 23 jun 2012: Added more filter strategies. Made it easier to use custom alloc + and free functions and toggle #defines from compiler flags. Small fixes. +*) 6 may 2012 (!): Made plugging in custom zlib/deflate functions more flexible. +*) 22 apr 2012 (!): Made interface more consistent, renaming a lot. Removed + redundant C++ codec classes. Reduced amount of structs. Everything changed, + but it is cleaner now imho and functionality remains the same. Also fixed + several bugs and shrunk the implementation code. Made new samples. +*) 6 nov 2011 (!): By default, the encoder now automatically chooses the best + PNG color model and bit depth, based on the amount and type of colors of the + raw image. For this, autoLeaveOutAlphaChannel replaced by auto_choose_color. +*) 9 okt 2011: simpler hash chain implementation for the encoder. +*) 8 sep 2011: lz77 encoder lazy matching instead of greedy matching. +*) 23 aug 2011: tweaked the zlib compression parameters after benchmarking. + A bug with the PNG filtertype heuristic was fixed, so that it chooses much + better ones (it's quite significant). A setting to do an experimental, slow, + brute force search for PNG filter types is added. +*) 17 aug 2011 (!): changed some C zlib related function names. +*) 16 aug 2011: made the code less wide (max 120 characters per line). +*) 17 apr 2011: code cleanup. Bugfixes. Convert low to 16-bit per sample colors. +*) 21 feb 2011: fixed compiling for C90. Fixed compiling with sections disabled. +*) 11 dec 2010: encoding is made faster, based on suggestion by Peter Eastman + to optimize long sequences of zeros. +*) 13 nov 2010: added LodePNG_InfoColor_hasPaletteAlpha and + LodePNG_InfoColor_canHaveAlpha functions for convenience. +*) 7 nov 2010: added LodePNG_error_text function to get error code description. +*) 30 okt 2010: made decoding slightly faster +*) 26 okt 2010: (!) changed some C function and struct names (more consistent). + Reorganized the documentation and the declaration order in the header. +*) 08 aug 2010: only changed some comments and external samples. +*) 05 jul 2010: fixed bug thanks to warnings in the new gcc version. +*) 14 mar 2010: fixed bug where too much memory was allocated for char buffers. +*) 02 sep 2008: fixed bug where it could create empty tree that linux apps could + read by ignoring the problem but windows apps couldn't. +*) 06 jun 2008: added more error checks for out of memory cases. +*) 26 apr 2008: added a few more checks here and there to ensure more safety. +*) 06 mar 2008: crash with encoding of strings fixed +*) 02 feb 2008: support for international text chunks added (iTXt) +*) 23 jan 2008: small cleanups, and #defines to divide code in sections +*) 20 jan 2008: support for unknown chunks allowing using LodePNG for an editor. +*) 18 jan 2008: support for tIME and pHYs chunks added to encoder and decoder. +*) 17 jan 2008: ability to encode and decode compressed zTXt chunks added + Also various fixes, such as in the deflate and the padding bits code. +*) 13 jan 2008: Added ability to encode Adam7-interlaced images. Improved + filtering code of encoder. +*) 07 jan 2008: (!) changed LodePNG to use ISO C90 instead of C++. A + C++ wrapper around this provides an interface almost identical to before. + Having LodePNG be pure ISO C90 makes it more portable. The C and C++ code + are together in these files but it works both for C and C++ compilers. +*) 29 dec 2007: (!) changed most integer types to unsigned int + other tweaks +*) 30 aug 2007: bug fixed which makes this Borland C++ compatible +*) 09 aug 2007: some VS2005 warnings removed again +*) 21 jul 2007: deflate code placed in new namespace separate from zlib code +*) 08 jun 2007: fixed bug with 2- and 4-bit color, and small interlaced images +*) 04 jun 2007: improved support for Visual Studio 2005: crash with accessing + invalid std::vector element [0] fixed, and level 3 and 4 warnings removed +*) 02 jun 2007: made the encoder add a tag with version by default +*) 27 may 2007: zlib and png code separated (but still in the same file), + simple encoder/decoder functions added for more simple usage cases +*) 19 may 2007: minor fixes, some code cleaning, new error added (error 69), + moved some examples from here to lodepng_examples.cpp +*) 12 may 2007: palette decoding bug fixed +*) 24 apr 2007: changed the license from BSD to the zlib license +*) 11 mar 2007: very simple addition: ability to encode bKGD chunks. +*) 04 mar 2007: (!) tEXt chunk related fixes, and support for encoding + palettized PNG images. Plus little interface change with palette and texts. +*) 03 mar 2007: Made it encode dynamic Huffman shorter with repeat codes. + Fixed a bug where the end code of a block had length 0 in the Huffman tree. +*) 26 feb 2007: Huffman compression with dynamic trees (BTYPE 2) now implemented + and supported by the encoder, resulting in smaller PNGs at the output. +*) 27 jan 2007: Made the Adler-32 test faster so that a timewaste is gone. +*) 24 jan 2007: gave encoder an error interface. Added color conversion from any + greyscale type to 8-bit greyscale with or without alpha. +*) 21 jan 2007: (!) Totally changed the interface. It allows more color types + to convert to and is more uniform. See the manual for how it works now. +*) 07 jan 2007: Some cleanup & fixes, and a few changes over the last days: + encode/decode custom tEXt chunks, separate classes for zlib & deflate, and + at last made the decoder give errors for incorrect Adler32 or Crc. +*) 01 jan 2007: Fixed bug with encoding PNGs with less than 8 bits per channel. +*) 29 dec 2006: Added support for encoding images without alpha channel, and + cleaned out code as well as making certain parts faster. +*) 28 dec 2006: Added "Settings" to the encoder. +*) 26 dec 2006: The encoder now does LZ77 encoding and produces much smaller files now. + Removed some code duplication in the decoder. Fixed little bug in an example. +*) 09 dec 2006: (!) Placed output parameters of public functions as first parameter. + Fixed a bug of the decoder with 16-bit per color. +*) 15 okt 2006: Changed documentation structure +*) 09 okt 2006: Encoder class added. It encodes a valid PNG image from the + given image buffer, however for now it's not compressed. +*) 08 sep 2006: (!) Changed to interface with a Decoder class +*) 30 jul 2006: (!) LodePNG_InfoPng , width and height are now retrieved in different + way. Renamed decodePNG to decodePNGGeneric. +*) 29 jul 2006: (!) Changed the interface: image info is now returned as a + struct of type LodePNG::LodePNG_Info, instead of a vector, which was a bit clumsy. +*) 28 jul 2006: Cleaned the code and added new error checks. + Corrected terminology "deflate" into "inflate". +*) 23 jun 2006: Added SDL example in the documentation in the header, this + example allows easy debugging by displaying the PNG and its transparency. +*) 22 jun 2006: (!) Changed way to obtain error value. Added + loadFile function for convenience. Made decodePNG32 faster. +*) 21 jun 2006: (!) Changed type of info vector to unsigned. + Changed position of palette in info vector. Fixed an important bug that + happened on PNGs with an uncompressed block. +*) 16 jun 2006: Internally changed unsigned into unsigned where + needed, and performed some optimizations. +*) 07 jun 2006: (!) Renamed functions to decodePNG and placed them + in LodePNG namespace. Changed the order of the parameters. Rewrote the + documentation in the header. Renamed files to lodepng.cpp and lodepng.h +*) 22 apr 2006: Optimized and improved some code +*) 07 sep 2005: (!) Changed to std::vector interface +*) 12 aug 2005: Initial release (C++, decoder only) + + +13. contact information +----------------------- + +Feel free to contact me with suggestions, problems, comments, ... concerning +LodePNG. If you encounter a PNG image that doesn't work properly with this +decoder, feel free to send it and I'll use it to find and fix the problem. + +My email address is (puzzle the account and domain together with an @ symbol): +Domain: gmail dot com. +Account: lode dot vandevenne. + + +Copyright (c) 2005-2016 Lode Vandevenne +*/ + +#include "lodepng.inl" \ No newline at end of file diff --git a/CameraParameterEstimation/apps/basics/extern/lodepng.inl b/CameraParameterEstimation/apps/basics/extern/lodepng.inl new file mode 100644 index 0000000..6cb0c7d --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/lodepng.inl @@ -0,0 +1,6231 @@ +#ifdef LODEPNG_IMPLEMENTATION +/* +LodePNG version 20160501 + +Copyright (c) 2005-2016 Lode Vandevenne + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +/* +The manual and changelog are in the header file "lodepng.h" +Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for C. +*/ + +// #include "lodepng.h" + +#include +#include +#include + +#if defined(_MSC_VER) && (_MSC_VER >= 1310) /*Visual Studio: A few warning types are not desired here.*/ +#pragma warning( disable : 4244 ) /*implicit conversions: not warned by gcc -Wall -Wextra and requires too much casts*/ +#pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/ +#endif /*_MSC_VER */ + +const char* LODEPNG_VERSION_STRING = "20160501"; + +/* +This source file is built up in the following large parts. The code sections +with the "LODEPNG_COMPILE_" #defines divide this up further in an intermixed way. +-Tools for C and common code for PNG and Zlib +-C Code for Zlib (huffman, deflate, ...) +-C Code for PNG (file format chunks, adam7, PNG filters, color conversions, ...) +-The C++ wrapper around all of the above +*/ + +/*The malloc, realloc and free functions defined here with "lodepng_" in front +of the name, so that you can easily change them to others related to your +platform if needed. Everything else in the code calls these. Pass +-DLODEPNG_NO_COMPILE_ALLOCATORS to the compiler, or comment out +#define LODEPNG_COMPILE_ALLOCATORS in the header, to disable the ones here and +define them in your own project's source files without needing to change +lodepng source code. Don't forget to remove "static" if you copypaste them +from here.*/ + +#ifdef LODEPNG_COMPILE_ALLOCATORS +static void* lodepng_malloc(size_t size) +{ + return malloc(size); +} + +static void* lodepng_realloc(void* ptr, size_t new_size) +{ + return realloc(ptr, new_size); +} + +static void lodepng_free(void* ptr) +{ + free(ptr); +} +#else /*LODEPNG_COMPILE_ALLOCATORS*/ +void* lodepng_malloc(size_t size); +void* lodepng_realloc(void* ptr, size_t new_size); +void lodepng_free(void* ptr); +#endif /*LODEPNG_COMPILE_ALLOCATORS*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // Tools for C, and common code for PNG and Zlib. // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/* +Often in case of an error a value is assigned to a variable and then it breaks +out of a loop (to go to the cleanup phase of a function). This macro does that. +It makes the error handling code shorter and more readable. + +Example: if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83); +*/ +#define CERROR_BREAK(errorvar, code)\ +{\ + errorvar = code;\ + break;\ +} + +/*version of CERROR_BREAK that assumes the common case where the error variable is named "error"*/ +#define ERROR_BREAK(code) CERROR_BREAK(error, code) + +/*Set error var to the error code, and return it.*/ +#define CERROR_RETURN_ERROR(errorvar, code)\ +{\ + errorvar = code;\ + return code;\ +} + +/*Try the code, if it returns error, also return the error.*/ +#define CERROR_TRY_RETURN(call)\ +{\ + unsigned error = call;\ + if(error) return error;\ +} + +/*Set error var to the error code, and return from the void function.*/ +#define CERROR_RETURN(errorvar, code)\ +{\ + errorvar = code;\ + return;\ +} + +/* +About uivector, ucvector and string: +-All of them wrap dynamic arrays or text strings in a similar way. +-LodePNG was originally written in C++. The vectors replace the std::vectors that were used in the C++ version. +-The string tools are made to avoid problems with compilers that declare things like strncat as deprecated. +-They're not used in the interface, only internally in this file as static functions. +-As with many other structs in this file, the init and cleanup functions serve as ctor and dtor. +*/ + +#ifdef LODEPNG_COMPILE_ZLIB +/*dynamic vector of unsigned ints*/ +typedef struct uivector +{ + unsigned* data; + size_t size; /*size in number of unsigned longs*/ + size_t allocsize; /*allocated size in bytes*/ +} uivector; + +static void uivector_cleanup(void* p) +{ + ((uivector*)p)->size = ((uivector*)p)->allocsize = 0; + lodepng_free(((uivector*)p)->data); + ((uivector*)p)->data = NULL; +} + +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned uivector_reserve(uivector* p, size_t allocsize) +{ + if(allocsize > p->allocsize) + { + size_t newsize = (allocsize > p->allocsize * 2) ? allocsize : (allocsize * 3 / 2); + void* data = lodepng_realloc(p->data, newsize); + if(data) + { + p->allocsize = newsize; + p->data = (unsigned*)data; + } + else return 0; /*error: not enough memory*/ + } + return 1; +} + +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned uivector_resize(uivector* p, size_t size) +{ + if(!uivector_reserve(p, size * sizeof(unsigned))) return 0; + p->size = size; + return 1; /*success*/ +} + +/*resize and give all new elements the value*/ +static unsigned uivector_resizev(uivector* p, size_t size, unsigned value) +{ + size_t oldsize = p->size, i; + if(!uivector_resize(p, size)) return 0; + for(i = oldsize; i < size; ++i) p->data[i] = value; + return 1; +} + +static void uivector_init(uivector* p) +{ + p->data = NULL; + p->size = p->allocsize = 0; +} + +#ifdef LODEPNG_COMPILE_ENCODER +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned uivector_push_back(uivector* p, unsigned c) +{ + if(!uivector_resize(p, p->size + 1)) return 0; + p->data[p->size - 1] = c; + return 1; +} +#endif /*LODEPNG_COMPILE_ENCODER*/ +#endif /*LODEPNG_COMPILE_ZLIB*/ + +/* /////////////////////////////////////////////////////////////////////////// */ + +/*dynamic vector of unsigned chars*/ +typedef struct ucvector +{ + unsigned char* data; + size_t size; /*used size*/ + size_t allocsize; /*allocated size*/ +} ucvector; + +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned ucvector_reserve(ucvector* p, size_t allocsize) +{ + if(allocsize > p->allocsize) + { + size_t newsize = (allocsize > p->allocsize * 2) ? allocsize : (allocsize * 3 / 2); + void* data = lodepng_realloc(p->data, newsize); + if(data) + { + p->allocsize = newsize; + p->data = (unsigned char*)data; + } + else return 0; /*error: not enough memory*/ + } + return 1; +} + +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned ucvector_resize(ucvector* p, size_t size) +{ + if(!ucvector_reserve(p, size * sizeof(unsigned char))) return 0; + p->size = size; + return 1; /*success*/ +} + +#ifdef LODEPNG_COMPILE_PNG + +static void ucvector_cleanup(void* p) +{ + ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0; + lodepng_free(((ucvector*)p)->data); + ((ucvector*)p)->data = NULL; +} + +static void ucvector_init(ucvector* p) +{ + p->data = NULL; + p->size = p->allocsize = 0; +} +#endif /*LODEPNG_COMPILE_PNG*/ + +#ifdef LODEPNG_COMPILE_ZLIB +/*you can both convert from vector to buffer&size and vica versa. If you use +init_buffer to take over a buffer and size, it is not needed to use cleanup*/ +static void ucvector_init_buffer(ucvector* p, unsigned char* buffer, size_t size) +{ + p->data = buffer; + p->allocsize = p->size = size; +} +#endif /*LODEPNG_COMPILE_ZLIB*/ + +#if (defined(LODEPNG_COMPILE_PNG) && defined(LODEPNG_COMPILE_ANCILLARY_CHUNKS)) || defined(LODEPNG_COMPILE_ENCODER) +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned ucvector_push_back(ucvector* p, unsigned char c) +{ + if(!ucvector_resize(p, p->size + 1)) return 0; + p->data[p->size - 1] = c; + return 1; +} +#endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/ + + +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_PNG +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned string_resize(char** out, size_t size) +{ + char* data = (char*)lodepng_realloc(*out, size + 1); + if(data) + { + data[size] = 0; /*null termination char*/ + *out = data; + } + return data != 0; +} + +/*init a {char*, size_t} pair for use as string*/ +static void string_init(char** out) +{ + *out = NULL; + string_resize(out, 0); +} + +/*free the above pair again*/ +static void string_cleanup(char** out) +{ + lodepng_free(*out); + *out = NULL; +} + +static void string_set(char** out, const char* in) +{ + size_t insize = strlen(in), i; + if(string_resize(out, insize)) + { + for(i = 0; i != insize; ++i) + { + (*out)[i] = in[i]; + } + } +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +#endif /*LODEPNG_COMPILE_PNG*/ + +/* ////////////////////////////////////////////////////////////////////////// */ + +unsigned lodepng_read32bitInt(const unsigned char* buffer) +{ + return (unsigned)((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]); +} + +#if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER) +/*buffer must have at least 4 allocated bytes available*/ +static void lodepng_set32bitInt(unsigned char* buffer, unsigned value) +{ + buffer[0] = (unsigned char)((value >> 24) & 0xff); + buffer[1] = (unsigned char)((value >> 16) & 0xff); + buffer[2] = (unsigned char)((value >> 8) & 0xff); + buffer[3] = (unsigned char)((value ) & 0xff); +} +#endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/ + +#ifdef LODEPNG_COMPILE_ENCODER +static void lodepng_add32bitInt(ucvector* buffer, unsigned value) +{ + ucvector_resize(buffer, buffer->size + 4); /*todo: give error if resize failed*/ + lodepng_set32bitInt(&buffer->data[buffer->size - 4], value); +} +#endif /*LODEPNG_COMPILE_ENCODER*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / File IO / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_DISK + +/* returns negative value on error. This should be pure C compatible, so no fstat. */ +static long lodepng_filesize(const char* filename) +{ + FILE* file; + long size; + file = fopen(filename, "rb"); + if(!file) return -1; + + if(fseek(file, 0, SEEK_END) != 0) + { + fclose(file); + return -1; + } + + size = ftell(file); + /* It may give LONG_MAX as directory size, this is invalid for us. */ + if(size == LONG_MAX) size = -1; + + fclose(file); + return size; +} + +/* load file into buffer that already has the correct allocated size. Returns error code.*/ +static unsigned lodepng_buffer_file(unsigned char* out, size_t size, const char* filename) +{ + FILE* file; + size_t readsize; + file = fopen(filename, "rb"); + if(!file) return 78; + + readsize = fread(out, 1, size, file); + fclose(file); + + if (readsize != size) return 78; + return 0; +} + +unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename) +{ + long size = lodepng_filesize(filename); + if (size < 0) return 78; + *outsize = (size_t)size; + + *out = (unsigned char*)lodepng_malloc((size_t)size); + if(!(*out) && size > 0) return 83; /*the above malloc failed*/ + + return lodepng_buffer_file(*out, (size_t)size, filename); +} + +/*write given buffer to the file, overwriting the file, it doesn't append to it.*/ +unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename) +{ + FILE* file; + file = fopen(filename, "wb" ); + if(!file) return 79; + fwrite((char*)buffer , 1 , buffersize, file); + fclose(file); + return 0; +} + +#endif /*LODEPNG_COMPILE_DISK*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // End of common code and tools. Begin of Zlib related code. // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_ZLIB +#ifdef LODEPNG_COMPILE_ENCODER +/*TODO: this ignores potential out of memory errors*/ +#define addBitToStream(/*size_t**/ bitpointer, /*ucvector**/ bitstream, /*unsigned char*/ bit)\ +{\ + /*add a new byte at the end*/\ + if(((*bitpointer) & 7) == 0) ucvector_push_back(bitstream, (unsigned char)0);\ + /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/\ + (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7));\ + ++(*bitpointer);\ +} + +static void addBitsToStream(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits) +{ + size_t i; + for(i = 0; i != nbits; ++i) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> i) & 1)); +} + +static void addBitsToStreamReversed(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits) +{ + size_t i; + for(i = 0; i != nbits; ++i) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> (nbits - 1 - i)) & 1)); +} +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_DECODER + +#define READBIT(bitpointer, bitstream) ((bitstream[bitpointer >> 3] >> (bitpointer & 0x7)) & (unsigned char)1) + +static unsigned char readBitFromStream(size_t* bitpointer, const unsigned char* bitstream) +{ + unsigned char result = (unsigned char)(READBIT(*bitpointer, bitstream)); + ++(*bitpointer); + return result; +} + +static unsigned readBitsFromStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) +{ + unsigned result = 0, i; + for(i = 0; i != nbits; ++i) + { + result += ((unsigned)READBIT(*bitpointer, bitstream)) << i; + ++(*bitpointer); + } + return result; +} +#endif /*LODEPNG_COMPILE_DECODER*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Deflate - Huffman / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#define FIRST_LENGTH_CODE_INDEX 257 +#define LAST_LENGTH_CODE_INDEX 285 +/*256 literals, the end code, some length codes, and 2 unused codes*/ +#define NUM_DEFLATE_CODE_SYMBOLS 288 +/*the distance codes have their own symbols, 30 used, 2 unused*/ +#define NUM_DISTANCE_SYMBOLS 32 +/*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/ +#define NUM_CODE_LENGTH_CODES 19 + +/*the base lengths represented by codes 257-285*/ +static const unsigned LENGTHBASE[29] + = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, + 67, 83, 99, 115, 131, 163, 195, 227, 258}; + +/*the extra bits used by codes 257-285 (added to base length)*/ +static const unsigned LENGTHEXTRA[29] + = {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}; + +/*the base backwards distances (the bits of distance codes appear after length codes and use their own huffman tree)*/ +static const unsigned DISTANCEBASE[30] + = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, + 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; + +/*the extra bits of backwards distances (added to base)*/ +static const unsigned DISTANCEEXTRA[30] + = {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}; + +/*the order in which "code length alphabet code lengths" are stored, out of this +the huffman tree of the dynamic huffman tree lengths is generated*/ +static const unsigned CLCL_ORDER[NUM_CODE_LENGTH_CODES] + = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* ////////////////////////////////////////////////////////////////////////// */ + +/* +Huffman tree struct, containing multiple representations of the tree +*/ +typedef struct HuffmanTree +{ + unsigned* tree2d; + unsigned* tree1d; + unsigned* lengths; /*the lengths of the codes of the 1d-tree*/ + unsigned maxbitlen; /*maximum number of bits a single code can get*/ + unsigned numcodes; /*number of symbols in the alphabet = number of codes*/ +} HuffmanTree; + +/*function used for debug purposes to draw the tree in ascii art with C++*/ +/* +static void HuffmanTree_draw(HuffmanTree* tree) +{ + std::cout << "tree. length: " << tree->numcodes << " maxbitlen: " << tree->maxbitlen << std::endl; + for(size_t i = 0; i != tree->tree1d.size; ++i) + { + if(tree->lengths.data[i]) + std::cout << i << " " << tree->tree1d.data[i] << " " << tree->lengths.data[i] << std::endl; + } + std::cout << std::endl; +}*/ + +static void HuffmanTree_init(HuffmanTree* tree) +{ + tree->tree2d = 0; + tree->tree1d = 0; + tree->lengths = 0; +} + +static void HuffmanTree_cleanup(HuffmanTree* tree) +{ + lodepng_free(tree->tree2d); + lodepng_free(tree->tree1d); + lodepng_free(tree->lengths); +} + +/*the tree representation used by the decoder. return value is error*/ +static unsigned HuffmanTree_make2DTree(HuffmanTree* tree) +{ + unsigned nodefilled = 0; /*up to which node it is filled*/ + unsigned treepos = 0; /*position in the tree (1 of the numcodes columns)*/ + unsigned n, i; + + tree->tree2d = (unsigned*)lodepng_malloc(tree->numcodes * 2 * sizeof(unsigned)); + if(!tree->tree2d) return 83; /*alloc fail*/ + + /* + convert tree1d[] to tree2d[][]. In the 2D array, a value of 32767 means + uninited, a value >= numcodes is an address to another bit, a value < numcodes + is a code. The 2 rows are the 2 possible bit values (0 or 1), there are as + many columns as codes - 1. + A good huffman tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. + Here, the internal nodes are stored (what their 0 and 1 option point to). + There is only memory for such good tree currently, if there are more nodes + (due to too long length codes), error 55 will happen + */ + for(n = 0; n < tree->numcodes * 2; ++n) + { + tree->tree2d[n] = 32767; /*32767 here means the tree2d isn't filled there yet*/ + } + + for(n = 0; n < tree->numcodes; ++n) /*the codes*/ + { + for(i = 0; i != tree->lengths[n]; ++i) /*the bits for this code*/ + { + unsigned char bit = (unsigned char)((tree->tree1d[n] >> (tree->lengths[n] - i - 1)) & 1); + /*oversubscribed, see comment in lodepng_error_text*/ + if(treepos > 2147483647 || treepos + 2 > tree->numcodes) return 55; + if(tree->tree2d[2 * treepos + bit] == 32767) /*not yet filled in*/ + { + if(i + 1 == tree->lengths[n]) /*last bit*/ + { + tree->tree2d[2 * treepos + bit] = n; /*put the current code in it*/ + treepos = 0; + } + else + { + /*put address of the next step in here, first that address has to be found of course + (it's just nodefilled + 1)...*/ + ++nodefilled; + /*addresses encoded with numcodes added to it*/ + tree->tree2d[2 * treepos + bit] = nodefilled + tree->numcodes; + treepos = nodefilled; + } + } + else treepos = tree->tree2d[2 * treepos + bit] - tree->numcodes; + } + } + + for(n = 0; n < tree->numcodes * 2; ++n) + { + if(tree->tree2d[n] == 32767) tree->tree2d[n] = 0; /*remove possible remaining 32767's*/ + } + + return 0; +} + +/* +Second step for the ...makeFromLengths and ...makeFromFrequencies functions. +numcodes, lengths and maxbitlen must already be filled in correctly. return +value is error. +*/ +static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) +{ + uivector blcount; + uivector nextcode; + unsigned error = 0; + unsigned bits, n; + + uivector_init(&blcount); + uivector_init(&nextcode); + + tree->tree1d = (unsigned*)lodepng_malloc(tree->numcodes * sizeof(unsigned)); + if(!tree->tree1d) error = 83; /*alloc fail*/ + + if(!uivector_resizev(&blcount, tree->maxbitlen + 1, 0) + || !uivector_resizev(&nextcode, tree->maxbitlen + 1, 0)) + error = 83; /*alloc fail*/ + + if(!error) + { + /*step 1: count number of instances of each code length*/ + for(bits = 0; bits != tree->numcodes; ++bits) ++blcount.data[tree->lengths[bits]]; + /*step 2: generate the nextcode values*/ + for(bits = 1; bits <= tree->maxbitlen; ++bits) + { + nextcode.data[bits] = (nextcode.data[bits - 1] + blcount.data[bits - 1]) << 1; + } + /*step 3: generate all the codes*/ + for(n = 0; n != tree->numcodes; ++n) + { + if(tree->lengths[n] != 0) tree->tree1d[n] = nextcode.data[tree->lengths[n]]++; + } + } + + uivector_cleanup(&blcount); + uivector_cleanup(&nextcode); + + if(!error) return HuffmanTree_make2DTree(tree); + else return error; +} + +/* +given the code lengths (as stored in the PNG file), generate the tree as defined +by Deflate. maxbitlen is the maximum bits that a code in the tree can have. +return value is error. +*/ +static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* bitlen, + size_t numcodes, unsigned maxbitlen) +{ + unsigned i; + tree->lengths = (unsigned*)lodepng_malloc(numcodes * sizeof(unsigned)); + if(!tree->lengths) return 83; /*alloc fail*/ + for(i = 0; i != numcodes; ++i) tree->lengths[i] = bitlen[i]; + tree->numcodes = (unsigned)numcodes; /*number of symbols*/ + tree->maxbitlen = maxbitlen; + return HuffmanTree_makeFromLengths2(tree); +} + +#ifdef LODEPNG_COMPILE_ENCODER + +/*BPM: Boundary Package Merge, see "A Fast and Space-Economical Algorithm for Length-Limited Coding", +Jyrki Katajainen, Alistair Moffat, Andrew Turpin, 1995.*/ + +/*chain node for boundary package merge*/ +typedef struct BPMNode +{ + int weight; /*the sum of all weights in this chain*/ + unsigned index; /*index of this leaf node (called "count" in the paper)*/ + struct BPMNode* tail; /*the next nodes in this chain (null if last)*/ + int in_use; +} BPMNode; + +/*lists of chains*/ +typedef struct BPMLists +{ + /*memory pool*/ + unsigned memsize; + BPMNode* memory; + unsigned numfree; + unsigned nextfree; + BPMNode** freelist; + /*two heads of lookahead chains per list*/ + unsigned listsize; + BPMNode** chains0; + BPMNode** chains1; +} BPMLists; + +/*creates a new chain node with the given parameters, from the memory in the lists */ +static BPMNode* bpmnode_create(BPMLists* lists, int weight, unsigned index, BPMNode* tail) +{ + unsigned i; + BPMNode* result; + + /*memory full, so garbage collect*/ + if(lists->nextfree >= lists->numfree) + { + /*mark only those that are in use*/ + for(i = 0; i != lists->memsize; ++i) lists->memory[i].in_use = 0; + for(i = 0; i != lists->listsize; ++i) + { + BPMNode* node; + for(node = lists->chains0[i]; node != 0; node = node->tail) node->in_use = 1; + for(node = lists->chains1[i]; node != 0; node = node->tail) node->in_use = 1; + } + /*collect those that are free*/ + lists->numfree = 0; + for(i = 0; i != lists->memsize; ++i) + { + if(!lists->memory[i].in_use) lists->freelist[lists->numfree++] = &lists->memory[i]; + } + lists->nextfree = 0; + } + + result = lists->freelist[lists->nextfree++]; + result->weight = weight; + result->index = index; + result->tail = tail; + return result; +} + +/*sort the leaves with stable mergesort*/ +static void bpmnode_sort(BPMNode* leaves, size_t num) +{ + BPMNode* mem = (BPMNode*)lodepng_malloc(sizeof(*leaves) * num); + size_t width, counter = 0; + for(width = 1; width < num; width *= 2) + { + BPMNode* a = (counter & 1) ? mem : leaves; + BPMNode* b = (counter & 1) ? leaves : mem; + size_t p; + for(p = 0; p < num; p += 2 * width) + { + size_t q = (p + width > num) ? num : (p + width); + size_t r = (p + 2 * width > num) ? num : (p + 2 * width); + size_t i = p, j = q, k; + for(k = p; k < r; k++) + { + if(i < q && (j >= r || a[i].weight <= a[j].weight)) b[k] = a[i++]; + else b[k] = a[j++]; + } + } + counter++; + } + if(counter & 1) memcpy(leaves, mem, sizeof(*leaves) * num); + lodepng_free(mem); +} + +/*Boundary Package Merge step, numpresent is the amount of leaves, and c is the current chain.*/ +static void boundaryPM(BPMLists* lists, BPMNode* leaves, size_t numpresent, int c, int num) +{ + unsigned lastindex = lists->chains1[c]->index; + + if(c == 0) + { + if(lastindex >= numpresent) return; + lists->chains0[c] = lists->chains1[c]; + lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, 0); + } + else + { + /*sum of the weights of the head nodes of the previous lookahead chains.*/ + int sum = lists->chains0[c - 1]->weight + lists->chains1[c - 1]->weight; + lists->chains0[c] = lists->chains1[c]; + if(lastindex < numpresent && sum > leaves[lastindex].weight) + { + lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, lists->chains1[c]->tail); + return; + } + lists->chains1[c] = bpmnode_create(lists, sum, lastindex, lists->chains1[c - 1]); + /*in the end we are only interested in the chain of the last list, so no + need to recurse if we're at the last one (this gives measurable speedup)*/ + if(num + 1 < (int)(2 * numpresent - 2)) + { + boundaryPM(lists, leaves, numpresent, c - 1, num); + boundaryPM(lists, leaves, numpresent, c - 1, num); + } + } +} + +unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, + size_t numcodes, unsigned maxbitlen) +{ + unsigned error = 0; + unsigned i; + size_t numpresent = 0; /*number of symbols with non-zero frequency*/ + BPMNode* leaves; /*the symbols, only those with > 0 frequency*/ + + if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/ + if((1u << maxbitlen) < numcodes) return 80; /*error: represent all symbols*/ + + leaves = (BPMNode*)lodepng_malloc(numcodes * sizeof(*leaves)); + if(!leaves) return 83; /*alloc fail*/ + + for(i = 0; i != numcodes; ++i) + { + if(frequencies[i] > 0) + { + leaves[numpresent].weight = (int)frequencies[i]; + leaves[numpresent].index = i; + ++numpresent; + } + } + + for(i = 0; i != numcodes; ++i) lengths[i] = 0; + + /*ensure at least two present symbols. There should be at least one symbol + according to RFC 1951 section 3.2.7. Some decoders incorrectly require two. To + make these work as well ensure there are at least two symbols. The + Package-Merge code below also doesn't work correctly if there's only one + symbol, it'd give it the theoritical 0 bits but in practice zlib wants 1 bit*/ + if(numpresent == 0) + { + lengths[0] = lengths[1] = 1; /*note that for RFC 1951 section 3.2.7, only lengths[0] = 1 is needed*/ + } + else if(numpresent == 1) + { + lengths[leaves[0].index] = 1; + lengths[leaves[0].index == 0 ? 1 : 0] = 1; + } + else + { + BPMLists lists; + BPMNode* node; + + bpmnode_sort(leaves, numpresent); + + lists.listsize = maxbitlen; + lists.memsize = 2 * maxbitlen * (maxbitlen + 1); + lists.nextfree = 0; + lists.numfree = lists.memsize; + lists.memory = (BPMNode*)lodepng_malloc(lists.memsize * sizeof(*lists.memory)); + lists.freelist = (BPMNode**)lodepng_malloc(lists.memsize * sizeof(BPMNode*)); + lists.chains0 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); + lists.chains1 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); + if(!lists.memory || !lists.freelist || !lists.chains0 || !lists.chains1) error = 83; /*alloc fail*/ + + if(!error) + { + for(i = 0; i != lists.memsize; ++i) lists.freelist[i] = &lists.memory[i]; + + bpmnode_create(&lists, leaves[0].weight, 1, 0); + bpmnode_create(&lists, leaves[1].weight, 2, 0); + + for(i = 0; i != lists.listsize; ++i) + { + lists.chains0[i] = &lists.memory[0]; + lists.chains1[i] = &lists.memory[1]; + } + + /*each boundaryPM call adds one chain to the last list, and we need 2 * numpresent - 2 chains.*/ + for(i = 2; i != 2 * numpresent - 2; ++i) boundaryPM(&lists, leaves, numpresent, (int)maxbitlen - 1, (int)i); + + for(node = lists.chains1[maxbitlen - 1]; node; node = node->tail) + { + for(i = 0; i != node->index; ++i) ++lengths[leaves[i].index]; + } + } + + lodepng_free(lists.memory); + lodepng_free(lists.freelist); + lodepng_free(lists.chains0); + lodepng_free(lists.chains1); + } + + lodepng_free(leaves); + return error; +} + +/*Create the Huffman tree given the symbol frequencies*/ +static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigned* frequencies, + size_t mincodes, size_t numcodes, unsigned maxbitlen) +{ + unsigned error = 0; + while(!frequencies[numcodes - 1] && numcodes > mincodes) --numcodes; /*trim zeroes*/ + tree->maxbitlen = maxbitlen; + tree->numcodes = (unsigned)numcodes; /*number of symbols*/ + tree->lengths = (unsigned*)lodepng_realloc(tree->lengths, numcodes * sizeof(unsigned)); + if(!tree->lengths) return 83; /*alloc fail*/ + /*initialize all lengths to 0*/ + memset(tree->lengths, 0, numcodes * sizeof(unsigned)); + + error = lodepng_huffman_code_lengths(tree->lengths, frequencies, numcodes, maxbitlen); + if(!error) error = HuffmanTree_makeFromLengths2(tree); + return error; +} + +static unsigned HuffmanTree_getCode(const HuffmanTree* tree, unsigned index) +{ + return tree->tree1d[index]; +} + +static unsigned HuffmanTree_getLength(const HuffmanTree* tree, unsigned index) +{ + return tree->lengths[index]; +} +#endif /*LODEPNG_COMPILE_ENCODER*/ + +/*get the literal and length code tree of a deflated block with fixed tree, as per the deflate specification*/ +static unsigned generateFixedLitLenTree(HuffmanTree* tree) +{ + unsigned i, error = 0; + unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); + if(!bitlen) return 83; /*alloc fail*/ + + /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/ + for(i = 0; i <= 143; ++i) bitlen[i] = 8; + for(i = 144; i <= 255; ++i) bitlen[i] = 9; + for(i = 256; i <= 279; ++i) bitlen[i] = 7; + for(i = 280; i <= 287; ++i) bitlen[i] = 8; + + error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15); + + lodepng_free(bitlen); + return error; +} + +/*get the distance code tree of a deflated block with fixed tree, as specified in the deflate specification*/ +static unsigned generateFixedDistanceTree(HuffmanTree* tree) +{ + unsigned i, error = 0; + unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); + if(!bitlen) return 83; /*alloc fail*/ + + /*there are 32 distance codes, but 30-31 are unused*/ + for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen[i] = 5; + error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15); + + lodepng_free(bitlen); + return error; +} + +#ifdef LODEPNG_COMPILE_DECODER + +/* +returns the code, or (unsigned)(-1) if error happened +inbitlength is the length of the complete buffer, in bits (so its byte length times 8) +*/ +static unsigned huffmanDecodeSymbol(const unsigned char* in, size_t* bp, + const HuffmanTree* codetree, size_t inbitlength) +{ + unsigned treepos = 0, ct; + for(;;) + { + if(*bp >= inbitlength) return (unsigned)(-1); /*error: end of input memory reached without endcode*/ + /* + decode the symbol from the tree. The "readBitFromStream" code is inlined in + the expression below because this is the biggest bottleneck while decoding + */ + ct = codetree->tree2d[(treepos << 1) + READBIT(*bp, in)]; + ++(*bp); + if(ct < codetree->numcodes) return ct; /*the symbol is decoded, return it*/ + else treepos = ct - codetree->numcodes; /*symbol not yet decoded, instead move tree position*/ + + if(treepos >= codetree->numcodes) return (unsigned)(-1); /*error: it appeared outside the codetree*/ + } +} +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_DECODER + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Inflator (Decompressor) / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*get the tree of a deflated block with fixed tree, as specified in the deflate specification*/ +static void getTreeInflateFixed(HuffmanTree* tree_ll, HuffmanTree* tree_d) +{ + /*TODO: check for out of memory errors*/ + generateFixedLitLenTree(tree_ll); + generateFixedDistanceTree(tree_d); +} + +/*get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree*/ +static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, + const unsigned char* in, size_t* bp, size_t inlength) +{ + /*make sure that length values that aren't filled in will be 0, or a wrong tree will be generated*/ + unsigned error = 0; + unsigned n, HLIT, HDIST, HCLEN, i; + size_t inbitlength = inlength * 8; + + /*see comments in deflateDynamic for explanation of the context and these variables, it is analogous*/ + unsigned* bitlen_ll = 0; /*lit,len code lengths*/ + unsigned* bitlen_d = 0; /*dist code lengths*/ + /*code length code lengths ("clcl"), the bit lengths of the huffman tree used to compress bitlen_ll and bitlen_d*/ + unsigned* bitlen_cl = 0; + HuffmanTree tree_cl; /*the code tree for code length codes (the huffman tree for compressed huffman trees)*/ + + if((*bp) + 14 > (inlength << 3)) return 49; /*error: the bit pointer is or will go past the memory*/ + + /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/ + HLIT = readBitsFromStream(bp, in, 5) + 257; + /*number of distance codes. Unlike the spec, the value 1 is added to it here already*/ + HDIST = readBitsFromStream(bp, in, 5) + 1; + /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/ + HCLEN = readBitsFromStream(bp, in, 4) + 4; + + if((*bp) + HCLEN * 3 > (inlength << 3)) return 50; /*error: the bit pointer is or will go past the memory*/ + + HuffmanTree_init(&tree_cl); + + while(!error) + { + /*read the code length codes out of 3 * (amount of code length codes) bits*/ + + bitlen_cl = (unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(unsigned)); + if(!bitlen_cl) ERROR_BREAK(83 /*alloc fail*/); + + for(i = 0; i != NUM_CODE_LENGTH_CODES; ++i) + { + if(i < HCLEN) bitlen_cl[CLCL_ORDER[i]] = readBitsFromStream(bp, in, 3); + else bitlen_cl[CLCL_ORDER[i]] = 0; /*if not, it must stay 0*/ + } + + error = HuffmanTree_makeFromLengths(&tree_cl, bitlen_cl, NUM_CODE_LENGTH_CODES, 7); + if(error) break; + + /*now we can use this tree to read the lengths for the tree that this function will return*/ + bitlen_ll = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); + bitlen_d = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); + if(!bitlen_ll || !bitlen_d) ERROR_BREAK(83 /*alloc fail*/); + for(i = 0; i != NUM_DEFLATE_CODE_SYMBOLS; ++i) bitlen_ll[i] = 0; + for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen_d[i] = 0; + + /*i is the current symbol we're reading in the part that contains the code lengths of lit/len and dist codes*/ + i = 0; + while(i < HLIT + HDIST) + { + unsigned code = huffmanDecodeSymbol(in, bp, &tree_cl, inbitlength); + if(code <= 15) /*a length code*/ + { + if(i < HLIT) bitlen_ll[i] = code; + else bitlen_d[i - HLIT] = code; + ++i; + } + else if(code == 16) /*repeat previous*/ + { + unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/ + unsigned value; /*set value to the previous code*/ + + if(i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/ + + if((*bp + 2) > inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ + replength += readBitsFromStream(bp, in, 2); + + if(i < HLIT + 1) value = bitlen_ll[i - 1]; + else value = bitlen_d[i - HLIT - 1]; + /*repeat this value in the next lengths*/ + for(n = 0; n < replength; ++n) + { + if(i >= HLIT + HDIST) ERROR_BREAK(13); /*error: i is larger than the amount of codes*/ + if(i < HLIT) bitlen_ll[i] = value; + else bitlen_d[i - HLIT] = value; + ++i; + } + } + else if(code == 17) /*repeat "0" 3-10 times*/ + { + unsigned replength = 3; /*read in the bits that indicate repeat length*/ + if((*bp + 3) > inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ + replength += readBitsFromStream(bp, in, 3); + + /*repeat this value in the next lengths*/ + for(n = 0; n < replength; ++n) + { + if(i >= HLIT + HDIST) ERROR_BREAK(14); /*error: i is larger than the amount of codes*/ + + if(i < HLIT) bitlen_ll[i] = 0; + else bitlen_d[i - HLIT] = 0; + ++i; + } + } + else if(code == 18) /*repeat "0" 11-138 times*/ + { + unsigned replength = 11; /*read in the bits that indicate repeat length*/ + if((*bp + 7) > inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ + replength += readBitsFromStream(bp, in, 7); + + /*repeat this value in the next lengths*/ + for(n = 0; n < replength; ++n) + { + if(i >= HLIT + HDIST) ERROR_BREAK(15); /*error: i is larger than the amount of codes*/ + + if(i < HLIT) bitlen_ll[i] = 0; + else bitlen_d[i - HLIT] = 0; + ++i; + } + } + else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ + { + if(code == (unsigned)(-1)) + { + /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol + (10=no endcode, 11=wrong jump outside of tree)*/ + error = (*bp) > inbitlength ? 10 : 11; + } + else error = 16; /*unexisting code, this can never happen*/ + break; + } + } + if(error) break; + + if(bitlen_ll[256] == 0) ERROR_BREAK(64); /*the length of the end code 256 must be larger than 0*/ + + /*now we've finally got HLIT and HDIST, so generate the code trees, and the function is done*/ + error = HuffmanTree_makeFromLengths(tree_ll, bitlen_ll, NUM_DEFLATE_CODE_SYMBOLS, 15); + if(error) break; + error = HuffmanTree_makeFromLengths(tree_d, bitlen_d, NUM_DISTANCE_SYMBOLS, 15); + + break; /*end of error-while*/ + } + + lodepng_free(bitlen_cl); + lodepng_free(bitlen_ll); + lodepng_free(bitlen_d); + HuffmanTree_cleanup(&tree_cl); + + return error; +} + +/*inflate a block with dynamic of fixed Huffman tree*/ +static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size_t* bp, + size_t* pos, size_t inlength, unsigned btype) +{ + unsigned error = 0; + HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/ + HuffmanTree tree_d; /*the huffman tree for distance codes*/ + size_t inbitlength = inlength * 8; + + HuffmanTree_init(&tree_ll); + HuffmanTree_init(&tree_d); + + if(btype == 1) getTreeInflateFixed(&tree_ll, &tree_d); + else if(btype == 2) error = getTreeInflateDynamic(&tree_ll, &tree_d, in, bp, inlength); + + while(!error) /*decode all symbols until end reached, breaks at end code*/ + { + /*code_ll is literal, length or end code*/ + unsigned code_ll = huffmanDecodeSymbol(in, bp, &tree_ll, inbitlength); + if(code_ll <= 255) /*literal symbol*/ + { + /*ucvector_push_back would do the same, but for some reason the two lines below run 10% faster*/ + if(!ucvector_resize(out, (*pos) + 1)) ERROR_BREAK(83 /*alloc fail*/); + out->data[*pos] = (unsigned char)code_ll; + ++(*pos); + } + else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/ + { + unsigned code_d, distance; + unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/ + size_t start, forward, backward, length; + + /*part 1: get length base*/ + length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX]; + + /*part 2: get extra bits and add the value of that to length*/ + numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX]; + if((*bp + numextrabits_l) > inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ + length += readBitsFromStream(bp, in, numextrabits_l); + + /*part 3: get distance code*/ + code_d = huffmanDecodeSymbol(in, bp, &tree_d, inbitlength); + if(code_d > 29) + { + if(code_ll == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ + { + /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol + (10=no endcode, 11=wrong jump outside of tree)*/ + error = (*bp) > inlength * 8 ? 10 : 11; + } + else error = 18; /*error: invalid distance code (30-31 are never used)*/ + break; + } + distance = DISTANCEBASE[code_d]; + + /*part 4: get extra bits from distance*/ + numextrabits_d = DISTANCEEXTRA[code_d]; + if((*bp + numextrabits_d) > inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ + distance += readBitsFromStream(bp, in, numextrabits_d); + + /*part 5: fill in all the out[n] values based on the length and dist*/ + start = (*pos); + if(distance > start) ERROR_BREAK(52); /*too long backward distance*/ + backward = start - distance; + + if(!ucvector_resize(out, (*pos) + length)) ERROR_BREAK(83 /*alloc fail*/); + if (distance < length) { + for(forward = 0; forward < length; ++forward) + { + out->data[(*pos)++] = out->data[backward++]; + } + } else { + memcpy(out->data + *pos, out->data + backward, length); + *pos += length; + } + } + else if(code_ll == 256) + { + break; /*end code, break the loop*/ + } + else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ + { + /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol + (10=no endcode, 11=wrong jump outside of tree)*/ + error = ((*bp) > inlength * 8) ? 10 : 11; + break; + } + } + + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); + + return error; +} + +static unsigned inflateNoCompression(ucvector* out, const unsigned char* in, size_t* bp, size_t* pos, size_t inlength) +{ + size_t p; + unsigned LEN, NLEN, n, error = 0; + + /*go to first boundary of byte*/ + while(((*bp) & 0x7) != 0) ++(*bp); + p = (*bp) / 8; /*byte position*/ + + /*read LEN (2 bytes) and NLEN (2 bytes)*/ + if(p + 4 >= inlength) return 52; /*error, bit pointer will jump past memory*/ + LEN = in[p] + 256u * in[p + 1]; p += 2; + NLEN = in[p] + 256u * in[p + 1]; p += 2; + + /*check if 16-bit NLEN is really the one's complement of LEN*/ + if(LEN + NLEN != 65535) return 21; /*error: NLEN is not one's complement of LEN*/ + + if(!ucvector_resize(out, (*pos) + LEN)) return 83; /*alloc fail*/ + + /*read the literal data: LEN bytes are now stored in the out buffer*/ + if(p + LEN > inlength) return 23; /*error: reading outside of in buffer*/ + for(n = 0; n < LEN; ++n) out->data[(*pos)++] = in[p++]; + + (*bp) = p * 8; + + return error; +} + +static unsigned lodepng_inflatev(ucvector* out, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings) +{ + /*bit pointer in the "in" data, current byte is bp >> 3, current bit is bp & 0x7 (from lsb to msb of the byte)*/ + size_t bp = 0; + unsigned BFINAL = 0; + size_t pos = 0; /*byte position in the out buffer*/ + unsigned error = 0; + + (void)settings; + + while(!BFINAL) + { + unsigned BTYPE; + if(bp + 2 >= insize * 8) return 52; /*error, bit pointer will jump past memory*/ + BFINAL = readBitFromStream(&bp, in); + BTYPE = 1u * readBitFromStream(&bp, in); + BTYPE += 2u * readBitFromStream(&bp, in); + + if(BTYPE == 3) return 20; /*error: invalid BTYPE*/ + else if(BTYPE == 0) error = inflateNoCompression(out, in, &bp, &pos, insize); /*no compression*/ + else error = inflateHuffmanBlock(out, in, &bp, &pos, insize, BTYPE); /*compression, BTYPE 01 or 10*/ + + if(error) return error; + } + + return error; +} + +unsigned lodepng_inflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings) +{ + unsigned error; + ucvector v; + ucvector_init_buffer(&v, *out, *outsize); + error = lodepng_inflatev(&v, in, insize, settings); + *out = v.data; + *outsize = v.size; + return error; +} + +static unsigned inflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings) +{ + if(settings->custom_inflate) + { + return settings->custom_inflate(out, outsize, in, insize, settings); + } + else + { + return lodepng_inflate(out, outsize, in, insize, settings); + } +} + +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Deflator (Compressor) / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258; + +/*bitlen is the size in bits of the code*/ +static void addHuffmanSymbol(size_t* bp, ucvector* compressed, unsigned code, unsigned bitlen) +{ + addBitsToStreamReversed(bp, compressed, code, bitlen); +} + +/*search the index in the array, that has the largest value smaller than or equal to the given value, +given array must be sorted (if no value is smaller, it returns the size of the given array)*/ +static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value) +{ + /*binary search (only small gain over linear). TODO: use CPU log2 instruction for getting symbols instead*/ + size_t left = 1; + size_t right = array_size - 1; + + while(left <= right) { + size_t mid = (left + right) >> 1; + if (array[mid] >= value) right = mid - 1; + else left = mid + 1; + } + if(left >= array_size || array[left] > value) left--; + return left; +} + +static void addLengthDistance(uivector* values, size_t length, size_t distance) +{ + /*values in encoded vector are those used by deflate: + 0-255: literal bytes + 256: end + 257-285: length/distance pair (length code, followed by extra length bits, distance code, extra distance bits) + 286-287: invalid*/ + + unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length); + unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]); + unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance); + unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]); + + uivector_push_back(values, length_code + FIRST_LENGTH_CODE_INDEX); + uivector_push_back(values, extra_length); + uivector_push_back(values, dist_code); + uivector_push_back(values, extra_distance); +} + +/*3 bytes of data get encoded into two bytes. The hash cannot use more than 3 +bytes as input because 3 is the minimum match length for deflate*/ +static const unsigned HASH_NUM_VALUES = 65536; +static const unsigned HASH_BIT_MASK = 65535; /*HASH_NUM_VALUES - 1, but C90 does not like that as initializer*/ + +typedef struct Hash +{ + int* head; /*hash value to head circular pos - can be outdated if went around window*/ + /*circular pos to prev circular pos*/ + unsigned short* chain; + int* val; /*circular pos to hash value*/ + + /*TODO: do this not only for zeros but for any repeated byte. However for PNG + it's always going to be the zeros that dominate, so not important for PNG*/ + int* headz; /*similar to head, but for chainz*/ + unsigned short* chainz; /*those with same amount of zeros*/ + unsigned short* zeros; /*length of zeros streak, used as a second hash chain*/ +} Hash; + +static unsigned hash_init(Hash* hash, unsigned windowsize) +{ + unsigned i; + hash->head = (int*)lodepng_malloc(sizeof(int) * HASH_NUM_VALUES); + hash->val = (int*)lodepng_malloc(sizeof(int) * windowsize); + hash->chain = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); + + hash->zeros = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); + hash->headz = (int*)lodepng_malloc(sizeof(int) * (MAX_SUPPORTED_DEFLATE_LENGTH + 1)); + hash->chainz = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); + + if(!hash->head || !hash->chain || !hash->val || !hash->headz|| !hash->chainz || !hash->zeros) + { + return 83; /*alloc fail*/ + } + + /*initialize hash table*/ + for(i = 0; i != HASH_NUM_VALUES; ++i) hash->head[i] = -1; + for(i = 0; i != windowsize; ++i) hash->val[i] = -1; + for(i = 0; i != windowsize; ++i) hash->chain[i] = i; /*same value as index indicates uninitialized*/ + + for(i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; ++i) hash->headz[i] = -1; + for(i = 0; i != windowsize; ++i) hash->chainz[i] = i; /*same value as index indicates uninitialized*/ + + return 0; +} + +static void hash_cleanup(Hash* hash) +{ + lodepng_free(hash->head); + lodepng_free(hash->val); + lodepng_free(hash->chain); + + lodepng_free(hash->zeros); + lodepng_free(hash->headz); + lodepng_free(hash->chainz); +} + + + +static unsigned getHash(const unsigned char* data, size_t size, size_t pos) +{ + unsigned result = 0; + if(pos + 2 < size) + { + /*A simple shift and xor hash is used. Since the data of PNGs is dominated + by zeroes due to the filters, a better hash does not have a significant + effect on speed in traversing the chain, and causes more time spend on + calculating the hash.*/ + result ^= (unsigned)(data[pos + 0] << 0u); + result ^= (unsigned)(data[pos + 1] << 4u); + result ^= (unsigned)(data[pos + 2] << 8u); + } else { + size_t amount, i; + if(pos >= size) return 0; + amount = size - pos; + for(i = 0; i != amount; ++i) result ^= (unsigned)(data[pos + i] << (i * 8u)); + } + return result & HASH_BIT_MASK; +} + +static unsigned countZeros(const unsigned char* data, size_t size, size_t pos) +{ + const unsigned char* start = data + pos; + const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH; + if(end > data + size) end = data + size; + data = start; + while(data != end && *data == 0) ++data; + /*subtracting two addresses returned as 32-bit number (max value is MAX_SUPPORTED_DEFLATE_LENGTH)*/ + return (unsigned)(data - start); +} + +/*wpos = pos & (windowsize - 1)*/ +static void updateHashChain(Hash* hash, size_t wpos, unsigned hashval, unsigned short numzeros) +{ + hash->val[wpos] = (int)hashval; + if(hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval]; + hash->head[hashval] = wpos; + + hash->zeros[wpos] = numzeros; + if(hash->headz[numzeros] != -1) hash->chainz[wpos] = hash->headz[numzeros]; + hash->headz[numzeros] = wpos; +} + +/* +LZ77-encode the data. Return value is error code. The input are raw bytes, the output +is in the form of unsigned integers with codes representing for example literal bytes, or +length/distance pairs. +It uses a hash table technique to let it encode faster. When doing LZ77 encoding, a +sliding window (of windowsize) is used, and all past bytes in that window can be used as +the "dictionary". A brute force search through all possible distances would be slow, and +this hash technique is one out of several ways to speed this up. +*/ +static unsigned encodeLZ77(uivector* out, Hash* hash, + const unsigned char* in, size_t inpos, size_t insize, unsigned windowsize, + unsigned minmatch, unsigned nicematch, unsigned lazymatching) +{ + size_t pos; + unsigned i, error = 0; + /*for large window lengths, assume the user wants no compression loss. Otherwise, max hash chain length speedup.*/ + unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8; + unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64; + + unsigned usezeros = 1; /*not sure if setting it to false for windowsize < 8192 is better or worse*/ + unsigned numzeros = 0; + + unsigned offset; /*the offset represents the distance in LZ77 terminology*/ + unsigned length; + unsigned lazy = 0; + unsigned lazylength = 0, lazyoffset = 0; + unsigned hashval; + unsigned current_offset, current_length; + unsigned prev_offset; + const unsigned char *lastptr, *foreptr, *backptr; + unsigned hashpos; + + if(windowsize == 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/ + if((windowsize & (windowsize - 1)) != 0) return 90; /*error: must be power of two*/ + + if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH; + + for(pos = inpos; pos < insize; ++pos) + { + size_t wpos = pos & (windowsize - 1); /*position for in 'circular' hash buffers*/ + unsigned chainlength = 0; + + hashval = getHash(in, insize, pos); + + if(usezeros && hashval == 0) + { + if(numzeros == 0) numzeros = countZeros(in, insize, pos); + else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; + } + else + { + numzeros = 0; + } + + updateHashChain(hash, wpos, hashval, numzeros); + + /*the length and offset found for the current position*/ + length = 0; + offset = 0; + + hashpos = hash->chain[wpos]; + + lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH]; + + /*search for the longest string*/ + prev_offset = 0; + for(;;) + { + if(chainlength++ >= maxchainlength) break; + current_offset = hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize; + + if(current_offset < prev_offset) break; /*stop when went completely around the circular buffer*/ + prev_offset = current_offset; + if(current_offset > 0) + { + /*test the next characters*/ + foreptr = &in[pos]; + backptr = &in[pos - current_offset]; + + /*common case in PNGs is lots of zeros. Quickly skip over them as a speedup*/ + if(numzeros >= 3) + { + unsigned skip = hash->zeros[hashpos]; + if(skip > numzeros) skip = numzeros; + backptr += skip; + foreptr += skip; + } + + while(foreptr != lastptr && *backptr == *foreptr) /*maximum supported length by deflate is max length*/ + { + ++backptr; + ++foreptr; + } + current_length = (unsigned)(foreptr - &in[pos]); + + if(current_length > length) + { + length = current_length; /*the longest length*/ + offset = current_offset; /*the offset that is related to this longest length*/ + /*jump out once a length of max length is found (speed gain). This also jumps + out if length is MAX_SUPPORTED_DEFLATE_LENGTH*/ + if(current_length >= nicematch) break; + } + } + + if(hashpos == hash->chain[hashpos]) break; + + if(numzeros >= 3 && length > numzeros) + { + hashpos = hash->chainz[hashpos]; + if(hash->zeros[hashpos] != numzeros) break; + } + else + { + hashpos = hash->chain[hashpos]; + /*outdated hash value, happens if particular value was not encountered in whole last window*/ + if(hash->val[hashpos] != (int)hashval) break; + } + } + + if(lazymatching) + { + if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH) + { + lazy = 1; + lazylength = length; + lazyoffset = offset; + continue; /*try the next byte*/ + } + if(lazy) + { + lazy = 0; + if(pos == 0) ERROR_BREAK(81); + if(length > lazylength + 1) + { + /*push the previous character as literal*/ + if(!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 /*alloc fail*/); + } + else + { + length = lazylength; + offset = lazyoffset; + hash->head[hashval] = -1; /*the same hashchain update will be done, this ensures no wrong alteration*/ + hash->headz[numzeros] = -1; /*idem*/ + --pos; + } + } + } + if(length >= 3 && offset > windowsize) ERROR_BREAK(86 /*too big (or overflown negative) offset*/); + + /*encode it as length/distance pair or literal value*/ + if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/ + { + if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); + } + else if(length < minmatch || (length == 3 && offset > 4096)) + { + /*compensate for the fact that longer offsets have more extra bits, a + length of only 3 may be not worth it then*/ + if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); + } + else + { + addLengthDistance(out, length, offset); + for(i = 1; i < length; ++i) + { + ++pos; + wpos = pos & (windowsize - 1); + hashval = getHash(in, insize, pos); + if(usezeros && hashval == 0) + { + if(numzeros == 0) numzeros = countZeros(in, insize, pos); + else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; + } + else + { + numzeros = 0; + } + updateHashChain(hash, wpos, hashval, numzeros); + } + } + } /*end of the loop through each character of input*/ + + return error; +} + +/* /////////////////////////////////////////////////////////////////////////// */ + +static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, size_t datasize) +{ + /*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte, + 2 bytes LEN, 2 bytes NLEN, LEN bytes literal DATA*/ + + size_t i, j, numdeflateblocks = (datasize + 65534) / 65535; + unsigned datapos = 0; + for(i = 0; i != numdeflateblocks; ++i) + { + unsigned BFINAL, BTYPE, LEN, NLEN; + unsigned char firstbyte; + + BFINAL = (i == numdeflateblocks - 1); + BTYPE = 0; + + firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1)); + ucvector_push_back(out, firstbyte); + + LEN = 65535; + if(datasize - datapos < 65535) LEN = (unsigned)datasize - datapos; + NLEN = 65535 - LEN; + + ucvector_push_back(out, (unsigned char)(LEN & 255)); + ucvector_push_back(out, (unsigned char)(LEN >> 8)); + ucvector_push_back(out, (unsigned char)(NLEN & 255)); + ucvector_push_back(out, (unsigned char)(NLEN >> 8)); + + /*Decompressed data*/ + for(j = 0; j < 65535 && datapos < datasize; ++j) + { + ucvector_push_back(out, data[datapos++]); + } + } + + return 0; +} + +/* +write the lz77-encoded data, which has lit, len and dist codes, to compressed stream using huffman trees. +tree_ll: the tree for lit and len codes. +tree_d: the tree for distance codes. +*/ +static void writeLZ77data(size_t* bp, ucvector* out, const uivector* lz77_encoded, + const HuffmanTree* tree_ll, const HuffmanTree* tree_d) +{ + size_t i = 0; + for(i = 0; i != lz77_encoded->size; ++i) + { + unsigned val = lz77_encoded->data[i]; + addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_ll, val), HuffmanTree_getLength(tree_ll, val)); + if(val > 256) /*for a length code, 3 more things have to be added*/ + { + unsigned length_index = val - FIRST_LENGTH_CODE_INDEX; + unsigned n_length_extra_bits = LENGTHEXTRA[length_index]; + unsigned length_extra_bits = lz77_encoded->data[++i]; + + unsigned distance_code = lz77_encoded->data[++i]; + + unsigned distance_index = distance_code; + unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index]; + unsigned distance_extra_bits = lz77_encoded->data[++i]; + + addBitsToStream(bp, out, length_extra_bits, n_length_extra_bits); + addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_d, distance_code), + HuffmanTree_getLength(tree_d, distance_code)); + addBitsToStream(bp, out, distance_extra_bits, n_distance_extra_bits); + } + } +} + +/*Deflate for a block of type "dynamic", that is, with freely, optimally, created huffman trees*/ +static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, + const unsigned char* data, size_t datapos, size_t dataend, + const LodePNGCompressSettings* settings, unsigned final) +{ + unsigned error = 0; + + /* + A block is compressed as follows: The PNG data is lz77 encoded, resulting in + literal bytes and length/distance pairs. This is then huffman compressed with + two huffman trees. One huffman tree is used for the lit and len values ("ll"), + another huffman tree is used for the dist values ("d"). These two trees are + stored using their code lengths, and to compress even more these code lengths + are also run-length encoded and huffman compressed. This gives a huffman tree + of code lengths "cl". The code lenghts used to describe this third tree are + the code length code lengths ("clcl"). + */ + + /*The lz77 encoded data, represented with integers since there will also be length and distance codes in it*/ + uivector lz77_encoded; + HuffmanTree tree_ll; /*tree for lit,len values*/ + HuffmanTree tree_d; /*tree for distance codes*/ + HuffmanTree tree_cl; /*tree for encoding the code lengths representing tree_ll and tree_d*/ + uivector frequencies_ll; /*frequency of lit,len codes*/ + uivector frequencies_d; /*frequency of dist codes*/ + uivector frequencies_cl; /*frequency of code length codes*/ + uivector bitlen_lld; /*lit,len,dist code lenghts (int bits), literally (without repeat codes).*/ + uivector bitlen_lld_e; /*bitlen_lld encoded with repeat codes (this is a rudemtary run length compression)*/ + /*bitlen_cl is the code length code lengths ("clcl"). The bit lengths of codes to represent tree_cl + (these are written as is in the file, it would be crazy to compress these using yet another huffman + tree that needs to be represented by yet another set of code lengths)*/ + uivector bitlen_cl; + size_t datasize = dataend - datapos; + + /* + Due to the huffman compression of huffman tree representations ("two levels"), there are some anologies: + bitlen_lld is to tree_cl what data is to tree_ll and tree_d. + bitlen_lld_e is to bitlen_lld what lz77_encoded is to data. + bitlen_cl is to bitlen_lld_e what bitlen_lld is to lz77_encoded. + */ + + unsigned BFINAL = final; + size_t numcodes_ll, numcodes_d, i; + unsigned HLIT, HDIST, HCLEN; + + uivector_init(&lz77_encoded); + HuffmanTree_init(&tree_ll); + HuffmanTree_init(&tree_d); + HuffmanTree_init(&tree_cl); + uivector_init(&frequencies_ll); + uivector_init(&frequencies_d); + uivector_init(&frequencies_cl); + uivector_init(&bitlen_lld); + uivector_init(&bitlen_lld_e); + uivector_init(&bitlen_cl); + + /*This while loop never loops due to a break at the end, it is here to + allow breaking out of it to the cleanup phase on error conditions.*/ + while(!error) + { + if(settings->use_lz77) + { + error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, + settings->minmatch, settings->nicematch, settings->lazymatching); + if(error) break; + } + else + { + if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 /*alloc fail*/); + for(i = datapos; i < dataend; ++i) lz77_encoded.data[i - datapos] = data[i]; /*no LZ77, but still will be Huffman compressed*/ + } + + if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83 /*alloc fail*/); + if(!uivector_resizev(&frequencies_d, 30, 0)) ERROR_BREAK(83 /*alloc fail*/); + + /*Count the frequencies of lit, len and dist codes*/ + for(i = 0; i != lz77_encoded.size; ++i) + { + unsigned symbol = lz77_encoded.data[i]; + ++frequencies_ll.data[symbol]; + if(symbol > 256) + { + unsigned dist = lz77_encoded.data[i + 2]; + ++frequencies_d.data[dist]; + i += 3; + } + } + frequencies_ll.data[256] = 1; /*there will be exactly 1 end code, at the end of the block*/ + + /*Make both huffman trees, one for the lit and len codes, one for the dist codes*/ + error = HuffmanTree_makeFromFrequencies(&tree_ll, frequencies_ll.data, 257, frequencies_ll.size, 15); + if(error) break; + /*2, not 1, is chosen for mincodes: some buggy PNG decoders require at least 2 symbols in the dist tree*/ + error = HuffmanTree_makeFromFrequencies(&tree_d, frequencies_d.data, 2, frequencies_d.size, 15); + if(error) break; + + numcodes_ll = tree_ll.numcodes; if(numcodes_ll > 286) numcodes_ll = 286; + numcodes_d = tree_d.numcodes; if(numcodes_d > 30) numcodes_d = 30; + /*store the code lengths of both generated trees in bitlen_lld*/ + for(i = 0; i != numcodes_ll; ++i) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_ll, (unsigned)i)); + for(i = 0; i != numcodes_d; ++i) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_d, (unsigned)i)); + + /*run-length compress bitlen_ldd into bitlen_lld_e by using repeat codes 16 (copy length 3-6 times), + 17 (3-10 zeroes), 18 (11-138 zeroes)*/ + for(i = 0; i != (unsigned)bitlen_lld.size; ++i) + { + unsigned j = 0; /*amount of repititions*/ + while(i + j + 1 < (unsigned)bitlen_lld.size && bitlen_lld.data[i + j + 1] == bitlen_lld.data[i]) ++j; + + if(bitlen_lld.data[i] == 0 && j >= 2) /*repeat code for zeroes*/ + { + ++j; /*include the first zero*/ + if(j <= 10) /*repeat code 17 supports max 10 zeroes*/ + { + uivector_push_back(&bitlen_lld_e, 17); + uivector_push_back(&bitlen_lld_e, j - 3); + } + else /*repeat code 18 supports max 138 zeroes*/ + { + if(j > 138) j = 138; + uivector_push_back(&bitlen_lld_e, 18); + uivector_push_back(&bitlen_lld_e, j - 11); + } + i += (j - 1); + } + else if(j >= 3) /*repeat code for value other than zero*/ + { + size_t k; + unsigned num = j / 6, rest = j % 6; + uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]); + for(k = 0; k < num; ++k) + { + uivector_push_back(&bitlen_lld_e, 16); + uivector_push_back(&bitlen_lld_e, 6 - 3); + } + if(rest >= 3) + { + uivector_push_back(&bitlen_lld_e, 16); + uivector_push_back(&bitlen_lld_e, rest - 3); + } + else j -= rest; + i += j; + } + else /*too short to benefit from repeat code*/ + { + uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]); + } + } + + /*generate tree_cl, the huffmantree of huffmantrees*/ + + if(!uivector_resizev(&frequencies_cl, NUM_CODE_LENGTH_CODES, 0)) ERROR_BREAK(83 /*alloc fail*/); + for(i = 0; i != bitlen_lld_e.size; ++i) + { + ++frequencies_cl.data[bitlen_lld_e.data[i]]; + /*after a repeat code come the bits that specify the number of repetitions, + those don't need to be in the frequencies_cl calculation*/ + if(bitlen_lld_e.data[i] >= 16) ++i; + } + + error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl.data, + frequencies_cl.size, frequencies_cl.size, 7); + if(error) break; + + if(!uivector_resize(&bitlen_cl, tree_cl.numcodes)) ERROR_BREAK(83 /*alloc fail*/); + for(i = 0; i != tree_cl.numcodes; ++i) + { + /*lenghts of code length tree is in the order as specified by deflate*/ + bitlen_cl.data[i] = HuffmanTree_getLength(&tree_cl, CLCL_ORDER[i]); + } + while(bitlen_cl.data[bitlen_cl.size - 1] == 0 && bitlen_cl.size > 4) + { + /*remove zeros at the end, but minimum size must be 4*/ + if(!uivector_resize(&bitlen_cl, bitlen_cl.size - 1)) ERROR_BREAK(83 /*alloc fail*/); + } + if(error) break; + + /* + Write everything into the output + + After the BFINAL and BTYPE, the dynamic block consists out of the following: + - 5 bits HLIT, 5 bits HDIST, 4 bits HCLEN + - (HCLEN+4)*3 bits code lengths of code length alphabet + - HLIT + 257 code lenghts of lit/length alphabet (encoded using the code length + alphabet, + possible repetition codes 16, 17, 18) + - HDIST + 1 code lengths of distance alphabet (encoded using the code length + alphabet, + possible repetition codes 16, 17, 18) + - compressed data + - 256 (end code) + */ + + /*Write block type*/ + addBitToStream(bp, out, BFINAL); + addBitToStream(bp, out, 0); /*first bit of BTYPE "dynamic"*/ + addBitToStream(bp, out, 1); /*second bit of BTYPE "dynamic"*/ + + /*write the HLIT, HDIST and HCLEN values*/ + HLIT = (unsigned)(numcodes_ll - 257); + HDIST = (unsigned)(numcodes_d - 1); + HCLEN = (unsigned)bitlen_cl.size - 4; + /*trim zeroes for HCLEN. HLIT and HDIST were already trimmed at tree creation*/ + while(!bitlen_cl.data[HCLEN + 4 - 1] && HCLEN > 0) --HCLEN; + addBitsToStream(bp, out, HLIT, 5); + addBitsToStream(bp, out, HDIST, 5); + addBitsToStream(bp, out, HCLEN, 4); + + /*write the code lenghts of the code length alphabet*/ + for(i = 0; i != HCLEN + 4; ++i) addBitsToStream(bp, out, bitlen_cl.data[i], 3); + + /*write the lenghts of the lit/len AND the dist alphabet*/ + for(i = 0; i != bitlen_lld_e.size; ++i) + { + addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_cl, bitlen_lld_e.data[i]), + HuffmanTree_getLength(&tree_cl, bitlen_lld_e.data[i])); + /*extra bits of repeat codes*/ + if(bitlen_lld_e.data[i] == 16) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 2); + else if(bitlen_lld_e.data[i] == 17) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 3); + else if(bitlen_lld_e.data[i] == 18) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 7); + } + + /*write the compressed data symbols*/ + writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d); + /*error: the length of the end code 256 must be larger than 0*/ + if(HuffmanTree_getLength(&tree_ll, 256) == 0) ERROR_BREAK(64); + + /*write the end code*/ + addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256)); + + break; /*end of error-while*/ + } + + /*cleanup*/ + uivector_cleanup(&lz77_encoded); + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); + HuffmanTree_cleanup(&tree_cl); + uivector_cleanup(&frequencies_ll); + uivector_cleanup(&frequencies_d); + uivector_cleanup(&frequencies_cl); + uivector_cleanup(&bitlen_lld_e); + uivector_cleanup(&bitlen_lld); + uivector_cleanup(&bitlen_cl); + + return error; +} + +static unsigned deflateFixed(ucvector* out, size_t* bp, Hash* hash, + const unsigned char* data, + size_t datapos, size_t dataend, + const LodePNGCompressSettings* settings, unsigned final) +{ + HuffmanTree tree_ll; /*tree for literal values and length codes*/ + HuffmanTree tree_d; /*tree for distance codes*/ + + unsigned BFINAL = final; + unsigned error = 0; + size_t i; + + HuffmanTree_init(&tree_ll); + HuffmanTree_init(&tree_d); + + generateFixedLitLenTree(&tree_ll); + generateFixedDistanceTree(&tree_d); + + addBitToStream(bp, out, BFINAL); + addBitToStream(bp, out, 1); /*first bit of BTYPE*/ + addBitToStream(bp, out, 0); /*second bit of BTYPE*/ + + if(settings->use_lz77) /*LZ77 encoded*/ + { + uivector lz77_encoded; + uivector_init(&lz77_encoded); + error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, + settings->minmatch, settings->nicematch, settings->lazymatching); + if(!error) writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d); + uivector_cleanup(&lz77_encoded); + } + else /*no LZ77, but still will be Huffman compressed*/ + { + for(i = datapos; i < dataend; ++i) + { + addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, data[i]), HuffmanTree_getLength(&tree_ll, data[i])); + } + } + /*add END code*/ + if(!error) addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256)); + + /*cleanup*/ + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); + + return error; +} + +static unsigned lodepng_deflatev(ucvector* out, const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings) +{ + unsigned error = 0; + size_t i, blocksize, numdeflateblocks; + size_t bp = 0; /*the bit pointer*/ + Hash hash; + + if(settings->btype > 2) return 61; + else if(settings->btype == 0) return deflateNoCompression(out, in, insize); + else if(settings->btype == 1) blocksize = insize; + else /*if(settings->btype == 2)*/ + { + /*on PNGs, deflate blocks of 65-262k seem to give most dense encoding*/ + blocksize = insize / 8 + 8; + if(blocksize < 65536) blocksize = 65536; + if(blocksize > 262144) blocksize = 262144; + } + + numdeflateblocks = (insize + blocksize - 1) / blocksize; + if(numdeflateblocks == 0) numdeflateblocks = 1; + + error = hash_init(&hash, settings->windowsize); + if(error) return error; + + for(i = 0; i != numdeflateblocks && !error; ++i) + { + unsigned final = (i == numdeflateblocks - 1); + size_t start = i * blocksize; + size_t end = start + blocksize; + if(end > insize) end = insize; + + if(settings->btype == 1) error = deflateFixed(out, &bp, &hash, in, start, end, settings, final); + else if(settings->btype == 2) error = deflateDynamic(out, &bp, &hash, in, start, end, settings, final); + } + + hash_cleanup(&hash); + + return error; +} + +unsigned lodepng_deflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings) +{ + unsigned error; + ucvector v; + ucvector_init_buffer(&v, *out, *outsize); + error = lodepng_deflatev(&v, in, insize, settings); + *out = v.data; + *outsize = v.size; + return error; +} + +static unsigned deflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings) +{ + if(settings->custom_deflate) + { + return settings->custom_deflate(out, outsize, in, insize, settings); + } + else + { + return lodepng_deflate(out, outsize, in, insize, settings); + } +} + +#endif /*LODEPNG_COMPILE_DECODER*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Adler32 */ +/* ////////////////////////////////////////////////////////////////////////// */ + +static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len) +{ + unsigned s1 = adler & 0xffff; + unsigned s2 = (adler >> 16) & 0xffff; + + while(len > 0) + { + /*at least 5550 sums can be done before the sums overflow, saving a lot of module divisions*/ + unsigned amount = len > 5550 ? 5550 : len; + len -= amount; + while(amount > 0) + { + s1 += (*data++); + s2 += s1; + --amount; + } + s1 %= 65521; + s2 %= 65521; + } + + return (s2 << 16) | s1; +} + +/*Return the adler32 of the bytes data[0..len-1]*/ +static unsigned adler32(const unsigned char* data, unsigned len) +{ + return update_adler32(1L, data, len); +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Zlib / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_DECODER + +unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGDecompressSettings* settings) +{ + unsigned error = 0; + unsigned CM, CINFO, FDICT; + + if(insize < 2) return 53; /*error, size of zlib data too small*/ + /*read information from zlib header*/ + if((in[0] * 256 + in[1]) % 31 != 0) + { + /*error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way*/ + return 24; + } + + CM = in[0] & 15; + CINFO = (in[0] >> 4) & 15; + /*FCHECK = in[1] & 31;*/ /*FCHECK is already tested above*/ + FDICT = (in[1] >> 5) & 1; + /*FLEVEL = (in[1] >> 6) & 3;*/ /*FLEVEL is not used here*/ + + if(CM != 8 || CINFO > 7) + { + /*error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec*/ + return 25; + } + if(FDICT != 0) + { + /*error: the specification of PNG says about the zlib stream: + "The additional flags shall not specify a preset dictionary."*/ + return 26; + } + + error = inflate(out, outsize, in + 2, insize - 2, settings); + if(error) return error; + + if(!settings->ignore_adler32) + { + unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]); + unsigned checksum = adler32(*out, (unsigned)(*outsize)); + if(checksum != ADLER32) return 58; /*error, adler checksum not correct, data must be corrupted*/ + } + + return 0; /*no error*/ +} + +static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGDecompressSettings* settings) +{ + if(settings->custom_zlib) + { + return settings->custom_zlib(out, outsize, in, insize, settings); + } + else + { + return lodepng_zlib_decompress(out, outsize, in, insize, settings); + } +} + +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER + +unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGCompressSettings* settings) +{ + /*initially, *out must be NULL and outsize 0, if you just give some random *out + that's pointing to a non allocated buffer, this'll crash*/ + ucvector outv; + size_t i; + unsigned error; + unsigned char* deflatedata = 0; + size_t deflatesize = 0; + + /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/ + unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/ + unsigned FLEVEL = 0; + unsigned FDICT = 0; + unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64; + unsigned FCHECK = 31 - CMFFLG % 31; + CMFFLG += FCHECK; + + /*ucvector-controlled version of the output buffer, for dynamic array*/ + ucvector_init_buffer(&outv, *out, *outsize); + + ucvector_push_back(&outv, (unsigned char)(CMFFLG >> 8)); + ucvector_push_back(&outv, (unsigned char)(CMFFLG & 255)); + + error = deflate(&deflatedata, &deflatesize, in, insize, settings); + + if(!error) + { + unsigned ADLER32 = adler32(in, (unsigned)insize); + for(i = 0; i != deflatesize; ++i) ucvector_push_back(&outv, deflatedata[i]); + lodepng_free(deflatedata); + lodepng_add32bitInt(&outv, ADLER32); + } + + *out = outv.data; + *outsize = outv.size; + + return error; +} + +/* compress using the default or custom zlib function */ +static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGCompressSettings* settings) +{ + if(settings->custom_zlib) + { + return settings->custom_zlib(out, outsize, in, insize, settings); + } + else + { + return lodepng_zlib_compress(out, outsize, in, insize, settings); + } +} + +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#else /*no LODEPNG_COMPILE_ZLIB*/ + +#ifdef LODEPNG_COMPILE_DECODER +static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGDecompressSettings* settings) +{ + if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ + return settings->custom_zlib(out, outsize, in, insize, settings); +} +#endif /*LODEPNG_COMPILE_DECODER*/ +#ifdef LODEPNG_COMPILE_ENCODER +static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGCompressSettings* settings) +{ + if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ + return settings->custom_zlib(out, outsize, in, insize, settings); +} +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#endif /*LODEPNG_COMPILE_ZLIB*/ + +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_ENCODER + +/*this is a good tradeoff between speed and compression ratio*/ +#define DEFAULT_WINDOWSIZE 2048 + +void lodepng_compress_settings_init(LodePNGCompressSettings* settings) +{ + /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/ + settings->btype = 2; + settings->use_lz77 = 1; + settings->windowsize = DEFAULT_WINDOWSIZE; + settings->minmatch = 3; + settings->nicematch = 128; + settings->lazymatching = 1; + + settings->custom_zlib = 0; + settings->custom_deflate = 0; + settings->custom_context = 0; +} + +const LodePNGCompressSettings lodepng_default_compress_settings = {2, 1, DEFAULT_WINDOWSIZE, 3, 128, 1, 0, 0, 0}; + + +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_DECODER + +void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings) +{ + settings->ignore_adler32 = 0; + + settings->custom_zlib = 0; + settings->custom_inflate = 0; + settings->custom_context = 0; +} + +const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, 0}; + +#endif /*LODEPNG_COMPILE_DECODER*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // End of Zlib related code. Begin of PNG related code. // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_PNG + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / CRC32 / */ +/* ////////////////////////////////////////////////////////////////////////// */ + + +#ifndef LODEPNG_NO_COMPILE_CRC +/* CRC polynomial: 0xedb88320 */ +static unsigned lodepng_crc32_table[256] = { + 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, + 249268274u, 2044508324u, 3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u, + 498536548u, 1789927666u, 4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u, + 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u, 4195302755u, 2366115317u, + 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u, + 901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u, + 651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u, + 671266974u, 1594198024u, 3322730930u, 2970347812u, 795835527u, 1483230225u, 3244367275u, 3060149565u, + 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u, + 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u, + 1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u, + 1706088902u, 314042704u, 2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u, + 1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u, + 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u, 2852801631u, 3708648649u, + 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u, + 1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u, + 3988292384u, 2596254646u, 62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u, + 3814918930u, 2489596804u, 225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u, + 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u, 426522225u, 1852507879u, + 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u, + 3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u, + 3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u, + 3412177804u, 3160834842u, 628085408u, 1382605366u, 3423369109u, 3138078467u, 570562233u, 1426400815u, + 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u, + 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u, + 2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u, + 2262029012u, 4057260610u, 1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u, + 2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u, 1634467795u, 376229701u, + 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u, + 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u, + 3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u, + 3009837614u, 3294710456u, 1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u +}; + +/*Return the CRC of the bytes buf[0..len-1].*/ +unsigned lodepng_crc32(const unsigned char* data, size_t length) +{ + unsigned r = 0xffffffffu; + size_t i; + for(i = 0; i < length; ++i) + { + r = lodepng_crc32_table[(r ^ data[i]) & 0xff] ^ (r >> 8); + } + return r ^ 0xffffffffu; +} +#else /* !LODEPNG_NO_COMPILE_CRC */ +unsigned lodepng_crc32(const unsigned char* data, size_t length); +#endif /* !LODEPNG_NO_COMPILE_CRC */ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Reading and writing single bits and bytes from/to stream for LodePNG / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream) +{ + unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1); + ++(*bitpointer); + return result; +} + +static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) +{ + unsigned result = 0; + size_t i; + for(i = 0 ; i < nbits; ++i) + { + result <<= 1; + result |= (unsigned)readBitFromReversedStream(bitpointer, bitstream); + } + return result; +} + +#ifdef LODEPNG_COMPILE_DECODER +static void setBitOfReversedStream0(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) +{ + /*the current bit in bitstream must be 0 for this to work*/ + if(bit) + { + /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/ + bitstream[(*bitpointer) >> 3] |= (bit << (7 - ((*bitpointer) & 0x7))); + } + ++(*bitpointer); +} +#endif /*LODEPNG_COMPILE_DECODER*/ + +static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) +{ + /*the current bit in bitstream may be 0 or 1 for this to work*/ + if(bit == 0) bitstream[(*bitpointer) >> 3] &= (unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7)))); + else bitstream[(*bitpointer) >> 3] |= (1 << (7 - ((*bitpointer) & 0x7))); + ++(*bitpointer); +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / PNG chunks / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +unsigned lodepng_chunk_length(const unsigned char* chunk) +{ + return lodepng_read32bitInt(&chunk[0]); +} + +void lodepng_chunk_type(char type[5], const unsigned char* chunk) +{ + unsigned i; + for(i = 0; i != 4; ++i) type[i] = (char)chunk[4 + i]; + type[4] = 0; /*null termination char*/ +} + +unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type) +{ + if(strlen(type) != 4) return 0; + return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]); +} + +unsigned char lodepng_chunk_ancillary(const unsigned char* chunk) +{ + return((chunk[4] & 32) != 0); +} + +unsigned char lodepng_chunk_private(const unsigned char* chunk) +{ + return((chunk[6] & 32) != 0); +} + +unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk) +{ + return((chunk[7] & 32) != 0); +} + +unsigned char* lodepng_chunk_data(unsigned char* chunk) +{ + return &chunk[8]; +} + +const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk) +{ + return &chunk[8]; +} + +unsigned lodepng_chunk_check_crc(const unsigned char* chunk) +{ + unsigned length = lodepng_chunk_length(chunk); + unsigned CRC = lodepng_read32bitInt(&chunk[length + 8]); + /*the CRC is taken of the data and the 4 chunk type letters, not the length*/ + unsigned checksum = lodepng_crc32(&chunk[4], length + 4); + if(CRC != checksum) return 1; + else return 0; +} + +void lodepng_chunk_generate_crc(unsigned char* chunk) +{ + unsigned length = lodepng_chunk_length(chunk); + unsigned CRC = lodepng_crc32(&chunk[4], length + 4); + lodepng_set32bitInt(chunk + 8 + length, CRC); +} + +unsigned char* lodepng_chunk_next(unsigned char* chunk) +{ + unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; + return &chunk[total_chunk_length]; +} + +const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk) +{ + unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; + return &chunk[total_chunk_length]; +} + +unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk) +{ + unsigned i; + unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; + unsigned char *chunk_start, *new_buffer; + size_t new_length = (*outlength) + total_chunk_length; + if(new_length < total_chunk_length || new_length < (*outlength)) return 77; /*integer overflow happened*/ + + new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); + if(!new_buffer) return 83; /*alloc fail*/ + (*out) = new_buffer; + (*outlength) = new_length; + chunk_start = &(*out)[new_length - total_chunk_length]; + + for(i = 0; i != total_chunk_length; ++i) chunk_start[i] = chunk[i]; + + return 0; +} + +unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, + const char* type, const unsigned char* data) +{ + unsigned i; + unsigned char *chunk, *new_buffer; + size_t new_length = (*outlength) + length + 12; + if(new_length < length + 12 || new_length < (*outlength)) return 77; /*integer overflow happened*/ + new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); + if(!new_buffer) return 83; /*alloc fail*/ + (*out) = new_buffer; + (*outlength) = new_length; + chunk = &(*out)[(*outlength) - length - 12]; + + /*1: length*/ + lodepng_set32bitInt(chunk, (unsigned)length); + + /*2: chunk name (4 letters)*/ + chunk[4] = (unsigned char)type[0]; + chunk[5] = (unsigned char)type[1]; + chunk[6] = (unsigned char)type[2]; + chunk[7] = (unsigned char)type[3]; + + /*3: the data*/ + for(i = 0; i != length; ++i) chunk[8 + i] = data[i]; + + /*4: CRC (of the chunkname characters and the data)*/ + lodepng_chunk_generate_crc(chunk); + + return 0; +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Color types and such / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*return type is a LodePNG error code*/ +static unsigned checkColorValidity(LodePNGColorType colortype, unsigned bd) /*bd = bitdepth*/ +{ + switch(colortype) + { + case 0: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break; /*grey*/ + case 2: if(!( bd == 8 || bd == 16)) return 37; break; /*RGB*/ + case 3: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; break; /*palette*/ + case 4: if(!( bd == 8 || bd == 16)) return 37; break; /*grey + alpha*/ + case 6: if(!( bd == 8 || bd == 16)) return 37; break; /*RGBA*/ + default: return 31; + } + return 0; /*allowed color type / bits combination*/ +} + +static unsigned getNumColorChannels(LodePNGColorType colortype) +{ + switch(colortype) + { + case 0: return 1; /*grey*/ + case 2: return 3; /*RGB*/ + case 3: return 1; /*palette*/ + case 4: return 2; /*grey + alpha*/ + case 6: return 4; /*RGBA*/ + } + return 0; /*unexisting color type*/ +} + +static unsigned lodepng_get_bpp_lct(LodePNGColorType colortype, unsigned bitdepth) +{ + /*bits per pixel is amount of channels * bits per channel*/ + return getNumColorChannels(colortype) * bitdepth; +} + +/* ////////////////////////////////////////////////////////////////////////// */ + +void lodepng_color_mode_init(LodePNGColorMode* info) +{ + info->key_defined = 0; + info->key_r = info->key_g = info->key_b = 0; + info->colortype = LCT_RGBA; + info->bitdepth = 8; + info->palette = 0; + info->palettesize = 0; +} + +void lodepng_color_mode_cleanup(LodePNGColorMode* info) +{ + lodepng_palette_clear(info); +} + +unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source) +{ + size_t i; + lodepng_color_mode_cleanup(dest); + *dest = *source; + if(source->palette) + { + dest->palette = (unsigned char*)lodepng_malloc(1024); + if(!dest->palette && source->palettesize) return 83; /*alloc fail*/ + for(i = 0; i != source->palettesize * 4; ++i) dest->palette[i] = source->palette[i]; + } + return 0; +} + +static int lodepng_color_mode_equal(const LodePNGColorMode* a, const LodePNGColorMode* b) +{ + size_t i; + if(a->colortype != b->colortype) return 0; + if(a->bitdepth != b->bitdepth) return 0; + if(a->key_defined != b->key_defined) return 0; + if(a->key_defined) + { + if(a->key_r != b->key_r) return 0; + if(a->key_g != b->key_g) return 0; + if(a->key_b != b->key_b) return 0; + } + /*if one of the palette sizes is 0, then we consider it to be the same as the + other: it means that e.g. the palette was not given by the user and should be + considered the same as the palette inside the PNG.*/ + if(1/*a->palettesize != 0 && b->palettesize != 0*/) { + if(a->palettesize != b->palettesize) return 0; + for(i = 0; i != a->palettesize * 4; ++i) + { + if(a->palette[i] != b->palette[i]) return 0; + } + } + return 1; +} + +void lodepng_palette_clear(LodePNGColorMode* info) +{ + if(info->palette) lodepng_free(info->palette); + info->palette = 0; + info->palettesize = 0; +} + +unsigned lodepng_palette_add(LodePNGColorMode* info, + unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + unsigned char* data; + /*the same resize technique as C++ std::vectors is used, and here it's made so that for a palette with + the max of 256 colors, it'll have the exact alloc size*/ + if(!info->palette) /*allocate palette if empty*/ + { + /*room for 256 colors with 4 bytes each*/ + data = (unsigned char*)lodepng_realloc(info->palette, 1024); + if(!data) return 83; /*alloc fail*/ + else info->palette = data; + } + info->palette[4 * info->palettesize + 0] = r; + info->palette[4 * info->palettesize + 1] = g; + info->palette[4 * info->palettesize + 2] = b; + info->palette[4 * info->palettesize + 3] = a; + ++info->palettesize; + return 0; +} + +unsigned lodepng_get_bpp(const LodePNGColorMode* info) +{ + /*calculate bits per pixel out of colortype and bitdepth*/ + return lodepng_get_bpp_lct(info->colortype, info->bitdepth); +} + +unsigned lodepng_get_channels(const LodePNGColorMode* info) +{ + return getNumColorChannels(info->colortype); +} + +unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info) +{ + return info->colortype == LCT_GREY || info->colortype == LCT_GREY_ALPHA; +} + +unsigned lodepng_is_alpha_type(const LodePNGColorMode* info) +{ + return (info->colortype & 4) != 0; /*4 or 6*/ +} + +unsigned lodepng_is_palette_type(const LodePNGColorMode* info) +{ + return info->colortype == LCT_PALETTE; +} + +unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info) +{ + size_t i; + for(i = 0; i != info->palettesize; ++i) + { + if(info->palette[i * 4 + 3] < 255) return 1; + } + return 0; +} + +unsigned lodepng_can_have_alpha(const LodePNGColorMode* info) +{ + return info->key_defined + || lodepng_is_alpha_type(info) + || lodepng_has_palette_alpha(info); +} + +size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color) +{ + /*will not overflow for any color type if roughly w * h < 268435455*/ + size_t bpp = lodepng_get_bpp(color); + size_t n = w * h; + return ((n / 8) * bpp) + ((n & 7) * bpp + 7) / 8; +} + +size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) +{ + /*will not overflow for any color type if roughly w * h < 268435455*/ + size_t bpp = lodepng_get_bpp_lct(colortype, bitdepth); + size_t n = w * h; + return ((n / 8) * bpp) + ((n & 7) * bpp + 7) / 8; +} + + +#ifdef LODEPNG_COMPILE_PNG +#ifdef LODEPNG_COMPILE_DECODER +/*in an idat chunk, each scanline is a multiple of 8 bits, unlike the lodepng output buffer*/ +static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, const LodePNGColorMode* color) +{ + /*will not overflow for any color type if roughly w * h < 268435455*/ + size_t bpp = lodepng_get_bpp(color); + size_t line = ((w / 8) * bpp) + ((w & 7) * bpp + 7) / 8; + return h * line; +} +#endif /*LODEPNG_COMPILE_DECODER*/ +#endif /*LODEPNG_COMPILE_PNG*/ + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + +static void LodePNGUnknownChunks_init(LodePNGInfo* info) +{ + unsigned i; + for(i = 0; i != 3; ++i) info->unknown_chunks_data[i] = 0; + for(i = 0; i != 3; ++i) info->unknown_chunks_size[i] = 0; +} + +static void LodePNGUnknownChunks_cleanup(LodePNGInfo* info) +{ + unsigned i; + for(i = 0; i != 3; ++i) lodepng_free(info->unknown_chunks_data[i]); +} + +static unsigned LodePNGUnknownChunks_copy(LodePNGInfo* dest, const LodePNGInfo* src) +{ + unsigned i; + + LodePNGUnknownChunks_cleanup(dest); + + for(i = 0; i != 3; ++i) + { + size_t j; + dest->unknown_chunks_size[i] = src->unknown_chunks_size[i]; + dest->unknown_chunks_data[i] = (unsigned char*)lodepng_malloc(src->unknown_chunks_size[i]); + if(!dest->unknown_chunks_data[i] && dest->unknown_chunks_size[i]) return 83; /*alloc fail*/ + for(j = 0; j < src->unknown_chunks_size[i]; ++j) + { + dest->unknown_chunks_data[i][j] = src->unknown_chunks_data[i][j]; + } + } + + return 0; +} + +/******************************************************************************/ + +static void LodePNGText_init(LodePNGInfo* info) +{ + info->text_num = 0; + info->text_keys = NULL; + info->text_strings = NULL; +} + +static void LodePNGText_cleanup(LodePNGInfo* info) +{ + size_t i; + for(i = 0; i != info->text_num; ++i) + { + string_cleanup(&info->text_keys[i]); + string_cleanup(&info->text_strings[i]); + } + lodepng_free(info->text_keys); + lodepng_free(info->text_strings); +} + +static unsigned LodePNGText_copy(LodePNGInfo* dest, const LodePNGInfo* source) +{ + size_t i = 0; + dest->text_keys = 0; + dest->text_strings = 0; + dest->text_num = 0; + for(i = 0; i != source->text_num; ++i) + { + CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i])); + } + return 0; +} + +void lodepng_clear_text(LodePNGInfo* info) +{ + LodePNGText_cleanup(info); +} + +unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str) +{ + char** new_keys = (char**)(lodepng_realloc(info->text_keys, sizeof(char*) * (info->text_num + 1))); + char** new_strings = (char**)(lodepng_realloc(info->text_strings, sizeof(char*) * (info->text_num + 1))); + if(!new_keys || !new_strings) + { + lodepng_free(new_keys); + lodepng_free(new_strings); + return 83; /*alloc fail*/ + } + + ++info->text_num; + info->text_keys = new_keys; + info->text_strings = new_strings; + + string_init(&info->text_keys[info->text_num - 1]); + string_set(&info->text_keys[info->text_num - 1], key); + + string_init(&info->text_strings[info->text_num - 1]); + string_set(&info->text_strings[info->text_num - 1], str); + + return 0; +} + +/******************************************************************************/ + +static void LodePNGIText_init(LodePNGInfo* info) +{ + info->itext_num = 0; + info->itext_keys = NULL; + info->itext_langtags = NULL; + info->itext_transkeys = NULL; + info->itext_strings = NULL; +} + +static void LodePNGIText_cleanup(LodePNGInfo* info) +{ + size_t i; + for(i = 0; i != info->itext_num; ++i) + { + string_cleanup(&info->itext_keys[i]); + string_cleanup(&info->itext_langtags[i]); + string_cleanup(&info->itext_transkeys[i]); + string_cleanup(&info->itext_strings[i]); + } + lodepng_free(info->itext_keys); + lodepng_free(info->itext_langtags); + lodepng_free(info->itext_transkeys); + lodepng_free(info->itext_strings); +} + +static unsigned LodePNGIText_copy(LodePNGInfo* dest, const LodePNGInfo* source) +{ + size_t i = 0; + dest->itext_keys = 0; + dest->itext_langtags = 0; + dest->itext_transkeys = 0; + dest->itext_strings = 0; + dest->itext_num = 0; + for(i = 0; i != source->itext_num; ++i) + { + CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i], + source->itext_transkeys[i], source->itext_strings[i])); + } + return 0; +} + +void lodepng_clear_itext(LodePNGInfo* info) +{ + LodePNGIText_cleanup(info); +} + +unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, + const char* transkey, const char* str) +{ + char** new_keys = (char**)(lodepng_realloc(info->itext_keys, sizeof(char*) * (info->itext_num + 1))); + char** new_langtags = (char**)(lodepng_realloc(info->itext_langtags, sizeof(char*) * (info->itext_num + 1))); + char** new_transkeys = (char**)(lodepng_realloc(info->itext_transkeys, sizeof(char*) * (info->itext_num + 1))); + char** new_strings = (char**)(lodepng_realloc(info->itext_strings, sizeof(char*) * (info->itext_num + 1))); + if(!new_keys || !new_langtags || !new_transkeys || !new_strings) + { + lodepng_free(new_keys); + lodepng_free(new_langtags); + lodepng_free(new_transkeys); + lodepng_free(new_strings); + return 83; /*alloc fail*/ + } + + ++info->itext_num; + info->itext_keys = new_keys; + info->itext_langtags = new_langtags; + info->itext_transkeys = new_transkeys; + info->itext_strings = new_strings; + + string_init(&info->itext_keys[info->itext_num - 1]); + string_set(&info->itext_keys[info->itext_num - 1], key); + + string_init(&info->itext_langtags[info->itext_num - 1]); + string_set(&info->itext_langtags[info->itext_num - 1], langtag); + + string_init(&info->itext_transkeys[info->itext_num - 1]); + string_set(&info->itext_transkeys[info->itext_num - 1], transkey); + + string_init(&info->itext_strings[info->itext_num - 1]); + string_set(&info->itext_strings[info->itext_num - 1], str); + + return 0; +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +void lodepng_info_init(LodePNGInfo* info) +{ + lodepng_color_mode_init(&info->color); + info->interlace_method = 0; + info->compression_method = 0; + info->filter_method = 0; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + info->background_defined = 0; + info->background_r = info->background_g = info->background_b = 0; + + LodePNGText_init(info); + LodePNGIText_init(info); + + info->time_defined = 0; + info->phys_defined = 0; + + LodePNGUnknownChunks_init(info); +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} + +void lodepng_info_cleanup(LodePNGInfo* info) +{ + lodepng_color_mode_cleanup(&info->color); +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + LodePNGText_cleanup(info); + LodePNGIText_cleanup(info); + + LodePNGUnknownChunks_cleanup(info); +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} + +unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source) +{ + lodepng_info_cleanup(dest); + *dest = *source; + lodepng_color_mode_init(&dest->color); + CERROR_TRY_RETURN(lodepng_color_mode_copy(&dest->color, &source->color)); + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + CERROR_TRY_RETURN(LodePNGText_copy(dest, source)); + CERROR_TRY_RETURN(LodePNGIText_copy(dest, source)); + + LodePNGUnknownChunks_init(dest); + CERROR_TRY_RETURN(LodePNGUnknownChunks_copy(dest, source)); +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + return 0; +} + +void lodepng_info_swap(LodePNGInfo* a, LodePNGInfo* b) +{ + LodePNGInfo temp = *a; + *a = *b; + *b = temp; +} + +/* ////////////////////////////////////////////////////////////////////////// */ + +/*index: bitgroup index, bits: bitgroup size(1, 2 or 4), in: bitgroup value, out: octet array to add bits to*/ +static void addColorBits(unsigned char* out, size_t index, unsigned bits, unsigned in) +{ + unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1; /*8 / bits - 1*/ + /*p = the partial index in the byte, e.g. with 4 palettebits it is 0 for first half or 1 for second half*/ + unsigned p = index & m; + in &= (1u << bits) - 1u; /*filter out any other bits of the input value*/ + in = in << (bits * (m - p)); + if(p == 0) out[index * bits / 8] = in; + else out[index * bits / 8] |= in; +} + +typedef struct ColorTree ColorTree; + +/* +One node of a color tree +This is the data structure used to count the number of unique colors and to get a palette +index for a color. It's like an octree, but because the alpha channel is used too, each +node has 16 instead of 8 children. +*/ +struct ColorTree +{ + ColorTree* children[16]; /*up to 16 pointers to ColorTree of next level*/ + int index; /*the payload. Only has a meaningful value if this is in the last level*/ +}; + +static void color_tree_init(ColorTree* tree) +{ + int i; + for(i = 0; i != 16; ++i) tree->children[i] = 0; + tree->index = -1; +} + +static void color_tree_cleanup(ColorTree* tree) +{ + int i; + for(i = 0; i != 16; ++i) + { + if(tree->children[i]) + { + color_tree_cleanup(tree->children[i]); + lodepng_free(tree->children[i]); + } + } +} + +/*returns -1 if color not present, its index otherwise*/ +static int color_tree_get(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + int bit = 0; + for(bit = 0; bit < 8; ++bit) + { + int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); + if(!tree->children[i]) return -1; + else tree = tree->children[i]; + } + return tree ? tree->index : -1; +} + +#ifdef LODEPNG_COMPILE_ENCODER +static int color_tree_has(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + return color_tree_get(tree, r, g, b, a) >= 0; +} +#endif /*LODEPNG_COMPILE_ENCODER*/ + +/*color is not allowed to already exist. +Index should be >= 0 (it's signed to be compatible with using -1 for "doesn't exist")*/ +static void color_tree_add(ColorTree* tree, + unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned index) +{ + int bit; + for(bit = 0; bit < 8; ++bit) + { + int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); + if(!tree->children[i]) + { + tree->children[i] = (ColorTree*)lodepng_malloc(sizeof(ColorTree)); + color_tree_init(tree->children[i]); + } + tree = tree->children[i]; + } + tree->index = (int)index; +} + +/*put a pixel, given its RGBA color, into image of any color type*/ +static unsigned rgba8ToPixel(unsigned char* out, size_t i, + const LodePNGColorMode* mode, ColorTree* tree /*for palette*/, + unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + if(mode->colortype == LCT_GREY) + { + unsigned char grey = r; /*((unsigned short)r + g + b) / 3*/; + if(mode->bitdepth == 8) out[i] = grey; + else if(mode->bitdepth == 16) out[i * 2 + 0] = out[i * 2 + 1] = grey; + else + { + /*take the most significant bits of grey*/ + grey = (grey >> (8 - mode->bitdepth)) & ((1 << mode->bitdepth) - 1); + addColorBits(out, i, mode->bitdepth, grey); + } + } + else if(mode->colortype == LCT_RGB) + { + if(mode->bitdepth == 8) + { + out[i * 3 + 0] = r; + out[i * 3 + 1] = g; + out[i * 3 + 2] = b; + } + else + { + out[i * 6 + 0] = out[i * 6 + 1] = r; + out[i * 6 + 2] = out[i * 6 + 3] = g; + out[i * 6 + 4] = out[i * 6 + 5] = b; + } + } + else if(mode->colortype == LCT_PALETTE) + { + int index = color_tree_get(tree, r, g, b, a); + if(index < 0) return 82; /*color not in palette*/ + if(mode->bitdepth == 8) out[i] = index; + else addColorBits(out, i, mode->bitdepth, (unsigned)index); + } + else if(mode->colortype == LCT_GREY_ALPHA) + { + unsigned char grey = r; /*((unsigned short)r + g + b) / 3*/; + if(mode->bitdepth == 8) + { + out[i * 2 + 0] = grey; + out[i * 2 + 1] = a; + } + else if(mode->bitdepth == 16) + { + out[i * 4 + 0] = out[i * 4 + 1] = grey; + out[i * 4 + 2] = out[i * 4 + 3] = a; + } + } + else if(mode->colortype == LCT_RGBA) + { + if(mode->bitdepth == 8) + { + out[i * 4 + 0] = r; + out[i * 4 + 1] = g; + out[i * 4 + 2] = b; + out[i * 4 + 3] = a; + } + else + { + out[i * 8 + 0] = out[i * 8 + 1] = r; + out[i * 8 + 2] = out[i * 8 + 3] = g; + out[i * 8 + 4] = out[i * 8 + 5] = b; + out[i * 8 + 6] = out[i * 8 + 7] = a; + } + } + + return 0; /*no error*/ +} + +/*put a pixel, given its RGBA16 color, into image of any color 16-bitdepth type*/ +static void rgba16ToPixel(unsigned char* out, size_t i, + const LodePNGColorMode* mode, + unsigned short r, unsigned short g, unsigned short b, unsigned short a) +{ + if(mode->colortype == LCT_GREY) + { + unsigned short grey = r; /*((unsigned)r + g + b) / 3*/; + out[i * 2 + 0] = (grey >> 8) & 255; + out[i * 2 + 1] = grey & 255; + } + else if(mode->colortype == LCT_RGB) + { + out[i * 6 + 0] = (r >> 8) & 255; + out[i * 6 + 1] = r & 255; + out[i * 6 + 2] = (g >> 8) & 255; + out[i * 6 + 3] = g & 255; + out[i * 6 + 4] = (b >> 8) & 255; + out[i * 6 + 5] = b & 255; + } + else if(mode->colortype == LCT_GREY_ALPHA) + { + unsigned short grey = r; /*((unsigned)r + g + b) / 3*/; + out[i * 4 + 0] = (grey >> 8) & 255; + out[i * 4 + 1] = grey & 255; + out[i * 4 + 2] = (a >> 8) & 255; + out[i * 4 + 3] = a & 255; + } + else if(mode->colortype == LCT_RGBA) + { + out[i * 8 + 0] = (r >> 8) & 255; + out[i * 8 + 1] = r & 255; + out[i * 8 + 2] = (g >> 8) & 255; + out[i * 8 + 3] = g & 255; + out[i * 8 + 4] = (b >> 8) & 255; + out[i * 8 + 5] = b & 255; + out[i * 8 + 6] = (a >> 8) & 255; + out[i * 8 + 7] = a & 255; + } +} + +/*Get RGBA8 color of pixel with index i (y * width + x) from the raw image with given color type.*/ +static void getPixelColorRGBA8(unsigned char* r, unsigned char* g, + unsigned char* b, unsigned char* a, + const unsigned char* in, size_t i, + const LodePNGColorMode* mode) +{ + if(mode->colortype == LCT_GREY) + { + if(mode->bitdepth == 8) + { + *r = *g = *b = in[i]; + if(mode->key_defined && *r == mode->key_r) *a = 0; + else *a = 255; + } + else if(mode->bitdepth == 16) + { + *r = *g = *b = in[i * 2 + 0]; + if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; + else *a = 255; + } + else + { + unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ + size_t j = i * mode->bitdepth; + unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); + *r = *g = *b = (value * 255) / highest; + if(mode->key_defined && value == mode->key_r) *a = 0; + else *a = 255; + } + } + else if(mode->colortype == LCT_RGB) + { + if(mode->bitdepth == 8) + { + *r = in[i * 3 + 0]; *g = in[i * 3 + 1]; *b = in[i * 3 + 2]; + if(mode->key_defined && *r == mode->key_r && *g == mode->key_g && *b == mode->key_b) *a = 0; + else *a = 255; + } + else + { + *r = in[i * 6 + 0]; + *g = in[i * 6 + 2]; + *b = in[i * 6 + 4]; + if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r + && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g + && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; + else *a = 255; + } + } + else if(mode->colortype == LCT_PALETTE) + { + unsigned index; + if(mode->bitdepth == 8) index = in[i]; + else + { + size_t j = i * mode->bitdepth; + index = readBitsFromReversedStream(&j, in, mode->bitdepth); + } + + if(index >= mode->palettesize) + { + /*This is an error according to the PNG spec, but common PNG decoders make it black instead. + Done here too, slightly faster due to no error handling needed.*/ + *r = *g = *b = 0; + *a = 255; + } + else + { + *r = mode->palette[index * 4 + 0]; + *g = mode->palette[index * 4 + 1]; + *b = mode->palette[index * 4 + 2]; + *a = mode->palette[index * 4 + 3]; + } + } + else if(mode->colortype == LCT_GREY_ALPHA) + { + if(mode->bitdepth == 8) + { + *r = *g = *b = in[i * 2 + 0]; + *a = in[i * 2 + 1]; + } + else + { + *r = *g = *b = in[i * 4 + 0]; + *a = in[i * 4 + 2]; + } + } + else if(mode->colortype == LCT_RGBA) + { + if(mode->bitdepth == 8) + { + *r = in[i * 4 + 0]; + *g = in[i * 4 + 1]; + *b = in[i * 4 + 2]; + *a = in[i * 4 + 3]; + } + else + { + *r = in[i * 8 + 0]; + *g = in[i * 8 + 2]; + *b = in[i * 8 + 4]; + *a = in[i * 8 + 6]; + } + } +} + +/*Similar to getPixelColorRGBA8, but with all the for loops inside of the color +mode test cases, optimized to convert the colors much faster, when converting +to RGBA or RGB with 8 bit per cannel. buffer must be RGBA or RGB output with +enough memory, if has_alpha is true the output is RGBA. mode has the color mode +of the input buffer.*/ +static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, + unsigned has_alpha, const unsigned char* in, + const LodePNGColorMode* mode) +{ + unsigned num_channels = has_alpha ? 4 : 3; + size_t i; + if(mode->colortype == LCT_GREY) + { + if(mode->bitdepth == 8) + { + for(i = 0; i != numpixels; ++i, buffer += num_channels) + { + buffer[0] = buffer[1] = buffer[2] = in[i]; + if(has_alpha) buffer[3] = mode->key_defined && in[i] == mode->key_r ? 0 : 255; + } + } + else if(mode->bitdepth == 16) + { + for(i = 0; i != numpixels; ++i, buffer += num_channels) + { + buffer[0] = buffer[1] = buffer[2] = in[i * 2]; + if(has_alpha) buffer[3] = mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r ? 0 : 255; + } + } + else + { + unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ + size_t j = 0; + for(i = 0; i != numpixels; ++i, buffer += num_channels) + { + unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); + buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest; + if(has_alpha) buffer[3] = mode->key_defined && value == mode->key_r ? 0 : 255; + } + } + } + else if(mode->colortype == LCT_RGB) + { + if(mode->bitdepth == 8) + { + for(i = 0; i != numpixels; ++i, buffer += num_channels) + { + buffer[0] = in[i * 3 + 0]; + buffer[1] = in[i * 3 + 1]; + buffer[2] = in[i * 3 + 2]; + if(has_alpha) buffer[3] = mode->key_defined && buffer[0] == mode->key_r + && buffer[1]== mode->key_g && buffer[2] == mode->key_b ? 0 : 255; + } + } + else + { + for(i = 0; i != numpixels; ++i, buffer += num_channels) + { + buffer[0] = in[i * 6 + 0]; + buffer[1] = in[i * 6 + 2]; + buffer[2] = in[i * 6 + 4]; + if(has_alpha) buffer[3] = mode->key_defined + && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r + && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g + && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b ? 0 : 255; + } + } + } + else if(mode->colortype == LCT_PALETTE) + { + unsigned index; + size_t j = 0; + for(i = 0; i != numpixels; ++i, buffer += num_channels) + { + if(mode->bitdepth == 8) index = in[i]; + else index = readBitsFromReversedStream(&j, in, mode->bitdepth); + + if(index >= mode->palettesize) + { + /*This is an error according to the PNG spec, but most PNG decoders make it black instead. + Done here too, slightly faster due to no error handling needed.*/ + buffer[0] = buffer[1] = buffer[2] = 0; + if(has_alpha) buffer[3] = 255; + } + else + { + buffer[0] = mode->palette[index * 4 + 0]; + buffer[1] = mode->palette[index * 4 + 1]; + buffer[2] = mode->palette[index * 4 + 2]; + if(has_alpha) buffer[3] = mode->palette[index * 4 + 3]; + } + } + } + else if(mode->colortype == LCT_GREY_ALPHA) + { + if(mode->bitdepth == 8) + { + for(i = 0; i != numpixels; ++i, buffer += num_channels) + { + buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0]; + if(has_alpha) buffer[3] = in[i * 2 + 1]; + } + } + else + { + for(i = 0; i != numpixels; ++i, buffer += num_channels) + { + buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0]; + if(has_alpha) buffer[3] = in[i * 4 + 2]; + } + } + } + else if(mode->colortype == LCT_RGBA) + { + if(mode->bitdepth == 8) + { + for(i = 0; i != numpixels; ++i, buffer += num_channels) + { + buffer[0] = in[i * 4 + 0]; + buffer[1] = in[i * 4 + 1]; + buffer[2] = in[i * 4 + 2]; + if(has_alpha) buffer[3] = in[i * 4 + 3]; + } + } + else + { + for(i = 0; i != numpixels; ++i, buffer += num_channels) + { + buffer[0] = in[i * 8 + 0]; + buffer[1] = in[i * 8 + 2]; + buffer[2] = in[i * 8 + 4]; + if(has_alpha) buffer[3] = in[i * 8 + 6]; + } + } + } +} + +/*Get RGBA16 color of pixel with index i (y * width + x) from the raw image with +given color type, but the given color type must be 16-bit itself.*/ +static void getPixelColorRGBA16(unsigned short* r, unsigned short* g, unsigned short* b, unsigned short* a, + const unsigned char* in, size_t i, const LodePNGColorMode* mode) +{ + if(mode->colortype == LCT_GREY) + { + *r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1]; + if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; + else *a = 65535; + } + else if(mode->colortype == LCT_RGB) + { + *r = 256u * in[i * 6 + 0] + in[i * 6 + 1]; + *g = 256u * in[i * 6 + 2] + in[i * 6 + 3]; + *b = 256u * in[i * 6 + 4] + in[i * 6 + 5]; + if(mode->key_defined + && 256u * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r + && 256u * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g + && 256u * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; + else *a = 65535; + } + else if(mode->colortype == LCT_GREY_ALPHA) + { + *r = *g = *b = 256u * in[i * 4 + 0] + in[i * 4 + 1]; + *a = 256u * in[i * 4 + 2] + in[i * 4 + 3]; + } + else if(mode->colortype == LCT_RGBA) + { + *r = 256u * in[i * 8 + 0] + in[i * 8 + 1]; + *g = 256u * in[i * 8 + 2] + in[i * 8 + 3]; + *b = 256u * in[i * 8 + 4] + in[i * 8 + 5]; + *a = 256u * in[i * 8 + 6] + in[i * 8 + 7]; + } +} + +unsigned lodepng_convert(unsigned char* out, const unsigned char* in, + const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, + unsigned w, unsigned h) +{ + size_t i; + ColorTree tree; + size_t numpixels = w * h; + + if(lodepng_color_mode_equal(mode_out, mode_in)) + { + size_t numbytes = lodepng_get_raw_size(w, h, mode_in); + for(i = 0; i != numbytes; ++i) out[i] = in[i]; + return 0; + } + + if(mode_out->colortype == LCT_PALETTE) + { + size_t palettesize = mode_out->palettesize; + const unsigned char* palette = mode_out->palette; + size_t palsize = 1u << mode_out->bitdepth; + /*if the user specified output palette but did not give the values, assume + they want the values of the input color type (assuming that one is palette). + Note that we never create a new palette ourselves.*/ + if(palettesize == 0) + { + palettesize = mode_in->palettesize; + palette = mode_in->palette; + } + if(palettesize < palsize) palsize = palettesize; + color_tree_init(&tree); + for(i = 0; i != palsize; ++i) + { + const unsigned char* p = &palette[i * 4]; + color_tree_add(&tree, p[0], p[1], p[2], p[3], i); + } + } + + if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16) + { + for(i = 0; i != numpixels; ++i) + { + unsigned short r = 0, g = 0, b = 0, a = 0; + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); + rgba16ToPixel(out, i, mode_out, r, g, b, a); + } + } + else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA) + { + getPixelColorsRGBA8(out, numpixels, 1, in, mode_in); + } + else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB) + { + getPixelColorsRGBA8(out, numpixels, 0, in, mode_in); + } + else + { + unsigned char r = 0, g = 0, b = 0, a = 0; + for(i = 0; i != numpixels; ++i) + { + getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); + CERROR_TRY_RETURN(rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a)); + } + } + + if(mode_out->colortype == LCT_PALETTE) + { + color_tree_cleanup(&tree); + } + + return 0; /*no error*/ +} + +#ifdef LODEPNG_COMPILE_ENCODER + +void lodepng_color_profile_init(LodePNGColorProfile* profile) +{ + profile->colored = 0; + profile->key = 0; + profile->alpha = 0; + profile->key_r = profile->key_g = profile->key_b = 0; + profile->numcolors = 0; + profile->bits = 1; +} + +/*function used for debug purposes with C++*/ +/*void printColorProfile(LodePNGColorProfile* p) +{ + std::cout << "colored: " << (int)p->colored << ", "; + std::cout << "key: " << (int)p->key << ", "; + std::cout << "key_r: " << (int)p->key_r << ", "; + std::cout << "key_g: " << (int)p->key_g << ", "; + std::cout << "key_b: " << (int)p->key_b << ", "; + std::cout << "alpha: " << (int)p->alpha << ", "; + std::cout << "numcolors: " << (int)p->numcolors << ", "; + std::cout << "bits: " << (int)p->bits << std::endl; +}*/ + +/*Returns how many bits needed to represent given value (max 8 bit)*/ +static unsigned getValueRequiredBits(unsigned char value) +{ + if(value == 0 || value == 255) return 1; + /*The scaling of 2-bit and 4-bit values uses multiples of 85 and 17*/ + if(value % 17 == 0) return value % 85 == 0 ? 2 : 4; + return 8; +} + +/*profile must already have been inited with mode. +It's ok to set some parameters of profile to done already.*/ +unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, + const unsigned char* in, unsigned w, unsigned h, + const LodePNGColorMode* mode) +{ + unsigned error = 0; + size_t i; + ColorTree tree; + size_t numpixels = w * h; + + unsigned colored_done = lodepng_is_greyscale_type(mode) ? 1 : 0; + unsigned alpha_done = lodepng_can_have_alpha(mode) ? 0 : 1; + unsigned numcolors_done = 0; + unsigned bpp = lodepng_get_bpp(mode); + unsigned bits_done = bpp == 1 ? 1 : 0; + unsigned maxnumcolors = 257; + unsigned sixteen = 0; + if(bpp <= 8) maxnumcolors = bpp == 1 ? 2 : (bpp == 2 ? 4 : (bpp == 4 ? 16 : 256)); + + color_tree_init(&tree); + + /*Check if the 16-bit input is truly 16-bit*/ + if(mode->bitdepth == 16) + { + unsigned short r, g, b, a; + for(i = 0; i != numpixels; ++i) + { + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); + if((r & 255) != ((r >> 8) & 255) || (g & 255) != ((g >> 8) & 255) || + (b & 255) != ((b >> 8) & 255) || (a & 255) != ((a >> 8) & 255)) /*first and second byte differ*/ + { + sixteen = 1; + break; + } + } + } + + if(sixteen) + { + unsigned short r = 0, g = 0, b = 0, a = 0; + profile->bits = 16; + bits_done = numcolors_done = 1; /*counting colors no longer useful, palette doesn't support 16-bit*/ + + for(i = 0; i != numpixels; ++i) + { + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); + + if(!colored_done && (r != g || r != b)) + { + profile->colored = 1; + colored_done = 1; + } + + if(!alpha_done) + { + unsigned matchkey = (r == profile->key_r && g == profile->key_g && b == profile->key_b); + if(a != 65535 && (a != 0 || (profile->key && !matchkey))) + { + profile->alpha = 1; + alpha_done = 1; + if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + else if(a == 0 && !profile->alpha && !profile->key) + { + profile->key = 1; + profile->key_r = r; + profile->key_g = g; + profile->key_b = b; + } + else if(a == 65535 && profile->key && matchkey) + { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + profile->alpha = 1; + alpha_done = 1; + } + } + if(alpha_done && numcolors_done && colored_done && bits_done) break; + } + + if(profile->key && !profile->alpha) + { + for(i = 0; i != numpixels; ++i) + { + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); + if(a != 0 && r == profile->key_r && g == profile->key_g && b == profile->key_b) + { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + profile->alpha = 1; + alpha_done = 1; + } + } + } + } + else /* < 16-bit */ + { + unsigned char r = 0, g = 0, b = 0, a = 0; + for(i = 0; i != numpixels; ++i) + { + getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode); + + if(!bits_done && profile->bits < 8) + { + /*only r is checked, < 8 bits is only relevant for greyscale*/ + unsigned bits = getValueRequiredBits(r); + if(bits > profile->bits) profile->bits = bits; + } + bits_done = (profile->bits >= bpp); + + if(!colored_done && (r != g || r != b)) + { + profile->colored = 1; + colored_done = 1; + if(profile->bits < 8) profile->bits = 8; /*PNG has no colored modes with less than 8-bit per channel*/ + } + + if(!alpha_done) + { + unsigned matchkey = (r == profile->key_r && g == profile->key_g && b == profile->key_b); + if(a != 255 && (a != 0 || (profile->key && !matchkey))) + { + profile->alpha = 1; + alpha_done = 1; + if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + else if(a == 0 && !profile->alpha && !profile->key) + { + profile->key = 1; + profile->key_r = r; + profile->key_g = g; + profile->key_b = b; + } + else if(a == 255 && profile->key && matchkey) + { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + profile->alpha = 1; + alpha_done = 1; + if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + } + + if(!numcolors_done) + { + if(!color_tree_has(&tree, r, g, b, a)) + { + color_tree_add(&tree, r, g, b, a, profile->numcolors); + if(profile->numcolors < 256) + { + unsigned char* p = profile->palette; + unsigned n = profile->numcolors; + p[n * 4 + 0] = r; + p[n * 4 + 1] = g; + p[n * 4 + 2] = b; + p[n * 4 + 3] = a; + } + ++profile->numcolors; + numcolors_done = profile->numcolors >= maxnumcolors; + } + } + + if(alpha_done && numcolors_done && colored_done && bits_done) break; + } + + if(profile->key && !profile->alpha) + { + for(i = 0; i != numpixels; ++i) + { + getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode); + if(a != 0 && r == profile->key_r && g == profile->key_g && b == profile->key_b) + { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + profile->alpha = 1; + alpha_done = 1; + } + } + } + + /*make the profile's key always 16-bit for consistency - repeat each byte twice*/ + profile->key_r += (profile->key_r << 8); + profile->key_g += (profile->key_g << 8); + profile->key_b += (profile->key_b << 8); + } + + color_tree_cleanup(&tree); + return error; +} + +/*Automatically chooses color type that gives smallest amount of bits in the +output image, e.g. grey if there are only greyscale pixels, palette if there +are less than 256 colors, ... +Updates values of mode with a potentially smaller color model. mode_out should +contain the user chosen color model, but will be overwritten with the new chosen one.*/ +unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, + const unsigned char* image, unsigned w, unsigned h, + const LodePNGColorMode* mode_in) +{ + LodePNGColorProfile prof; + unsigned error = 0; + unsigned i, n, palettebits, grey_ok, palette_ok; + + lodepng_color_profile_init(&prof); + error = lodepng_get_color_profile(&prof, image, w, h, mode_in); + if(error) return error; + mode_out->key_defined = 0; + + if(prof.key && w * h <= 16) + { + prof.alpha = 1; /*too few pixels to justify tRNS chunk overhead*/ + if(prof.bits < 8) prof.bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + grey_ok = !prof.colored && !prof.alpha; /*grey without alpha, with potentially low bits*/ + n = prof.numcolors; + palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8)); + palette_ok = n <= 256 && (n * 2 < w * h) && prof.bits <= 8; + if(w * h < n * 2) palette_ok = 0; /*don't add palette overhead if image has only a few pixels*/ + if(grey_ok && prof.bits <= palettebits) palette_ok = 0; /*grey is less overhead*/ + + if(palette_ok) + { + unsigned char* p = prof.palette; + lodepng_palette_clear(mode_out); /*remove potential earlier palette*/ + for(i = 0; i != prof.numcolors; ++i) + { + error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]); + if(error) break; + } + + mode_out->colortype = LCT_PALETTE; + mode_out->bitdepth = palettebits; + + if(mode_in->colortype == LCT_PALETTE && mode_in->palettesize >= mode_out->palettesize + && mode_in->bitdepth == mode_out->bitdepth) + { + /*If input should have same palette colors, keep original to preserve its order and prevent conversion*/ + lodepng_color_mode_cleanup(mode_out); + lodepng_color_mode_copy(mode_out, mode_in); + } + } + else /*8-bit or 16-bit per channel*/ + { + mode_out->bitdepth = prof.bits; + mode_out->colortype = prof.alpha ? (prof.colored ? LCT_RGBA : LCT_GREY_ALPHA) + : (prof.colored ? LCT_RGB : LCT_GREY); + + if(prof.key && !prof.alpha) + { + unsigned mask = (1u << mode_out->bitdepth) - 1u; /*profile always uses 16-bit, mask converts it*/ + mode_out->key_r = prof.key_r & mask; + mode_out->key_g = prof.key_g & mask; + mode_out->key_b = prof.key_b & mask; + mode_out->key_defined = 1; + } + } + + return error; +} + +#endif /* #ifdef LODEPNG_COMPILE_ENCODER */ + +/* +Paeth predicter, used by PNG filter type 4 +The parameters are of type short, but should come from unsigned chars, the shorts +are only needed to make the paeth calculation correct. +*/ +static unsigned char paethPredictor(short a, short b, short c) +{ + short pa = abs(b - c); + short pb = abs(a - c); + short pc = abs(a + b - c - c); + + if(pc < pa && pc < pb) return (unsigned char)c; + else if(pb < pa) return (unsigned char)b; + else return (unsigned char)a; +} + +/*shared values used by multiple Adam7 related functions*/ + +static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/ +static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/ +static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/ +static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/ + +/* +Outputs various dimensions and positions in the image related to the Adam7 reduced images. +passw: output containing the width of the 7 passes +passh: output containing the height of the 7 passes +filter_passstart: output containing the index of the start and end of each + reduced image with filter bytes +padded_passstart output containing the index of the start and end of each + reduced image when without filter bytes but with padded scanlines +passstart: output containing the index of the start and end of each reduced + image without padding between scanlines, but still padding between the images +w, h: width and height of non-interlaced image +bpp: bits per pixel +"padded" is only relevant if bpp is less than 8 and a scanline or image does not + end at a full byte +*/ +static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8], + size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp) +{ + /*the passstart values have 8 values: the 8th one indicates the byte after the end of the 7th (= last) pass*/ + unsigned i; + + /*calculate width and height in pixels of each pass*/ + for(i = 0; i != 7; ++i) + { + passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i]; + passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i]; + if(passw[i] == 0) passh[i] = 0; + if(passh[i] == 0) passw[i] = 0; + } + + filter_passstart[0] = padded_passstart[0] = passstart[0] = 0; + for(i = 0; i != 7; ++i) + { + /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/ + filter_passstart[i + 1] = filter_passstart[i] + + ((passw[i] && passh[i]) ? passh[i] * (1 + (passw[i] * bpp + 7) / 8) : 0); + /*bits padded if needed to fill full byte at end of each scanline*/ + padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7) / 8); + /*only padded at end of reduced image*/ + passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7) / 8; + } +} + +#ifdef LODEPNG_COMPILE_DECODER + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / PNG Decoder / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*read the information from the header and store it in the LodePNGInfo. return value is error*/ +unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, + const unsigned char* in, size_t insize) +{ + LodePNGInfo* info = &state->info_png; + if(insize == 0 || in == 0) + { + CERROR_RETURN_ERROR(state->error, 48); /*error: the given data is empty*/ + } + if(insize < 33) + { + CERROR_RETURN_ERROR(state->error, 27); /*error: the data length is smaller than the length of a PNG header*/ + } + + /*when decoding a new PNG image, make sure all parameters created after previous decoding are reset*/ + lodepng_info_cleanup(info); + lodepng_info_init(info); + + if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 + || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) + { + CERROR_RETURN_ERROR(state->error, 28); /*error: the first 8 bytes are not the correct PNG signature*/ + } + if(lodepng_chunk_length(in + 8) != 13) + { + CERROR_RETURN_ERROR(state->error, 94); /*error: header size must be 13 bytes*/ + } + if(!lodepng_chunk_type_equals(in + 8, "IHDR")) + { + CERROR_RETURN_ERROR(state->error, 29); /*error: it doesn't start with a IHDR chunk!*/ + } + + /*read the values given in the header*/ + *w = lodepng_read32bitInt(&in[16]); + *h = lodepng_read32bitInt(&in[20]); + info->color.bitdepth = in[24]; + info->color.colortype = (LodePNGColorType)in[25]; + info->compression_method = in[26]; + info->filter_method = in[27]; + info->interlace_method = in[28]; + + if(*w == 0 || *h == 0) + { + CERROR_RETURN_ERROR(state->error, 93); + } + + if(!state->decoder.ignore_crc) + { + unsigned CRC = lodepng_read32bitInt(&in[29]); + unsigned checksum = lodepng_crc32(&in[12], 17); + if(CRC != checksum) + { + CERROR_RETURN_ERROR(state->error, 57); /*invalid CRC*/ + } + } + + /*error: only compression method 0 is allowed in the specification*/ + if(info->compression_method != 0) CERROR_RETURN_ERROR(state->error, 32); + /*error: only filter method 0 is allowed in the specification*/ + if(info->filter_method != 0) CERROR_RETURN_ERROR(state->error, 33); + /*error: only interlace methods 0 and 1 exist in the specification*/ + if(info->interlace_method > 1) CERROR_RETURN_ERROR(state->error, 34); + + state->error = checkColorValidity(info->color.colortype, info->color.bitdepth); + return state->error; +} + +static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, + size_t bytewidth, unsigned char filterType, size_t length) +{ + /* + For PNG filter method 0 + unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte, + the filter works byte per byte (bytewidth = 1) + precon is the previous unfiltered scanline, recon the result, scanline the current one + the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead + recon and scanline MAY be the same memory address! precon must be disjoint. + */ + + size_t i; + switch(filterType) + { + case 0: + for(i = 0; i != length; ++i) recon[i] = scanline[i]; + break; + case 1: + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth]; + break; + case 2: + if(precon) + { + for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i]; + } + else + { + for(i = 0; i != length; ++i) recon[i] = scanline[i]; + } + break; + case 3: + if(precon) + { + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1); + for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1); + } + else + { + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1); + } + break; + case 4: + if(precon) + { + for(i = 0; i != bytewidth; ++i) + { + recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ + } + for(i = bytewidth; i < length; ++i) + { + recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])); + } + } + else + { + for(i = 0; i != bytewidth; ++i) + { + recon[i] = scanline[i]; + } + for(i = bytewidth; i < length; ++i) + { + /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/ + recon[i] = (scanline[i] + recon[i - bytewidth]); + } + } + break; + default: return 36; /*error: unexisting filter type given*/ + } + return 0; +} + +static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) +{ + /* + For PNG filter method 0 + this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 seven times) + out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline + w and h are image dimensions or dimensions of reduced image, bpp is bits per pixel + in and out are allowed to be the same memory address (but aren't the same size since in has the extra filter bytes) + */ + + unsigned y; + unsigned char* prevline = 0; + + /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ + size_t bytewidth = (bpp + 7) / 8; + size_t linebytes = (w * bpp + 7) / 8; + + for(y = 0; y < h; ++y) + { + size_t outindex = linebytes * y; + size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ + unsigned char filterType = in[inindex]; + + CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes)); + + prevline = &out[outindex]; + } + + return 0; +} + +/* +in: Adam7 interlaced image, with no padding bits between scanlines, but between + reduced images so that each reduced image starts at a byte. +out: the same pixels, but re-ordered so that they're now a non-interlaced image with size w*h +bpp: bits per pixel +out has the following size in bits: w * h * bpp. +in is possibly bigger due to padding bits between reduced images. +out must be big enough AND must be 0 everywhere if bpp < 8 in the current implementation +(because that's likely a little bit faster) +NOTE: comments about padding bits are only relevant if bpp < 8 +*/ +static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) +{ + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + + if(bpp >= 8) + { + for(i = 0; i != 7; ++i) + { + unsigned x, y, b; + size_t bytewidth = bpp / 8; + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) + { + size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth; + size_t pixeloutstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; + for(b = 0; b < bytewidth; ++b) + { + out[pixeloutstart + b] = in[pixelinstart + b]; + } + } + } + } + else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ + { + for(i = 0; i != 7; ++i) + { + unsigned x, y, b; + unsigned ilinebits = bpp * passw[i]; + unsigned olinebits = bpp * w; + size_t obp, ibp; /*bit pointers (for out and in buffer)*/ + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) + { + ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp); + obp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; + for(b = 0; b < bpp; ++b) + { + unsigned char bit = readBitFromReversedStream(&ibp, in); + /*note that this function assumes the out buffer is completely 0, use setBitOfReversedStream otherwise*/ + setBitOfReversedStream0(&obp, out, bit); + } + } + } + } +} + +static void removePaddingBits(unsigned char* out, const unsigned char* in, + size_t olinebits, size_t ilinebits, unsigned h) +{ + /* + After filtering there are still padding bits if scanlines have non multiple of 8 bit amounts. They need + to be removed (except at last scanline of (Adam7-reduced) image) before working with pure image buffers + for the Adam7 code, the color convert code and the output to the user. + in and out are allowed to be the same buffer, in may also be higher but still overlapping; in must + have >= ilinebits*h bits, out must have >= olinebits*h bits, olinebits must be <= ilinebits + also used to move bits after earlier such operations happened, e.g. in a sequence of reduced images from Adam7 + only useful if (ilinebits - olinebits) is a value in the range 1..7 + */ + unsigned y; + size_t diff = ilinebits - olinebits; + size_t ibp = 0, obp = 0; /*input and output bit pointers*/ + for(y = 0; y < h; ++y) + { + size_t x; + for(x = 0; x < olinebits; ++x) + { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + ibp += diff; + } +} + +/*out must be buffer big enough to contain full image, and in must contain the full decompressed data from +the IDAT chunks (with filter index bytes and possible padding bits) +return value is error*/ +static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, + unsigned w, unsigned h, const LodePNGInfo* info_png) +{ + /* + This function converts the filtered-padded-interlaced data into pure 2D image buffer with the PNG's colortype. + Steps: + *) if no Adam7: 1) unfilter 2) remove padding bits (= posible extra bits per scanline if bpp < 8) + *) if adam7: 1) 7x unfilter 2) 7x remove padding bits 3) Adam7_deinterlace + NOTE: the in buffer will be overwritten with intermediate data! + */ + unsigned bpp = lodepng_get_bpp(&info_png->color); + if(bpp == 0) return 31; /*error: invalid colortype*/ + + if(info_png->interlace_method == 0) + { + if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) + { + CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp)); + removePaddingBits(out, in, w * bpp, ((w * bpp + 7) / 8) * 8, h); + } + /*we can immediately filter into the out buffer, no other steps needed*/ + else CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp)); + } + else /*interlace_method is 1 (Adam7)*/ + { + unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + + for(i = 0; i != 7; ++i) + { + CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp)); + /*TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline, + move bytes instead of bits or move not at all*/ + if(bpp < 8) + { + /*remove padding bits in scanlines; after this there still may be padding + bits between the different reduced images: each reduced image still starts nicely at a byte*/ + removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp, + ((passw[i] * bpp + 7) / 8) * 8, passh[i]); + } + } + + Adam7_deinterlace(out, in, w, h, bpp); + } + + return 0; +} + +static unsigned readChunk_PLTE(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) +{ + unsigned pos = 0, i; + if(color->palette) lodepng_free(color->palette); + color->palettesize = chunkLength / 3; + color->palette = (unsigned char*)lodepng_malloc(4 * color->palettesize); + if(!color->palette && color->palettesize) + { + color->palettesize = 0; + return 83; /*alloc fail*/ + } + if(color->palettesize > 256) return 38; /*error: palette too big*/ + + for(i = 0; i != color->palettesize; ++i) + { + color->palette[4 * i + 0] = data[pos++]; /*R*/ + color->palette[4 * i + 1] = data[pos++]; /*G*/ + color->palette[4 * i + 2] = data[pos++]; /*B*/ + color->palette[4 * i + 3] = 255; /*alpha*/ + } + + return 0; /* OK */ +} + +static unsigned readChunk_tRNS(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) +{ + unsigned i; + if(color->colortype == LCT_PALETTE) + { + /*error: more alpha values given than there are palette entries*/ + if(chunkLength > color->palettesize) return 38; + + for(i = 0; i != chunkLength; ++i) color->palette[4 * i + 3] = data[i]; + } + else if(color->colortype == LCT_GREY) + { + /*error: this chunk must be 2 bytes for greyscale image*/ + if(chunkLength != 2) return 30; + + color->key_defined = 1; + color->key_r = color->key_g = color->key_b = 256u * data[0] + data[1]; + } + else if(color->colortype == LCT_RGB) + { + /*error: this chunk must be 6 bytes for RGB image*/ + if(chunkLength != 6) return 41; + + color->key_defined = 1; + color->key_r = 256u * data[0] + data[1]; + color->key_g = 256u * data[2] + data[3]; + color->key_b = 256u * data[4] + data[5]; + } + else return 42; /*error: tRNS chunk not allowed for other color models*/ + + return 0; /* OK */ +} + + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +/*background color chunk (bKGD)*/ +static unsigned readChunk_bKGD(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) +{ + if(info->color.colortype == LCT_PALETTE) + { + /*error: this chunk must be 1 byte for indexed color image*/ + if(chunkLength != 1) return 43; + + info->background_defined = 1; + info->background_r = info->background_g = info->background_b = data[0]; + } + else if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) + { + /*error: this chunk must be 2 bytes for greyscale image*/ + if(chunkLength != 2) return 44; + + info->background_defined = 1; + info->background_r = info->background_g = info->background_b = 256u * data[0] + data[1]; + } + else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) + { + /*error: this chunk must be 6 bytes for greyscale image*/ + if(chunkLength != 6) return 45; + + info->background_defined = 1; + info->background_r = 256u * data[0] + data[1]; + info->background_g = 256u * data[2] + data[3]; + info->background_b = 256u * data[4] + data[5]; + } + + return 0; /* OK */ +} + +/*text chunk (tEXt)*/ +static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) +{ + unsigned error = 0; + char *key = 0, *str = 0; + unsigned i; + + while(!error) /*not really a while loop, only used to break on error*/ + { + unsigned length, string2_begin; + + length = 0; + while(length < chunkLength && data[length] != 0) ++length; + /*even though it's not allowed by the standard, no error is thrown if + there's no null termination char, if the text is empty*/ + if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ + + key = (char*)lodepng_malloc(length + 1); + if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ + + key[length] = 0; + for(i = 0; i != length; ++i) key[i] = (char)data[i]; + + string2_begin = length + 1; /*skip keyword null terminator*/ + + length = chunkLength < string2_begin ? 0 : chunkLength - string2_begin; + str = (char*)lodepng_malloc(length + 1); + if(!str) CERROR_BREAK(error, 83); /*alloc fail*/ + + str[length] = 0; + for(i = 0; i != length; ++i) str[i] = (char)data[string2_begin + i]; + + error = lodepng_add_text(info, key, str); + + break; + } + + lodepng_free(key); + lodepng_free(str); + + return error; +} + +/*compressed text chunk (zTXt)*/ +static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings, + const unsigned char* data, size_t chunkLength) +{ + unsigned error = 0; + unsigned i; + + unsigned length, string2_begin; + char *key = 0; + ucvector decoded; + + ucvector_init(&decoded); + + while(!error) /*not really a while loop, only used to break on error*/ + { + for(length = 0; length < chunkLength && data[length] != 0; ++length) ; + if(length + 2 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ + if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ + + key = (char*)lodepng_malloc(length + 1); + if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ + + key[length] = 0; + for(i = 0; i != length; ++i) key[i] = (char)data[i]; + + if(data[length + 1] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ + + string2_begin = length + 2; + if(string2_begin > chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ + + length = chunkLength - string2_begin; + /*will fail if zlib error, e.g. if length is too small*/ + error = zlib_decompress(&decoded.data, &decoded.size, + (unsigned char*)(&data[string2_begin]), + length, zlibsettings); + if(error) break; + ucvector_push_back(&decoded, 0); + + error = lodepng_add_text(info, key, (char*)decoded.data); + + break; + } + + lodepng_free(key); + ucvector_cleanup(&decoded); + + return error; +} + +/*international text chunk (iTXt)*/ +static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings, + const unsigned char* data, size_t chunkLength) +{ + unsigned error = 0; + unsigned i; + + unsigned length, begin, compressed; + char *key = 0, *langtag = 0, *transkey = 0; + ucvector decoded; + ucvector_init(&decoded); + + while(!error) /*not really a while loop, only used to break on error*/ + { + /*Quick check if the chunk length isn't too small. Even without check + it'd still fail with other error checks below if it's too short. This just gives a different error code.*/ + if(chunkLength < 5) CERROR_BREAK(error, 30); /*iTXt chunk too short*/ + + /*read the key*/ + for(length = 0; length < chunkLength && data[length] != 0; ++length) ; + if(length + 3 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination char, corrupt?*/ + if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ + + key = (char*)lodepng_malloc(length + 1); + if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ + + key[length] = 0; + for(i = 0; i != length; ++i) key[i] = (char)data[i]; + + /*read the compression method*/ + compressed = data[length + 1]; + if(data[length + 2] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ + + /*even though it's not allowed by the standard, no error is thrown if + there's no null termination char, if the text is empty for the next 3 texts*/ + + /*read the langtag*/ + begin = length + 3; + length = 0; + for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length; + + langtag = (char*)lodepng_malloc(length + 1); + if(!langtag) CERROR_BREAK(error, 83); /*alloc fail*/ + + langtag[length] = 0; + for(i = 0; i != length; ++i) langtag[i] = (char)data[begin + i]; + + /*read the transkey*/ + begin += length + 1; + length = 0; + for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length; + + transkey = (char*)lodepng_malloc(length + 1); + if(!transkey) CERROR_BREAK(error, 83); /*alloc fail*/ + + transkey[length] = 0; + for(i = 0; i != length; ++i) transkey[i] = (char)data[begin + i]; + + /*read the actual text*/ + begin += length + 1; + + length = chunkLength < begin ? 0 : chunkLength - begin; + + if(compressed) + { + /*will fail if zlib error, e.g. if length is too small*/ + error = zlib_decompress(&decoded.data, &decoded.size, + (unsigned char*)(&data[begin]), + length, zlibsettings); + if(error) break; + if(decoded.allocsize < decoded.size) decoded.allocsize = decoded.size; + ucvector_push_back(&decoded, 0); + } + else + { + if(!ucvector_resize(&decoded, length + 1)) CERROR_BREAK(error, 83 /*alloc fail*/); + + decoded.data[length] = 0; + for(i = 0; i != length; ++i) decoded.data[i] = data[begin + i]; + } + + error = lodepng_add_itext(info, key, langtag, transkey, (char*)decoded.data); + + break; + } + + lodepng_free(key); + lodepng_free(langtag); + lodepng_free(transkey); + ucvector_cleanup(&decoded); + + return error; +} + +static unsigned readChunk_tIME(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) +{ + if(chunkLength != 7) return 73; /*invalid tIME chunk size*/ + + info->time_defined = 1; + info->time.year = 256u * data[0] + data[1]; + info->time.month = data[2]; + info->time.day = data[3]; + info->time.hour = data[4]; + info->time.minute = data[5]; + info->time.second = data[6]; + + return 0; /* OK */ +} + +static unsigned readChunk_pHYs(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) +{ + if(chunkLength != 9) return 74; /*invalid pHYs chunk size*/ + + info->phys_defined = 1; + info->phys_x = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3]; + info->phys_y = 16777216u * data[4] + 65536u * data[5] + 256u * data[6] + data[7]; + info->phys_unit = data[8]; + + return 0; /* OK */ +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +/*read a PNG, the result will be in the same color type as the PNG (hence "generic")*/ +static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, + LodePNGState* state, + const unsigned char* in, size_t insize) +{ + unsigned char IEND = 0; + const unsigned char* chunk; + size_t i; + ucvector idat; /*the data from idat chunks*/ + ucvector scanlines; + size_t predict; + size_t numpixels; + size_t outsize = 0; + + /*for unknown chunk order*/ + unsigned unknown = 0; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + unsigned critical_pos = 1; /*1 = after IHDR, 2 = after PLTE, 3 = after IDAT*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + + /*provide some proper output values if error will happen*/ + *out = 0; + + state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/ + if(state->error) return; + + numpixels = *w * *h; + + /*multiplication overflow*/ + if(*h != 0 && numpixels / *h != *w) CERROR_RETURN(state->error, 92); + /*multiplication overflow possible further below. Allows up to 2^31-1 pixel + bytes with 16-bit RGBA, the rest is room for filter bytes.*/ + if(numpixels > 268435455) CERROR_RETURN(state->error, 92); + + ucvector_init(&idat); + chunk = &in[33]; /*first byte of the first chunk after the header*/ + + /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. + IDAT data is put at the start of the in buffer*/ + while(!IEND && !state->error) + { + unsigned chunkLength; + const unsigned char* data; /*the data in the chunk*/ + + /*error: size of the in buffer too small to contain next chunk*/ + if((size_t)((chunk - in) + 12) > insize || chunk < in) CERROR_BREAK(state->error, 30); + + /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/ + chunkLength = lodepng_chunk_length(chunk); + /*error: chunk length larger than the max PNG chunk size*/ + if(chunkLength > 2147483647) CERROR_BREAK(state->error, 63); + + if((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in) + { + CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk*/ + } + + data = lodepng_chunk_data_const(chunk); + + /*IDAT chunk, containing compressed image data*/ + if(lodepng_chunk_type_equals(chunk, "IDAT")) + { + size_t oldsize = idat.size; + if(!ucvector_resize(&idat, oldsize + chunkLength)) CERROR_BREAK(state->error, 83 /*alloc fail*/); + for(i = 0; i != chunkLength; ++i) idat.data[oldsize + i] = data[i]; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + critical_pos = 3; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + } + /*IEND chunk*/ + else if(lodepng_chunk_type_equals(chunk, "IEND")) + { + IEND = 1; + } + /*palette chunk (PLTE)*/ + else if(lodepng_chunk_type_equals(chunk, "PLTE")) + { + state->error = readChunk_PLTE(&state->info_png.color, data, chunkLength); + if(state->error) break; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + critical_pos = 2; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + } + /*palette transparency chunk (tRNS)*/ + else if(lodepng_chunk_type_equals(chunk, "tRNS")) + { + state->error = readChunk_tRNS(&state->info_png.color, data, chunkLength); + if(state->error) break; + } +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*background color chunk (bKGD)*/ + else if(lodepng_chunk_type_equals(chunk, "bKGD")) + { + state->error = readChunk_bKGD(&state->info_png, data, chunkLength); + if(state->error) break; + } + /*text chunk (tEXt)*/ + else if(lodepng_chunk_type_equals(chunk, "tEXt")) + { + if(state->decoder.read_text_chunks) + { + state->error = readChunk_tEXt(&state->info_png, data, chunkLength); + if(state->error) break; + } + } + /*compressed text chunk (zTXt)*/ + else if(lodepng_chunk_type_equals(chunk, "zTXt")) + { + if(state->decoder.read_text_chunks) + { + state->error = readChunk_zTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); + if(state->error) break; + } + } + /*international text chunk (iTXt)*/ + else if(lodepng_chunk_type_equals(chunk, "iTXt")) + { + if(state->decoder.read_text_chunks) + { + state->error = readChunk_iTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); + if(state->error) break; + } + } + else if(lodepng_chunk_type_equals(chunk, "tIME")) + { + state->error = readChunk_tIME(&state->info_png, data, chunkLength); + if(state->error) break; + } + else if(lodepng_chunk_type_equals(chunk, "pHYs")) + { + state->error = readChunk_pHYs(&state->info_png, data, chunkLength); + if(state->error) break; + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + else /*it's not an implemented chunk type, so ignore it: skip over the data*/ + { + /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/ + if(!lodepng_chunk_ancillary(chunk)) CERROR_BREAK(state->error, 69); + + unknown = 1; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + if(state->decoder.remember_unknown_chunks) + { + state->error = lodepng_chunk_append(&state->info_png.unknown_chunks_data[critical_pos - 1], + &state->info_png.unknown_chunks_size[critical_pos - 1], chunk); + if(state->error) break; + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + } + + if(!state->decoder.ignore_crc && !unknown) /*check CRC if wanted, only on known chunk types*/ + { + if(lodepng_chunk_check_crc(chunk)) CERROR_BREAK(state->error, 57); /*invalid CRC*/ + } + + if(!IEND) chunk = lodepng_chunk_next_const(chunk); + } + + ucvector_init(&scanlines); + /*predict output size, to allocate exact size for output buffer to avoid more dynamic allocation. + If the decompressed size does not match the prediction, the image must be corrupt.*/ + if(state->info_png.interlace_method == 0) + { + /*The extra *h is added because this are the filter bytes every scanline starts with*/ + predict = lodepng_get_raw_size_idat(*w, *h, &state->info_png.color) + *h; + } + else + { + /*Adam-7 interlaced: predicted size is the sum of the 7 sub-images sizes*/ + const LodePNGColorMode* color = &state->info_png.color; + predict = 0; + predict += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, color) + ((*h + 7) >> 3); + if(*w > 4) predict += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, color) + ((*h + 7) >> 3); + predict += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, color) + ((*h + 3) >> 3); + if(*w > 2) predict += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, color) + ((*h + 3) >> 2); + predict += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, color) + ((*h + 1) >> 2); + if(*w > 1) predict += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, color) + ((*h + 1) >> 1); + predict += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, color) + ((*h + 0) >> 1); + } + if(!state->error && !ucvector_reserve(&scanlines, predict)) state->error = 83; /*alloc fail*/ + if(!state->error) + { + state->error = zlib_decompress(&scanlines.data, &scanlines.size, idat.data, + idat.size, &state->decoder.zlibsettings); + if(!state->error && scanlines.size != predict) state->error = 91; /*decompressed size doesn't match prediction*/ + } + ucvector_cleanup(&idat); + + if(!state->error) + { + outsize = lodepng_get_raw_size(*w, *h, &state->info_png.color); + *out = (unsigned char*)lodepng_malloc(outsize); + if(!*out) state->error = 83; /*alloc fail*/ + } + if(!state->error) + { + for(i = 0; i < outsize; i++) (*out)[i] = 0; + state->error = postProcessScanlines(*out, scanlines.data, *w, *h, &state->info_png); + } + ucvector_cleanup(&scanlines); +} + +unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, + LodePNGState* state, + const unsigned char* in, size_t insize) +{ + *out = 0; + decodeGeneric(out, w, h, state, in, insize); + if(state->error) return state->error; + if(!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color)) + { + /*same color type, no copying or converting of data needed*/ + /*store the info_png color settings on the info_raw so that the info_raw still reflects what colortype + the raw image has to the end user*/ + if(!state->decoder.color_convert) + { + state->error = lodepng_color_mode_copy(&state->info_raw, &state->info_png.color); + if(state->error) return state->error; + } + } + else + { + /*color conversion needed; sort of copy of the data*/ + unsigned char* data = *out; + size_t outsize; + + /*TODO: check if this works according to the statement in the documentation: "The converter can convert + from greyscale input color type, to 8-bit greyscale or greyscale with alpha"*/ + if(!(state->info_raw.colortype == LCT_RGB || state->info_raw.colortype == LCT_RGBA) + && !(state->info_raw.bitdepth == 8)) + { + return 56; /*unsupported color mode conversion*/ + } + + outsize = lodepng_get_raw_size(*w, *h, &state->info_raw); + *out = (unsigned char*)lodepng_malloc(outsize); + if(!(*out)) + { + state->error = 83; /*alloc fail*/ + } + else state->error = lodepng_convert(*out, data, &state->info_raw, + &state->info_png.color, *w, *h); + lodepng_free(data); + } + return state->error; +} + +unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, + size_t insize, LodePNGColorType colortype, unsigned bitdepth) +{ + unsigned error; + LodePNGState state; + lodepng_state_init(&state); + state.info_raw.colortype = colortype; + state.info_raw.bitdepth = bitdepth; + error = lodepng_decode(out, w, h, &state, in, insize); + lodepng_state_cleanup(&state); + return error; +} + +unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) +{ + return lodepng_decode_memory(out, w, h, in, insize, LCT_RGBA, 8); +} + +unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) +{ + return lodepng_decode_memory(out, w, h, in, insize, LCT_RGB, 8); +} + +#ifdef LODEPNG_COMPILE_DISK +unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename, + LodePNGColorType colortype, unsigned bitdepth) +{ + unsigned char* buffer = 0; + size_t buffersize; + unsigned error; + error = lodepng_load_file(&buffer, &buffersize, filename); + if(!error) error = lodepng_decode_memory(out, w, h, buffer, buffersize, colortype, bitdepth); + lodepng_free(buffer); + return error; +} + +unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) +{ + return lodepng_decode_file(out, w, h, filename, LCT_RGBA, 8); +} + +unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) +{ + return lodepng_decode_file(out, w, h, filename, LCT_RGB, 8); +} +#endif /*LODEPNG_COMPILE_DISK*/ + +void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings) +{ + settings->color_convert = 1; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + settings->read_text_chunks = 1; + settings->remember_unknown_chunks = 0; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + settings->ignore_crc = 0; + lodepng_decompress_settings_init(&settings->zlibsettings); +} + +#endif /*LODEPNG_COMPILE_DECODER*/ + +#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) + +void lodepng_state_init(LodePNGState* state) +{ +#ifdef LODEPNG_COMPILE_DECODER + lodepng_decoder_settings_init(&state->decoder); +#endif /*LODEPNG_COMPILE_DECODER*/ +#ifdef LODEPNG_COMPILE_ENCODER + lodepng_encoder_settings_init(&state->encoder); +#endif /*LODEPNG_COMPILE_ENCODER*/ + lodepng_color_mode_init(&state->info_raw); + lodepng_info_init(&state->info_png); + state->error = 1; +} + +void lodepng_state_cleanup(LodePNGState* state) +{ + lodepng_color_mode_cleanup(&state->info_raw); + lodepng_info_cleanup(&state->info_png); +} + +void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source) +{ + lodepng_state_cleanup(dest); + *dest = *source; + lodepng_color_mode_init(&dest->info_raw); + lodepng_info_init(&dest->info_png); + dest->error = lodepng_color_mode_copy(&dest->info_raw, &source->info_raw); if(dest->error) return; + dest->error = lodepng_info_copy(&dest->info_png, &source->info_png); if(dest->error) return; +} + +#endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ + +#ifdef LODEPNG_COMPILE_ENCODER + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / PNG Encoder / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*chunkName must be string of 4 characters*/ +static unsigned addChunk(ucvector* out, const char* chunkName, const unsigned char* data, size_t length) +{ + CERROR_TRY_RETURN(lodepng_chunk_create(&out->data, &out->size, (unsigned)length, chunkName, data)); + out->allocsize = out->size; /*fix the allocsize again*/ + return 0; +} + +static void writeSignature(ucvector* out) +{ + /*8 bytes PNG signature, aka the magic bytes*/ + ucvector_push_back(out, 137); + ucvector_push_back(out, 80); + ucvector_push_back(out, 78); + ucvector_push_back(out, 71); + ucvector_push_back(out, 13); + ucvector_push_back(out, 10); + ucvector_push_back(out, 26); + ucvector_push_back(out, 10); +} + +static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth, unsigned interlace_method) +{ + unsigned error = 0; + ucvector header; + ucvector_init(&header); + + lodepng_add32bitInt(&header, w); /*width*/ + lodepng_add32bitInt(&header, h); /*height*/ + ucvector_push_back(&header, (unsigned char)bitdepth); /*bit depth*/ + ucvector_push_back(&header, (unsigned char)colortype); /*color type*/ + ucvector_push_back(&header, 0); /*compression method*/ + ucvector_push_back(&header, 0); /*filter method*/ + ucvector_push_back(&header, interlace_method); /*interlace method*/ + + error = addChunk(out, "IHDR", header.data, header.size); + ucvector_cleanup(&header); + + return error; +} + +static unsigned addChunk_PLTE(ucvector* out, const LodePNGColorMode* info) +{ + unsigned error = 0; + size_t i; + ucvector PLTE; + ucvector_init(&PLTE); + for(i = 0; i != info->palettesize * 4; ++i) + { + /*add all channels except alpha channel*/ + if(i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]); + } + error = addChunk(out, "PLTE", PLTE.data, PLTE.size); + ucvector_cleanup(&PLTE); + + return error; +} + +static unsigned addChunk_tRNS(ucvector* out, const LodePNGColorMode* info) +{ + unsigned error = 0; + size_t i; + ucvector tRNS; + ucvector_init(&tRNS); + if(info->colortype == LCT_PALETTE) + { + size_t amount = info->palettesize; + /*the tail of palette values that all have 255 as alpha, does not have to be encoded*/ + for(i = info->palettesize; i != 0; --i) + { + if(info->palette[4 * (i - 1) + 3] == 255) --amount; + else break; + } + /*add only alpha channel*/ + for(i = 0; i != amount; ++i) ucvector_push_back(&tRNS, info->palette[4 * i + 3]); + } + else if(info->colortype == LCT_GREY) + { + if(info->key_defined) + { + ucvector_push_back(&tRNS, (unsigned char)(info->key_r >> 8)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_r & 255)); + } + } + else if(info->colortype == LCT_RGB) + { + if(info->key_defined) + { + ucvector_push_back(&tRNS, (unsigned char)(info->key_r >> 8)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_r & 255)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_g >> 8)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_g & 255)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_b >> 8)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_b & 255)); + } + } + + error = addChunk(out, "tRNS", tRNS.data, tRNS.size); + ucvector_cleanup(&tRNS); + + return error; +} + +static unsigned addChunk_IDAT(ucvector* out, const unsigned char* data, size_t datasize, + LodePNGCompressSettings* zlibsettings) +{ + ucvector zlibdata; + unsigned error = 0; + + /*compress with the Zlib compressor*/ + ucvector_init(&zlibdata); + error = zlib_compress(&zlibdata.data, &zlibdata.size, data, datasize, zlibsettings); + if(!error) error = addChunk(out, "IDAT", zlibdata.data, zlibdata.size); + ucvector_cleanup(&zlibdata); + + return error; +} + +static unsigned addChunk_IEND(ucvector* out) +{ + unsigned error = 0; + error = addChunk(out, "IEND", 0, 0); + return error; +} + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + +static unsigned addChunk_tEXt(ucvector* out, const char* keyword, const char* textstring) +{ + unsigned error = 0; + size_t i; + ucvector text; + ucvector_init(&text); + for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&text, (unsigned char)keyword[i]); + if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ + ucvector_push_back(&text, 0); /*0 termination char*/ + for(i = 0; textstring[i] != 0; ++i) ucvector_push_back(&text, (unsigned char)textstring[i]); + error = addChunk(out, "tEXt", text.data, text.size); + ucvector_cleanup(&text); + + return error; +} + +static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* textstring, + LodePNGCompressSettings* zlibsettings) +{ + unsigned error = 0; + ucvector data, compressed; + size_t i, textsize = strlen(textstring); + + ucvector_init(&data); + ucvector_init(&compressed); + for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)keyword[i]); + if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ + ucvector_push_back(&data, 0); /*0 termination char*/ + ucvector_push_back(&data, 0); /*compression method: 0*/ + + error = zlib_compress(&compressed.data, &compressed.size, + (unsigned char*)textstring, textsize, zlibsettings); + if(!error) + { + for(i = 0; i != compressed.size; ++i) ucvector_push_back(&data, compressed.data[i]); + error = addChunk(out, "zTXt", data.data, data.size); + } + + ucvector_cleanup(&compressed); + ucvector_cleanup(&data); + return error; +} + +static unsigned addChunk_iTXt(ucvector* out, unsigned compressed, const char* keyword, const char* langtag, + const char* transkey, const char* textstring, LodePNGCompressSettings* zlibsettings) +{ + unsigned error = 0; + ucvector data; + size_t i, textsize = strlen(textstring); + + ucvector_init(&data); + + for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)keyword[i]); + if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ + ucvector_push_back(&data, 0); /*null termination char*/ + ucvector_push_back(&data, compressed ? 1 : 0); /*compression flag*/ + ucvector_push_back(&data, 0); /*compression method*/ + for(i = 0; langtag[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)langtag[i]); + ucvector_push_back(&data, 0); /*null termination char*/ + for(i = 0; transkey[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)transkey[i]); + ucvector_push_back(&data, 0); /*null termination char*/ + + if(compressed) + { + ucvector compressed_data; + ucvector_init(&compressed_data); + error = zlib_compress(&compressed_data.data, &compressed_data.size, + (unsigned char*)textstring, textsize, zlibsettings); + if(!error) + { + for(i = 0; i != compressed_data.size; ++i) ucvector_push_back(&data, compressed_data.data[i]); + } + ucvector_cleanup(&compressed_data); + } + else /*not compressed*/ + { + for(i = 0; textstring[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)textstring[i]); + } + + if(!error) error = addChunk(out, "iTXt", data.data, data.size); + ucvector_cleanup(&data); + return error; +} + +static unsigned addChunk_bKGD(ucvector* out, const LodePNGInfo* info) +{ + unsigned error = 0; + ucvector bKGD; + ucvector_init(&bKGD); + if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) + { + ucvector_push_back(&bKGD, (unsigned char)(info->background_r >> 8)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255)); + } + else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) + { + ucvector_push_back(&bKGD, (unsigned char)(info->background_r >> 8)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_g >> 8)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_g & 255)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_b >> 8)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_b & 255)); + } + else if(info->color.colortype == LCT_PALETTE) + { + ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255)); /*palette index*/ + } + + error = addChunk(out, "bKGD", bKGD.data, bKGD.size); + ucvector_cleanup(&bKGD); + + return error; +} + +static unsigned addChunk_tIME(ucvector* out, const LodePNGTime* time) +{ + unsigned error = 0; + unsigned char* data = (unsigned char*)lodepng_malloc(7); + if(!data) return 83; /*alloc fail*/ + data[0] = (unsigned char)(time->year >> 8); + data[1] = (unsigned char)(time->year & 255); + data[2] = (unsigned char)time->month; + data[3] = (unsigned char)time->day; + data[4] = (unsigned char)time->hour; + data[5] = (unsigned char)time->minute; + data[6] = (unsigned char)time->second; + error = addChunk(out, "tIME", data, 7); + lodepng_free(data); + return error; +} + +static unsigned addChunk_pHYs(ucvector* out, const LodePNGInfo* info) +{ + unsigned error = 0; + ucvector data; + ucvector_init(&data); + + lodepng_add32bitInt(&data, info->phys_x); + lodepng_add32bitInt(&data, info->phys_y); + ucvector_push_back(&data, info->phys_unit); + + error = addChunk(out, "pHYs", data.data, data.size); + ucvector_cleanup(&data); + + return error; +} + +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline, + size_t length, size_t bytewidth, unsigned char filterType) +{ + size_t i; + switch(filterType) + { + case 0: /*None*/ + for(i = 0; i != length; ++i) out[i] = scanline[i]; + break; + case 1: /*Sub*/ + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth]; + break; + case 2: /*Up*/ + if(prevline) + { + for(i = 0; i != length; ++i) out[i] = scanline[i] - prevline[i]; + } + else + { + for(i = 0; i != length; ++i) out[i] = scanline[i]; + } + break; + case 3: /*Average*/ + if(prevline) + { + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i] - (prevline[i] >> 1); + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) >> 1); + } + else + { + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - (scanline[i - bytewidth] >> 1); + } + break; + case 4: /*Paeth*/ + if(prevline) + { + /*paethPredictor(0, prevline[i], 0) is always prevline[i]*/ + for(i = 0; i != bytewidth; ++i) out[i] = (scanline[i] - prevline[i]); + for(i = bytewidth; i < length; ++i) + { + out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth])); + } + } + else + { + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; + /*paethPredictor(scanline[i - bytewidth], 0, 0) is always scanline[i - bytewidth]*/ + for(i = bytewidth; i < length; ++i) out[i] = (scanline[i] - scanline[i - bytewidth]); + } + break; + default: return; /*unexisting filter type given*/ + } +} + +/* log2 approximation. A slight bit faster than std::log. */ +static float flog2(float f) +{ + float result = 0; + while(f > 32) { result += 4; f /= 16; } + while(f > 2) { ++result; f /= 2; } + return result + 1.442695f * (f * f * f / 3 - 3 * f * f / 2 + 3 * f - 1.83333f); +} + +static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, + const LodePNGColorMode* info, const LodePNGEncoderSettings* settings) +{ + /* + For PNG filter method 0 + out must be a buffer with as size: h + (w * h * bpp + 7) / 8, because there are + the scanlines with 1 extra byte per scanline + */ + + unsigned bpp = lodepng_get_bpp(info); + /*the width of a scanline in bytes, not including the filter type*/ + size_t linebytes = (w * bpp + 7) / 8; + /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ + size_t bytewidth = (bpp + 7) / 8; + const unsigned char* prevline = 0; + unsigned x, y; + unsigned error = 0; + LodePNGFilterStrategy strategy = settings->filter_strategy; + + /* + There is a heuristic called the minimum sum of absolute differences heuristic, suggested by the PNG standard: + * If the image type is Palette, or the bit depth is smaller than 8, then do not filter the image (i.e. + use fixed filtering, with the filter None). + * (The other case) If the image type is Grayscale or RGB (with or without Alpha), and the bit depth is + not smaller than 8, then use adaptive filtering heuristic as follows: independently for each row, apply + all five filters and select the filter that produces the smallest sum of absolute values per row. + This heuristic is used if filter strategy is LFS_MINSUM and filter_palette_zero is true. + + If filter_palette_zero is true and filter_strategy is not LFS_MINSUM, the above heuristic is followed, + but for "the other case", whatever strategy filter_strategy is set to instead of the minimum sum + heuristic is used. + */ + if(settings->filter_palette_zero && + (info->colortype == LCT_PALETTE || info->bitdepth < 8)) strategy = LFS_ZERO; + + if(bpp == 0) return 31; /*error: invalid color type*/ + + if(strategy == LFS_ZERO) + { + for(y = 0; y != h; ++y) + { + size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ + size_t inindex = linebytes * y; + out[outindex] = 0; /*filter type byte*/ + filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, 0); + prevline = &in[inindex]; + } + } + else if(strategy == LFS_MINSUM) + { + /*adaptive filtering*/ + size_t sum[5]; + unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ + size_t smallest = 0; + unsigned char type, bestType = 0; + + for(type = 0; type != 5; ++type) + { + attempt[type] = (unsigned char*)lodepng_malloc(linebytes); + if(!attempt[type]) return 83; /*alloc fail*/ + } + + if(!error) + { + for(y = 0; y != h; ++y) + { + /*try the 5 filter types*/ + for(type = 0; type != 5; ++type) + { + filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); + + /*calculate the sum of the result*/ + sum[type] = 0; + if(type == 0) + { + for(x = 0; x != linebytes; ++x) sum[type] += (unsigned char)(attempt[type][x]); + } + else + { + for(x = 0; x != linebytes; ++x) + { + /*For differences, each byte should be treated as signed, values above 127 are negative + (converted to signed char). Filtertype 0 isn't a difference though, so use unsigned there. + This means filtertype 0 is almost never chosen, but that is justified.*/ + unsigned char s = attempt[type][x]; + sum[type] += s < 128 ? s : (255U - s); + } + } + + /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ + if(type == 0 || sum[type] < smallest) + { + bestType = type; + smallest = sum[type]; + } + } + + prevline = &in[y * linebytes]; + + /*now fill the out values*/ + out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; + } + } + + for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); + } + else if(strategy == LFS_ENTROPY) + { + float sum[5]; + unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ + float smallest = 0; + unsigned type, bestType = 0; + unsigned count[256]; + + for(type = 0; type != 5; ++type) + { + attempt[type] = (unsigned char*)lodepng_malloc(linebytes); + if(!attempt[type]) return 83; /*alloc fail*/ + } + + for(y = 0; y != h; ++y) + { + /*try the 5 filter types*/ + for(type = 0; type != 5; ++type) + { + filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); + for(x = 0; x != 256; ++x) count[x] = 0; + for(x = 0; x != linebytes; ++x) ++count[attempt[type][x]]; + ++count[type]; /*the filter type itself is part of the scanline*/ + sum[type] = 0; + for(x = 0; x != 256; ++x) + { + float p = count[x] / (float)(linebytes + 1); + sum[type] += count[x] == 0 ? 0 : flog2(1 / p) * p; + } + /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ + if(type == 0 || sum[type] < smallest) + { + bestType = type; + smallest = sum[type]; + } + } + + prevline = &in[y * linebytes]; + + /*now fill the out values*/ + out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; + } + + for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); + } + else if(strategy == LFS_PREDEFINED) + { + for(y = 0; y != h; ++y) + { + size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ + size_t inindex = linebytes * y; + unsigned char type = settings->predefined_filters[y]; + out[outindex] = type; /*filter type byte*/ + filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type); + prevline = &in[inindex]; + } + } + else if(strategy == LFS_BRUTE_FORCE) + { + /*brute force filter chooser. + deflate the scanline after every filter attempt to see which one deflates best. + This is very slow and gives only slightly smaller, sometimes even larger, result*/ + size_t size[5]; + unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ + size_t smallest = 0; + unsigned type = 0, bestType = 0; + unsigned char* dummy; + LodePNGCompressSettings zlibsettings = settings->zlibsettings; + /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose, + to simulate the true case where the tree is the same for the whole image. Sometimes it gives + better result with dynamic tree anyway. Using the fixed tree sometimes gives worse, but in rare + cases better compression. It does make this a bit less slow, so it's worth doing this.*/ + zlibsettings.btype = 1; + /*a custom encoder likely doesn't read the btype setting and is optimized for complete PNG + images only, so disable it*/ + zlibsettings.custom_zlib = 0; + zlibsettings.custom_deflate = 0; + for(type = 0; type != 5; ++type) + { + attempt[type] = (unsigned char*)lodepng_malloc(linebytes); + if(!attempt[type]) return 83; /*alloc fail*/ + } + for(y = 0; y != h; ++y) /*try the 5 filter types*/ + { + for(type = 0; type != 5; ++type) + { + unsigned testsize = linebytes; + /*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/ + + filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); + size[type] = 0; + dummy = 0; + zlib_compress(&dummy, &size[type], attempt[type], testsize, &zlibsettings); + lodepng_free(dummy); + /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/ + if(type == 0 || size[type] < smallest) + { + bestType = type; + smallest = size[type]; + } + } + prevline = &in[y * linebytes]; + out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; + } + for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); + } + else return 88; /* unknown filter strategy */ + + return error; +} + +static void addPaddingBits(unsigned char* out, const unsigned char* in, + size_t olinebits, size_t ilinebits, unsigned h) +{ + /*The opposite of the removePaddingBits function + olinebits must be >= ilinebits*/ + unsigned y; + size_t diff = olinebits - ilinebits; + size_t obp = 0, ibp = 0; /*bit pointers*/ + for(y = 0; y != h; ++y) + { + size_t x; + for(x = 0; x < ilinebits; ++x) + { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + /*obp += diff; --> no, fill in some value in the padding bits too, to avoid + "Use of uninitialised value of size ###" warning from valgrind*/ + for(x = 0; x != diff; ++x) setBitOfReversedStream(&obp, out, 0); + } +} + +/* +in: non-interlaced image with size w*h +out: the same pixels, but re-ordered according to PNG's Adam7 interlacing, with + no padding bits between scanlines, but between reduced images so that each + reduced image starts at a byte. +bpp: bits per pixel +there are no padding bits, not between scanlines, not between reduced images +in has the following size in bits: w * h * bpp. +out is possibly bigger due to padding bits between reduced images +NOTE: comments about padding bits are only relevant if bpp < 8 +*/ +static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) +{ + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + + if(bpp >= 8) + { + for(i = 0; i != 7; ++i) + { + unsigned x, y, b; + size_t bytewidth = bpp / 8; + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) + { + size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; + size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth; + for(b = 0; b < bytewidth; ++b) + { + out[pixeloutstart + b] = in[pixelinstart + b]; + } + } + } + } + else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ + { + for(i = 0; i != 7; ++i) + { + unsigned x, y, b; + unsigned ilinebits = bpp * passw[i]; + unsigned olinebits = bpp * w; + size_t obp, ibp; /*bit pointers (for out and in buffer)*/ + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) + { + ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; + obp = (8 * passstart[i]) + (y * ilinebits + x * bpp); + for(b = 0; b < bpp; ++b) + { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + } + } + } +} + +/*out must be buffer big enough to contain uncompressed IDAT chunk data, and in must contain the full image. +return value is error**/ +static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const unsigned char* in, + unsigned w, unsigned h, + const LodePNGInfo* info_png, const LodePNGEncoderSettings* settings) +{ + /* + This function converts the pure 2D image with the PNG's colortype, into filtered-padded-interlaced data. Steps: + *) if no Adam7: 1) add padding bits (= posible extra bits per scanline if bpp < 8) 2) filter + *) if adam7: 1) Adam7_interlace 2) 7x add padding bits 3) 7x filter + */ + unsigned bpp = lodepng_get_bpp(&info_png->color); + unsigned error = 0; + + if(info_png->interlace_method == 0) + { + *outsize = h + (h * ((w * bpp + 7) / 8)); /*image size plus an extra byte per scanline + possible padding bits*/ + *out = (unsigned char*)lodepng_malloc(*outsize); + if(!(*out) && (*outsize)) error = 83; /*alloc fail*/ + + if(!error) + { + /*non multiple of 8 bits per scanline, padding bits needed per scanline*/ + if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) + { + unsigned char* padded = (unsigned char*)lodepng_malloc(h * ((w * bpp + 7) / 8)); + if(!padded) error = 83; /*alloc fail*/ + if(!error) + { + addPaddingBits(padded, in, ((w * bpp + 7) / 8) * 8, w * bpp, h); + error = filter(*out, padded, w, h, &info_png->color, settings); + } + lodepng_free(padded); + } + else + { + /*we can immediately filter into the out buffer, no other steps needed*/ + error = filter(*out, in, w, h, &info_png->color, settings); + } + } + } + else /*interlace_method is 1 (Adam7)*/ + { + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned char* adam7; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + + *outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/ + *out = (unsigned char*)lodepng_malloc(*outsize); + if(!(*out)) error = 83; /*alloc fail*/ + + adam7 = (unsigned char*)lodepng_malloc(passstart[7]); + if(!adam7 && passstart[7]) error = 83; /*alloc fail*/ + + if(!error) + { + unsigned i; + + Adam7_interlace(adam7, in, w, h, bpp); + for(i = 0; i != 7; ++i) + { + if(bpp < 8) + { + unsigned char* padded = (unsigned char*)lodepng_malloc(padded_passstart[i + 1] - padded_passstart[i]); + if(!padded) ERROR_BREAK(83); /*alloc fail*/ + addPaddingBits(padded, &adam7[passstart[i]], + ((passw[i] * bpp + 7) / 8) * 8, passw[i] * bpp, passh[i]); + error = filter(&(*out)[filter_passstart[i]], padded, + passw[i], passh[i], &info_png->color, settings); + lodepng_free(padded); + } + else + { + error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]], + passw[i], passh[i], &info_png->color, settings); + } + + if(error) break; + } + } + + lodepng_free(adam7); + } + + return error; +} + +/* +palette must have 4 * palettesize bytes allocated, and given in format RGBARGBARGBARGBA... +returns 0 if the palette is opaque, +returns 1 if the palette has a single color with alpha 0 ==> color key +returns 2 if the palette is semi-translucent. +*/ +static unsigned getPaletteTranslucency(const unsigned char* palette, size_t palettesize) +{ + size_t i; + unsigned key = 0; + unsigned r = 0, g = 0, b = 0; /*the value of the color with alpha 0, so long as color keying is possible*/ + for(i = 0; i != palettesize; ++i) + { + if(!key && palette[4 * i + 3] == 0) + { + r = palette[4 * i + 0]; g = palette[4 * i + 1]; b = palette[4 * i + 2]; + key = 1; + i = (size_t)(-1); /*restart from beginning, to detect earlier opaque colors with key's value*/ + } + else if(palette[4 * i + 3] != 255) return 2; + /*when key, no opaque RGB may have key's RGB*/ + else if(key && r == palette[i * 4 + 0] && g == palette[i * 4 + 1] && b == palette[i * 4 + 2]) return 2; + } + return key; +} + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t datasize) +{ + unsigned char* inchunk = data; + while((size_t)(inchunk - data) < datasize) + { + CERROR_TRY_RETURN(lodepng_chunk_append(&out->data, &out->size, inchunk)); + out->allocsize = out->size; /*fix the allocsize again*/ + inchunk = lodepng_chunk_next(inchunk); + } + return 0; +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +unsigned lodepng_encode(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h, + LodePNGState* state) +{ + LodePNGInfo info; + ucvector outv; + unsigned char* data = 0; /*uncompressed version of the IDAT chunk data*/ + size_t datasize = 0; + + /*provide some proper output values if error will happen*/ + *out = 0; + *outsize = 0; + state->error = 0; + + lodepng_info_init(&info); + lodepng_info_copy(&info, &state->info_png); + + + if((info.color.colortype == LCT_PALETTE || state->encoder.force_palette) + && (info.color.palettesize == 0 || info.color.palettesize > 256)) + { + state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/ + return state->error; + } + + if(state->encoder.auto_convert) + { + state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw); + } + if(state->error) return state->error; + + if(state->encoder.zlibsettings.btype > 2) + { + CERROR_RETURN_ERROR(state->error, 61); /*error: unexisting btype*/ + } + if(state->info_png.interlace_method > 1) + { + CERROR_RETURN_ERROR(state->error, 71); /*error: unexisting interlace mode*/ + } + + state->error = checkColorValidity(info.color.colortype, info.color.bitdepth); + if(state->error) return state->error; /*error: unexisting color type given*/ + state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth); + if(state->error) return state->error; /*error: unexisting color type given*/ + + if(!lodepng_color_mode_equal(&state->info_raw, &info.color)) + { + unsigned char* converted; + size_t size = (w * h * (size_t)lodepng_get_bpp(&info.color) + 7) / 8; + + converted = (unsigned char*)lodepng_malloc(size); + if(!converted && size) state->error = 83; /*alloc fail*/ + if(!state->error) + { + state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h); + } + if(!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder); + lodepng_free(converted); + } + else preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder); + + ucvector_init(&outv); + while(!state->error) /*while only executed once, to break on error*/ + { +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + size_t i; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + /*write signature and chunks*/ + writeSignature(&outv); + /*IHDR*/ + addChunk_IHDR(&outv, w, h, info.color.colortype, info.color.bitdepth, info.interlace_method); +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*unknown chunks between IHDR and PLTE*/ + if(info.unknown_chunks_data[0]) + { + state->error = addUnknownChunks(&outv, info.unknown_chunks_data[0], info.unknown_chunks_size[0]); + if(state->error) break; + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + /*PLTE*/ + if(info.color.colortype == LCT_PALETTE) + { + addChunk_PLTE(&outv, &info.color); + } + if(state->encoder.force_palette && (info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA)) + { + addChunk_PLTE(&outv, &info.color); + } + /*tRNS*/ + if(info.color.colortype == LCT_PALETTE && getPaletteTranslucency(info.color.palette, info.color.palettesize) != 0) + { + addChunk_tRNS(&outv, &info.color); + } + if((info.color.colortype == LCT_GREY || info.color.colortype == LCT_RGB) && info.color.key_defined) + { + addChunk_tRNS(&outv, &info.color); + } +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*bKGD (must come between PLTE and the IDAt chunks*/ + if(info.background_defined) addChunk_bKGD(&outv, &info); + /*pHYs (must come before the IDAT chunks)*/ + if(info.phys_defined) addChunk_pHYs(&outv, &info); + + /*unknown chunks between PLTE and IDAT*/ + if(info.unknown_chunks_data[1]) + { + state->error = addUnknownChunks(&outv, info.unknown_chunks_data[1], info.unknown_chunks_size[1]); + if(state->error) break; + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + /*IDAT (multiple IDAT chunks must be consecutive)*/ + state->error = addChunk_IDAT(&outv, data, datasize, &state->encoder.zlibsettings); + if(state->error) break; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*tIME*/ + if(info.time_defined) addChunk_tIME(&outv, &info.time); + /*tEXt and/or zTXt*/ + for(i = 0; i != info.text_num; ++i) + { + if(strlen(info.text_keys[i]) > 79) + { + state->error = 66; /*text chunk too large*/ + break; + } + if(strlen(info.text_keys[i]) < 1) + { + state->error = 67; /*text chunk too small*/ + break; + } + if(state->encoder.text_compression) + { + addChunk_zTXt(&outv, info.text_keys[i], info.text_strings[i], &state->encoder.zlibsettings); + } + else + { + addChunk_tEXt(&outv, info.text_keys[i], info.text_strings[i]); + } + } + /*LodePNG version id in text chunk*/ + if(state->encoder.add_id) + { + unsigned alread_added_id_text = 0; + for(i = 0; i != info.text_num; ++i) + { + if(!strcmp(info.text_keys[i], "LodePNG")) + { + alread_added_id_text = 1; + break; + } + } + if(alread_added_id_text == 0) + { + addChunk_tEXt(&outv, "LodePNG", LODEPNG_VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/ + } + } + /*iTXt*/ + for(i = 0; i != info.itext_num; ++i) + { + if(strlen(info.itext_keys[i]) > 79) + { + state->error = 66; /*text chunk too large*/ + break; + } + if(strlen(info.itext_keys[i]) < 1) + { + state->error = 67; /*text chunk too small*/ + break; + } + addChunk_iTXt(&outv, state->encoder.text_compression, + info.itext_keys[i], info.itext_langtags[i], info.itext_transkeys[i], info.itext_strings[i], + &state->encoder.zlibsettings); + } + + /*unknown chunks between IDAT and IEND*/ + if(info.unknown_chunks_data[2]) + { + state->error = addUnknownChunks(&outv, info.unknown_chunks_data[2], info.unknown_chunks_size[2]); + if(state->error) break; + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + addChunk_IEND(&outv); + + break; /*this isn't really a while loop; no error happened so break out now!*/ + } + + lodepng_info_cleanup(&info); + lodepng_free(data); + /*instead of cleaning the vector up, give it to the output*/ + *out = outv.data; + *outsize = outv.size; + + return state->error; +} + +unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, const unsigned char* image, + unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) +{ + unsigned error; + LodePNGState state; + lodepng_state_init(&state); + // Start Maciej: State - disable auto encoding! + state.encoder.auto_convert = false; + // End Maciej + state.info_raw.colortype = colortype; + state.info_raw.bitdepth = bitdepth; + state.info_png.color.colortype = colortype; + state.info_png.color.bitdepth = bitdepth; + lodepng_encode(out, outsize, image, w, h, &state); + error = state.error; + lodepng_state_cleanup(&state); + return error; +} + +unsigned lodepng_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) +{ + return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGBA, 8); +} + +unsigned lodepng_encode24(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) +{ + return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGB, 8); +} + +#ifdef LODEPNG_COMPILE_DISK +unsigned lodepng_encode_file(const char* filename, const unsigned char* image, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) +{ + unsigned char* buffer; + size_t buffersize; + unsigned error = lodepng_encode_memory(&buffer, &buffersize, image, w, h, colortype, bitdepth); + if(!error) error = lodepng_save_file(buffer, buffersize, filename); + lodepng_free(buffer); + return error; +} + +unsigned lodepng_encode32_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) +{ + return lodepng_encode_file(filename, image, w, h, LCT_RGBA, 8); +} + +unsigned lodepng_encode24_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) +{ + return lodepng_encode_file(filename, image, w, h, LCT_RGB, 8); +} +#endif /*LODEPNG_COMPILE_DISK*/ + +void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings) +{ + lodepng_compress_settings_init(&settings->zlibsettings); + settings->filter_palette_zero = 1; + settings->filter_strategy = LFS_MINSUM; + settings->auto_convert = 1; + settings->force_palette = 0; + settings->predefined_filters = 0; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + settings->add_id = 0; + settings->text_compression = 1; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} + +#endif /*LODEPNG_COMPILE_ENCODER*/ +#endif /*LODEPNG_COMPILE_PNG*/ + +#ifdef LODEPNG_COMPILE_ERROR_TEXT +/* +This returns the description of a numerical error code in English. This is also +the documentation of all the error codes. +*/ +const char* lodepng_error_text(unsigned code) +{ + switch(code) + { + case 0: return "no error, everything went ok"; + case 1: return "nothing done yet"; /*the Encoder/Decoder has done nothing yet, error checking makes no sense yet*/ + case 10: return "end of input memory reached without huffman end code"; /*while huffman decoding*/ + case 11: return "error in code tree made it jump outside of huffman tree"; /*while huffman decoding*/ + case 13: return "problem while processing dynamic deflate block"; + case 14: return "problem while processing dynamic deflate block"; + case 15: return "problem while processing dynamic deflate block"; + case 16: return "unexisting code while processing dynamic deflate block"; + case 17: return "end of out buffer memory reached while inflating"; + case 18: return "invalid distance code while inflating"; + case 19: return "end of out buffer memory reached while inflating"; + case 20: return "invalid deflate block BTYPE encountered while decoding"; + case 21: return "NLEN is not ones complement of LEN in a deflate block"; + /*end of out buffer memory reached while inflating: + This can happen if the inflated deflate data is longer than the amount of bytes required to fill up + all the pixels of the image, given the color depth and image dimensions. Something that doesn't + happen in a normal, well encoded, PNG image.*/ + case 22: return "end of out buffer memory reached while inflating"; + case 23: return "end of in buffer memory reached while inflating"; + case 24: return "invalid FCHECK in zlib header"; + case 25: return "invalid compression method in zlib header"; + case 26: return "FDICT encountered in zlib header while it's not used for PNG"; + case 27: return "PNG file is smaller than a PNG header"; + /*Checks the magic file header, the first 8 bytes of the PNG file*/ + case 28: return "incorrect PNG signature, it's no PNG or corrupted"; + case 29: return "first chunk is not the header chunk"; + case 30: return "chunk length too large, chunk broken off at end of file"; + case 31: return "illegal PNG color type or bpp"; + case 32: return "illegal PNG compression method"; + case 33: return "illegal PNG filter method"; + case 34: return "illegal PNG interlace method"; + case 35: return "chunk length of a chunk is too large or the chunk too small"; + case 36: return "illegal PNG filter type encountered"; + case 37: return "illegal bit depth for this color type given"; + case 38: return "the palette is too big"; /*more than 256 colors*/ + case 39: return "more palette alpha values given in tRNS chunk than there are colors in the palette"; + case 40: return "tRNS chunk has wrong size for greyscale image"; + case 41: return "tRNS chunk has wrong size for RGB image"; + case 42: return "tRNS chunk appeared while it was not allowed for this color type"; + case 43: return "bKGD chunk has wrong size for palette image"; + case 44: return "bKGD chunk has wrong size for greyscale image"; + case 45: return "bKGD chunk has wrong size for RGB image"; + case 48: return "empty input buffer given to decoder. Maybe caused by non-existing file?"; + case 49: return "jumped past memory while generating dynamic huffman tree"; + case 50: return "jumped past memory while generating dynamic huffman tree"; + case 51: return "jumped past memory while inflating huffman block"; + case 52: return "jumped past memory while inflating"; + case 53: return "size of zlib data too small"; + case 54: return "repeat symbol in tree while there was no value symbol yet"; + /*jumped past tree while generating huffman tree, this could be when the + tree will have more leaves than symbols after generating it out of the + given lenghts. They call this an oversubscribed dynamic bit lengths tree in zlib.*/ + case 55: return "jumped past tree while generating huffman tree"; + case 56: return "given output image colortype or bitdepth not supported for color conversion"; + case 57: return "invalid CRC encountered (checking CRC can be disabled)"; + case 58: return "invalid ADLER32 encountered (checking ADLER32 can be disabled)"; + case 59: return "requested color conversion not supported"; + case 60: return "invalid window size given in the settings of the encoder (must be 0-32768)"; + case 61: return "invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)"; + /*LodePNG leaves the choice of RGB to greyscale conversion formula to the user.*/ + case 62: return "conversion from color to greyscale not supported"; + case 63: return "length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk"; /*(2^31-1)*/ + /*this would result in the inability of a deflated block to ever contain an end code. It must be at least 1.*/ + case 64: return "the length of the END symbol 256 in the Huffman tree is 0"; + case 66: return "the length of a text chunk keyword given to the encoder is longer than the maximum of 79 bytes"; + case 67: return "the length of a text chunk keyword given to the encoder is smaller than the minimum of 1 byte"; + case 68: return "tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors"; + case 69: return "unknown chunk type with 'critical' flag encountered by the decoder"; + case 71: return "unexisting interlace mode given to encoder (must be 0 or 1)"; + case 72: return "while decoding, unexisting compression method encountering in zTXt or iTXt chunk (it must be 0)"; + case 73: return "invalid tIME chunk size"; + case 74: return "invalid pHYs chunk size"; + /*length could be wrong, or data chopped off*/ + case 75: return "no null termination char found while decoding text chunk"; + case 76: return "iTXt chunk too short to contain required bytes"; + case 77: return "integer overflow in buffer size"; + case 78: return "failed to open file for reading"; /*file doesn't exist or couldn't be opened for reading*/ + case 79: return "failed to open file for writing"; + case 80: return "tried creating a tree of 0 symbols"; + case 81: return "lazy matching at pos 0 is impossible"; + case 82: return "color conversion to palette requested while a color isn't in palette"; + case 83: return "memory allocation failed"; + case 84: return "given image too small to contain all pixels to be encoded"; + case 86: return "impossible offset in lz77 encoding (internal bug)"; + case 87: return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined"; + case 88: return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy"; + case 89: return "text chunk keyword too short or long: must have size 1-79"; + /*the windowsize in the LodePNGCompressSettings. Requiring POT(==> & instead of %) makes encoding 12% faster.*/ + case 90: return "windowsize must be a power of two"; + case 91: return "invalid decompressed idat size"; + case 92: return "too many pixels, not supported"; + case 93: return "zero width or height is invalid"; + case 94: return "header chunk must have a size of 13 bytes"; + } + return "unknown error code"; +} +#endif /*LODEPNG_COMPILE_ERROR_TEXT*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // C++ Wrapper // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_CPP +namespace lodepng +{ + +#ifdef LODEPNG_COMPILE_DISK +unsigned load_file(std::vector& buffer, const std::string& filename) +{ + long size = lodepng_filesize(filename.c_str()); + if(size < 0) return 78; + buffer.resize((size_t)size); + return size == 0 ? 0 : lodepng_buffer_file(&buffer[0], (size_t)size, filename.c_str()); +} + +/*write given buffer to the file, overwriting the file, it doesn't append to it.*/ +unsigned save_file(const std::vector& buffer, const std::string& filename) +{ + return lodepng_save_file(buffer.empty() ? 0 : &buffer[0], buffer.size(), filename.c_str()); +} +#endif /* LODEPNG_COMPILE_DISK */ + +#ifdef LODEPNG_COMPILE_ZLIB +#ifdef LODEPNG_COMPILE_DECODER +unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, + const LodePNGDecompressSettings& settings) +{ + unsigned char* buffer = 0; + size_t buffersize = 0; + unsigned error = zlib_decompress(&buffer, &buffersize, in, insize, &settings); + if(buffer) + { + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned decompress(std::vector& out, const std::vector& in, + const LodePNGDecompressSettings& settings) +{ + return decompress(out, in.empty() ? 0 : &in[0], in.size(), settings); +} +#endif /* LODEPNG_COMPILE_DECODER */ + +#ifdef LODEPNG_COMPILE_ENCODER +unsigned compress(std::vector& out, const unsigned char* in, size_t insize, + const LodePNGCompressSettings& settings) +{ + unsigned char* buffer = 0; + size_t buffersize = 0; + unsigned error = zlib_compress(&buffer, &buffersize, in, insize, &settings); + if(buffer) + { + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned compress(std::vector& out, const std::vector& in, + const LodePNGCompressSettings& settings) +{ + return compress(out, in.empty() ? 0 : &in[0], in.size(), settings); +} +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_ZLIB */ + + +#ifdef LODEPNG_COMPILE_PNG + +State::State() +{ + lodepng_state_init(this); +} + +State::State(const State& other) +{ + lodepng_state_init(this); + lodepng_state_copy(this, &other); +} + +State::~State() +{ + lodepng_state_cleanup(this); +} + +State& State::operator=(const State& other) +{ + lodepng_state_copy(this, &other); + return *this; +} + +#ifdef LODEPNG_COMPILE_DECODER + +unsigned decode(std::vector& out, unsigned& w, unsigned& h, const unsigned char* in, + size_t insize, LodePNGColorType colortype, unsigned bitdepth) +{ + unsigned char* buffer; + unsigned error = lodepng_decode_memory(&buffer, &w, &h, in, insize, colortype, bitdepth); + if(buffer && !error) + { + State state; + state.info_raw.colortype = colortype; + state.info_raw.bitdepth = bitdepth; + size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + const std::vector& in, LodePNGColorType colortype, unsigned bitdepth) +{ + return decode(out, w, h, in.empty() ? 0 : &in[0], (unsigned)in.size(), colortype, bitdepth); +} + +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + State& state, + const unsigned char* in, size_t insize) +{ + unsigned char* buffer = NULL; + unsigned error = lodepng_decode(&buffer, &w, &h, &state, in, insize); + if(buffer && !error) + { + size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + } + lodepng_free(buffer); + return error; +} + +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + State& state, + const std::vector& in) +{ + return decode(out, w, h, state, in.empty() ? 0 : &in[0], in.size()); +} + +#ifdef LODEPNG_COMPILE_DISK +unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::string& filename, + LodePNGColorType colortype, unsigned bitdepth) +{ + std::vector buffer; + unsigned error = load_file(buffer, filename); + if(error) return error; + return decode(out, w, h, buffer, colortype, bitdepth); +} +#endif /* LODEPNG_COMPILE_DECODER */ +#endif /* LODEPNG_COMPILE_DISK */ + +#ifdef LODEPNG_COMPILE_ENCODER +unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) +{ + unsigned char* buffer; + size_t buffersize; + unsigned error = lodepng_encode_memory(&buffer, &buffersize, in, w, h, colortype, bitdepth); + if(buffer) + { + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned encode(std::vector& out, + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) +{ + if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; + return encode(out, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); +} + +unsigned encode(std::vector& out, + const unsigned char* in, unsigned w, unsigned h, + State& state) +{ + unsigned char* buffer; + size_t buffersize; + unsigned error = lodepng_encode(&buffer, &buffersize, in, w, h, &state); + if(buffer) + { + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned encode(std::vector& out, + const std::vector& in, unsigned w, unsigned h, + State& state) +{ + if(lodepng_get_raw_size(w, h, &state.info_raw) > in.size()) return 84; + return encode(out, in.empty() ? 0 : &in[0], w, h, state); +} + +#ifdef LODEPNG_COMPILE_DISK +unsigned encode(const std::string& filename, + const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) +{ + std::vector buffer; + unsigned error = encode(buffer, in, w, h, colortype, bitdepth); + if(!error) error = save_file(buffer, filename); + return error; +} + +unsigned encode(const std::string& filename, + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) +{ + if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; + return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); +} +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_PNG */ +} /* namespace lodepng */ +#endif /*LODEPNG_COMPILE_CPP*/ + +#endif /*LODE_PNG_IMPLEMENTATION*/ \ No newline at end of file diff --git a/CameraParameterEstimation/apps/basics/extern/par_shapes.h b/CameraParameterEstimation/apps/basics/extern/par_shapes.h new file mode 100644 index 0000000..fe6409e --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/par_shapes.h @@ -0,0 +1,2025 @@ +// SHAPES :: https://github.com/prideout/par +// Simple C library for creation and manipulation of triangle meshes. +// +// The API is divided into three sections: +// +// - Generators. Create parametric surfaces, platonic solids, etc. +// - Queries. Ask a mesh for its axis-aligned bounding box, etc. +// - Transforms. Rotate a mesh, merge it with another, add normals, etc. +// +// In addition to the comment block above each function declaration, the API +// has informal documentation here: +// +// http://github.prideout.net/shapes/ +// +// For our purposes, a "mesh" is a list of points and a list of triangles; the +// former is a flattened list of three-tuples (32-bit floats) and the latter is +// also a flattened list of three-tuples (16-bit uints). Triangles are always +// oriented such that their front face winds counter-clockwise. +// +// Optionally, meshes can contain 3D normals (one per vertex), and 2D texture +// coordinates (one per vertex). That's it! If you need something fancier, +// look elsewhere. +// +// The MIT License +// Copyright (c) 2015 Philip Rideout + +#ifndef PAR_SHAPES_H +#define PAR_SHAPES_H + +#include +#include + +#ifndef PAR_SHAPES_T +#define PAR_SHAPES_T uint16_t +#endif + +typedef struct par_shapes_mesh_s { + float* points; // Flat list of 3-tuples (X Y Z X Y Z...) + int npoints; // Number of points (not the number of floats). + PAR_SHAPES_T* triangles; // Flat list of 3-tuples (I J K I J K...) + int ntriangles; // Number of triangles (not the number of indices). + float* normals; // Optional list of 3-tuples (X Y Z X Y Z...) + float* tcoords; // Optional list of 2-tuples (U V U V U V...) +} par_shapes_mesh; + +void par_shapes_free_mesh(par_shapes_mesh*); + +// Generators ------------------------------------------------------------------ + +// Instance a cylinder that sits on the Z=0 plane using the given tessellation +// levels across the UV domain. Think of "slices" like a number of pizza +// slices, and "stacks" like a number of stacked rings. Height and radius are +// both 1.0, but they can easily be changed with par_shapes_scale. +par_shapes_mesh* par_shapes_create_cylinder(int slices, int stacks); + +// Create a donut that sits on the Z=0 plane with the specified inner radius. +// The outer radius can be controlled with par_shapes_scale. +par_shapes_mesh* par_shapes_create_torus(int slices, int stacks, float radius); + +// Create a sphere with texture coordinates and small triangles near the poles. +par_shapes_mesh* par_shapes_create_parametric_sphere(int slices, int stacks); + +// Approximate a sphere with a subdivided icosahedron, which produces a nice +// distribution of triangles, but no texture coordinates. Each subdivision +// level scales the number of triangles by four, so use a very low number. +par_shapes_mesh* par_shapes_create_subdivided_sphere(int nsubdivisions); + +// More parametric surfaces. +par_shapes_mesh* par_shapes_create_klein_bottle(int slices, int stacks); +par_shapes_mesh* par_shapes_create_trefoil_knot(int slices, int stacks, + float radius); +par_shapes_mesh* par_shapes_create_hemisphere(int slices, int stacks); +par_shapes_mesh* par_shapes_create_plane(int slices, int stacks); + +// Create a parametric surface from a callback function that consumes a 2D +// point in [0,1] and produces a 3D point. +typedef void (*par_shapes_fn)(float const*, float*, void*); +par_shapes_mesh* par_shapes_create_parametric(par_shapes_fn, int slices, + int stacks, void* userdata); + +// Generate points for a 20-sided polyhedron that fits in the unit sphere. +// Texture coordinates and normals are not provided. +par_shapes_mesh* par_shapes_create_icosahedron(); + +// Generate points for a 12-sided polyhedron that fits in the unit sphere. +// Again, texture coordinates and normals are not provided. +par_shapes_mesh* par_shapes_create_dodecahedron(); + +// More platonic solids. +par_shapes_mesh* par_shapes_create_octohedron(); +par_shapes_mesh* par_shapes_create_tetrahedron(); +par_shapes_mesh* par_shapes_create_cube(); + +// Generate an orientable disk shape in 3-space. Does not include normals or +// texture coordinates. +par_shapes_mesh* par_shapes_create_disk(float radius, int slices, + float const* center, float const* normal); + +// Create an empty shape. Useful for building scenes with merge_and_free. +par_shapes_mesh* par_shapes_create_empty(); + +// Generate a rock shape that sits on the Y=0 plane, and sinks into it a bit. +// This includes smooth normals but no texture coordinates. Each subdivision +// level scales the number of triangles by four, so use a very low number. +par_shapes_mesh* par_shapes_create_rock(int seed, int nsubdivisions); + +// Create trees or vegetation by executing a recursive turtle graphics program. +// The program is a list of command-argument pairs. See the unit test for +// an example. +par_shapes_mesh* par_shapes_create_lsystem(char const* program, int slices, + int maxdepth); + +// Queries --------------------------------------------------------------------- + +// Dump out a text file conforming to the venerable OBJ format. +void par_shapes_export(par_shapes_mesh const*, char const* objfile); + +// Take a pointer to 6 floats and set them to min xyz, max xyz. +void par_shapes_compute_aabb(par_shapes_mesh const* mesh, float* aabb); + +// Make a deep copy of a mesh. To make a brand new copy, pass null to "target". +// To avoid memory churn, pass an existing mesh to "target". +par_shapes_mesh* par_shapes_clone(par_shapes_mesh const* mesh, + par_shapes_mesh* target); + +// Transformations ------------------------------------------------------------- + +void par_shapes_merge(par_shapes_mesh* dst, par_shapes_mesh const* src); +void par_shapes_translate(par_shapes_mesh*, float x, float y, float z); +void par_shapes_rotate(par_shapes_mesh*, float radians, float const* axis); +void par_shapes_scale(par_shapes_mesh*, float x, float y, float z); +void par_shapes_merge_and_free(par_shapes_mesh* dst, par_shapes_mesh* src); + +// Reverse the winding of a run of faces. Useful when drawing the inside of +// a Cornell Box. Pass 0 for nfaces to reverse every face in the mesh. +void par_shapes_invert(par_shapes_mesh*, int startface, int nfaces); + +// Remove all triangles whose area is less than minarea. +void par_shapes_remove_degenerate(par_shapes_mesh*, float minarea); + +// Dereference the entire index buffer and replace the point list. +// This creates an inefficient structure, but is useful for drawing facets. +// If create_indices is true, a trivial "0 1 2 3..." index buffer is generated. +void par_shapes_unweld(par_shapes_mesh* mesh, bool create_indices); + +// Merge colocated verts, build a new index buffer, and return the +// optimized mesh. Epsilon is the maximum distance to consider when +// welding vertices. The mapping argument can be null, or a pointer to +// npoints integers, which gets filled with the mapping from old vertex +// indices to new indices. +par_shapes_mesh* par_shapes_weld(par_shapes_mesh const*, float epsilon, + PAR_SHAPES_T* mapping); + +// Compute smooth normals by averaging adjacent facet normals. +void par_shapes_compute_normals(par_shapes_mesh* m); + +#ifndef PAR_HELPERS +#define PAR_HELPERS 1 +#define PAR_PI (3.14159265359) +#define PAR_MIN(a, b) (a > b ? b : a) +#define PAR_MAX(a, b) (a > b ? a : b) +#define PAR_CLAMP(v, lo, hi) PAR_MAX(lo, PAR_MIN(hi, v)) +#define PAR_MALLOC(T, N) ((T*) malloc(N * sizeof(T))) +#define PAR_CALLOC(T, N) ((T*) calloc(N * sizeof(T), 1)) +#define PAR_REALLOC(T, BUF, N) ((T*) realloc(BUF, sizeof(T) * N)) +#define PAR_FREE(BUF) free(BUF) +#define PAR_SWAP(T, A, B) { T tmp = B; B = A; A = tmp; } +#define PAR_SQR(a) (a * a) +#endif + +// ----------------------------------------------------------------------------- +// END PUBLIC API +// ----------------------------------------------------------------------------- + +#endif // PAR_SHAPES_H + +#ifdef PAR_SHAPES_IMPLEMENTATION + +#include +#include +#include +#include +#include +#include +#include + +static void par_shapes__sphere(float const* uv, float* xyz, void*); +static void par_shapes__hemisphere(float const* uv, float* xyz, void*); +static void par_shapes__plane(float const* uv, float* xyz, void*); +static void par_shapes__klein(float const* uv, float* xyz, void*); +static void par_shapes__cylinder(float const* uv, float* xyz, void*); +static void par_shapes__torus(float const* uv, float* xyz, void*); +static void par_shapes__trefoil(float const* uv, float* xyz, void*); + +struct osn_context; +static int par__simplex_noise(int64_t seed, struct osn_context** ctx); +static void par__simplex_noise_free(struct osn_context* ctx); +static double par__simplex_noise2(struct osn_context* ctx, double x, double y); + +static void par_shapes__copy3(float* result, float const* a) +{ + result[0] = a[0]; + result[1] = a[1]; + result[2] = a[2]; +} + +static float par_shapes__dot3(float const* a, float const* b) +{ + return b[0] * a[0] + b[1] * a[1] + b[2] * a[2]; +} + +static void par_shapes__transform3(float* p, float const* x, float const* y, + float const* z) +{ + float px = par_shapes__dot3(p, x); + float py = par_shapes__dot3(p, y); + float pz = par_shapes__dot3(p, z); + p[0] = px; + p[1] = py; + p[2] = pz; +} + +static void par_shapes__cross3(float* result, float const* a, float const* b) +{ + float x = (a[1] * b[2]) - (a[2] * b[1]); + float y = (a[2] * b[0]) - (a[0] * b[2]); + float z = (a[0] * b[1]) - (a[1] * b[0]); + result[0] = x; + result[1] = y; + result[2] = z; +} + +static void par_shapes__mix3(float* d, float const* a, float const* b, float t) +{ + float x = b[0] * t + a[0] * (1 - t); + float y = b[1] * t + a[1] * (1 - t); + float z = b[2] * t + a[2] * (1 - t); + d[0] = x; + d[1] = y; + d[2] = z; +} + +static void par_shapes__scale3(float* result, float a) +{ + result[0] *= a; + result[1] *= a; + result[2] *= a; +} + +static void par_shapes__normalize3(float* v) +{ + float lsqr = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + if (lsqr > 0) { + par_shapes__scale3(v, 1.0f / lsqr); + } +} + +static void par_shapes__subtract3(float* result, float const* a) +{ + result[0] -= a[0]; + result[1] -= a[1]; + result[2] -= a[2]; +} + +static void par_shapes__add3(float* result, float const* a) +{ + result[0] += a[0]; + result[1] += a[1]; + result[2] += a[2]; +} + +static float par_shapes__sqrdist3(float const* a, float const* b) +{ + float dx = a[0] - b[0]; + float dy = a[1] - b[1]; + float dz = a[2] - b[2]; + return dx * dx + dy * dy + dz * dz; +} + +static void par_shapes__compute_welded_normals(par_shapes_mesh* m) +{ + m->normals = PAR_MALLOC(float, m->npoints * 3); + PAR_SHAPES_T* weldmap = PAR_MALLOC(PAR_SHAPES_T, m->npoints); + par_shapes_mesh* welded = par_shapes_weld(m, 0.01, weldmap); + par_shapes_compute_normals(welded); + float* pdst = m->normals; + for (int i = 0; i < m->npoints; i++, pdst += 3) { + int d = weldmap[i]; + float const* pnormal = welded->normals + d * 3; + pdst[0] = pnormal[0]; + pdst[1] = pnormal[1]; + pdst[2] = pnormal[2]; + } + free(weldmap); + par_shapes_free_mesh(welded); +} + +par_shapes_mesh* par_shapes_create_cylinder(int slices, int stacks) +{ + if (slices < 3 || stacks < 1) { + return 0; + } + return par_shapes_create_parametric(par_shapes__cylinder, slices, + stacks, 0); +} + +par_shapes_mesh* par_shapes_create_parametric_sphere(int slices, int stacks) +{ + if (slices < 3 || stacks < 3) { + return 0; + } + par_shapes_mesh* m = par_shapes_create_parametric(par_shapes__sphere, + slices, stacks, 0); + par_shapes_remove_degenerate(m, 0.0001); + return m; +} + +par_shapes_mesh* par_shapes_create_hemisphere(int slices, int stacks) +{ + if (slices < 3 || stacks < 3) { + return 0; + } + par_shapes_mesh* m = par_shapes_create_parametric(par_shapes__hemisphere, + slices, stacks, 0); + par_shapes_remove_degenerate(m, 0.0001); + return m; +} + +par_shapes_mesh* par_shapes_create_torus(int slices, int stacks, float radius) +{ + if (slices < 3 || stacks < 3) { + return 0; + } + void* userdata = (void*) &radius; + return par_shapes_create_parametric(par_shapes__torus, slices, + stacks, userdata); +} + +par_shapes_mesh* par_shapes_create_klein_bottle(int slices, int stacks) +{ + if (slices < 3 || stacks < 3) { + return 0; + } + par_shapes_mesh* mesh = par_shapes_create_parametric( + par_shapes__klein, slices, stacks, 0); + int face = 0; + for (int stack = 0; stack < stacks; stack++) { + for (int slice = 0; slice < slices; slice++, face += 2) { + if (stack < 27 * stacks / 32) { + par_shapes_invert(mesh, face, 2); + } + } + } + par_shapes__compute_welded_normals(mesh); + return mesh; +} + +par_shapes_mesh* par_shapes_create_trefoil_knot(int slices, int stacks, + float radius) +{ + if (slices < 3 || stacks < 3) { + return 0; + } + return par_shapes_create_parametric( + par_shapes__trefoil, slices, stacks, 0); +} + +par_shapes_mesh* par_shapes_create_plane(int slices, int stacks) +{ + if (slices < 1 || stacks < 1) { + return 0; + } + return par_shapes_create_parametric(par_shapes__plane, slices, + stacks, 0); +} + +par_shapes_mesh* par_shapes_create_parametric(par_shapes_fn fn, + int slices, int stacks, void* userdata) +{ + par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1); + + // Generate verts. + mesh->npoints = (slices + 1) * (stacks + 1); + mesh->points = PAR_CALLOC(float, 3 * mesh->npoints); + float uv[2]; + float xyz[3]; + float* points = mesh->points; + for (int stack = 0; stack < stacks + 1; stack++) { + uv[0] = (float) stack / stacks; + for (int slice = 0; slice < slices + 1; slice++) { + uv[1] = (float) slice / slices; + fn(uv, xyz, userdata); + *points++ = xyz[0]; + *points++ = xyz[1]; + *points++ = xyz[2]; + } + } + + // Generate texture coordinates. + mesh->tcoords = PAR_CALLOC(float, 2 * mesh->npoints); + float* uvs = mesh->tcoords; + for (int stack = 0; stack < stacks + 1; stack++) { + uv[0] = (float) stack / stacks; + for (int slice = 0; slice < slices + 1; slice++) { + uv[1] = (float) slice / slices; + *uvs++ = uv[0]; + *uvs++ = uv[1]; + } + } + + // Generate faces. + mesh->ntriangles = 2 * slices * stacks; + mesh->triangles = PAR_CALLOC(PAR_SHAPES_T, 3 * mesh->ntriangles); + int v = 0; + PAR_SHAPES_T* face = mesh->triangles; + for (int stack = 0; stack < stacks; stack++) { + for (int slice = 0; slice < slices; slice++) { + int next = slice + 1; + *face++ = v + slice + slices + 1; + *face++ = v + next; + *face++ = v + slice; + *face++ = v + slice + slices + 1; + *face++ = v + next + slices + 1; + *face++ = v + next; + } + v += slices + 1; + } + + par_shapes__compute_welded_normals(mesh); + return mesh; +} + +void par_shapes_free_mesh(par_shapes_mesh* mesh) +{ + free(mesh->points); + free(mesh->triangles); + free(mesh->normals); + free(mesh->tcoords); + free(mesh); +} + +void par_shapes_export(par_shapes_mesh const* mesh, char const* filename) +{ + FILE* objfile = fopen(filename, "wt"); + float const* points = mesh->points; + float const* tcoords = mesh->tcoords; + float const* norms = mesh->normals; + PAR_SHAPES_T const* indices = mesh->triangles; + if (tcoords && norms) { + for (int nvert = 0; nvert < mesh->npoints; nvert++) { + fprintf(objfile, "v %f %f %f\n", points[0], points[1], points[2]); + fprintf(objfile, "vt %f %f\n", tcoords[0], tcoords[1]); + fprintf(objfile, "vn %f %f %f\n", norms[0], norms[1], norms[2]); + points += 3; + norms += 3; + tcoords += 2; + } + for (int nface = 0; nface < mesh->ntriangles; nface++) { + int a = 1 + *indices++; + int b = 1 + *indices++; + int c = 1 + *indices++; + fprintf(objfile, "f %d/%d/%d %d/%d/%d %d/%d/%d\n", + a, a, a, b, b, b, c, c, c); + } + } else if (norms) { + for (int nvert = 0; nvert < mesh->npoints; nvert++) { + fprintf(objfile, "v %f %f %f\n", points[0], points[1], points[2]); + fprintf(objfile, "vn %f %f %f\n", norms[0], norms[1], norms[2]); + points += 3; + norms += 3; + } + for (int nface = 0; nface < mesh->ntriangles; nface++) { + int a = 1 + *indices++; + int b = 1 + *indices++; + int c = 1 + *indices++; + fprintf(objfile, "f %d//%d %d//%d %d//%d\n", a, a, b, b, c, c); + } + } else if (tcoords) { + for (int nvert = 0; nvert < mesh->npoints; nvert++) { + fprintf(objfile, "v %f %f %f\n", points[0], points[1], points[2]); + fprintf(objfile, "vt %f %f\n", tcoords[0], tcoords[1]); + points += 3; + tcoords += 2; + } + for (int nface = 0; nface < mesh->ntriangles; nface++) { + int a = 1 + *indices++; + int b = 1 + *indices++; + int c = 1 + *indices++; + fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c); + } + } else { + for (int nvert = 0; nvert < mesh->npoints; nvert++) { + fprintf(objfile, "v %f %f %f\n", points[0], points[1], points[2]); + points += 3; + } + for (int nface = 0; nface < mesh->ntriangles; nface++) { + int a = 1 + *indices++; + int b = 1 + *indices++; + int c = 1 + *indices++; + fprintf(objfile, "f %d %d %d\n", a, b, c); + } + } + fclose(objfile); +} + +static void par_shapes__sphere(float const* uv, float* xyz, void* userdata) +{ + float phi = uv[0] * PAR_PI; + float theta = uv[1] * 2 * PAR_PI; + xyz[0] = cosf(theta) * sinf(phi); + xyz[1] = sinf(theta) * sinf(phi); + xyz[2] = cosf(phi); +} + +static void par_shapes__hemisphere(float const* uv, float* xyz, void* userdata) +{ + float phi = uv[0] * PAR_PI; + float theta = uv[1] * PAR_PI; + xyz[0] = cosf(theta) * sinf(phi); + xyz[1] = sinf(theta) * sinf(phi); + xyz[2] = cosf(phi); +} + +static void par_shapes__plane(float const* uv, float* xyz, void* userdata) +{ + xyz[0] = uv[0]; + xyz[1] = uv[1]; + xyz[2] = 0; +} + +static void par_shapes__klein(float const* uv, float* xyz, void* userdata) +{ + float u = uv[0] * PAR_PI; + float v = uv[1] * 2 * PAR_PI; + u = u * 2; + if (u < PAR_PI) { + xyz[0] = 3 * cosf(u) * (1 + sinf(u)) + (2 * (1 - cosf(u) / 2)) * + cosf(u) * cosf(v); + xyz[2] = -8 * sinf(u) - 2 * (1 - cosf(u) / 2) * sinf(u) * cosf(v); + } else { + xyz[0] = 3 * cosf(u) * (1 + sinf(u)) + (2 * (1 - cosf(u) / 2)) * + cosf(v + PAR_PI); + xyz[2] = -8 * sinf(u); + } + xyz[1] = -2 * (1 - cosf(u) / 2) * sinf(v); +} + +static void par_shapes__cylinder(float const* uv, float* xyz, void* userdata) +{ + float theta = uv[1] * 2 * PAR_PI; + xyz[0] = sinf(theta); + xyz[1] = cosf(theta); + xyz[2] = uv[0]; +} + +static void par_shapes__torus(float const* uv, float* xyz, void* userdata) +{ + float major = 1; + float minor = *((float*) userdata); + float theta = uv[0] * 2 * PAR_PI; + float phi = uv[1] * 2 * PAR_PI; + float beta = major + minor * cosf(phi); + xyz[0] = cosf(theta) * beta; + xyz[1] = sinf(theta) * beta; + xyz[2] = sinf(phi) * minor; +} + +static void par_shapes__trefoil(float const* uv, float* xyz, void* userdata) +{ + const float a = 0.5f; + const float b = 0.3f; + const float c = 0.5f; + const float d = 0.1f; + const float u = (1 - uv[0]) * 4 * PAR_PI; + const float v = uv[1] * 2 * PAR_PI; + const float r = a + b * cos(1.5f * u); + const float x = r * cos(u); + const float y = r * sin(u); + const float z = c * sin(1.5f * u); + float q[3]; + q[0] = + -1.5f * b * sin(1.5f * u) * cos(u) - (a + b * cos(1.5f * u)) * sin(u); + q[1] = + -1.5f * b * sin(1.5f * u) * sin(u) + (a + b * cos(1.5f * u)) * cos(u); + q[2] = 1.5f * c * cos(1.5f * u); + par_shapes__normalize3(q); + float qvn[3] = {q[1], -q[0], 0}; + par_shapes__normalize3(qvn); + float ww[3]; + par_shapes__cross3(ww, q, qvn); + xyz[0] = x + d * (qvn[0] * cos(v) + ww[0] * sin(v)); + xyz[1] = y + d * (qvn[1] * cos(v) + ww[1] * sin(v)); + xyz[2] = z + d * ww[2] * sin(v); +} + +void par_shapes_merge(par_shapes_mesh* dst, par_shapes_mesh const* src) +{ + PAR_SHAPES_T offset = dst->npoints; + int npoints = dst->npoints + src->npoints; + int vecsize = sizeof(float) * 3; + dst->points = PAR_REALLOC(float, dst->points, 3 * npoints); + memcpy(dst->points + 3 * dst->npoints, src->points, vecsize * src->npoints); + dst->npoints = npoints; + if (src->normals || dst->normals) { + dst->normals = PAR_REALLOC(float, dst->normals, 3 * npoints); + if (src->normals) { + memcpy(dst->normals + 3 * offset, src->normals, + vecsize * src->npoints); + } + } + if (src->tcoords || dst->tcoords) { + int uvsize = sizeof(float) * 2; + dst->tcoords = PAR_REALLOC(float, dst->tcoords, 2 * npoints); + if (src->tcoords) { + memcpy(dst->tcoords + 2 * offset, src->tcoords, + uvsize * src->npoints); + } + } + int ntriangles = dst->ntriangles + src->ntriangles; + dst->triangles = PAR_REALLOC(PAR_SHAPES_T, dst->triangles, 3 * ntriangles); + PAR_SHAPES_T* ptriangles = dst->triangles + 3 * dst->ntriangles; + PAR_SHAPES_T const* striangles = src->triangles; + for (int i = 0; i < src->ntriangles; i++) { + *ptriangles++ = offset + *striangles++; + *ptriangles++ = offset + *striangles++; + *ptriangles++ = offset + *striangles++; + } + dst->ntriangles = ntriangles; +} + +par_shapes_mesh* par_shapes_create_disk(float radius, int slices, + float const* center, float const* normal) +{ + par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1); + mesh->npoints = slices + 1; + mesh->points = PAR_MALLOC(float, 3 * mesh->npoints); + float* points = mesh->points; + *points++ = 0; + *points++ = 0; + *points++ = 0; + for (int i = 0; i < slices; i++) { + float theta = i * PAR_PI * 2 / slices; + *points++ = radius * cos(theta); + *points++ = radius * sin(theta); + *points++ = 0; + } + float nnormal[3] = {normal[0], normal[1], normal[2]}; + par_shapes__normalize3(nnormal); + mesh->normals = PAR_MALLOC(float, 3 * mesh->npoints); + float* norms = mesh->normals; + for (int i = 0; i < mesh->npoints; i++) { + *norms++ = nnormal[0]; + *norms++ = nnormal[1]; + *norms++ = nnormal[2]; + } + mesh->ntriangles = slices; + mesh->triangles = (PAR_SHAPES_T*) + malloc(sizeof(PAR_SHAPES_T) * 3 * mesh->ntriangles); + PAR_SHAPES_T* triangles = mesh->triangles; + for (int i = 0; i < slices; i++) { + *triangles++ = 0; + *triangles++ = 1 + i; + *triangles++ = 1 + (i + 1) % slices; + } + float k[3] = {0, 0, -1}; + float axis[3]; + par_shapes__cross3(axis, nnormal, k); + par_shapes__normalize3(axis); + par_shapes_rotate(mesh, acos(nnormal[2]), axis); + par_shapes_translate(mesh, center[0], center[1], center[2]); + return mesh; +} + +par_shapes_mesh* par_shapes_create_empty() +{ + return PAR_CALLOC(par_shapes_mesh, 1); +} + +void par_shapes_translate(par_shapes_mesh* m, float x, float y, float z) +{ + float* points = m->points; + for (int i = 0; i < m->npoints; i++) { + *points++ += x; + *points++ += y; + *points++ += z; + } +} + +void par_shapes_rotate(par_shapes_mesh* mesh, float radians, float const* axis) +{ + float s = sinf(radians); + float c = cosf(radians); + float x = axis[0]; + float y = axis[1]; + float z = axis[2]; + float xy = x * y; + float yz = y * z; + float zx = z * x; + float oneMinusC = 1.0f - c; + float col0[3] = { + (((x * x) * oneMinusC) + c), + ((xy * oneMinusC) + (z * s)), ((zx * oneMinusC) - (y * s)) + }; + float col1[3] = { + ((xy * oneMinusC) - (z * s)), + (((y * y) * oneMinusC) + c), ((yz * oneMinusC) + (x * s)) + }; + float col2[3] = { + ((zx * oneMinusC) + (y * s)), + ((yz * oneMinusC) - (x * s)), (((z * z) * oneMinusC) + c) + }; + float* p = mesh->points; + for (int i = 0; i < mesh->npoints; i++, p += 3) { + float x = col0[0] * p[0] + col1[0] * p[1] + col2[0] * p[2]; + float y = col0[1] * p[0] + col1[1] * p[1] + col2[1] * p[2]; + float z = col0[2] * p[0] + col1[2] * p[1] + col2[2] * p[2]; + p[0] = x; + p[1] = y; + p[2] = z; + } + p = mesh->normals; + if (p) { + for (int i = 0; i < mesh->npoints; i++, p += 3) { + float x = col0[0] * p[0] + col1[0] * p[1] + col2[0] * p[2]; + float y = col0[1] * p[0] + col1[1] * p[1] + col2[1] * p[2]; + float z = col0[2] * p[0] + col1[2] * p[1] + col2[2] * p[2]; + p[0] = x; + p[1] = y; + p[2] = z; + } + } +} + +void par_shapes_scale(par_shapes_mesh* m, float x, float y, float z) +{ + float* points = m->points; + for (int i = 0; i < m->npoints; i++) { + *points++ *= x; + *points++ *= y; + *points++ *= z; + } +} + +void par_shapes_merge_and_free(par_shapes_mesh* dst, par_shapes_mesh* src) +{ + par_shapes_merge(dst, src); + par_shapes_free_mesh(src); +} + +void par_shapes_compute_aabb(par_shapes_mesh const* m, float* aabb) +{ + float* points = m->points; + aabb[0] = aabb[3] = points[0]; + aabb[1] = aabb[4] = points[1]; + aabb[2] = aabb[5] = points[2]; + points += 3; + for (int i = 1; i < m->npoints; i++, points += 3) { + aabb[0] = PAR_MIN(points[0], aabb[0]); + aabb[1] = PAR_MIN(points[1], aabb[1]); + aabb[2] = PAR_MIN(points[2], aabb[2]); + aabb[3] = PAR_MAX(points[0], aabb[3]); + aabb[4] = PAR_MAX(points[1], aabb[4]); + aabb[5] = PAR_MAX(points[2], aabb[5]); + } +} + +void par_shapes_invert(par_shapes_mesh* m, int face, int nfaces) +{ + nfaces = nfaces ? nfaces : m->ntriangles; + PAR_SHAPES_T* tri = m->triangles + face * 3; + for (int i = 0; i < nfaces; i++) { + PAR_SWAP(PAR_SHAPES_T, tri[0], tri[2]); + tri += 3; + } +} + +par_shapes_mesh* par_shapes_create_icosahedron() +{ + static float verts[] = { + 0.000, 0.000, 1.000, + 0.894, 0.000, 0.447, + 0.276, 0.851, 0.447, + -0.724, 0.526, 0.447, + -0.724, -0.526, 0.447, + 0.276, -0.851, 0.447, + 0.724, 0.526, -0.447, + -0.276, 0.851, -0.447, + -0.894, 0.000, -0.447, + -0.276, -0.851, -0.447, + 0.724, -0.526, -0.447, + 0.000, 0.000, -1.000 + }; + static PAR_SHAPES_T faces[] = { + 0,1,2, + 0,2,3, + 0,3,4, + 0,4,5, + 0,5,1, + 7,6,11, + 8,7,11, + 9,8,11, + 10,9,11, + 6,10,11, + 6,2,1, + 7,3,2, + 8,4,3, + 9,5,4, + 10,1,5, + 6,7,2, + 7,8,3, + 8,9,4, + 9,10,5, + 10,6,1 + }; + par_shapes_mesh* mesh = (par_shapes_mesh*) + calloc(sizeof(par_shapes_mesh), 1); + mesh->npoints = sizeof(verts) / sizeof(verts[0]) / 3; + mesh->points = PAR_MALLOC(float, sizeof(verts) / 4); + memcpy(mesh->points, verts, sizeof(verts)); + mesh->ntriangles = sizeof(faces) / sizeof(faces[0]) / 3; + mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, sizeof(faces) / 2); + memcpy(mesh->triangles, faces, sizeof(faces)); + return mesh; +} + +par_shapes_mesh* par_shapes_create_dodecahedron() +{ + static float verts[20 * 3] = { + 0.607, 0.000, 0.795, + 0.188, 0.577, 0.795, + -0.491, 0.357, 0.795, + -0.491, -0.357, 0.795, + 0.188, -0.577, 0.795, + 0.982, 0.000, 0.188, + 0.304, 0.934, 0.188, + -0.795, 0.577, 0.188, + -0.795, -0.577, 0.188, + 0.304, -0.934, 0.188, + 0.795, 0.577, -0.188, + -0.304, 0.934, -0.188, + -0.982, 0.000, -0.188, + -0.304, -0.934, -0.188, + 0.795, -0.577, -0.188, + 0.491, 0.357, -0.795, + -0.188, 0.577, -0.795, + -0.607, 0.000, -0.795, + -0.188, -0.577, -0.795, + 0.491, -0.357, -0.795, + }; + static PAR_SHAPES_T pentagons[12 * 5] = { + 0,1,2,3,4, + 5,10,6,1,0, + 6,11,7,2,1, + 7,12,8,3,2, + 8,13,9,4,3, + 9,14,5,0,4, + 15,16,11,6,10, + 16,17,12,7,11, + 17,18,13,8,12, + 18,19,14,9,13, + 19,15,10,5,14, + 19,18,17,16,15 + }; + int npentagons = sizeof(pentagons) / sizeof(pentagons[0]) / 5; + par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1); + int ncorners = sizeof(verts) / sizeof(verts[0]) / 3; + mesh->npoints = ncorners; + mesh->points = PAR_MALLOC(float, mesh->npoints * 3); + memcpy(mesh->points, verts, sizeof(verts)); + PAR_SHAPES_T const* pentagon = pentagons; + mesh->ntriangles = npentagons * 3; + mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3); + PAR_SHAPES_T* tris = mesh->triangles; + for (int p = 0; p < npentagons; p++, pentagon += 5) { + *tris++ = pentagon[0]; + *tris++ = pentagon[1]; + *tris++ = pentagon[2]; + *tris++ = pentagon[0]; + *tris++ = pentagon[2]; + *tris++ = pentagon[3]; + *tris++ = pentagon[0]; + *tris++ = pentagon[3]; + *tris++ = pentagon[4]; + } + return mesh; +} + +par_shapes_mesh* par_shapes_create_octohedron() +{ + static float verts[6 * 3] = { + 0.000, 0.000, 1.000, + 1.000, 0.000, 0.000, + 0.000, 1.000, 0.000, + -1.000, 0.000, 0.000, + 0.000, -1.000, 0.000, + 0.000, 0.000, -1.000 + }; + static PAR_SHAPES_T triangles[8 * 3] = { + 0,1,2, + 0,2,3, + 0,3,4, + 0,4,1, + 2,1,5, + 3,2,5, + 4,3,5, + 1,4,5, + }; + int ntris = sizeof(triangles) / sizeof(triangles[0]) / 3; + par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1); + int ncorners = sizeof(verts) / sizeof(verts[0]) / 3; + mesh->npoints = ncorners; + mesh->points = PAR_MALLOC(float, mesh->npoints * 3); + memcpy(mesh->points, verts, sizeof(verts)); + PAR_SHAPES_T const* triangle = triangles; + mesh->ntriangles = ntris; + mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3); + PAR_SHAPES_T* tris = mesh->triangles; + for (int p = 0; p < ntris; p++) { + *tris++ = *triangle++; + *tris++ = *triangle++; + *tris++ = *triangle++; + } + return mesh; +} + +par_shapes_mesh* par_shapes_create_tetrahedron() +{ + static float verts[4 * 3] = { + 0.000, 1.333, 0, + 0.943, 0, 0, + -0.471, 0, 0.816, + -0.471, 0, -0.816, + }; + static PAR_SHAPES_T triangles[4 * 3] = { + 2,1,0, + 3,2,0, + 1,3,0, + 1,2,3, + }; + int ntris = sizeof(triangles) / sizeof(triangles[0]) / 3; + par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1); + int ncorners = sizeof(verts) / sizeof(verts[0]) / 3; + mesh->npoints = ncorners; + mesh->points = PAR_MALLOC(float, mesh->npoints * 3); + memcpy(mesh->points, verts, sizeof(verts)); + PAR_SHAPES_T const* triangle = triangles; + mesh->ntriangles = ntris; + mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3); + PAR_SHAPES_T* tris = mesh->triangles; + for (int p = 0; p < ntris; p++) { + *tris++ = *triangle++; + *tris++ = *triangle++; + *tris++ = *triangle++; + } + return mesh; +} + +par_shapes_mesh* par_shapes_create_cube() +{ + static float verts[8 * 3] = { + 0, 0, 0, // 0 + 0, 1, 0, // 1 + 1, 1, 0, // 2 + 1, 0, 0, // 3 + 0, 0, 1, // 4 + 0, 1, 1, // 5 + 1, 1, 1, // 6 + 1, 0, 1, // 7 + }; + static PAR_SHAPES_T quads[6 * 4] = { + 7,6,5,4, // front + 0,1,2,3, // back + 6,7,3,2, // right + 5,6,2,1, // top + 4,5,1,0, // left + 7,4,0,3, // bottom + }; + int nquads = sizeof(quads) / sizeof(quads[0]) / 4; + par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1); + int ncorners = sizeof(verts) / sizeof(verts[0]) / 3; + mesh->npoints = ncorners; + mesh->points = PAR_MALLOC(float, mesh->npoints * 3); + memcpy(mesh->points, verts, sizeof(verts)); + PAR_SHAPES_T const* quad = quads; + mesh->ntriangles = nquads * 2; + mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3); + PAR_SHAPES_T* tris = mesh->triangles; + for (int p = 0; p < nquads; p++, quad += 4) { + *tris++ = quad[0]; + *tris++ = quad[1]; + *tris++ = quad[2]; + *tris++ = quad[2]; + *tris++ = quad[3]; + *tris++ = quad[0]; + } + return mesh; +} + +typedef struct { + char* cmd; + char* arg; +} par_shapes__command; + +typedef struct { + char const* name; + int weight; + int ncommands; + par_shapes__command* commands; +} par_shapes__rule; + +typedef struct { + int pc; + float position[3]; + float scale[3]; + par_shapes_mesh* orientation; + par_shapes__rule* rule; +} par_shapes__stackframe; + +static par_shapes__rule* par_shapes__pick_rule(const char* name, + par_shapes__rule* rules, int nrules) +{ + par_shapes__rule* rule = 0; + int total = 0; + for (int i = 0; i < nrules; i++) { + rule = rules + i; + if (!strcmp(rule->name, name)) { + total += rule->weight; + } + } + float r = (float) rand() / RAND_MAX; + float t = 0; + for (int i = 0; i < nrules; i++) { + rule = rules + i; + if (!strcmp(rule->name, name)) { + t += (float) rule->weight / total; + if (t >= r) { + return rule; + } + } + } + return rule; +} + +static par_shapes_mesh* par_shapes__create_turtle() +{ + const float xaxis[] = {1, 0, 0}; + const float yaxis[] = {0, 1, 0}; + const float zaxis[] = {0, 0, 1}; + par_shapes_mesh* turtle = PAR_CALLOC(par_shapes_mesh, 1); + turtle->npoints = 3; + turtle->points = PAR_CALLOC(float, turtle->npoints * 3); + par_shapes__copy3(turtle->points + 0, xaxis); + par_shapes__copy3(turtle->points + 3, yaxis); + par_shapes__copy3(turtle->points + 6, zaxis); + return turtle; +} + +static par_shapes_mesh* par_shapes__apply_turtle(par_shapes_mesh* mesh, + par_shapes_mesh* turtle, float const* pos, float const* scale) +{ + par_shapes_mesh* m = par_shapes_clone(mesh, 0); + for (int p = 0; p < m->npoints; p++) { + float* pt = m->points + p * 3; + pt[0] *= scale[0]; + pt[1] *= scale[1]; + pt[2] *= scale[2]; + par_shapes__transform3(pt, + turtle->points + 0, turtle->points + 3, turtle->points + 6); + pt[0] += pos[0]; + pt[1] += pos[1]; + pt[2] += pos[2]; + } + return m; +} + +static void par_shapes__connect(par_shapes_mesh* scene, + par_shapes_mesh* cylinder, int slices) +{ + int stacks = 1; + int npoints = (slices + 1) * (stacks + 1); + assert(scene->npoints >= npoints && "Cannot connect to empty scene."); + + // Create the new point list. + npoints = scene->npoints + (slices + 1); + float* points = PAR_MALLOC(float, npoints * 3); + memcpy(points, scene->points, sizeof(float) * scene->npoints * 3); + float* newpts = points + scene->npoints * 3; + memcpy(newpts, cylinder->points + (slices + 1) * 3, + sizeof(float) * (slices + 1) * 3); + free(scene->points); + scene->points = points; + + // Create the new triangle list. + int ntriangles = scene->ntriangles + 2 * slices * stacks; + PAR_SHAPES_T* triangles = PAR_MALLOC(PAR_SHAPES_T, ntriangles * 3); + memcpy(triangles, scene->triangles, 2 * scene->ntriangles * 3); + int v = scene->npoints - (slices + 1); + PAR_SHAPES_T* face = triangles + scene->ntriangles * 3; + for (int stack = 0; stack < stacks; stack++) { + for (int slice = 0; slice < slices; slice++) { + int next = slice + 1; + *face++ = v + slice + slices + 1; + *face++ = v + next; + *face++ = v + slice; + *face++ = v + slice + slices + 1; + *face++ = v + next + slices + 1; + *face++ = v + next; + } + v += slices + 1; + } + free(scene->triangles); + scene->triangles = triangles; + + scene->npoints = npoints; + scene->ntriangles = ntriangles; +} + +par_shapes_mesh* par_shapes_create_lsystem(char const* text, int slices, + int maxdepth) +{ + char* program; + program = PAR_MALLOC(char, strlen(text) + 1); + + // The first pass counts the number of rules and commands. + strcpy(program, text); + char *cmd = strtok(program, " "); + int nrules = 1; + int ncommands = 0; + while (cmd) { + char *arg = strtok(0, " "); + if (!arg) { + puts("lsystem error: unexpected end of program."); + break; + } + if (!strcmp(cmd, "rule")) { + nrules++; + } else { + ncommands++; + } + cmd = strtok(0, " "); + } + + // Allocate space. + par_shapes__rule* rules = PAR_MALLOC(par_shapes__rule, nrules); + par_shapes__command* commands = PAR_MALLOC(par_shapes__command, ncommands); + + // Initialize the entry rule. + par_shapes__rule* current_rule = &rules[0]; + par_shapes__command* current_command = &commands[0]; + current_rule->name = "entry"; + current_rule->weight = 1; + current_rule->ncommands = 0; + current_rule->commands = current_command; + + // The second pass fills in the structures. + strcpy(program, text); + cmd = strtok(program, " "); + while (cmd) { + char *arg = strtok(0, " "); + if (!strcmp(cmd, "rule")) { + current_rule++; + + // Split the argument into a rule name and weight. + char* dot = strchr(arg, '.'); + if (dot) { + current_rule->weight = atoi(dot + 1); + *dot = 0; + } else { + current_rule->weight = 1; + } + + current_rule->name = arg; + current_rule->ncommands = 0; + current_rule->commands = current_command; + } else { + current_rule->ncommands++; + current_command->cmd = cmd; + current_command->arg = arg; + current_command++; + } + cmd = strtok(0, " "); + } + + // For testing purposes, dump out the parsed program. + #ifdef TEST_PARSE + for (int i = 0; i < nrules; i++) { + par_shapes__rule rule = rules[i]; + printf("rule %s.%d\n", rule.name, rule.weight); + for (int c = 0; c < rule.ncommands; c++) { + par_shapes__command cmd = rule.commands[c]; + printf("\t%s %s\n", cmd.cmd, cmd.arg); + } + } + #endif + + // Instantiate the aggregated shape and the template shapes. + par_shapes_mesh* scene = PAR_CALLOC(par_shapes_mesh, 1); + par_shapes_mesh* tube = par_shapes_create_cylinder(slices, 1); + par_shapes_mesh* turtle = par_shapes__create_turtle(); + + const float xaxis[] = {1, 0, 0}; + const float yaxis[] = {0, 1, 0}; + const float zaxis[] = {0, 0, 1}; + const float units[] = {1, 1, 1}; + + // Execute the L-system program until the stack size is 0. + par_shapes__stackframe* stack = + PAR_CALLOC(par_shapes__stackframe, maxdepth); + int stackptr = 0; + stack[0].orientation = turtle; + stack[0].rule = &rules[0]; + par_shapes__copy3(stack[0].scale, units); + while (stackptr >= 0) { + + par_shapes__stackframe* frame = &stack[stackptr]; + par_shapes__rule* rule = frame->rule; + par_shapes_mesh* turtle = frame->orientation; + float* position = frame->position; + float* scale = frame->scale; + + if (frame->pc >= rule->ncommands) { + par_shapes_free_mesh(turtle); + stackptr--; + continue; + } + + par_shapes__command* cmd = rule->commands + (frame->pc++); + #ifdef DUMP_TRACE + printf("%5s %5s %5s:%d %03d\n", cmd->cmd, cmd->arg, rule->name, + frame->pc - 1, stackptr); + #endif + + float value; + if (!strcmp(cmd->cmd, "shape")) { + par_shapes_mesh* m = par_shapes__apply_turtle(tube, turtle, + position, scale); + if (!strcmp(cmd->arg, "connect")) { + par_shapes__connect(scene, m, slices); + } else { + par_shapes_merge(scene, m); + } + par_shapes_free_mesh(m); + } else if (!strcmp(cmd->cmd, "call") && stackptr < maxdepth - 1) { + rule = par_shapes__pick_rule(cmd->arg, rules, nrules); + frame = &stack[++stackptr]; + frame->rule = rule; + frame->orientation = par_shapes_clone(turtle, 0); + frame->pc = 0; + par_shapes__copy3(frame->scale, scale); + par_shapes__copy3(frame->position, position); + continue; + } else { + value = atof(cmd->arg); + if (!strcmp(cmd->cmd, "rx")) { + par_shapes_rotate(turtle, value * PAR_PI / 180.0, xaxis); + } else if (!strcmp(cmd->cmd, "ry")) { + par_shapes_rotate(turtle, value * PAR_PI / 180.0, yaxis); + } else if (!strcmp(cmd->cmd, "rz")) { + par_shapes_rotate(turtle, value * PAR_PI / 180.0, zaxis); + } else if (!strcmp(cmd->cmd, "tx")) { + float vec[3] = {value, 0, 0}; + float t[3] = { + par_shapes__dot3(turtle->points + 0, vec), + par_shapes__dot3(turtle->points + 3, vec), + par_shapes__dot3(turtle->points + 6, vec) + }; + par_shapes__add3(position, t); + } else if (!strcmp(cmd->cmd, "ty")) { + float vec[3] = {0, value, 0}; + float t[3] = { + par_shapes__dot3(turtle->points + 0, vec), + par_shapes__dot3(turtle->points + 3, vec), + par_shapes__dot3(turtle->points + 6, vec) + }; + par_shapes__add3(position, t); + } else if (!strcmp(cmd->cmd, "tz")) { + float vec[3] = {0, 0, value}; + float t[3] = { + par_shapes__dot3(turtle->points + 0, vec), + par_shapes__dot3(turtle->points + 3, vec), + par_shapes__dot3(turtle->points + 6, vec) + }; + par_shapes__add3(position, t); + } else if (!strcmp(cmd->cmd, "sx")) { + scale[0] *= value; + } else if (!strcmp(cmd->cmd, "sy")) { + scale[1] *= value; + } else if (!strcmp(cmd->cmd, "sz")) { + scale[2] *= value; + } else if (!strcmp(cmd->cmd, "sa")) { + scale[0] *= value; + scale[1] *= value; + scale[2] *= value; + } + } + } + free(stack); + free(program); + free(rules); + free(commands); + return scene; +} + +void par_shapes_unweld(par_shapes_mesh* mesh, bool create_indices) +{ + int npoints = mesh->ntriangles * 3; + float* points = PAR_MALLOC(float, 3 * npoints); + float* dst = points; + PAR_SHAPES_T const* index = mesh->triangles; + for (int i = 0; i < npoints; i++) { + float const* src = mesh->points + 3 * (*index++); + *dst++ = src[0]; + *dst++ = src[1]; + *dst++ = src[2]; + } + free(mesh->points); + mesh->points = points; + mesh->npoints = npoints; + if (create_indices) { + PAR_SHAPES_T* triangles = (PAR_SHAPES_T*) + malloc(sizeof(PAR_SHAPES_T) * 3 * mesh->ntriangles); + PAR_SHAPES_T* index = triangles; + for (int i = 0; i < mesh->ntriangles * 3; i++) { + *index++ = i; + } + free(mesh->triangles); + mesh->triangles = triangles; + } +} + +void par_shapes_compute_normals(par_shapes_mesh* m) +{ + free(m->normals); + m->normals = PAR_CALLOC(float, m->npoints * 3); + PAR_SHAPES_T const* triangle = m->triangles; + float next[3], prev[3], cp[3]; + for (int f = 0; f < m->ntriangles; f++, triangle += 3) { + float const* pa = m->points + 3 * triangle[0]; + float const* pb = m->points + 3 * triangle[1]; + float const* pc = m->points + 3 * triangle[2]; + par_shapes__copy3(next, pb); + par_shapes__subtract3(next, pa); + par_shapes__copy3(prev, pc); + par_shapes__subtract3(prev, pa); + par_shapes__cross3(cp, next, prev); + par_shapes__add3(m->normals + 3 * triangle[0], cp); + par_shapes__copy3(next, pc); + par_shapes__subtract3(next, pb); + par_shapes__copy3(prev, pa); + par_shapes__subtract3(prev, pb); + par_shapes__cross3(cp, next, prev); + par_shapes__add3(m->normals + 3 * triangle[1], cp); + par_shapes__copy3(next, pa); + par_shapes__subtract3(next, pc); + par_shapes__copy3(prev, pb); + par_shapes__subtract3(prev, pc); + par_shapes__cross3(cp, next, prev); + par_shapes__add3(m->normals + 3 * triangle[2], cp); + } + float* normal = m->normals; + for (int p = 0; p < m->npoints; p++, normal += 3) { + par_shapes__normalize3(normal); + } +} + +static void par_shapes__subdivide(par_shapes_mesh* mesh) +{ + assert(mesh->npoints == mesh->ntriangles * 3 && "Must be unwelded."); + int ntriangles = mesh->ntriangles * 4; + int npoints = ntriangles * 3; + float* points = PAR_CALLOC(float, npoints * 3); + float* dpoint = points; + float const* spoint = mesh->points; + for (int t = 0; t < mesh->ntriangles; t++, spoint += 9, dpoint += 3) { + float const* a = spoint; + float const* b = spoint + 3; + float const* c = spoint + 6; + float const* p0 = dpoint; + float const* p1 = dpoint + 3; + float const* p2 = dpoint + 6; + par_shapes__mix3(dpoint, a, b, 0.5); + par_shapes__mix3(dpoint += 3, b, c, 0.5); + par_shapes__mix3(dpoint += 3, a, c, 0.5); + par_shapes__add3(dpoint += 3, a); + par_shapes__add3(dpoint += 3, p0); + par_shapes__add3(dpoint += 3, p2); + par_shapes__add3(dpoint += 3, p0); + par_shapes__add3(dpoint += 3, b); + par_shapes__add3(dpoint += 3, p1); + par_shapes__add3(dpoint += 3, p2); + par_shapes__add3(dpoint += 3, p1); + par_shapes__add3(dpoint += 3, c); + } + free(mesh->points); + mesh->points = points; + mesh->npoints = npoints; + mesh->ntriangles = ntriangles; +} + +par_shapes_mesh* par_shapes_create_subdivided_sphere(int nsubd) +{ + par_shapes_mesh* mesh = par_shapes_create_icosahedron(); + par_shapes_unweld(mesh, false); + free(mesh->triangles); + mesh->triangles = 0; + while (nsubd--) { + par_shapes__subdivide(mesh); + } + for (int i = 0; i < mesh->npoints; i++) { + par_shapes__normalize3(mesh->points + i * 3); + } + mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, 3 * mesh->ntriangles); + for (int i = 0; i < mesh->ntriangles * 3; i++) { + mesh->triangles[i] = i; + } + par_shapes_mesh* tmp = mesh; + mesh = par_shapes_weld(mesh, 0.01, 0); + par_shapes_free_mesh(tmp); + par_shapes_compute_normals(mesh); + return mesh; +} + +par_shapes_mesh* par_shapes_create_rock(int seed, int subd) +{ + par_shapes_mesh* mesh = par_shapes_create_subdivided_sphere(subd); + struct osn_context* ctx; + par__simplex_noise(seed, &ctx); + for (int p = 0; p < mesh->npoints; p++) { + float* pt = mesh->points + p * 3; + float a = 0.25, f = 1.0; + double n = a * par__simplex_noise2(ctx, f * pt[0], f * pt[2]); + a *= 0.5; f *= 2; + n += a * par__simplex_noise2(ctx, f * pt[0], f * pt[2]); + pt[0] *= 1 + 2 * n; + pt[1] *= 1 + n; + pt[2] *= 1 + 2 * n; + if (pt[1] < 0) { + pt[1] = -pow(-pt[1], 0.5) / 2; + } + } + par__simplex_noise_free(ctx); + par_shapes_compute_normals(mesh); + return mesh; +} + +par_shapes_mesh* par_shapes_clone(par_shapes_mesh const* mesh, + par_shapes_mesh* clone) +{ + if (!clone) { + clone = PAR_CALLOC(par_shapes_mesh, 1); + } + clone->npoints = mesh->npoints; + clone->points = PAR_REALLOC(float, clone->points, 3 * clone->npoints); + memcpy(clone->points, mesh->points, sizeof(float) * 3 * clone->npoints); + clone->ntriangles = mesh->ntriangles; + clone->triangles = PAR_REALLOC(PAR_SHAPES_T, clone->triangles, 3 * + clone->ntriangles); + memcpy(clone->triangles, mesh->triangles, + sizeof(PAR_SHAPES_T) * 3 * clone->ntriangles); + if (mesh->normals) { + clone->normals = PAR_REALLOC(float, clone->normals, 3 * clone->npoints); + memcpy(clone->normals, mesh->normals, + sizeof(float) * 3 * clone->npoints); + } + if (mesh->tcoords) { + clone->tcoords = PAR_REALLOC(float, clone->tcoords, 2 * clone->npoints); + memcpy(clone->tcoords, mesh->tcoords, + sizeof(float) * 2 * clone->npoints); + } + return clone; +} + +static struct { + float const* points; + int gridsize; +} par_shapes__sort_context; + +static int par_shapes__cmp1(const void *arg0, const void *arg1) +{ + const int g = par_shapes__sort_context.gridsize; + + // Convert arg0 into a flattened grid index. + PAR_SHAPES_T d0 = *(const PAR_SHAPES_T*) arg0; + float const* p0 = par_shapes__sort_context.points + d0 * 3; + int i0 = (int) p0[0]; + int j0 = (int) p0[1]; + int k0 = (int) p0[2]; + int index0 = i0 + g * j0 + g * g * k0; + + // Convert arg1 into a flattened grid index. + PAR_SHAPES_T d1 = *(const PAR_SHAPES_T*) arg1; + float const* p1 = par_shapes__sort_context.points + d1 * 3; + int i1 = (int) p1[0]; + int j1 = (int) p1[1]; + int k1 = (int) p1[2]; + int index1 = i1 + g * j1 + g * g * k1; + + // Return the ordering. + if (index0 < index1) return -1; + if (index0 > index1) return 1; + return 0; +} + +static void par_shapes__sort_points(par_shapes_mesh* mesh, int gridsize, + PAR_SHAPES_T* sortmap) +{ + // Run qsort over a list of consecutive integers that get deferenced + // within the comparator function; this creates a reorder mapping. + for (int i = 0; i < mesh->npoints; i++) { + sortmap[i] = i; + } + par_shapes__sort_context.gridsize = gridsize; + par_shapes__sort_context.points = mesh->points; + qsort(sortmap, mesh->npoints, sizeof(PAR_SHAPES_T), par_shapes__cmp1); + + // Apply the reorder mapping to the XYZ coordinate data. + float* newpts = PAR_MALLOC(float, mesh->npoints * 3); + PAR_SHAPES_T* invmap = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints); + float* dstpt = newpts; + for (int i = 0; i < mesh->npoints; i++) { + invmap[sortmap[i]] = i; + float const* srcpt = mesh->points + 3 * sortmap[i]; + *dstpt++ = *srcpt++; + *dstpt++ = *srcpt++; + *dstpt++ = *srcpt++; + } + free(mesh->points); + mesh->points = newpts; + + // Apply the inverse reorder mapping to the triangle indices. + PAR_SHAPES_T* newinds = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3); + PAR_SHAPES_T* dstind = newinds; + PAR_SHAPES_T const* srcind = mesh->triangles; + for (int i = 0; i < mesh->ntriangles * 3; i++) { + *dstind++ = invmap[*srcind++]; + } + free(mesh->triangles); + mesh->triangles = newinds; + + // Cleanup. + memcpy(sortmap, invmap, sizeof(PAR_SHAPES_T) * mesh->npoints); + free(invmap); +} + +static void par_shapes__weld_points(par_shapes_mesh* mesh, int gridsize, + float epsilon, PAR_SHAPES_T* weldmap) +{ + // Each bin contains a "pointer" (really an index) to its first point. + // We add 1 because 0 is reserved to mean that the bin is empty. + // Since the points are spatially sorted, there's no need to store + // a point count in each bin. + PAR_SHAPES_T* bins = PAR_CALLOC(PAR_SHAPES_T, + gridsize * gridsize * gridsize); + int prev_binindex = -1; + for (int p = 0; p < mesh->npoints; p++) { + float const* pt = mesh->points + p * 3; + int i = (int) pt[0]; + int j = (int) pt[1]; + int k = (int) pt[2]; + int this_binindex = i + gridsize * j + gridsize * gridsize * k; + if (this_binindex != prev_binindex) { + bins[this_binindex] = 1 + p; + } + prev_binindex = this_binindex; + } + + // Examine all bins that intersect the epsilon-sized cube centered at each + // point, and check for colocated points within those bins. + float const* pt = mesh->points; + int nremoved = 0; + for (int p = 0; p < mesh->npoints; p++, pt += 3) { + + // Skip if this point has already been welded. + if (weldmap[p] != p) { + continue; + } + + // Build a list of bins that intersect the epsilon-sized cube. + int nearby[8]; + int nbins = 0; + int minp[3], maxp[3]; + for (int c = 0; c < 3; c++) { + minp[c] = (int) (pt[c] - epsilon); + maxp[c] = (int) (pt[c] + epsilon); + } + for (int i = minp[0]; i <= maxp[0]; i++) { + for (int j = minp[1]; j <= maxp[1]; j++) { + for (int k = minp[2]; k <= maxp[2]; k++) { + int binindex = i + gridsize * j + gridsize * gridsize * k; + PAR_SHAPES_T binvalue = *(bins + binindex); + if (binvalue > 0) { + if (nbins == 8) { + printf("Epsilon value is too large.\n"); + break; + } + nearby[nbins++] = binindex; + } + } + } + } + + // Check for colocated points in each nearby bin. + for (int b = 0; b < nbins; b++) { + int binindex = nearby[b]; + PAR_SHAPES_T binvalue = *(bins + binindex); + PAR_SHAPES_T nindex = binvalue - 1; + while (true) { + + // If this isn't "self" and it's colocated, then weld it! + if (nindex != p && weldmap[nindex] == nindex) { + float const* thatpt = mesh->points + nindex * 3; + float dist2 = par_shapes__sqrdist3(thatpt, pt); + if (dist2 < epsilon) { + weldmap[nindex] = p; + nremoved++; + } + } + + // Advance to the next point if possible. + if (++nindex >= mesh->npoints) { + break; + } + + // If the next point is outside the bin, then we're done. + float const* nextpt = mesh->points + nindex * 3; + int i = (int) nextpt[0]; + int j = (int) nextpt[1]; + int k = (int) nextpt[2]; + int nextbinindex = i + gridsize * j + gridsize * gridsize * k; + if (nextbinindex != binindex) { + break; + } + } + } + } + free(bins); + + // Apply the weldmap to the vertices. + int npoints = mesh->npoints - nremoved; + float* newpts = PAR_MALLOC(float, 3 * npoints); + float* dst = newpts; + PAR_SHAPES_T* condensed_map = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints); + PAR_SHAPES_T* cmap = condensed_map; + float const* src = mesh->points; + int ci = 0; + for (int p = 0; p < mesh->npoints; p++, src += 3) { + if (weldmap[p] == p) { + *dst++ = src[0]; + *dst++ = src[1]; + *dst++ = src[2]; + *cmap++ = ci++; + } else { + assert(weldmap[p] < p); + *cmap++ = condensed_map[weldmap[p]]; + } + } + assert(ci == npoints); + free(mesh->points); + memcpy(weldmap, condensed_map, mesh->npoints * sizeof(PAR_SHAPES_T)); + free(condensed_map); + mesh->points = newpts; + mesh->npoints = npoints; + + // Apply the weldmap to the triangle indices and skip the degenerates. + PAR_SHAPES_T const* tsrc = mesh->triangles; + PAR_SHAPES_T* tdst = mesh->triangles; + int ntriangles = 0; + for (int i = 0; i < mesh->ntriangles; i++, tsrc += 3) { + PAR_SHAPES_T a = weldmap[tsrc[0]]; + PAR_SHAPES_T b = weldmap[tsrc[1]]; + PAR_SHAPES_T c = weldmap[tsrc[2]]; + if (a != b && a != c && b != c) { + *tdst++ = a; + *tdst++ = b; + *tdst++ = c; + ntriangles++; + } + } + mesh->ntriangles = ntriangles; +} + +par_shapes_mesh* par_shapes_weld(par_shapes_mesh const* mesh, float epsilon, + PAR_SHAPES_T* weldmap) +{ + par_shapes_mesh* clone = par_shapes_clone(mesh, 0); + float aabb[6]; + int gridsize = 20; + float maxcell = gridsize - 1; + par_shapes_compute_aabb(clone, aabb); + float scale[3] = { + maxcell / (aabb[3] - aabb[0]), + maxcell / (aabb[4] - aabb[1]), + maxcell / (aabb[5] - aabb[2]), + }; + par_shapes_translate(clone, -aabb[0], -aabb[1], -aabb[2]); + par_shapes_scale(clone, scale[0], scale[1], scale[2]); + PAR_SHAPES_T* sortmap = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints); + par_shapes__sort_points(clone, gridsize, sortmap); + bool owner = false; + if (!weldmap) { + owner = true; + weldmap = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints); + } + for (int i = 0; i < mesh->npoints; i++) { + weldmap[i] = i; + } + par_shapes__weld_points(clone, gridsize, epsilon, weldmap); + if (owner) { + free(weldmap); + } else { + PAR_SHAPES_T* newmap = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints); + for (int i = 0; i < mesh->npoints; i++) { + newmap[i] = weldmap[sortmap[i]]; + } + memcpy(weldmap, newmap, sizeof(PAR_SHAPES_T) * mesh->npoints); + free(newmap); + } + free(sortmap); + par_shapes_scale(clone, 1.0 / scale[0], 1.0 / scale[1], 1.0 / scale[2]); + par_shapes_translate(clone, aabb[0], aabb[1], aabb[2]); + return clone; +} + +// ----------------------------------------------------------------------------- +// BEGIN OPEN SIMPLEX NOISE +// ----------------------------------------------------------------------------- + +#define STRETCH_CONSTANT_2D (-0.211324865405187) // (1 / sqrt(2 + 1) - 1 ) / 2; +#define SQUISH_CONSTANT_2D (0.366025403784439) // (sqrt(2 + 1) -1) / 2; +#define STRETCH_CONSTANT_3D (-1.0 / 6.0) // (1 / sqrt(3 + 1) - 1) / 3; +#define SQUISH_CONSTANT_3D (1.0 / 3.0) // (sqrt(3+1)-1)/3; +#define STRETCH_CONSTANT_4D (-0.138196601125011) // (1 / sqrt(4 + 1) - 1) / 4; +#define SQUISH_CONSTANT_4D (0.309016994374947) // (sqrt(4 + 1) - 1) / 4; + +#define NORM_CONSTANT_2D (47.0) +#define NORM_CONSTANT_3D (103.0) +#define NORM_CONSTANT_4D (30.0) + +#define DEFAULT_SEED (0LL) + +struct osn_context { + int16_t* perm; + int16_t* permGradIndex3D; +}; + +#define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0])) + +/* + * Gradients for 2D. They approximate the directions to the + * vertices of an octagon from the center. + */ +static const int8_t gradients2D[] = { + 5, 2, 2, 5, -5, 2, -2, 5, 5, -2, 2, -5, -5, -2, -2, -5, +}; + +/* + * Gradients for 3D. They approximate the directions to the + * vertices of a rhombicuboctahedron from the center, skewed so + * that the triangular and square facets can be inscribed inside + * circles of the same radius. + */ +static const signed char gradients3D[] = { + -11, 4, 4, -4, 11, 4, -4, 4, 11, 11, 4, 4, 4, 11, 4, 4, 4, 11, -11, -4, 4, + -4, -11, 4, -4, -4, 11, 11, -4, 4, 4, -11, 4, 4, -4, 11, -11, 4, -4, -4, 11, + -4, -4, 4, -11, 11, 4, -4, 4, 11, -4, 4, 4, -11, -11, -4, -4, -4, -11, -4, + -4, -4, -11, 11, -4, -4, 4, -11, -4, 4, -4, -11, +}; + +/* + * Gradients for 4D. They approximate the directions to the + * vertices of a disprismatotesseractihexadecachoron from the center, + * skewed so that the tetrahedral and cubic facets can be inscribed inside + * spheres of the same radius. + */ +static const signed char gradients4D[] = { + 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, -3, 1, 1, 1, -1, 3, 1, 1, + -1, 1, 3, 1, -1, 1, 1, 3, 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, 1, 1, -1, 1, + 3, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, 3, 1, -1, 1, 1, + 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, + 1, -1, 1, -1, 3, 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, -3, + -1, -1, 1, -1, -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, 3, 1, 1, -1, 1, 3, + 1, -1, 1, 1, 3, -1, 1, 1, 1, -3, -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, -1, + -1, 1, 1, -3, 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, -3, + -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, 3, 1, -1, -1, 1, 3, + -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, + -1, -1, 1, -1, -3, 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, -1, 1, -1, -1, + -3, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, +}; + +static double extrapolate2( + struct osn_context* ctx, int xsb, int ysb, double dx, double dy) +{ + int16_t* perm = ctx->perm; + int index = perm[(perm[xsb & 0xFF] + ysb) & 0xFF] & 0x0E; + return gradients2D[index] * dx + gradients2D[index + 1] * dy; +} + +static inline int fastFloor(double x) +{ + int xi = (int) x; + return x < xi ? xi - 1 : xi; +} + +static int allocate_perm(struct osn_context* ctx, int nperm, int ngrad) +{ + if (ctx->perm) + free(ctx->perm); + if (ctx->permGradIndex3D) + free(ctx->permGradIndex3D); + ctx->perm = (int16_t*) malloc(sizeof(*ctx->perm) * nperm); + if (!ctx->perm) + return -ENOMEM; + ctx->permGradIndex3D = + (int16_t*) malloc(sizeof(*ctx->permGradIndex3D) * ngrad); + if (!ctx->permGradIndex3D) { + free(ctx->perm); + return -ENOMEM; + } + return 0; +} + +static int par__simplex_noise(int64_t seed, struct osn_context** ctx) +{ + int rc; + int16_t source[256]; + int i; + int16_t* perm; + int16_t* permGradIndex3D; + + *ctx = (struct osn_context*) malloc(sizeof(**ctx)); + if (!(*ctx)) + return -ENOMEM; + (*ctx)->perm = NULL; + (*ctx)->permGradIndex3D = NULL; + + rc = allocate_perm(*ctx, 256, 256); + if (rc) { + free(*ctx); + return rc; + } + + perm = (*ctx)->perm; + permGradIndex3D = (*ctx)->permGradIndex3D; + + for (i = 0; i < 256; i++) + source[i] = (int16_t) i; + seed = seed * 6364136223846793005LL + 1442695040888963407LL; + seed = seed * 6364136223846793005LL + 1442695040888963407LL; + seed = seed * 6364136223846793005LL + 1442695040888963407LL; + for (i = 255; i >= 0; i--) { + seed = seed * 6364136223846793005LL + 1442695040888963407LL; + int r = (int) ((seed + 31) % (i + 1)); + if (r < 0) + r += (i + 1); + perm[i] = source[r]; + permGradIndex3D[i] = + (short) ((perm[i] % (ARRAYSIZE(gradients3D) / 3)) * 3); + source[r] = source[i]; + } + return 0; +} + +static void par__simplex_noise_free(struct osn_context* ctx) +{ + if (!ctx) + return; + if (ctx->perm) { + free(ctx->perm); + ctx->perm = NULL; + } + if (ctx->permGradIndex3D) { + free(ctx->permGradIndex3D); + ctx->permGradIndex3D = NULL; + } + free(ctx); +} + +static double par__simplex_noise2(struct osn_context* ctx, double x, double y) +{ + // Place input coordinates onto grid. + double stretchOffset = (x + y) * STRETCH_CONSTANT_2D; + double xs = x + stretchOffset; + double ys = y + stretchOffset; + + // Floor to get grid coordinates of rhombus (stretched square) super-cell + // origin. + int xsb = fastFloor(xs); + int ysb = fastFloor(ys); + + // Skew out to get actual coordinates of rhombus origin. We'll need these + // later. + double squishOffset = (xsb + ysb) * SQUISH_CONSTANT_2D; + double xb = xsb + squishOffset; + double yb = ysb + squishOffset; + + // Compute grid coordinates relative to rhombus origin. + double xins = xs - xsb; + double yins = ys - ysb; + + // Sum those together to get a value that determines which region we're in. + double inSum = xins + yins; + + // Positions relative to origin point. + double dx0 = x - xb; + double dy0 = y - yb; + + // We'll be defining these inside the next block and using them afterwards. + double dx_ext, dy_ext; + int xsv_ext, ysv_ext; + + double value = 0; + + // Contribution (1,0) + double dx1 = dx0 - 1 - SQUISH_CONSTANT_2D; + double dy1 = dy0 - 0 - SQUISH_CONSTANT_2D; + double attn1 = 2 - dx1 * dx1 - dy1 * dy1; + if (attn1 > 0) { + attn1 *= attn1; + value += attn1 * attn1 * extrapolate2(ctx, xsb + 1, ysb + 0, dx1, dy1); + } + + // Contribution (0,1) + double dx2 = dx0 - 0 - SQUISH_CONSTANT_2D; + double dy2 = dy0 - 1 - SQUISH_CONSTANT_2D; + double attn2 = 2 - dx2 * dx2 - dy2 * dy2; + if (attn2 > 0) { + attn2 *= attn2; + value += attn2 * attn2 * extrapolate2(ctx, xsb + 0, ysb + 1, dx2, dy2); + } + + if (inSum <= 1) { // We're inside the triangle (2-Simplex) at (0,0) + double zins = 1 - inSum; + if (zins > xins || zins > yins) { + if (xins > yins) { + xsv_ext = xsb + 1; + ysv_ext = ysb - 1; + dx_ext = dx0 - 1; + dy_ext = dy0 + 1; + } else { + xsv_ext = xsb - 1; + ysv_ext = ysb + 1; + dx_ext = dx0 + 1; + dy_ext = dy0 - 1; + } + } else { //(1,0) and (0,1) are the closest two vertices. + xsv_ext = xsb + 1; + ysv_ext = ysb + 1; + dx_ext = dx0 - 1 - 2 * SQUISH_CONSTANT_2D; + dy_ext = dy0 - 1 - 2 * SQUISH_CONSTANT_2D; + } + } else { // We're inside the triangle (2-Simplex) at (1,1) + double zins = 2 - inSum; + if (zins < xins || zins < yins) { + if (xins > yins) { + xsv_ext = xsb + 2; + ysv_ext = ysb + 0; + dx_ext = dx0 - 2 - 2 * SQUISH_CONSTANT_2D; + dy_ext = dy0 + 0 - 2 * SQUISH_CONSTANT_2D; + } else { + xsv_ext = xsb + 0; + ysv_ext = ysb + 2; + dx_ext = dx0 + 0 - 2 * SQUISH_CONSTANT_2D; + dy_ext = dy0 - 2 - 2 * SQUISH_CONSTANT_2D; + } + } else { //(1,0) and (0,1) are the closest two vertices. + dx_ext = dx0; + dy_ext = dy0; + xsv_ext = xsb; + ysv_ext = ysb; + } + xsb += 1; + ysb += 1; + dx0 = dx0 - 1 - 2 * SQUISH_CONSTANT_2D; + dy0 = dy0 - 1 - 2 * SQUISH_CONSTANT_2D; + } + + // Contribution (0,0) or (1,1) + double attn0 = 2 - dx0 * dx0 - dy0 * dy0; + if (attn0 > 0) { + attn0 *= attn0; + value += attn0 * attn0 * extrapolate2(ctx, xsb, ysb, dx0, dy0); + } + + // Extra Vertex + double attn_ext = 2 - dx_ext * dx_ext - dy_ext * dy_ext; + if (attn_ext > 0) { + attn_ext *= attn_ext; + value += attn_ext * attn_ext * + extrapolate2(ctx, xsv_ext, ysv_ext, dx_ext, dy_ext); + } + + return value / NORM_CONSTANT_2D; +} + +void par_shapes_remove_degenerate(par_shapes_mesh* mesh, float mintriarea) +{ + int ntriangles = 0; + PAR_SHAPES_T* triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3); + PAR_SHAPES_T* dst = triangles; + PAR_SHAPES_T const* src = mesh->triangles; + float next[3], prev[3], cp[3]; + float mincplen2 = (mintriarea * 2) * (mintriarea * 2); + for (int f = 0; f < mesh->ntriangles; f++, src += 3) { + float const* pa = mesh->points + 3 * src[0]; + float const* pb = mesh->points + 3 * src[1]; + float const* pc = mesh->points + 3 * src[2]; + par_shapes__copy3(next, pb); + par_shapes__subtract3(next, pa); + par_shapes__copy3(prev, pc); + par_shapes__subtract3(prev, pa); + par_shapes__cross3(cp, next, prev); + float cplen2 = par_shapes__dot3(cp, cp); + if (cplen2 >= mincplen2) { + *dst++ = src[0]; + *dst++ = src[1]; + *dst++ = src[2]; + ntriangles++; + } + } + mesh->ntriangles = ntriangles; + free(mesh->triangles); + mesh->triangles = triangles; +} + +#endif // PAR_SHAPES_IMPLEMENTATION diff --git a/CameraParameterEstimation/apps/basics/extern/stb_image.h b/CameraParameterEstimation/apps/basics/extern/stb_image.h new file mode 100644 index 0000000..55adcf7 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/stb_image.h @@ -0,0 +1,6760 @@ +/* stb_image - v2.12 - public domain image loader - http://nothings.org/stb_image.h + no warranty implied; use at your own risk + + Do this: + #define STB_IMAGE_IMPLEMENTATION + before you include this file in *one* C or C++ file to create the implementation. + + // i.e. it should look like this: + #include ... + #include ... + #include ... + #define STB_IMAGE_IMPLEMENTATION + #include "stb_image.h" + + You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. + And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free + + + QUICK NOTES: + Primarily of interest to game developers and other people who can + avoid problematic images and only need the trivial interface + + JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) + PNG 1/2/4/8-bit-per-channel (16 bpc not supported) + + TGA (not sure what subset, if a subset) + BMP non-1bpp, non-RLE + PSD (composited view only, no extra channels, 8/16 bit-per-channel) + + GIF (*comp always reports as 4-channel) + HDR (radiance rgbE format) + PIC (Softimage PIC) + PNM (PPM and PGM binary only) + + Animated GIF still needs a proper API, but here's one way to do it: + http://gist.github.com/urraka/685d9a6340b26b830d49 + + - decode from memory or through FILE (define STBI_NO_STDIO to remove code) + - decode from arbitrary I/O callbacks + - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) + + Full documentation under "DOCUMENTATION" below. + + + Revision 2.00 release notes: + + - Progressive JPEG is now supported. + + - PPM and PGM binary formats are now supported, thanks to Ken Miller. + + - x86 platforms now make use of SSE2 SIMD instructions for + JPEG decoding, and ARM platforms can use NEON SIMD if requested. + This work was done by Fabian "ryg" Giesen. SSE2 is used by + default, but NEON must be enabled explicitly; see docs. + + With other JPEG optimizations included in this version, we see + 2x speedup on a JPEG on an x86 machine, and a 1.5x speedup + on a JPEG on an ARM machine, relative to previous versions of this + library. The same results will not obtain for all JPGs and for all + x86/ARM machines. (Note that progressive JPEGs are significantly + slower to decode than regular JPEGs.) This doesn't mean that this + is the fastest JPEG decoder in the land; rather, it brings it + closer to parity with standard libraries. If you want the fastest + decode, look elsewhere. (See "Philosophy" section of docs below.) + + See final bullet items below for more info on SIMD. + + - Added STBI_MALLOC, STBI_REALLOC, and STBI_FREE macros for replacing + the memory allocator. Unlike other STBI libraries, these macros don't + support a context parameter, so if you need to pass a context in to + the allocator, you'll have to store it in a global or a thread-local + variable. + + - Split existing STBI_NO_HDR flag into two flags, STBI_NO_HDR and + STBI_NO_LINEAR. + STBI_NO_HDR: suppress implementation of .hdr reader format + STBI_NO_LINEAR: suppress high-dynamic-range light-linear float API + + - You can suppress implementation of any of the decoders to reduce + your code footprint by #defining one or more of the following + symbols before creating the implementation. + + STBI_NO_JPEG + STBI_NO_PNG + STBI_NO_BMP + STBI_NO_PSD + STBI_NO_TGA + STBI_NO_GIF + STBI_NO_HDR + STBI_NO_PIC + STBI_NO_PNM (.ppm and .pgm) + + - You can request *only* certain decoders and suppress all other ones + (this will be more forward-compatible, as addition of new decoders + doesn't require you to disable them explicitly): + + STBI_ONLY_JPEG + STBI_ONLY_PNG + STBI_ONLY_BMP + STBI_ONLY_PSD + STBI_ONLY_TGA + STBI_ONLY_GIF + STBI_ONLY_HDR + STBI_ONLY_PIC + STBI_ONLY_PNM (.ppm and .pgm) + + Note that you can define multiples of these, and you will get all + of them ("only x" and "only y" is interpreted to mean "only x&y"). + + - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still + want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB + + - Compilation of all SIMD code can be suppressed with + #define STBI_NO_SIMD + It should not be necessary to disable SIMD unless you have issues + compiling (e.g. using an x86 compiler which doesn't support SSE + intrinsics or that doesn't support the method used to detect + SSE2 support at run-time), and even those can be reported as + bugs so I can refine the built-in compile-time checking to be + smarter. + + - The old STBI_SIMD system which allowed installing a user-defined + IDCT etc. has been removed. If you need this, don't upgrade. My + assumption is that almost nobody was doing this, and those who + were will find the built-in SIMD more satisfactory anyway. + + - RGB values computed for JPEG images are slightly different from + previous versions of stb_image. (This is due to using less + integer precision in SIMD.) The C code has been adjusted so + that the same RGB values will be computed regardless of whether + SIMD support is available, so your app should always produce + consistent results. But these results are slightly different from + previous versions. (Specifically, about 3% of available YCbCr values + will compute different RGB results from pre-1.49 versions by +-1; + most of the deviating values are one smaller in the G channel.) + + - If you must produce consistent results with previous versions of + stb_image, #define STBI_JPEG_OLD and you will get the same results + you used to; however, you will not get the SIMD speedups for + the YCbCr-to-RGB conversion step (although you should still see + significant JPEG speedup from the other changes). + + Please note that STBI_JPEG_OLD is a temporary feature; it will be + removed in future versions of the library. It is only intended for + near-term back-compatibility use. + + + Latest revision history: + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 + RGB-format JPEG; remove white matting in PSD; + allocate large structures on the stack; + correct channel count for PNG & BMP + 2.10 (2016-01-22) avoid warning introduced in 2.09 + 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED + 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA + 2.07 (2015-09-13) partial animated GIF support + limited 16-bit PSD support + minor bugs, code cleanup, and compiler warnings + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value + 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning + 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit + 2.03 (2015-04-12) additional corruption checking + stbi_set_flip_vertically_on_load + fix NEON support; fix mingw support + 2.02 (2015-01-19) fix incorrect assert, fix warning + 2.01 (2015-01-17) fix various warnings + 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG + 2.00 (2014-12-25) optimize JPEG, including x86 SSE2 & ARM NEON SIMD + progressive JPEG + PGM/PPM support + STBI_MALLOC,STBI_REALLOC,STBI_FREE + STBI_NO_*, STBI_ONLY_* + GIF bugfix + + See end of file for full revision history. + + + ============================ Contributors ========================= + + Image formats Extensions, features + Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) + Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) + Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) + Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) + Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) + Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) + Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) + urraka@github (animated gif) Junggon Kim (PNM comments) + Daniel Gibson (16-bit TGA) + + Optimizations & bugfixes + Fabian "ryg" Giesen + Arseny Kapoulkine + + Bug & warning fixes + Marc LeBlanc David Woo Guillaume George Martins Mozeiko + Christpher Lloyd Martin Golini Jerry Jansson Joseph Thomson + Dave Moore Roy Eltham Hayaki Saito Phil Jordan + Won Chun Luke Graham Johan Duparc Nathan Reed + the Horde3D community Thomas Ruf Ronny Chevalier Nick Verigakis + Janez Zemva John Bartholomew Michal Cichon svdijk@github + Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson + Laurent Gomila Cort Stratton Sergio Gonzalez romigrou@github + Aruelien Pocheville Thibault Reuille Cass Everitt Matthew Gregan + Ryamond Barbiero Paul Du Bois Engin Manap snagar@github + Michaelangel007@github Oriol Ferrer Mesia socks-the-fox + Blazej Dariusz Roszkowski + + +LICENSE + +This software is dual-licensed to the public domain and under the following +license: you are granted a perpetual, irrevocable license to copy, modify, +publish, and distribute this file as you see fit. + +*/ + +#ifndef STBI_INCLUDE_STB_IMAGE_H +#define STBI_INCLUDE_STB_IMAGE_H + +// DOCUMENTATION +// +// Limitations: +// - no 16-bit-per-channel PNG +// - no 12-bit-per-channel JPEG +// - no JPEGs with arithmetic coding +// - no 1-bit BMP +// - GIF always returns *comp=4 +// +// Basic usage (see HDR discussion below for HDR usage): +// int x,y,n; +// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); +// // ... process data if not NULL ... +// // ... x = width, y = height, n = # 8-bit components per pixel ... +// // ... replace '0' with '1'..'4' to force that many components per pixel +// // ... but 'n' will always be the number that it would have been if you said 0 +// stbi_image_free(data) +// +// Standard parameters: +// int *x -- outputs image width in pixels +// int *y -- outputs image height in pixels +// int *comp -- outputs # of image components in image file +// int req_comp -- if non-zero, # of image components requested in result +// +// The return value from an image loader is an 'unsigned char *' which points +// to the pixel data, or NULL on an allocation failure or if the image is +// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, +// with each pixel consisting of N interleaved 8-bit components; the first +// pixel pointed to is top-left-most in the image. There is no padding between +// image scanlines or between pixels, regardless of format. The number of +// components N is 'req_comp' if req_comp is non-zero, or *comp otherwise. +// If req_comp is non-zero, *comp has the number of components that _would_ +// have been output otherwise. E.g. if you set req_comp to 4, you will always +// get RGBA output, but you can check *comp to see if it's trivially opaque +// because e.g. there were only 3 channels in the source image. +// +// An output image with N components has the following components interleaved +// in this order in each pixel: +// +// N=#comp components +// 1 grey +// 2 grey, alpha +// 3 red, green, blue +// 4 red, green, blue, alpha +// +// If image loading fails for any reason, the return value will be NULL, +// and *x, *y, *comp will be unchanged. The function stbi_failure_reason() +// can be queried for an extremely brief, end-user unfriendly explanation +// of why the load failed. Define STBI_NO_FAILURE_STRINGS to avoid +// compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly +// more user-friendly ones. +// +// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. +// +// =========================================================================== +// +// Philosophy +// +// stb libraries are designed with the following priorities: +// +// 1. easy to use +// 2. easy to maintain +// 3. good performance +// +// Sometimes I let "good performance" creep up in priority over "easy to maintain", +// and for best performance I may provide less-easy-to-use APIs that give higher +// performance, in addition to the easy to use ones. Nevertheless, it's important +// to keep in mind that from the standpoint of you, a client of this library, +// all you care about is #1 and #3, and stb libraries do not emphasize #3 above all. +// +// Some secondary priorities arise directly from the first two, some of which +// make more explicit reasons why performance can't be emphasized. +// +// - Portable ("ease of use") +// - Small footprint ("easy to maintain") +// - No dependencies ("ease of use") +// +// =========================================================================== +// +// I/O callbacks +// +// I/O callbacks allow you to read from arbitrary sources, like packaged +// files or some other source. Data read from callbacks are processed +// through a small internal buffer (currently 128 bytes) to try to reduce +// overhead. +// +// The three functions you must define are "read" (reads some bytes of data), +// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). +// +// =========================================================================== +// +// SIMD support +// +// The JPEG decoder will try to automatically use SIMD kernels on x86 when +// supported by the compiler. For ARM Neon support, you must explicitly +// request it. +// +// (The old do-it-yourself SIMD API is no longer supported in the current +// code.) +// +// On x86, SSE2 will automatically be used when available based on a run-time +// test; if not, the generic C versions are used as a fall-back. On ARM targets, +// the typical path is to have separate builds for NEON and non-NEON devices +// (at least this is true for iOS and Android). Therefore, the NEON support is +// toggled by a build flag: define STBI_NEON to get NEON loops. +// +// The output of the JPEG decoder is slightly different from versions where +// SIMD support was introduced (that is, for versions before 1.49). The +// difference is only +-1 in the 8-bit RGB channels, and only on a small +// fraction of pixels. You can force the pre-1.49 behavior by defining +// STBI_JPEG_OLD, but this will disable some of the SIMD decoding path +// and hence cost some performance. +// +// If for some reason you do not want to use any of SIMD code, or if +// you have issues compiling it, you can disable it entirely by +// defining STBI_NO_SIMD. +// +// =========================================================================== +// +// HDR image support (disable by defining STBI_NO_HDR) +// +// stb_image now supports loading HDR images in general, and currently +// the Radiance .HDR file format, although the support is provided +// generically. You can still load any file through the existing interface; +// if you attempt to load an HDR file, it will be automatically remapped to +// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; +// both of these constants can be reconfigured through this interface: +// +// stbi_hdr_to_ldr_gamma(2.2f); +// stbi_hdr_to_ldr_scale(1.0f); +// +// (note, do not use _inverse_ constants; stbi_image will invert them +// appropriately). +// +// Additionally, there is a new, parallel interface for loading files as +// (linear) floats to preserve the full dynamic range: +// +// float *data = stbi_loadf(filename, &x, &y, &n, 0); +// +// If you load LDR images through this interface, those images will +// be promoted to floating point values, run through the inverse of +// constants corresponding to the above: +// +// stbi_ldr_to_hdr_scale(1.0f); +// stbi_ldr_to_hdr_gamma(2.2f); +// +// Finally, given a filename (or an open file or memory block--see header +// file for details) containing image data, you can query for the "most +// appropriate" interface to use (that is, whether the image is HDR or +// not), using: +// +// stbi_is_hdr(char *filename); +// +// =========================================================================== +// +// iPhone PNG support: +// +// By default we convert iphone-formatted PNGs back to RGB, even though +// they are internally encoded differently. You can disable this conversion +// by by calling stbi_convert_iphone_png_to_rgb(0), in which case +// you will always just get the native iphone "format" through (which +// is BGR stored in RGB). +// +// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per +// pixel to remove any premultiplied alpha *only* if the image file explicitly +// says there's premultiplied data (currently only happens in iPhone images, +// and only if iPhone convert-to-rgb processing is on). +// + + +#ifndef STBI_NO_STDIO +#include +#endif // STBI_NO_STDIO + +#define STBI_VERSION 1 + +enum +{ + STBI_default = 0, // only used for req_comp + + STBI_grey = 1, + STBI_grey_alpha = 2, + STBI_rgb = 3, + STBI_rgb_alpha = 4 +}; + +typedef unsigned char stbi_uc; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef STB_IMAGE_STATIC +#define STBIDEF static +#else +#define STBIDEF extern +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// PRIMARY API - works on images of any type +// + +// +// load image by filename, open file, or memory buffer +// + +typedef struct +{ + int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative + int (*eof) (void *user); // returns nonzero if we are at end of file/data +} stbi_io_callbacks; + +STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp); +STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *comp, int req_comp); +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *comp, int req_comp); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); +// for stbi_load_from_file, file pointer is left pointing immediately after image +#endif + +#ifndef STBI_NO_LINEAR + STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp); + STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); + STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); + + #ifndef STBI_NO_STDIO + STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); + #endif +#endif + +#ifndef STBI_NO_HDR + STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); + STBIDEF void stbi_hdr_to_ldr_scale(float scale); +#endif // STBI_NO_HDR + +#ifndef STBI_NO_LINEAR + STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); + STBIDEF void stbi_ldr_to_hdr_scale(float scale); +#endif // STBI_NO_LINEAR + +// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename); +STBIDEF int stbi_is_hdr_from_file(FILE *f); +#endif // STBI_NO_STDIO + + +// get a VERY brief reason for failure +// NOT THREADSAFE +STBIDEF const char *stbi_failure_reason (void); + +// free the loaded image -- this is just free() +STBIDEF void stbi_image_free (void *retval_from_stbi_load); + +// get image dimensions & components without fully decoding +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); + +#endif + + + +// for image formats that explicitly notate that they have premultiplied alpha, +// we just return the colors as stored in the file. set this flag to force +// unpremultiplication. results are undefined if the unpremultiply overflow. +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + +// indicate whether we should process iphone images back to canonical format, +// or just pass them through "as-is" +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + +// flip the image vertically, so the first pixel in the output array is the bottom left +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); + +// ZLIB client - used by PNG, available for other purposes + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); +STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + +STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + + +#ifdef __cplusplus +} +#endif + +// +// +//// end header file ///////////////////////////////////////////////////// +#endif // STBI_INCLUDE_STB_IMAGE_H + +#ifdef STB_IMAGE_IMPLEMENTATION + +#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ + || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ + || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ + || defined(STBI_ONLY_ZLIB) + #ifndef STBI_ONLY_JPEG + #define STBI_NO_JPEG + #endif + #ifndef STBI_ONLY_PNG + #define STBI_NO_PNG + #endif + #ifndef STBI_ONLY_BMP + #define STBI_NO_BMP + #endif + #ifndef STBI_ONLY_PSD + #define STBI_NO_PSD + #endif + #ifndef STBI_ONLY_TGA + #define STBI_NO_TGA + #endif + #ifndef STBI_ONLY_GIF + #define STBI_NO_GIF + #endif + #ifndef STBI_ONLY_HDR + #define STBI_NO_HDR + #endif + #ifndef STBI_ONLY_PIC + #define STBI_NO_PIC + #endif + #ifndef STBI_ONLY_PNM + #define STBI_NO_PNM + #endif +#endif + +#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) +#define STBI_NO_ZLIB +#endif + + +#include +#include // ptrdiff_t on osx +#include +#include + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) +#include // ldexp +#endif + +#ifndef STBI_NO_STDIO +#include +#endif + +#ifndef STBI_ASSERT +#include +#define STBI_ASSERT(x) assert(x) +#endif + + +#ifndef _MSC_VER + #ifdef __cplusplus + #define stbi_inline inline + #else + #define stbi_inline + #endif +#else + #define stbi_inline __forceinline +#endif + + +#ifdef _MSC_VER +typedef unsigned short stbi__uint16; +typedef signed short stbi__int16; +typedef unsigned int stbi__uint32; +typedef signed int stbi__int32; +#else +#include +typedef uint16_t stbi__uint16; +typedef int16_t stbi__int16; +typedef uint32_t stbi__uint32; +typedef int32_t stbi__int32; +#endif + +// should produce compiler error if size is wrong +typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; + +#ifdef _MSC_VER +#define STBI_NOTUSED(v) (void)(v) +#else +#define STBI_NOTUSED(v) (void)sizeof(v) +#endif + +#ifdef _MSC_VER +#define STBI_HAS_LROTL +#endif + +#ifdef STBI_HAS_LROTL + #define stbi_lrot(x,y) _lrotl(x,y) +#else + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) +#endif + +#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) +// ok +#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." +#endif + +#ifndef STBI_MALLOC +#define STBI_MALLOC(sz) malloc(sz) +#define STBI_REALLOC(p,newsz) realloc(p,newsz) +#define STBI_FREE(p) free(p) +#endif + +#ifndef STBI_REALLOC_SIZED +#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) +#endif + +// x86/x64 detection +#if defined(__x86_64__) || defined(_M_X64) +#define STBI__X64_TARGET +#elif defined(__i386) || defined(_M_IX86) +#define STBI__X86_TARGET +#endif + +#if defined(__GNUC__) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) +// NOTE: not clear do we actually need this for the 64-bit path? +// gcc doesn't support sse2 intrinsics unless you compile with -msse2, +// (but compiling with -msse2 allows the compiler to use SSE2 everywhere; +// this is just broken and gcc are jerks for not fixing it properly +// http://www.virtualdub.org/blog/pivot/entry.php?id=363 ) +#define STBI_NO_SIMD +#endif + +#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) +// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET +// +// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the +// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. +// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not +// simultaneously enabling "-mstackrealign". +// +// See https://github.com/nothings/stb/issues/81 for more information. +// +// So default to no SSE2 on 32-bit MinGW. If you've read this far and added +// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. +#define STBI_NO_SIMD +#endif + +#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) +#define STBI_SSE2 +#include + +#ifdef _MSC_VER + +#if _MSC_VER >= 1400 // not VC6 +#include // __cpuid +static int stbi__cpuid3(void) +{ + int info[4]; + __cpuid(info,1); + return info[3]; +} +#else +static int stbi__cpuid3(void) +{ + int res; + __asm { + mov eax,1 + cpuid + mov res,edx + } + return res; +} +#endif + +#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name + +static int stbi__sse2_available() +{ + int info3 = stbi__cpuid3(); + return ((info3 >> 26) & 1) != 0; +} +#else // assume GCC-style if not VC++ +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) + +static int stbi__sse2_available() +{ +#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later + // GCC 4.8+ has a nice way to do this + return __builtin_cpu_supports("sse2"); +#else + // portable way to do this, preferably without using GCC inline ASM? + // just bail for now. + return 0; +#endif +} +#endif +#endif + +// ARM NEON +#if defined(STBI_NO_SIMD) && defined(STBI_NEON) +#undef STBI_NEON +#endif + +#ifdef STBI_NEON +#include +// assume GCC or Clang on ARM targets +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) +#endif + +#ifndef STBI_SIMD_ALIGN +#define STBI_SIMD_ALIGN(type, name) type name +#endif + +/////////////////////////////////////////////// +// +// stbi__context struct and start_xxx functions + +// stbi__context structure is our basic context used by all images, so it +// contains all the IO context, plus some basic image information +typedef struct +{ + stbi__uint32 img_x, img_y; + int img_n, img_out_n; + + stbi_io_callbacks io; + void *io_user_data; + + int read_from_callbacks; + int buflen; + stbi_uc buffer_start[128]; + + stbi_uc *img_buffer, *img_buffer_end; + stbi_uc *img_buffer_original, *img_buffer_original_end; +} stbi__context; + + +static void stbi__refill_buffer(stbi__context *s); + +// initialize a memory-decode context +static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) +{ + s->io.read = NULL; + s->read_from_callbacks = 0; + s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; + s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; +} + +// initialize a callback-based context +static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user) +{ + s->io = *c; + s->io_user_data = user; + s->buflen = sizeof(s->buffer_start); + s->read_from_callbacks = 1; + s->img_buffer_original = s->buffer_start; + stbi__refill_buffer(s); + s->img_buffer_original_end = s->img_buffer_end; +} + +#ifndef STBI_NO_STDIO + +static int stbi__stdio_read(void *user, char *data, int size) +{ + return (int) fread(data,1,size,(FILE*) user); +} + +static void stbi__stdio_skip(void *user, int n) +{ + fseek((FILE*) user, n, SEEK_CUR); +} + +static int stbi__stdio_eof(void *user) +{ + return feof((FILE*) user); +} + +static stbi_io_callbacks stbi__stdio_callbacks = +{ + stbi__stdio_read, + stbi__stdio_skip, + stbi__stdio_eof, +}; + +static void stbi__start_file(stbi__context *s, FILE *f) +{ + stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); +} + +//static void stop_file(stbi__context *s) { } + +#endif // !STBI_NO_STDIO + +static void stbi__rewind(stbi__context *s) +{ + // conceptually rewind SHOULD rewind to the beginning of the stream, + // but we just rewind to the beginning of the initial buffer, because + // we only use it after doing 'test', which only ever looks at at most 92 bytes + s->img_buffer = s->img_buffer_original; + s->img_buffer_end = s->img_buffer_original_end; +} + +#ifndef STBI_NO_JPEG +static int stbi__jpeg_test(stbi__context *s); +static stbi_uc *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNG +static int stbi__png_test(stbi__context *s); +static stbi_uc *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_BMP +static int stbi__bmp_test(stbi__context *s); +static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_TGA +static int stbi__tga_test(stbi__context *s); +static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s); +static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_HDR +static int stbi__hdr_test(stbi__context *s); +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_test(stbi__context *s); +static stbi_uc *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_GIF +static int stbi__gif_test(stbi__context *s); +static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNM +static int stbi__pnm_test(stbi__context *s); +static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +// this is not threadsafe +static const char *stbi__g_failure_reason; + +STBIDEF const char *stbi_failure_reason(void) +{ + return stbi__g_failure_reason; +} + +static int stbi__err(const char *str) +{ + stbi__g_failure_reason = str; + return 0; +} + +static void *stbi__malloc(size_t size) +{ + return STBI_MALLOC(size); +} + +// stbi__err - error +// stbi__errpf - error returning pointer to float +// stbi__errpuc - error returning pointer to unsigned char + +#ifdef STBI_NO_FAILURE_STRINGS + #define stbi__err(x,y) 0 +#elif defined(STBI_FAILURE_USERMSG) + #define stbi__err(x,y) stbi__err(y) +#else + #define stbi__err(x,y) stbi__err(x) +#endif + +#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) +#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) + +STBIDEF void stbi_image_free(void *retval_from_stbi_load) +{ + STBI_FREE(retval_from_stbi_load); +} + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); +#endif + +#ifndef STBI_NO_HDR +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); +#endif + +static int stbi__vertically_flip_on_load = 0; + +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load = flag_true_if_should_flip; +} + +static unsigned char *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + #ifndef STBI_NO_JPEG + if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_PNG + if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_BMP + if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_GIF + if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_PSD + if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_PIC + if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp); + #endif + #ifndef STBI_NO_PNM + if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp); + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + float *hdr = stbi__hdr_load(s, x,y,comp,req_comp); + return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } + #endif + + #ifndef STBI_NO_TGA + // test tga last because it's a crappy test! + if (stbi__tga_test(s)) + return stbi__tga_load(s,x,y,comp,req_comp); + #endif + + return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); +} + +static unsigned char *stbi__load_flip(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *result = stbi__load_main(s, x, y, comp, req_comp); + + if (stbi__vertically_flip_on_load && result != NULL) { + int w = *x, h = *y; + int depth = req_comp ? req_comp : *comp; + int row,col,z; + stbi_uc temp; + + // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once + for (row = 0; row < (h>>1); row++) { + for (col = 0; col < w; col++) { + for (z = 0; z < depth; z++) { + temp = result[(row * w + col) * depth + z]; + result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z]; + result[((h - row - 1) * w + col) * depth + z] = temp; + } + } + } + } + + return result; +} + +#ifndef STBI_NO_HDR +static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) +{ + if (stbi__vertically_flip_on_load && result != NULL) { + int w = *x, h = *y; + int depth = req_comp ? req_comp : *comp; + int row,col,z; + float temp; + + // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once + for (row = 0; row < (h>>1); row++) { + for (col = 0; col < w; col++) { + for (z = 0; z < depth; z++) { + temp = result[(row * w + col) * depth + z]; + result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z]; + result[((h - row - 1) * w + col) * depth + z] = temp; + } + } + } + } +} +#endif + +#ifndef STBI_NO_STDIO + +static FILE *stbi__fopen(char const *filename, char const *mode) +{ + FILE *f; +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != fopen_s(&f, filename, mode)) + f=0; +#else + f = fopen(filename, mode); +#endif + return f; +} + + +STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + unsigned char *result; + if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_flip(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} +#endif //!STBI_NO_STDIO + +STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_flip(&s,x,y,comp,req_comp); +} + +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__load_flip(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_LINEAR +static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *data; + #ifndef STBI_NO_HDR + printf("HDR!\n"); + if (stbi__hdr_test(s)) { + float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp); + if (hdr_data) + stbi__float_postprocess(hdr_data,x,y,comp,req_comp); + return hdr_data; + } + #endif + printf("LDR!\n"); + data = stbi__load_flip(s, x, y, comp, req_comp); + if (data) + return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); +} + +STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_STDIO +STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + float *result; + FILE *f = stbi__fopen(filename, "rb"); + if (!f) return stbi__errpf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_file(&s,f); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} +#endif // !STBI_NO_STDIO + +#endif // !STBI_NO_LINEAR + +// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is +// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always +// reports false! + +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(buffer); + STBI_NOTUSED(len); + return 0; + #endif +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result=0; + if (f) { + result = stbi_is_hdr_from_file(f); + fclose(f); + } + return result; +} + +STBIDEF int stbi_is_hdr_from_file(FILE *f) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_file(&s,f); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(f); + return 0; + #endif +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(clbk); + STBI_NOTUSED(user); + return 0; + #endif +} + +#ifndef STBI_NO_LINEAR +static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; + +STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } +STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } +#endif + +static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; + +STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } +STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } + + +////////////////////////////////////////////////////////////////////////////// +// +// Common code used by all image loaders +// + +enum +{ + STBI__SCAN_load=0, + STBI__SCAN_type, + STBI__SCAN_header +}; + +static void stbi__refill_buffer(stbi__context *s) +{ + int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); + if (n == 0) { + // at end of file, treat same as if from memory, but need to handle case + // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file + s->read_from_callbacks = 0; + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start+1; + *s->img_buffer = 0; + } else { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } +} + +stbi_inline static stbi_uc stbi__get8(stbi__context *s) +{ + if (s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; + if (s->read_from_callbacks) { + stbi__refill_buffer(s); + return *s->img_buffer++; + } + return 0; +} + +stbi_inline static int stbi__at_eof(stbi__context *s) +{ + if (s->io.read) { + if (!(s->io.eof)(s->io_user_data)) return 0; + // if feof() is true, check if buffer = end + // special case: we've only got the special 0 character at the end + if (s->read_from_callbacks == 0) return 1; + } + + return s->img_buffer >= s->img_buffer_end; +} + +static void stbi__skip(stbi__context *s, int n) +{ + if (n < 0) { + s->img_buffer = s->img_buffer_end; + return; + } + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + s->img_buffer = s->img_buffer_end; + (s->io.skip)(s->io_user_data, n - blen); + return; + } + } + s->img_buffer += n; +} +/* +static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) +{ + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + int res, count; + + memcpy(buffer, s->img_buffer, blen); + + count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); + res = (count == (n-blen)); + s->img_buffer = s->img_buffer_end; + return res; + } + } + + if (s->img_buffer+n <= s->img_buffer_end) { + memcpy(buffer, s->img_buffer, n); + s->img_buffer += n; + return 1; + } else + return 0; +} +*/ +static int stbi__get16be(stbi__context *s) +{ + int z = stbi__get8(s); + return (z << 8) + stbi__get8(s); +} +/* +static stbi__uint32 stbi__get32be(stbi__context *s) +{ + stbi__uint32 z = stbi__get16be(s); + return (z << 16) + stbi__get16be(s); +} +*/ +#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) +// nothing +#else +static int stbi__get16le(stbi__context *s) +{ + int z = stbi__get8(s); + return z + (stbi__get8(s) << 8); +} +#endif + +#ifndef STBI_NO_BMP +static stbi__uint32 stbi__get32le(stbi__context *s) +{ + stbi__uint32 z = stbi__get16le(s); + return z + (stbi__get16le(s) << 16); +} +#endif + +#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings + + +////////////////////////////////////////////////////////////////////////////// +// +// generic converter from built-in img_n to req_comp +// individual types do this automatically as much as possible (e.g. jpeg +// does all cases internally since it needs to colorspace convert anyway, +// and it never has alpha, so very few cases ). png can automatically +// interleave an alpha=255 channel, but falls back to this for other cases +// +// assume data buffer is malloced, so malloc a new one and free that one +// only failure mode is malloc failing + +/* +static stbi_uc stbi__compute_y(int r, int g, int b) +{ + return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); +} +*/ + +/* +static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + unsigned char *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (unsigned char *) stbi__malloc(req_comp * x * y); + if (good == NULL) { + STBI_FREE(data); + return stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + unsigned char *src = data + j * x * img_n ; + unsigned char *dest = good + j * x * req_comp; + + #define COMBO(a,b) ((a)*8+(b)) + #define CASE(a,b) case COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (COMBO(img_n, req_comp)) { + CASE(1,2) dest[0]=src[0], dest[1]=255; break; + CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break; + CASE(2,1) dest[0]=src[0]; break; + CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break; + CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break; + CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break; + CASE(3,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; + CASE(3,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; break; + CASE(4,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; + CASE(4,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; + CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; + default: STBI_ASSERT(0); + } + #undef CASE + } + + STBI_FREE(data); + return good; +} +*/ +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) +{ + int i,k,n; + float *output = (float *) stbi__malloc(x * y * comp * sizeof(float)); + if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); + } + if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; + } + STBI_FREE(data); + return output; +} +#endif + +#ifndef STBI_NO_HDR +#define stbi__float2int(x) ((int) (x)) +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) +{ + int i,k,n; + stbi_uc *output = (stbi_uc *) stbi__malloc(x * y * comp); + if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + if (k < comp) { + float z = data[i*comp+k] * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + } + STBI_FREE(data); + return output; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// "baseline" JPEG/JFIF decoder +// +// simple implementation +// - doesn't support delayed output of y-dimension +// - simple interface (only one output format: 8-bit interleaved RGB) +// - doesn't try to recover corrupt jpegs +// - doesn't allow partial loading, loading multiple at once +// - still fast on x86 (copying globals into locals doesn't help x86) +// - allocates lots of intermediate memory (full size of all components) +// - non-interleaved case requires this anyway +// - allows good upsampling (see next) +// high-quality +// - upsampled channels are bilinearly interpolated, even across blocks +// - quality integer IDCT derived from IJG's 'slow' +// performance +// - fast huffman; reasonable integer IDCT +// - some SIMD kernels for common paths on targets with SSE2/NEON +// - uses a lot of intermediate memory, could cache poorly + +#ifndef STBI_NO_JPEG + +// huffman decoding acceleration +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache + +typedef struct +{ + stbi_uc fast[1 << FAST_BITS]; + // weirdly, repacking this into AoS is a 10% speed loss, instead of a win + stbi__uint16 code[256]; + stbi_uc values[256]; + stbi_uc size[257]; + unsigned int maxcode[18]; + int delta[17]; // old 'firstsymbol' - old 'firstcode' +} stbi__huffman; + +typedef struct +{ + stbi__context *s; + stbi__huffman huff_dc[4]; + stbi__huffman huff_ac[4]; + stbi_uc dequant[4][64]; + stbi__int16 fast_ac[4][1 << FAST_BITS]; + +// sizes for components, interleaved MCUs + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; + +// definition of jpeg image component + struct + { + int id; + int h,v; + int tq; + int hd,ha; + int dc_pred; + + int x,y,w2,h2; + stbi_uc *data; + void *raw_data, *raw_coeff; + stbi_uc *linebuf; + short *coeff; // progressive only + int coeff_w, coeff_h; // number of 8x8 coefficient blocks + } img_comp[4]; + + stbi__uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop + + int progressive; + int spec_start; + int spec_end; + int succ_high; + int succ_low; + int eob_run; + int rgb; + + int scan_n, order[4]; + int restart_interval, todo; + +// kernels + void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]); + void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step); + stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs); +} stbi__jpeg; + +static int stbi__build_huffman(stbi__huffman *h, int *count) +{ + int i,j,k=0,code; + // build size list for each symbol (from JPEG spec) + for (i=0; i < 16; ++i) + for (j=0; j < count[i]; ++j) + h->size[k++] = (stbi_uc) (i+1); + h->size[k] = 0; + + // compute actual symbols (from jpeg spec) + code = 0; + k = 0; + for(j=1; j <= 16; ++j) { + // compute delta to add to code to compute symbol id + h->delta[j] = k - code; + if (h->size[k] == j) { + while (h->size[k] == j) + h->code[k++] = (stbi__uint16) (code++); + if (code-1 >= (1 << j)) return stbi__err("bad code lengths","Corrupt JPEG"); + } + // compute largest code + 1 for this size, preshifted as needed later + h->maxcode[j] = code << (16-j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; + + // build non-spec acceleration table; 255 is flag for not-accelerated + memset(h->fast, 255, 1 << FAST_BITS); + for (i=0; i < k; ++i) { + int s = h->size[i]; + if (s <= FAST_BITS) { + int c = h->code[i] << (FAST_BITS-s); + int m = 1 << (FAST_BITS-s); + for (j=0; j < m; ++j) { + h->fast[c+j] = (stbi_uc) i; + } + } + } + return 1; +} + +// build a table that decodes both magnitude and value of small ACs in +// one go. +static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) +{ + int i; + for (i=0; i < (1 << FAST_BITS); ++i) { + stbi_uc fast = h->fast[i]; + fast_ac[i] = 0; + if (fast < 255) { + int rs = h->values[fast]; + int run = (rs >> 4) & 15; + int magbits = rs & 15; + int len = h->size[fast]; + + if (magbits && len + magbits <= FAST_BITS) { + // magnitude code followed by receive_extend code + int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); + int m = 1 << (magbits - 1); + if (k < m) k += (-1 << magbits) + 1; + // if the result is small enough, we can fit it in fast_ac table + if (k >= -128 && k <= 127) + fast_ac[i] = (stbi__int16) ((k << 8) + (run << 4) + (len + magbits)); + } + } + } +} + +static void stbi__grow_buffer_unsafe(stbi__jpeg *j) +{ + do { + int b = j->nomore ? 0 : stbi__get8(j->s); + if (b == 0xff) { + int c = stbi__get8(j->s); + if (c != 0) { + j->marker = (unsigned char) c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while (j->code_bits <= 24); +} + +// (1 << n) - 1 +static stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; + +// decode a jpeg huffman value from the bitstream +stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) +{ + unsigned int temp; + int c,k; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + // look at the top FAST_BITS and determine what symbol ID it is, + // if the code is <= FAST_BITS + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + k = h->fast[c]; + if (k < 255) { + int s = h->size[k]; + if (s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } + + // naive test is to shift the code_buffer down so k bits are + // valid, then test against maxcode. To speed this up, we've + // preshifted maxcode left so that it has (16-k) 0s at the + // end; in other words, regardless of the number of bits, it + // wants to be compared against something shifted to have 16; + // that way we don't need to shift inside the loop. + temp = j->code_buffer >> 16; + for (k=FAST_BITS+1 ; ; ++k) + if (temp < h->maxcode[k]) + break; + if (k == 17) { + // error! code not found + j->code_bits -= 16; + return -1; + } + + if (k > j->code_bits) + return -1; + + // convert the huffman code to the symbol id + c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; + STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); + + // convert the id to a symbol + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; +} + +// bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); + + sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB + k = stbi_lrot(j->code_buffer, n); + STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k + (stbi__jbias[n] & ~sgn); +} + +// get some unsigned bits +stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) +{ + unsigned int k; + if (j->code_bits < n) stbi__grow_buffer_unsafe(j); + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k; +} + +stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) +{ + unsigned int k; + if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); + k = j->code_buffer; + j->code_buffer <<= 1; + --j->code_bits; + return k & 0x80000000; +} + +// given a value that's at position X in the zigzag stream, +// where does it appear in the 8x8 matrix coded as row-major? +static stbi_uc stbi__jpeg_dezigzag[64+15] = +{ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63 +}; + +// decode one 64-entry block-- +static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi_uc *dequant) +{ + int diff,dc,k; + int t; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + t = stbi__jpeg_huff_decode(j, hdc); + if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + + // 0 all the ac values now so we can do it 32-bits at a time + memset(data,0,64*sizeof(data[0])); + + diff = t ? stbi__extend_receive(j, t) : 0; + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc * dequant[0]); + + // decode AC components, see JPEG spec + k = 1; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) * dequant[zig]); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (rs != 0xf0) break; // end block + k += 16; + } else { + k += r; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]); + } + } + } while (k < 64); + return 1; +} + +static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) +{ + int diff,dc; + int t; + if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + if (j->succ_high == 0) { + // first scan for DC coefficient, must be first + memset(data,0,64*sizeof(data[0])); // 0 all the ac values now + t = stbi__jpeg_huff_decode(j, hdc); + diff = t ? stbi__extend_receive(j, t) : 0; + + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc << j->succ_low); + } else { + // refinement scan for DC coefficient + if (stbi__jpeg_get_bit(j)) + data[0] += (short) (1 << j->succ_low); + } + return 1; +} + +// @OPTIMIZE: store non-zigzagged during the decode passes, +// and only de-zigzag when dequantizing +static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) +{ + int k; + if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->succ_high == 0) { + int shift = j->succ_low; + + if (j->eob_run) { + --j->eob_run; + return 1; + } + + k = j->spec_start; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) << shift); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r); + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + --j->eob_run; + break; + } + k += 16; + } else { + k += r; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) << shift); + } + } + } while (k <= j->spec_end); + } else { + // refinement scan for these AC coefficients + + short bit = (short) (1 << j->succ_low); + + if (j->eob_run) { + --j->eob_run; + for (k = j->spec_start; k <= j->spec_end; ++k) { + short *p = &data[stbi__jpeg_dezigzag[k]]; + if (*p != 0) + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } + } else { + k = j->spec_start; + do { + int r,s; + int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r) - 1; + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + r = 64; // force end of block + } else { + // r=15 s=0 should write 16 0s, so we just do + // a run of 15 0s and then write s (which is 0), + // so we don't have to do anything special here + } + } else { + if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); + // sign bit + if (stbi__jpeg_get_bit(j)) + s = bit; + else + s = -bit; + } + + // advance by r + while (k <= j->spec_end) { + short *p = &data[stbi__jpeg_dezigzag[k++]]; + if (*p != 0) { + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } else { + if (r == 0) { + *p = (short) s; + break; + } + --r; + } + } + } while (k <= j->spec_end); + } + } + return 1; +} + +// take a -128..127 value and stbi__clamp it and convert to 0..255 +stbi_inline static stbi_uc stbi__clamp(int x) +{ + // trick to use a single test to catch both cases + if ((unsigned int) x > 255) { + if (x < 0) return 0; + if (x > 255) return 255; + } + return (stbi_uc) x; +} + +#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) +#define stbi__fsh(x) ((x) << 12) + +// derived from jidctint -- DCT_ISLOW +#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ + int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2+p3) * stbi__f2f(0.5411961f); \ + t2 = p1 + p3*stbi__f2f(-1.847759065f); \ + t3 = p1 + p2*stbi__f2f( 0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = stbi__fsh(p2+p3); \ + t1 = stbi__fsh(p2-p3); \ + x0 = t0+t3; \ + x3 = t0-t3; \ + x1 = t1+t2; \ + x2 = t1-t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0+t2; \ + p4 = t1+t3; \ + p1 = t0+t3; \ + p2 = t1+t2; \ + p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ + t0 = t0*stbi__f2f( 0.298631336f); \ + t1 = t1*stbi__f2f( 2.053119869f); \ + t2 = t2*stbi__f2f( 3.072711026f); \ + t3 = t3*stbi__f2f( 1.501321110f); \ + p1 = p5 + p1*stbi__f2f(-0.899976223f); \ + p2 = p5 + p2*stbi__f2f(-2.562915447f); \ + p3 = p3*stbi__f2f(-1.961570560f); \ + p4 = p4*stbi__f2f(-0.390180644f); \ + t3 += p1+p4; \ + t2 += p2+p3; \ + t1 += p2+p4; \ + t0 += p1+p3; + +static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) +{ + int i,val[64],*v=val; + stbi_uc *o; + short *d = data; + + // columns + for (i=0; i < 8; ++i,++d, ++v) { + // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing + if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 + && d[40]==0 && d[48]==0 && d[56]==0) { + // no shortcut 0 seconds + // (1|2|3|4|5|6|7)==0 0 seconds + // all separate -0.047 seconds + // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds + int dcterm = d[0] << 2; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } else { + STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) + // constants scaled things up by 1<<12; let's bring them back + // down, but keep 2 extra bits of precision + x0 += 512; x1 += 512; x2 += 512; x3 += 512; + v[ 0] = (x0+t3) >> 10; + v[56] = (x0-t3) >> 10; + v[ 8] = (x1+t2) >> 10; + v[48] = (x1-t2) >> 10; + v[16] = (x2+t1) >> 10; + v[40] = (x2-t1) >> 10; + v[24] = (x3+t0) >> 10; + v[32] = (x3-t0) >> 10; + } + } + + for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { + // no fast case since the first 1D IDCT spread components out + STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) + // constants scaled things up by 1<<12, plus we had 1<<2 from first + // loop, plus horizontal and vertical each scale by sqrt(8) so together + // we've got an extra 1<<3, so 1<<17 total we need to remove. + // so we want to round that, which means adding 0.5 * 1<<17, + // aka 65536. Also, we'll end up with -128 to 127 that we want + // to encode as 0..255 by adding 128, so we'll add that before the shift + x0 += 65536 + (128<<17); + x1 += 65536 + (128<<17); + x2 += 65536 + (128<<17); + x3 += 65536 + (128<<17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = stbi__clamp((x0+t3) >> 17); + o[7] = stbi__clamp((x0-t3) >> 17); + o[1] = stbi__clamp((x1+t2) >> 17); + o[6] = stbi__clamp((x1-t2) >> 17); + o[2] = stbi__clamp((x2+t1) >> 17); + o[5] = stbi__clamp((x2-t1) >> 17); + o[3] = stbi__clamp((x3+t0) >> 17); + o[4] = stbi__clamp((x3-t0) >> 17); + } +} + +#ifdef STBI_SSE2 +// sse2 integer IDCT. not the fastest possible implementation but it +// produces bit-identical results to the generic C version so it's +// fully "transparent". +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + // This is constructed to match our regular (generic) integer IDCT exactly. + __m128i row0, row1, row2, row3, row4, row5, row6, row7; + __m128i tmp; + + // dot product constant: even elems=x, odd elems=y + #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) + + // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) + // out(1) = c1[even]*x + c1[odd]*y + #define dct_rot(out0,out1, x,y,c0,c1) \ + __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ + __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ + __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ + __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ + __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ + __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) + + // out = in << 12 (in 16-bit, out 32-bit) + #define dct_widen(out, in) \ + __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ + __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) + + // wide add + #define dct_wadd(out, a, b) \ + __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_add_epi32(a##_h, b##_h) + + // wide sub + #define dct_wsub(out, a, b) \ + __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) + + // butterfly a/b, add bias, then shift by "s" and pack + #define dct_bfly32o(out0, out1, a,b,bias,s) \ + { \ + __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ + __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ + dct_wadd(sum, abiased, b); \ + dct_wsub(dif, abiased, b); \ + out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ + out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ + } + + // 8-bit interleave step (for transposes) + #define dct_interleave8(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi8(a, b); \ + b = _mm_unpackhi_epi8(tmp, b) + + // 16-bit interleave step (for transposes) + #define dct_interleave16(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi16(a, b); \ + b = _mm_unpackhi_epi16(tmp, b) + + #define dct_pass(bias,shift) \ + { \ + /* even part */ \ + dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ + __m128i sum04 = _mm_add_epi16(row0, row4); \ + __m128i dif04 = _mm_sub_epi16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ + dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ + __m128i sum17 = _mm_add_epi16(row1, row7); \ + __m128i sum35 = _mm_add_epi16(row3, row5); \ + dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ + dct_wadd(x4, y0o, y4o); \ + dct_wadd(x5, y1o, y5o); \ + dct_wadd(x6, y2o, y5o); \ + dct_wadd(x7, y3o, y4o); \ + dct_bfly32o(row0,row7, x0,x7,bias,shift); \ + dct_bfly32o(row1,row6, x1,x6,bias,shift); \ + dct_bfly32o(row2,row5, x2,x5,bias,shift); \ + dct_bfly32o(row3,row4, x3,x4,bias,shift); \ + } + + __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); + __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f)); + __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); + __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); + __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f)); + __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f)); + __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f)); + __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f)); + + // rounding biases in column/row passes, see stbi__idct_block for explanation. + __m128i bias_0 = _mm_set1_epi32(512); + __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); + + // load + row0 = _mm_load_si128((const __m128i *) (data + 0*8)); + row1 = _mm_load_si128((const __m128i *) (data + 1*8)); + row2 = _mm_load_si128((const __m128i *) (data + 2*8)); + row3 = _mm_load_si128((const __m128i *) (data + 3*8)); + row4 = _mm_load_si128((const __m128i *) (data + 4*8)); + row5 = _mm_load_si128((const __m128i *) (data + 5*8)); + row6 = _mm_load_si128((const __m128i *) (data + 6*8)); + row7 = _mm_load_si128((const __m128i *) (data + 7*8)); + + // column pass + dct_pass(bias_0, 10); + + { + // 16bit 8x8 transpose pass 1 + dct_interleave16(row0, row4); + dct_interleave16(row1, row5); + dct_interleave16(row2, row6); + dct_interleave16(row3, row7); + + // transpose pass 2 + dct_interleave16(row0, row2); + dct_interleave16(row1, row3); + dct_interleave16(row4, row6); + dct_interleave16(row5, row7); + + // transpose pass 3 + dct_interleave16(row0, row1); + dct_interleave16(row2, row3); + dct_interleave16(row4, row5); + dct_interleave16(row6, row7); + } + + // row pass + dct_pass(bias_1, 17); + + { + // pack + __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 + __m128i p1 = _mm_packus_epi16(row2, row3); + __m128i p2 = _mm_packus_epi16(row4, row5); + __m128i p3 = _mm_packus_epi16(row6, row7); + + // 8bit 8x8 transpose pass 1 + dct_interleave8(p0, p2); // a0e0a1e1... + dct_interleave8(p1, p3); // c0g0c1g1... + + // transpose pass 2 + dct_interleave8(p0, p1); // a0c0e0g0... + dct_interleave8(p2, p3); // b0d0f0h0... + + // transpose pass 3 + dct_interleave8(p0, p2); // a0b0c0d0... + dct_interleave8(p1, p3); // a4b4c4d4... + + // store + _mm_storel_epi64((__m128i *) out, p0); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p2); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p1); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p3); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); + } + +#undef dct_const +#undef dct_rot +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_interleave8 +#undef dct_interleave16 +#undef dct_pass +} + +#endif // STBI_SSE2 + +#ifdef STBI_NEON + +// NEON integer IDCT. should produce bit-identical +// results to the generic C version. +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; + + int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); + int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); + int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f)); + int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f)); + int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); + int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); + int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); + int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); + int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f)); + int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f)); + int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f)); + int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f)); + +#define dct_long_mul(out, inq, coeff) \ + int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) + +#define dct_long_mac(out, acc, inq, coeff) \ + int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) + +#define dct_widen(out, inq) \ + int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ + int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) + +// wide add +#define dct_wadd(out, a, b) \ + int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vaddq_s32(a##_h, b##_h) + +// wide sub +#define dct_wsub(out, a, b) \ + int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vsubq_s32(a##_h, b##_h) + +// butterfly a/b, then shift using "shiftop" by "s" and pack +#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ + { \ + dct_wadd(sum, a, b); \ + dct_wsub(dif, a, b); \ + out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ + out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ + } + +#define dct_pass(shiftop, shift) \ + { \ + /* even part */ \ + int16x8_t sum26 = vaddq_s16(row2, row6); \ + dct_long_mul(p1e, sum26, rot0_0); \ + dct_long_mac(t2e, p1e, row6, rot0_1); \ + dct_long_mac(t3e, p1e, row2, rot0_2); \ + int16x8_t sum04 = vaddq_s16(row0, row4); \ + int16x8_t dif04 = vsubq_s16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + int16x8_t sum15 = vaddq_s16(row1, row5); \ + int16x8_t sum17 = vaddq_s16(row1, row7); \ + int16x8_t sum35 = vaddq_s16(row3, row5); \ + int16x8_t sum37 = vaddq_s16(row3, row7); \ + int16x8_t sumodd = vaddq_s16(sum17, sum35); \ + dct_long_mul(p5o, sumodd, rot1_0); \ + dct_long_mac(p1o, p5o, sum17, rot1_1); \ + dct_long_mac(p2o, p5o, sum35, rot1_2); \ + dct_long_mul(p3o, sum37, rot2_0); \ + dct_long_mul(p4o, sum15, rot2_1); \ + dct_wadd(sump13o, p1o, p3o); \ + dct_wadd(sump24o, p2o, p4o); \ + dct_wadd(sump23o, p2o, p3o); \ + dct_wadd(sump14o, p1o, p4o); \ + dct_long_mac(x4, sump13o, row7, rot3_0); \ + dct_long_mac(x5, sump24o, row5, rot3_1); \ + dct_long_mac(x6, sump23o, row3, rot3_2); \ + dct_long_mac(x7, sump14o, row1, rot3_3); \ + dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ + dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ + dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ + dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ + } + + // load + row0 = vld1q_s16(data + 0*8); + row1 = vld1q_s16(data + 1*8); + row2 = vld1q_s16(data + 2*8); + row3 = vld1q_s16(data + 3*8); + row4 = vld1q_s16(data + 4*8); + row5 = vld1q_s16(data + 5*8); + row6 = vld1q_s16(data + 6*8); + row7 = vld1q_s16(data + 7*8); + + // add DC bias + row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); + + // column pass + dct_pass(vrshrn_n_s32, 10); + + // 16bit 8x8 transpose + { +// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. +// whether compilers actually get this is another story, sadly. +#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } +#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } + + // pass 1 + dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 + dct_trn16(row2, row3); + dct_trn16(row4, row5); + dct_trn16(row6, row7); + + // pass 2 + dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 + dct_trn32(row1, row3); + dct_trn32(row4, row6); + dct_trn32(row5, row7); + + // pass 3 + dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 + dct_trn64(row1, row5); + dct_trn64(row2, row6); + dct_trn64(row3, row7); + +#undef dct_trn16 +#undef dct_trn32 +#undef dct_trn64 + } + + // row pass + // vrshrn_n_s32 only supports shifts up to 16, we need + // 17. so do a non-rounding shift of 16 first then follow + // up with a rounding shift by 1. + dct_pass(vshrn_n_s32, 16); + + { + // pack and round + uint8x8_t p0 = vqrshrun_n_s16(row0, 1); + uint8x8_t p1 = vqrshrun_n_s16(row1, 1); + uint8x8_t p2 = vqrshrun_n_s16(row2, 1); + uint8x8_t p3 = vqrshrun_n_s16(row3, 1); + uint8x8_t p4 = vqrshrun_n_s16(row4, 1); + uint8x8_t p5 = vqrshrun_n_s16(row5, 1); + uint8x8_t p6 = vqrshrun_n_s16(row6, 1); + uint8x8_t p7 = vqrshrun_n_s16(row7, 1); + + // again, these can translate into one instruction, but often don't. +#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } +#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } + + // sadly can't use interleaved stores here since we only write + // 8 bytes to each scan line! + + // 8x8 8-bit transpose pass 1 + dct_trn8_8(p0, p1); + dct_trn8_8(p2, p3); + dct_trn8_8(p4, p5); + dct_trn8_8(p6, p7); + + // pass 2 + dct_trn8_16(p0, p2); + dct_trn8_16(p1, p3); + dct_trn8_16(p4, p6); + dct_trn8_16(p5, p7); + + // pass 3 + dct_trn8_32(p0, p4); + dct_trn8_32(p1, p5); + dct_trn8_32(p2, p6); + dct_trn8_32(p3, p7); + + // store + vst1_u8(out, p0); out += out_stride; + vst1_u8(out, p1); out += out_stride; + vst1_u8(out, p2); out += out_stride; + vst1_u8(out, p3); out += out_stride; + vst1_u8(out, p4); out += out_stride; + vst1_u8(out, p5); out += out_stride; + vst1_u8(out, p6); out += out_stride; + vst1_u8(out, p7); + +#undef dct_trn8_8 +#undef dct_trn8_16 +#undef dct_trn8_32 + } + +#undef dct_long_mul +#undef dct_long_mac +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_pass +} + +#endif // STBI_NEON + +#define STBI__MARKER_none 0xff +// if there's a pending marker from the entropy stream, return that +// otherwise, fetch from the stream and get a marker. if there's no +// marker, return 0xff, which is never a valid marker value +static stbi_uc stbi__get_marker(stbi__jpeg *j) +{ + stbi_uc x; + if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } + x = stbi__get8(j->s); + if (x != 0xff) return STBI__MARKER_none; + while (x == 0xff) + x = stbi__get8(j->s); + return x; +} + +// in each scan, we'll have scan_n components, and the order +// of the components is specified by order[] +#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) + +// after a restart interval, stbi__jpeg_reset the entropy decoder and +// the dc prediction +static void stbi__jpeg_reset(stbi__jpeg *j) +{ + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; + j->marker = STBI__MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + j->eob_run = 0; + // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + // since we don't even allow 1<<30 pixels +} + +static int stbi__parse_entropy_coded_data(stbi__jpeg *z) +{ + stbi__jpeg_reset(z); + if (!z->progressive) { + if (z->scan_n == 1) { + int i,j; + STBI_SIMD_ALIGN(short, data[64]); + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + STBI_SIMD_ALIGN(short, data[64]); + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x)*8; + int y2 = (j*z->img_comp[n].v + y)*8; + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } else { + if (z->scan_n == 1) { + int i,j; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + if (z->spec_start == 0) { + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } else { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) + return 0; + } + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x); + int y2 = (j*z->img_comp[n].v + y); + short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } +} + +static void stbi__jpeg_dequantize(short *data, stbi_uc *dequant) +{ + int i; + for (i=0; i < 64; ++i) + data[i] *= dequant[i]; +} + +static void stbi__jpeg_finish(stbi__jpeg *z) +{ + if (z->progressive) { + // dequantize and idct the data + int i,j,n; + for (n=0; n < z->s->img_n; ++n) { + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + } + } + } + } +} + +static int stbi__process_marker(stbi__jpeg *z, int m) +{ + int L; + switch (m) { + case STBI__MARKER_none: // no marker found + return stbi__err("expected marker","Corrupt JPEG"); + + case 0xDD: // DRI - specify restart interval + if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG"); + z->restart_interval = stbi__get16be(z->s); + return 1; + + case 0xDB: // DQT - define quantization table + L = stbi__get16be(z->s)-2; + while (L > 0) { + int q = stbi__get8(z->s); + int p = q >> 4; + int t = q & 15,i; + if (p != 0) return stbi__err("bad DQT type","Corrupt JPEG"); + if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); + for (i=0; i < 64; ++i) + z->dequant[t][stbi__jpeg_dezigzag[i]] = stbi__get8(z->s); + L -= 65; + } + return L==0; + + case 0xC4: // DHT - define huffman table + L = stbi__get16be(z->s)-2; + while (L > 0) { + stbi_uc *v; + int sizes[16],i,n=0; + int q = stbi__get8(z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG"); + for (i=0; i < 16; ++i) { + sizes[i] = stbi__get8(z->s); + n += sizes[i]; + } + L -= 17; + if (tc == 0) { + if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0; + v = z->huff_dc[th].values; + } else { + if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0; + v = z->huff_ac[th].values; + } + for (i=0; i < n; ++i) + v[i] = stbi__get8(z->s); + if (tc != 0) + stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); + L -= n; + } + return L==0; + } + // check for comment block or APP blocks + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { + stbi__skip(z->s, stbi__get16be(z->s)-2); + return 1; + } + return 0; +} + +// after we see SOS +static int stbi__process_scan_header(stbi__jpeg *z) +{ + int i; + int Ls = stbi__get16be(z->s); + z->scan_n = stbi__get8(z->s); + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG"); + if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG"); + for (i=0; i < z->scan_n; ++i) { + int id = stbi__get8(z->s), which; + int q = stbi__get8(z->s); + for (which = 0; which < z->s->img_n; ++which) + if (z->img_comp[which].id == id) + break; + if (which == z->s->img_n) return 0; // no match + z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG"); + z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG"); + z->order[i] = which; + } + + { + int aa; + z->spec_start = stbi__get8(z->s); + z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 + aa = stbi__get8(z->s); + z->succ_high = (aa >> 4); + z->succ_low = (aa & 15); + if (z->progressive) { + if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) + return stbi__err("bad SOS", "Corrupt JPEG"); + } else { + if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG"); + if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG"); + z->spec_end = 63; + } + } + + return 1; +} + +static int stbi__process_frame_header(stbi__jpeg *z, int scan) +{ + stbi__context *s = z->s; + int Lf,p,i,q, h_max=1,v_max=1,c; + Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG + p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires + c = stbi__get8(s); + if (c != 3 && c != 1) return stbi__err("bad component count","Corrupt JPEG"); // JFIF requires + s->img_n = c; + for (i=0; i < c; ++i) { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } + + if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG"); + + z->rgb = 0; + for (i=0; i < s->img_n; ++i) { + static unsigned char rgb[3] = { 'R', 'G', 'B' }; + z->img_comp[i].id = stbi__get8(s); + if (z->img_comp[i].id != i+1) // JFIF requires + if (z->img_comp[i].id != i) { // some version of jpegtran outputs non-JFIF-compliant files! + // somethings output this (see http://fileformats.archiveteam.org/wiki/JPEG#Color_format) + if (z->img_comp[i].id != rgb[i]) + return stbi__err("bad component ID","Corrupt JPEG"); + ++z->rgb; + } + q = stbi__get8(s); + z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); + z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); + z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG"); + } + + if (scan != STBI__SCAN_load) return 1; + + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + + for (i=0; i < s->img_n; ++i) { + if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } + + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + + for (i=0; i < s->img_n; ++i) { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].raw_data = stbi__malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); + + if (z->img_comp[i].raw_data == NULL) { + for(--i; i >= 0; --i) { + STBI_FREE(z->img_comp[i].raw_data); + z->img_comp[i].raw_data = NULL; + } + return stbi__err("outofmem", "Out of memory"); + } + // align blocks for idct using mmx/sse + z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); + z->img_comp[i].linebuf = NULL; + if (z->progressive) { + z->img_comp[i].coeff_w = (z->img_comp[i].w2 + 7) >> 3; + z->img_comp[i].coeff_h = (z->img_comp[i].h2 + 7) >> 3; + z->img_comp[i].raw_coeff = STBI_MALLOC(z->img_comp[i].coeff_w * z->img_comp[i].coeff_h * 64 * sizeof(short) + 15); + z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); + } else { + z->img_comp[i].coeff = 0; + z->img_comp[i].raw_coeff = 0; + } + } + + return 1; +} + +// use comparisons since in some cases we handle more than one case (e.g. SOF) +#define stbi__DNL(x) ((x) == 0xdc) +#define stbi__SOI(x) ((x) == 0xd8) +#define stbi__EOI(x) ((x) == 0xd9) +#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) +#define stbi__SOS(x) ((x) == 0xda) + +#define stbi__SOF_progressive(x) ((x) == 0xc2) + +static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) +{ + int m; + z->marker = STBI__MARKER_none; // initialize cached marker to empty + m = stbi__get_marker(z); + if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); + if (scan == STBI__SCAN_type) return 1; + m = stbi__get_marker(z); + while (!stbi__SOF(m)) { + if (!stbi__process_marker(z,m)) return 0; + m = stbi__get_marker(z); + while (m == STBI__MARKER_none) { + // some files have extra padding after their blocks, so ok, we'll scan + if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); + m = stbi__get_marker(z); + } + } + z->progressive = stbi__SOF_progressive(m); + if (!stbi__process_frame_header(z, scan)) return 0; + return 1; +} + +// decode image to YCbCr format +static int stbi__decode_jpeg_image(stbi__jpeg *j) +{ + int m; + for (m = 0; m < 4; m++) { + j->img_comp[m].raw_data = NULL; + j->img_comp[m].raw_coeff = NULL; + } + j->restart_interval = 0; + if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; + m = stbi__get_marker(j); + while (!stbi__EOI(m)) { + if (stbi__SOS(m)) { + if (!stbi__process_scan_header(j)) return 0; + if (!stbi__parse_entropy_coded_data(j)) return 0; + if (j->marker == STBI__MARKER_none ) { + // handle 0s at the end of image data from IP Kamera 9060 + while (!stbi__at_eof(j->s)) { + int x = stbi__get8(j->s); + if (x == 255) { + j->marker = stbi__get8(j->s); + break; + } else if (x != 0) { + return stbi__err("junk before marker", "Corrupt JPEG"); + } + } + // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 + } + } else { + if (!stbi__process_marker(j, m)) return 0; + } + m = stbi__get_marker(j); + } + if (j->progressive) + stbi__jpeg_finish(j); + return 1; +} + +// static jfif-centered resampling (across block boundaries) + +typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, + int w, int hs); + +#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) + +static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + STBI_NOTUSED(out); + STBI_NOTUSED(in_far); + STBI_NOTUSED(w); + STBI_NOTUSED(hs); + return in_near; +} + +static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples vertically for every one in input + int i; + STBI_NOTUSED(hs); + for (i=0; i < w; ++i) + out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2); + return out; +} + +static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples horizontally for every one in input + int i; + stbi_uc *input = in_near; + + if (w == 1) { + // if only one sample, can't do any interpolation + out[0] = out[1] = input[0]; + return out; + } + + out[0] = input[0]; + out[1] = stbi__div4(input[0]*3 + input[1] + 2); + for (i=1; i < w-1; ++i) { + int n = 3*input[i]+2; + out[i*2+0] = stbi__div4(n+input[i-1]); + out[i*2+1] = stbi__div4(n+input[i+1]); + } + out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2); + out[i*2+1] = input[w-1]; + + STBI_NOTUSED(in_far); + STBI_NOTUSED(hs); + + return out; +} + +#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) + +static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i,t0,t1; + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + out[0] = stbi__div4(t1+2); + for (i=1; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i=0,t0,t1; + + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + // process groups of 8 pixels for as long as we can. + // note we can't handle the last pixel in a row in this loop + // because we need to handle the filter boundary conditions. + for (; i < ((w-1) & ~7); i += 8) { +#if defined(STBI_SSE2) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + __m128i zero = _mm_setzero_si128(); + __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); + __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); + __m128i farw = _mm_unpacklo_epi8(farb, zero); + __m128i nearw = _mm_unpacklo_epi8(nearb, zero); + __m128i diff = _mm_sub_epi16(farw, nearw); + __m128i nears = _mm_slli_epi16(nearw, 2); + __m128i curr = _mm_add_epi16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + __m128i prv0 = _mm_slli_si128(curr, 2); + __m128i nxt0 = _mm_srli_si128(curr, 2); + __m128i prev = _mm_insert_epi16(prv0, t1, 0); + __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + __m128i bias = _mm_set1_epi16(8); + __m128i curs = _mm_slli_epi16(curr, 2); + __m128i prvd = _mm_sub_epi16(prev, curr); + __m128i nxtd = _mm_sub_epi16(next, curr); + __m128i curb = _mm_add_epi16(curs, bias); + __m128i even = _mm_add_epi16(prvd, curb); + __m128i odd = _mm_add_epi16(nxtd, curb); + + // interleave even and odd pixels, then undo scaling. + __m128i int0 = _mm_unpacklo_epi16(even, odd); + __m128i int1 = _mm_unpackhi_epi16(even, odd); + __m128i de0 = _mm_srli_epi16(int0, 4); + __m128i de1 = _mm_srli_epi16(int1, 4); + + // pack and write output + __m128i outv = _mm_packus_epi16(de0, de1); + _mm_storeu_si128((__m128i *) (out + i*2), outv); +#elif defined(STBI_NEON) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + uint8x8_t farb = vld1_u8(in_far + i); + uint8x8_t nearb = vld1_u8(in_near + i); + int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); + int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); + int16x8_t curr = vaddq_s16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + int16x8_t prv0 = vextq_s16(curr, curr, 7); + int16x8_t nxt0 = vextq_s16(curr, curr, 1); + int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); + int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + int16x8_t curs = vshlq_n_s16(curr, 2); + int16x8_t prvd = vsubq_s16(prev, curr); + int16x8_t nxtd = vsubq_s16(next, curr); + int16x8_t even = vaddq_s16(curs, prvd); + int16x8_t odd = vaddq_s16(curs, nxtd); + + // undo scaling and round, then store with even/odd phases interleaved + uint8x8x2_t o; + o.val[0] = vqrshrun_n_s16(even, 4); + o.val[1] = vqrshrun_n_s16(odd, 4); + vst2_u8(out + i*2, o); +#endif + + // "previous" value for next iter + t1 = 3*in_near[i+7] + in_far[i+7]; + } + + t0 = t1; + t1 = 3*in_near[i] + in_far[i]; + out[i*2] = stbi__div16(3*t1 + t0 + 8); + + for (++i; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} +#endif + +static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // resample with nearest-neighbor + int i,j; + STBI_NOTUSED(in_far); + for (i=0; i < w; ++i) + for (j=0; j < hs; ++j) + out[i*hs+j] = in_near[i]; + return out; +} + +#ifdef STBI_JPEG_OLD +// this is the same YCbCr-to-RGB calculation that stb_image has used +// historically before the algorithm changes in 1.49 +#define float2fixed(x) ((int) ((x) * 65536 + 0.5)) +static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 16) + 32768; // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr*float2fixed(1.40200f); + g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f); + b = y_fixed + cb*float2fixed(1.77200f); + r >>= 16; + g >>= 16; + b >>= 16; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#else +// this is a reduced-precision calculation of YCbCr-to-RGB introduced +// to make sure the code produces the same results in both SIMD and scalar +#define float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) +static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* float2fixed(1.40200f); + g = y_fixed + (cr*-float2fixed(0.71414f)) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#endif + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) +{ + int i = 0; + +#ifdef STBI_SSE2 + // step == 3 is pretty ugly on the final interleave, and i'm not convinced + // it's useful in practice (you wouldn't use it for textures, for example). + // so just accelerate step == 4 case. + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + __m128i signflip = _mm_set1_epi8(-0x80); + __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); + __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); + __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); + __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); + __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); + __m128i xw = _mm_set1_epi16(255); // alpha channel + + for (; i+7 < count; i += 8) { + // load + __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); + __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); + __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); + __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 + __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 + + // unpack to short (and left-shift cr, cb by 8) + __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); + __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); + __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); + + // color transform + __m128i yws = _mm_srli_epi16(yw, 4); + __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); + __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); + __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); + __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); + __m128i rws = _mm_add_epi16(cr0, yws); + __m128i gwt = _mm_add_epi16(cb0, yws); + __m128i bws = _mm_add_epi16(yws, cb1); + __m128i gws = _mm_add_epi16(gwt, cr1); + + // descale + __m128i rw = _mm_srai_epi16(rws, 4); + __m128i bw = _mm_srai_epi16(bws, 4); + __m128i gw = _mm_srai_epi16(gws, 4); + + // back to byte, set up for transpose + __m128i brb = _mm_packus_epi16(rw, bw); + __m128i gxb = _mm_packus_epi16(gw, xw); + + // transpose to interleave channels + __m128i t0 = _mm_unpacklo_epi8(brb, gxb); + __m128i t1 = _mm_unpackhi_epi8(brb, gxb); + __m128i o0 = _mm_unpacklo_epi16(t0, t1); + __m128i o1 = _mm_unpackhi_epi16(t0, t1); + + // store + _mm_storeu_si128((__m128i *) (out + 0), o0); + _mm_storeu_si128((__m128i *) (out + 16), o1); + out += 32; + } + } +#endif + +#ifdef STBI_NEON + // in this version, step=3 support would be easy to add. but is there demand? + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + uint8x8_t signflip = vdup_n_u8(0x80); + int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); + int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); + int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); + int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); + + for (; i+7 < count; i += 8) { + // load + uint8x8_t y_bytes = vld1_u8(y + i); + uint8x8_t cr_bytes = vld1_u8(pcr + i); + uint8x8_t cb_bytes = vld1_u8(pcb + i); + int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); + int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); + + // expand to s16 + int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); + int16x8_t crw = vshll_n_s8(cr_biased, 7); + int16x8_t cbw = vshll_n_s8(cb_biased, 7); + + // color transform + int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); + int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); + int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); + int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); + int16x8_t rws = vaddq_s16(yws, cr0); + int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); + int16x8_t bws = vaddq_s16(yws, cb1); + + // undo scaling, round, convert to byte + uint8x8x4_t o; + o.val[0] = vqrshrun_n_s16(rws, 4); + o.val[1] = vqrshrun_n_s16(gws, 4); + o.val[2] = vqrshrun_n_s16(bws, 4); + o.val[3] = vdup_n_u8(255); + + // store, interleaving r/g/b/a + vst4_u8(out, o); + out += 8*4; + } + } +#endif + + for (; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* float2fixed(1.40200f); + g = y_fixed + cr*-float2fixed(0.71414f) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#endif + +// set up the kernels +static void stbi__setup_jpeg(stbi__jpeg *j) +{ + j->idct_block_kernel = stbi__idct_block; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; + +#ifdef STBI_SSE2 + if (stbi__sse2_available()) { + j->idct_block_kernel = stbi__idct_simd; + #ifndef STBI_JPEG_OLD + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + #endif + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; + } +#endif + +#ifdef STBI_NEON + j->idct_block_kernel = stbi__idct_simd; + #ifndef STBI_JPEG_OLD + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + #endif + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; +#endif +} + +// clean up the temporary component buffers +static void stbi__cleanup_jpeg(stbi__jpeg *j) +{ + int i; + for (i=0; i < j->s->img_n; ++i) { + if (j->img_comp[i].raw_data) { + STBI_FREE(j->img_comp[i].raw_data); + j->img_comp[i].raw_data = NULL; + j->img_comp[i].data = NULL; + } + if (j->img_comp[i].raw_coeff) { + STBI_FREE(j->img_comp[i].raw_coeff); + j->img_comp[i].raw_coeff = 0; + j->img_comp[i].coeff = 0; + } + if (j->img_comp[i].linebuf) { + STBI_FREE(j->img_comp[i].linebuf); + j->img_comp[i].linebuf = NULL; + } + } +} + +typedef struct +{ + resample_row_func resample; + stbi_uc *line0,*line1; + int hs,vs; // expansion factor in each axis + int w_lores; // horizontal pixels pre-expansion + int ystep; // how far through vertical expansion we are + int ypos; // which pre-expansion row we're on +} stbi__resample; + +static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) +{ + int n, decode_n; + z->s->img_n = 0; // make stbi__cleanup_jpeg safe + + // validate req_comp + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + + // load a jpeg image from whichever source, but leave in YCbCr format + if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } + + // determine actual number of components to generate + n = req_comp ? req_comp : z->s->img_n; + + if (z->s->img_n == 3 && n < 3) + decode_n = 1; + else + decode_n = z->s->img_n; + + // resample and color-convert + { + int k; + unsigned int i,j; + stbi_uc *output; + stbi_uc *coutput[4]; + + stbi__resample res_comp[4]; + + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + + // allocate line buffer big enough for upsampling off the edges + // with upsample factor of 4 + z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); + if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs-1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; + + if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; + else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; + else r->resample = stbi__resample_row_generic; + } + + // can't error after this so, this is safe + output = (stbi_uc *) stbi__malloc(n * z->s->img_x * z->s->img_y + 1); + if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + // now go ahead and resample + for (j=0; j < z->s->img_y; ++j) { + stbi_uc *out = output + n * z->s->img_x * j; + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + if (++r->ystep >= r->vs) { + r->ystep = 0; + r->line0 = r->line1; + if (++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + if (n >= 3) { + stbi_uc *y = coutput[0]; + if (z->s->img_n == 3) { + if (z->rgb == 3) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = y[i]; + out[1] = coutput[1][i]; + out[2] = coutput[2][i]; + out[3] = 255; + out += n; + } + } else { + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } else + for (i=0; i < z->s->img_x; ++i) { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; // not used if n==3 + out += n; + } + } else { + stbi_uc *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; + } + } + stbi__cleanup_jpeg(z); + *out_x = z->s->img_x; + *out_y = z->s->img_y; + if (comp) *comp = z->s->img_n; // report original components, not output + return output; + } +} + +static unsigned char *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char* result; + stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); + j->s = s; + stbi__setup_jpeg(j); + result = load_jpeg_image(j, x,y,comp,req_comp); + STBI_FREE(j); + return result; +} + +static int stbi__jpeg_test(stbi__context *s) +{ + int r; + stbi__jpeg j; + j.s = s; + stbi__setup_jpeg(&j); + r = stbi__decode_jpeg_header(&j, STBI__SCAN_type); + stbi__rewind(s); + return r; +} + +static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) +{ + if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { + stbi__rewind( j->s ); + return 0; + } + if (x) *x = j->s->img_x; + if (y) *y = j->s->img_y; + if (comp) *comp = j->s->img_n; + return 1; +} + +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) +{ + int result; + stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); + j->s = s; + result = stbi__jpeg_info_raw(j, x, y, comp); + STBI_FREE(j); + return result; +} +#endif + +// public domain zlib decode v0.2 Sean Barrett 2006-11-18 +// simple implementation +// - all input must be provided in an upfront buffer +// - all output is written to a single output buffer (can malloc/realloc) +// performance +// - fast huffman + +#ifndef STBI_NO_ZLIB + +// fast-way is faster to check than jpeg huffman, but slow way is slower +#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables +#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) + +// zlib-style huffman encoding +// (jpegs packs from left, zlib from right, so can't share code) +typedef struct +{ + stbi__uint16 fast[1 << STBI__ZFAST_BITS]; + stbi__uint16 firstcode[16]; + int maxcode[17]; + stbi__uint16 firstsymbol[16]; + stbi_uc size[288]; + stbi__uint16 value[288]; +} stbi__zhuffman; + +stbi_inline static int stbi__bitreverse16(int n) +{ + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; +} + +stbi_inline static int stbi__bit_reverse(int v, int bits) +{ + STBI_ASSERT(bits <= 16); + // to bit reverse n bits, reverse 16 and shift + // e.g. 11 bits, bit reverse and shift away 5 + return stbi__bitreverse16(v) >> (16-bits); +} + +static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num) +{ + int i,k=0; + int code, next_code[16], sizes[17]; + + // DEFLATE spec for generating codes + memset(sizes, 0, sizeof(sizes)); + memset(z->fast, 0, sizeof(z->fast)); + for (i=0; i < num; ++i) + ++sizes[sizelist[i]]; + sizes[0] = 0; + for (i=1; i < 16; ++i) + if (sizes[i] > (1 << i)) + return stbi__err("bad sizes", "Corrupt PNG"); + code = 0; + for (i=1; i < 16; ++i) { + next_code[i] = code; + z->firstcode[i] = (stbi__uint16) code; + z->firstsymbol[i] = (stbi__uint16) k; + code = (code + sizes[i]); + if (sizes[i]) + if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG"); + z->maxcode[i] = code << (16-i); // preshift for inner loop + code <<= 1; + k += sizes[i]; + } + z->maxcode[16] = 0x10000; // sentinel + for (i=0; i < num; ++i) { + int s = sizelist[i]; + if (s) { + int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; + stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i); + z->size [c] = (stbi_uc ) s; + z->value[c] = (stbi__uint16) i; + if (s <= STBI__ZFAST_BITS) { + int j = stbi__bit_reverse(next_code[s],s); + while (j < (1 << STBI__ZFAST_BITS)) { + z->fast[j] = fastv; + j += (1 << s); + } + } + ++next_code[s]; + } + } + return 1; +} + +// zlib-from-memory implementation for PNG reading +// because PNG allows splitting the zlib stream arbitrarily, +// and it's annoying structurally to have PNG call ZLIB call PNG, +// we require PNG read all the IDATs and combine them into a single +// memory buffer + +typedef struct +{ + stbi_uc *zbuffer, *zbuffer_end; + int num_bits; + stbi__uint32 code_buffer; + + char *zout; + char *zout_start; + char *zout_end; + int z_expandable; + + stbi__zhuffman z_length, z_distance; +} stbi__zbuf; + +stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) +{ + if (z->zbuffer >= z->zbuffer_end) return 0; + return *z->zbuffer++; +} + +static void stbi__fill_bits(stbi__zbuf *z) +{ + do { + STBI_ASSERT(z->code_buffer < (1U << z->num_bits)); + z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; + z->num_bits += 8; + } while (z->num_bits <= 24); +} + +stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) +{ + unsigned int k; + if (z->num_bits < n) stbi__fill_bits(z); + k = z->code_buffer & ((1 << n) - 1); + z->code_buffer >>= n; + z->num_bits -= n; + return k; +} + +static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s,k; + // not resolved by fast table, so compute it the slow way + // use jpeg approach, which requires MSbits at top + k = stbi__bit_reverse(a->code_buffer, 16); + for (s=STBI__ZFAST_BITS+1; ; ++s) + if (k < z->maxcode[s]) + break; + if (s == 16) return -1; // invalid code! + // code size is s, so: + b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; + STBI_ASSERT(z->size[b] == s); + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; +} + +stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s; + if (a->num_bits < 16) stbi__fill_bits(a); + b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; + if (b) { + s = b >> 9; + a->code_buffer >>= s; + a->num_bits -= s; + return b & 511; + } + return stbi__zhuffman_decode_slowpath(a, z); +} + +static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes +{ + char *q; + int cur, limit, old_limit; + z->zout = zout; + if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); + cur = (int) (z->zout - z->zout_start); + limit = old_limit = (int) (z->zout_end - z->zout_start); + while (cur + n > limit) + limit *= 2; + q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); + STBI_NOTUSED(old_limit); + if (q == NULL) return stbi__err("outofmem", "Out of memory"); + z->zout_start = q; + z->zout = q + cur; + z->zout_end = q + limit; + return 1; +} + +static int stbi__zlength_base[31] = { + 3,4,5,6,7,8,9,10,11,13, + 15,17,19,23,27,31,35,43,51,59, + 67,83,99,115,131,163,195,227,258,0,0 }; + +static int stbi__zlength_extra[31]= +{ 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,0,0 }; + +static int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, +257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + +static int stbi__zdist_extra[32] = +{ 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}; + +static int stbi__parse_huffman_block(stbi__zbuf *a) +{ + char *zout = a->zout; + for(;;) { + int z = stbi__zhuffman_decode(a, &a->z_length); + if (z < 256) { + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes + if (zout >= a->zout_end) { + if (!stbi__zexpand(a, zout, 1)) return 0; + zout = a->zout; + } + *zout++ = (char) z; + } else { + stbi_uc *p; + int len,dist; + if (z == 256) { + a->zout = zout; + return 1; + } + z -= 257; + len = stbi__zlength_base[z]; + if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); + z = stbi__zhuffman_decode(a, &a->z_distance); + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); + dist = stbi__zdist_base[z]; + if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); + if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); + if (zout + len > a->zout_end) { + if (!stbi__zexpand(a, zout, len)) return 0; + zout = a->zout; + } + p = (stbi_uc *) (zout - dist); + if (dist == 1) { // run of one byte; common in images. + stbi_uc v = *p; + if (len) { do *zout++ = v; while (--len); } + } else { + if (len) { do *zout++ = *p++; while (--len); } + } + } + } +} + +static int stbi__compute_huffman_codes(stbi__zbuf *a) +{ + static stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + stbi__zhuffman z_codelength; + stbi_uc lencodes[286+32+137];//padding for maximum single op + stbi_uc codelength_sizes[19]; + int i,n; + + int hlit = stbi__zreceive(a,5) + 257; + int hdist = stbi__zreceive(a,5) + 1; + int hclen = stbi__zreceive(a,4) + 4; + + memset(codelength_sizes, 0, sizeof(codelength_sizes)); + for (i=0; i < hclen; ++i) { + int s = stbi__zreceive(a,3); + codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; + } + if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + + n = 0; + while (n < hlit + hdist) { + int c = stbi__zhuffman_decode(a, &z_codelength); + if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); + if (c < 16) + lencodes[n++] = (stbi_uc) c; + else if (c == 16) { + c = stbi__zreceive(a,2)+3; + memset(lencodes+n, lencodes[n-1], c); + n += c; + } else if (c == 17) { + c = stbi__zreceive(a,3)+3; + memset(lencodes+n, 0, c); + n += c; + } else { + STBI_ASSERT(c == 18); + c = stbi__zreceive(a,7)+11; + memset(lencodes+n, 0, c); + n += c; + } + } + if (n != hlit+hdist) return stbi__err("bad codelengths","Corrupt PNG"); + if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; + return 1; +} + +static int stbi__parse_uncompressed_block(stbi__zbuf *a) +{ + stbi_uc header[4]; + int len,nlen,k; + if (a->num_bits & 7) + stbi__zreceive(a, a->num_bits & 7); // discard + // drain the bit-packed data into header + k = 0; + while (a->num_bits > 0) { + header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check + a->code_buffer >>= 8; + a->num_bits -= 8; + } + STBI_ASSERT(a->num_bits == 0); + // now fill header the normal way + while (k < 4) + header[k++] = stbi__zget8(a); + len = header[1] * 256 + header[0]; + nlen = header[3] * 256 + header[2]; + if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); + if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); + if (a->zout + len > a->zout_end) + if (!stbi__zexpand(a, a->zout, len)) return 0; + memcpy(a->zout, a->zbuffer, len); + a->zbuffer += len; + a->zout += len; + return 1; +} + +static int stbi__parse_zlib_header(stbi__zbuf *a) +{ + int cmf = stbi__zget8(a); + int cm = cmf & 15; + /* int cinfo = cmf >> 4; */ + int flg = stbi__zget8(a); + if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec + if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png + if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png + // window = 1 << (8 + cinfo)... but who cares, we fully buffer output + return 1; +} + +// @TODO: should statically initialize these for optimal thread safety +static stbi_uc stbi__zdefault_length[288], stbi__zdefault_distance[32]; +static void stbi__init_zdefaults(void) +{ + int i; // use <= to match clearly with spec + for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; + for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; + for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; + for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; + + for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; +} + +static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) +{ + int final, type; + if (parse_header) + if (!stbi__parse_zlib_header(a)) return 0; + a->num_bits = 0; + a->code_buffer = 0; + do { + final = stbi__zreceive(a,1); + type = stbi__zreceive(a,2); + if (type == 0) { + if (!stbi__parse_uncompressed_block(a)) return 0; + } else if (type == 3) { + return 0; + } else { + if (type == 1) { + // use fixed code lengths + if (!stbi__zdefault_distance[31]) stbi__init_zdefaults(); + if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; + } else { + if (!stbi__compute_huffman_codes(a)) return 0; + } + if (!stbi__parse_huffman_block(a)) return 0; + } + } while (!final); + return 1; +} + +static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) +{ + a->zout_start = obuf; + a->zout = obuf; + a->zout_end = obuf + olen; + a->z_expandable = exp; + + return stbi__parse_zlib(a, parse_header); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) +{ + return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(16384); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer+len; + if (stbi__do_zlib(&a, p, 16384, 1, 0)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) + return (int) (a.zout - a.zout_start); + else + return -1; +} +#endif + +// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 +// simple implementation +// - only 8-bit samples +// - no CRC checking +// - allocates lots of intermediate memory +// - avoids problem of streaming data between subsystems +// - avoids explicit window management +// performance +// - uses stb_zlib, a PD zlib implementation with fast huffman decoding + +#ifndef STBI_NO_PNG +typedef struct +{ + stbi__uint32 length; + stbi__uint32 type; +} stbi__pngchunk; + +static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) +{ + stbi__pngchunk c; + c.length = stbi__get32be(s); + c.type = stbi__get32be(s); + return c; +} + +static int stbi__check_png_header(stbi__context *s) +{ + static stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; + int i; + for (i=0; i < 8; ++i) + if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); + return 1; +} + +typedef struct +{ + stbi__context *s; + stbi_uc *idata, *expanded, *out; + int depth; +} stbi__png; + + +enum { + STBI__F_none=0, + STBI__F_sub=1, + STBI__F_up=2, + STBI__F_avg=3, + STBI__F_paeth=4, + // synthetic filters used for first scanline to avoid needing a dummy row of 0s + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static stbi_uc first_row_filter[5] = +{ + STBI__F_none, + STBI__F_sub, + STBI__F_none, + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static int stbi__paeth(int a, int b, int c) +{ + int p = a + b - c; + int pa = abs(p-a); + int pb = abs(p-b); + int pc = abs(p-c); + if (pa <= pb && pa <= pc) return a; + if (pb <= pc) return b; + return c; +} + +static stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; + +// create the png data from post-deflated data +static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) +{ + int bytes = (depth == 16? 2 : 1); + stbi__context *s = a->s; + stbi__uint32 i,j,stride = x*out_n*bytes; + stbi__uint32 img_len, img_width_bytes; + int k; + int img_n = s->img_n; // copy it into a local for later + + int output_bytes = out_n*bytes; + int filter_bytes = img_n*bytes; + int width = x; + + STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); + a->out = (stbi_uc *) stbi__malloc(x * y * output_bytes); // extra bytes to write off the end into + if (!a->out) return stbi__err("outofmem", "Out of memory"); + + img_width_bytes = (((img_n * x * depth) + 7) >> 3); + img_len = (img_width_bytes + 1) * y; + if (s->img_x == x && s->img_y == y) { + if (raw_len != img_len) return stbi__err("not enough pixels","Corrupt PNG"); + } else { // interlaced: + if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); + } + + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *prior = cur - stride; + int filter = *raw++; + + if (filter > 4) + return stbi__err("invalid filter","Corrupt PNG"); + + if (depth < 8) { + STBI_ASSERT(img_width_bytes <= x); + cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place + filter_bytes = 1; + width = img_width_bytes; + } + + // if first row, use special filter that doesn't sample previous row + if (j == 0) filter = first_row_filter[filter]; + + // handle first byte explicitly + for (k=0; k < filter_bytes; ++k) { + switch (filter) { + case STBI__F_none : cur[k] = raw[k]; break; + case STBI__F_sub : cur[k] = raw[k]; break; + case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break; + case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break; + case STBI__F_avg_first : cur[k] = raw[k]; break; + case STBI__F_paeth_first: cur[k] = raw[k]; break; + } + } + + if (depth == 8) { + if (img_n != out_n) + cur[img_n] = 255; // first pixel + raw += img_n; + cur += out_n; + prior += out_n; + } else if (depth == 16) { + if (img_n != out_n) { + cur[filter_bytes] = 255; // first pixel top byte + cur[filter_bytes+1] = 255; // first pixel bottom byte + } + raw += filter_bytes; + cur += output_bytes; + prior += output_bytes; + } else { + raw += 1; + cur += 1; + prior += 1; + } + + // this is a little gross, so that we don't switch per-pixel or per-component + if (depth < 8 || img_n == out_n) { + int nk = (width - 1)*filter_bytes; + #define CASE(f) \ + case f: \ + for (k=0; k < nk; ++k) + switch (filter) { + // "none" filter turns into a memcpy here; make that explicit. + case STBI__F_none: memcpy(cur, raw, nk); break; + CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); break; + CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); break; + CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); break; + CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); break; + CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); break; + } + #undef CASE + raw += nk; + } else { + STBI_ASSERT(img_n+1 == out_n); + #define CASE(f) \ + case f: \ + for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ + for (k=0; k < filter_bytes; ++k) + switch (filter) { + CASE(STBI__F_none) cur[k] = raw[k]; break; + CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); break; + CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); break; + CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); break; + CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); break; + CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); break; + } + #undef CASE + + // the loop above sets the high byte of the pixels' alpha, but for + // 16 bit png files we also need the low byte set. we'll do that here. + if (depth == 16) { + cur = a->out + stride*j; // start at the beginning of the row again + for (i=0; i < x; ++i,cur+=output_bytes) { + cur[filter_bytes+1] = 255; + } + } + } + } + + // we make a separate pass to expand bits to pixels; for performance, + // this could run two scanlines behind the above code, so it won't + // intefere with filtering but will still be in the cache. + if (depth < 8) { + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes; + // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit + // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop + stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range + + // note that the final byte might overshoot and write more data than desired. + // we can allocate enough data that this never writes out of memory, but it + // could also overwrite the next scanline. can it overwrite non-empty data + // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. + // so we need to explicitly clamp the final ones + + if (depth == 4) { + for (k=x*img_n; k >= 2; k-=2, ++in) { + *cur++ = scale * ((*in >> 4) ); + *cur++ = scale * ((*in ) & 0x0f); + } + if (k > 0) *cur++ = scale * ((*in >> 4) ); + } else if (depth == 2) { + for (k=x*img_n; k >= 4; k-=4, ++in) { + *cur++ = scale * ((*in >> 6) ); + *cur++ = scale * ((*in >> 4) & 0x03); + *cur++ = scale * ((*in >> 2) & 0x03); + *cur++ = scale * ((*in ) & 0x03); + } + if (k > 0) *cur++ = scale * ((*in >> 6) ); + if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); + if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); + } else if (depth == 1) { + for (k=x*img_n; k >= 8; k-=8, ++in) { + *cur++ = scale * ((*in >> 7) ); + *cur++ = scale * ((*in >> 6) & 0x01); + *cur++ = scale * ((*in >> 5) & 0x01); + *cur++ = scale * ((*in >> 4) & 0x01); + *cur++ = scale * ((*in >> 3) & 0x01); + *cur++ = scale * ((*in >> 2) & 0x01); + *cur++ = scale * ((*in >> 1) & 0x01); + *cur++ = scale * ((*in ) & 0x01); + } + if (k > 0) *cur++ = scale * ((*in >> 7) ); + if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); + if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); + if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); + if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); + if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); + if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); + } + if (img_n != out_n) { + int q; + // insert alpha = 255 + cur = a->out + stride*j; + if (img_n == 1) { + for (q=x-1; q >= 0; --q) { + cur[q*2+1] = 255; + cur[q*2+0] = cur[q]; + } + } else { + STBI_ASSERT(img_n == 3); + for (q=x-1; q >= 0; --q) { + cur[q*4+3] = 255; + cur[q*4+2] = cur[q*3+2]; + cur[q*4+1] = cur[q*3+1]; + cur[q*4+0] = cur[q*3+0]; + } + } + } + } + } else if (depth == 16) { + // force the image data from big-endian to platform-native. + // this is done in a separate pass due to the decoding relying + // on the data being untouched, but could probably be done + // per-line during decode if care is taken. + stbi_uc *cur = a->out; + stbi__uint16 *cur16 = (stbi__uint16*)cur; + + for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) { + *cur16 = (cur[0] << 8) | cur[1]; + } + } + + return 1; +} + +static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) +{ + stbi_uc *final; + int p; + if (!interlaced) + return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); + + // de-interlacing + final = (stbi_uc *) stbi__malloc(a->s->img_x * a->s->img_y * out_n); + for (p=0; p < 7; ++p) { + int xorig[] = { 0,4,0,2,0,1,0 }; + int yorig[] = { 0,0,4,0,2,0,1 }; + int xspc[] = { 8,8,4,4,2,2,1 }; + int yspc[] = { 8,8,8,4,4,2,2 }; + int i,j,x,y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; + y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; + if (x && y) { + stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; + if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { + STBI_FREE(final); + return 0; + } + for (j=0; j < y; ++j) { + for (i=0; i < x; ++i) { + int out_y = j*yspc[p]+yorig[p]; + int out_x = i*xspc[p]+xorig[p]; + memcpy(final + out_y*a->s->img_x*out_n + out_x*out_n, + a->out + (j*x+i)*out_n, out_n); + } + } + STBI_FREE(a->out); + image_data += img_len; + image_data_len -= img_len; + } + } + a->out = final; + + return 1; +} + +static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + // compute color-based transparency, assuming we've + // already got 255 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i=0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 255); + p += 2; + } + } else { + for (i=0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi__uint16 *p = (stbi__uint16*) z->out; + + // compute color-based transparency, assuming we've + // already got 65535 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i = 0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 65535); + p += 2; + } + } else { + for (i = 0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n) +{ + stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; + stbi_uc *p, *temp_out, *orig = a->out; + + p = (stbi_uc *) stbi__malloc(pixel_count * pal_img_n); + if (p == NULL) return stbi__err("outofmem", "Out of memory"); + + // between here and free(out) below, exitting would leak + temp_out = p; + + if (pal_img_n == 3) { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p += 3; + } + } else { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p[3] = palette[n+3]; + p += 4; + } + } + STBI_FREE(a->out); + a->out = temp_out; + + STBI_NOTUSED(len); + + return 1; +} + +static int stbi__reduce_png(stbi__png *p) +{ + int i; + int img_len = p->s->img_x * p->s->img_y * p->s->img_out_n; + stbi_uc *reduced; + stbi__uint16 *orig = (stbi__uint16*)p->out; + + if (p->depth != 16) return 1; // don't need to do anything if not 16-bit data + + reduced = (stbi_uc *)stbi__malloc(img_len); + if (p == NULL) return stbi__err("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is a decent approx of 16->8 bit scaling + + p->out = reduced; + STBI_FREE(orig); + + return 1; +} + +static int stbi__unpremultiply_on_load = 0; +static int stbi__de_iphone_flag = 0; + +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) +{ + stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply; +} + +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) +{ + stbi__de_iphone_flag = flag_true_if_should_convert; +} + +static void stbi__de_iphone(stbi__png *z) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + if (s->img_out_n == 3) { // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 3; + } + } else { + STBI_ASSERT(s->img_out_n == 4); + if (stbi__unpremultiply_on_load) { + // convert bgr to rgb and unpremultiply + for (i=0; i < pixel_count; ++i) { + stbi_uc a = p[3]; + stbi_uc t = p[0]; + if (a) { + p[0] = p[2] * 255 / a; + p[1] = p[1] * 255 / a; + p[2] = t * 255 / a; + } else { + p[0] = p[2]; + p[2] = t; + } + p += 4; + } + } else { + // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 4; + } + } + } +} + +#define STBI__PNG_TYPE(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) + +static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) +{ + stbi_uc palette[1024], pal_img_n=0; + stbi_uc has_trans=0, tc[3]; + stbi__uint16 tc16[3]; + stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; + int first=1,k,interlace=0, color=0, is_iphone=0; + stbi__context *s = z->s; + + z->expanded = NULL; + z->idata = NULL; + z->out = NULL; + + if (!stbi__check_png_header(s)) return 0; + + if (scan == STBI__SCAN_type) return 1; + + for (;;) { + stbi__pngchunk c = stbi__get_chunk_header(s); + switch (c.type) { + case STBI__PNG_TYPE('C','g','B','I'): + is_iphone = 1; + stbi__skip(s, c.length); + break; + case STBI__PNG_TYPE('I','H','D','R'): { + int comp,filter; + if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); + first = 0; + if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); + s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); + s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); + z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); + color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); + comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); + filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); + interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); + if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); + if (!pal_img_n) { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + if (scan == STBI__SCAN_header) return 1; + } else { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); + // if SCAN_header, have to scan to see if we have a tRNS + } + break; + } + + case STBI__PNG_TYPE('P','L','T','E'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); + pal_len = c.length / 3; + if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG"); + for (i=0; i < pal_len; ++i) { + palette[i*4+0] = stbi__get8(s); + palette[i*4+1] = stbi__get8(s); + palette[i*4+2] = stbi__get8(s); + palette[i*4+3] = 255; + } + break; + } + + case STBI__PNG_TYPE('t','R','N','S'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG"); + if (pal_img_n) { + if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } + if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG"); + if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG"); + pal_img_n = 4; + for (i=0; i < c.length; ++i) + palette[i*4+3] = stbi__get8(s); + } else { + if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG"); + if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); + has_trans = 1; + if (z->depth == 16) { + for (k = 0; k < s->img_n; ++k) tc16[k] = stbi__get16be(s); // copy the values as-is + } else { + for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger + } + } + break; + } + + case STBI__PNG_TYPE('I','D','A','T'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG"); + if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; } + if ((int)(ioff + c.length) < (int)ioff) return 0; + if (ioff + c.length > idata_limit) { + stbi__uint32 idata_limit_old = idata_limit; + stbi_uc *p; + if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + STBI_NOTUSED(idata_limit_old); + p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); + z->idata = p; + } + if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); + ioff += c.length; + break; + } + + case STBI__PNG_TYPE('I','E','N','D'): { + stbi__uint32 raw_len, bpl; + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (scan != STBI__SCAN_load) return 1; + if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG"); + // initial guess for decoded data size to avoid unnecessary reallocs + bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component + raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; + z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone); + if (z->expanded == NULL) return 0; // zlib should set error + STBI_FREE(z->idata); z->idata = NULL; + if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n+1; + else + s->img_out_n = s->img_n; + if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; + if (has_trans) { + if (z->depth == 16) { + if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; + } else { + if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; + } + } + if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) + stbi__de_iphone(z); + if (pal_img_n) { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if (req_comp >= 3) s->img_out_n = req_comp; + if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } + STBI_FREE(z->expanded); z->expanded = NULL; + return 1; + } + + default: + // if critical, fail + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if ((c.type & (1 << 29)) == 0) { + #ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX PNG chunk not known"; + invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); + invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); + invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); + invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); + #endif + return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); + } + stbi__skip(s, c.length); + break; + } + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + } +} + +static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp) +{ + unsigned char *result=NULL; + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { + if (p->depth == 16) { + if (!stbi__reduce_png(p)) { + return result; + } + } + result = p->out; + p->out = NULL; + if (req_comp && req_comp != p->s->img_out_n) { + result = stbi__convert_format(result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + p->s->img_out_n = req_comp; + if (result == NULL) return result; + } + *x = p->s->img_x; + *y = p->s->img_y; + if (n) *n = p->s->img_n; + } + STBI_FREE(p->out); p->out = NULL; + STBI_FREE(p->expanded); p->expanded = NULL; + STBI_FREE(p->idata); p->idata = NULL; + + return result; +} + +static unsigned char *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__png p; + p.s = s; + return stbi__do_png(&p, x,y,comp,req_comp); +} + +static int stbi__png_test(stbi__context *s) +{ + int r; + r = stbi__check_png_header(s); + stbi__rewind(s); + return r; +} + +static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) +{ + if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { + stbi__rewind( p->s ); + return 0; + } + if (x) *x = p->s->img_x; + if (y) *y = p->s->img_y; + if (comp) *comp = p->s->img_n; + return 1; +} + +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__png p; + p.s = s; + return stbi__png_info_raw(&p, x, y, comp); +} +#endif + +// Microsoft/Windows BMP image + +#ifndef STBI_NO_BMP +static int stbi__bmp_test_raw(stbi__context *s) +{ + int r; + int sz; + if (stbi__get8(s) != 'B') return 0; + if (stbi__get8(s) != 'M') return 0; + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + stbi__get32le(s); // discard data offset + sz = stbi__get32le(s); + r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); + return r; +} + +static int stbi__bmp_test(stbi__context *s) +{ + int r = stbi__bmp_test_raw(s); + stbi__rewind(s); + return r; +} + + +// returns 0..31 for the highest set bit +static int stbi__high_bit(unsigned int z) +{ + int n=0; + if (z == 0) return -1; + if (z >= 0x10000) n += 16, z >>= 16; + if (z >= 0x00100) n += 8, z >>= 8; + if (z >= 0x00010) n += 4, z >>= 4; + if (z >= 0x00004) n += 2, z >>= 2; + if (z >= 0x00002) n += 1, z >>= 1; + return n; +} + +static int stbi__bitcount(unsigned int a) +{ + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits + return a & 0xff; +} + +static int stbi__shiftsigned(int v, int shift, int bits) +{ + int result; + int z=0; + + if (shift < 0) v <<= -shift; + else v >>= shift; + result = v; + + z = bits; + while (z < 8) { + result += v >> z; + z += bits; + } + return result; +} + +typedef struct +{ + int bpp, offset, hsz; + unsigned int mr,mg,mb,ma, all_a; +} stbi__bmp_data; + +static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) +{ + int hsz; + if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + info->offset = stbi__get32le(s); + info->hsz = hsz = stbi__get32le(s); + info->mr = info->mg = info->mb = info->ma = 0; + + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); + if (hsz == 12) { + s->img_x = stbi__get16le(s); + s->img_y = stbi__get16le(s); + } else { + s->img_x = stbi__get32le(s); + s->img_y = stbi__get32le(s); + } + if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); + info->bpp = stbi__get16le(s); + if (info->bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit"); + if (hsz != 12) { + int compress = stbi__get32le(s); + if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); + stbi__get32le(s); // discard sizeof + stbi__get32le(s); // discard hres + stbi__get32le(s); // discard vres + stbi__get32le(s); // discard colorsused + stbi__get32le(s); // discard max important + if (hsz == 40 || hsz == 56) { + if (hsz == 56) { + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + } + if (info->bpp == 16 || info->bpp == 32) { + if (compress == 0) { + if (info->bpp == 32) { + info->mr = 0xffu << 16; + info->mg = 0xffu << 8; + info->mb = 0xffu << 0; + info->ma = 0xffu << 24; + info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 + } else { + info->mr = 31u << 10; + info->mg = 31u << 5; + info->mb = 31u << 0; + } + } else if (compress == 3) { + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + // not documented, but generated by photoshop and handled by mspaint + if (info->mr == info->mg && info->mg == info->mb) { + // ?!?!? + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else { + int i; + if (hsz != 108 && hsz != 124) + return stbi__errpuc("bad BMP", "bad BMP"); + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->ma = stbi__get32le(s); + stbi__get32le(s); // discard color space + for (i=0; i < 12; ++i) + stbi__get32le(s); // discard color space parameters + if (hsz == 124) { + stbi__get32le(s); // discard rendering intent + stbi__get32le(s); // discard offset of profile data + stbi__get32le(s); // discard size of profile data + stbi__get32le(s); // discard reserved + } + } + } + return (void *) 1; +} + + +static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *out; + unsigned int mr=0,mg=0,mb=0,ma=0, all_a; + stbi_uc pal[256][4]; + int psize=0,i,j,width; + int flip_vertically, pad, target; + stbi__bmp_data info; + + info.all_a = 255; + if (stbi__bmp_parse_header(s, &info) == NULL) + return NULL; // error code already set + + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + + mr = info.mr; + mg = info.mg; + mb = info.mb; + ma = info.ma; + all_a = info.all_a; + + if (info.hsz == 12) { + if (info.bpp < 24) + psize = (info.offset - 14 - 24) / 3; + } else { + if (info.bpp < 16) + psize = (info.offset - 14 - info.hsz) >> 2; + } + + s->img_n = ma ? 4 : 3; + if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 + target = req_comp; + else + target = s->img_n; // if they want monochrome, we'll post-convert + + out = (stbi_uc *) stbi__malloc(target * s->img_x * s->img_y); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + if (info.bpp < 16) { + int z=0; + if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } + for (i=0; i < psize; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + if (info.hsz != 12) stbi__get8(s); + pal[i][3] = 255; + } + stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); + if (info.bpp == 4) width = (s->img_x + 1) >> 1; + else if (info.bpp == 8) width = s->img_x; + else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } + pad = (-width)&3; + for (j=0; j < (int) s->img_y; ++j) { + for (i=0; i < (int) s->img_x; i += 2) { + int v=stbi__get8(s),v2=0; + if (info.bpp == 4) { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + v = (info.bpp == 8) ? stbi__get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + } + stbi__skip(s, pad); + } + } else { + int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; + int z = 0; + int easy=0; + stbi__skip(s, info.offset - 14 - info.hsz); + if (info.bpp == 24) width = 3 * s->img_x; + else if (info.bpp == 16) width = 2*s->img_x; + else /* bpp = 32 and pad = 0 */ width=0; + pad = (-width) & 3; + if (info.bpp == 24) { + easy = 1; + } else if (info.bpp == 32) { + if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) + easy = 2; + } + if (!easy) { + if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } + // right shift amt to put high bit in position #7 + rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr); + gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); + bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); + ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); + } + for (j=0; j < (int) s->img_y; ++j) { + if (easy) { + for (i=0; i < (int) s->img_x; ++i) { + unsigned char a; + out[z+2] = stbi__get8(s); + out[z+1] = stbi__get8(s); + out[z+0] = stbi__get8(s); + z += 3; + a = (easy == 2 ? stbi__get8(s) : 255); + all_a |= a; + if (target == 4) out[z++] = a; + } + } else { + int bpp = info.bpp; + for (i=0; i < (int) s->img_x; ++i) { + stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); + int a; + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); + a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); + all_a |= a; + if (target == 4) out[z++] = STBI__BYTECAST(a); + } + } + stbi__skip(s, pad); + } + } + + // if alpha channel is all 0s, replace with all 255s + if (target == 4 && all_a == 0) + for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) + out[i] = 255; + + if (flip_vertically) { + stbi_uc t; + for (j=0; j < (int) s->img_y>>1; ++j) { + stbi_uc *p1 = out + j *s->img_x*target; + stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; + for (i=0; i < (int) s->img_x*target; ++i) { + t = p1[i], p1[i] = p2[i], p2[i] = t; + } + } + } + + if (req_comp && req_comp != target) { + out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + return out; +} +#endif + +// Targa Truevision - TGA +// by Jonathan Dummer +#ifndef STBI_NO_TGA +// returns STBI_rgb or whatever, 0 on error +static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) +{ + // only RGB or RGBA (incl. 16bit) or grey allowed + if(is_rgb16) *is_rgb16 = 0; + switch(bits_per_pixel) { + case 8: return STBI_grey; + case 16: if(is_grey) return STBI_grey_alpha; + // else: fall-through + case 15: if(is_rgb16) *is_rgb16 = 1; + return STBI_rgb; + case 24: // fall-through + case 32: return bits_per_pixel/8; + default: return 0; + } +} + +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) +{ + int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; + int sz, tga_colormap_type; + stbi__get8(s); // discard Offset + tga_colormap_type = stbi__get8(s); // colormap type + if( tga_colormap_type > 1 ) { + stbi__rewind(s); + return 0; // only RGB or indexed allowed + } + tga_image_type = stbi__get8(s); // image type + if ( tga_colormap_type == 1 ) { // colormapped (paletted) image + if (tga_image_type != 1 && tga_image_type != 9) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip image x and y origin + tga_colormap_bpp = sz; + } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE + if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) { + stbi__rewind(s); + return 0; // only RGB or grey allowed, +/- RLE + } + stbi__skip(s,9); // skip colormap specification and image x/y origin + tga_colormap_bpp = 0; + } + tga_w = stbi__get16le(s); + if( tga_w < 1 ) { + stbi__rewind(s); + return 0; // test width + } + tga_h = stbi__get16le(s); + if( tga_h < 1 ) { + stbi__rewind(s); + return 0; // test height + } + tga_bits_per_pixel = stbi__get8(s); // bits per pixel + stbi__get8(s); // ignore alpha bits + if (tga_colormap_bpp != 0) { + if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { + // when using a colormap, tga_bits_per_pixel is the size of the indexes + // I don't think anything but 8 or 16bit indexes makes sense + stbi__rewind(s); + return 0; + } + tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); + } else { + tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); + } + if(!tga_comp) { + stbi__rewind(s); + return 0; + } + if (x) *x = tga_w; + if (y) *y = tga_h; + if (comp) *comp = tga_comp; + return 1; // seems to have passed everything +} + +static int stbi__tga_test(stbi__context *s) +{ + int res = 0; + int sz, tga_color_type; + stbi__get8(s); // discard Offset + tga_color_type = stbi__get8(s); // color type + if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed + sz = stbi__get8(s); // image type + if ( tga_color_type == 1 ) { // colormapped (paletted) image + if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + stbi__skip(s,4); // skip image x and y origin + } else { // "normal" image w/o colormap + if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE + stbi__skip(s,9); // skip colormap specification and image x/y origin + } + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height + sz = stbi__get8(s); // bits per pixel + if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + + res = 1; // if we got this far, everything's good and we can return 1 instead of 0 + +errorEnd: + stbi__rewind(s); + return res; +} + +// read 16bit value and convert to 24bit RGB +void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) +{ + stbi__uint16 px = stbi__get16le(s); + stbi__uint16 fiveBitMask = 31; + // we have 3 channels with 5bits each + int r = (px >> 10) & fiveBitMask; + int g = (px >> 5) & fiveBitMask; + int b = px & fiveBitMask; + // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later + out[0] = (r * 255)/31; + out[1] = (g * 255)/31; + out[2] = (b * 255)/31; + + // some people claim that the most significant bit might be used for alpha + // (possibly if an alpha-bit is set in the "image descriptor byte") + // but that only made 16bit test images completely translucent.. + // so let's treat all 15 and 16bit TGAs as RGB with no alpha. +} + +static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + // read in the TGA header stuff + int tga_offset = stbi__get8(s); + int tga_indexed = stbi__get8(s); + int tga_image_type = stbi__get8(s); + int tga_is_RLE = 0; + int tga_palette_start = stbi__get16le(s); + int tga_palette_len = stbi__get16le(s); + int tga_palette_bits = stbi__get8(s); + int tga_x_origin = stbi__get16le(s); + int tga_y_origin = stbi__get16le(s); + int tga_width = stbi__get16le(s); + int tga_height = stbi__get16le(s); + int tga_bits_per_pixel = stbi__get8(s); + int tga_comp, tga_rgb16=0; + int tga_inverted = stbi__get8(s); + // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) + // image data + unsigned char *tga_data; + unsigned char *tga_palette = NULL; + int i, j; + unsigned char raw_data[4]; + int RLE_count = 0; + int RLE_repeating = 0; + int read_next_pixel = 1; + + // do a tiny bit of precessing + if ( tga_image_type >= 8 ) + { + tga_image_type -= 8; + tga_is_RLE = 1; + } + tga_inverted = 1 - ((tga_inverted >> 5) & 1); + + // If I'm paletted, then I'll use the number of bits from the palette + if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); + else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); + + if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency + return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); + + // tga info + *x = tga_width; + *y = tga_height; + if (comp) *comp = tga_comp; + + tga_data = (unsigned char*)stbi__malloc( (size_t)tga_width * tga_height * tga_comp ); + if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); + + // skip to the data's starting position (offset usually = 0) + stbi__skip(s, tga_offset ); + + if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) { + for (i=0; i < tga_height; ++i) { + int row = tga_inverted ? tga_height -i - 1 : i; + stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; + stbi__getn(s, tga_row, tga_width * tga_comp); + } + } else { + // do I need to load a palette? + if ( tga_indexed) + { + // any data to skip? (offset usually = 0) + stbi__skip(s, tga_palette_start ); + // load the palette + tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_comp ); + if (!tga_palette) { + STBI_FREE(tga_data); + return stbi__errpuc("outofmem", "Out of memory"); + } + if (tga_rgb16) { + stbi_uc *pal_entry = tga_palette; + STBI_ASSERT(tga_comp == STBI_rgb); + for (i=0; i < tga_palette_len; ++i) { + stbi__tga_read_rgb16(s, pal_entry); + pal_entry += tga_comp; + } + } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { + STBI_FREE(tga_data); + STBI_FREE(tga_palette); + return stbi__errpuc("bad palette", "Corrupt TGA"); + } + } + // load the data + for (i=0; i < tga_width * tga_height; ++i) + { + // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? + if ( tga_is_RLE ) + { + if ( RLE_count == 0 ) + { + // yep, get the next byte as a RLE command + int RLE_cmd = stbi__get8(s); + RLE_count = 1 + (RLE_cmd & 127); + RLE_repeating = RLE_cmd >> 7; + read_next_pixel = 1; + } else if ( !RLE_repeating ) + { + read_next_pixel = 1; + } + } else + { + read_next_pixel = 1; + } + // OK, if I need to read a pixel, do it now + if ( read_next_pixel ) + { + // load however much data we did have + if ( tga_indexed ) + { + // read in index, then perform the lookup + int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); + if ( pal_idx >= tga_palette_len ) { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_comp; + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = tga_palette[pal_idx+j]; + } + } else if(tga_rgb16) { + STBI_ASSERT(tga_comp == STBI_rgb); + stbi__tga_read_rgb16(s, raw_data); + } else { + // read in the data raw + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = stbi__get8(s); + } + } + // clear the reading flag for the next pixel + read_next_pixel = 0; + } // end of reading a pixel + + // copy data + for (j = 0; j < tga_comp; ++j) + tga_data[i*tga_comp+j] = raw_data[j]; + + // in case we're in RLE mode, keep counting down + --RLE_count; + } + // do I need to invert the image? + if ( tga_inverted ) + { + for (j = 0; j*2 < tga_height; ++j) + { + int index1 = j * tga_width * tga_comp; + int index2 = (tga_height - 1 - j) * tga_width * tga_comp; + for (i = tga_width * tga_comp; i > 0; --i) + { + unsigned char temp = tga_data[index1]; + tga_data[index1] = tga_data[index2]; + tga_data[index2] = temp; + ++index1; + ++index2; + } + } + } + // clear my palette, if I had one + if ( tga_palette != NULL ) + { + STBI_FREE( tga_palette ); + } + } + + // swap RGB - if the source data was RGB16, it already is in the right order + if (tga_comp >= 3 && !tga_rgb16) + { + unsigned char* tga_pixel = tga_data; + for (i=0; i < tga_width * tga_height; ++i) + { + unsigned char temp = tga_pixel[0]; + tga_pixel[0] = tga_pixel[2]; + tga_pixel[2] = temp; + tga_pixel += tga_comp; + } + } + + // convert to target component count + if (req_comp && req_comp != tga_comp) + tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); + + // the things I do to get rid of an error message, and yet keep + // Microsoft's C compilers happy... [8^( + tga_palette_start = tga_palette_len = tga_palette_bits = + tga_x_origin = tga_y_origin = 0; + // OK, done + return tga_data; +} +#endif + +// ************************************************************************************************* +// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s) +{ + int r = (stbi__get32be(s) == 0x38425053); + stbi__rewind(s); + return r; +} + +static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + int pixelCount; + int channelCount, compression; + int channel, i, count, len; + int bitdepth; + int w,h; + stbi_uc *out; + + // Check identifier + if (stbi__get32be(s) != 0x38425053) // "8BPS" + return stbi__errpuc("not PSD", "Corrupt PSD image"); + + // Check file type version. + if (stbi__get16be(s) != 1) + return stbi__errpuc("wrong version", "Unsupported version of PSD image"); + + // Skip 6 reserved bytes. + stbi__skip(s, 6 ); + + // Read the number of channels (R, G, B, A, etc). + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) + return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); + + // Read the rows and columns of the image. + h = stbi__get32be(s); + w = stbi__get32be(s); + + // Make sure the depth is 8 bits. + bitdepth = stbi__get16be(s); + if (bitdepth != 8 && bitdepth != 16) + return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); + + // Make sure the color mode is RGB. + // Valid options are: + // 0: Bitmap + // 1: Grayscale + // 2: Indexed color + // 3: RGB color + // 4: CMYK color + // 7: Multichannel + // 8: Duotone + // 9: Lab color + if (stbi__get16be(s) != 3) + return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); + + // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) + stbi__skip(s,stbi__get32be(s) ); + + // Skip the image resources. (resolution, pen tool paths, etc) + stbi__skip(s, stbi__get32be(s) ); + + // Skip the reserved data. + stbi__skip(s, stbi__get32be(s) ); + + // Find out if the data is compressed. + // Known values: + // 0: no compression + // 1: RLE compressed + compression = stbi__get16be(s); + if (compression > 1) + return stbi__errpuc("bad compression", "PSD has an unknown compression format"); + + // Create the destination image. + out = (stbi_uc *) stbi__malloc(4 * w*h); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + pixelCount = w*h; + + // Initialize the data to zero. + //memset( out, 0, pixelCount * 4 ); + + // Finally, the image data. + if (compression) { + // RLE as used by .PSD and .TIFF + // Loop until you get the number of unpacked bytes you are expecting: + // Read the next source byte into n. + // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. + // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. + // Else if n is 128, noop. + // Endloop + + // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, + // which we're going to just skip. + stbi__skip(s, h * channelCount * 2 ); + + // Read the RLE data by channel. + for (channel = 0; channel < 4; channel++) { + stbi_uc *p; + + p = out+channel; + if (channel >= channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++, p += 4) + *p = (channel == 3 ? 255 : 0); + } else { + // Read the RLE data. + count = 0; + while (count < pixelCount) { + len = stbi__get8(s); + if (len == 128) { + // No-op. + } else if (len < 128) { + // Copy next len+1 bytes literally. + len++; + count += len; + while (len) { + *p = stbi__get8(s); + p += 4; + len--; + } + } else if (len > 128) { + stbi_uc val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len ^= 0x0FF; + len += 2; + val = stbi__get8(s); + count += len; + while (len) { + *p = val; + p += 4; + len--; + } + } + } + } + } + + } else { + // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) + // where each channel consists of an 8-bit value for each pixel in the image. + + // Read the data by channel. + for (channel = 0; channel < 4; channel++) { + stbi_uc *p; + + p = out + channel; + if (channel >= channelCount) { + // Fill this channel with default data. + stbi_uc val = channel == 3 ? 255 : 0; + for (i = 0; i < pixelCount; i++, p += 4) + *p = val; + } else { + // Read the data. + if (bitdepth == 16) { + for (i = 0; i < pixelCount; i++, p += 4) + *p = (stbi_uc) (stbi__get16be(s) >> 8); + } else { + for (i = 0; i < pixelCount; i++, p += 4) + *p = stbi__get8(s); + } + } + } + } + + if (channelCount >= 4) { + for (i=0; i < w*h; ++i) { + unsigned char *pixel = out + 4*i; + if (pixel[3] != 0 && pixel[3] != 255) { + // remove weird white matte from PSD + float a = pixel[3] / 255.0f; + float ra = 1.0f / a; + float inv_a = 255.0f * (1 - ra); + pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); + pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); + pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); + } + } + } + + if (req_comp && req_comp != 4) { + out = stbi__convert_format(out, 4, req_comp, w, h); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + if (comp) *comp = 4; + *y = h; + *x = w; + + return out; +} +#endif + +// ************************************************************************************************* +// Softimage PIC loader +// by Tom Seddon +// +// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format +// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ + +#ifndef STBI_NO_PIC +static int stbi__pic_is4(stbi__context *s,const char *str) +{ + int i; + for (i=0; i<4; ++i) + if (stbi__get8(s) != (stbi_uc)str[i]) + return 0; + + return 1; +} + +static int stbi__pic_test_core(stbi__context *s) +{ + int i; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) + return 0; + + for(i=0;i<84;++i) + stbi__get8(s); + + if (!stbi__pic_is4(s,"PICT")) + return 0; + + return 1; +} + +typedef struct +{ + stbi_uc size,type,channel; +} stbi__pic_packet; + +static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) +{ + int mask=0x80, i; + + for (i=0; i<4; ++i, mask>>=1) { + if (channel & mask) { + if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short"); + dest[i]=stbi__get8(s); + } + } + + return dest; +} + +static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src) +{ + int mask=0x80,i; + + for (i=0;i<4; ++i, mask>>=1) + if (channel&mask) + dest[i]=src[i]; +} + +static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result) +{ + int act_comp=0,num_packets=0,y,chained; + stbi__pic_packet packets[10]; + + // this will (should...) cater for even some bizarre stuff like having data + // for the same channel in multiple packets. + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return stbi__errpuc("bad format","too many packets"); + + packet = &packets[num_packets++]; + + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + + act_comp |= packet->channel; + + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)"); + if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp"); + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? + + for(y=0; ytype) { + default: + return stbi__errpuc("bad format","packet has bad compression type"); + + case 0: {//uncompressed + int x; + + for(x=0;xchannel,dest)) + return 0; + break; + } + + case 1://Pure RLE + { + int left=width, i; + + while (left>0) { + stbi_uc count,value[4]; + + count=stbi__get8(s); + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)"); + + if (count > left) + count = (stbi_uc) left; + + if (!stbi__readval(s,packet->channel,value)) return 0; + + for(i=0; ichannel,dest,value); + left -= count; + } + } + break; + + case 2: {//Mixed RLE + int left=width; + while (left>0) { + int count = stbi__get8(s), i; + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)"); + + if (count >= 128) { // Repeated + stbi_uc value[4]; + + if (count==128) + count = stbi__get16be(s); + else + count -= 127; + if (count > left) + return stbi__errpuc("bad file","scanline overrun"); + + if (!stbi__readval(s,packet->channel,value)) + return 0; + + for(i=0;ichannel,dest,value); + } else { // Raw + ++count; + if (count>left) return stbi__errpuc("bad file","scanline overrun"); + + for(i=0;ichannel,dest)) + return 0; + } + left-=count; + } + break; + } + } + } + } + + return result; +} + +static stbi_uc *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp) +{ + stbi_uc *result; + int i, x,y; + + for (i=0; i<92; ++i) + stbi__get8(s); + + x = stbi__get16be(s); + y = stbi__get16be(s); + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); + if ((1 << 28) / x < y) return stbi__errpuc("too large", "Image too large to decode"); + + stbi__get32be(s); //skip `ratio' + stbi__get16be(s); //skip `fields' + stbi__get16be(s); //skip `pad' + + // intermediate buffer is RGBA + result = (stbi_uc *) stbi__malloc(x*y*4); + memset(result, 0xff, x*y*4); + + if (!stbi__pic_load_core(s,x,y,comp, result)) { + STBI_FREE(result); + result=0; + } + *px = x; + *py = y; + if (req_comp == 0) req_comp = *comp; + result=stbi__convert_format(result,4,req_comp,x,y); + + return result; +} + +static int stbi__pic_test(stbi__context *s) +{ + int r = stbi__pic_test_core(s); + stbi__rewind(s); + return r; +} +#endif + +// ************************************************************************************************* +// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb + +#ifndef STBI_NO_GIF +typedef struct +{ + stbi__int16 prefix; + stbi_uc first; + stbi_uc suffix; +} stbi__gif_lzw; + +typedef struct +{ + int w,h; + stbi_uc *out, *old_out; // output buffer (always 4 components) + int flags, bgindex, ratio, transparent, eflags, delay; + stbi_uc pal[256][4]; + stbi_uc lpal[256][4]; + stbi__gif_lzw codes[4096]; + stbi_uc *color_table; + int parse, step; + int lflags; + int start_x, start_y; + int max_x, max_y; + int cur_x, cur_y; + int line_size; +} stbi__gif; + +static int stbi__gif_test_raw(stbi__context *s) +{ + int sz; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; + sz = stbi__get8(s); + if (sz != '9' && sz != '7') return 0; + if (stbi__get8(s) != 'a') return 0; + return 1; +} + +static int stbi__gif_test(stbi__context *s) +{ + int r = stbi__gif_test_raw(s); + stbi__rewind(s); + return r; +} + +static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) +{ + int i; + for (i=0; i < num_entries; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + pal[i][3] = transp == i ? 0 : 255; + } +} + +static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) +{ + stbi_uc version; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') + return stbi__err("not GIF", "Corrupt GIF"); + + version = stbi__get8(s); + if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); + if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); + + stbi__g_failure_reason = ""; + g->w = stbi__get16le(s); + g->h = stbi__get16le(s); + g->flags = stbi__get8(s); + g->bgindex = stbi__get8(s); + g->ratio = stbi__get8(s); + g->transparent = -1; + + if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + + if (is_info) return 1; + + if (g->flags & 0x80) + stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); + + return 1; +} + +static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); + if (!stbi__gif_header(s, g, comp, 1)) { + STBI_FREE(g); + stbi__rewind( s ); + return 0; + } + if (x) *x = g->w; + if (y) *y = g->h; + STBI_FREE(g); + return 1; +} + +static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) +{ + stbi_uc *p, *c; + + // recurse to decode the prefixes, since the linked-list is backwards, + // and working backwards through an interleaved image would be nasty + if (g->codes[code].prefix >= 0) + stbi__out_gif_code(g, g->codes[code].prefix); + + if (g->cur_y >= g->max_y) return; + + p = &g->out[g->cur_x + g->cur_y]; + c = &g->color_table[g->codes[code].suffix * 4]; + + if (c[3] >= 128) { + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } + g->cur_x += 4; + + if (g->cur_x >= g->max_x) { + g->cur_x = g->start_x; + g->cur_y += g->step; + + while (g->cur_y >= g->max_y && g->parse > 0) { + g->step = (1 << g->parse) * g->line_size; + g->cur_y = g->start_y + (g->step >> 1); + --g->parse; + } + } +} + +static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) +{ + stbi_uc lzw_cs; + stbi__int32 len, init_code; + stbi__uint32 first; + stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; + stbi__gif_lzw *p; + + lzw_cs = stbi__get8(s); + if (lzw_cs > 12) return NULL; + clear = 1 << lzw_cs; + first = 1; + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + bits = 0; + valid_bits = 0; + for (init_code = 0; init_code < clear; init_code++) { + g->codes[init_code].prefix = -1; + g->codes[init_code].first = (stbi_uc) init_code; + g->codes[init_code].suffix = (stbi_uc) init_code; + } + + // support no starting clear code + avail = clear+2; + oldcode = -1; + + len = 0; + for(;;) { + if (valid_bits < codesize) { + if (len == 0) { + len = stbi__get8(s); // start new block + if (len == 0) + return g->out; + } + --len; + bits |= (stbi__int32) stbi__get8(s) << valid_bits; + valid_bits += 8; + } else { + stbi__int32 code = bits & codemask; + bits >>= codesize; + valid_bits -= codesize; + // @OPTIMIZE: is there some way we can accelerate the non-clear path? + if (code == clear) { // clear code + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + first = 0; + } else if (code == clear + 1) { // end of stream code + stbi__skip(s, len); + while ((len = stbi__get8(s)) > 0) + stbi__skip(s,len); + return g->out; + } else if (code <= avail) { + if (first) return stbi__errpuc("no clear code", "Corrupt GIF"); + + if (oldcode >= 0) { + p = &g->codes[avail++]; + if (avail > 4096) return stbi__errpuc("too many codes", "Corrupt GIF"); + p->prefix = (stbi__int16) oldcode; + p->first = g->codes[oldcode].first; + p->suffix = (code == avail) ? p->first : g->codes[code].first; + } else if (code == avail) + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + + stbi__out_gif_code(g, (stbi__uint16) code); + + if ((avail & codemask) == 0 && avail <= 0x0FFF) { + codesize++; + codemask = (1 << codesize) - 1; + } + + oldcode = code; + } else { + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + } + } + } +} + +static void stbi__fill_gif_background(stbi__gif *g, int x0, int y0, int x1, int y1) +{ + int x, y; + stbi_uc *c = g->pal[g->bgindex]; + for (y = y0; y < y1; y += 4 * g->w) { + for (x = x0; x < x1; x += 4) { + stbi_uc *p = &g->out[y + x]; + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = 0; + } + } +} + +// this function is designed to support animated gifs, although stb_image doesn't support it +static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp) +{ + int i; + stbi_uc *prev_out = 0; + + if (g->out == 0 && !stbi__gif_header(s, g, comp,0)) + return 0; // stbi__g_failure_reason set by stbi__gif_header + + prev_out = g->out; + g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); + if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); + + switch ((g->eflags & 0x1C) >> 2) { + case 0: // unspecified (also always used on 1st frame) + stbi__fill_gif_background(g, 0, 0, 4 * g->w, 4 * g->w * g->h); + break; + case 1: // do not dispose + if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h); + g->old_out = prev_out; + break; + case 2: // dispose to background + if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h); + stbi__fill_gif_background(g, g->start_x, g->start_y, g->max_x, g->max_y); + break; + case 3: // dispose to previous + if (g->old_out) { + for (i = g->start_y; i < g->max_y; i += 4 * g->w) + memcpy(&g->out[i + g->start_x], &g->old_out[i + g->start_x], g->max_x - g->start_x); + } + break; + } + + for (;;) { + switch (stbi__get8(s)) { + case 0x2C: /* Image Descriptor */ + { + int prev_trans = -1; + stbi__int32 x, y, w, h; + stbi_uc *o; + + x = stbi__get16le(s); + y = stbi__get16le(s); + w = stbi__get16le(s); + h = stbi__get16le(s); + if (((x + w) > (g->w)) || ((y + h) > (g->h))) + return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); + + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; + + g->lflags = stbi__get8(s); + + if (g->lflags & 0x40) { + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } else { + g->step = g->line_size; + g->parse = 0; + } + + if (g->lflags & 0x80) { + stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (stbi_uc *) g->lpal; + } else if (g->flags & 0x80) { + if (g->transparent >= 0 && (g->eflags & 0x01)) { + prev_trans = g->pal[g->transparent][3]; + g->pal[g->transparent][3] = 0; + } + g->color_table = (stbi_uc *) g->pal; + } else + return stbi__errpuc("missing color table", "Corrupt GIF"); + + o = stbi__process_gif_raster(s, g); + if (o == NULL) return NULL; + + if (prev_trans != -1) + g->pal[g->transparent][3] = (stbi_uc) prev_trans; + + return o; + } + + case 0x21: // Comment Extension. + { + int len; + if (stbi__get8(s) == 0xF9) { // Graphic Control Extension. + len = stbi__get8(s); + if (len == 4) { + g->eflags = stbi__get8(s); + g->delay = stbi__get16le(s); + g->transparent = stbi__get8(s); + } else { + stbi__skip(s, len); + break; + } + } + while ((len = stbi__get8(s)) != 0) + stbi__skip(s, len); + break; + } + + case 0x3B: // gif stream termination code + return (stbi_uc *) s; // using '1' causes warning on some compilers + + default: + return stbi__errpuc("unknown code", "Corrupt GIF"); + } + } + + STBI_NOTUSED(req_comp); +} + +static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *u = 0; + stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); + memset(g, 0, sizeof(*g)); + + u = stbi__gif_load_next(s, g, comp, req_comp); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + if (u) { + *x = g->w; + *y = g->h; + if (req_comp && req_comp != 4) + u = stbi__convert_format(u, 4, req_comp, g->w, g->h); + } + else if (g->out) + STBI_FREE(g->out); + STBI_FREE(g); + return u; +} + +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) +{ + return stbi__gif_info_raw(s,x,y,comp); +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR loader +// originally by Nicolas Schulz +#ifndef STBI_NO_HDR +static int stbi__hdr_test_core(stbi__context *s) +{ + const char *signature = "#?RADIANCE\n"; + int i; + for (i=0; signature[i]; ++i) + if (stbi__get8(s) != signature[i]) + return 0; + return 1; +} + +static int stbi__hdr_test(stbi__context* s) +{ + int r = stbi__hdr_test_core(s); + stbi__rewind(s); + return r; +} + +#define STBI__HDR_BUFLEN 1024 +static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) +{ + int len=0; + char c = '\0'; + + c = (char) stbi__get8(z); + + while (!stbi__at_eof(z) && c != '\n') { + buffer[len++] = c; + if (len == STBI__HDR_BUFLEN-1) { + // flush to end of line + while (!stbi__at_eof(z) && stbi__get8(z) != '\n') + ; + break; + } + c = (char) stbi__get8(z); + } + + buffer[len] = 0; + return buffer; +} + +static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) +{ + if ( input[3] != 0 ) { + float f1; + // Exponent + f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); + if (req_comp <= 2) + output[0] = (input[0] + input[1] + input[2]) * f1 / 3; + else { + output[0] = input[0] * f1; + output[1] = input[1] * f1; + output[2] = input[2] * f1; + } + if (req_comp == 2) output[1] = 1; + if (req_comp == 4) output[3] = 1; + } else { + switch (req_comp) { + case 4: output[3] = 1; /* fallthrough */ + case 3: output[0] = output[1] = output[2] = 0; + break; + case 2: output[1] = 1; /* fallthrough */ + case 1: output[0] = 0; + break; + } + } +} + +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + int width, height; + stbi_uc *scanline; + float *hdr_data; + int len; + unsigned char count, value; + int i, j, k, c1,c2, z; + + + // Check identifier + if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0) + return stbi__errpf("not HDR", "Corrupt HDR image"); + + // Parse header + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); + + // Parse width and height + // can't use sscanf() if we're not using stdio! + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + height = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + width = (int) strtol(token, NULL, 10); + + *x = width; + *y = height; + + if (comp) *comp = 3; + if (req_comp == 0) req_comp = 3; + + // Read data + hdr_data = (float *) stbi__malloc(height * width * req_comp * sizeof(float)); + + // Load image data + // image data is stored as some number of sca + if ( width < 8 || width >= 32768) { + // Read flat data + for (j=0; j < height; ++j) { + for (i=0; i < width; ++i) { + stbi_uc rgbe[4]; + main_decode_loop: + stbi__getn(s, rgbe, 4); + stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); + } + } + } else { + // Read RLE-encoded data + scanline = NULL; + + for (j = 0; j < height; ++j) { + c1 = stbi__get8(s); + c2 = stbi__get8(s); + len = stbi__get8(s); + if (c1 != 2 || c2 != 2 || (len & 0x80)) { + // not run-length encoded, so we have to actually use THIS data as a decoded + // pixel (note this can't be a valid pixel--one of RGB must be >= 128) + stbi_uc rgbe[4]; + rgbe[0] = (stbi_uc) c1; + rgbe[1] = (stbi_uc) c2; + rgbe[2] = (stbi_uc) len; + rgbe[3] = (stbi_uc) stbi__get8(s); + stbi__hdr_convert(hdr_data, rgbe, req_comp); + i = 1; + j = 0; + STBI_FREE(scanline); + goto main_decode_loop; // yes, this makes no sense + } + len <<= 8; + len |= stbi__get8(s); + if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } + if (scanline == NULL) scanline = (stbi_uc *) stbi__malloc(width * 4); + + for (k = 0; k < 4; ++k) { + i = 0; + while (i < width) { + count = stbi__get8(s); + if (count > 128) { + // Run + value = stbi__get8(s); + count -= 128; + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = value; + } else { + // Dump + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = stbi__get8(s); + } + } + } + for (i=0; i < width; ++i) + stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); + } + STBI_FREE(scanline); + } + + return hdr_data; +} + +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + + if (stbi__hdr_test(s) == 0) { + stbi__rewind( s ); + return 0; + } + + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) { + stbi__rewind( s ); + return 0; + } + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *y = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *x = (int) strtol(token, NULL, 10); + *comp = 3; + return 1; +} +#endif // STBI_NO_HDR + +#ifndef STBI_NO_BMP +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) +{ + void *p; + stbi__bmp_data info; + + info.all_a = 255; + p = stbi__bmp_parse_header(s, &info); + stbi__rewind( s ); + if (p == NULL) + return 0; + *x = s->img_x; + *y = s->img_y; + *comp = info.ma ? 4 : 3; + return 1; +} +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) +{ + int channelCount; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + *y = stbi__get32be(s); + *x = stbi__get32be(s); + if (stbi__get16be(s) != 8) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 3) { + stbi__rewind( s ); + return 0; + } + *comp = 4; + return 1; +} +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) +{ + int act_comp=0,num_packets=0,chained; + stbi__pic_packet packets[10]; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { + stbi__rewind(s); + return 0; + } + + stbi__skip(s, 88); + + *x = stbi__get16be(s); + *y = stbi__get16be(s); + if (stbi__at_eof(s)) { + stbi__rewind( s); + return 0; + } + if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { + stbi__rewind( s ); + return 0; + } + + stbi__skip(s, 8); + + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return 0; + + packet = &packets[num_packets++]; + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + act_comp |= packet->channel; + + if (stbi__at_eof(s)) { + stbi__rewind( s ); + return 0; + } + if (packet->size != 8) { + stbi__rewind( s ); + return 0; + } + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); + + return 1; +} +#endif + +// ************************************************************************************************* +// Portable Gray Map and Portable Pixel Map loader +// by Ken Miller +// +// PGM: http://netpbm.sourceforge.net/doc/pgm.html +// PPM: http://netpbm.sourceforge.net/doc/ppm.html +// +// Known limitations: +// Does not support comments in the header section +// Does not support ASCII image data (formats P2 and P3) +// Does not support 16-bit-per-channel + +#ifndef STBI_NO_PNM + +static int stbi__pnm_test(stbi__context *s) +{ + char p, t; + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind( s ); + return 0; + } + return 1; +} + +static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi_uc *out; + if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n)) + return 0; + *x = s->img_x; + *y = s->img_y; + *comp = s->img_n; + + out = (stbi_uc *) stbi__malloc(s->img_n * s->img_x * s->img_y); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + stbi__getn(s, out, s->img_n * s->img_x * s->img_y); + + if (req_comp && req_comp != s->img_n) { + out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + return out; +} + +static int stbi__pnm_isspace(char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; +} + +static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) +{ + for (;;) { + while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) + *c = (char) stbi__get8(s); + + if (stbi__at_eof(s) || *c != '#') + break; + + while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' ) + *c = (char) stbi__get8(s); + } +} + +static int stbi__pnm_isdigit(char c) +{ + return c >= '0' && c <= '9'; +} + +static int stbi__pnm_getinteger(stbi__context *s, char *c) +{ + int value = 0; + + while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { + value = value*10 + (*c - '0'); + *c = (char) stbi__get8(s); + } + + return value; +} + +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) +{ + int maxv; + char c, p, t; + + stbi__rewind( s ); + + // Get identifier + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind( s ); + return 0; + } + + *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm + + c = (char) stbi__get8(s); + stbi__pnm_skip_whitespace(s, &c); + + *x = stbi__pnm_getinteger(s, &c); // read width + stbi__pnm_skip_whitespace(s, &c); + + *y = stbi__pnm_getinteger(s, &c); // read height + stbi__pnm_skip_whitespace(s, &c); + + maxv = stbi__pnm_getinteger(s, &c); // read max value + + if (maxv > 255) + return stbi__err("max value > 255", "PPM image not 8-bit"); + else + return 1; +} +#endif + +static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) +{ + #ifndef STBI_NO_JPEG + if (stbi__jpeg_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNG + if (stbi__png_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_GIF + if (stbi__gif_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_BMP + if (stbi__bmp_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PIC + if (stbi__pic_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNM + if (stbi__pnm_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_info(s, x, y, comp)) return 1; + #endif + + // test tga last because it's a crappy test! + #ifndef STBI_NO_TGA + if (stbi__tga_info(s, x, y, comp)) + return 1; + #endif + return stbi__err("unknown image type", "Image not of any known type, or corrupt"); +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; +} + +STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__info_main(&s,x,y,comp); + fseek(f,pos,SEEK_SET); + return r; +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__info_main(&s,x,y,comp); +} + +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__info_main(&s,x,y,comp); +} + +#endif // STB_IMAGE_IMPLEMENTATION + +/* + revision history: + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) allocate large structures on the stack + remove white matting for transparent PSD + fix reported channel count for PNG & BMP + re-enable SSE2 in non-gcc 64-bit + support RGB-formatted JPEG + read 16-bit PNGs (only as 8-bit) + 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED + 2.09 (2016-01-16) allow comments in PNM files + 16-bit-per-pixel TGA (not bit-per-component) + info() for TGA could break due to .hdr handling + info() for BMP to shares code instead of sloppy parse + can use STBI_REALLOC_SIZED if allocator doesn't support realloc + code cleanup + 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA + 2.07 (2015-09-13) fix compiler warnings + partial animated GIF support + limited 16-bpc PSD support + #ifdef unused functions + bug with < 92 byte PIC,PNM,HDR,TGA + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value + 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning + 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit + 2.03 (2015-04-12) extra corruption checking (mmozeiko) + stbi_set_flip_vertically_on_load (nguillemot) + fix NEON support; fix mingw support + 2.02 (2015-01-19) fix incorrect assert, fix warning + 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 + 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG + 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) + progressive JPEG (stb) + PGM/PPM support (Ken Miller) + STBI_MALLOC,STBI_REALLOC,STBI_FREE + GIF bugfix -- seemingly never worked + STBI_NO_*, STBI_ONLY_* + 1.48 (2014-12-14) fix incorrectly-named assert() + 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) + optimize PNG (ryg) + fix bug in interlaced PNG with user-specified channel count (stb) + 1.46 (2014-08-26) + fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG + 1.45 (2014-08-16) + fix MSVC-ARM internal compiler error by wrapping malloc + 1.44 (2014-08-07) + various warning fixes from Ronny Chevalier + 1.43 (2014-07-15) + fix MSVC-only compiler problem in code changed in 1.42 + 1.42 (2014-07-09) + don't define _CRT_SECURE_NO_WARNINGS (affects user code) + fixes to stbi__cleanup_jpeg path + added STBI_ASSERT to avoid requiring assert.h + 1.41 (2014-06-25) + fix search&replace from 1.36 that messed up comments/error messages + 1.40 (2014-06-22) + fix gcc struct-initialization warning + 1.39 (2014-06-15) + fix to TGA optimization when req_comp != number of components in TGA; + fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) + add support for BMP version 5 (more ignored fields) + 1.38 (2014-06-06) + suppress MSVC warnings on integer casts truncating values + fix accidental rename of 'skip' field of I/O + 1.37 (2014-06-04) + remove duplicate typedef + 1.36 (2014-06-03) + convert to header file single-file library + if de-iphone isn't set, load iphone images color-swapped instead of returning NULL + 1.35 (2014-05-27) + various warnings + fix broken STBI_SIMD path + fix bug where stbi_load_from_file no longer left file pointer in correct place + fix broken non-easy path for 32-bit BMP (possibly never used) + TGA optimization by Arseny Kapoulkine + 1.34 (unknown) + use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case + 1.33 (2011-07-14) + make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements + 1.32 (2011-07-13) + support for "info" function for all supported filetypes (SpartanJ) + 1.31 (2011-06-20) + a few more leak fixes, bug in PNG handling (SpartanJ) + 1.30 (2011-06-11) + added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) + removed deprecated format-specific test/load functions + removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway + error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) + fix inefficiency in decoding 32-bit BMP (David Woo) + 1.29 (2010-08-16) + various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) + fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) + cast-to-stbi_uc to fix warnings + 1.26 (2010-07-24) + fix bug in file buffering for PNG reported by SpartanJ + 1.25 (2010-07-17) + refix trans_data warning (Won Chun) + 1.24 (2010-07-12) + perf improvements reading from files on platforms with lock-heavy fgetc() + minor perf improvements for jpeg + deprecated type-specific functions so we'll get feedback if they're needed + attempt to fix trans_data warning (Won Chun) + 1.23 fixed bug in iPhone support + 1.22 (2010-07-10) + removed image *writing* support + stbi_info support from Jetro Lauha + GIF support from Jean-Marc Lienher + iPhone PNG-extensions from James Brown + warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) + 1.21 fix use of 'stbi_uc' in header (reported by jon blow) + 1.20 added support for Softimage PIC, by Tom Seddon + 1.19 bug in interlaced PNG corruption check (found by ryg) + 1.18 (2008-08-02) + fix a threading bug (local mutable static) + 1.17 support interlaced PNG + 1.16 major bugfix - stbi__convert_format converted one too many pixels + 1.15 initialize some fields for thread safety + 1.14 fix threadsafe conversion bug + header-file-only version (#define STBI_HEADER_FILE_ONLY before including) + 1.13 threadsafe + 1.12 const qualifiers in the API + 1.11 Support installable IDCT, colorspace conversion routines + 1.10 Fixes for 64-bit (don't use "unsigned long") + optimized upsampling by Fabian "ryg" Giesen + 1.09 Fix format-conversion for PSD code (bad global variables!) + 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz + 1.07 attempt to fix C++ warning/errors again + 1.06 attempt to fix C++ warning/errors again + 1.05 fix TGA loading to return correct *comp and use good luminance calc + 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free + 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR + 1.02 support for (subset of) HDR files, float interface for preferred access to them + 1.01 fix bug: possible bug in handling right-side up bmps... not sure + fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all + 1.00 interface to zlib that skips zlib header + 0.99 correct handling of alpha in palette + 0.98 TGA loader by lonesock; dynamically add loaders (untested) + 0.97 jpeg errors on too large a file; also catch another malloc failure + 0.96 fix detection of invalid v value - particleman@mollyrocket forum + 0.95 during header scan, seek to markers in case of padding + 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same + 0.93 handle jpegtran output; verbose errors + 0.92 read 4,8,16,24,32-bit BMP files of several formats + 0.91 output 24-bit Windows 3.0 BMP files + 0.90 fix a few more warnings; bump version number to approach 1.0 + 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd + 0.60 fix compiling as c++ + 0.59 fix warnings: merge Dave Moore's -Wall fixes + 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian + 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available + 0.56 fix bug: zlib uncompressed mode len vs. nlen + 0.55 fix bug: restart_interval not initialized to 0 + 0.54 allow NULL for 'int *comp' + 0.53 fix bug in png 3->4; speedup png decoding + 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments + 0.51 obey req_comp requests, 1-component jpegs return as 1-component, + on 'test' only check type, not whether we support this variant + 0.50 (2006-11-19) + first released version +*/ diff --git a/CameraParameterEstimation/apps/basics/extern/stb_image_resize.h b/CameraParameterEstimation/apps/basics/extern/stb_image_resize.h new file mode 100644 index 0000000..4cabe54 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/stb_image_resize.h @@ -0,0 +1,2578 @@ +/* stb_image_resize - v0.91 - public domain image resizing + by Jorge L Rodriguez (@VinoBS) - 2014 + http://github.com/nothings/stb + + Written with emphasis on usability, portability, and efficiency. (No + SIMD or threads, so it be easily outperformed by libs that use those.) + Only scaling and translation is supported, no rotations or shears. + Easy API downsamples w/Mitchell filter, upsamples w/cubic interpolation. + + COMPILING & LINKING + In one C/C++ file that #includes this file, do this: + #define STB_IMAGE_RESIZE_IMPLEMENTATION + before the #include. That will create the implementation in that file. + + QUICKSTART + stbir_resize_uint8( input_pixels , in_w , in_h , 0, + output_pixels, out_w, out_h, 0, num_channels) + stbir_resize_float(...) + stbir_resize_uint8_srgb( input_pixels , in_w , in_h , 0, + output_pixels, out_w, out_h, 0, + num_channels , alpha_chan , 0) + stbir_resize_uint8_srgb_edgemode( + input_pixels , in_w , in_h , 0, + output_pixels, out_w, out_h, 0, + num_channels , alpha_chan , 0, STBIR_EDGE_CLAMP) + // WRAP/REFLECT/ZERO + + FULL API + See the "header file" section of the source for API documentation. + + ADDITIONAL DOCUMENTATION + + SRGB & FLOATING POINT REPRESENTATION + The sRGB functions presume IEEE floating point. If you do not have + IEEE floating point, define STBIR_NON_IEEE_FLOAT. This will use + a slower implementation. + + MEMORY ALLOCATION + The resize functions here perform a single memory allocation using + malloc. To control the memory allocation, before the #include that + triggers the implementation, do: + + #define STBIR_MALLOC(size,context) ... + #define STBIR_FREE(ptr,context) ... + + Each resize function makes exactly one call to malloc/free, so to use + temp memory, store the temp memory in the context and return that. + + ASSERT + Define STBIR_ASSERT(boolval) to override assert() and not use assert.h + + OPTIMIZATION + Define STBIR_SATURATE_INT to compute clamp values in-range using + integer operations instead of float operations. This may be faster + on some platforms. + + DEFAULT FILTERS + For functions which don't provide explicit control over what filters + to use, you can change the compile-time defaults with + + #define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_something + #define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_something + + See stbir_filter in the header-file section for the list of filters. + + NEW FILTERS + A number of 1D filter kernels are used. For a list of + supported filters see the stbir_filter enum. To add a new filter, + write a filter function and add it to stbir__filter_info_table. + + PROGRESS + For interactive use with slow resize operations, you can install + a progress-report callback: + + #define STBIR_PROGRESS_REPORT(val) some_func(val) + + The parameter val is a float which goes from 0 to 1 as progress is made. + + For example: + + static void my_progress_report(float progress); + #define STBIR_PROGRESS_REPORT(val) my_progress_report(val) + + #define STB_IMAGE_RESIZE_IMPLEMENTATION + #include "stb_image_resize.h" + + static void my_progress_report(float progress) + { + printf("Progress: %f%%\n", progress*100); + } + + MAX CHANNELS + If your image has more than 64 channels, define STBIR_MAX_CHANNELS + to the max you'll have. + + ALPHA CHANNEL + Most of the resizing functions provide the ability to control how + the alpha channel of an image is processed. The important things + to know about this: + + 1. The best mathematically-behaved version of alpha to use is + called "premultiplied alpha", in which the other color channels + have had the alpha value multiplied in. If you use premultiplied + alpha, linear filtering (such as image resampling done by this + library, or performed in texture units on GPUs) does the "right + thing". While premultiplied alpha is standard in the movie CGI + industry, it is still uncommon in the videogame/real-time world. + + If you linearly filter non-premultiplied alpha, strange effects + occur. (For example, the average of 1% opaque bright green + and 99% opaque black produces 50% transparent dark green when + non-premultiplied, whereas premultiplied it produces 50% + transparent near-black. The former introduces green energy + that doesn't exist in the source image.) + + 2. Artists should not edit premultiplied-alpha images; artists + want non-premultiplied alpha images. Thus, art tools generally output + non-premultiplied alpha images. + + 3. You will get best results in most cases by converting images + to premultiplied alpha before processing them mathematically. + + 4. If you pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED, the + resizer does not do anything special for the alpha channel; + it is resampled identically to other channels. This produces + the correct results for premultiplied-alpha images, but produces + less-than-ideal results for non-premultiplied-alpha images. + + 5. If you do not pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED, + then the resizer weights the contribution of input pixels + based on their alpha values, or, equivalently, it multiplies + the alpha value into the color channels, resamples, then divides + by the resultant alpha value. Input pixels which have alpha=0 do + not contribute at all to output pixels unless _all_ of the input + pixels affecting that output pixel have alpha=0, in which case + the result for that pixel is the same as it would be without + STBIR_FLAG_ALPHA_PREMULTIPLIED. However, this is only true for + input images in integer formats. For input images in float format, + input pixels with alpha=0 have no effect, and output pixels + which have alpha=0 will be 0 in all channels. (For float images, + you can manually achieve the same result by adding a tiny epsilon + value to the alpha channel of every image, and then subtracting + or clamping it at the end.) + + 6. You can suppress the behavior described in #5 and make + all-0-alpha pixels have 0 in all channels by #defining + STBIR_NO_ALPHA_EPSILON. + + 7. You can separately control whether the alpha channel is + interpreted as linear or affected by the colorspace. By default + it is linear; you almost never want to apply the colorspace. + (For example, graphics hardware does not apply sRGB conversion + to the alpha channel.) + + ADDITIONAL CONTRIBUTORS + Sean Barrett: API design, optimizations + + REVISIONS + 0.91 (2016-04-02) fix warnings; fix handling of subpixel regions + 0.90 (2014-09-17) first released version + + LICENSE + + This software is dual-licensed to the public domain and under the following + license: you are granted a perpetual, irrevocable license to copy, modify, + publish, and distribute this file as you see fit. + + TODO + Don't decode all of the image data when only processing a partial tile + Don't use full-width decode buffers when only processing a partial tile + When processing wide images, break processing into tiles so data fits in L1 cache + Installable filters? + Resize that respects alpha test coverage + (Reference code: FloatImage::alphaTestCoverage and FloatImage::scaleAlphaToCoverage: + https://code.google.com/p/nvidia-texture-tools/source/browse/trunk/src/nvimage/FloatImage.cpp ) +*/ + +#ifndef STBIR_INCLUDE_STB_IMAGE_RESIZE_H +#define STBIR_INCLUDE_STB_IMAGE_RESIZE_H + +#ifdef _MSC_VER +typedef unsigned char stbir_uint8; +typedef unsigned short stbir_uint16; +typedef unsigned int stbir_uint32; +#else +#include +typedef uint8_t stbir_uint8; +typedef uint16_t stbir_uint16; +typedef uint32_t stbir_uint32; +#endif + +#ifdef STB_IMAGE_RESIZE_STATIC +#define STBIRDEF static +#else +#ifdef __cplusplus +#define STBIRDEF extern "C" +#else +#define STBIRDEF extern +#endif +#endif + + +////////////////////////////////////////////////////////////////////////////// +// +// Easy-to-use API: +// +// * "input pixels" points to an array of image data with 'num_channels' channels (e.g. RGB=3, RGBA=4) +// * input_w is input image width (x-axis), input_h is input image height (y-axis) +// * stride is the offset between successive rows of image data in memory, in bytes. you can +// specify 0 to mean packed continuously in memory +// * alpha channel is treated identically to other channels. +// * colorspace is linear or sRGB as specified by function name +// * returned result is 1 for success or 0 in case of an error. +// #define STBIR_ASSERT() to trigger an assert on parameter validation errors. +// * Memory required grows approximately linearly with input and output size, but with +// discontinuities at input_w == output_w and input_h == output_h. +// * These functions use a "default" resampling filter defined at compile time. To change the filter, +// you can change the compile-time defaults by #defining STBIR_DEFAULT_FILTER_UPSAMPLE +// and STBIR_DEFAULT_FILTER_DOWNSAMPLE, or you can use the medium-complexity API. + +STBIRDEF int stbir_resize_uint8( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels); + +STBIRDEF int stbir_resize_float( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + float *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels); + + +// The following functions interpret image data as gamma-corrected sRGB. +// Specify STBIR_ALPHA_CHANNEL_NONE if you have no alpha channel, +// or otherwise provide the index of the alpha channel. Flags value +// of 0 will probably do the right thing if you're not sure what +// the flags mean. + +#define STBIR_ALPHA_CHANNEL_NONE -1 + +// Set this flag if your texture has premultiplied alpha. Otherwise, stbir will +// use alpha-weighted resampling (effectively premultiplying, resampling, +// then unpremultiplying). +#define STBIR_FLAG_ALPHA_PREMULTIPLIED (1 << 0) +// The specified alpha channel should be handled as gamma-corrected value even +// when doing sRGB operations. +#define STBIR_FLAG_ALPHA_USES_COLORSPACE (1 << 1) + +STBIRDEF int stbir_resize_uint8_srgb(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags); + + +typedef enum +{ + STBIR_EDGE_CLAMP = 1, + STBIR_EDGE_REFLECT = 2, + STBIR_EDGE_WRAP = 3, + STBIR_EDGE_ZERO = 4, +} stbir_edge; + +// This function adds the ability to specify how requests to sample off the edge of the image are handled. +STBIRDEF int stbir_resize_uint8_srgb_edgemode(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode); + +////////////////////////////////////////////////////////////////////////////// +// +// Medium-complexity API +// +// This extends the easy-to-use API as follows: +// +// * Alpha-channel can be processed separately +// * If alpha_channel is not STBIR_ALPHA_CHANNEL_NONE +// * Alpha channel will not be gamma corrected (unless flags&STBIR_FLAG_GAMMA_CORRECT) +// * Filters will be weighted by alpha channel (unless flags&STBIR_FLAG_ALPHA_PREMULTIPLIED) +// * Filter can be selected explicitly +// * uint16 image type +// * sRGB colorspace available for all types +// * context parameter for passing to STBIR_MALLOC + +typedef enum +{ + STBIR_FILTER_DEFAULT = 0, // use same filter type that easy-to-use API chooses + STBIR_FILTER_BOX = 1, // A trapezoid w/1-pixel wide ramps, same result as box for integer scale ratios + STBIR_FILTER_TRIANGLE = 2, // On upsampling, produces same results as bilinear texture filtering + STBIR_FILTER_CUBICBSPLINE = 3, // The cubic b-spline (aka Mitchell-Netrevalli with B=1,C=0), gaussian-esque + STBIR_FILTER_CATMULLROM = 4, // An interpolating cubic spline + STBIR_FILTER_MITCHELL = 5, // Mitchell-Netrevalli filter with B=1/3, C=1/3 +} stbir_filter; + +typedef enum +{ + STBIR_COLORSPACE_LINEAR, + STBIR_COLORSPACE_SRGB, + + STBIR_MAX_COLORSPACES, +} stbir_colorspace; + +// The following functions are all identical except for the type of the image data + +STBIRDEF int stbir_resize_uint8_generic( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, + void *alloc_context); + +STBIRDEF int stbir_resize_uint16_generic(const stbir_uint16 *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + stbir_uint16 *output_pixels , int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, + void *alloc_context); + +STBIRDEF int stbir_resize_float_generic( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + float *output_pixels , int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, + void *alloc_context); + + + +////////////////////////////////////////////////////////////////////////////// +// +// Full-complexity API +// +// This extends the medium API as follows: +// +// * uint32 image type +// * not typesafe +// * separate filter types for each axis +// * separate edge modes for each axis +// * can specify scale explicitly for subpixel correctness +// * can specify image source tile using texture coordinates + +typedef enum +{ + STBIR_TYPE_UINT8 , + STBIR_TYPE_UINT16, + STBIR_TYPE_UINT32, + STBIR_TYPE_FLOAT , + + STBIR_MAX_TYPES +} stbir_datatype; + +STBIRDEF int stbir_resize( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + stbir_datatype datatype, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, + stbir_filter filter_horizontal, stbir_filter filter_vertical, + stbir_colorspace space, void *alloc_context); + +STBIRDEF int stbir_resize_subpixel(const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + stbir_datatype datatype, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, + stbir_filter filter_horizontal, stbir_filter filter_vertical, + stbir_colorspace space, void *alloc_context, + float x_scale, float y_scale, + float x_offset, float y_offset); + +STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + stbir_datatype datatype, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, + stbir_filter filter_horizontal, stbir_filter filter_vertical, + stbir_colorspace space, void *alloc_context, + float s0, float t0, float s1, float t1); +// (s0, t0) & (s1, t1) are the top-left and bottom right corner (uv addressing style: [0, 1]x[0, 1]) of a region of the input image to use. + +// +// +//// end header file ///////////////////////////////////////////////////// +#endif // STBIR_INCLUDE_STB_IMAGE_RESIZE_H + + + + + +#ifdef STB_IMAGE_RESIZE_IMPLEMENTATION + +#ifndef STBIR_ASSERT +#include +#define STBIR_ASSERT(x) assert(x) +#endif + +// For memset +#include + +#include + +#ifndef STBIR_MALLOC +#include +#define STBIR_MALLOC(size,c) malloc(size) +#define STBIR_FREE(ptr,c) free(ptr) +#endif + +#ifndef _MSC_VER +#ifdef __cplusplus +#define stbir__inline inline +#else +#define stbir__inline +#endif +#else +#define stbir__inline __forceinline +#endif + + +// should produce compiler error if size is wrong +typedef unsigned char stbir__validate_uint32[sizeof(stbir_uint32) == 4 ? 1 : -1]; + +#ifdef _MSC_VER +#define STBIR__NOTUSED(v) (void)(v) +#else +#define STBIR__NOTUSED(v) (void)sizeof(v) +#endif + +#define STBIR__ARRAY_SIZE(a) (sizeof((a))/sizeof((a)[0])) + +#ifndef STBIR_DEFAULT_FILTER_UPSAMPLE +#define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_CATMULLROM +#endif + +#ifndef STBIR_DEFAULT_FILTER_DOWNSAMPLE +#define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_MITCHELL +#endif + +#ifndef STBIR_PROGRESS_REPORT +#define STBIR_PROGRESS_REPORT(float_0_to_1) +#endif + +#ifndef STBIR_MAX_CHANNELS +#define STBIR_MAX_CHANNELS 64 +#endif + +#if STBIR_MAX_CHANNELS > 65536 +#error "Too many channels; STBIR_MAX_CHANNELS must be no more than 65536." +// because we store the indices in 16-bit variables +#endif + +// This value is added to alpha just before premultiplication to avoid +// zeroing out color values. It is equivalent to 2^-80. If you don't want +// that behavior (it may interfere if you have floating point images with +// very small alpha values) then you can define STBIR_NO_ALPHA_EPSILON to +// disable it. +#ifndef STBIR_ALPHA_EPSILON +#define STBIR_ALPHA_EPSILON ((float)1 / (1 << 20) / (1 << 20) / (1 << 20) / (1 << 20)) +#endif + + + +#ifdef _MSC_VER +#define STBIR__UNUSED_PARAM(v) (void)(v) +#else +#define STBIR__UNUSED_PARAM(v) (void)sizeof(v) +#endif + +// must match stbir_datatype +static unsigned char stbir__type_size[] = { + 1, // STBIR_TYPE_UINT8 + 2, // STBIR_TYPE_UINT16 + 4, // STBIR_TYPE_UINT32 + 4, // STBIR_TYPE_FLOAT +}; + +// Kernel function centered at 0 +typedef float (stbir__kernel_fn)(float x, float scale); +typedef float (stbir__support_fn)(float scale); + +typedef struct +{ + stbir__kernel_fn* kernel; + stbir__support_fn* support; +} stbir__filter_info; + +// When upsampling, the contributors are which source pixels contribute. +// When downsampling, the contributors are which destination pixels are contributed to. +typedef struct +{ + int n0; // First contributing pixel + int n1; // Last contributing pixel +} stbir__contributors; + +typedef struct +{ + const void* input_data; + int input_w; + int input_h; + int input_stride_bytes; + + void* output_data; + int output_w; + int output_h; + int output_stride_bytes; + + float s0, t0, s1, t1; + + float horizontal_shift; // Units: output pixels + float vertical_shift; // Units: output pixels + float horizontal_scale; + float vertical_scale; + + int channels; + int alpha_channel; + stbir_uint32 flags; + stbir_datatype type; + stbir_filter horizontal_filter; + stbir_filter vertical_filter; + stbir_edge edge_horizontal; + stbir_edge edge_vertical; + stbir_colorspace colorspace; + + stbir__contributors* horizontal_contributors; + float* horizontal_coefficients; + + stbir__contributors* vertical_contributors; + float* vertical_coefficients; + + int decode_buffer_pixels; + float* decode_buffer; + + float* horizontal_buffer; + + // cache these because ceil/floor are inexplicably showing up in profile + int horizontal_coefficient_width; + int vertical_coefficient_width; + int horizontal_filter_pixel_width; + int vertical_filter_pixel_width; + int horizontal_filter_pixel_margin; + int vertical_filter_pixel_margin; + int horizontal_num_contributors; + int vertical_num_contributors; + + int ring_buffer_length_bytes; // The length of an individual entry in the ring buffer. The total number of ring buffers is stbir__get_filter_pixel_width(filter) + int ring_buffer_first_scanline; + int ring_buffer_last_scanline; + int ring_buffer_begin_index; + float* ring_buffer; + + float* encode_buffer; // A temporary buffer to store floats so we don't lose precision while we do multiply-adds. + + int horizontal_contributors_size; + int horizontal_coefficients_size; + int vertical_contributors_size; + int vertical_coefficients_size; + int decode_buffer_size; + int horizontal_buffer_size; + int ring_buffer_size; + int encode_buffer_size; +} stbir__info; + +static stbir__inline int stbir__min(int a, int b) +{ + return a < b ? a : b; +} + +static stbir__inline int stbir__max(int a, int b) +{ + return a > b ? a : b; +} + +static stbir__inline float stbir__saturate(float x) +{ + if (x < 0) + return 0; + + if (x > 1) + return 1; + + return x; +} + +#ifdef STBIR_SATURATE_INT +static stbir__inline stbir_uint8 stbir__saturate8(int x) +{ + if ((unsigned int) x <= 255) + return x; + + if (x < 0) + return 0; + + return 255; +} + +static stbir__inline stbir_uint16 stbir__saturate16(int x) +{ + if ((unsigned int) x <= 65535) + return x; + + if (x < 0) + return 0; + + return 65535; +} +#endif + +static float stbir__srgb_uchar_to_linear_float[256] = { + 0.000000f, 0.000304f, 0.000607f, 0.000911f, 0.001214f, 0.001518f, 0.001821f, 0.002125f, 0.002428f, 0.002732f, 0.003035f, + 0.003347f, 0.003677f, 0.004025f, 0.004391f, 0.004777f, 0.005182f, 0.005605f, 0.006049f, 0.006512f, 0.006995f, 0.007499f, + 0.008023f, 0.008568f, 0.009134f, 0.009721f, 0.010330f, 0.010960f, 0.011612f, 0.012286f, 0.012983f, 0.013702f, 0.014444f, + 0.015209f, 0.015996f, 0.016807f, 0.017642f, 0.018500f, 0.019382f, 0.020289f, 0.021219f, 0.022174f, 0.023153f, 0.024158f, + 0.025187f, 0.026241f, 0.027321f, 0.028426f, 0.029557f, 0.030713f, 0.031896f, 0.033105f, 0.034340f, 0.035601f, 0.036889f, + 0.038204f, 0.039546f, 0.040915f, 0.042311f, 0.043735f, 0.045186f, 0.046665f, 0.048172f, 0.049707f, 0.051269f, 0.052861f, + 0.054480f, 0.056128f, 0.057805f, 0.059511f, 0.061246f, 0.063010f, 0.064803f, 0.066626f, 0.068478f, 0.070360f, 0.072272f, + 0.074214f, 0.076185f, 0.078187f, 0.080220f, 0.082283f, 0.084376f, 0.086500f, 0.088656f, 0.090842f, 0.093059f, 0.095307f, + 0.097587f, 0.099899f, 0.102242f, 0.104616f, 0.107023f, 0.109462f, 0.111932f, 0.114435f, 0.116971f, 0.119538f, 0.122139f, + 0.124772f, 0.127438f, 0.130136f, 0.132868f, 0.135633f, 0.138432f, 0.141263f, 0.144128f, 0.147027f, 0.149960f, 0.152926f, + 0.155926f, 0.158961f, 0.162029f, 0.165132f, 0.168269f, 0.171441f, 0.174647f, 0.177888f, 0.181164f, 0.184475f, 0.187821f, + 0.191202f, 0.194618f, 0.198069f, 0.201556f, 0.205079f, 0.208637f, 0.212231f, 0.215861f, 0.219526f, 0.223228f, 0.226966f, + 0.230740f, 0.234551f, 0.238398f, 0.242281f, 0.246201f, 0.250158f, 0.254152f, 0.258183f, 0.262251f, 0.266356f, 0.270498f, + 0.274677f, 0.278894f, 0.283149f, 0.287441f, 0.291771f, 0.296138f, 0.300544f, 0.304987f, 0.309469f, 0.313989f, 0.318547f, + 0.323143f, 0.327778f, 0.332452f, 0.337164f, 0.341914f, 0.346704f, 0.351533f, 0.356400f, 0.361307f, 0.366253f, 0.371238f, + 0.376262f, 0.381326f, 0.386430f, 0.391573f, 0.396755f, 0.401978f, 0.407240f, 0.412543f, 0.417885f, 0.423268f, 0.428691f, + 0.434154f, 0.439657f, 0.445201f, 0.450786f, 0.456411f, 0.462077f, 0.467784f, 0.473532f, 0.479320f, 0.485150f, 0.491021f, + 0.496933f, 0.502887f, 0.508881f, 0.514918f, 0.520996f, 0.527115f, 0.533276f, 0.539480f, 0.545725f, 0.552011f, 0.558340f, + 0.564712f, 0.571125f, 0.577581f, 0.584078f, 0.590619f, 0.597202f, 0.603827f, 0.610496f, 0.617207f, 0.623960f, 0.630757f, + 0.637597f, 0.644480f, 0.651406f, 0.658375f, 0.665387f, 0.672443f, 0.679543f, 0.686685f, 0.693872f, 0.701102f, 0.708376f, + 0.715694f, 0.723055f, 0.730461f, 0.737911f, 0.745404f, 0.752942f, 0.760525f, 0.768151f, 0.775822f, 0.783538f, 0.791298f, + 0.799103f, 0.806952f, 0.814847f, 0.822786f, 0.830770f, 0.838799f, 0.846873f, 0.854993f, 0.863157f, 0.871367f, 0.879622f, + 0.887923f, 0.896269f, 0.904661f, 0.913099f, 0.921582f, 0.930111f, 0.938686f, 0.947307f, 0.955974f, 0.964686f, 0.973445f, + 0.982251f, 0.991102f, 1.0f +}; + +static float stbir__srgb_to_linear(float f) +{ + if (f <= 0.04045f) + return f / 12.92f; + else + return (float)pow((f + 0.055f) / 1.055f, 2.4f); +} + +static float stbir__linear_to_srgb(float f) +{ + if (f <= 0.0031308f) + return f * 12.92f; + else + return 1.055f * (float)pow(f, 1 / 2.4f) - 0.055f; +} + +#ifndef STBIR_NON_IEEE_FLOAT +// From https://gist.github.com/rygorous/2203834 + +typedef union +{ + stbir_uint32 u; + float f; +} stbir__FP32; + +static const stbir_uint32 fp32_to_srgb8_tab4[104] = { + 0x0073000d, 0x007a000d, 0x0080000d, 0x0087000d, 0x008d000d, 0x0094000d, 0x009a000d, 0x00a1000d, + 0x00a7001a, 0x00b4001a, 0x00c1001a, 0x00ce001a, 0x00da001a, 0x00e7001a, 0x00f4001a, 0x0101001a, + 0x010e0033, 0x01280033, 0x01410033, 0x015b0033, 0x01750033, 0x018f0033, 0x01a80033, 0x01c20033, + 0x01dc0067, 0x020f0067, 0x02430067, 0x02760067, 0x02aa0067, 0x02dd0067, 0x03110067, 0x03440067, + 0x037800ce, 0x03df00ce, 0x044600ce, 0x04ad00ce, 0x051400ce, 0x057b00c5, 0x05dd00bc, 0x063b00b5, + 0x06970158, 0x07420142, 0x07e30130, 0x087b0120, 0x090b0112, 0x09940106, 0x0a1700fc, 0x0a9500f2, + 0x0b0f01cb, 0x0bf401ae, 0x0ccb0195, 0x0d950180, 0x0e56016e, 0x0f0d015e, 0x0fbc0150, 0x10630143, + 0x11070264, 0x1238023e, 0x1357021d, 0x14660201, 0x156601e9, 0x165a01d3, 0x174401c0, 0x182401af, + 0x18fe0331, 0x1a9602fe, 0x1c1502d2, 0x1d7e02ad, 0x1ed4028d, 0x201a0270, 0x21520256, 0x227d0240, + 0x239f0443, 0x25c003fe, 0x27bf03c4, 0x29a10392, 0x2b6a0367, 0x2d1d0341, 0x2ebe031f, 0x304d0300, + 0x31d105b0, 0x34a80555, 0x37520507, 0x39d504c5, 0x3c37048b, 0x3e7c0458, 0x40a8042a, 0x42bd0401, + 0x44c20798, 0x488e071e, 0x4c1c06b6, 0x4f76065d, 0x52a50610, 0x55ac05cc, 0x5892058f, 0x5b590559, + 0x5e0c0a23, 0x631c0980, 0x67db08f6, 0x6c55087f, 0x70940818, 0x74a007bd, 0x787d076c, 0x7c330723, +}; + +static stbir_uint8 stbir__linear_to_srgb_uchar(float in) +{ + static const stbir__FP32 almostone = { 0x3f7fffff }; // 1-eps + static const stbir__FP32 minval = { (127-13) << 23 }; + stbir_uint32 tab,bias,scale,t; + stbir__FP32 f; + + // Clamp to [2^(-13), 1-eps]; these two values map to 0 and 1, respectively. + // The tests are carefully written so that NaNs map to 0, same as in the reference + // implementation. + if (!(in > minval.f)) // written this way to catch NaNs + in = minval.f; + if (in > almostone.f) + in = almostone.f; + + // Do the table lookup and unpack bias, scale + f.f = in; + tab = fp32_to_srgb8_tab4[(f.u - minval.u) >> 20]; + bias = (tab >> 16) << 9; + scale = tab & 0xffff; + + // Grab next-highest mantissa bits and perform linear interpolation + t = (f.u >> 12) & 0xff; + return (unsigned char) ((bias + scale*t) >> 16); +} + +#else +// sRGB transition values, scaled by 1<<28 +static int stbir__srgb_offset_to_linear_scaled[256] = +{ + 0, 40738, 122216, 203693, 285170, 366648, 448125, 529603, + 611080, 692557, 774035, 855852, 942009, 1033024, 1128971, 1229926, + 1335959, 1447142, 1563542, 1685229, 1812268, 1944725, 2082664, 2226148, + 2375238, 2529996, 2690481, 2856753, 3028870, 3206888, 3390865, 3580856, + 3776916, 3979100, 4187460, 4402049, 4622919, 4850123, 5083710, 5323731, + 5570236, 5823273, 6082892, 6349140, 6622065, 6901714, 7188133, 7481369, + 7781466, 8088471, 8402427, 8723380, 9051372, 9386448, 9728650, 10078021, + 10434603, 10798439, 11169569, 11548036, 11933879, 12327139, 12727857, 13136073, + 13551826, 13975156, 14406100, 14844697, 15290987, 15745007, 16206795, 16676389, + 17153826, 17639142, 18132374, 18633560, 19142734, 19659934, 20185196, 20718552, + 21260042, 21809696, 22367554, 22933648, 23508010, 24090680, 24681686, 25281066, + 25888850, 26505076, 27129772, 27762974, 28404716, 29055026, 29713942, 30381490, + 31057708, 31742624, 32436272, 33138682, 33849884, 34569912, 35298800, 36036568, + 36783260, 37538896, 38303512, 39077136, 39859796, 40651528, 41452360, 42262316, + 43081432, 43909732, 44747252, 45594016, 46450052, 47315392, 48190064, 49074096, + 49967516, 50870356, 51782636, 52704392, 53635648, 54576432, 55526772, 56486700, + 57456236, 58435408, 59424248, 60422780, 61431036, 62449032, 63476804, 64514376, + 65561776, 66619028, 67686160, 68763192, 69850160, 70947088, 72053992, 73170912, + 74297864, 75434880, 76581976, 77739184, 78906536, 80084040, 81271736, 82469648, + 83677792, 84896192, 86124888, 87363888, 88613232, 89872928, 91143016, 92423512, + 93714432, 95015816, 96327688, 97650056, 98982952, 100326408, 101680440, 103045072, + 104420320, 105806224, 107202800, 108610064, 110028048, 111456776, 112896264, 114346544, + 115807632, 117279552, 118762328, 120255976, 121760536, 123276016, 124802440, 126339832, + 127888216, 129447616, 131018048, 132599544, 134192112, 135795792, 137410592, 139036528, + 140673648, 142321952, 143981456, 145652208, 147334208, 149027488, 150732064, 152447968, + 154175200, 155913792, 157663776, 159425168, 161197984, 162982240, 164777968, 166585184, + 168403904, 170234160, 172075968, 173929344, 175794320, 177670896, 179559120, 181458992, + 183370528, 185293776, 187228736, 189175424, 191133888, 193104112, 195086128, 197079968, + 199085648, 201103184, 203132592, 205173888, 207227120, 209292272, 211369392, 213458480, + 215559568, 217672656, 219797792, 221934976, 224084240, 226245600, 228419056, 230604656, + 232802400, 235012320, 237234432, 239468736, 241715280, 243974080, 246245120, 248528464, + 250824112, 253132064, 255452368, 257785040, 260130080, 262487520, 264857376, 267239664, +}; + +static stbir_uint8 stbir__linear_to_srgb_uchar(float f) +{ + int x = (int) (f * (1 << 28)); // has headroom so you don't need to clamp + int v = 0; + int i; + + // Refine the guess with a short binary search. + i = v + 128; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 64; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 32; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 16; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 8; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 4; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 2; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 1; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + + return (stbir_uint8) v; +} +#endif + +static float stbir__filter_trapezoid(float x, float scale) +{ + float halfscale = scale / 2; + float t = 0.5f + halfscale; + STBIR_ASSERT(scale <= 1); + + x = (float)fabs(x); + + if (x >= t) + return 0; + else + { + float r = 0.5f - halfscale; + if (x <= r) + return 1; + else + return (t - x) / scale; + } +} + +static float stbir__support_trapezoid(float scale) +{ + STBIR_ASSERT(scale <= 1); + return 0.5f + scale / 2; +} + +static float stbir__filter_triangle(float x, float s) +{ + STBIR__UNUSED_PARAM(s); + + x = (float)fabs(x); + + if (x <= 1.0f) + return 1 - x; + else + return 0; +} + +static float stbir__filter_cubic(float x, float s) +{ + STBIR__UNUSED_PARAM(s); + + x = (float)fabs(x); + + if (x < 1.0f) + return (4 + x*x*(3*x - 6))/6; + else if (x < 2.0f) + return (8 + x*(-12 + x*(6 - x)))/6; + + return (0.0f); +} + +static float stbir__filter_catmullrom(float x, float s) +{ + STBIR__UNUSED_PARAM(s); + + x = (float)fabs(x); + + if (x < 1.0f) + return 1 - x*x*(2.5f - 1.5f*x); + else if (x < 2.0f) + return 2 - x*(4 + x*(0.5f*x - 2.5f)); + + return (0.0f); +} + +static float stbir__filter_mitchell(float x, float s) +{ + STBIR__UNUSED_PARAM(s); + + x = (float)fabs(x); + + if (x < 1.0f) + return (16 + x*x*(21 * x - 36))/18; + else if (x < 2.0f) + return (32 + x*(-60 + x*(36 - 7*x)))/18; + + return (0.0f); +} + +static float stbir__support_zero(float s) +{ + STBIR__UNUSED_PARAM(s); + return 0; +} + +static float stbir__support_one(float s) +{ + STBIR__UNUSED_PARAM(s); + return 1; +} + +static float stbir__support_two(float s) +{ + STBIR__UNUSED_PARAM(s); + return 2; +} + +static stbir__filter_info stbir__filter_info_table[] = { + { NULL, stbir__support_zero }, + { stbir__filter_trapezoid, stbir__support_trapezoid }, + { stbir__filter_triangle, stbir__support_one }, + { stbir__filter_cubic, stbir__support_two }, + { stbir__filter_catmullrom, stbir__support_two }, + { stbir__filter_mitchell, stbir__support_two }, +}; + +stbir__inline static int stbir__use_upsampling(float ratio) +{ + return ratio > 1; +} + +stbir__inline static int stbir__use_width_upsampling(stbir__info* stbir_info) +{ + return stbir__use_upsampling(stbir_info->horizontal_scale); +} + +stbir__inline static int stbir__use_height_upsampling(stbir__info* stbir_info) +{ + return stbir__use_upsampling(stbir_info->vertical_scale); +} + +// This is the maximum number of input samples that can affect an output sample +// with the given filter +static int stbir__get_filter_pixel_width(stbir_filter filter, float scale) +{ + STBIR_ASSERT(filter != 0); + STBIR_ASSERT(filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); + + if (stbir__use_upsampling(scale)) + return (int)ceil(stbir__filter_info_table[filter].support(1/scale) * 2); + else + return (int)ceil(stbir__filter_info_table[filter].support(scale) * 2 / scale); +} + +// This is how much to expand buffers to account for filters seeking outside +// the image boundaries. +static int stbir__get_filter_pixel_margin(stbir_filter filter, float scale) +{ + return stbir__get_filter_pixel_width(filter, scale) / 2; +} + +static int stbir__get_coefficient_width(stbir_filter filter, float scale) +{ + if (stbir__use_upsampling(scale)) + return (int)ceil(stbir__filter_info_table[filter].support(1 / scale) * 2); + else + return (int)ceil(stbir__filter_info_table[filter].support(scale) * 2); +} + +static int stbir__get_contributors(float scale, stbir_filter filter, int input_size, int output_size) +{ + if (stbir__use_upsampling(scale)) + return output_size; + else + return (input_size + stbir__get_filter_pixel_margin(filter, scale) * 2); +} + +static int stbir__get_total_horizontal_coefficients(stbir__info* info) +{ + return info->horizontal_num_contributors + * stbir__get_coefficient_width (info->horizontal_filter, info->horizontal_scale); +} + +static int stbir__get_total_vertical_coefficients(stbir__info* info) +{ + return info->vertical_num_contributors + * stbir__get_coefficient_width (info->vertical_filter, info->vertical_scale); +} + +static stbir__contributors* stbir__get_contributor(stbir__contributors* contributors, int n) +{ + return &contributors[n]; +} + +// For perf reasons this code is duplicated in stbir__resample_horizontal_upsample/downsample, +// if you change it here change it there too. +static float* stbir__get_coefficient(float* coefficients, stbir_filter filter, float scale, int n, int c) +{ + int width = stbir__get_coefficient_width(filter, scale); + return &coefficients[width*n + c]; +} + +static int stbir__edge_wrap_slow(stbir_edge edge, int n, int max) +{ + switch (edge) + { + case STBIR_EDGE_ZERO: + return 0; // we'll decode the wrong pixel here, and then overwrite with 0s later + + case STBIR_EDGE_CLAMP: + if (n < 0) + return 0; + + if (n >= max) + return max - 1; + + return n; // NOTREACHED + + case STBIR_EDGE_REFLECT: + { + if (n < 0) + { + if (n < max) + return -n; + else + return max - 1; + } + + if (n >= max) + { + int max2 = max * 2; + if (n >= max2) + return 0; + else + return max2 - n - 1; + } + + return n; // NOTREACHED + } + + case STBIR_EDGE_WRAP: + if (n >= 0) + return (n % max); + else + { + int m = (-n) % max; + + if (m != 0) + m = max - m; + + return (m); + } + return n; // NOTREACHED + + default: + STBIR_ASSERT(!"Unimplemented edge type"); + return 0; + } +} + +stbir__inline static int stbir__edge_wrap(stbir_edge edge, int n, int max) +{ + // avoid per-pixel switch + if (n >= 0 && n < max) + return n; + return stbir__edge_wrap_slow(edge, n, max); +} + +// What input pixels contribute to this output pixel? +static void stbir__calculate_sample_range_upsample(int n, float out_filter_radius, float scale_ratio, float out_shift, int* in_first_pixel, int* in_last_pixel, float* in_center_of_out) +{ + float out_pixel_center = (float)n + 0.5f; + float out_pixel_influence_lowerbound = out_pixel_center - out_filter_radius; + float out_pixel_influence_upperbound = out_pixel_center + out_filter_radius; + + float in_pixel_influence_lowerbound = (out_pixel_influence_lowerbound + out_shift) / scale_ratio; + float in_pixel_influence_upperbound = (out_pixel_influence_upperbound + out_shift) / scale_ratio; + + *in_center_of_out = (out_pixel_center + out_shift) / scale_ratio; + *in_first_pixel = (int)(floor(in_pixel_influence_lowerbound + 0.5)); + *in_last_pixel = (int)(floor(in_pixel_influence_upperbound - 0.5)); +} + +// What output pixels does this input pixel contribute to? +static void stbir__calculate_sample_range_downsample(int n, float in_pixels_radius, float scale_ratio, float out_shift, int* out_first_pixel, int* out_last_pixel, float* out_center_of_in) +{ + float in_pixel_center = (float)n + 0.5f; + float in_pixel_influence_lowerbound = in_pixel_center - in_pixels_radius; + float in_pixel_influence_upperbound = in_pixel_center + in_pixels_radius; + + float out_pixel_influence_lowerbound = in_pixel_influence_lowerbound * scale_ratio - out_shift; + float out_pixel_influence_upperbound = in_pixel_influence_upperbound * scale_ratio - out_shift; + + *out_center_of_in = in_pixel_center * scale_ratio - out_shift; + *out_first_pixel = (int)(floor(out_pixel_influence_lowerbound + 0.5)); + *out_last_pixel = (int)(floor(out_pixel_influence_upperbound - 0.5)); +} + +static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbir_filter filter, float scale, int in_first_pixel, int in_last_pixel, float in_center_of_out, stbir__contributors* contributor, float* coefficient_group) +{ + int i; + float total_filter = 0; + float filter_scale; + + STBIR_ASSERT(in_last_pixel - in_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(1/scale) * 2)); // Taken directly from stbir__get_coefficient_width() which we can't call because we don't know if we're horizontal or vertical. + + contributor->n0 = in_first_pixel; + contributor->n1 = in_last_pixel; + + STBIR_ASSERT(contributor->n1 >= contributor->n0); + + for (i = 0; i <= in_last_pixel - in_first_pixel; i++) + { + float in_pixel_center = (float)(i + in_first_pixel) + 0.5f; + coefficient_group[i] = stbir__filter_info_table[filter].kernel(in_center_of_out - in_pixel_center, 1 / scale); + + // If the coefficient is zero, skip it. (Don't do the <0 check here, we want the influence of those outside pixels.) + if (i == 0 && !coefficient_group[i]) + { + contributor->n0 = ++in_first_pixel; + i--; + continue; + } + + total_filter += coefficient_group[i]; + } + + STBIR_ASSERT(stbir__filter_info_table[filter].kernel((float)(in_last_pixel + 1) + 0.5f - in_center_of_out, 1/scale) == 0); + + STBIR_ASSERT(total_filter > 0.9); + STBIR_ASSERT(total_filter < 1.1f); // Make sure it's not way off. + + // Make sure the sum of all coefficients is 1. + filter_scale = 1 / total_filter; + + for (i = 0; i <= in_last_pixel - in_first_pixel; i++) + coefficient_group[i] *= filter_scale; + + for (i = in_last_pixel - in_first_pixel; i >= 0; i--) + { + if (coefficient_group[i]) + break; + + // This line has no weight. We can skip it. + contributor->n1 = contributor->n0 + i - 1; + } +} + +static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, stbir_filter filter, float scale_ratio, int out_first_pixel, int out_last_pixel, float out_center_of_in, stbir__contributors* contributor, float* coefficient_group) +{ + int i; + + STBIR_ASSERT(out_last_pixel - out_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(scale_ratio) * 2)); // Taken directly from stbir__get_coefficient_width() which we can't call because we don't know if we're horizontal or vertical. + + contributor->n0 = out_first_pixel; + contributor->n1 = out_last_pixel; + + STBIR_ASSERT(contributor->n1 >= contributor->n0); + + for (i = 0; i <= out_last_pixel - out_first_pixel; i++) + { + float out_pixel_center = (float)(i + out_first_pixel) + 0.5f; + float x = out_pixel_center - out_center_of_in; + coefficient_group[i] = stbir__filter_info_table[filter].kernel(x, scale_ratio) * scale_ratio; + } + + STBIR_ASSERT(stbir__filter_info_table[filter].kernel((float)(out_last_pixel + 1) + 0.5f - out_center_of_in, scale_ratio) == 0); + + for (i = out_last_pixel - out_first_pixel; i >= 0; i--) + { + if (coefficient_group[i]) + break; + + // This line has no weight. We can skip it. + contributor->n1 = contributor->n0 + i - 1; + } +} + +static void stbir__normalize_downsample_coefficients(stbir__info* stbir_info, stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size) +{ + int num_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size); + int num_coefficients = stbir__get_coefficient_width(filter, scale_ratio); + int i, j; + int skip; + + for (i = 0; i < output_size; i++) + { + float scale; + float total = 0; + + for (j = 0; j < num_contributors; j++) + { + if (i >= contributors[j].n0 && i <= contributors[j].n1) + { + float coefficient = *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i - contributors[j].n0); + total += coefficient; + } + else if (i < contributors[j].n0) + break; + } + + STBIR_ASSERT(total > 0.9f); + STBIR_ASSERT(total < 1.1f); + + scale = 1 / total; + + for (j = 0; j < num_contributors; j++) + { + if (i >= contributors[j].n0 && i <= contributors[j].n1) + *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i - contributors[j].n0) *= scale; + else if (i < contributors[j].n0) + break; + } + } + + // Optimize: Skip zero coefficients and contributions outside of image bounds. + // Do this after normalizing because normalization depends on the n0/n1 values. + for (j = 0; j < num_contributors; j++) + { + int range, max, width; + + skip = 0; + while (*stbir__get_coefficient(coefficients, filter, scale_ratio, j, skip) == 0) + skip++; + + contributors[j].n0 += skip; + + while (contributors[j].n0 < 0) + { + contributors[j].n0++; + skip++; + } + + range = contributors[j].n1 - contributors[j].n0 + 1; + max = stbir__min(num_coefficients, range); + + width = stbir__get_coefficient_width(filter, scale_ratio); + for (i = 0; i < max; i++) + { + if (i + skip >= width) + break; + + *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i) = *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i + skip); + } + + continue; + } + + // Using min to avoid writing into invalid pixels. + for (i = 0; i < num_contributors; i++) + contributors[i].n1 = stbir__min(contributors[i].n1, output_size - 1); +} + +// Each scan line uses the same kernel values so we should calculate the kernel +// values once and then we can use them for every scan line. +static void stbir__calculate_filters(stbir__info* stbir_info, stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size) +{ + int n; + int total_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size); + + if (stbir__use_upsampling(scale_ratio)) + { + float out_pixels_radius = stbir__filter_info_table[filter].support(1 / scale_ratio) * scale_ratio; + + // Looping through out pixels + for (n = 0; n < total_contributors; n++) + { + float in_center_of_out; // Center of the current out pixel in the in pixel space + int in_first_pixel, in_last_pixel; + + stbir__calculate_sample_range_upsample(n, out_pixels_radius, scale_ratio, shift, &in_first_pixel, &in_last_pixel, &in_center_of_out); + + stbir__calculate_coefficients_upsample(stbir_info, filter, scale_ratio, in_first_pixel, in_last_pixel, in_center_of_out, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0)); + } + } + else + { + float in_pixels_radius = stbir__filter_info_table[filter].support(scale_ratio) / scale_ratio; + + // Looping through in pixels + for (n = 0; n < total_contributors; n++) + { + float out_center_of_in; // Center of the current out pixel in the in pixel space + int out_first_pixel, out_last_pixel; + int n_adjusted = n - stbir__get_filter_pixel_margin(filter, scale_ratio); + + stbir__calculate_sample_range_downsample(n_adjusted, in_pixels_radius, scale_ratio, shift, &out_first_pixel, &out_last_pixel, &out_center_of_in); + + stbir__calculate_coefficients_downsample(stbir_info, filter, scale_ratio, out_first_pixel, out_last_pixel, out_center_of_in, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0)); + } + + stbir__normalize_downsample_coefficients(stbir_info, contributors, coefficients, filter, scale_ratio, shift, input_size, output_size); + } +} + +static float* stbir__get_decode_buffer(stbir__info* stbir_info) +{ + // The 0 index of the decode buffer starts after the margin. This makes + // it okay to use negative indexes on the decode buffer. + return &stbir_info->decode_buffer[stbir_info->horizontal_filter_pixel_margin * stbir_info->channels]; +} + +#define STBIR__DECODE(type, colorspace) ((type) * (STBIR_MAX_COLORSPACES) + (colorspace)) + +static void stbir__decode_scanline(stbir__info* stbir_info, int n) +{ + int c; + int channels = stbir_info->channels; + int alpha_channel = stbir_info->alpha_channel; + int type = stbir_info->type; + int colorspace = stbir_info->colorspace; + int input_w = stbir_info->input_w; + int input_stride_bytes = stbir_info->input_stride_bytes; + float* decode_buffer = stbir__get_decode_buffer(stbir_info); + stbir_edge edge_horizontal = stbir_info->edge_horizontal; + stbir_edge edge_vertical = stbir_info->edge_vertical; + int in_buffer_row_offset = stbir__edge_wrap(edge_vertical, n, stbir_info->input_h) * input_stride_bytes; + const void* input_data = (char *) stbir_info->input_data + in_buffer_row_offset; + int max_x = input_w + stbir_info->horizontal_filter_pixel_margin; + int decode = STBIR__DECODE(type, colorspace); + + int x = -stbir_info->horizontal_filter_pixel_margin; + + // special handling for STBIR_EDGE_ZERO because it needs to return an item that doesn't appear in the input, + // and we want to avoid paying overhead on every pixel if not STBIR_EDGE_ZERO + if (edge_vertical == STBIR_EDGE_ZERO && (n < 0 || n >= stbir_info->input_h)) + { + for (; x < max_x; x++) + for (c = 0; c < channels; c++) + decode_buffer[x*channels + c] = 0; + return; + } + + switch (decode) + { + case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_LINEAR): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = ((float)((const unsigned char*)input_data)[input_pixel_index + c]) / 255; + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_SRGB): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = stbir__srgb_uchar_to_linear_float[((const unsigned char*)input_data)[input_pixel_index + c]]; + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned char*)input_data)[input_pixel_index + alpha_channel]) / 255; + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_LINEAR): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = ((float)((const unsigned short*)input_data)[input_pixel_index + c]) / 65535; + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_SRGB): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((float)((const unsigned short*)input_data)[input_pixel_index + c]) / 65535); + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned short*)input_data)[input_pixel_index + alpha_channel]) / 65535; + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_LINEAR): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / 4294967295); + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_SRGB): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear((float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / 4294967295)); + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + decode_buffer[decode_pixel_index + alpha_channel] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + alpha_channel]) / 4294967295); + } + break; + + case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_LINEAR): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = ((const float*)input_data)[input_pixel_index + c]; + } + break; + + case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_SRGB): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((const float*)input_data)[input_pixel_index + c]); + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + decode_buffer[decode_pixel_index + alpha_channel] = ((const float*)input_data)[input_pixel_index + alpha_channel]; + } + + break; + + default: + STBIR_ASSERT(!"Unknown type/colorspace/channels combination."); + break; + } + + if (!(stbir_info->flags & STBIR_FLAG_ALPHA_PREMULTIPLIED)) + { + for (x = -stbir_info->horizontal_filter_pixel_margin; x < max_x; x++) + { + int decode_pixel_index = x * channels; + + // If the alpha value is 0 it will clobber the color values. Make sure it's not. + float alpha = decode_buffer[decode_pixel_index + alpha_channel]; +#ifndef STBIR_NO_ALPHA_EPSILON + if (stbir_info->type != STBIR_TYPE_FLOAT) { + alpha += STBIR_ALPHA_EPSILON; + decode_buffer[decode_pixel_index + alpha_channel] = alpha; + } +#endif + for (c = 0; c < channels; c++) + { + if (c == alpha_channel) + continue; + + decode_buffer[decode_pixel_index + c] *= alpha; + } + } + } + + if (edge_horizontal == STBIR_EDGE_ZERO) + { + for (x = -stbir_info->horizontal_filter_pixel_margin; x < 0; x++) + { + for (c = 0; c < channels; c++) + decode_buffer[x*channels + c] = 0; + } + for (x = input_w; x < max_x; x++) + { + for (c = 0; c < channels; c++) + decode_buffer[x*channels + c] = 0; + } + } +} + +static float* stbir__get_ring_buffer_entry(float* ring_buffer, int index, int ring_buffer_length) +{ + return &ring_buffer[index * ring_buffer_length]; +} + +static float* stbir__add_empty_ring_buffer_entry(stbir__info* stbir_info, int n) +{ + int ring_buffer_index; + float* ring_buffer; + + if (stbir_info->ring_buffer_begin_index < 0) + { + ring_buffer_index = stbir_info->ring_buffer_begin_index = 0; + stbir_info->ring_buffer_first_scanline = n; + } + else + { + ring_buffer_index = (stbir_info->ring_buffer_begin_index + (stbir_info->ring_buffer_last_scanline - stbir_info->ring_buffer_first_scanline) + 1) % stbir_info->vertical_filter_pixel_width; + STBIR_ASSERT(ring_buffer_index != stbir_info->ring_buffer_begin_index); + } + + ring_buffer = stbir__get_ring_buffer_entry(stbir_info->ring_buffer, ring_buffer_index, stbir_info->ring_buffer_length_bytes / sizeof(float)); + memset(ring_buffer, 0, stbir_info->ring_buffer_length_bytes); + + stbir_info->ring_buffer_last_scanline = n; + + return ring_buffer; +} + + +static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n, float* output_buffer) +{ + int x, k; + int output_w = stbir_info->output_w; + int kernel_pixel_width = stbir_info->horizontal_filter_pixel_width; + int channels = stbir_info->channels; + float* decode_buffer = stbir__get_decode_buffer(stbir_info); + stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors; + float* horizontal_coefficients = stbir_info->horizontal_coefficients; + int coefficient_width = stbir_info->horizontal_coefficient_width; + + for (x = 0; x < output_w; x++) + { + int n0 = horizontal_contributors[x].n0; + int n1 = horizontal_contributors[x].n1; + + int out_pixel_index = x * channels; + int coefficient_group = coefficient_width * x; + int coefficient_counter = 0; + + STBIR_ASSERT(n1 >= n0); + STBIR_ASSERT(n0 >= -stbir_info->horizontal_filter_pixel_margin); + STBIR_ASSERT(n1 >= -stbir_info->horizontal_filter_pixel_margin); + STBIR_ASSERT(n0 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin); + STBIR_ASSERT(n1 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin); + + switch (channels) { + case 1: + for (k = n0; k <= n1; k++) + { + int in_pixel_index = k * 1; + float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; + STBIR_ASSERT(coefficient != 0); + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + } + break; + case 2: + for (k = n0; k <= n1; k++) + { + int in_pixel_index = k * 2; + float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; + STBIR_ASSERT(coefficient != 0); + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; + } + break; + case 3: + for (k = n0; k <= n1; k++) + { + int in_pixel_index = k * 3; + float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; + STBIR_ASSERT(coefficient != 0); + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; + output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient; + } + break; + case 4: + for (k = n0; k <= n1; k++) + { + int in_pixel_index = k * 4; + float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; + STBIR_ASSERT(coefficient != 0); + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; + output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient; + output_buffer[out_pixel_index + 3] += decode_buffer[in_pixel_index + 3] * coefficient; + } + break; + default: + for (k = n0; k <= n1; k++) + { + int in_pixel_index = k * channels; + float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; + int c; + STBIR_ASSERT(coefficient != 0); + for (c = 0; c < channels; c++) + output_buffer[out_pixel_index + c] += decode_buffer[in_pixel_index + c] * coefficient; + } + break; + } + } +} + +static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, int n, float* output_buffer) +{ + int x, k; + int input_w = stbir_info->input_w; + int output_w = stbir_info->output_w; + int kernel_pixel_width = stbir_info->horizontal_filter_pixel_width; + int channels = stbir_info->channels; + float* decode_buffer = stbir__get_decode_buffer(stbir_info); + stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors; + float* horizontal_coefficients = stbir_info->horizontal_coefficients; + int coefficient_width = stbir_info->horizontal_coefficient_width; + int filter_pixel_margin = stbir_info->horizontal_filter_pixel_margin; + int max_x = input_w + filter_pixel_margin * 2; + + STBIR_ASSERT(!stbir__use_width_upsampling(stbir_info)); + + switch (channels) { + case 1: + for (x = 0; x < max_x; x++) + { + int n0 = horizontal_contributors[x].n0; + int n1 = horizontal_contributors[x].n1; + + int in_x = x - filter_pixel_margin; + int in_pixel_index = in_x * 1; + int max_n = n1; + int coefficient_group = coefficient_width * x; + + for (k = n0; k <= max_n; k++) + { + int out_pixel_index = k * 1; + float coefficient = horizontal_coefficients[coefficient_group + k - n0]; + STBIR_ASSERT(coefficient != 0); + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + } + } + break; + + case 2: + for (x = 0; x < max_x; x++) + { + int n0 = horizontal_contributors[x].n0; + int n1 = horizontal_contributors[x].n1; + + int in_x = x - filter_pixel_margin; + int in_pixel_index = in_x * 2; + int max_n = n1; + int coefficient_group = coefficient_width * x; + + for (k = n0; k <= max_n; k++) + { + int out_pixel_index = k * 2; + float coefficient = horizontal_coefficients[coefficient_group + k - n0]; + STBIR_ASSERT(coefficient != 0); + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; + } + } + break; + + case 3: + for (x = 0; x < max_x; x++) + { + int n0 = horizontal_contributors[x].n0; + int n1 = horizontal_contributors[x].n1; + + int in_x = x - filter_pixel_margin; + int in_pixel_index = in_x * 3; + int max_n = n1; + int coefficient_group = coefficient_width * x; + + for (k = n0; k <= max_n; k++) + { + int out_pixel_index = k * 3; + float coefficient = horizontal_coefficients[coefficient_group + k - n0]; + STBIR_ASSERT(coefficient != 0); + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; + output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient; + } + } + break; + + case 4: + for (x = 0; x < max_x; x++) + { + int n0 = horizontal_contributors[x].n0; + int n1 = horizontal_contributors[x].n1; + + int in_x = x - filter_pixel_margin; + int in_pixel_index = in_x * 4; + int max_n = n1; + int coefficient_group = coefficient_width * x; + + for (k = n0; k <= max_n; k++) + { + int out_pixel_index = k * 4; + float coefficient = horizontal_coefficients[coefficient_group + k - n0]; + STBIR_ASSERT(coefficient != 0); + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; + output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient; + output_buffer[out_pixel_index + 3] += decode_buffer[in_pixel_index + 3] * coefficient; + } + } + break; + + default: + for (x = 0; x < max_x; x++) + { + int n0 = horizontal_contributors[x].n0; + int n1 = horizontal_contributors[x].n1; + + int in_x = x - filter_pixel_margin; + int in_pixel_index = in_x * channels; + int max_n = n1; + int coefficient_group = coefficient_width * x; + + for (k = n0; k <= max_n; k++) + { + int c; + int out_pixel_index = k * channels; + float coefficient = horizontal_coefficients[coefficient_group + k - n0]; + STBIR_ASSERT(coefficient != 0); + for (c = 0; c < channels; c++) + output_buffer[out_pixel_index + c] += decode_buffer[in_pixel_index + c] * coefficient; + } + } + break; + } +} + +static void stbir__decode_and_resample_upsample(stbir__info* stbir_info, int n) +{ + // Decode the nth scanline from the source image into the decode buffer. + stbir__decode_scanline(stbir_info, n); + + // Now resample it into the ring buffer. + if (stbir__use_width_upsampling(stbir_info)) + stbir__resample_horizontal_upsample(stbir_info, n, stbir__add_empty_ring_buffer_entry(stbir_info, n)); + else + stbir__resample_horizontal_downsample(stbir_info, n, stbir__add_empty_ring_buffer_entry(stbir_info, n)); + + // Now it's sitting in the ring buffer ready to be used as source for the vertical sampling. +} + +static void stbir__decode_and_resample_downsample(stbir__info* stbir_info, int n) +{ + // Decode the nth scanline from the source image into the decode buffer. + stbir__decode_scanline(stbir_info, n); + + memset(stbir_info->horizontal_buffer, 0, stbir_info->output_w * stbir_info->channels * sizeof(float)); + + // Now resample it into the horizontal buffer. + if (stbir__use_width_upsampling(stbir_info)) + stbir__resample_horizontal_upsample(stbir_info, n, stbir_info->horizontal_buffer); + else + stbir__resample_horizontal_downsample(stbir_info, n, stbir_info->horizontal_buffer); + + // Now it's sitting in the horizontal buffer ready to be distributed into the ring buffers. +} + +// Get the specified scan line from the ring buffer. +static float* stbir__get_ring_buffer_scanline(int get_scanline, float* ring_buffer, int begin_index, int first_scanline, int ring_buffer_size, int ring_buffer_length) +{ + int ring_buffer_index = (begin_index + (get_scanline - first_scanline)) % ring_buffer_size; + return stbir__get_ring_buffer_entry(ring_buffer, ring_buffer_index, ring_buffer_length); +} + + +static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void *output_buffer, float *encode_buffer, int channels, int alpha_channel, int decode) +{ + int x; + int n; + int num_nonalpha; + stbir_uint16 nonalpha[STBIR_MAX_CHANNELS]; + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_PREMULTIPLIED)) + { + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + float alpha = encode_buffer[pixel_index + alpha_channel]; + float reciprocal_alpha = alpha ? 1.0f / alpha : 0; + + // unrolling this produced a 1% slowdown upscaling a large RGBA linear-space image on my machine - stb + for (n = 0; n < channels; n++) + if (n != alpha_channel) + encode_buffer[pixel_index + n] *= reciprocal_alpha; + + // We added in a small epsilon to prevent the color channel from being deleted with zero alpha. + // Because we only add it for integer types, it will automatically be discarded on integer + // conversion, so we don't need to subtract it back out (which would be problematic for + // numeric precision reasons). + } + } + + // build a table of all channels that need colorspace correction, so + // we don't perform colorspace correction on channels that don't need it. + for (x=0, num_nonalpha=0; x < channels; ++x) + if (x != alpha_channel || (stbir_info->flags & STBIR_FLAG_ALPHA_USES_COLORSPACE)) + nonalpha[num_nonalpha++] = x; + + #define STBIR__ROUND_INT(f) ((int) ((f)+0.5)) + #define STBIR__ROUND_UINT(f) ((stbir_uint32) ((f)+0.5)) + + #ifdef STBIR__SATURATE_INT + #define STBIR__ENCODE_LINEAR8(f) stbir__saturate8 (STBIR__ROUND_INT((f) * 255 )) + #define STBIR__ENCODE_LINEAR16(f) stbir__saturate16(STBIR__ROUND_INT((f) * 65535)) + #else + #define STBIR__ENCODE_LINEAR8(f) (unsigned char ) STBIR__ROUND_INT(stbir__saturate(f) * 255 ) + #define STBIR__ENCODE_LINEAR16(f) (unsigned short) STBIR__ROUND_INT(stbir__saturate(f) * 65535) + #endif + + switch (decode) + { + case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_LINEAR): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < channels; n++) + { + int index = pixel_index + n; + ((unsigned char*)output_buffer)[index] = STBIR__ENCODE_LINEAR8(encode_buffer[index]); + } + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_SRGB): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < num_nonalpha; n++) + { + int index = pixel_index + nonalpha[n]; + ((unsigned char*)output_buffer)[index] = stbir__linear_to_srgb_uchar(encode_buffer[index]); + } + + if (!(stbir_info->flags & STBIR_FLAG_ALPHA_USES_COLORSPACE)) + ((unsigned char *)output_buffer)[pixel_index + alpha_channel] = STBIR__ENCODE_LINEAR8(encode_buffer[pixel_index+alpha_channel]); + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_LINEAR): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < channels; n++) + { + int index = pixel_index + n; + ((unsigned short*)output_buffer)[index] = STBIR__ENCODE_LINEAR16(encode_buffer[index]); + } + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_SRGB): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < num_nonalpha; n++) + { + int index = pixel_index + nonalpha[n]; + ((unsigned short*)output_buffer)[index] = (unsigned short)STBIR__ROUND_INT(stbir__linear_to_srgb(stbir__saturate(encode_buffer[index])) * 65535); + } + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + ((unsigned short*)output_buffer)[pixel_index + alpha_channel] = STBIR__ENCODE_LINEAR16(encode_buffer[pixel_index + alpha_channel]); + } + + break; + + case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_LINEAR): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < channels; n++) + { + int index = pixel_index + n; + ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__saturate(encode_buffer[index])) * 4294967295); + } + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_SRGB): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < num_nonalpha; n++) + { + int index = pixel_index + nonalpha[n]; + ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__linear_to_srgb(stbir__saturate(encode_buffer[index]))) * 4294967295); + } + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + ((unsigned int*)output_buffer)[pixel_index + alpha_channel] = (unsigned int)STBIR__ROUND_INT(((double)stbir__saturate(encode_buffer[pixel_index + alpha_channel])) * 4294967295); + } + break; + + case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_LINEAR): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < channels; n++) + { + int index = pixel_index + n; + ((float*)output_buffer)[index] = encode_buffer[index]; + } + } + break; + + case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_SRGB): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < num_nonalpha; n++) + { + int index = pixel_index + nonalpha[n]; + ((float*)output_buffer)[index] = stbir__linear_to_srgb(encode_buffer[index]); + } + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + ((float*)output_buffer)[pixel_index + alpha_channel] = encode_buffer[pixel_index + alpha_channel]; + } + break; + + default: + STBIR_ASSERT(!"Unknown type/colorspace/channels combination."); + break; + } +} + +static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, int in_first_scanline, int in_last_scanline, float in_center_of_out) +{ + int x, k; + int output_w = stbir_info->output_w; + stbir__contributors* vertical_contributors = stbir_info->vertical_contributors; + float* vertical_coefficients = stbir_info->vertical_coefficients; + int channels = stbir_info->channels; + int alpha_channel = stbir_info->alpha_channel; + int type = stbir_info->type; + int colorspace = stbir_info->colorspace; + int kernel_pixel_width = stbir_info->vertical_filter_pixel_width; + void* output_data = stbir_info->output_data; + float* encode_buffer = stbir_info->encode_buffer; + int decode = STBIR__DECODE(type, colorspace); + int coefficient_width = stbir_info->vertical_coefficient_width; + int coefficient_counter; + int contributor = n; + + float* ring_buffer = stbir_info->ring_buffer; + int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index; + int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline; + int ring_buffer_last_scanline = stbir_info->ring_buffer_last_scanline; + int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float); + + int n0,n1, output_row_start; + int coefficient_group = coefficient_width * contributor; + + n0 = vertical_contributors[contributor].n0; + n1 = vertical_contributors[contributor].n1; + + output_row_start = n * stbir_info->output_stride_bytes; + + STBIR_ASSERT(stbir__use_height_upsampling(stbir_info)); + + memset(encode_buffer, 0, output_w * sizeof(float) * channels); + + // I tried reblocking this for better cache usage of encode_buffer + // (using x_outer, k, x_inner), but it lost speed. -- stb + + coefficient_counter = 0; + switch (channels) { + case 1: + for (k = n0; k <= n1; k++) + { + int coefficient_index = coefficient_counter++; + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length); + float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; + for (x = 0; x < output_w; ++x) + { + int in_pixel_index = x * 1; + encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient; + } + } + break; + case 2: + for (k = n0; k <= n1; k++) + { + int coefficient_index = coefficient_counter++; + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length); + float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; + for (x = 0; x < output_w; ++x) + { + int in_pixel_index = x * 2; + encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient; + encode_buffer[in_pixel_index + 1] += ring_buffer_entry[in_pixel_index + 1] * coefficient; + } + } + break; + case 3: + for (k = n0; k <= n1; k++) + { + int coefficient_index = coefficient_counter++; + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length); + float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; + for (x = 0; x < output_w; ++x) + { + int in_pixel_index = x * 3; + encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient; + encode_buffer[in_pixel_index + 1] += ring_buffer_entry[in_pixel_index + 1] * coefficient; + encode_buffer[in_pixel_index + 2] += ring_buffer_entry[in_pixel_index + 2] * coefficient; + } + } + break; + case 4: + for (k = n0; k <= n1; k++) + { + int coefficient_index = coefficient_counter++; + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length); + float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; + for (x = 0; x < output_w; ++x) + { + int in_pixel_index = x * 4; + encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient; + encode_buffer[in_pixel_index + 1] += ring_buffer_entry[in_pixel_index + 1] * coefficient; + encode_buffer[in_pixel_index + 2] += ring_buffer_entry[in_pixel_index + 2] * coefficient; + encode_buffer[in_pixel_index + 3] += ring_buffer_entry[in_pixel_index + 3] * coefficient; + } + } + break; + default: + for (k = n0; k <= n1; k++) + { + int coefficient_index = coefficient_counter++; + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length); + float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; + for (x = 0; x < output_w; ++x) + { + int in_pixel_index = x * channels; + int c; + for (c = 0; c < channels; c++) + encode_buffer[in_pixel_index + c] += ring_buffer_entry[in_pixel_index + c] * coefficient; + } + } + break; + } + stbir__encode_scanline(stbir_info, output_w, (char *) output_data + output_row_start, encode_buffer, channels, alpha_channel, decode); +} + +static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n, int in_first_scanline, int in_last_scanline, float in_center_of_out) +{ + int x, k; + int output_w = stbir_info->output_w; + int output_h = stbir_info->output_h; + stbir__contributors* vertical_contributors = stbir_info->vertical_contributors; + float* vertical_coefficients = stbir_info->vertical_coefficients; + int channels = stbir_info->channels; + int kernel_pixel_width = stbir_info->vertical_filter_pixel_width; + void* output_data = stbir_info->output_data; + float* horizontal_buffer = stbir_info->horizontal_buffer; + int coefficient_width = stbir_info->vertical_coefficient_width; + int contributor = n + stbir_info->vertical_filter_pixel_margin; + + float* ring_buffer = stbir_info->ring_buffer; + int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index; + int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline; + int ring_buffer_last_scanline = stbir_info->ring_buffer_last_scanline; + int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float); + int n0,n1; + + n0 = vertical_contributors[contributor].n0; + n1 = vertical_contributors[contributor].n1; + + STBIR_ASSERT(!stbir__use_height_upsampling(stbir_info)); + + for (k = n0; k <= n1; k++) + { + int coefficient_index = k - n0; + int coefficient_group = coefficient_width * contributor; + float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; + + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length); + + switch (channels) { + case 1: + for (x = 0; x < output_w; x++) + { + int in_pixel_index = x * 1; + ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient; + } + break; + case 2: + for (x = 0; x < output_w; x++) + { + int in_pixel_index = x * 2; + ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient; + ring_buffer_entry[in_pixel_index + 1] += horizontal_buffer[in_pixel_index + 1] * coefficient; + } + break; + case 3: + for (x = 0; x < output_w; x++) + { + int in_pixel_index = x * 3; + ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient; + ring_buffer_entry[in_pixel_index + 1] += horizontal_buffer[in_pixel_index + 1] * coefficient; + ring_buffer_entry[in_pixel_index + 2] += horizontal_buffer[in_pixel_index + 2] * coefficient; + } + break; + case 4: + for (x = 0; x < output_w; x++) + { + int in_pixel_index = x * 4; + ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient; + ring_buffer_entry[in_pixel_index + 1] += horizontal_buffer[in_pixel_index + 1] * coefficient; + ring_buffer_entry[in_pixel_index + 2] += horizontal_buffer[in_pixel_index + 2] * coefficient; + ring_buffer_entry[in_pixel_index + 3] += horizontal_buffer[in_pixel_index + 3] * coefficient; + } + break; + default: + for (x = 0; x < output_w; x++) + { + int in_pixel_index = x * channels; + + int c; + for (c = 0; c < channels; c++) + ring_buffer_entry[in_pixel_index + c] += horizontal_buffer[in_pixel_index + c] * coefficient; + } + break; + } + } +} + +static void stbir__buffer_loop_upsample(stbir__info* stbir_info) +{ + int y; + float scale_ratio = stbir_info->vertical_scale; + float out_scanlines_radius = stbir__filter_info_table[stbir_info->vertical_filter].support(1/scale_ratio) * scale_ratio; + + STBIR_ASSERT(stbir__use_height_upsampling(stbir_info)); + + for (y = 0; y < stbir_info->output_h; y++) + { + float in_center_of_out = 0; // Center of the current out scanline in the in scanline space + int in_first_scanline = 0, in_last_scanline = 0; + + stbir__calculate_sample_range_upsample(y, out_scanlines_radius, scale_ratio, stbir_info->vertical_shift, &in_first_scanline, &in_last_scanline, &in_center_of_out); + + STBIR_ASSERT(in_last_scanline - in_first_scanline <= stbir_info->vertical_filter_pixel_width); + + if (stbir_info->ring_buffer_begin_index >= 0) + { + // Get rid of whatever we don't need anymore. + while (in_first_scanline > stbir_info->ring_buffer_first_scanline) + { + if (stbir_info->ring_buffer_first_scanline == stbir_info->ring_buffer_last_scanline) + { + // We just popped the last scanline off the ring buffer. + // Reset it to the empty state. + stbir_info->ring_buffer_begin_index = -1; + stbir_info->ring_buffer_first_scanline = 0; + stbir_info->ring_buffer_last_scanline = 0; + break; + } + else + { + stbir_info->ring_buffer_first_scanline++; + stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->vertical_filter_pixel_width; + } + } + } + + // Load in new ones. + if (stbir_info->ring_buffer_begin_index < 0) + stbir__decode_and_resample_upsample(stbir_info, in_first_scanline); + + while (in_last_scanline > stbir_info->ring_buffer_last_scanline) + stbir__decode_and_resample_upsample(stbir_info, stbir_info->ring_buffer_last_scanline + 1); + + // Now all buffers should be ready to write a row of vertical sampling. + stbir__resample_vertical_upsample(stbir_info, y, in_first_scanline, in_last_scanline, in_center_of_out); + + STBIR_PROGRESS_REPORT((float)y / stbir_info->output_h); + } +} + +static void stbir__empty_ring_buffer(stbir__info* stbir_info, int first_necessary_scanline) +{ + int output_stride_bytes = stbir_info->output_stride_bytes; + int channels = stbir_info->channels; + int alpha_channel = stbir_info->alpha_channel; + int type = stbir_info->type; + int colorspace = stbir_info->colorspace; + int output_w = stbir_info->output_w; + void* output_data = stbir_info->output_data; + int decode = STBIR__DECODE(type, colorspace); + + float* ring_buffer = stbir_info->ring_buffer; + int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float); + + if (stbir_info->ring_buffer_begin_index >= 0) + { + // Get rid of whatever we don't need anymore. + while (first_necessary_scanline > stbir_info->ring_buffer_first_scanline) + { + if (stbir_info->ring_buffer_first_scanline >= 0 && stbir_info->ring_buffer_first_scanline < stbir_info->output_h) + { + int output_row_start = stbir_info->ring_buffer_first_scanline * output_stride_bytes; + float* ring_buffer_entry = stbir__get_ring_buffer_entry(ring_buffer, stbir_info->ring_buffer_begin_index, ring_buffer_length); + stbir__encode_scanline(stbir_info, output_w, (char *) output_data + output_row_start, ring_buffer_entry, channels, alpha_channel, decode); + STBIR_PROGRESS_REPORT((float)stbir_info->ring_buffer_first_scanline / stbir_info->output_h); + } + + if (stbir_info->ring_buffer_first_scanline == stbir_info->ring_buffer_last_scanline) + { + // We just popped the last scanline off the ring buffer. + // Reset it to the empty state. + stbir_info->ring_buffer_begin_index = -1; + stbir_info->ring_buffer_first_scanline = 0; + stbir_info->ring_buffer_last_scanline = 0; + break; + } + else + { + stbir_info->ring_buffer_first_scanline++; + stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->vertical_filter_pixel_width; + } + } + } +} + +static void stbir__buffer_loop_downsample(stbir__info* stbir_info) +{ + int y; + float scale_ratio = stbir_info->vertical_scale; + int output_h = stbir_info->output_h; + float in_pixels_radius = stbir__filter_info_table[stbir_info->vertical_filter].support(scale_ratio) / scale_ratio; + int pixel_margin = stbir_info->vertical_filter_pixel_margin; + int max_y = stbir_info->input_h + pixel_margin; + + STBIR_ASSERT(!stbir__use_height_upsampling(stbir_info)); + + for (y = -pixel_margin; y < max_y; y++) + { + float out_center_of_in; // Center of the current out scanline in the in scanline space + int out_first_scanline, out_last_scanline; + + stbir__calculate_sample_range_downsample(y, in_pixels_radius, scale_ratio, stbir_info->vertical_shift, &out_first_scanline, &out_last_scanline, &out_center_of_in); + + STBIR_ASSERT(out_last_scanline - out_first_scanline <= stbir_info->vertical_filter_pixel_width); + + if (out_last_scanline < 0 || out_first_scanline >= output_h) + continue; + + stbir__empty_ring_buffer(stbir_info, out_first_scanline); + + stbir__decode_and_resample_downsample(stbir_info, y); + + // Load in new ones. + if (stbir_info->ring_buffer_begin_index < 0) + stbir__add_empty_ring_buffer_entry(stbir_info, out_first_scanline); + + while (out_last_scanline > stbir_info->ring_buffer_last_scanline) + stbir__add_empty_ring_buffer_entry(stbir_info, stbir_info->ring_buffer_last_scanline + 1); + + // Now the horizontal buffer is ready to write to all ring buffer rows. + stbir__resample_vertical_downsample(stbir_info, y, out_first_scanline, out_last_scanline, out_center_of_in); + } + + stbir__empty_ring_buffer(stbir_info, stbir_info->output_h); +} + +static void stbir__setup(stbir__info *info, int input_w, int input_h, int output_w, int output_h, int channels) +{ + info->input_w = input_w; + info->input_h = input_h; + info->output_w = output_w; + info->output_h = output_h; + info->channels = channels; +} + +static void stbir__calculate_transform(stbir__info *info, float s0, float t0, float s1, float t1, float *transform) +{ + info->s0 = s0; + info->t0 = t0; + info->s1 = s1; + info->t1 = t1; + + if (transform) + { + info->horizontal_scale = transform[0]; + info->vertical_scale = transform[1]; + info->horizontal_shift = transform[2]; + info->vertical_shift = transform[3]; + } + else + { + info->horizontal_scale = ((float)info->output_w / info->input_w) / (s1 - s0); + info->vertical_scale = ((float)info->output_h / info->input_h) / (t1 - t0); + + info->horizontal_shift = s0 * info->output_w / (s1 - s0); + info->vertical_shift = t0 * info->output_h / (t1 - t0); + } +} + +static void stbir__choose_filter(stbir__info *info, stbir_filter h_filter, stbir_filter v_filter) +{ + if (h_filter == 0) + h_filter = stbir__use_upsampling(info->horizontal_scale) ? STBIR_DEFAULT_FILTER_UPSAMPLE : STBIR_DEFAULT_FILTER_DOWNSAMPLE; + if (v_filter == 0) + v_filter = stbir__use_upsampling(info->vertical_scale) ? STBIR_DEFAULT_FILTER_UPSAMPLE : STBIR_DEFAULT_FILTER_DOWNSAMPLE; + info->horizontal_filter = h_filter; + info->vertical_filter = v_filter; +} + +static stbir_uint32 stbir__calculate_memory(stbir__info *info) +{ + int pixel_margin = stbir__get_filter_pixel_margin(info->horizontal_filter, info->horizontal_scale); + int filter_height = stbir__get_filter_pixel_width(info->vertical_filter, info->vertical_scale); + + info->horizontal_num_contributors = stbir__get_contributors(info->horizontal_scale, info->horizontal_filter, info->input_w, info->output_w); + info->vertical_num_contributors = stbir__get_contributors(info->vertical_scale , info->vertical_filter , info->input_h, info->output_h); + + info->horizontal_contributors_size = info->horizontal_num_contributors * sizeof(stbir__contributors); + info->horizontal_coefficients_size = stbir__get_total_horizontal_coefficients(info) * sizeof(float); + info->vertical_contributors_size = info->vertical_num_contributors * sizeof(stbir__contributors); + info->vertical_coefficients_size = stbir__get_total_vertical_coefficients(info) * sizeof(float); + info->decode_buffer_size = (info->input_w + pixel_margin * 2) * info->channels * sizeof(float); + info->horizontal_buffer_size = info->output_w * info->channels * sizeof(float); + info->ring_buffer_size = info->output_w * info->channels * filter_height * sizeof(float); + info->encode_buffer_size = info->output_w * info->channels * sizeof(float); + + STBIR_ASSERT(info->horizontal_filter != 0); + STBIR_ASSERT(info->horizontal_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); // this now happens too late + STBIR_ASSERT(info->vertical_filter != 0); + STBIR_ASSERT(info->vertical_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); // this now happens too late + + if (stbir__use_height_upsampling(info)) + // The horizontal buffer is for when we're downsampling the height and we + // can't output the result of sampling the decode buffer directly into the + // ring buffers. + info->horizontal_buffer_size = 0; + else + // The encode buffer is to retain precision in the height upsampling method + // and isn't used when height downsampling. + info->encode_buffer_size = 0; + + return info->horizontal_contributors_size + info->horizontal_coefficients_size + + info->vertical_contributors_size + info->vertical_coefficients_size + + info->decode_buffer_size + info->horizontal_buffer_size + + info->ring_buffer_size + info->encode_buffer_size; +} + +static int stbir__resize_allocated(stbir__info *info, + const void* input_data, int input_stride_in_bytes, + void* output_data, int output_stride_in_bytes, + int alpha_channel, stbir_uint32 flags, stbir_datatype type, + stbir_edge edge_horizontal, stbir_edge edge_vertical, stbir_colorspace colorspace, + void* tempmem, size_t tempmem_size_in_bytes) +{ + size_t memory_required = stbir__calculate_memory(info); + + int width_stride_input = input_stride_in_bytes ? input_stride_in_bytes : info->channels * info->input_w * stbir__type_size[type]; + int width_stride_output = output_stride_in_bytes ? output_stride_in_bytes : info->channels * info->output_w * stbir__type_size[type]; + +#ifdef STBIR_DEBUG_OVERWRITE_TEST +#define OVERWRITE_ARRAY_SIZE 8 + unsigned char overwrite_output_before_pre[OVERWRITE_ARRAY_SIZE]; + unsigned char overwrite_tempmem_before_pre[OVERWRITE_ARRAY_SIZE]; + unsigned char overwrite_output_after_pre[OVERWRITE_ARRAY_SIZE]; + unsigned char overwrite_tempmem_after_pre[OVERWRITE_ARRAY_SIZE]; + + size_t begin_forbidden = width_stride_output * (info->output_h - 1) + info->output_w * info->channels * stbir__type_size[type]; + memcpy(overwrite_output_before_pre, &((unsigned char*)output_data)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE); + memcpy(overwrite_output_after_pre, &((unsigned char*)output_data)[begin_forbidden], OVERWRITE_ARRAY_SIZE); + memcpy(overwrite_tempmem_before_pre, &((unsigned char*)tempmem)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE); + memcpy(overwrite_tempmem_after_pre, &((unsigned char*)tempmem)[tempmem_size_in_bytes], OVERWRITE_ARRAY_SIZE); +#endif + + STBIR_ASSERT(info->channels >= 0); + STBIR_ASSERT(info->channels <= STBIR_MAX_CHANNELS); + + if (info->channels < 0 || info->channels > STBIR_MAX_CHANNELS) + return 0; + + STBIR_ASSERT(info->horizontal_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); + STBIR_ASSERT(info->vertical_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); + + if (info->horizontal_filter >= STBIR__ARRAY_SIZE(stbir__filter_info_table)) + return 0; + if (info->vertical_filter >= STBIR__ARRAY_SIZE(stbir__filter_info_table)) + return 0; + + if (alpha_channel < 0) + flags |= STBIR_FLAG_ALPHA_USES_COLORSPACE | STBIR_FLAG_ALPHA_PREMULTIPLIED; + + if (!(flags&STBIR_FLAG_ALPHA_USES_COLORSPACE) || !(flags&STBIR_FLAG_ALPHA_PREMULTIPLIED)) + STBIR_ASSERT(alpha_channel >= 0 && alpha_channel < info->channels); + + if (alpha_channel >= info->channels) + return 0; + + STBIR_ASSERT(tempmem); + + if (!tempmem) + return 0; + + STBIR_ASSERT(tempmem_size_in_bytes >= memory_required); + + if (tempmem_size_in_bytes < memory_required) + return 0; + + memset(tempmem, 0, tempmem_size_in_bytes); + + info->input_data = input_data; + info->input_stride_bytes = width_stride_input; + + info->output_data = output_data; + info->output_stride_bytes = width_stride_output; + + info->alpha_channel = alpha_channel; + info->flags = flags; + info->type = type; + info->edge_horizontal = edge_horizontal; + info->edge_vertical = edge_vertical; + info->colorspace = colorspace; + + info->horizontal_coefficient_width = stbir__get_coefficient_width (info->horizontal_filter, info->horizontal_scale); + info->vertical_coefficient_width = stbir__get_coefficient_width (info->vertical_filter , info->vertical_scale ); + info->horizontal_filter_pixel_width = stbir__get_filter_pixel_width (info->horizontal_filter, info->horizontal_scale); + info->vertical_filter_pixel_width = stbir__get_filter_pixel_width (info->vertical_filter , info->vertical_scale ); + info->horizontal_filter_pixel_margin = stbir__get_filter_pixel_margin(info->horizontal_filter, info->horizontal_scale); + info->vertical_filter_pixel_margin = stbir__get_filter_pixel_margin(info->vertical_filter , info->vertical_scale ); + + info->ring_buffer_length_bytes = info->output_w * info->channels * sizeof(float); + info->decode_buffer_pixels = info->input_w + info->horizontal_filter_pixel_margin * 2; + +#define STBIR__NEXT_MEMPTR(current, newtype) (newtype*)(((unsigned char*)current) + current##_size) + + info->horizontal_contributors = (stbir__contributors *) tempmem; + info->horizontal_coefficients = STBIR__NEXT_MEMPTR(info->horizontal_contributors, float); + info->vertical_contributors = STBIR__NEXT_MEMPTR(info->horizontal_coefficients, stbir__contributors); + info->vertical_coefficients = STBIR__NEXT_MEMPTR(info->vertical_contributors, float); + info->decode_buffer = STBIR__NEXT_MEMPTR(info->vertical_coefficients, float); + + if (stbir__use_height_upsampling(info)) + { + info->horizontal_buffer = NULL; + info->ring_buffer = STBIR__NEXT_MEMPTR(info->decode_buffer, float); + info->encode_buffer = STBIR__NEXT_MEMPTR(info->ring_buffer, float); + + STBIR_ASSERT((size_t)STBIR__NEXT_MEMPTR(info->encode_buffer, unsigned char) == (size_t)tempmem + tempmem_size_in_bytes); + } + else + { + info->horizontal_buffer = STBIR__NEXT_MEMPTR(info->decode_buffer, float); + info->ring_buffer = STBIR__NEXT_MEMPTR(info->horizontal_buffer, float); + info->encode_buffer = NULL; + + STBIR_ASSERT((size_t)STBIR__NEXT_MEMPTR(info->ring_buffer, unsigned char) == (size_t)tempmem + tempmem_size_in_bytes); + } + +#undef STBIR__NEXT_MEMPTR + + // This signals that the ring buffer is empty + info->ring_buffer_begin_index = -1; + + stbir__calculate_filters(info, info->horizontal_contributors, info->horizontal_coefficients, info->horizontal_filter, info->horizontal_scale, info->horizontal_shift, info->input_w, info->output_w); + stbir__calculate_filters(info, info->vertical_contributors, info->vertical_coefficients, info->vertical_filter, info->vertical_scale, info->vertical_shift, info->input_h, info->output_h); + + STBIR_PROGRESS_REPORT(0); + + if (stbir__use_height_upsampling(info)) + stbir__buffer_loop_upsample(info); + else + stbir__buffer_loop_downsample(info); + + STBIR_PROGRESS_REPORT(1); + +#ifdef STBIR_DEBUG_OVERWRITE_TEST + STBIR_ASSERT(memcmp(overwrite_output_before_pre, &((unsigned char*)output_data)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE) == 0); + STBIR_ASSERT(memcmp(overwrite_output_after_pre, &((unsigned char*)output_data)[begin_forbidden], OVERWRITE_ARRAY_SIZE) == 0); + STBIR_ASSERT(memcmp(overwrite_tempmem_before_pre, &((unsigned char*)tempmem)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE) == 0); + STBIR_ASSERT(memcmp(overwrite_tempmem_after_pre, &((unsigned char*)tempmem)[tempmem_size_in_bytes], OVERWRITE_ARRAY_SIZE) == 0); +#endif + + return 1; +} + + +static int stbir__resize_arbitrary( + void *alloc_context, + const void* input_data, int input_w, int input_h, int input_stride_in_bytes, + void* output_data, int output_w, int output_h, int output_stride_in_bytes, + float s0, float t0, float s1, float t1, float *transform, + int channels, int alpha_channel, stbir_uint32 flags, stbir_datatype type, + stbir_filter h_filter, stbir_filter v_filter, + stbir_edge edge_horizontal, stbir_edge edge_vertical, stbir_colorspace colorspace) +{ + stbir__info info; + int result; + size_t memory_required; + void* extra_memory; + + stbir__setup(&info, input_w, input_h, output_w, output_h, channels); + stbir__calculate_transform(&info, s0,t0,s1,t1,transform); + stbir__choose_filter(&info, h_filter, v_filter); + memory_required = stbir__calculate_memory(&info); + extra_memory = STBIR_MALLOC(memory_required, alloc_context); + + if (!extra_memory) + return 0; + + result = stbir__resize_allocated(&info, input_data, input_stride_in_bytes, + output_data, output_stride_in_bytes, + alpha_channel, flags, type, + edge_horizontal, edge_vertical, + colorspace, extra_memory, memory_required); + + STBIR_FREE(extra_memory, alloc_context); + + return result; +} + +STBIRDEF int stbir_resize_uint8( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels) +{ + return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,-1,0, STBIR_TYPE_UINT8, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT, + STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_COLORSPACE_LINEAR); +} + +STBIRDEF int stbir_resize_float( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + float *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels) +{ + return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,-1,0, STBIR_TYPE_FLOAT, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT, + STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_COLORSPACE_LINEAR); +} + +STBIRDEF int stbir_resize_uint8_srgb(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags) +{ + return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT8, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT, + STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_COLORSPACE_SRGB); +} + +STBIRDEF int stbir_resize_uint8_srgb_edgemode(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode) +{ + return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT8, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT, + edge_wrap_mode, edge_wrap_mode, STBIR_COLORSPACE_SRGB); +} + +STBIRDEF int stbir_resize_uint8_generic( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, + void *alloc_context) +{ + return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT8, filter, filter, + edge_wrap_mode, edge_wrap_mode, space); +} + +STBIRDEF int stbir_resize_uint16_generic(const stbir_uint16 *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + stbir_uint16 *output_pixels , int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, + void *alloc_context) +{ + return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT16, filter, filter, + edge_wrap_mode, edge_wrap_mode, space); +} + + +STBIRDEF int stbir_resize_float_generic( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + float *output_pixels , int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, + void *alloc_context) +{ + return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_FLOAT, filter, filter, + edge_wrap_mode, edge_wrap_mode, space); +} + + +STBIRDEF int stbir_resize( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + stbir_datatype datatype, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, + stbir_filter filter_horizontal, stbir_filter filter_vertical, + stbir_colorspace space, void *alloc_context) +{ + return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,alpha_channel,flags, datatype, filter_horizontal, filter_vertical, + edge_mode_horizontal, edge_mode_vertical, space); +} + + +STBIRDEF int stbir_resize_subpixel(const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + stbir_datatype datatype, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, + stbir_filter filter_horizontal, stbir_filter filter_vertical, + stbir_colorspace space, void *alloc_context, + float x_scale, float y_scale, + float x_offset, float y_offset) +{ + float transform[4]; + transform[0] = x_scale; + transform[1] = y_scale; + transform[2] = x_offset; + transform[3] = y_offset; + return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,transform,num_channels,alpha_channel,flags, datatype, filter_horizontal, filter_vertical, + edge_mode_horizontal, edge_mode_vertical, space); +} + +STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + stbir_datatype datatype, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, + stbir_filter filter_horizontal, stbir_filter filter_vertical, + stbir_colorspace space, void *alloc_context, + float s0, float t0, float s1, float t1) +{ + return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + s0,t0,s1,t1,NULL,num_channels,alpha_channel,flags, datatype, filter_horizontal, filter_vertical, + edge_mode_horizontal, edge_mode_vertical, space); +} + +#endif // STB_IMAGE_RESIZE_IMPLEMENTATION diff --git a/CameraParameterEstimation/apps/basics/extern/stb_image_write.h b/CameraParameterEstimation/apps/basics/extern/stb_image_write.h new file mode 100644 index 0000000..cf5c98f --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/stb_image_write.h @@ -0,0 +1,1048 @@ +/* stb_image_write - v1.02 - public domain - http://nothings.org/stb/stb_image_write.h + writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010-2015 + no warranty implied; use at your own risk + + Before #including, + + #define STB_IMAGE_WRITE_IMPLEMENTATION + + in the file that you want to have the implementation. + + Will probably not work correctly with strict-aliasing optimizations. + +ABOUT: + + This header file is a library for writing images to C stdio. It could be + adapted to write to memory or a general streaming interface; let me know. + + The PNG output is not optimal; it is 20-50% larger than the file + written by a decent optimizing implementation. This library is designed + for source code compactness and simplicity, not optimal image file size + or run-time performance. + +BUILDING: + + You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h. + You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace + malloc,realloc,free. + You can define STBIW_MEMMOVE() to replace memmove() + +USAGE: + + There are four functions, one for each image file format: + + int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); + int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); + + There are also four equivalent functions that use an arbitrary write function. You are + expected to open/close your file-equivalent before and after calling these: + + int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); + int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); + int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); + int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); + + where the callback is: + void stbi_write_func(void *context, void *data, int size); + + You can define STBI_WRITE_NO_STDIO to disable the file variant of these + functions, so the library will not use stdio.h at all. However, this will + also disable HDR writing, because it requires stdio for formatted output. + + Each function returns 0 on failure and non-0 on success. + + The functions create an image file defined by the parameters. The image + is a rectangle of pixels stored from left-to-right, top-to-bottom. + Each pixel contains 'comp' channels of data stored interleaved with 8-bits + per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is + monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall. + The *data pointer points to the first byte of the top-left-most pixel. + For PNG, "stride_in_bytes" is the distance in bytes from the first byte of + a row of pixels to the first byte of the next row of pixels. + + PNG creates output files with the same number of components as the input. + The BMP format expands Y to RGB in the file format and does not + output alpha. + + PNG supports writing rectangles of data even when the bytes storing rows of + data are not consecutive in memory (e.g. sub-rectangles of a larger image), + by supplying the stride between the beginning of adjacent rows. The other + formats do not. (Thus you cannot write a native-format BMP through the BMP + writer, both because it is in BGR order and because it may have padding + at the end of the line.) + + HDR expects linear float data. Since the format is always 32-bit rgb(e) + data, alpha (if provided) is discarded, and for monochrome data it is + replicated across all three channels. + + TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed + data, set the global variable 'stbi_write_tga_with_rle' to 0. + +CREDITS: + + PNG/BMP/TGA + Sean Barrett + HDR + Baldur Karlsson + TGA monochrome: + Jean-Sebastien Guay + misc enhancements: + Tim Kelsey + TGA RLE + Alan Hickman + initial file IO callback implementation + Emmanuel Julien + bugfixes: + github:Chribba + Guillaume Chereau + github:jry2 + github:romigrou + Sergio Gonzalez + Jonas Karlsson + Filip Wasil + Thatcher Ulrich + +LICENSE + +This software is dual-licensed to the public domain and under the following +license: you are granted a perpetual, irrevocable license to copy, modify, +publish, and distribute this file as you see fit. + +*/ + +#ifndef INCLUDE_STB_IMAGE_WRITE_H +#define INCLUDE_STB_IMAGE_WRITE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef STB_IMAGE_WRITE_STATIC +#define STBIWDEF static +#else +#define STBIWDEF extern +extern int stbi_write_tga_with_rle; +#endif + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); +STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); +#endif + +typedef void stbi_write_func(void *context, void *data, int size); + +STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); +STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); + +#ifdef __cplusplus +} +#endif + +#endif//INCLUDE_STB_IMAGE_WRITE_H + +#ifdef STB_IMAGE_WRITE_IMPLEMENTATION + +#ifdef _WIN32 + #ifndef _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS + #endif + #ifndef _CRT_NONSTDC_NO_DEPRECATE + #define _CRT_NONSTDC_NO_DEPRECATE + #endif +#endif + +#ifndef STBI_WRITE_NO_STDIO +#include +#endif // STBI_WRITE_NO_STDIO + +#include +#include +#include +#include + +#if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED)) +// ok +#elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)." +#endif + +#ifndef STBIW_MALLOC +#define STBIW_MALLOC(sz) malloc(sz) +#define STBIW_REALLOC(p,newsz) realloc(p,newsz) +#define STBIW_FREE(p) free(p) +#endif + +#ifndef STBIW_REALLOC_SIZED +#define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz) +#endif + + +#ifndef STBIW_MEMMOVE +#define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz) +#endif + + +#ifndef STBIW_ASSERT +#include +#define STBIW_ASSERT(x) assert(x) +#endif + +#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff) + +typedef struct +{ + stbi_write_func *func; + void *context; +} stbi__write_context; + +// initialize a callback-based context +static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context) +{ + s->func = c; + s->context = context; +} + +#ifndef STBI_WRITE_NO_STDIO + +static void stbi__stdio_write(void *context, void *data, int size) +{ + fwrite(data,1,size,(FILE*) context); +} + +static int stbi__start_write_file(stbi__write_context *s, const char *filename) +{ + FILE *f = fopen(filename, "wb"); + stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f); + return f != NULL; +} + +static void stbi__end_write_file(stbi__write_context *s) +{ + fclose((FILE *)s->context); +} + +#endif // !STBI_WRITE_NO_STDIO + +typedef unsigned int stbiw_uint32; +typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1]; + +#ifdef STB_IMAGE_WRITE_STATIC +static int stbi_write_tga_with_rle = 1; +#else +int stbi_write_tga_with_rle = 1; +#endif + +static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v) +{ + while (*fmt) { + switch (*fmt++) { + case ' ': break; + case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int)); + s->func(s->context,&x,1); + break; } + case '2': { int x = va_arg(v,int); + unsigned char b[2]; + b[0] = STBIW_UCHAR(x); + b[1] = STBIW_UCHAR(x>>8); + s->func(s->context,b,2); + break; } + case '4': { stbiw_uint32 x = va_arg(v,int); + unsigned char b[4]; + b[0]=STBIW_UCHAR(x); + b[1]=STBIW_UCHAR(x>>8); + b[2]=STBIW_UCHAR(x>>16); + b[3]=STBIW_UCHAR(x>>24); + s->func(s->context,b,4); + break; } + default: + STBIW_ASSERT(0); + return; + } + } +} + +static void stbiw__writef(stbi__write_context *s, const char *fmt, ...) +{ + va_list v; + va_start(v, fmt); + stbiw__writefv(s, fmt, v); + va_end(v); +} + +static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c) +{ + unsigned char arr[3]; + arr[0] = a, arr[1] = b, arr[2] = c; + s->func(s->context, arr, 3); +} + +static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d) +{ + unsigned char bg[3] = { 255, 0, 255}, px[3]; + int k; + + if (write_alpha < 0) + s->func(s->context, &d[comp - 1], 1); + + switch (comp) { + case 1: + s->func(s->context,d,1); + break; + case 2: + if (expand_mono) + stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp + else + s->func(s->context, d, 1); // monochrome TGA + break; + case 4: + if (!write_alpha) { + // composite against pink background + for (k = 0; k < 3; ++k) + px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255; + stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]); + break; + } + /* FALLTHROUGH */ + case 3: + stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]); + break; + } + if (write_alpha > 0) + s->func(s->context, &d[comp - 1], 1); +} + +static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono) +{ + stbiw_uint32 zero = 0; + int i,j, j_end; + + if (y <= 0) + return; + + if (vdir < 0) + j_end = -1, j = y-1; + else + j_end = y, j = 0; + + for (; j != j_end; j += vdir) { + for (i=0; i < x; ++i) { + unsigned char *d = (unsigned char *) data + (j*x+i)*comp; + stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d); + } + s->func(s->context, &zero, scanline_pad); + } +} + +static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...) +{ + if (y < 0 || x < 0) { + return 0; + } else { + va_list v; + va_start(v, fmt); + stbiw__writefv(s, fmt, v); + va_end(v); + stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono); + return 1; + } +} + +static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data) +{ + int pad = (-x*3) & 3; + return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad, + "11 4 22 4" "4 44 22 444444", + 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header + 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header +} + +STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) +{ + stbi__write_context s; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_bmp_core(&s, x, y, comp, data); +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) +{ + stbi__write_context s; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_bmp_core(&s, x, y, comp, data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif //!STBI_WRITE_NO_STDIO + +static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data) +{ + int has_alpha = (comp == 2 || comp == 4); + int colorbytes = has_alpha ? comp-1 : comp; + int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3 + + if (y < 0 || x < 0) + return 0; + + if (!stbi_write_tga_with_rle) { + return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0, + "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8); + } else { + int i,j,k; + + stbiw__writef(s, "111 221 2222 11", 0,0,format+8, 0,0,0, 0,0,x,y, (colorbytes + has_alpha) * 8, has_alpha * 8); + + for (j = y - 1; j >= 0; --j) { + unsigned char *row = (unsigned char *) data + j * x * comp; + int len; + + for (i = 0; i < x; i += len) { + unsigned char *begin = row + i * comp; + int diff = 1; + len = 1; + + if (i < x - 1) { + ++len; + diff = memcmp(begin, row + (i + 1) * comp, comp); + if (diff) { + const unsigned char *prev = begin; + for (k = i + 2; k < x && len < 128; ++k) { + if (memcmp(prev, row + k * comp, comp)) { + prev += comp; + ++len; + } else { + --len; + break; + } + } + } else { + for (k = i + 2; k < x && len < 128; ++k) { + if (!memcmp(begin, row + k * comp, comp)) { + ++len; + } else { + break; + } + } + } + } + + if (diff) { + unsigned char header = STBIW_UCHAR(len - 1); + s->func(s->context, &header, 1); + for (k = 0; k < len; ++k) { + stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp); + } + } else { + unsigned char header = STBIW_UCHAR(len - 129); + s->func(s->context, &header, 1); + stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin); + } + } + } + } + return 1; +} + +int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) +{ + stbi__write_context s; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_tga_core(&s, x, y, comp, (void *) data); +} + +#ifndef STBI_WRITE_NO_STDIO +int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) +{ + stbi__write_context s; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_tga_core(&s, x, y, comp, (void *) data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR writer +// by Baldur Karlsson +#ifndef STBI_WRITE_NO_STDIO + +#define stbiw__max(a, b) ((a) > (b) ? (a) : (b)) + +void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) +{ + int exponent; + float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2])); + + if (maxcomp < 1e-32f) { + rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0; + } else { + float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp; + + rgbe[0] = (unsigned char)(linear[0] * normalize); + rgbe[1] = (unsigned char)(linear[1] * normalize); + rgbe[2] = (unsigned char)(linear[2] * normalize); + rgbe[3] = (unsigned char)(exponent + 128); + } +} + +void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte) +{ + unsigned char lengthbyte = STBIW_UCHAR(length+128); + STBIW_ASSERT(length+128 <= 255); + s->func(s->context, &lengthbyte, 1); + s->func(s->context, &databyte, 1); +} + +void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data) +{ + unsigned char lengthbyte = STBIW_UCHAR(length); + STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code + s->func(s->context, &lengthbyte, 1); + s->func(s->context, data, length); +} + +void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline) +{ + unsigned char scanlineheader[4] = { 2, 2, 0, 0 }; + unsigned char rgbe[4]; + float linear[3]; + int x; + + scanlineheader[2] = (width&0xff00)>>8; + scanlineheader[3] = (width&0x00ff); + + /* skip RLE for images too small or large */ + if (width < 8 || width >= 32768) { + for (x=0; x < width; x++) { + switch (ncomp) { + case 4: /* fallthrough */ + case 3: linear[2] = scanline[x*ncomp + 2]; + linear[1] = scanline[x*ncomp + 1]; + linear[0] = scanline[x*ncomp + 0]; + break; + default: + linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; + break; + } + stbiw__linear_to_rgbe(rgbe, linear); + s->func(s->context, rgbe, 4); + } + } else { + int c,r; + /* encode into scratch buffer */ + for (x=0; x < width; x++) { + switch(ncomp) { + case 4: /* fallthrough */ + case 3: linear[2] = scanline[x*ncomp + 2]; + linear[1] = scanline[x*ncomp + 1]; + linear[0] = scanline[x*ncomp + 0]; + break; + default: + linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; + break; + } + stbiw__linear_to_rgbe(rgbe, linear); + scratch[x + width*0] = rgbe[0]; + scratch[x + width*1] = rgbe[1]; + scratch[x + width*2] = rgbe[2]; + scratch[x + width*3] = rgbe[3]; + } + + s->func(s->context, scanlineheader, 4); + + /* RLE each component separately */ + for (c=0; c < 4; c++) { + unsigned char *comp = &scratch[width*c]; + + x = 0; + while (x < width) { + // find first run + r = x; + while (r+2 < width) { + if (comp[r] == comp[r+1] && comp[r] == comp[r+2]) + break; + ++r; + } + if (r+2 >= width) + r = width; + // dump up to first run + while (x < r) { + int len = r-x; + if (len > 128) len = 128; + stbiw__write_dump_data(s, len, &comp[x]); + x += len; + } + // if there's a run, output it + if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd + // find next byte after run + while (r < width && comp[r] == comp[x]) + ++r; + // output run up to r + while (x < r) { + int len = r-x; + if (len > 127) len = 127; + stbiw__write_run_data(s, len, comp[x]); + x += len; + } + } + } + } + } +} + +static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data) +{ + if (y <= 0 || x <= 0 || data == NULL) + return 0; + else { + // Each component is stored separately. Allocate scratch space for full output scanline. + unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4); + int i, len; + char buffer[128]; + char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"; + s->func(s->context, header, sizeof(header)-1); + + len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); + s->func(s->context, buffer, len); + + for(i=0; i < y; i++) + stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*i*x); + STBIW_FREE(scratch); + return 1; + } +} + +int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data) +{ + stbi__write_context s; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_hdr_core(&s, x, y, comp, (float *) data); +} + +int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) +{ + stbi__write_context s; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif // STBI_WRITE_NO_STDIO + + +////////////////////////////////////////////////////////////////////////////// +// +// PNG writer +// + +// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size() +#define stbiw__sbraw(a) ((int *) (a) - 2) +#define stbiw__sbm(a) stbiw__sbraw(a)[0] +#define stbiw__sbn(a) stbiw__sbraw(a)[1] + +#define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a)) +#define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0) +#define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a))) + +#define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v)) +#define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0) +#define stbiw__sbfree(a) ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0) + +static void *stbiw__sbgrowf(void **arr, int increment, int itemsize) +{ + int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1; + void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2); + STBIW_ASSERT(p); + if (p) { + if (!*arr) ((int *) p)[1] = 0; + *arr = (void *) ((int *) p + 2); + stbiw__sbm(*arr) = m; + } + return *arr; +} + +static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount) +{ + while (*bitcount >= 8) { + stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer)); + *bitbuffer >>= 8; + *bitcount -= 8; + } + return data; +} + +static int stbiw__zlib_bitrev(int code, int codebits) +{ + int res=0; + while (codebits--) { + res = (res << 1) | (code & 1); + code >>= 1; + } + return res; +} + +static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit) +{ + int i; + for (i=0; i < limit && i < 258; ++i) + if (a[i] != b[i]) break; + return i; +} + +static unsigned int stbiw__zhash(unsigned char *data) +{ + stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16); + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + return hash; +} + +#define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount)) +#define stbiw__zlib_add(code,codebits) \ + (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush()) +#define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c) +// default huffman tables +#define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8) +#define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9) +#define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7) +#define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8) +#define stbiw__zlib_huff(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n)) +#define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n)) + +#define stbiw__ZHASH 16384 + +unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) +{ + static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 }; + static unsigned char lengtheb[]= { 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 }; + static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 }; + static unsigned char disteb[] = { 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 }; + unsigned int bitbuf=0; + int i,j, bitcount=0; + unsigned char *out = NULL; + unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**)); + if (quality < 5) quality = 5; + + stbiw__sbpush(out, 0x78); // DEFLATE 32K window + stbiw__sbpush(out, 0x5e); // FLEVEL = 1 + stbiw__zlib_add(1,1); // BFINAL = 1 + stbiw__zlib_add(1,2); // BTYPE = 1 -- fixed huffman + + for (i=0; i < stbiw__ZHASH; ++i) + hash_table[i] = NULL; + + i=0; + while (i < data_len-3) { + // hash next 3 bytes of data to be compressed + int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3; + unsigned char *bestloc = 0; + unsigned char **hlist = hash_table[h]; + int n = stbiw__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32768) { // if entry lies within window + int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i); + if (d >= best) best=d,bestloc=hlist[j]; + } + } + // when hash table entry is too long, delete half the entries + if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) { + STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality); + stbiw__sbn(hash_table[h]) = quality; + } + stbiw__sbpush(hash_table[h],data+i); + + if (bestloc) { + // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal + h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1); + hlist = hash_table[h]; + n = stbiw__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32767) { + int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1); + if (e > best) { // if next match is better, bail on current match + bestloc = NULL; + break; + } + } + } + } + + if (bestloc) { + int d = (int) (data+i - bestloc); // distance back + STBIW_ASSERT(d <= 32767 && best <= 258); + for (j=0; best > lengthc[j+1]-1; ++j); + stbiw__zlib_huff(j+257); + if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]); + for (j=0; d > distc[j+1]-1; ++j); + stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5); + if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]); + i += best; + } else { + stbiw__zlib_huffb(data[i]); + ++i; + } + } + // write out final bytes + for (;i < data_len; ++i) + stbiw__zlib_huffb(data[i]); + stbiw__zlib_huff(256); // end of block + // pad with 0 bits to byte boundary + while (bitcount) + stbiw__zlib_add(0,1); + + for (i=0; i < stbiw__ZHASH; ++i) + (void) stbiw__sbfree(hash_table[i]); + STBIW_FREE(hash_table); + + { + // compute adler32 on input + unsigned int s1=1, s2=0; + int blocklen = (int) (data_len % 5552); + j=0; + while (j < data_len) { + for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1; + s1 %= 65521, s2 %= 65521; + j += blocklen; + blocklen = 5552; + } + stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(s2)); + stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(s1)); + } + *out_len = stbiw__sbn(out); + // make returned pointer freeable + STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len); + return (unsigned char *) stbiw__sbraw(out); +} + +static unsigned int stbiw__crc32(unsigned char *buffer, int len) +{ + static unsigned int crc_table[256] = + { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D + }; + + unsigned int crc = ~0u; + int i; + for (i=0; i < len; ++i) + crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; + return ~crc; +} + +#define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4) +#define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v)); +#define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3]) + +static void stbiw__wpcrc(unsigned char **data, int len) +{ + unsigned int crc = stbiw__crc32(*data - len - 4, len+4); + stbiw__wp32(*data, crc); +} + +static unsigned char stbiw__paeth(int a, int b, int c) +{ + int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c); + if (pa <= pb && pa <= pc) return STBIW_UCHAR(a); + if (pb <= pc) return STBIW_UCHAR(b); + return STBIW_UCHAR(c); +} + +unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) +{ + int ctype[5] = { -1, 0, 4, 2, 6 }; + unsigned char sig[8] = { 137,80,78,71,13,10,26,10 }; + unsigned char *out,*o, *filt, *zlib; + signed char *line_buffer; + int i,j,k,p,zlen; + + if (stride_bytes == 0) + stride_bytes = x * n; + + filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0; + line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; } + for (j=0; j < y; ++j) { + static int mapping[] = { 0,1,2,3,4 }; + static int firstmap[] = { 0,1,0,5,6 }; + int *mymap = j ? mapping : firstmap; + int best = 0, bestval = 0x7fffffff; + for (p=0; p < 2; ++p) { + for (k= p?best:0; k < 5; ++k) { + int type = mymap[k],est=0; + unsigned char *z = pixels + stride_bytes*j; + for (i=0; i < n; ++i) + switch (type) { + case 0: line_buffer[i] = z[i]; break; + case 1: line_buffer[i] = z[i]; break; + case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break; + case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break; + case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break; + case 5: line_buffer[i] = z[i]; break; + case 6: line_buffer[i] = z[i]; break; + } + for (i=n; i < x*n; ++i) { + switch (type) { + case 0: line_buffer[i] = z[i]; break; + case 1: line_buffer[i] = z[i] - z[i-n]; break; + case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break; + case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break; + case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break; + case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break; + case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break; + } + } + if (p) break; + for (i=0; i < x*n; ++i) + est += abs((signed char) line_buffer[i]); + if (est < bestval) { bestval = est; best = k; } + } + } + // when we get here, best contains the filter type, and line_buffer contains the data + filt[j*(x*n+1)] = (unsigned char) best; + STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n); + } + STBIW_FREE(line_buffer); + zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory + STBIW_FREE(filt); + if (!zlib) return 0; + + // each tag requires 12 bytes of overhead + out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12); + if (!out) return 0; + *out_len = 8 + 12+13 + 12+zlen + 12; + + o=out; + STBIW_MEMMOVE(o,sig,8); o+= 8; + stbiw__wp32(o, 13); // header length + stbiw__wptag(o, "IHDR"); + stbiw__wp32(o, x); + stbiw__wp32(o, y); + *o++ = 8; // depth + *o++ = STBIW_UCHAR(ctype[n]);// color type + *o++ = 0; + *o++ = 0; + *o++ = 0; + stbiw__wpcrc(&o,13); + + stbiw__wp32(o, zlen); + stbiw__wptag(o, "IDAT"); + STBIW_MEMMOVE(o, zlib, zlen); + o += zlen; + STBIW_FREE(zlib); + stbiw__wpcrc(&o, zlen); + + stbiw__wp32(o,0); + stbiw__wptag(o, "IEND"); + stbiw__wpcrc(&o,0); + + STBIW_ASSERT(o == out + *out_len); + + return out; +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes) +{ + FILE *f; + int len; + unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len); + if (png == NULL) return 0; + f = fopen(filename, "wb"); + if (!f) { STBIW_FREE(png); return 0; } + fwrite(png, 1, len, f); + fclose(f); + STBIW_FREE(png); + return 1; +} +#endif + +STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes) +{ + int len; + unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len); + if (png == NULL) return 0; + func(context, png, len); + STBIW_FREE(png); + return 1; +} + +#endif // STB_IMAGE_WRITE_IMPLEMENTATION + +/* Revision history + 1.02 (2016-04-02) + avoid allocating large structures on the stack + 1.01 (2016-01-16) + STBIW_REALLOC_SIZED: support allocators with no realloc support + avoid race-condition in crc initialization + minor compile issues + 1.00 (2015-09-14) + installable file IO function + 0.99 (2015-09-13) + warning fixes; TGA rle support + 0.98 (2015-04-08) + added STBIW_MALLOC, STBIW_ASSERT etc + 0.97 (2015-01-18) + fixed HDR asserts, rewrote HDR rle logic + 0.96 (2015-01-17) + add HDR output + fix monochrome BMP + 0.95 (2014-08-17) + add monochrome TGA output + 0.94 (2014-05-31) + rename private functions to avoid conflicts with stb_image.h + 0.93 (2014-05-27) + warning fixes + 0.92 (2010-08-01) + casts to unsigned char to fix warnings + 0.91 (2010-07-17) + first public release + 0.90 first internal release +*/ diff --git a/CameraParameterEstimation/apps/basics/extern/stb_textedit.h b/CameraParameterEstimation/apps/basics/extern/stb_textedit.h new file mode 100644 index 0000000..6740b91 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/stb_textedit.h @@ -0,0 +1,1301 @@ +// stb_textedit.h - v1.7 - public domain - Sean Barrett +// Development of this library was sponsored by RAD Game Tools +// +// This C header file implements the guts of a multi-line text-editing +// widget; you implement display, word-wrapping, and low-level string +// insertion/deletion, and stb_textedit will map user inputs into +// insertions & deletions, plus updates to the cursor position, +// selection state, and undo state. +// +// It is intended for use in games and other systems that need to build +// their own custom widgets and which do not have heavy text-editing +// requirements (this library is not recommended for use for editing large +// texts, as its performance does not scale and it has limited undo). +// +// Non-trivial behaviors are modelled after Windows text controls. +// +// +// LICENSE +// +// This software is in the public domain. Where that dedication is not +// recognized, you are granted a perpetual, irrevocable license to copy, +// distribute, and modify this file as you see fit. +// +// +// DEPENDENCIES +// +// Uses the C runtime function 'memmove', which you can override +// by defining STB_TEXTEDIT_memmove before the implementation. +// Uses no other functions. Performs no runtime allocations. +// +// +// VERSION HISTORY +// +// 1.7 (2015-09-13) change y range handling in case baseline is non-0 +// 1.6 (2015-04-15) allow STB_TEXTEDIT_memmove +// 1.5 (2014-09-10) add support for secondary keys for OS X +// 1.4 (2014-08-17) fix signed/unsigned warnings +// 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary +// 1.2 (2014-05-27) fix some RAD types that had crept into the new code +// 1.1 (2013-12-15) move-by-word (requires STB_TEXTEDIT_IS_SPACE ) +// 1.0 (2012-07-26) improve documentation, initial public release +// 0.3 (2012-02-24) bugfixes, single-line mode; insert mode +// 0.2 (2011-11-28) fixes to undo/redo +// 0.1 (2010-07-08) initial version +// +// ADDITIONAL CONTRIBUTORS +// +// Ulf Winklemann: move-by-word in 1.1 +// Fabian Giesen: secondary key inputs in 1.5 +// Martins Mozeiko: STB_TEXTEDIT_memmove +// +// Bugfixes: +// Scott Graham +// Daniel Keller +// Omar Cornut +// +// USAGE +// +// This file behaves differently depending on what symbols you define +// before including it. +// +// +// Header-file mode: +// +// If you do not define STB_TEXTEDIT_IMPLEMENTATION before including this, +// it will operate in "header file" mode. In this mode, it declares a +// single public symbol, STB_TexteditState, which encapsulates the current +// state of a text widget (except for the string, which you will store +// separately). +// +// To compile in this mode, you must define STB_TEXTEDIT_CHARTYPE to a +// primitive type that defines a single character (e.g. char, wchar_t, etc). +// +// To save space or increase undo-ability, you can optionally define the +// following things that are used by the undo system: +// +// STB_TEXTEDIT_POSITIONTYPE small int type encoding a valid cursor position +// STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow +// STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer +// +// If you don't define these, they are set to permissive types and +// moderate sizes. The undo system does no memory allocations, so +// it grows STB_TexteditState by the worst-case storage which is (in bytes): +// +// [4 + sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT +// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT +// +// +// Implementation mode: +// +// If you define STB_TEXTEDIT_IMPLEMENTATION before including this, it +// will compile the implementation of the text edit widget, depending +// on a large number of symbols which must be defined before the include. +// +// The implementation is defined only as static functions. You will then +// need to provide your own APIs in the same file which will access the +// static functions. +// +// The basic concept is that you provide a "string" object which +// behaves like an array of characters. stb_textedit uses indices to +// refer to positions in the string, implicitly representing positions +// in the displayed textedit. This is true for both plain text and +// rich text; even with rich text stb_truetype interacts with your +// code as if there was an array of all the displayed characters. +// +// Symbols that must be the same in header-file and implementation mode: +// +// STB_TEXTEDIT_CHARTYPE the character type +// STB_TEXTEDIT_POSITIONTYPE small type that a valid cursor position +// STB_TEXTEDIT_UNDOSTATECOUNT the number of undo states to allow +// STB_TEXTEDIT_UNDOCHARCOUNT the number of characters to store in the undo buffer +// +// Symbols you must define for implementation mode: +// +// STB_TEXTEDIT_STRING the type of object representing a string being edited, +// typically this is a wrapper object with other data you need +// +// STB_TEXTEDIT_STRINGLEN(obj) the length of the string (ideally O(1)) +// STB_TEXTEDIT_LAYOUTROW(&r,obj,n) returns the results of laying out a line of characters +// starting from character #n (see discussion below) +// STB_TEXTEDIT_GETWIDTH(obj,n,i) returns the pixel delta from the xpos of the i'th character +// to the xpos of the i+1'th char for a line of characters +// starting at character #n (i.e. accounts for kerning +// with previous char) +// STB_TEXTEDIT_KEYTOTEXT(k) maps a keyboard input to an insertable character +// (return type is int, -1 means not valid to insert) +// STB_TEXTEDIT_GETCHAR(obj,i) returns the i'th character of obj, 0-based +// STB_TEXTEDIT_NEWLINE the character returned by _GETCHAR() we recognize +// as manually wordwrapping for end-of-line positioning +// +// STB_TEXTEDIT_DELETECHARS(obj,i,n) delete n characters starting at i +// STB_TEXTEDIT_INSERTCHARS(obj,i,c*,n) insert n characters at i (pointed to by STB_TEXTEDIT_CHARTYPE*) +// +// STB_TEXTEDIT_K_SHIFT a power of two that is or'd in to a keyboard input to represent the shift key +// +// STB_TEXTEDIT_K_LEFT keyboard input to move cursor left +// STB_TEXTEDIT_K_RIGHT keyboard input to move cursor right +// STB_TEXTEDIT_K_UP keyboard input to move cursor up +// STB_TEXTEDIT_K_DOWN keyboard input to move cursor down +// STB_TEXTEDIT_K_LINESTART keyboard input to move cursor to start of line // e.g. HOME +// STB_TEXTEDIT_K_LINEEND keyboard input to move cursor to end of line // e.g. END +// STB_TEXTEDIT_K_TEXTSTART keyboard input to move cursor to start of text // e.g. ctrl-HOME +// STB_TEXTEDIT_K_TEXTEND keyboard input to move cursor to end of text // e.g. ctrl-END +// STB_TEXTEDIT_K_DELETE keyboard input to delete selection or character under cursor +// STB_TEXTEDIT_K_BACKSPACE keyboard input to delete selection or character left of cursor +// STB_TEXTEDIT_K_UNDO keyboard input to perform undo +// STB_TEXTEDIT_K_REDO keyboard input to perform redo +// +// Optional: +// STB_TEXTEDIT_K_INSERT keyboard input to toggle insert mode +// STB_TEXTEDIT_IS_SPACE(ch) true if character is whitespace (e.g. 'isspace'), +// required for WORDLEFT/WORDRIGHT +// STB_TEXTEDIT_K_WORDLEFT keyboard input to move cursor left one word // e.g. ctrl-LEFT +// STB_TEXTEDIT_K_WORDRIGHT keyboard input to move cursor right one word // e.g. ctrl-RIGHT +// STB_TEXTEDIT_K_LINESTART2 secondary keyboard input to move cursor to start of line +// STB_TEXTEDIT_K_LINEEND2 secondary keyboard input to move cursor to end of line +// STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text +// STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text +// +// Todo: +// STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page +// STB_TEXTEDIT_K_PGDOWN keyboard input to move cursor down a page +// +// Keyboard input must be encoded as a single integer value; e.g. a character code +// and some bitflags that represent shift states. to simplify the interface, SHIFT must +// be a bitflag, so we can test the shifted state of cursor movements to allow selection, +// i.e. (STB_TEXTED_K_RIGHT|STB_TEXTEDIT_K_SHIFT) should be shifted right-arrow. +// +// You can encode other things, such as CONTROL or ALT, in additional bits, and +// then test for their presence in e.g. STB_TEXTEDIT_K_WORDLEFT. For example, +// my Windows implementations add an additional CONTROL bit, and an additional KEYDOWN +// bit. Then all of the STB_TEXTEDIT_K_ values bitwise-or in the KEYDOWN bit, +// and I pass both WM_KEYDOWN and WM_CHAR events to the "key" function in the +// API below. The control keys will only match WM_KEYDOWN events because of the +// keydown bit I add, and STB_TEXTEDIT_KEYTOTEXT only tests for the KEYDOWN +// bit so it only decodes WM_CHAR events. +// +// STB_TEXTEDIT_LAYOUTROW returns information about the shape of one displayed +// row of characters assuming they start on the i'th character--the width and +// the height and the number of characters consumed. This allows this library +// to traverse the entire layout incrementally. You need to compute word-wrapping +// here. +// +// Each textfield keeps its own insert mode state, which is not how normal +// applications work. To keep an app-wide insert mode, update/copy the +// "insert_mode" field of STB_TexteditState before/after calling API functions. +// +// API +// +// void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) +// +// void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) +// void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) +// int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +// int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len) +// void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int key) +// +// Each of these functions potentially updates the string and updates the +// state. +// +// initialize_state: +// set the textedit state to a known good default state when initially +// constructing the textedit. +// +// click: +// call this with the mouse x,y on a mouse down; it will update the cursor +// and reset the selection start/end to the cursor point. the x,y must +// be relative to the text widget, with (0,0) being the top left. +// +// drag: +// call this with the mouse x,y on a mouse drag/up; it will update the +// cursor and the selection end point +// +// cut: +// call this to delete the current selection; returns true if there was +// one. you should FIRST copy the current selection to the system paste buffer. +// (To copy, just copy the current selection out of the string yourself.) +// +// paste: +// call this to paste text at the current cursor point or over the current +// selection if there is one. +// +// key: +// call this for keyboard inputs sent to the textfield. you can use it +// for "key down" events or for "translated" key events. if you need to +// do both (as in Win32), or distinguish Unicode characters from control +// inputs, set a high bit to distinguish the two; then you can define the +// various definitions like STB_TEXTEDIT_K_LEFT have the is-key-event bit +// set, and make STB_TEXTEDIT_KEYTOCHAR check that the is-key-event bit is +// clear. +// +// When rendering, you can read the cursor position and selection state from +// the STB_TexteditState. +// +// +// Notes: +// +// This is designed to be usable in IMGUI, so it allows for the possibility of +// running in an IMGUI that has NOT cached the multi-line layout. For this +// reason, it provides an interface that is compatible with computing the +// layout incrementally--we try to make sure we make as few passes through +// as possible. (For example, to locate the mouse pointer in the text, we +// could define functions that return the X and Y positions of characters +// and binary search Y and then X, but if we're doing dynamic layout this +// will run the layout algorithm many times, so instead we manually search +// forward in one pass. Similar logic applies to e.g. up-arrow and +// down-arrow movement.) +// +// If it's run in a widget that *has* cached the layout, then this is less +// efficient, but it's not horrible on modern computers. But you wouldn't +// want to edit million-line files with it. + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//// +//// Header-file mode +//// +//// + +#ifndef INCLUDE_STB_TEXTEDIT_H +#define INCLUDE_STB_TEXTEDIT_H + +//////////////////////////////////////////////////////////////////////// +// +// STB_TexteditState +// +// Definition of STB_TexteditState which you should store +// per-textfield; it includes cursor position, selection state, +// and undo state. +// + +#ifndef STB_TEXTEDIT_UNDOSTATECOUNT +#define STB_TEXTEDIT_UNDOSTATECOUNT 99 +#endif +#ifndef STB_TEXTEDIT_UNDOCHARCOUNT +#define STB_TEXTEDIT_UNDOCHARCOUNT 999 +#endif +#ifndef STB_TEXTEDIT_CHARTYPE +#define STB_TEXTEDIT_CHARTYPE int +#endif +#ifndef STB_TEXTEDIT_POSITIONTYPE +#define STB_TEXTEDIT_POSITIONTYPE int +#endif + +typedef struct +{ + // private data + STB_TEXTEDIT_POSITIONTYPE where; + short insert_length; + short delete_length; + short char_storage; +} StbUndoRecord; + +typedef struct +{ + // private data + StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT]; + STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT]; + short undo_point, redo_point; + short undo_char_point, redo_char_point; +} StbUndoState; + +typedef struct +{ + ///////////////////// + // + // public data + // + + int cursor; + // position of the text cursor within the string + + int select_start; // selection start point + int select_end; + // selection start and end point in characters; if equal, no selection. + // note that start may be less than or greater than end (e.g. when + // dragging the mouse, start is where the initial click was, and you + // can drag in either direction) + + unsigned char insert_mode; + // each textfield keeps its own insert mode state. to keep an app-wide + // insert mode, copy this value in/out of the app state + + ///////////////////// + // + // private data + // + unsigned char cursor_at_end_of_line; // not implemented yet + unsigned char initialized; + unsigned char has_preferred_x; + unsigned char single_line; + unsigned char padding1, padding2, padding3; + float preferred_x; // this determines where the cursor up/down tries to seek to along x + StbUndoState undostate; +} STB_TexteditState; + + +//////////////////////////////////////////////////////////////////////// +// +// StbTexteditRow +// +// Result of layout query, used by stb_textedit to determine where +// the text in each row is. + +// result of layout query +typedef struct +{ + float x0,x1; // starting x location, end x location (allows for align=right, etc) + float baseline_y_delta; // position of baseline relative to previous row's baseline + float ymin,ymax; // height of row above and below baseline + int num_chars; +} StbTexteditRow; +#endif //INCLUDE_STB_TEXTEDIT_H + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//// +//// Implementation mode +//// +//// + + +// implementation isn't include-guarded, since it might have indirectly +// included just the "header" portion +#ifdef STB_TEXTEDIT_IMPLEMENTATION + +#ifndef STB_TEXTEDIT_memmove +#include +#define STB_TEXTEDIT_memmove memmove +#endif + + +///////////////////////////////////////////////////////////////////////////// +// +// Mouse input handling +// + +// traverse the layout to locate the nearest character to a display position +static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y) +{ + StbTexteditRow r; + int n = STB_TEXTEDIT_STRINGLEN(str); + float base_y = 0, prev_x; + int i=0, k; + + r.x0 = r.x1 = 0; + r.ymin = r.ymax = 0; + r.num_chars = 0; + + // search rows to find one that straddles 'y' + while (i < n) { + STB_TEXTEDIT_LAYOUTROW(&r, str, i); + if (r.num_chars <= 0) + return n; + + if (i==0 && y < base_y + r.ymin) + return 0; + + if (y < base_y + r.ymax) + break; + + i += r.num_chars; + base_y += r.baseline_y_delta; + } + + // below all text, return 'after' last character + if (i >= n) + return n; + + // check if it's before the beginning of the line + if (x < r.x0) + return i; + + // check if it's before the end of the line + if (x < r.x1) { + // search characters in row for one that straddles 'x' + k = i; + prev_x = r.x0; + for (i=0; i < r.num_chars; ++i) { + float w = STB_TEXTEDIT_GETWIDTH(str, k, i); + if (x < prev_x+w) { + if (x < prev_x+w/2) + return k+i; + else + return k+i+1; + } + prev_x += w; + } + // shouldn't happen, but if it does, fall through to end-of-line case + } + + // if the last character is a newline, return that. otherwise return 'after' the last character + if (STB_TEXTEDIT_GETCHAR(str, i+r.num_chars-1) == STB_TEXTEDIT_NEWLINE) + return i+r.num_chars-1; + else + return i+r.num_chars; +} + +// API click: on mouse down, move the cursor to the clicked location, and reset the selection +static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) +{ + state->cursor = stb_text_locate_coord(str, x, y); + state->select_start = state->cursor; + state->select_end = state->cursor; + state->has_preferred_x = 0; +} + +// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location +static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) +{ + int p = stb_text_locate_coord(str, x, y); + state->cursor = state->select_end = p; +} + +///////////////////////////////////////////////////////////////////////////// +// +// Keyboard input handling +// + +// forward declarations +static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state); +static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state); +static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length); +static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length); +static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length); + +typedef struct +{ + float x,y; // position of n'th character + float height; // height of line + int first_char, length; // first char of row, and length + int prev_first; // first char of previous row +} StbFindState; + +// find the x/y location of a character, and remember info about the previous row in +// case we get a move-up event (for page up, we'll have to rescan) +static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line) +{ + StbTexteditRow r; + int prev_start = 0; + int z = STB_TEXTEDIT_STRINGLEN(str); + int i=0, first; + + if (n == z) { + // if it's at the end, then find the last line -- simpler than trying to + // explicitly handle this case in the regular code + if (single_line) { + STB_TEXTEDIT_LAYOUTROW(&r, str, 0); + find->y = 0; + find->first_char = 0; + find->length = z; + find->height = r.ymax - r.ymin; + find->x = r.x1; + } else { + find->y = 0; + find->x = 0; + find->height = 1; + while (i < z) { + STB_TEXTEDIT_LAYOUTROW(&r, str, i); + prev_start = i; + i += r.num_chars; + } + find->first_char = i; + find->length = 0; + find->prev_first = prev_start; + } + return; + } + + // search rows to find the one that straddles character n + find->y = 0; + + for(;;) { + STB_TEXTEDIT_LAYOUTROW(&r, str, i); + if (n < i + r.num_chars) + break; + prev_start = i; + i += r.num_chars; + find->y += r.baseline_y_delta; + } + + find->first_char = first = i; + find->length = r.num_chars; + find->height = r.ymax - r.ymin; + find->prev_first = prev_start; + + // now scan to find xpos + find->x = r.x0; + i = 0; + for (i=0; first+i < n; ++i) + find->x += STB_TEXTEDIT_GETWIDTH(str, first, i); +} + +#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end) + +// make the selection/cursor state valid if client altered the string +static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + int n = STB_TEXTEDIT_STRINGLEN(str); + if (STB_TEXT_HAS_SELECTION(state)) { + if (state->select_start > n) state->select_start = n; + if (state->select_end > n) state->select_end = n; + // if clamping forced them to be equal, move the cursor to match + if (state->select_start == state->select_end) + state->cursor = state->select_start; + } + if (state->cursor > n) state->cursor = n; +} + +// delete characters while updating undo +static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len) +{ + stb_text_makeundo_delete(str, state, where, len); + STB_TEXTEDIT_DELETECHARS(str, where, len); + state->has_preferred_x = 0; +} + +// delete the section +static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + stb_textedit_clamp(str, state); + if (STB_TEXT_HAS_SELECTION(state)) { + if (state->select_start < state->select_end) { + stb_textedit_delete(str, state, state->select_start, state->select_end - state->select_start); + state->select_end = state->cursor = state->select_start; + } else { + stb_textedit_delete(str, state, state->select_end, state->select_start - state->select_end); + state->select_start = state->cursor = state->select_end; + } + state->has_preferred_x = 0; + } +} + +// canoncialize the selection so start <= end +static void stb_textedit_sortselection(STB_TexteditState *state) +{ + if (state->select_end < state->select_start) { + int temp = state->select_end; + state->select_end = state->select_start; + state->select_start = temp; + } +} + +// move cursor to first character of selection +static void stb_textedit_move_to_first(STB_TexteditState *state) +{ + if (STB_TEXT_HAS_SELECTION(state)) { + stb_textedit_sortselection(state); + state->cursor = state->select_start; + state->select_end = state->select_start; + state->has_preferred_x = 0; + } +} + +// move cursor to last character of selection +static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + if (STB_TEXT_HAS_SELECTION(state)) { + stb_textedit_sortselection(state); + stb_textedit_clamp(str, state); + state->cursor = state->select_end; + state->select_start = state->select_end; + state->has_preferred_x = 0; + } +} + +#ifdef STB_TEXTEDIT_IS_SPACE +static int is_word_boundary( STB_TEXTEDIT_STRING *_str, int _idx ) +{ + return _idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str,_idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str, _idx) ) ) : 1; +} + +static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *_str, STB_TexteditState *_state ) +{ + int c = _state->cursor - 1; + while( c >= 0 && !is_word_boundary( _str, c ) ) + --c; + + if( c < 0 ) + c = 0; + + return c; +} + +static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *_str, STB_TexteditState *_state ) +{ + const int len = STB_TEXTEDIT_STRINGLEN(_str); + int c = _state->cursor+1; + while( c < len && !is_word_boundary( _str, c ) ) + ++c; + + if( c > len ) + c = len; + + return c; +} +#endif + +// update selection and cursor to match each other +static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state) +{ + if (!STB_TEXT_HAS_SELECTION(state)) + state->select_start = state->select_end = state->cursor; + else + state->cursor = state->select_end; +} + +// API cut: delete selection +static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + if (STB_TEXT_HAS_SELECTION(state)) { + stb_textedit_delete_selection(str,state); // implicity clamps + state->has_preferred_x = 0; + return 1; + } + return 0; +} + +// API paste: replace existing selection with passed-in text +static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len) +{ + STB_TEXTEDIT_CHARTYPE *text = (STB_TEXTEDIT_CHARTYPE *) ctext; + // if there's a selection, the paste should delete it + stb_textedit_clamp(str, state); + stb_textedit_delete_selection(str,state); + // try to insert the characters + if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) { + stb_text_makeundo_insert(state, state->cursor, len); + state->cursor += len; + state->has_preferred_x = 0; + return 1; + } + // remove the undo since we didn't actually insert the characters + if (state->undostate.undo_point) + --state->undostate.undo_point; + return 0; +} + +// API key: process a keyboard input +static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int key) +{ +retry: + switch (key) { + default: { + int c = STB_TEXTEDIT_KEYTOTEXT(key); + if (c > 0) { + STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c; + + // can't add newline in single-line mode + if (c == '\n' && state->single_line) + break; + + if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) { + stb_text_makeundo_replace(str, state, state->cursor, 1, 1); + STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1); + if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { + ++state->cursor; + state->has_preferred_x = 0; + } + } else { + stb_textedit_delete_selection(str,state); // implicity clamps + if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { + stb_text_makeundo_insert(state, state->cursor, 1); + ++state->cursor; + state->has_preferred_x = 0; + } + } + } + break; + } + +#ifdef STB_TEXTEDIT_K_INSERT + case STB_TEXTEDIT_K_INSERT: + state->insert_mode = !state->insert_mode; + break; +#endif + + case STB_TEXTEDIT_K_UNDO: + stb_text_undo(str, state); + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_REDO: + stb_text_redo(str, state); + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_LEFT: + // if currently there's a selection, move cursor to start of selection + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_first(state); + else + if (state->cursor > 0) + --state->cursor; + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_RIGHT: + // if currently there's a selection, move cursor to end of selection + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_last(str, state); + else + ++state->cursor; + stb_textedit_clamp(str, state); + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_LEFT | STB_TEXTEDIT_K_SHIFT: + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + // move selection left + if (state->select_end > 0) + --state->select_end; + state->cursor = state->select_end; + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_IS_SPACE + case STB_TEXTEDIT_K_WORDLEFT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_first(state); + else { + state->cursor = stb_textedit_move_to_word_previous(str, state); + stb_textedit_clamp( str, state ); + } + break; + + case STB_TEXTEDIT_K_WORDRIGHT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_last(str, state); + else { + state->cursor = stb_textedit_move_to_word_next(str, state); + stb_textedit_clamp( str, state ); + } + break; + + case STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT: + if( !STB_TEXT_HAS_SELECTION( state ) ) + stb_textedit_prep_selection_at_cursor(state); + + state->cursor = stb_textedit_move_to_word_previous(str, state); + state->select_end = state->cursor; + + stb_textedit_clamp( str, state ); + break; + + case STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT: + if( !STB_TEXT_HAS_SELECTION( state ) ) + stb_textedit_prep_selection_at_cursor(state); + + state->cursor = stb_textedit_move_to_word_next(str, state); + state->select_end = state->cursor; + + stb_textedit_clamp( str, state ); + break; +#endif + + case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT: + stb_textedit_prep_selection_at_cursor(state); + // move selection right + ++state->select_end; + stb_textedit_clamp(str, state); + state->cursor = state->select_end; + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_DOWN: + case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + StbTexteditRow row; + int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; + + if (state->single_line) { + // on windows, up&down in single-line behave like left&right + key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT); + goto retry; + } + + if (sel) + stb_textedit_prep_selection_at_cursor(state); + else if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_last(str,state); + + // compute current position of cursor point + stb_textedit_clamp(str, state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + + // now find character position down a row + if (find.length) { + float goal_x = state->has_preferred_x ? state->preferred_x : find.x; + float x; + int start = find.first_char + find.length; + state->cursor = start; + STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); + x = row.x0; + for (i=0; i < row.num_chars; ++i) { + float dx = STB_TEXTEDIT_GETWIDTH(str, start, i); + #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE + if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) + break; + #endif + x += dx; + if (x > goal_x) + break; + ++state->cursor; + } + stb_textedit_clamp(str, state); + + state->has_preferred_x = 1; + state->preferred_x = goal_x; + + if (sel) + state->select_end = state->cursor; + } + break; + } + + case STB_TEXTEDIT_K_UP: + case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + StbTexteditRow row; + int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; + + if (state->single_line) { + // on windows, up&down become left&right + key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT); + goto retry; + } + + if (sel) + stb_textedit_prep_selection_at_cursor(state); + else if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_first(state); + + // compute current position of cursor point + stb_textedit_clamp(str, state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + + // can only go up if there's a previous row + if (find.prev_first != find.first_char) { + // now find character position up a row + float goal_x = state->has_preferred_x ? state->preferred_x : find.x; + float x; + state->cursor = find.prev_first; + STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); + x = row.x0; + for (i=0; i < row.num_chars; ++i) { + float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i); + #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE + if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) + break; + #endif + x += dx; + if (x > goal_x) + break; + ++state->cursor; + } + stb_textedit_clamp(str, state); + + state->has_preferred_x = 1; + state->preferred_x = goal_x; + + if (sel) + state->select_end = state->cursor; + } + break; + } + + case STB_TEXTEDIT_K_DELETE: + case STB_TEXTEDIT_K_DELETE | STB_TEXTEDIT_K_SHIFT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_delete_selection(str, state); + else { + int n = STB_TEXTEDIT_STRINGLEN(str); + if (state->cursor < n) + stb_textedit_delete(str, state, state->cursor, 1); + } + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_BACKSPACE: + case STB_TEXTEDIT_K_BACKSPACE | STB_TEXTEDIT_K_SHIFT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_delete_selection(str, state); + else { + stb_textedit_clamp(str, state); + if (state->cursor > 0) { + stb_textedit_delete(str, state, state->cursor-1, 1); + --state->cursor; + } + } + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_K_TEXTSTART2 + case STB_TEXTEDIT_K_TEXTSTART2: +#endif + case STB_TEXTEDIT_K_TEXTSTART: + state->cursor = state->select_start = state->select_end = 0; + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_K_TEXTEND2 + case STB_TEXTEDIT_K_TEXTEND2: +#endif + case STB_TEXTEDIT_K_TEXTEND: + state->cursor = STB_TEXTEDIT_STRINGLEN(str); + state->select_start = state->select_end = 0; + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_K_TEXTSTART2 + case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT: +#endif + case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT: + stb_textedit_prep_selection_at_cursor(state); + state->cursor = state->select_end = 0; + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_K_TEXTEND2 + case STB_TEXTEDIT_K_TEXTEND2 | STB_TEXTEDIT_K_SHIFT: +#endif + case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT: + stb_textedit_prep_selection_at_cursor(state); + state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str); + state->has_preferred_x = 0; + break; + + +#ifdef STB_TEXTEDIT_K_LINESTART2 + case STB_TEXTEDIT_K_LINESTART2: +#endif + case STB_TEXTEDIT_K_LINESTART: { + StbFindState find; + stb_textedit_clamp(str, state); + stb_textedit_move_to_first(state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + state->cursor = find.first_char; + state->has_preferred_x = 0; + break; + } + +#ifdef STB_TEXTEDIT_K_LINEEND2 + case STB_TEXTEDIT_K_LINEEND2: +#endif + case STB_TEXTEDIT_K_LINEEND: { + StbFindState find; + stb_textedit_clamp(str, state); + stb_textedit_move_to_first(state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + + state->has_preferred_x = 0; + state->cursor = find.first_char + find.length; + if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE) + --state->cursor; + break; + } + +#ifdef STB_TEXTEDIT_K_LINESTART2 + case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT: +#endif + case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + state->cursor = state->select_end = find.first_char; + state->has_preferred_x = 0; + break; + } + +#ifdef STB_TEXTEDIT_K_LINEEND2 + case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT: +#endif + case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + state->has_preferred_x = 0; + state->cursor = find.first_char + find.length; + if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE) + --state->cursor; + state->select_end = state->cursor; + break; + } + +// @TODO: +// STB_TEXTEDIT_K_PGUP - move cursor up a page +// STB_TEXTEDIT_K_PGDOWN - move cursor down a page + } +} + +///////////////////////////////////////////////////////////////////////////// +// +// Undo processing +// +// @OPTIMIZE: the undo/redo buffer should be circular + +static void stb_textedit_flush_redo(StbUndoState *state) +{ + state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; + state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; +} + +// discard the oldest entry in the undo list +static void stb_textedit_discard_undo(StbUndoState *state) +{ + if (state->undo_point > 0) { + // if the 0th undo state has characters, clean those up + if (state->undo_rec[0].char_storage >= 0) { + int n = state->undo_rec[0].insert_length, i; + // delete n characters from all other records + state->undo_char_point = state->undo_char_point - (short) n; // vsnet05 + STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE))); + for (i=0; i < state->undo_point; ++i) + if (state->undo_rec[i].char_storage >= 0) + state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it + } + --state->undo_point; + STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0]))); + } +} + +// discard the oldest entry in the redo list--it's bad if this +// ever happens, but because undo & redo have to store the actual +// characters in different cases, the redo character buffer can +// fill up even though the undo buffer didn't +static void stb_textedit_discard_redo(StbUndoState *state) +{ + int k = STB_TEXTEDIT_UNDOSTATECOUNT-1; + + if (state->redo_point <= k) { + // if the k'th undo state has characters, clean those up + if (state->undo_rec[k].char_storage >= 0) { + int n = state->undo_rec[k].insert_length, i; + // delete n characters from all other records + state->redo_char_point = state->redo_char_point + (short) n; // vsnet05 + STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE))); + for (i=state->redo_point; i < k; ++i) + if (state->undo_rec[i].char_storage >= 0) + state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05 + } + ++state->redo_point; + STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]))); + } +} + +static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numchars) +{ + // any time we create a new undo record, we discard redo + stb_textedit_flush_redo(state); + + // if we have no free records, we have to make room, by sliding the + // existing records down + if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT) + stb_textedit_discard_undo(state); + + // if the characters to store won't possibly fit in the buffer, we can't undo + if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) { + state->undo_point = 0; + state->undo_char_point = 0; + return NULL; + } + + // if we don't have enough free characters in the buffer, we have to make room + while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT) + stb_textedit_discard_undo(state); + + return &state->undo_rec[state->undo_point++]; +} + +static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len) +{ + StbUndoRecord *r = stb_text_create_undo_record(state, insert_len); + if (r == NULL) + return NULL; + + r->where = pos; + r->insert_length = (short) insert_len; + r->delete_length = (short) delete_len; + + if (insert_len == 0) { + r->char_storage = -1; + return NULL; + } else { + r->char_storage = state->undo_char_point; + state->undo_char_point = state->undo_char_point + (short) insert_len; + return &state->undo_char[r->char_storage]; + } +} + +static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + StbUndoState *s = &state->undostate; + StbUndoRecord u, *r; + if (s->undo_point == 0) + return; + + // we need to do two things: apply the undo record, and create a redo record + u = s->undo_rec[s->undo_point-1]; + r = &s->undo_rec[s->redo_point-1]; + r->char_storage = -1; + + r->insert_length = u.delete_length; + r->delete_length = u.insert_length; + r->where = u.where; + + if (u.delete_length) { + // if the undo record says to delete characters, then the redo record will + // need to re-insert the characters that get deleted, so we need to store + // them. + + // there are three cases: + // there's enough room to store the characters + // characters stored for *redoing* don't leave room for redo + // characters stored for *undoing* don't leave room for redo + // if the last is true, we have to bail + + if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) { + // the undo records take up too much character space; there's no space to store the redo characters + r->insert_length = 0; + } else { + int i; + + // there's definitely room to store the characters eventually + while (s->undo_char_point + u.delete_length > s->redo_char_point) { + // there's currently not enough room, so discard a redo record + stb_textedit_discard_redo(s); + // should never happen: + if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) + return; + } + r = &s->undo_rec[s->redo_point-1]; + + r->char_storage = s->redo_char_point - u.delete_length; + s->redo_char_point = s->redo_char_point - (short) u.delete_length; + + // now save the characters + for (i=0; i < u.delete_length; ++i) + s->undo_char[r->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u.where + i); + } + + // now we can carry out the deletion + STB_TEXTEDIT_DELETECHARS(str, u.where, u.delete_length); + } + + // check type of recorded action: + if (u.insert_length) { + // easy case: was a deletion, so we need to insert n characters + STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length); + s->undo_char_point -= u.insert_length; + } + + state->cursor = u.where + u.insert_length; + + s->undo_point--; + s->redo_point--; +} + +static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) +{ + StbUndoState *s = &state->undostate; + StbUndoRecord *u, r; + if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) + return; + + // we need to do two things: apply the redo record, and create an undo record + u = &s->undo_rec[s->undo_point]; + r = s->undo_rec[s->redo_point]; + + // we KNOW there must be room for the undo record, because the redo record + // was derived from an undo record + + u->delete_length = r.insert_length; + u->insert_length = r.delete_length; + u->where = r.where; + u->char_storage = -1; + + if (r.delete_length) { + // the redo record requires us to delete characters, so the undo record + // needs to store the characters + + if (s->undo_char_point + u->insert_length > s->redo_char_point) { + u->insert_length = 0; + u->delete_length = 0; + } else { + int i; + u->char_storage = s->undo_char_point; + s->undo_char_point = s->undo_char_point + u->insert_length; + + // now save the characters + for (i=0; i < u->insert_length; ++i) + s->undo_char[u->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u->where + i); + } + + STB_TEXTEDIT_DELETECHARS(str, r.where, r.delete_length); + } + + if (r.insert_length) { + // easy case: need to insert n characters + STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length); + } + + state->cursor = r.where + r.insert_length; + + s->undo_point++; + s->redo_point++; +} + +static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length) +{ + stb_text_createundo(&state->undostate, where, 0, length); +} + +static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length) +{ + int i; + STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0); + if (p) { + for (i=0; i < length; ++i) + p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); + } +} + +static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length) +{ + int i; + STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length); + if (p) { + for (i=0; i < old_length; ++i) + p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); + } +} + +// reset the state to default +static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_line) +{ + state->undostate.undo_point = 0; + state->undostate.undo_char_point = 0; + state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; + state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; + state->select_end = state->select_start = 0; + state->cursor = 0; + state->has_preferred_x = 0; + state->preferred_x = 0; + state->cursor_at_end_of_line = 0; + state->initialized = 1; + state->single_line = (unsigned char) is_single_line; + state->insert_mode = 0; +} + +// API initialize +static void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) +{ + stb_textedit_clear_state(state, is_single_line); +} +#endif//STB_TEXTEDIT_IMPLEMENTATION diff --git a/CameraParameterEstimation/apps/basics/extern/stb_truetype.h b/CameraParameterEstimation/apps/basics/extern/stb_truetype.h new file mode 100644 index 0000000..bfb1841 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/stb_truetype.h @@ -0,0 +1,3249 @@ +// stb_truetype.h - v1.09 - public domain +// authored from 2009-2015 by Sean Barrett / RAD Game Tools +// +// This library processes TrueType files: +// parse files +// extract glyph metrics +// extract glyph shapes +// render glyphs to one-channel bitmaps with antialiasing (box filter) +// +// Todo: +// non-MS cmaps +// crashproof on bad data +// hinting? (no longer patented) +// cleartype-style AA? +// optimize: use simple memory allocator for intermediates +// optimize: build edge-list directly from curves +// optimize: rasterize directly from curves? +// +// ADDITIONAL CONTRIBUTORS +// +// Mikko Mononen: compound shape support, more cmap formats +// Tor Andersson: kerning, subpixel rendering +// +// Bug/warning reports/fixes: +// "Zer" on mollyrocket (with fix) +// Cass Everitt +// stoiko (Haemimont Games) +// Brian Hook +// Walter van Niftrik +// David Gow +// David Given +// Ivan-Assen Ivanov +// Anthony Pesch +// Johan Duparc +// Hou Qiming +// Fabian "ryg" Giesen +// Martins Mozeiko +// Cap Petschulat +// Omar Cornut +// github:aloucks +// Peter LaValle +// Sergey Popov +// Giumo X. Clanjor +// Higor Euripedes +// Thomas Fields +// Derek Vinyard +// +// Misc other: +// Ryan Gordon +// +// VERSION HISTORY +// +// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly +// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges +// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; +// variant PackFontRanges to pack and render in separate phases; +// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?); +// fixed an assert() bug in the new rasterizer +// replace assert() with STBTT_assert() in new rasterizer +// 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine) +// also more precise AA rasterizer, except if shapes overlap +// remove need for STBTT_sort +// 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC +// 1.04 (2015-04-15) typo in example +// 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes +// +// Full history can be found at the end of this file. +// +// LICENSE +// +// This software is in the public domain. Where that dedication is not +// recognized, you are granted a perpetual, irrevocable license to copy, +// distribute, and modify this file as you see fit. +// +// USAGE +// +// Include this file in whatever places neeed to refer to it. In ONE C/C++ +// file, write: +// #define STB_TRUETYPE_IMPLEMENTATION +// before the #include of this file. This expands out the actual +// implementation into that C/C++ file. +// +// To make the implementation private to the file that generates the implementation, +// #define STBTT_STATIC +// +// Simple 3D API (don't ship this, but it's fine for tools and quick start) +// stbtt_BakeFontBitmap() -- bake a font to a bitmap for use as texture +// stbtt_GetBakedQuad() -- compute quad to draw for a given char +// +// Improved 3D API (more shippable): +// #include "stb_rect_pack.h" -- optional, but you really want it +// stbtt_PackBegin() +// stbtt_PackSetOversample() -- for improved quality on small fonts +// stbtt_PackFontRanges() -- pack and renders +// stbtt_PackEnd() +// stbtt_GetPackedQuad() +// +// "Load" a font file from a memory buffer (you have to keep the buffer loaded) +// stbtt_InitFont() +// stbtt_GetFontOffsetForIndex() -- use for TTC font collections +// +// Render a unicode codepoint to a bitmap +// stbtt_GetCodepointBitmap() -- allocates and returns a bitmap +// stbtt_MakeCodepointBitmap() -- renders into bitmap you provide +// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be +// +// Character advance/positioning +// stbtt_GetCodepointHMetrics() +// stbtt_GetFontVMetrics() +// stbtt_GetCodepointKernAdvance() +// +// Starting with version 1.06, the rasterizer was replaced with a new, +// faster and generally-more-precise rasterizer. The new rasterizer more +// accurately measures pixel coverage for anti-aliasing, except in the case +// where multiple shapes overlap, in which case it overestimates the AA pixel +// coverage. Thus, anti-aliasing of intersecting shapes may look wrong. If +// this turns out to be a problem, you can re-enable the old rasterizer with +// #define STBTT_RASTERIZER_VERSION 1 +// which will incur about a 15% speed hit. +// +// ADDITIONAL DOCUMENTATION +// +// Immediately after this block comment are a series of sample programs. +// +// After the sample programs is the "header file" section. This section +// includes documentation for each API function. +// +// Some important concepts to understand to use this library: +// +// Codepoint +// Characters are defined by unicode codepoints, e.g. 65 is +// uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is +// the hiragana for "ma". +// +// Glyph +// A visual character shape (every codepoint is rendered as +// some glyph) +// +// Glyph index +// A font-specific integer ID representing a glyph +// +// Baseline +// Glyph shapes are defined relative to a baseline, which is the +// bottom of uppercase characters. Characters extend both above +// and below the baseline. +// +// Current Point +// As you draw text to the screen, you keep track of a "current point" +// which is the origin of each character. The current point's vertical +// position is the baseline. Even "baked fonts" use this model. +// +// Vertical Font Metrics +// The vertical qualities of the font, used to vertically position +// and space the characters. See docs for stbtt_GetFontVMetrics. +// +// Font Size in Pixels or Points +// The preferred interface for specifying font sizes in stb_truetype +// is to specify how tall the font's vertical extent should be in pixels. +// If that sounds good enough, skip the next paragraph. +// +// Most font APIs instead use "points", which are a common typographic +// measurement for describing font size, defined as 72 points per inch. +// stb_truetype provides a point API for compatibility. However, true +// "per inch" conventions don't make much sense on computer displays +// since they different monitors have different number of pixels per +// inch. For example, Windows traditionally uses a convention that +// there are 96 pixels per inch, thus making 'inch' measurements have +// nothing to do with inches, and thus effectively defining a point to +// be 1.333 pixels. Additionally, the TrueType font data provides +// an explicit scale factor to scale a given font's glyphs to points, +// but the author has observed that this scale factor is often wrong +// for non-commercial fonts, thus making fonts scaled in points +// according to the TrueType spec incoherently sized in practice. +// +// ADVANCED USAGE +// +// Quality: +// +// - Use the functions with Subpixel at the end to allow your characters +// to have subpixel positioning. Since the font is anti-aliased, not +// hinted, this is very import for quality. (This is not possible with +// baked fonts.) +// +// - Kerning is now supported, and if you're supporting subpixel rendering +// then kerning is worth using to give your text a polished look. +// +// Performance: +// +// - Convert Unicode codepoints to glyph indexes and operate on the glyphs; +// if you don't do this, stb_truetype is forced to do the conversion on +// every call. +// +// - There are a lot of memory allocations. We should modify it to take +// a temp buffer and allocate from the temp buffer (without freeing), +// should help performance a lot. +// +// NOTES +// +// The system uses the raw data found in the .ttf file without changing it +// and without building auxiliary data structures. This is a bit inefficient +// on little-endian systems (the data is big-endian), but assuming you're +// caching the bitmaps or glyph shapes this shouldn't be a big deal. +// +// It appears to be very hard to programmatically determine what font a +// given file is in a general way. I provide an API for this, but I don't +// recommend it. +// +// +// SOURCE STATISTICS (based on v0.6c, 2050 LOC) +// +// Documentation & header file 520 LOC \___ 660 LOC documentation +// Sample code 140 LOC / +// Truetype parsing 620 LOC ---- 620 LOC TrueType +// Software rasterization 240 LOC \ . +// Curve tesselation 120 LOC \__ 550 LOC Bitmap creation +// Bitmap management 100 LOC / +// Baked bitmap interface 70 LOC / +// Font name matching & access 150 LOC ---- 150 +// C runtime library abstraction 60 LOC ---- 60 +// +// +// PERFORMANCE MEASUREMENTS FOR 1.06: +// +// 32-bit 64-bit +// Previous release: 8.83 s 7.68 s +// Pool allocations: 7.72 s 6.34 s +// Inline sort : 6.54 s 5.65 s +// New rasterizer : 5.63 s 5.00 s + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +//// +//// SAMPLE PROGRAMS +//// +// +// Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless +// +#if 0 +#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation +#include "stb_truetype.h" + +unsigned char ttf_buffer[1<<20]; +unsigned char temp_bitmap[512*512]; + +stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs +GLuint ftex; + +void my_stbtt_initfont(void) +{ + fread(ttf_buffer, 1, 1<<20, fopen("c:/windows/fonts/times.ttf", "rb")); + stbtt_BakeFontBitmap(ttf_buffer,0, 32.0, temp_bitmap,512,512, 32,96, cdata); // no guarantee this fits! + // can free ttf_buffer at this point + glGenTextures(1, &ftex); + glBindTexture(GL_TEXTURE_2D, ftex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap); + // can free temp_bitmap at this point + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +} + +void my_stbtt_print(float x, float y, char *text) +{ + // assume orthographic projection with units = screen pixels, origin at top left + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, ftex); + glBegin(GL_QUADS); + while (*text) { + if (*text >= 32 && *text < 128) { + stbtt_aligned_quad q; + stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9 + glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0); + glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0); + glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1); + glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y1); + } + ++text; + } + glEnd(); +} +#endif +// +// +////////////////////////////////////////////////////////////////////////////// +// +// Complete program (this compiles): get a single bitmap, print as ASCII art +// +#if 0 +#include +#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation +#include "stb_truetype.h" + +char ttf_buffer[1<<25]; + +int main(int argc, char **argv) +{ + stbtt_fontinfo font; + unsigned char *bitmap; + int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20); + + fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb")); + + stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0)); + bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0); + + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) + putchar(" .:ioVM@"[bitmap[j*w+i]>>5]); + putchar('\n'); + } + return 0; +} +#endif +// +// Output: +// +// .ii. +// @@@@@@. +// V@Mio@@o +// :i. V@V +// :oM@@M +// :@@@MM@M +// @@o o@M +// :@@. M@M +// @@@o@@@@ +// :M@@V:@@. +// +////////////////////////////////////////////////////////////////////////////// +// +// Complete program: print "Hello World!" banner, with bugs +// +#if 0 +char buffer[24<<20]; +unsigned char screen[20][79]; + +int main(int arg, char **argv) +{ + stbtt_fontinfo font; + int i,j,ascent,baseline,ch=0; + float scale, xpos=2; // leave a little padding in case the character extends left + char *text = "Heljo World!"; // intentionally misspelled to show 'lj' brokenness + + fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb")); + stbtt_InitFont(&font, buffer, 0); + + scale = stbtt_ScaleForPixelHeight(&font, 15); + stbtt_GetFontVMetrics(&font, &ascent,0,0); + baseline = (int) (ascent*scale); + + while (text[ch]) { + int advance,lsb,x0,y0,x1,y1; + float x_shift = xpos - (float) floor(xpos); + stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb); + stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale,scale,x_shift,0, &x0,&y0,&x1,&y1); + stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(int) xpos + x0], x1-x0,y1-y0, 79, scale,scale,x_shift,0, text[ch]); + // note that this stomps the old data, so where character boxes overlap (e.g. 'lj') it's wrong + // because this API is really for baking character bitmaps into textures. if you want to render + // a sequence of characters, you really need to render each bitmap to a temp buffer, then + // "alpha blend" that into the working buffer + xpos += (advance * scale); + if (text[ch+1]) + xpos += scale*stbtt_GetCodepointKernAdvance(&font, text[ch],text[ch+1]); + ++ch; + } + + for (j=0; j < 20; ++j) { + for (i=0; i < 78; ++i) + putchar(" .:ioVM@"[screen[j][i]>>5]); + putchar('\n'); + } + + return 0; +} +#endif + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +//// +//// INTEGRATION WITH YOUR CODEBASE +//// +//// The following sections allow you to supply alternate definitions +//// of C library functions used by stb_truetype. + +#ifdef STB_TRUETYPE_IMPLEMENTATION + // #define your own (u)stbtt_int8/16/32 before including to override this + #ifndef stbtt_uint8 + typedef unsigned char stbtt_uint8; + typedef signed char stbtt_int8; + typedef unsigned short stbtt_uint16; + typedef signed short stbtt_int16; + typedef unsigned int stbtt_uint32; + typedef signed int stbtt_int32; + #endif + + typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1]; + typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1]; + + // #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h + #ifndef STBTT_ifloor + #include + #define STBTT_ifloor(x) ((int) floor(x)) + #define STBTT_iceil(x) ((int) ceil(x)) + #endif + + #ifndef STBTT_sqrt + #include + #define STBTT_sqrt(x) sqrt(x) + #endif + + // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h + #ifndef STBTT_malloc + #include + #define STBTT_malloc(x,u) ((void)(u),malloc(x)) + #define STBTT_free(x,u) ((void)(u),free(x)) + #endif + + #ifndef STBTT_assert + #include + #define STBTT_assert(x) assert(x) + #endif + + #ifndef STBTT_strlen + #include + #define STBTT_strlen(x) strlen(x) + #endif + + #ifndef STBTT_memcpy + #include + #define STBTT_memcpy memcpy + #define STBTT_memset memset + #endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +//// +//// INTERFACE +//// +//// + +#ifndef __STB_INCLUDE_STB_TRUETYPE_H__ +#define __STB_INCLUDE_STB_TRUETYPE_H__ + +#ifdef STBTT_STATIC +#define STBTT_DEF static +#else +#define STBTT_DEF extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// TEXTURE BAKING API +// +// If you use this API, you only have to call two functions ever. +// + +typedef struct +{ + unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap + float xoff,yoff,xadvance; +} stbtt_bakedchar; + +STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) + float pixel_height, // height of font in pixels + unsigned char *pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar *chardata); // you allocate this, it's num_chars long +// if return is positive, the first unused row of the bitmap +// if return is negative, returns the negative of the number of characters that fit +// if return is 0, no characters fit and no rows were used +// This uses a very crappy packing. + +typedef struct +{ + float x0,y0,s0,t0; // top-left + float x1,y1,s1,t1; // bottom-right +} stbtt_aligned_quad; + +STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above + int char_index, // character to display + float *xpos, float *ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad *q, // output: quad to draw + int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier +// Call GetBakedQuad with char_index = 'character - first_char', and it +// creates the quad you need to draw and advances the current position. +// +// The coordinate system used assumes y increases downwards. +// +// Characters will extend both above and below the current position; +// see discussion of "BASELINE" above. +// +// It's inefficient; you might want to c&p it and optimize it. + + + +////////////////////////////////////////////////////////////////////////////// +// +// NEW TEXTURE BAKING API +// +// This provides options for packing multiple fonts into one atlas, not +// perfectly but better than nothing. + +typedef struct +{ + unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap + float xoff,yoff,xadvance; + float xoff2,yoff2; +} stbtt_packedchar; + +typedef struct stbtt_pack_context stbtt_pack_context; +typedef struct stbtt_fontinfo stbtt_fontinfo; +#ifndef STB_RECT_PACK_VERSION +typedef struct stbrp_rect stbrp_rect; +#endif + +STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); +// Initializes a packing context stored in the passed-in stbtt_pack_context. +// Future calls using this context will pack characters into the bitmap passed +// in here: a 1-channel bitmap that is weight x height. stride_in_bytes is +// the distance from one row to the next (or 0 to mean they are packed tightly +// together). "padding" is the amount of padding to leave between each +// character (normally you want '1' for bitmaps you'll use as textures with +// bilinear filtering). +// +// Returns 0 on failure, 1 on success. + +STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc); +// Cleans up the packing context and frees all memory. + +#define STBTT_POINT_SIZE(x) (-(x)) + +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, + int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range); +// Creates character bitmaps from the font_index'th font found in fontdata (use +// font_index=0 if you don't know what that is). It creates num_chars_in_range +// bitmaps for characters with unicode values starting at first_unicode_char_in_range +// and increasing. Data for how to render them is stored in chardata_for_range; +// pass these to stbtt_GetPackedQuad to get back renderable quads. +// +// font_size is the full height of the character from ascender to descender, +// as computed by stbtt_ScaleForPixelHeight. To use a point size as computed +// by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE() +// and pass that result as 'font_size': +// ..., 20 , ... // font max minus min y is 20 pixels tall +// ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall + +typedef struct +{ + float font_size; + int first_unicode_codepoint_in_range; // if non-zero, then the chars are continuous, and this is the first codepoint + int *array_of_unicode_codepoints; // if non-zero, then this is an array of unicode codepoints + int num_chars; + stbtt_packedchar *chardata_for_range; // output + unsigned char h_oversample, v_oversample; // don't set these, they're used internally +} stbtt_pack_range; + +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); +// Creates character bitmaps from multiple ranges of characters stored in +// ranges. This will usually create a better-packed bitmap than multiple +// calls to stbtt_PackFontRange. Note that you can call this multiple +// times within a single PackBegin/PackEnd. + +STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); +// Oversampling a font increases the quality by allowing higher-quality subpixel +// positioning, and is especially valuable at smaller text sizes. +// +// This function sets the amount of oversampling for all following calls to +// stbtt_PackFontRange(s) or stbtt_PackFontRangesGatherRects for a given +// pack context. The default (no oversampling) is achieved by h_oversample=1 +// and v_oversample=1. The total number of pixels required is +// h_oversample*v_oversample larger than the default; for example, 2x2 +// oversampling requires 4x the storage of 1x1. For best results, render +// oversampled textures with bilinear filtering. Look at the readme in +// stb/tests/oversample for information about oversampled fonts +// +// To use with PackFontRangesGather etc., you must set it before calls +// call to PackFontRangesGatherRects. + +STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above + int char_index, // character to display + float *xpos, float *ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad *q, // output: quad to draw + int align_to_integer); + +STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); +STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects); +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); +// Calling these functions in sequence is roughly equivalent to calling +// stbtt_PackFontRanges(). If you more control over the packing of multiple +// fonts, or if you want to pack custom data into a font texture, take a look +// at the source to of stbtt_PackFontRanges() and create a custom version +// using these functions, e.g. call GatherRects multiple times, +// building up a single array of rects, then call PackRects once, +// then call RenderIntoRects repeatedly. This may result in a +// better packing than calling PackFontRanges multiple times +// (or it may not). + +// this is an opaque structure that you shouldn't mess with which holds +// all the context needed from PackBegin to PackEnd. +struct stbtt_pack_context { + void *user_allocator_context; + void *pack_info; + int width; + int height; + int stride_in_bytes; + int padding; + unsigned int h_oversample, v_oversample; + unsigned char *pixels; + void *nodes; +}; + +////////////////////////////////////////////////////////////////////////////// +// +// FONT LOADING +// +// + +STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); +// Each .ttf/.ttc file may have more than one font. Each font has a sequential +// index number starting from 0. Call this function to get the font offset for +// a given index; it returns -1 if the index is out of range. A regular .ttf +// file will only define one font and it always be at offset 0, so it will +// return '0' for index 0, and -1 for all other indices. You can just skip +// this step if you know it's that kind of font. + + +// The following structure is defined publically so you can declare one on +// the stack or as a global or etc, but you should treat it as opaque. +typedef struct stbtt_fontinfo +{ + void * userdata; + unsigned char * data; // pointer to .ttf file + int fontstart; // offset of start of font + + int numGlyphs; // number of glyphs, needed for range checking + + int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf + int index_map; // a cmap mapping for our chosen character encoding + int indexToLocFormat; // format needed to map from glyph index to glyph +} stbtt_fontinfo; + +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); +// Given an offset into the file that defines a font, this function builds +// the necessary cached info for the rest of the system. You must allocate +// the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't +// need to do anything special to free it, because the contents are pure +// value data with no additional data structures. Returns 0 on failure. + + +////////////////////////////////////////////////////////////////////////////// +// +// CHARACTER TO GLYPH-INDEX CONVERSIOn + +STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint); +// If you're going to perform multiple operations on the same character +// and you want a speed-up, call this function with the character you're +// going to process, then use glyph-based functions instead of the +// codepoint-based functions. + + +////////////////////////////////////////////////////////////////////////////// +// +// CHARACTER PROPERTIES +// + +STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels); +// computes a scale factor to produce a font whose "height" is 'pixels' tall. +// Height is measured as the distance from the highest ascender to the lowest +// descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics +// and computing: +// scale = pixels / (ascent - descent) +// so if you prefer to measure height by the ascent only, use a similar calculation. + +STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels); +// computes a scale factor to produce a font whose EM size is mapped to +// 'pixels' tall. This is probably what traditional APIs compute, but +// I'm not positive. + +STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap); +// ascent is the coordinate above the baseline the font extends; descent +// is the coordinate below the baseline the font extends (i.e. it is typically negative) +// lineGap is the spacing between one row's descent and the next row's ascent... +// so you should advance the vertical position by "*ascent - *descent + *lineGap" +// these are expressed in unscaled coordinates, so you must multiply by +// the scale factor for a given size + +STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1); +// the bounding box around all possible characters + +STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing); +// leftSideBearing is the offset from the current horizontal position to the left edge of the character +// advanceWidth is the offset from the current horizontal position to the next horizontal position +// these are expressed in unscaled coordinates + +STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2); +// an additional amount to add to the 'advance' value between ch1 and ch2 + +STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1); +// Gets the bounding box of the visible part of the glyph, in unscaled coordinates + +STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing); +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2); +STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); +// as above, but takes one or more glyph indices for greater efficiency + + +////////////////////////////////////////////////////////////////////////////// +// +// GLYPH SHAPES (you probably don't need these, but they have to go before +// the bitmaps for C declaration-order reasons) +// + +#ifndef STBTT_vmove // you can predefine these to use different values (but why?) + enum { + STBTT_vmove=1, + STBTT_vline, + STBTT_vcurve + }; +#endif + +#ifndef stbtt_vertex // you can predefine this to use different values + // (we share this with other code at RAD) + #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file + typedef struct + { + stbtt_vertex_type x,y,cx,cy; + unsigned char type,padding; + } stbtt_vertex; +#endif + +STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index); +// returns non-zero if nothing is drawn for this glyph + +STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices); +STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices); +// returns # of vertices and fills *vertices with the pointer to them +// these are expressed in "unscaled" coordinates +// +// The shape is a series of countours. Each one starts with +// a STBTT_moveto, then consists of a series of mixed +// STBTT_lineto and STBTT_curveto segments. A lineto +// draws a line from previous endpoint to its x,y; a curveto +// draws a quadratic bezier from previous endpoint to +// its x,y, using cx,cy as the bezier control point. + +STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); +// frees the data allocated above + +////////////////////////////////////////////////////////////////////////////// +// +// BITMAP RENDERING +// + +STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata); +// frees the bitmap allocated below + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); +// allocates a large-enough single-channel 8bpp bitmap and renders the +// specified character/glyph at the specified scale into it, with +// antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque). +// *width & *height are filled out with the width & height of the bitmap, +// which is stored left-to-right, top-to-bottom. +// +// xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff); +// the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel +// shift for the character + +STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); +// the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap +// in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap +// is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the +// width and height and positioning info for it first. + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); +// same as stbtt_MakeCodepointBitmap, but you can specify a subpixel +// shift for the character + +STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); +// get the bbox of the bitmap centered around the glyph origin; so the +// bitmap width is ix1-ix0, height is iy1-iy0, and location to place +// the bitmap top left is (leftSideBearing*scale,iy0). +// (Note that the bitmap uses y-increases-down, but the shape uses +// y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.) + +STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); +// same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel +// shift for the character + +// the following functions are equivalent to the above functions, but operate +// on glyph indices instead of Unicode codepoints (for efficiency) +STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); +STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); +STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); +STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); + + +// @TODO: don't expose this structure +typedef struct +{ + int w,h,stride; + unsigned char *pixels; +} stbtt__bitmap; + +// rasterize a shape with quadratic beziers into a bitmap +STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, // 1-channel bitmap to draw into + float flatness_in_pixels, // allowable error of curve in pixels + stbtt_vertex *vertices, // array of vertices defining shape + int num_verts, // number of vertices in above array + float scale_x, float scale_y, // scale applied to input vertices + float shift_x, float shift_y, // translation applied to input vertices + int x_off, int y_off, // another translation applied to input + int invert, // if non-zero, vertically flip shape + void *userdata); // context for to STBTT_MALLOC + +////////////////////////////////////////////////////////////////////////////// +// +// Finding the right font... +// +// You should really just solve this offline, keep your own tables +// of what font is what, and don't try to get it out of the .ttf file. +// That's because getting it out of the .ttf file is really hard, because +// the names in the file can appear in many possible encodings, in many +// possible languages, and e.g. if you need a case-insensitive comparison, +// the details of that depend on the encoding & language in a complex way +// (actually underspecified in truetype, but also gigantic). +// +// But you can use the provided functions in two possible ways: +// stbtt_FindMatchingFont() will use *case-sensitive* comparisons on +// unicode-encoded names to try to find the font you want; +// you can run this before calling stbtt_InitFont() +// +// stbtt_GetFontNameString() lets you get any of the various strings +// from the file yourself and do your own comparisons on them. +// You have to have called stbtt_InitFont() first. + + +STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags); +// returns the offset (not index) of the font that matches, or -1 if none +// if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold". +// if you use any other flag, use a font name like "Arial"; this checks +// the 'macStyle' header field; i don't know if fonts set this consistently +#define STBTT_MACSTYLE_DONTCARE 0 +#define STBTT_MACSTYLE_BOLD 1 +#define STBTT_MACSTYLE_ITALIC 2 +#define STBTT_MACSTYLE_UNDERSCORE 4 +#define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0 + +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2); +// returns 1/0 whether the first string interpreted as utf8 is identical to +// the second string interpreted as big-endian utf16... useful for strings from next func + +STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID); +// returns the string (which may be big-endian double byte, e.g. for unicode) +// and puts the length in bytes in *length. +// +// some of the values for the IDs are below; for more see the truetype spec: +// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html +// http://www.microsoft.com/typography/otspec/name.htm + +enum { // platformID + STBTT_PLATFORM_ID_UNICODE =0, + STBTT_PLATFORM_ID_MAC =1, + STBTT_PLATFORM_ID_ISO =2, + STBTT_PLATFORM_ID_MICROSOFT =3 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_UNICODE + STBTT_UNICODE_EID_UNICODE_1_0 =0, + STBTT_UNICODE_EID_UNICODE_1_1 =1, + STBTT_UNICODE_EID_ISO_10646 =2, + STBTT_UNICODE_EID_UNICODE_2_0_BMP=3, + STBTT_UNICODE_EID_UNICODE_2_0_FULL=4 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT + STBTT_MS_EID_SYMBOL =0, + STBTT_MS_EID_UNICODE_BMP =1, + STBTT_MS_EID_SHIFTJIS =2, + STBTT_MS_EID_UNICODE_FULL =10 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes + STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4, + STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5, + STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6, + STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7 +}; + +enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... + // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs + STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410, + STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411, + STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412, + STBTT_MS_LANG_FRENCH =0x040c, STBTT_MS_LANG_RUSSIAN =0x0419, + STBTT_MS_LANG_GERMAN =0x0407, STBTT_MS_LANG_SPANISH =0x0409, + STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D +}; + +enum { // languageID for STBTT_PLATFORM_ID_MAC + STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11, + STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23, + STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32, + STBTT_MAC_LANG_FRENCH =1 , STBTT_MAC_LANG_SPANISH =6 , + STBTT_MAC_LANG_GERMAN =2 , STBTT_MAC_LANG_SWEDISH =5 , + STBTT_MAC_LANG_HEBREW =10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33, + STBTT_MAC_LANG_ITALIAN =3 , STBTT_MAC_LANG_CHINESE_TRAD =19 +}; + +#ifdef __cplusplus +} +#endif + +#endif // __STB_INCLUDE_STB_TRUETYPE_H__ + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +//// +//// IMPLEMENTATION +//// +//// + +#ifdef STB_TRUETYPE_IMPLEMENTATION + +#ifndef STBTT_MAX_OVERSAMPLE +#define STBTT_MAX_OVERSAMPLE 8 +#endif + +#if STBTT_MAX_OVERSAMPLE > 255 +#error "STBTT_MAX_OVERSAMPLE cannot be > 255" +#endif + +typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1]; + +#ifndef STBTT_RASTERIZER_VERSION +#define STBTT_RASTERIZER_VERSION 2 +#endif + +////////////////////////////////////////////////////////////////////////// +// +// accessors to parse data from file +// + +// on platforms that don't allow misaligned reads, if we want to allow +// truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE + +#define ttBYTE(p) (* (stbtt_uint8 *) (p)) +#define ttCHAR(p) (* (stbtt_int8 *) (p)) +#define ttFixed(p) ttLONG(p) + +#if defined(STB_TRUETYPE_BIGENDIAN) && !defined(ALLOW_UNALIGNED_TRUETYPE) + + #define ttUSHORT(p) (* (stbtt_uint16 *) (p)) + #define ttSHORT(p) (* (stbtt_int16 *) (p)) + #define ttULONG(p) (* (stbtt_uint32 *) (p)) + #define ttLONG(p) (* (stbtt_int32 *) (p)) + +#else + + static stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } + static stbtt_int16 ttSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } + static stbtt_uint32 ttULONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } + static stbtt_int32 ttLONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } + +#endif + +#define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) +#define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3]) + +static int stbtt__isfont(const stbtt_uint8 *font) +{ + // check the version number + if (stbtt_tag4(font, '1',0,0,0)) return 1; // TrueType 1 + if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this! + if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF + if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0 + return 0; +} + +// @OPTIMIZE: binary search +static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag) +{ + stbtt_int32 num_tables = ttUSHORT(data+fontstart+4); + stbtt_uint32 tabledir = fontstart + 12; + stbtt_int32 i; + for (i=0; i < num_tables; ++i) { + stbtt_uint32 loc = tabledir + 16*i; + if (stbtt_tag(data+loc+0, tag)) + return ttULONG(data+loc+8); + } + return 0; +} + +STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, int index) +{ + // if it's just a font, there's only one valid index + if (stbtt__isfont(font_collection)) + return index == 0 ? 0 : -1; + + // check if it's a TTC + if (stbtt_tag(font_collection, "ttcf")) { + // version 1? + if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) { + stbtt_int32 n = ttLONG(font_collection+8); + if (index >= n) + return -1; + return ttULONG(font_collection+12+index*4); + } + } + return -1; +} + +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, int fontstart) +{ + stbtt_uint8 *data = (stbtt_uint8 *) data2; + stbtt_uint32 cmap, t; + stbtt_int32 i,numTables; + + info->data = data; + info->fontstart = fontstart; + + cmap = stbtt__find_table(data, fontstart, "cmap"); // required + info->loca = stbtt__find_table(data, fontstart, "loca"); // required + info->head = stbtt__find_table(data, fontstart, "head"); // required + info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required + info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required + info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required + info->kern = stbtt__find_table(data, fontstart, "kern"); // not required + if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx) + return 0; + + t = stbtt__find_table(data, fontstart, "maxp"); + if (t) + info->numGlyphs = ttUSHORT(data+t+4); + else + info->numGlyphs = 0xffff; + + // find a cmap encoding table we understand *now* to avoid searching + // later. (todo: could make this installable) + // the same regardless of glyph. + numTables = ttUSHORT(data + cmap + 2); + info->index_map = 0; + for (i=0; i < numTables; ++i) { + stbtt_uint32 encoding_record = cmap + 4 + 8 * i; + // find an encoding we understand: + switch(ttUSHORT(data+encoding_record)) { + case STBTT_PLATFORM_ID_MICROSOFT: + switch (ttUSHORT(data+encoding_record+2)) { + case STBTT_MS_EID_UNICODE_BMP: + case STBTT_MS_EID_UNICODE_FULL: + // MS/Unicode + info->index_map = cmap + ttULONG(data+encoding_record+4); + break; + } + break; + case STBTT_PLATFORM_ID_UNICODE: + // Mac/iOS has these + // all the encodingIDs are unicode, so we don't bother to check it + info->index_map = cmap + ttULONG(data+encoding_record+4); + break; + } + } + if (info->index_map == 0) + return 0; + + info->indexToLocFormat = ttUSHORT(data+info->head + 50); + return 1; +} + +STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint) +{ + stbtt_uint8 *data = info->data; + stbtt_uint32 index_map = info->index_map; + + stbtt_uint16 format = ttUSHORT(data + index_map + 0); + if (format == 0) { // apple byte encoding + stbtt_int32 bytes = ttUSHORT(data + index_map + 2); + if (unicode_codepoint < bytes-6) + return ttBYTE(data + index_map + 6 + unicode_codepoint); + return 0; + } else if (format == 6) { + stbtt_uint32 first = ttUSHORT(data + index_map + 6); + stbtt_uint32 count = ttUSHORT(data + index_map + 8); + if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count) + return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2); + return 0; + } else if (format == 2) { + STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean + return 0; + } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges + stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1; + stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1; + stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10); + stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1; + + // do a binary search of the segments + stbtt_uint32 endCount = index_map + 14; + stbtt_uint32 search = endCount; + + if (unicode_codepoint > 0xffff) + return 0; + + // they lie from endCount .. endCount + segCount + // but searchRange is the nearest power of two, so... + if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2)) + search += rangeShift*2; + + // now decrement to bias correctly to find smallest + search -= 2; + while (entrySelector) { + stbtt_uint16 end; + searchRange >>= 1; + end = ttUSHORT(data + search + searchRange*2); + if (unicode_codepoint > end) + search += searchRange*2; + --entrySelector; + } + search += 2; + + { + stbtt_uint16 offset, start; + stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1); + + STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item)); + start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item); + if (unicode_codepoint < start) + return 0; + + offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item); + if (offset == 0) + return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item)); + + return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item); + } + } else if (format == 12 || format == 13) { + stbtt_uint32 ngroups = ttULONG(data+index_map+12); + stbtt_int32 low,high; + low = 0; high = (stbtt_int32)ngroups; + // Binary search the right group. + while (low < high) { + stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high + stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12); + stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4); + if ((stbtt_uint32) unicode_codepoint < start_char) + high = mid; + else if ((stbtt_uint32) unicode_codepoint > end_char) + low = mid+1; + else { + stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8); + if (format == 12) + return start_glyph + unicode_codepoint-start_char; + else // format == 13 + return start_glyph; + } + } + return 0; // not found + } + // @TODO + STBTT_assert(0); + return 0; +} + +STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices) +{ + return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices); +} + +static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy) +{ + v->type = type; + v->x = (stbtt_int16) x; + v->y = (stbtt_int16) y; + v->cx = (stbtt_int16) cx; + v->cy = (stbtt_int16) cy; +} + +static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) +{ + int g1,g2; + + if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range + if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format + + if (info->indexToLocFormat == 0) { + g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2; + g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2; + } else { + g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4); + g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4); + } + + return g1==g2 ? -1 : g1; // if length is 0, return -1 +} + +STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) +{ + int g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 0; + + if (x0) *x0 = ttSHORT(info->data + g + 2); + if (y0) *y0 = ttSHORT(info->data + g + 4); + if (x1) *x1 = ttSHORT(info->data + g + 6); + if (y1) *y1 = ttSHORT(info->data + g + 8); + return 1; +} + +STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1) +{ + return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1); +} + +STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index) +{ + stbtt_int16 numberOfContours; + int g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 1; + numberOfContours = ttSHORT(info->data + g); + return numberOfContours == 0; +} + +static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_off, int start_off, + stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy) +{ + if (start_off) { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy); + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx,sy,scx,scy); + } else { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0); + } + return num_vertices; +} + +STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +{ + stbtt_int16 numberOfContours; + stbtt_uint8 *endPtsOfContours; + stbtt_uint8 *data = info->data; + stbtt_vertex *vertices=0; + int num_vertices=0; + int g = stbtt__GetGlyfOffset(info, glyph_index); + + *pvertices = NULL; + + if (g < 0) return 0; + + numberOfContours = ttSHORT(data + g); + + if (numberOfContours > 0) { + stbtt_uint8 flags=0,flagcount; + stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0; + stbtt_int32 x,y,cx,cy,sx,sy, scx,scy; + stbtt_uint8 *points; + endPtsOfContours = (data + g + 10); + ins = ttUSHORT(data + g + 10 + numberOfContours * 2); + points = data + g + 10 + numberOfContours * 2 + 2 + ins; + + n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2); + + m = n + 2*numberOfContours; // a loose bound on how many vertices we might need + vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata); + if (vertices == 0) + return 0; + + next_move = 0; + flagcount=0; + + // in first pass, we load uninterpreted data into the allocated array + // above, shifted to the end of the array so we won't overwrite it when + // we create our final data starting from the front + + off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated + + // first load flags + + for (i=0; i < n; ++i) { + if (flagcount == 0) { + flags = *points++; + if (flags & 8) + flagcount = *points++; + } else + --flagcount; + vertices[off+i].type = flags; + } + + // now load x coordinates + x=0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + if (flags & 2) { + stbtt_int16 dx = *points++; + x += (flags & 16) ? dx : -dx; // ??? + } else { + if (!(flags & 16)) { + x = x + (stbtt_int16) (points[0]*256 + points[1]); + points += 2; + } + } + vertices[off+i].x = (stbtt_int16) x; + } + + // now load y coordinates + y=0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + if (flags & 4) { + stbtt_int16 dy = *points++; + y += (flags & 32) ? dy : -dy; // ??? + } else { + if (!(flags & 32)) { + y = y + (stbtt_int16) (points[0]*256 + points[1]); + points += 2; + } + } + vertices[off+i].y = (stbtt_int16) y; + } + + // now convert them to our format + num_vertices=0; + sx = sy = cx = cy = scx = scy = 0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + x = (stbtt_int16) vertices[off+i].x; + y = (stbtt_int16) vertices[off+i].y; + + if (next_move == i) { + if (i != 0) + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); + + // now start the new one + start_off = !(flags & 1); + if (start_off) { + // if we start off with an off-curve point, then when we need to find a point on the curve + // where we can start, and we need to save some state for when we wraparound. + scx = x; + scy = y; + if (!(vertices[off+i+1].type & 1)) { + // next point is also a curve point, so interpolate an on-point curve + sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1; + sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1; + } else { + // otherwise just use the next point as our start point + sx = (stbtt_int32) vertices[off+i+1].x; + sy = (stbtt_int32) vertices[off+i+1].y; + ++i; // we're using point i+1 as the starting point, so skip it + } + } else { + sx = x; + sy = y; + } + stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,sx,sy,0,0); + was_off = 0; + next_move = 1 + ttUSHORT(endPtsOfContours+j*2); + ++j; + } else { + if (!(flags & 1)) { // if it's a curve + if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy); + cx = x; + cy = y; + was_off = 1; + } else { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0); + was_off = 0; + } + } + } + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); + } else if (numberOfContours == -1) { + // Compound shapes. + int more = 1; + stbtt_uint8 *comp = data + g + 10; + num_vertices = 0; + vertices = 0; + while (more) { + stbtt_uint16 flags, gidx; + int comp_num_verts = 0, i; + stbtt_vertex *comp_verts = 0, *tmp = 0; + float mtx[6] = {1,0,0,1,0,0}, m, n; + + flags = ttSHORT(comp); comp+=2; + gidx = ttSHORT(comp); comp+=2; + + if (flags & 2) { // XY values + if (flags & 1) { // shorts + mtx[4] = ttSHORT(comp); comp+=2; + mtx[5] = ttSHORT(comp); comp+=2; + } else { + mtx[4] = ttCHAR(comp); comp+=1; + mtx[5] = ttCHAR(comp); comp+=1; + } + } + else { + // @TODO handle matching point + STBTT_assert(0); + } + if (flags & (1<<3)) { // WE_HAVE_A_SCALE + mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[1] = mtx[2] = 0; + } else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE + mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[1] = mtx[2] = 0; + mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; + } else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO + mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[1] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[2] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; + } + + // Find transformation scales. + m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); + n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); + + // Get indexed glyph. + comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts); + if (comp_num_verts > 0) { + // Transform vertices. + for (i = 0; i < comp_num_verts; ++i) { + stbtt_vertex* v = &comp_verts[i]; + stbtt_vertex_type x,y; + x=v->x; y=v->y; + v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); + v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); + x=v->cx; y=v->cy; + v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); + v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); + } + // Append vertices. + tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata); + if (!tmp) { + if (vertices) STBTT_free(vertices, info->userdata); + if (comp_verts) STBTT_free(comp_verts, info->userdata); + return 0; + } + if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); + STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex)); + if (vertices) STBTT_free(vertices, info->userdata); + vertices = tmp; + STBTT_free(comp_verts, info->userdata); + num_vertices += comp_num_verts; + } + // More components ? + more = flags & (1<<5); + } + } else if (numberOfContours < 0) { + // @TODO other compound variations? + STBTT_assert(0); + } else { + // numberOfCounters == 0, do nothing + } + + *pvertices = vertices; + return num_vertices; +} + +STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing) +{ + stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34); + if (glyph_index < numOfLongHorMetrics) { + if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index); + if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2); + } else { + if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1)); + if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics)); + } +} + +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +{ + stbtt_uint8 *data = info->data + info->kern; + stbtt_uint32 needle, straw; + int l, r, m; + + // we only look at the first table. it must be 'horizontal' and format 0. + if (!info->kern) + return 0; + if (ttUSHORT(data+2) < 1) // number of tables, need at least 1 + return 0; + if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format + return 0; + + l = 0; + r = ttUSHORT(data+10) - 1; + needle = glyph1 << 16 | glyph2; + while (l <= r) { + m = (l + r) >> 1; + straw = ttULONG(data+18+(m*6)); // note: unaligned read + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else + return ttSHORT(data+22+(m*6)); + } + return 0; +} + +STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) +{ + if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs + return 0; + return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2)); +} + +STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing) +{ + stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing); +} + +STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap) +{ + if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4); + if (descent) *descent = ttSHORT(info->data+info->hhea + 6); + if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8); +} + +STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1) +{ + *x0 = ttSHORT(info->data + info->head + 36); + *y0 = ttSHORT(info->data + info->head + 38); + *x1 = ttSHORT(info->data + info->head + 40); + *y1 = ttSHORT(info->data + info->head + 42); +} + +STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height) +{ + int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6); + return (float) height / fheight; +} + +STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels) +{ + int unitsPerEm = ttUSHORT(info->data + info->head + 18); + return pixels / unitsPerEm; +} + +STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) +{ + STBTT_free(v, info->userdata); +} + +////////////////////////////////////////////////////////////////////////////// +// +// antialiasing software rasterizer +// + +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + int x0=0,y0=0,x1,y1; // =0 suppresses compiler warning + if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) { + // e.g. space character + if (ix0) *ix0 = 0; + if (iy0) *iy0 = 0; + if (ix1) *ix1 = 0; + if (iy1) *iy1 = 0; + } else { + // move to integral bboxes (treating pixels as little squares, what pixels get touched)? + if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x); + if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y); + if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x); + if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y); + } +} + +STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1); +} + +STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1); +} + +STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1); +} + +////////////////////////////////////////////////////////////////////////////// +// +// Rasterizer + +typedef struct stbtt__hheap_chunk +{ + struct stbtt__hheap_chunk *next; +} stbtt__hheap_chunk; + +typedef struct stbtt__hheap +{ + struct stbtt__hheap_chunk *head; + void *first_free; + int num_remaining_in_head_chunk; +} stbtt__hheap; + +static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata) +{ + if (hh->first_free) { + void *p = hh->first_free; + hh->first_free = * (void **) p; + return p; + } else { + if (hh->num_remaining_in_head_chunk == 0) { + int count = (size < 32 ? 2000 : size < 128 ? 800 : 100); + stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata); + if (c == NULL) + return NULL; + c->next = hh->head; + hh->head = c; + hh->num_remaining_in_head_chunk = count; + } + --hh->num_remaining_in_head_chunk; + return (char *) (hh->head) + size * hh->num_remaining_in_head_chunk; + } +} + +static void stbtt__hheap_free(stbtt__hheap *hh, void *p) +{ + *(void **) p = hh->first_free; + hh->first_free = p; +} + +static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata) +{ + stbtt__hheap_chunk *c = hh->head; + while (c) { + stbtt__hheap_chunk *n = c->next; + STBTT_free(c, userdata); + c = n; + } +} + +typedef struct stbtt__edge { + float x0,y0, x1,y1; + int invert; +} stbtt__edge; + + +typedef struct stbtt__active_edge +{ + struct stbtt__active_edge *next; + #if STBTT_RASTERIZER_VERSION==1 + int x,dx; + float ey; + int direction; + #elif STBTT_RASTERIZER_VERSION==2 + float fx,fdx,fdy; + float direction; + float sy; + float ey; + #else + #error "Unrecognized value of STBTT_RASTERIZER_VERSION" + #endif +} stbtt__active_edge; + +#if STBTT_RASTERIZER_VERSION == 1 +#define STBTT_FIXSHIFT 10 +#define STBTT_FIX (1 << STBTT_FIXSHIFT) +#define STBTT_FIXMASK (STBTT_FIX-1) + +static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) +{ + stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); + if (!z) return z; + + // round dx down to avoid overshooting + if (dxdy < 0) + z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); + else + z->dx = STBTT_ifloor(STBTT_FIX * dxdy); + + z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); // use z->dx so when we offset later it's by the same amount + z->x -= off_x * STBTT_FIX; + + z->ey = e->y1; + z->next = 0; + z->direction = e->invert ? 1 : -1; + return z; +} +#elif STBTT_RASTERIZER_VERSION == 2 +static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) +{ + stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); + //STBTT_assert(e->y0 <= start_point); + if (!z) return z; + z->fdx = dxdy; + z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f; + z->fx = e->x0 + dxdy * (start_point - e->y0); + z->fx -= off_x; + z->direction = e->invert ? 1.0f : -1.0f; + z->sy = e->y0; + z->ey = e->y1; + z->next = 0; + return z; +} +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + +#if STBTT_RASTERIZER_VERSION == 1 +// note: this routine clips fills that extend off the edges... ideally this +// wouldn't happen, but it could happen if the truetype glyph bounding boxes +// are wrong, or if the user supplies a too-small bitmap +static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight) +{ + // non-zero winding fill + int x0=0, w=0; + + while (e) { + if (w == 0) { + // if we're currently at zero, we need to record the edge start point + x0 = e->x; w += e->direction; + } else { + int x1 = e->x; w += e->direction; + // if we went to zero, we need to draw + if (w == 0) { + int i = x0 >> STBTT_FIXSHIFT; + int j = x1 >> STBTT_FIXSHIFT; + + if (i < len && j >= 0) { + if (i == j) { + // x0,x1 are the same pixel, so compute combined coverage + scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> STBTT_FIXSHIFT); + } else { + if (i >= 0) // add antialiasing for x0 + scanline[i] = scanline[i] + (stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT); + else + i = -1; // clip + + if (j < len) // add antialiasing for x1 + scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT); + else + j = len; // clip + + for (++i; i < j; ++i) // fill pixels between x0 and x1 + scanline[i] = scanline[i] + (stbtt_uint8) max_weight; + } + } + } + } + + e = e->next; + } +} + +static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) +{ + stbtt__hheap hh = { 0, 0, 0 }; + stbtt__active_edge *active = NULL; + int y,j=0; + int max_weight = (255 / vsubsample); // weight per vertical scanline + int s; // vertical subsample index + unsigned char scanline_data[512], *scanline; + + if (result->w > 512) + scanline = (unsigned char *) STBTT_malloc(result->w, userdata); + else + scanline = scanline_data; + + y = off_y * vsubsample; + e[n].y0 = (off_y + result->h) * (float) vsubsample + 1; + + while (j < result->h) { + STBTT_memset(scanline, 0, result->w); + for (s=0; s < vsubsample; ++s) { + // find center of pixel for this scanline + float scan_y = y + 0.5f; + stbtt__active_edge **step = &active; + + // update all active edges; + // remove all active edges that terminate before the center of this scanline + while (*step) { + stbtt__active_edge * z = *step; + if (z->ey <= scan_y) { + *step = z->next; // delete from list + STBTT_assert(z->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } else { + z->x += z->dx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + } + + // resort the list if needed + for(;;) { + int changed=0; + step = &active; + while (*step && (*step)->next) { + if ((*step)->x > (*step)->next->x) { + stbtt__active_edge *t = *step; + stbtt__active_edge *q = t->next; + + t->next = q->next; + q->next = t; + *step = q; + changed = 1; + } + step = &(*step)->next; + } + if (!changed) break; + } + + // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline + while (e->y0 <= scan_y) { + if (e->y1 > scan_y) { + stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata); + if (z != NULL) { + // find insertion point + if (active == NULL) + active = z; + else if (z->x < active->x) { + // insert at front + z->next = active; + active = z; + } else { + // find thing to insert AFTER + stbtt__active_edge *p = active; + while (p->next && p->next->x < z->x) + p = p->next; + // at this point, p->next->x is NOT < z->x + z->next = p->next; + p->next = z; + } + } + } + ++e; + } + + // now process all active edges in XOR fashion + if (active) + stbtt__fill_active_edges(scanline, result->w, active, max_weight); + + ++y; + } + STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w); + ++j; + } + + stbtt__hheap_cleanup(&hh, userdata); + + if (scanline != scanline_data) + STBTT_free(scanline, userdata); +} + +#elif STBTT_RASTERIZER_VERSION == 2 + +// the edge passed in here does not cross the vertical line at x or the vertical line at x+1 +// (i.e. it has already been clipped to those) +static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1) +{ + if (y0 == y1) return; + STBTT_assert(y0 < y1); + STBTT_assert(e->sy <= e->ey); + if (y0 > e->ey) return; + if (y1 < e->sy) return; + if (y0 < e->sy) { + x0 += (x1-x0) * (e->sy - y0) / (y1-y0); + y0 = e->sy; + } + if (y1 > e->ey) { + x1 += (x1-x0) * (e->ey - y1) / (y1-y0); + y1 = e->ey; + } + + if (x0 == x) + STBTT_assert(x1 <= x+1); + else if (x0 == x+1) + STBTT_assert(x1 >= x); + else if (x0 <= x) + STBTT_assert(x1 <= x); + else if (x0 >= x+1) + STBTT_assert(x1 >= x+1); + else + STBTT_assert(x1 >= x && x1 <= x+1); + + if (x0 <= x && x1 <= x) + scanline[x] += e->direction * (y1-y0); + else if (x0 >= x+1 && x1 >= x+1) + ; + else { + STBTT_assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1); + scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); // coverage = 1 - average x position + } +} + +static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top) +{ + float y_bottom = y_top+1; + + while (e) { + // brute force every pixel + + // compute intersection points with top & bottom + STBTT_assert(e->ey >= y_top); + + if (e->fdx == 0) { + float x0 = e->fx; + if (x0 < len) { + if (x0 >= 0) { + stbtt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom); + stbtt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom); + } else { + stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom); + } + } + } else { + float x0 = e->fx; + float dx = e->fdx; + float xb = x0 + dx; + float x_top, x_bottom; + float sy0,sy1; + float dy = e->fdy; + STBTT_assert(e->sy <= y_bottom && e->ey >= y_top); + + // compute endpoints of line segment clipped to this scanline (if the + // line segment starts on this scanline. x0 is the intersection of the + // line with y_top, but that may be off the line segment. + if (e->sy > y_top) { + x_top = x0 + dx * (e->sy - y_top); + sy0 = e->sy; + } else { + x_top = x0; + sy0 = y_top; + } + if (e->ey < y_bottom) { + x_bottom = x0 + dx * (e->ey - y_top); + sy1 = e->ey; + } else { + x_bottom = xb; + sy1 = y_bottom; + } + + if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) { + // from here on, we don't have to range check x values + + if ((int) x_top == (int) x_bottom) { + float height; + // simple case, only spans one pixel + int x = (int) x_top; + height = sy1 - sy0; + STBTT_assert(x >= 0 && x < len); + scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height; + scanline_fill[x] += e->direction * height; // everything right of this pixel is filled + } else { + int x,x1,x2; + float y_crossing, step, sign, area; + // covers 2+ pixels + if (x_top > x_bottom) { + // flip scanline vertically; signed area is the same + float t; + sy0 = y_bottom - (sy0 - y_top); + sy1 = y_bottom - (sy1 - y_top); + t = sy0, sy0 = sy1, sy1 = t; + t = x_bottom, x_bottom = x_top, x_top = t; + dx = -dx; + dy = -dy; + t = x0, x0 = xb, xb = t; + } + + x1 = (int) x_top; + x2 = (int) x_bottom; + // compute intersection with y axis at x1+1 + y_crossing = (x1+1 - x0) * dy + y_top; + + sign = e->direction; + // area of the rectangle covered from y0..y_crossing + area = sign * (y_crossing-sy0); + // area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) + scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2); + + step = sign * dy; + for (x = x1+1; x < x2; ++x) { + scanline[x] += area + step/2; + area += step; + } + y_crossing += dy * (x2 - (x1+1)); + + STBTT_assert(fabs(area) <= 1.01f); + + scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing); + + scanline_fill[x2] += sign * (sy1-sy0); + } + } else { + // if edge goes outside of box we're drawing, we require + // clipping logic. since this does not match the intended use + // of this library, we use a different, very slow brute + // force implementation + int x; + for (x=0; x < len; ++x) { + // cases: + // + // there can be up to two intersections with the pixel. any intersection + // with left or right edges can be handled by splitting into two (or three) + // regions. intersections with top & bottom do not necessitate case-wise logic. + // + // the old way of doing this found the intersections with the left & right edges, + // then used some simple logic to produce up to three segments in sorted order + // from top-to-bottom. however, this had a problem: if an x edge was epsilon + // across the x border, then the corresponding y position might not be distinct + // from the other y segment, and it might ignored as an empty segment. to avoid + // that, we need to explicitly produce segments based on x positions. + + // rename variables to clear pairs + float y0 = y_top; + float x1 = (float) (x); + float x2 = (float) (x+1); + float x3 = xb; + float y3 = y_bottom; + float y1,y2; + + // x = e->x + e->dx * (y-y_top) + // (y-y_top) = (x - e->x) / e->dx + // y = (x - e->x) / e->dx + y_top + y1 = (x - x0) / dx + y_top; + y2 = (x+1 - x0) / dx + y_top; + + if (x0 < x1 && x3 > x2) { // three segments descending down-right + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else if (x3 < x1 && x0 > x2) { // three segments descending down-left + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x0 < x1 && x3 > x1) { // two segments across x, down-right + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x3 < x1 && x0 > x1) { // two segments across x, down-left + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x0 < x2 && x3 > x2) { // two segments across x+1, down-right + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else if (x3 < x2 && x0 > x2) { // two segments across x+1, down-left + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else { // one segment + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x3,y3); + } + } + } + } + e = e->next; + } +} + +// directly AA rasterize edges w/o supersampling +static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) +{ + stbtt__hheap hh = { 0, 0, 0 }; + stbtt__active_edge *active = NULL; + int y,j=0, i; + float scanline_data[129], *scanline, *scanline2; + + if (result->w > 64) + scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata); + else + scanline = scanline_data; + + scanline2 = scanline + result->w; + + y = off_y; + e[n].y0 = (float) (off_y + result->h) + 1; + + while (j < result->h) { + // find center of pixel for this scanline + float scan_y_top = y + 0.0f; + float scan_y_bottom = y + 1.0f; + stbtt__active_edge **step = &active; + + STBTT_memset(scanline , 0, result->w*sizeof(scanline[0])); + STBTT_memset(scanline2, 0, (result->w+1)*sizeof(scanline[0])); + + // update all active edges; + // remove all active edges that terminate before the top of this scanline + while (*step) { + stbtt__active_edge * z = *step; + if (z->ey <= scan_y_top) { + *step = z->next; // delete from list + STBTT_assert(z->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } else { + step = &((*step)->next); // advance through list + } + } + + // insert all edges that start before the bottom of this scanline + while (e->y0 <= scan_y_bottom) { + if (e->y0 != e->y1) { + stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); + if (z != NULL) { + STBTT_assert(z->ey >= scan_y_top); + // insert at front + z->next = active; + active = z; + } + } + ++e; + } + + // now process all active edges + if (active) + stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top); + + { + float sum = 0; + for (i=0; i < result->w; ++i) { + float k; + int m; + sum += scanline2[i]; + k = scanline[i] + sum; + k = (float) fabs(k)*255 + 0.5f; + m = (int) k; + if (m > 255) m = 255; + result->pixels[j*result->stride + i] = (unsigned char) m; + } + } + // advance all the edges + step = &active; + while (*step) { + stbtt__active_edge *z = *step; + z->fx += z->fdx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + + ++y; + ++j; + } + + stbtt__hheap_cleanup(&hh, userdata); + + if (scanline != scanline_data) + STBTT_free(scanline, userdata); +} +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + +#define STBTT__COMPARE(a,b) ((a)->y0 < (b)->y0) + +static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n) +{ + int i,j; + for (i=1; i < n; ++i) { + stbtt__edge t = p[i], *a = &t; + j = i; + while (j > 0) { + stbtt__edge *b = &p[j-1]; + int c = STBTT__COMPARE(a,b); + if (!c) break; + p[j] = p[j-1]; + --j; + } + if (i != j) + p[j] = t; + } +} + +static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n) +{ + /* threshhold for transitioning to insertion sort */ + while (n > 12) { + stbtt__edge t; + int c01,c12,c,m,i,j; + + /* compute median of three */ + m = n >> 1; + c01 = STBTT__COMPARE(&p[0],&p[m]); + c12 = STBTT__COMPARE(&p[m],&p[n-1]); + /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ + if (c01 != c12) { + /* otherwise, we'll need to swap something else to middle */ + int z; + c = STBTT__COMPARE(&p[0],&p[n-1]); + /* 0>mid && midn => n; 0 0 */ + /* 0n: 0>n => 0; 0 n */ + z = (c == c12) ? 0 : n-1; + t = p[z]; + p[z] = p[m]; + p[m] = t; + } + /* now p[m] is the median-of-three */ + /* swap it to the beginning so it won't move around */ + t = p[0]; + p[0] = p[m]; + p[m] = t; + + /* partition loop */ + i=1; + j=n-1; + for(;;) { + /* handling of equality is crucial here */ + /* for sentinels & efficiency with duplicates */ + for (;;++i) { + if (!STBTT__COMPARE(&p[i], &p[0])) break; + } + for (;;--j) { + if (!STBTT__COMPARE(&p[0], &p[j])) break; + } + /* make sure we haven't crossed */ + if (i >= j) break; + t = p[i]; + p[i] = p[j]; + p[j] = t; + + ++i; + --j; + } + /* recurse on smaller side, iterate on larger */ + if (j < (n-i)) { + stbtt__sort_edges_quicksort(p,j); + p = p+i; + n = n-i; + } else { + stbtt__sort_edges_quicksort(p+i, n-i); + n = j; + } + } +} + +static void stbtt__sort_edges(stbtt__edge *p, int n) +{ + stbtt__sort_edges_quicksort(p, n); + stbtt__sort_edges_ins_sort(p, n); +} + +typedef struct +{ + float x,y; +} stbtt__point; + +static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata) +{ + float y_scale_inv = invert ? -scale_y : scale_y; + stbtt__edge *e; + int n,i,j,k,m; +#if STBTT_RASTERIZER_VERSION == 1 + int vsubsample = result->h < 8 ? 15 : 5; +#elif STBTT_RASTERIZER_VERSION == 2 + int vsubsample = 1; +#else + #error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + // vsubsample should divide 255 evenly; otherwise we won't reach full opacity + + // now we have to blow out the windings into explicit edge lists + n = 0; + for (i=0; i < windings; ++i) + n += wcount[i]; + + e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel + if (e == 0) return; + n = 0; + + m=0; + for (i=0; i < windings; ++i) { + stbtt__point *p = pts + m; + m += wcount[i]; + j = wcount[i]-1; + for (k=0; k < wcount[i]; j=k++) { + int a=k,b=j; + // skip the edge if horizontal + if (p[j].y == p[k].y) + continue; + // add edge from j to k to the list + e[n].invert = 0; + if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) { + e[n].invert = 1; + a=j,b=k; + } + e[n].x0 = p[a].x * scale_x + shift_x; + e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample; + e[n].x1 = p[b].x * scale_x + shift_x; + e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample; + ++n; + } + } + + // now sort the edges by their highest point (should snap to integer, and then by x) + //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); + stbtt__sort_edges(e, n); + + // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule + stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); + + STBTT_free(e, userdata); +} + +static void stbtt__add_point(stbtt__point *points, int n, float x, float y) +{ + if (!points) return; // during first pass, it's unallocated + points[n].x = x; + points[n].y = y; +} + +// tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching +static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n) +{ + // midpoint + float mx = (x0 + 2*x1 + x2)/4; + float my = (y0 + 2*y1 + y2)/4; + // versus directly drawn line + float dx = (x0+x2)/2 - mx; + float dy = (y0+y2)/2 - my; + if (n > 16) // 65536 segments on one curve better be enough! + return 1; + if (dx*dx+dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA + stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1); + stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1); + } else { + stbtt__add_point(points, *num_points,x2,y2); + *num_points = *num_points+1; + } + return 1; +} + +// returns number of contours +static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) +{ + stbtt__point *points=0; + int num_points=0; + + float objspace_flatness_squared = objspace_flatness * objspace_flatness; + int i,n=0,start=0, pass; + + // count how many "moves" there are to get the contour count + for (i=0; i < num_verts; ++i) + if (vertices[i].type == STBTT_vmove) + ++n; + + *num_contours = n; + if (n == 0) return 0; + + *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata); + + if (*contour_lengths == 0) { + *num_contours = 0; + return 0; + } + + // make two passes through the points so we don't need to realloc + for (pass=0; pass < 2; ++pass) { + float x=0,y=0; + if (pass == 1) { + points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata); + if (points == NULL) goto error; + } + num_points = 0; + n= -1; + for (i=0; i < num_verts; ++i) { + switch (vertices[i].type) { + case STBTT_vmove: + // start the next contour + if (n >= 0) + (*contour_lengths)[n] = num_points - start; + ++n; + start = num_points; + + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x,y); + break; + case STBTT_vline: + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x, y); + break; + case STBTT_vcurve: + stbtt__tesselate_curve(points, &num_points, x,y, + vertices[i].cx, vertices[i].cy, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x, y = vertices[i].y; + break; + } + } + (*contour_lengths)[n] = num_points - start; + } + + return points; +error: + STBTT_free(points, userdata); + STBTT_free(*contour_lengths, userdata); + *contour_lengths = 0; + *num_contours = 0; + return NULL; +} + +STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata) +{ + float scale = scale_x > scale_y ? scale_y : scale_x; + int winding_count, *winding_lengths; + stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); + if (windings) { + stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); + STBTT_free(winding_lengths, userdata); + STBTT_free(windings, userdata); + } +} + +STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata) +{ + STBTT_free(bitmap, userdata); +} + +STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff) +{ + int ix0,iy0,ix1,iy1; + stbtt__bitmap gbm; + stbtt_vertex *vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + + if (scale_x == 0) scale_x = scale_y; + if (scale_y == 0) { + if (scale_x == 0) return NULL; + scale_y = scale_x; + } + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1); + + // now we get the size + gbm.w = (ix1 - ix0); + gbm.h = (iy1 - iy0); + gbm.pixels = NULL; // in case we error + + if (width ) *width = gbm.w; + if (height) *height = gbm.h; + if (xoff ) *xoff = ix0; + if (yoff ) *yoff = iy0; + + if (gbm.w && gbm.h) { + gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata); + if (gbm.pixels) { + gbm.stride = gbm.w; + + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); + } + } + STBTT_free(vertices, info->userdata); + return gbm.pixels; +} + +STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff); +} + +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph) +{ + int ix0,iy0; + stbtt_vertex *vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + stbtt__bitmap gbm; + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0); + gbm.pixels = output; + gbm.w = out_w; + gbm.h = out_h; + gbm.stride = out_stride; + + if (gbm.w && gbm.h) + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata); + + STBTT_free(vertices, info->userdata); +} + +STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph) +{ + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph); +} + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); +} + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint) +{ + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint)); +} + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff); +} + +STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint) +{ + stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint); +} + +////////////////////////////////////////////////////////////////////////////// +// +// bitmap baking +// +// This is SUPER-CRAPPY packing to keep source code small + +STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) + float pixel_height, // height of font in pixels + unsigned char *pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar *chardata) +{ + float scale; + int x,y,bottom_y, i; + stbtt_fontinfo f; + f.userdata = NULL; + if (!stbtt_InitFont(&f, data, offset)) + return -1; + STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + x=y=1; + bottom_y = 1; + + scale = stbtt_ScaleForPixelHeight(&f, pixel_height); + + for (i=0; i < num_chars; ++i) { + int advance, lsb, x0,y0,x1,y1,gw,gh; + int g = stbtt_FindGlyphIndex(&f, first_char + i); + stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb); + stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1); + gw = x1-x0; + gh = y1-y0; + if (x + gw + 1 >= pw) + y = bottom_y, x = 1; // advance to next row + if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row + return -i; + STBTT_assert(x+gw < pw); + STBTT_assert(y+gh < ph); + stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g); + chardata[i].x0 = (stbtt_int16) x; + chardata[i].y0 = (stbtt_int16) y; + chardata[i].x1 = (stbtt_int16) (x + gw); + chardata[i].y1 = (stbtt_int16) (y + gh); + chardata[i].xadvance = scale * advance; + chardata[i].xoff = (float) x0; + chardata[i].yoff = (float) y0; + x = x + gw + 1; + if (y+gh+1 > bottom_y) + bottom_y = y+gh+1; + } + return bottom_y; +} + +STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) +{ + float d3d_bias = opengl_fillrule ? 0 : -0.5f; + float ipw = 1.0f / pw, iph = 1.0f / ph; + stbtt_bakedchar *b = chardata + char_index; + int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f); + int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f); + + q->x0 = round_x + d3d_bias; + q->y0 = round_y + d3d_bias; + q->x1 = round_x + b->x1 - b->x0 + d3d_bias; + q->y1 = round_y + b->y1 - b->y0 + d3d_bias; + + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; + + *xpos += b->xadvance; +} + +////////////////////////////////////////////////////////////////////////////// +// +// rectangle packing replacement routines if you don't have stb_rect_pack.h +// + +#ifndef STB_RECT_PACK_VERSION +#ifdef _MSC_VER +#define STBTT__NOTUSED(v) (void)(v) +#else +#define STBTT__NOTUSED(v) (void)sizeof(v) +#endif + +typedef int stbrp_coord; + +//////////////////////////////////////////////////////////////////////////////////// +// // +// // +// COMPILER WARNING ?!?!? // +// // +// // +// if you get a compile warning due to these symbols being defined more than // +// once, move #include "stb_rect_pack.h" before #include "stb_truetype.h" // +// // +//////////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + int width,height; + int x,y,bottom_y; +} stbrp_context; + +typedef struct +{ + unsigned char x; +} stbrp_node; + +struct stbrp_rect +{ + stbrp_coord x,y; + int id,w,h,was_packed; +}; + +static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes) +{ + con->width = pw; + con->height = ph; + con->x = 0; + con->y = 0; + con->bottom_y = 0; + STBTT__NOTUSED(nodes); + STBTT__NOTUSED(num_nodes); +} + +static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) +{ + int i; + for (i=0; i < num_rects; ++i) { + if (con->x + rects[i].w > con->width) { + con->x = 0; + con->y = con->bottom_y; + } + if (con->y + rects[i].h > con->height) + break; + rects[i].x = con->x; + rects[i].y = con->y; + rects[i].was_packed = 1; + con->x += rects[i].w; + if (con->y + rects[i].h > con->bottom_y) + con->bottom_y = con->y + rects[i].h; + } + for ( ; i < num_rects; ++i) + rects[i].was_packed = 0; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// bitmap baking +// +// This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If +// stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy. + +STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context) +{ + stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context); + int num_nodes = pw - padding; + stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context); + + if (context == NULL || nodes == NULL) { + if (context != NULL) STBTT_free(context, alloc_context); + if (nodes != NULL) STBTT_free(nodes , alloc_context); + return 0; + } + + spc->user_allocator_context = alloc_context; + spc->width = pw; + spc->height = ph; + spc->pixels = pixels; + spc->pack_info = context; + spc->nodes = nodes; + spc->padding = padding; + spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; + spc->h_oversample = 1; + spc->v_oversample = 1; + + stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); + + if (pixels) + STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + + return 1; +} + +STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc) +{ + STBTT_free(spc->nodes , spc->user_allocator_context); + STBTT_free(spc->pack_info, spc->user_allocator_context); +} + +STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample) +{ + STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE); + STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE); + if (h_oversample <= STBTT_MAX_OVERSAMPLE) + spc->h_oversample = h_oversample; + if (v_oversample <= STBTT_MAX_OVERSAMPLE) + spc->v_oversample = v_oversample; +} + +#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1) + +static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) +{ + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_w = w - kernel_width; + int j; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze + for (j=0; j < h; ++j) { + int i; + unsigned int total; + STBTT_memset(buffer, 0, kernel_width); + + total = 0; + + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch (kernel_width) { + case 2: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 2); + } + break; + case 3: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 3); + } + break; + case 4: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 4); + } + break; + case 5: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 5); + } + break; + default: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / kernel_width); + } + break; + } + + for (; i < w; ++i) { + STBTT_assert(pixels[i] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i] = (unsigned char) (total / kernel_width); + } + + pixels += stride_in_bytes; + } +} + +static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) +{ + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_h = h - kernel_width; + int j; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze + for (j=0; j < w; ++j) { + int i; + unsigned int total; + STBTT_memset(buffer, 0, kernel_width); + + total = 0; + + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch (kernel_width) { + case 2: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 2); + } + break; + case 3: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 3); + } + break; + case 4: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 4); + } + break; + case 5: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 5); + } + break; + default: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); + } + break; + } + + for (; i < h; ++i) { + STBTT_assert(pixels[i*stride_in_bytes] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); + } + + pixels += 1; + } +} + +static float stbtt__oversample_shift(int oversample) +{ + if (!oversample) + return 0.0f; + + // The prefilter is a box filter of width "oversample", + // which shifts phase by (oversample - 1)/2 pixels in + // oversampled space. We want to shift in the opposite + // direction to counter this. + return (float)-(oversample - 1) / (2.0f * (float)oversample); +} + +// rects array must be big enough to accommodate all characters in the given ranges +STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) +{ + int i,j,k; + + k=0; + for (i=0; i < num_ranges; ++i) { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); + ranges[i].h_oversample = (unsigned char) spc->h_oversample; + ranges[i].v_oversample = (unsigned char) spc->v_oversample; + for (j=0; j < ranges[i].num_chars; ++j) { + int x0,y0,x1,y1; + int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; + int glyph = stbtt_FindGlyphIndex(info, codepoint); + stbtt_GetGlyphBitmapBoxSubpixel(info,glyph, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0,0, + &x0,&y0,&x1,&y1); + rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1); + rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1); + ++k; + } + } + + return k; +} + +// rects array must be big enough to accommodate all characters in the given ranges +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) +{ + int i,j,k, return_value = 1; + + // save current values + int old_h_over = spc->h_oversample; + int old_v_over = spc->v_oversample; + + k = 0; + for (i=0; i < num_ranges; ++i) { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); + float recip_h,recip_v,sub_x,sub_y; + spc->h_oversample = ranges[i].h_oversample; + spc->v_oversample = ranges[i].v_oversample; + recip_h = 1.0f / spc->h_oversample; + recip_v = 1.0f / spc->v_oversample; + sub_x = stbtt__oversample_shift(spc->h_oversample); + sub_y = stbtt__oversample_shift(spc->v_oversample); + for (j=0; j < ranges[i].num_chars; ++j) { + stbrp_rect *r = &rects[k]; + if (r->was_packed) { + stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; + int advance, lsb, x0,y0,x1,y1; + int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; + int glyph = stbtt_FindGlyphIndex(info, codepoint); + stbrp_coord pad = (stbrp_coord) spc->padding; + + // pad on left and top + r->x += pad; + r->y += pad; + r->w -= pad; + r->h -= pad; + stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb); + stbtt_GetGlyphBitmapBox(info, glyph, + scale * spc->h_oversample, + scale * spc->v_oversample, + &x0,&y0,&x1,&y1); + stbtt_MakeGlyphBitmapSubpixel(info, + spc->pixels + r->x + r->y*spc->stride_in_bytes, + r->w - spc->h_oversample+1, + r->h - spc->v_oversample+1, + spc->stride_in_bytes, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0,0, + glyph); + + if (spc->h_oversample > 1) + stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->h_oversample); + + if (spc->v_oversample > 1) + stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->v_oversample); + + bc->x0 = (stbtt_int16) r->x; + bc->y0 = (stbtt_int16) r->y; + bc->x1 = (stbtt_int16) (r->x + r->w); + bc->y1 = (stbtt_int16) (r->y + r->h); + bc->xadvance = scale * advance; + bc->xoff = (float) x0 * recip_h + sub_x; + bc->yoff = (float) y0 * recip_v + sub_y; + bc->xoff2 = (x0 + r->w) * recip_h + sub_x; + bc->yoff2 = (y0 + r->h) * recip_v + sub_y; + } else { + return_value = 0; // if any fail, report failure + } + + ++k; + } + } + + // restore original values + spc->h_oversample = old_h_over; + spc->v_oversample = old_v_over; + + return return_value; +} + +STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects) +{ + stbrp_pack_rects((stbrp_context *) spc->pack_info, rects, num_rects); +} + +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) +{ + stbtt_fontinfo info; + int i,j,n, return_value = 1; + //stbrp_context *context = (stbrp_context *) spc->pack_info; + stbrp_rect *rects; + + // flag all characters as NOT packed + for (i=0; i < num_ranges; ++i) + for (j=0; j < ranges[i].num_chars; ++j) + ranges[i].chardata_for_range[j].x0 = + ranges[i].chardata_for_range[j].y0 = + ranges[i].chardata_for_range[j].x1 = + ranges[i].chardata_for_range[j].y1 = 0; + + n = 0; + for (i=0; i < num_ranges; ++i) + n += ranges[i].num_chars; + + rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); + if (rects == NULL) + return 0; + + info.userdata = spc->user_allocator_context; + stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index)); + + n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); + + stbtt_PackFontRangesPackRects(spc, rects, n); + + return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); + + STBTT_free(rects, spc->user_allocator_context); + return return_value; +} + +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, + int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) +{ + stbtt_pack_range range; + range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range; + range.array_of_unicode_codepoints = NULL; + range.num_chars = num_chars_in_range; + range.chardata_for_range = chardata_for_range; + range.font_size = font_size; + return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); +} + +STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) +{ + float ipw = 1.0f / pw, iph = 1.0f / ph; + stbtt_packedchar *b = chardata + char_index; + + if (align_to_integer) { + float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f); + float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5f); + q->x0 = x; + q->y0 = y; + q->x1 = x + b->xoff2 - b->xoff; + q->y1 = y + b->yoff2 - b->yoff; + } else { + q->x0 = *xpos + b->xoff; + q->y0 = *ypos + b->yoff; + q->x1 = *xpos + b->xoff2; + q->y1 = *ypos + b->yoff2; + } + + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; + + *xpos += b->xadvance; +} + + +////////////////////////////////////////////////////////////////////////////// +// +// font name matching -- recommended not to use this +// + +// check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string +static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2) +{ + stbtt_int32 i=0; + + // convert utf16 to utf8 and compare the results while converting + while (len2) { + stbtt_uint16 ch = s2[0]*256 + s2[1]; + if (ch < 0x80) { + if (i >= len1) return -1; + if (s1[i++] != ch) return -1; + } else if (ch < 0x800) { + if (i+1 >= len1) return -1; + if (s1[i++] != 0xc0 + (ch >> 6)) return -1; + if (s1[i++] != 0x80 + (ch & 0x3f)) return -1; + } else if (ch >= 0xd800 && ch < 0xdc00) { + stbtt_uint32 c; + stbtt_uint16 ch2 = s2[2]*256 + s2[3]; + if (i+3 >= len1) return -1; + c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000; + if (s1[i++] != 0xf0 + (c >> 18)) return -1; + if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((c ) & 0x3f)) return -1; + s2 += 2; // plus another 2 below + len2 -= 2; + } else if (ch >= 0xdc00 && ch < 0xe000) { + return -1; + } else { + if (i+2 >= len1) return -1; + if (s1[i++] != 0xe0 + (ch >> 12)) return -1; + if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((ch ) & 0x3f)) return -1; + } + s2 += 2; + len2 -= 2; + } + return i; +} + +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) +{ + return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8*) s1, len1, (const stbtt_uint8*) s2, len2); +} + +// returns results in whatever encoding you request... but note that 2-byte encodings +// will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare +STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID) +{ + stbtt_int32 i,count,stringOffset; + stbtt_uint8 *fc = font->data; + stbtt_uint32 offset = font->fontstart; + stbtt_uint32 nm = stbtt__find_table(fc, offset, "name"); + if (!nm) return NULL; + + count = ttUSHORT(fc+nm+2); + stringOffset = nm + ttUSHORT(fc+nm+4); + for (i=0; i < count; ++i) { + stbtt_uint32 loc = nm + 6 + 12 * i; + if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2) + && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) { + *length = ttUSHORT(fc+loc+8); + return (const char *) (fc+stringOffset+ttUSHORT(fc+loc+10)); + } + } + return NULL; +} + +static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id) +{ + stbtt_int32 i; + stbtt_int32 count = ttUSHORT(fc+nm+2); + stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4); + + for (i=0; i < count; ++i) { + stbtt_uint32 loc = nm + 6 + 12 * i; + stbtt_int32 id = ttUSHORT(fc+loc+6); + if (id == target_id) { + // find the encoding + stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4); + + // is this a Unicode encoding? + if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) { + stbtt_int32 slen = ttUSHORT(fc+loc+8); + stbtt_int32 off = ttUSHORT(fc+loc+10); + + // check if there's a prefix match + stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen); + if (matchlen >= 0) { + // check for target_id+1 immediately following, with same encoding & language + if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) { + slen = ttUSHORT(fc+loc+12+8); + off = ttUSHORT(fc+loc+12+10); + if (slen == 0) { + if (matchlen == nlen) + return 1; + } else if (matchlen < nlen && name[matchlen] == ' ') { + ++matchlen; + if (stbtt_CompareUTF8toUTF16_bigendian((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen)) + return 1; + } + } else { + // if nothing immediately following + if (matchlen == nlen) + return 1; + } + } + } + + // @TODO handle other encodings + } + } + return 0; +} + +static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags) +{ + stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name); + stbtt_uint32 nm,hd; + if (!stbtt__isfont(fc+offset)) return 0; + + // check italics/bold/underline flags in macStyle... + if (flags) { + hd = stbtt__find_table(fc, offset, "head"); + if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0; + } + + nm = stbtt__find_table(fc, offset, "name"); + if (!nm) return 0; + + if (flags) { + // if we checked the macStyle flags, then just check the family and ignore the subfamily + if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } else { + if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } + + return 0; +} + +STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *name_utf8, stbtt_int32 flags) +{ + stbtt_int32 i; + for (i=0;;++i) { + stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i); + if (off < 0) return off; + if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags)) + return off; + } +} + +#endif // STB_TRUETYPE_IMPLEMENTATION + + +// FULL VERSION HISTORY +// +// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges +// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges +// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; +// allow PackFontRanges to pack and render in separate phases; +// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?); +// fixed an assert() bug in the new rasterizer +// replace assert() with STBTT_assert() in new rasterizer +// 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine) +// also more precise AA rasterizer, except if shapes overlap +// remove need for STBTT_sort +// 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC +// 1.04 (2015-04-15) typo in example +// 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes +// 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++ +// 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match +// non-oversampled; STBTT_POINT_SIZE for packed case only +// 1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling +// 0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg) +// 0.9 (2014-08-07) support certain mac/iOS fonts without an MS platformID +// 0.8b (2014-07-07) fix a warning +// 0.8 (2014-05-25) fix a few more warnings +// 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back +// 0.6c (2012-07-24) improve documentation +// 0.6b (2012-07-20) fix a few more warnings +// 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels, +// stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty +// 0.5 (2011-12-09) bugfixes: +// subpixel glyph renderer computed wrong bounding box +// first vertex of shape can be off-curve (FreeSans) +// 0.4b (2011-12-03) fixed an error in the font baking example +// 0.4 (2011-12-01) kerning, subpixel rendering (tor) +// bugfixes for: +// codepoint-to-glyph conversion using table fmt=12 +// codepoint-to-glyph conversion using table fmt=4 +// stbtt_GetBakedQuad with non-square texture (Zer) +// updated Hello World! sample to use kerning and subpixel +// fixed some warnings +// 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM) +// userdata, malloc-from-userdata, non-zero fill (stb) +// 0.2 (2009-03-11) Fix unsigned/signed char warnings +// 0.1 (2009-03-09) First public release +// diff --git a/CameraParameterEstimation/apps/basics/extern/tiny_dir.h b/CameraParameterEstimation/apps/basics/extern/tiny_dir.h new file mode 100644 index 0000000..bac4521 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/tiny_dir.h @@ -0,0 +1,559 @@ +/* +Copyright (c) 2013-2015, Cong Xu, Baudouin Feildel +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. 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. + +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. +*/ +#ifndef TINYDIR_H +#define TINYDIR_H + +#include +#include +#include +#ifdef _MSC_VER +# define WIN32_LEAN_AND_MEAN +# include +# pragma warning (disable : 4996) +#else +# include +# include +# include +#endif + + +/* types */ + +#define _TINYDIR_PATH_MAX 4096 +#ifdef _MSC_VER +/* extra chars for the "\\*" mask */ +# define _TINYDIR_PATH_EXTRA 2 +#else +# define _TINYDIR_PATH_EXTRA 0 +#endif +#define _TINYDIR_FILENAME_MAX 256 + +#ifdef _MSC_VER +# define _TINYDIR_FUNC static __inline +#else +# define _TINYDIR_FUNC static __inline__ +#endif + +/* Allow user to use a custom allocator by defining _TINYDIR_MALLOC and _TINYDIR_FREE. */ +#if defined(_TINYDIR_MALLOC) && defined(_TINYDIR_FREE) +#elif !defined(_TINYDIR_MALLOC) && !defined(_TINYDIR_FREE) +#else +#error "Either define both alloc and free or none of them!" +#endif + +#if !defined(_TINYDIR_MALLOC) + #define _TINYDIR_MALLOC(_size) malloc(_size) + #define _TINYDIR_FREE(_ptr) free(_ptr) +#endif //!defined(_TINYDIR_MALLOC) + +typedef struct +{ + char path[_TINYDIR_PATH_MAX]; + char name[_TINYDIR_FILENAME_MAX]; + char *extension; + int is_dir; + int is_reg; + +#ifndef _MSC_VER + struct stat _s; +#endif +} tinydir_file; + +typedef struct +{ + char path[_TINYDIR_PATH_MAX]; + int has_next; + size_t n_files; + + tinydir_file *_files; +#ifdef _MSC_VER + HANDLE _h; + WIN32_FIND_DATAA _f; +#else + DIR *_d; + struct dirent *_e; +#endif +} tinydir_dir; + + +/* declarations */ + +_TINYDIR_FUNC +int tinydir_open(tinydir_dir *dir, const char *path); +_TINYDIR_FUNC +int tinydir_open_sorted(tinydir_dir *dir, const char *path); +_TINYDIR_FUNC +void tinydir_close(tinydir_dir *dir); + +_TINYDIR_FUNC +int tinydir_next(tinydir_dir *dir); +_TINYDIR_FUNC +int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file); +_TINYDIR_FUNC +int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i); +_TINYDIR_FUNC +int tinydir_open_subdir_n(tinydir_dir *dir, size_t i); + +_TINYDIR_FUNC +void _tinydir_get_ext(tinydir_file *file); +_TINYDIR_FUNC +int _tinydir_file_cmp(const void *a, const void *b); + + +/* definitions*/ + +_TINYDIR_FUNC +int tinydir_open(tinydir_dir *dir, const char *path) +{ + if (dir == NULL || path == NULL || strlen(path) == 0) + { + errno = EINVAL; + return -1; + } + if (strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX) + { + errno = ENAMETOOLONG; + return -1; + } + + /* initialise dir */ + dir->_files = NULL; +#ifdef _MSC_VER + dir->_h = INVALID_HANDLE_VALUE; +#else + dir->_d = NULL; +#endif + tinydir_close(dir); + + strcpy(dir->path, path); +#ifdef _MSC_VER + strcat(dir->path, "\\*"); + dir->_h = FindFirstFileA(dir->path, &dir->_f); + dir->path[strlen(dir->path) - 2] = '\0'; + if (dir->_h == INVALID_HANDLE_VALUE) +#else + dir->_d = opendir(path); + if (dir->_d == NULL) +#endif + { + errno = ENOENT; + goto bail; + } + + /* read first file */ + dir->has_next = 1; +#ifndef _MSC_VER + dir->_e = readdir(dir->_d); + if (dir->_e == NULL) + { + dir->has_next = 0; + } +#endif + + return 0; + +bail: + tinydir_close(dir); + return -1; +} + +_TINYDIR_FUNC +int tinydir_open_sorted(tinydir_dir *dir, const char *path) +{ + /* Count the number of files first, to pre-allocate the files array */ + size_t n_files = 0; + if (tinydir_open(dir, path) == -1) + { + return -1; + } + while (dir->has_next) + { + n_files++; + if (tinydir_next(dir) == -1) + { + goto bail; + } + } + tinydir_close(dir); + + if (tinydir_open(dir, path) == -1) + { + return -1; + } + + dir->n_files = 0; + dir->_files = (tinydir_file *)_TINYDIR_MALLOC(sizeof *dir->_files * n_files); + if (dir->_files == NULL) + { + errno = ENOMEM; + goto bail; + } + while (dir->has_next) + { + tinydir_file *p_file; + dir->n_files++; + + p_file = &dir->_files[dir->n_files - 1]; + if (tinydir_readfile(dir, p_file) == -1) + { + goto bail; + } + + if (tinydir_next(dir) == -1) + { + goto bail; + } + + /* Just in case the number of files has changed between the first and + second reads, terminate without writing into unallocated memory */ + if (dir->n_files == n_files) + { + break; + } + } + + qsort(dir->_files, dir->n_files, sizeof(tinydir_file), _tinydir_file_cmp); + + return 0; + +bail: + tinydir_close(dir); + return -1; +} + +_TINYDIR_FUNC +void tinydir_close(tinydir_dir *dir) +{ + if (dir == NULL) + { + return; + } + + memset(dir->path, 0, sizeof(dir->path)); + dir->has_next = 0; + dir->n_files = 0; + if (dir->_files != NULL) + { + _TINYDIR_FREE(dir->_files); + } + dir->_files = NULL; +#ifdef _MSC_VER + if (dir->_h != INVALID_HANDLE_VALUE) + { + FindClose(dir->_h); + } + dir->_h = INVALID_HANDLE_VALUE; +#else + if (dir->_d) + { + closedir(dir->_d); + } + dir->_d = NULL; + dir->_e = NULL; +#endif +} + +_TINYDIR_FUNC +int tinydir_next(tinydir_dir *dir) +{ + if (dir == NULL) + { + errno = EINVAL; + return -1; + } + if (!dir->has_next) + { + errno = ENOENT; + return -1; + } + +#ifdef _MSC_VER + if (FindNextFileA(dir->_h, &dir->_f) == 0) +#else + dir->_e = readdir(dir->_d); + if (dir->_e == NULL) +#endif + { + dir->has_next = 0; +#ifdef _MSC_VER + if (GetLastError() != ERROR_SUCCESS && + GetLastError() != ERROR_NO_MORE_FILES) + { + tinydir_close(dir); + errno = EIO; + return -1; + } +#endif + } + + return 0; +} + +_TINYDIR_FUNC +int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file) +{ + if (dir == NULL || file == NULL) + { + errno = EINVAL; + return -1; + } +#ifdef _MSC_VER + if (dir->_h == INVALID_HANDLE_VALUE) +#else + if (dir->_e == NULL) +#endif + { + errno = ENOENT; + return -1; + } + if (strlen(dir->path) + + strlen( +#ifdef _MSC_VER + dir->_f.cFileName +#else + dir->_e->d_name +#endif + ) + 1 + _TINYDIR_PATH_EXTRA >= + _TINYDIR_PATH_MAX) + { + /* the path for the file will be too long */ + errno = ENAMETOOLONG; + return -1; + } + if (strlen( +#ifdef _MSC_VER + dir->_f.cFileName +#else + dir->_e->d_name +#endif + ) >= _TINYDIR_FILENAME_MAX) + { + errno = ENAMETOOLONG; + return -1; + } + + strcpy(file->path, dir->path); + strcat(file->path, "/"); + strcpy(file->name, +#ifdef _MSC_VER + dir->_f.cFileName +#else + dir->_e->d_name +#endif + ); + strcat(file->path, file->name); +#ifndef _MSC_VER + if (stat(file->path, &file->_s) == -1) + { + return -1; + } +#endif + _tinydir_get_ext(file); + + file->is_dir = +#ifdef _MSC_VER + !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); +#else + S_ISDIR(file->_s.st_mode); +#endif + file->is_reg = +#ifdef _MSC_VER + !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) || + ( + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) && + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) && +#ifdef FILE_ATTRIBUTE_INTEGRITY_STREAM + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_INTEGRITY_STREAM) && +#endif +#ifdef FILE_ATTRIBUTE_NO_SCRUB_DATA + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NO_SCRUB_DATA) && +#endif + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) && + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY)); +#else + S_ISREG(file->_s.st_mode); +#endif + + return 0; +} + +_TINYDIR_FUNC +int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i) +{ + if (dir == NULL || file == NULL) + { + errno = EINVAL; + return -1; + } + if (i >= dir->n_files) + { + errno = ENOENT; + return -1; + } + + memcpy(file, &dir->_files[i], sizeof(tinydir_file)); + _tinydir_get_ext(file); + + return 0; +} + +_TINYDIR_FUNC +int tinydir_open_subdir_n(tinydir_dir *dir, size_t i) +{ + char path[_TINYDIR_PATH_MAX]; + if (dir == NULL) + { + errno = EINVAL; + return -1; + } + if (i >= dir->n_files || !dir->_files[i].is_dir) + { + errno = ENOENT; + return -1; + } + + strcpy(path, dir->_files[i].path); + tinydir_close(dir); + if (tinydir_open_sorted(dir, path) == -1) + { + return -1; + } + + return 0; +} + +/* Open a single file given its path */ +_TINYDIR_FUNC +int tinydir_file_open(tinydir_file *file, const char *path) +{ + tinydir_dir dir; + int result = 0; + int found = 0; + char dir_name_buf[_TINYDIR_PATH_MAX]; + char file_name_buf[_TINYDIR_FILENAME_MAX]; + char *dir_name; + char *base_name; +#ifdef _MSC_VER + char drive_buf[_TINYDIR_PATH_MAX]; + char ext_buf[_TINYDIR_FILENAME_MAX]; +#endif + + if (file == NULL || path == NULL || strlen(path) == 0) + { + errno = EINVAL; + return -1; + } + if (strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX) + { + errno = ENAMETOOLONG; + return -1; + } + + /* Get the parent path */ +#ifdef _MSC_VER + if (_splitpath_s( + path, + drive_buf, sizeof drive_buf, + dir_name_buf, sizeof dir_name_buf, + file_name_buf, sizeof file_name_buf, + ext_buf, sizeof ext_buf)) + { + errno = EINVAL; + return -1; + } + /* Concatenate the drive letter and dir name to form full dir name */ + strcat(drive_buf, dir_name_buf); + dir_name = drive_buf; + /* Concatenate the file name and extension to form base name */ + strcat(file_name_buf, ext_buf); + base_name = file_name_buf; +#else + strcpy(dir_name_buf, path); + dir_name = dirname(dir_name_buf); + strcpy(file_name_buf, path); + base_name = basename(file_name_buf); +#endif + + /* Open the parent directory */ + if (tinydir_open(&dir, dir_name) == -1) + { + return -1; + } + + /* Read through the parent directory and look for the file */ + while (dir.has_next) + { + if (tinydir_readfile(&dir, file) == -1) + { + result = -1; + goto bail; + } + if (strcmp(file->name, base_name) == 0) + { + /* File found */ + found = 1; + goto bail; + } + tinydir_next(&dir); + } + if (!found) + { + result = -1; + errno = ENOENT; + } + +bail: + tinydir_close(&dir); + return result; +} + +_TINYDIR_FUNC +void _tinydir_get_ext(tinydir_file *file) +{ + char *period = strrchr(file->name, '.'); + if (period == NULL) + { + file->extension = &(file->name[strlen(file->name)]); + } + else + { + file->extension = period + 1; + } +} + +_TINYDIR_FUNC +int _tinydir_file_cmp(const void *a, const void *b) +{ + const tinydir_file *fa = (const tinydir_file *)a; + const tinydir_file *fb = (const tinydir_file *)b; + if (fa->is_dir != fb->is_dir) + { + return -(fa->is_dir - fb->is_dir); + } + return strncmp(fa->name, fb->name, _TINYDIR_FILENAME_MAX); +} + +#endif diff --git a/CameraParameterEstimation/apps/basics/extern/tiny_jpeg.h b/CameraParameterEstimation/apps/basics/extern/tiny_jpeg.h new file mode 100644 index 0000000..e8f9a92 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/extern/tiny_jpeg.h @@ -0,0 +1,1279 @@ +/** + * tiny_jpeg.h + * + * Tiny JPEG Encoder + * - Sergio Gonzalez + * + * This is a readable and simple single-header JPEG encoder. + * + * Features + * - Implements Baseline DCT JPEG compression. + * - No dynamic allocations. + * + * This library is coded in the spirit of the stb libraries and mostly follows + * the stb guidelines. + * + * It is written in C99. And depends on the C standard library. + * Works with C++11 + * + * + * ==== Thanks ==== + * + * AssociationSirius (Bug reports) + * Bernard van Gastel (Thread-safe defaults, BSD compilation) + * + * + * ==== License ==== + * + * This software is in the public domain. Where that dedication is not + * recognized, you are granted a perpetual, irrevocable license to copy and + * modify this file as you see fit. + * + */ + +// ============================================================ +// Usage +// ============================================================ +// Include "tiny_jpeg.h" to and use the public interface defined below. +// +// You *must* do: +// +// #define TJE_IMPLEMENTATION +// #include "tiny_jpeg.h" +// +// in exactly one of your C files to actually compile the implementation. + + +// Here is an example program that loads a bmp with stb_image and writes it +// with Tiny JPEG + +/* + +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + + +#define TJE_IMPLEMENTATION +#include "tiny_jpeg.h" + + +int main() +{ + int width, height, num_components; + unsigned char* data = stbi_load("in.bmp", &width, &height, &num_components, 0); + if ( !data ) { + puts("Could not find file"); + return EXIT_FAILURE; + } + + if ( !tje_encode_to_file("out.jpg", width, height, num_components, data) ) { + fprintf(stderr, "Could not write JPEG\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +*/ + + + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" // We use {0}, which will zero-out the struct. +#pragma GCC diagnostic ignored "-Wmissing-braces" +#pragma GCC diagnostic ignored "-Wpadded" +#endif + +// ============================================================ +// Public interface: +// ============================================================ + +#ifndef TJE_HEADER_GUARD +#define TJE_HEADER_GUARD + +// - tje_encode_to_file - +// +// Usage: +// Takes bitmap data and writes a JPEG-encoded image to disk. +// +// PARAMETERS +// dest_path: filename to which we will write. e.g. "out.jpg" +// width, height: image size in pixels +// num_components: 3 is RGB. 4 is RGBA. Those are the only supported values +// src_data: pointer to the pixel data. +// +// RETURN: +// 0 on error. 1 on success. + +int tje_encode_to_file(const char* dest_path, + const int width, + const int height, + const int num_components, + const unsigned char* src_data); + +// - tje_encode_to_file_at_quality - +// +// Usage: +// Takes bitmap data and writes a JPEG-encoded image to disk. +// +// PARAMETERS +// dest_path: filename to which we will write. e.g. "out.jpg" +// quality: 3: Highest. Compression varies wildly (between 1/3 and 1/20). +// 2: Very good quality. About 1/2 the size of 3. +// 1: Noticeable. About 1/6 the size of 3, or 1/3 the size of 2. +// width, height: image size in pixels +// num_components: 3 is RGB. 4 is RGBA. Those are the only supported values +// src_data: pointer to the pixel data. +// +// RETURN: +// 0 on error. 1 on success. + +int tje_encode_to_file_at_quality(const char* dest_path, + const int quality, + const int width, + const int height, + const int num_components, + const unsigned char* src_data); + +// - tje_encode_with_func - +// +// Usage +// Same as tje_encode_to_file_at_quality, but it takes a callback that knows +// how to handle (or ignore) `context`. The callback receives an array `data` +// of `size` bytes, which can be written directly to a file. There is no need +// to free the data. + +typedef void tje_write_func(void* context, void* data, int size); + +int tje_encode_with_func(tje_write_func* func, + void* context, + const int quality, + const int width, + const int height, + const int num_components, + const unsigned char* src_data); + +#endif // TJE_HEADER_GUARD + + + +// Implementation: In exactly one of the source files of your application, +// define TJE_IMPLEMENTATION and include tiny_jpeg.h + +// ============================================================ +// Internal +// ============================================================ +#ifdef TJE_IMPLEMENTATION + + +#define tjei_min(a, b) ((a) < b) ? (a) : (b); +#define tjei_max(a, b) ((a) < b) ? (b) : (a); + + +#if defined(_MSC_VER) +#define TJEI_FORCE_INLINE __forceinline +// #define TJEI_FORCE_INLINE __declspec(noinline) // For profiling +#else +#define TJEI_FORCE_INLINE static // TODO: equivalent for gcc & clang +#endif + +// Only use zero for debugging and/or inspection. +#define TJE_USE_FAST_DCT 1 + +// C std lib +#include +#include +#include // floorf, ceilf +#include // FILE, puts +#include // memcpy + + +#define TJEI_BUFFER_SIZE 1024 + +#ifdef _WIN32 + +#include +#ifndef snprintf +#define snprintf sprintf_s +#endif +// Not quite the same but it works for us. If I am not mistaken, it differs +// only in the return value. + +#endif + +#ifndef NDEBUG + +#ifdef _WIN32 +#define tje_log(msg) OutputDebugStringA(msg) +#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#define tje_log(msg) puts(msg) +#else +#warning "need a tje_log definition for your platform for debugging purposes (not needed if compiling with NDEBUG)" +#endif + +#else // NDEBUG +#define tje_log(msg) +#endif // NDEBUG + + +typedef struct +{ + void* context; + tje_write_func* func; +} TJEWriteContext; + +typedef struct +{ + // Huffman data. + uint8_t ehuffsize[4][257]; + uint16_t ehuffcode[4][256]; + uint8_t const * ht_bits[4]; + uint8_t const * ht_vals[4]; + + // Cuantization tables. + uint8_t qt_luma[64]; + uint8_t qt_chroma[64]; + + // fwrite by default. User-defined when using tje_encode_with_func. + TJEWriteContext write_context; + + // Buffered output. Big performance win when using the usual stdlib implementations. + size_t output_buffer_count; + uint8_t output_buffer[TJEI_BUFFER_SIZE]; +} TJEState; + +// ============================================================ +// Table definitions. +// +// The spec defines tjei_default reasonably good quantization matrices and huffman +// specification tables. +// +// +// Instead of hard-coding the final huffman table, we only hard-code the table +// spec suggested by the specification, and then derive the full table from +// there. This is only for didactic purposes but it might be useful if there +// ever is the case that we need to swap huffman tables from various sources. +// ============================================================ + + +// K.1 - suggested luminance QT +static const uint8_t tjei_default_qt_luma_from_spec[] = +{ + 16,11,10,16, 24, 40, 51, 61, + 12,12,14,19, 26, 58, 60, 55, + 14,13,16,24, 40, 57, 69, 56, + 14,17,22,29, 51, 87, 80, 62, + 18,22,37,56, 68,109,103, 77, + 24,35,55,64, 81,104,113, 92, + 49,64,78,87,103,121,120,101, + 72,92,95,98,112,100,103, 99, +}; + +// Unused +#if 0 +static const uint8_t tjei_default_qt_chroma_from_spec[] = +{ + // K.1 - suggested chrominance QT + 17,18,24,47,99,99,99,99, + 18,21,26,66,99,99,99,99, + 24,26,56,99,99,99,99,99, + 47,66,99,99,99,99,99,99, + 99,99,99,99,99,99,99,99, + 99,99,99,99,99,99,99,99, + 99,99,99,99,99,99,99,99, + 99,99,99,99,99,99,99,99, +}; +#endif + +static const uint8_t tjei_default_qt_chroma_from_paper[] = +{ + // Example QT from JPEG paper + 16, 12, 14, 14, 18, 24, 49, 72, + 11, 10, 16, 24, 40, 51, 61, 12, + 13, 17, 22, 35, 64, 92, 14, 16, + 22, 37, 55, 78, 95, 19, 24, 29, + 56, 64, 87, 98, 26, 40, 51, 68, + 81, 103, 112, 58, 57, 87, 109, 104, + 121,100, 60, 69, 80, 103, 113, 120, + 103, 55, 56, 62, 77, 92, 101, 99, +}; + +// == Procedure to 'deflate' the huffman tree: JPEG spec, C.2 + +// Number of 16 bit values for every code length. (K.3.3.1) +static const uint8_t tjei_default_ht_luma_dc_len[16] = +{ + 0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0 +}; +// values +static const uint8_t tjei_default_ht_luma_dc[12] = +{ + 0,1,2,3,4,5,6,7,8,9,10,11 +}; + +// Number of 16 bit values for every code length. (K.3.3.1) +static const uint8_t tjei_default_ht_chroma_dc_len[16] = +{ + 0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0 +}; +// values +static const uint8_t tjei_default_ht_chroma_dc[12] = +{ + 0,1,2,3,4,5,6,7,8,9,10,11 +}; + +// Same as above, but AC coefficients. +static const uint8_t tjei_default_ht_luma_ac_len[16] = +{ + 0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d +}; +static const uint8_t tjei_default_ht_luma_ac[] = +{ + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, + 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, + 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, + 0xF9, 0xFA +}; + +static const uint8_t tjei_default_ht_chroma_ac_len[16] = +{ + 0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77 +}; +static const uint8_t tjei_default_ht_chroma_ac[] = +{ + 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, + 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, + 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, + 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, + 0xF9, 0xFA +}; + + +// ============================================================ +// Code +// ============================================================ + +// Zig-zag order: +static const uint8_t tjei_zig_zag[64] = +{ + 0, 1, 5, 6, 14, 15, 27, 28, + 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, + 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, + 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, + 35, 36, 48, 49, 57, 58, 62, 63, +}; + +// Memory order as big endian. 0xhilo -> 0xlohi which looks as 0xhilo in memory. +static uint16_t tjei_be_word(const uint16_t le_word) +{ + uint16_t lo = (le_word & 0x00ff); + uint16_t hi = ((le_word & 0xff00) >> 8); + return (uint16_t)((lo << 8) | hi); +} + +// ============================================================ +// The following structs exist only for code clarity, debugability, and +// readability. They are used when writing to disk, but it is useful to have +// 1-packed-structs to document how the format works, and to inspect memory +// while developing. +// ============================================================ + +static const uint8_t tjeik_jfif_id[] = "JFIF"; +static const uint8_t tjeik_com_str[] = "Created by Tiny JPEG Encoder"; + +// TODO: Get rid of packed structs! +#pragma pack(push) +#pragma pack(1) +typedef struct +{ + uint16_t SOI; + // JFIF header. + uint16_t APP0; + uint16_t jfif_len; + uint8_t jfif_id[5]; + uint16_t version; + uint8_t units; + uint16_t x_density; + uint16_t y_density; + uint8_t x_thumb; + uint8_t y_thumb; +} TJEJPEGHeader; + +typedef struct +{ + uint16_t com; + uint16_t com_len; + char com_str[sizeof(tjeik_com_str) - 1]; +} TJEJPEGComment; + +// Helper struct for TJEFrameHeader (below). +typedef struct +{ + uint8_t component_id; + uint8_t sampling_factors; // most significant 4 bits: horizontal. 4 LSB: vertical (A.1.1) + uint8_t qt; // Quantization table selector. +} TJEComponentSpec; + +typedef struct +{ + uint16_t SOF; + uint16_t len; // 8 + 3 * frame.num_components + uint8_t precision; // Sample precision (bits per sample). + uint16_t height; + uint16_t width; + uint8_t num_components; // For this implementation, will be equal to 3. + TJEComponentSpec component_spec[3]; +} TJEFrameHeader; + +typedef struct +{ + uint8_t component_id; // Just as with TJEComponentSpec + uint8_t dc_ac; // (dc|ac) +} TJEFrameComponentSpec; + +typedef struct +{ + uint16_t SOS; + uint16_t len; + uint8_t num_components; // 3. + TJEFrameComponentSpec component_spec[3]; + uint8_t first; // 0 + uint8_t last; // 63 + uint8_t ah_al; // o +} TJEScanHeader; +#pragma pack(pop) + + +static void tjei_write(TJEState* state, const void* data, size_t num_bytes, size_t num_elements) +{ + size_t to_write = num_bytes * num_elements; + + // Cap to the buffer available size and copy memory. + size_t capped_count = tjei_min(to_write, TJEI_BUFFER_SIZE - 1 - state->output_buffer_count); + + memcpy(state->output_buffer + state->output_buffer_count, data, capped_count); + state->output_buffer_count += capped_count; + + assert (state->output_buffer_count <= TJEI_BUFFER_SIZE - 1); + + // Flush the buffer. + if ( state->output_buffer_count == TJEI_BUFFER_SIZE - 1 ) { + state->write_context.func(state->write_context.context, state->output_buffer, (int)state->output_buffer_count); + state->output_buffer_count = 0; + } + + // Recursively calling ourselves with the rest of the buffer. + if (capped_count < to_write) { + tjei_write(state, (uint8_t*)data+capped_count, to_write - capped_count, 1); + } +} + +static void tjei_write_DQT(TJEState* state, const uint8_t* matrix, uint8_t id) +{ + uint16_t DQT = tjei_be_word(0xffdb); + tjei_write(state, &DQT, sizeof(uint16_t), 1); + uint16_t len = tjei_be_word(0x0043); // 2(len) + 1(id) + 64(matrix) = 67 = 0x43 + tjei_write(state, &len, sizeof(uint16_t), 1); + assert(id < 4); + uint8_t precision_and_id = id; // 0x0000 8 bits | 0x00id + tjei_write(state, &precision_and_id, sizeof(uint8_t), 1); + // Write matrix + tjei_write(state, matrix, 64*sizeof(uint8_t), 1); +} + +typedef enum +{ + TJEI_DC = 0, + TJEI_AC = 1 +} TJEHuffmanTableClass; + +static void tjei_write_DHT(TJEState* state, + uint8_t const * matrix_len, + uint8_t const * matrix_val, + TJEHuffmanTableClass ht_class, + uint8_t id) +{ + int num_values = 0; + for ( int i = 0; i < 16; ++i ) { + num_values += matrix_len[i]; + } + assert(num_values <= 0xffff); + + uint16_t DHT = tjei_be_word(0xffc4); + // 2(len) + 1(Tc|th) + 16 (num lengths) + ?? (num values) + uint16_t len = tjei_be_word(2 + 1 + 16 + (uint16_t)num_values); + assert(id < 4); + uint8_t tc_th = (uint8_t)((((uint8_t)ht_class) << 4) | id); + + tjei_write(state, &DHT, sizeof(uint16_t), 1); + tjei_write(state, &len, sizeof(uint16_t), 1); + tjei_write(state, &tc_th, sizeof(uint8_t), 1); + tjei_write(state, matrix_len, sizeof(uint8_t), 16); + tjei_write(state, matrix_val, sizeof(uint8_t), (size_t)num_values); +} +// ============================================================ +// Huffman deflation code. +// ============================================================ + +// Returns all code sizes from the BITS specification (JPEG C.3) +static uint8_t* tjei_huff_get_code_lengths(uint8_t huffsize[/*256*/], uint8_t const * bits) +{ + int k = 0; + for ( int i = 0; i < 16; ++i ) { + for ( int j = 0; j < bits[i]; ++j ) { + huffsize[k++] = (uint8_t)(i + 1); + } + huffsize[k] = 0; + } + return huffsize; +} + +// Fills out the prefixes for each code. +static uint16_t* tjei_huff_get_codes(uint16_t codes[], uint8_t* huffsize, int64_t count) +{ + uint16_t code = 0; + int k = 0; + uint8_t sz = huffsize[0]; + for(;;) { + do { + assert(k < count); + codes[k++] = code++; + } while (huffsize[k] == sz); + if (huffsize[k] == 0) { + return codes; + } + do { + code = (uint16_t)(code << 1); + ++sz; + } while( huffsize[k] != sz ); + } +} + +static void tjei_huff_get_extended(uint8_t* out_ehuffsize, + uint16_t* out_ehuffcode, + uint8_t const * huffval, + uint8_t* huffsize, + uint16_t* huffcode, int64_t count) +{ + int k = 0; + do { + uint8_t val = huffval[k]; + out_ehuffcode[val] = huffcode[k]; + out_ehuffsize[val] = huffsize[k]; + k++; + } while ( k < count ); +} +// ============================================================ + +// Returns: +// out[1] : number of bits +// out[0] : bits +TJEI_FORCE_INLINE void tjei_calculate_variable_length_int(int value, uint16_t out[2]) +{ + int abs_val = value; + if ( value < 0 ) { + abs_val = -abs_val; + --value; + } + out[1] = 1; + while( abs_val >>= 1 ) { + ++out[1]; + } + out[0] = (uint16_t)(value & ((1 << out[1]) - 1)); +} + +// Write bits to file. +TJEI_FORCE_INLINE void tjei_write_bits(TJEState* state, + uint32_t* bitbuffer, uint32_t* location, + uint16_t num_bits, uint16_t bits) +{ + // v-- location + // [ ] <-- bit buffer + // 32 0 + // + // This call pushes to the bitbuffer and saves the location. Data is pushed + // from most significant to less significant. + // When we can write a full byte, we write a byte and shift. + + // Push the stack. + uint32_t nloc = *location + num_bits; + *bitbuffer |= (uint32_t)(bits << (32 - nloc)); + *location = nloc; + while ( *location >= 8 ) { + // Grab the most significant byte. + uint8_t c = (uint8_t)((*bitbuffer) >> 24); + // Write it to file. + tjei_write(state, &c, 1, 1); + if ( c == 0xff ) { + // Special case: tell JPEG this is not a marker. + char z = 0; + tjei_write(state, &z, 1, 1); + } + // Pop the stack. + *bitbuffer <<= 8; + *location -= 8; + } +} + +// DCT implementation by Thomas G. Lane. +// Obtained through NVIDIA +// http://developer.download.nvidia.com/SDK/9.5/Samples/vidimaging_samples.html#gpgpu_dct +// +// QUOTE: +// This implementation is based on Arai, Agui, and Nakajima's algorithm for +// scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in +// Japanese, but the algorithm is described in the Pennebaker & Mitchell +// JPEG textbook (see REFERENCES section in file README). The following code +// is based directly on figure 4-8 in P&M. +// +static void tjei_fdct (float * data) +{ + float tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + float tmp10, tmp11, tmp12, tmp13; + float z1, z2, z3, z4, z5, z11, z13; + float *dataptr; + int ctr; + + /* Pass 1: process rows. */ + + dataptr = data; + for ( ctr = 7; ctr >= 0; ctr-- ) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = tmp10 + tmp11; /* phase 3 */ + dataptr[4] = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * ((float) 0.707106781); /* c4 */ + dataptr[2] = tmp13 + z1; /* phase 5 */ + dataptr[6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = (tmp10 - tmp12) * ((float) 0.382683433); /* c6 */ + z2 = ((float) 0.541196100) * tmp10 + z5; /* c2-c6 */ + z4 = ((float) 1.306562965) * tmp12 + z5; /* c2+c6 */ + z3 = tmp11 * ((float) 0.707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[5] = z13 + z2; /* phase 6 */ + dataptr[3] = z13 - z2; + dataptr[1] = z11 + z4; + dataptr[7] = z11 - z4; + + dataptr += 8; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + + dataptr = data; + for ( ctr = 8-1; ctr >= 0; ctr-- ) { + tmp0 = dataptr[8*0] + dataptr[8*7]; + tmp7 = dataptr[8*0] - dataptr[8*7]; + tmp1 = dataptr[8*1] + dataptr[8*6]; + tmp6 = dataptr[8*1] - dataptr[8*6]; + tmp2 = dataptr[8*2] + dataptr[8*5]; + tmp5 = dataptr[8*2] - dataptr[8*5]; + tmp3 = dataptr[8*3] + dataptr[8*4]; + tmp4 = dataptr[8*3] - dataptr[8*4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[8*0] = tmp10 + tmp11; /* phase 3 */ + dataptr[8*4] = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * ((float) 0.707106781); /* c4 */ + dataptr[8*2] = tmp13 + z1; /* phase 5 */ + dataptr[8*6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = (tmp10 - tmp12) * ((float) 0.382683433); /* c6 */ + z2 = ((float) 0.541196100) * tmp10 + z5; /* c2-c6 */ + z4 = ((float) 1.306562965) * tmp12 + z5; /* c2+c6 */ + z3 = tmp11 * ((float) 0.707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[8*5] = z13 + z2; /* phase 6 */ + dataptr[8*3] = z13 - z2; + dataptr[8*1] = z11 + z4; + dataptr[8*7] = z11 - z4; + + dataptr++; /* advance pointer to next column */ + } +} +#if !TJE_USE_FAST_DCT +static float slow_fdct(int u, int v, float* data) +{ +#define kPI 3.14159265f + float res = 0.0f; + float cu = (u == 0) ? 0.70710678118654f : 1; + float cv = (v == 0) ? 0.70710678118654f : 1; + for ( int y = 0; y < 8; ++y ) { + for ( int x = 0; x < 8; ++x ) { + res += (data[y * 8 + x]) * + cosf(((2.0f * x + 1.0f) * u * kPI) / 16.0f) * + cosf(((2.0f * y + 1.0f) * v * kPI) / 16.0f); + } + } + res *= 0.25f * cu * cv; + return res; +#undef kPI +} +#endif + +#define ABS(x) ((x) < 0 ? -(x) : (x)) + +static void tjei_encode_and_write_MCU(TJEState* state, + float* mcu, +#if TJE_USE_FAST_DCT + float* qt, // Pre-processed quantization matrix. +#else + uint8_t* qt, +#endif + uint8_t* huff_dc_len, uint16_t* huff_dc_code, // Huffman tables + uint8_t* huff_ac_len, uint16_t* huff_ac_code, + int* pred, // Previous DC coefficient + uint32_t* bitbuffer, // Bitstack. + uint32_t* location) +{ + int du[64]; // Data unit in zig-zag order + + float dct_mcu[64]; + memcpy(dct_mcu, mcu, 64 * sizeof(float)); + +#if TJE_USE_FAST_DCT + tjei_fdct(dct_mcu); + for ( int i = 0; i < 64; ++i ) { + float fval = dct_mcu[i]; + fval *= qt[i]; +#if 0 + fval = (fval > 0) ? floorf(fval + 0.5f) : ceilf(fval - 0.5f); +#else + fval = floorf(fval + 1024 + 0.5f); + fval -= 1024; +#endif + int val = (int)fval; + du[tjei_zig_zag[i]] = val; + } +#else + for ( int v = 0; v < 8; ++v ) { + for ( int u = 0; u < 8; ++u ) { + dct_mcu[v * 8 + u] = slow_fdct(u, v, mcu); + } + } + for ( int i = 0; i < 64; ++i ) { + float fval = dct_mcu[i] / (qt[i]); + int val = (int)((fval > 0) ? floorf(fval + 0.5f) : ceilf(fval - 0.5f)); + du[tjei_zig_zag[i]] = val; + } +#endif + + uint16_t vli[2]; + + // Encode DC coefficient. + int diff = du[0] - *pred; + *pred = du[0]; + if ( diff != 0 ) { + tjei_calculate_variable_length_int(diff, vli); + // Write number of bits with Huffman coding + tjei_write_bits(state, bitbuffer, location, huff_dc_len[vli[1]], huff_dc_code[vli[1]]); + // Write the bits. + tjei_write_bits(state, bitbuffer, location, vli[1], vli[0]); + } else { + tjei_write_bits(state, bitbuffer, location, huff_dc_len[0], huff_dc_code[0]); + } + + // ==== Encode AC coefficients ==== + + int last_non_zero_i = 0; + // Find the last non-zero element. + for ( int i = 63; i > 0; --i ) { + if (du[i] != 0) { + last_non_zero_i = i; + break; + } + } + + for ( int i = 1; i <= last_non_zero_i; ++i ) { + // If zero, increase count. If >=15, encode (FF,00) + int zero_count = 0; + while ( du[i] == 0 ) { + ++zero_count; + ++i; + if (zero_count == 16) { + // encode (ff,00) == 0xf0 + tjei_write_bits(state, bitbuffer, location, huff_ac_len[0xf0], huff_ac_code[0xf0]); + zero_count = 0; + } + } + tjei_calculate_variable_length_int(du[i], vli); + + assert(zero_count < 0x10); + assert(vli[1] <= 10); + + uint16_t sym1 = (uint16_t)((uint16_t)zero_count << 4) | vli[1]; + + assert(huff_ac_len[sym1] != 0); + + // Write symbol 1 --- (RUNLENGTH, SIZE) + tjei_write_bits(state, bitbuffer, location, huff_ac_len[sym1], huff_ac_code[sym1]); + // Write symbol 2 --- (AMPLITUDE) + tjei_write_bits(state, bitbuffer, location, vli[1], vli[0]); + } + + if (last_non_zero_i != 63) { + // write EOB HUFF(00,00) + tjei_write_bits(state, bitbuffer, location, huff_ac_len[0], huff_ac_code[0]); + } + return; +} + +enum { + TJEI_LUMA_DC, + TJEI_LUMA_AC, + TJEI_CHROMA_DC, + TJEI_CHROMA_AC, +}; + +#if TJE_USE_FAST_DCT +struct TJEProcessedQT +{ + float chroma[64]; + float luma[64]; +}; +#endif + +// Set up huffman tables in state. +static void tjei_huff_expand(TJEState* state) +{ + assert(state); + + state->ht_bits[TJEI_LUMA_DC] = tjei_default_ht_luma_dc_len; + state->ht_bits[TJEI_LUMA_AC] = tjei_default_ht_luma_ac_len; + state->ht_bits[TJEI_CHROMA_DC] = tjei_default_ht_chroma_dc_len; + state->ht_bits[TJEI_CHROMA_AC] = tjei_default_ht_chroma_ac_len; + + state->ht_vals[TJEI_LUMA_DC] = tjei_default_ht_luma_dc; + state->ht_vals[TJEI_LUMA_AC] = tjei_default_ht_luma_ac; + state->ht_vals[TJEI_CHROMA_DC] = tjei_default_ht_chroma_dc; + state->ht_vals[TJEI_CHROMA_AC] = tjei_default_ht_chroma_ac; + + // How many codes in total for each of LUMA_(DC|AC) and CHROMA_(DC|AC) + int32_t spec_tables_len[4] = { 0 }; + + for ( int i = 0; i < 4; ++i ) { + for ( int k = 0; k < 16; ++k ) { + spec_tables_len[i] += state->ht_bits[i][k]; + } + } + + // Fill out the extended tables.. + uint8_t huffsize[4][257]; + uint16_t huffcode[4][256]; + for ( int i = 0; i < 4; ++i ) { + assert (256 >= spec_tables_len[i]); + tjei_huff_get_code_lengths(huffsize[i], state->ht_bits[i]); + tjei_huff_get_codes(huffcode[i], huffsize[i], spec_tables_len[i]); + } + for ( int i = 0; i < 4; ++i ) { + int64_t count = spec_tables_len[i]; + tjei_huff_get_extended(state->ehuffsize[i], + state->ehuffcode[i], + state->ht_vals[i], + &huffsize[i][0], + &huffcode[i][0], count); + } +} + +static int tjei_encode_main(TJEState* state, + const unsigned char* src_data, + const int width, + const int height, + const int src_num_components) +{ + if (src_num_components != 3 && src_num_components != 4) { + return 0; + } + + if (width > 0xffff || height > 0xffff) { + return 0; + } + +#if TJE_USE_FAST_DCT + struct TJEProcessedQT pqt; + // Again, taken from classic japanese implementation. + // + /* For float AA&N IDCT method, divisors are equal to quantization + * coefficients scaled by scalefactor[row]*scalefactor[col], where + * scalefactor[0] = 1 + * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 + * We apply a further scale factor of 8. + * What's actually stored is 1/divisor so that the inner loop can + * use a multiplication rather than a division. + */ + static const float aan_scales[] = { + 1.0f, 1.387039845f, 1.306562965f, 1.175875602f, + 1.0f, 0.785694958f, 0.541196100f, 0.275899379f + }; + + // build (de)quantization tables + for(int y=0; y<8; y++) { + for(int x=0; x<8; x++) { + int i = y*8 + x; + pqt.luma[y*8+x] = 1.0f / (8 * aan_scales[x] * aan_scales[y] * state->qt_luma[tjei_zig_zag[i]]); + pqt.chroma[y*8+x] = 1.0f / (8 * aan_scales[x] * aan_scales[y] * state->qt_chroma[tjei_zig_zag[i]]); + } + } +#endif + + { // Write header + TJEJPEGHeader header; + // JFIF header. + header.SOI = tjei_be_word(0xffd8); // Sequential DCT + header.APP0 = tjei_be_word(0xffe0); + + uint16_t jfif_len = sizeof(TJEJPEGHeader) - 4 /*SOI & APP0 markers*/; + header.jfif_len = tjei_be_word(jfif_len); + memcpy(header.jfif_id, (void*)tjeik_jfif_id, 5); + header.version = tjei_be_word(0x0102); + header.units = 0x01; // Dots-per-inch + header.x_density = tjei_be_word(0x0060); // 96 DPI + header.y_density = tjei_be_word(0x0060); // 96 DPI + header.x_thumb = 0; + header.y_thumb = 0; + tjei_write(state, &header, sizeof(TJEJPEGHeader), 1); + } + { // Write comment + TJEJPEGComment com; + uint16_t com_len = 2 + sizeof(tjeik_com_str) - 1; + // Comment + com.com = tjei_be_word(0xfffe); + com.com_len = tjei_be_word(com_len); + memcpy(com.com_str, (void*)tjeik_com_str, sizeof(tjeik_com_str)-1); + tjei_write(state, &com, sizeof(TJEJPEGComment), 1); + } + + // Write quantization tables. + tjei_write_DQT(state, state->qt_luma, 0x00); + tjei_write_DQT(state, state->qt_chroma, 0x01); + + { // Write the frame marker. + TJEFrameHeader header; + header.SOF = tjei_be_word(0xffc0); + header.len = tjei_be_word(8 + 3 * 3); + header.precision = 8; + assert(width <= 0xffff); + assert(height <= 0xffff); + header.width = tjei_be_word((uint16_t)width); + header.height = tjei_be_word((uint16_t)height); + header.num_components = 3; + uint8_t tables[3] = { + 0, // Luma component gets luma table (see tjei_write_DQT call above.) + 1, // Chroma component gets chroma table + 1, // Chroma component gets chroma table + }; + for (int i = 0; i < 3; ++i) { + TJEComponentSpec spec; + spec.component_id = (uint8_t)(i + 1); // No particular reason. Just 1, 2, 3. + spec.sampling_factors = (uint8_t)0x11; + spec.qt = tables[i]; + + header.component_spec[i] = spec; + } + // Write to file. + tjei_write(state, &header, sizeof(TJEFrameHeader), 1); + } + + tjei_write_DHT(state, state->ht_bits[TJEI_LUMA_DC], state->ht_vals[TJEI_LUMA_DC], TJEI_DC, 0); + tjei_write_DHT(state, state->ht_bits[TJEI_LUMA_AC], state->ht_vals[TJEI_LUMA_AC], TJEI_AC, 0); + tjei_write_DHT(state, state->ht_bits[TJEI_CHROMA_DC], state->ht_vals[TJEI_CHROMA_DC], TJEI_DC, 1); + tjei_write_DHT(state, state->ht_bits[TJEI_CHROMA_AC], state->ht_vals[TJEI_CHROMA_AC], TJEI_AC, 1); + + // Write start of scan + { + TJEScanHeader header; + header.SOS = tjei_be_word(0xffda); + header.len = tjei_be_word((uint16_t)(6 + (sizeof(TJEFrameComponentSpec) * 3))); + header.num_components = 3; + + uint8_t tables[3] = { + 0x00, + 0x11, + 0x11, + }; + for (int i = 0; i < 3; ++i) { + TJEFrameComponentSpec cs; + // Must be equal to component_id from frame header above. + cs.component_id = (uint8_t)(i + 1); + cs.dc_ac = (uint8_t)tables[i]; + + header.component_spec[i] = cs; + } + header.first = 0; + header.last = 63; + header.ah_al = 0; + tjei_write(state, &header, sizeof(TJEScanHeader), 1); + + } + // Write compressed data. + + float du_y[64]; + float du_b[64]; + float du_r[64]; + + // Set diff to 0. + int pred_y = 0; + int pred_b = 0; + int pred_r = 0; + + // Bit stack + uint32_t bitbuffer = 0; + uint32_t location = 0; + + + for ( int y = 0; y < height; y += 8 ) { + for ( int x = 0; x < width; x += 8 ) { + // Block loop: ==== + for ( int off_y = 0; off_y < 8; ++off_y ) { + for ( int off_x = 0; off_x < 8; ++off_x ) { + int block_index = (off_y * 8 + off_x); + + int src_index = (((y + off_y) * width) + (x + off_x)) * src_num_components; + + int col = x + off_x; + int row = y + off_y; + + if(row >= height) { + src_index -= (width * (row - height + 1)) * src_num_components; + } + if(col >= width) { + src_index -= (col - width + 1) * src_num_components; + } + assert(src_index < width * height * src_num_components); + + uint8_t r = src_data[src_index + 0]; + uint8_t g = src_data[src_index + 1]; + uint8_t b = src_data[src_index + 2]; + + float luma = 0.299f * r + 0.587f * g + 0.114f * b - 128; + float cb = -0.1687f * r - 0.3313f * g + 0.5f * b; + float cr = 0.5f * r - 0.4187f * g - 0.0813f * b; + + du_y[block_index] = luma; + du_b[block_index] = cb; + du_r[block_index] = cr; + } + } + + tjei_encode_and_write_MCU(state, du_y, +#if TJE_USE_FAST_DCT + pqt.luma, +#else + state->qt_luma, +#endif + state->ehuffsize[TJEI_LUMA_DC], state->ehuffcode[TJEI_LUMA_DC], + state->ehuffsize[TJEI_LUMA_AC], state->ehuffcode[TJEI_LUMA_AC], + &pred_y, &bitbuffer, &location); + tjei_encode_and_write_MCU(state, du_b, +#if TJE_USE_FAST_DCT + pqt.chroma, +#else + state->qt_chroma, +#endif + state->ehuffsize[TJEI_CHROMA_DC], state->ehuffcode[TJEI_CHROMA_DC], + state->ehuffsize[TJEI_CHROMA_AC], state->ehuffcode[TJEI_CHROMA_AC], + &pred_b, &bitbuffer, &location); + tjei_encode_and_write_MCU(state, du_r, +#if TJE_USE_FAST_DCT + pqt.chroma, +#else + state->qt_chroma, +#endif + state->ehuffsize[TJEI_CHROMA_DC], state->ehuffcode[TJEI_CHROMA_DC], + state->ehuffsize[TJEI_CHROMA_AC], state->ehuffcode[TJEI_CHROMA_AC], + &pred_r, &bitbuffer, &location); + + + } + } + + // Finish the image. + { // Flush + if (location > 0 && location < 8) { + tjei_write_bits(state, &bitbuffer, &location, (uint16_t)(8 - location), 0); + } + } + uint16_t EOI = tjei_be_word(0xffd9); + tjei_write(state, &EOI, sizeof(uint16_t), 1); + + if (state->output_buffer_count) { + state->write_context.func(state->write_context.context, state->output_buffer, (int)state->output_buffer_count); + state->output_buffer_count = 0; + } + + return 1; +} + +int tje_encode_to_file(const char* dest_path, + const int width, + const int height, + const int num_components, + const unsigned char* src_data) +{ + int res = tje_encode_to_file_at_quality(dest_path, 3, width, height, num_components, src_data); + return res; +} + +static void tjei_stdlib_func(void* context, void* data, int size) +{ + FILE* fd = (FILE*)context; + fwrite(data, size, 1, fd); +} + +// Define public interface. +int tje_encode_to_file_at_quality(const char* dest_path, + const int quality, + const int width, + const int height, + const int num_components, + const unsigned char* src_data) +{ + FILE* fd = fopen(dest_path, "wb"); + if (!fd) { + tje_log("Could not open file for writing."); + return 0; + } + + int result = tje_encode_with_func(tjei_stdlib_func, fd, + quality, width, height, num_components, src_data); + + result |= 0 == fclose(fd); + + return result; +} + +int tje_encode_with_func(tje_write_func* func, + void* context, + const int quality, + const int width, + const int height, + const int num_components, + const unsigned char* src_data) +{ + if (quality < 1 || quality > 3) { + tje_log("[ERROR] -- Valid 'quality' values are 1 (lowest), 2, or 3 (highest)\n"); + return 0; + } + + TJEState state = { 0 }; + + uint8_t qt_factor = 1; + switch(quality) { + case 3: + for ( int i = 0; i < 64; ++i ) { + state.qt_luma[i] = 1; + state.qt_chroma[i] = 1; + } + break; + case 2: + qt_factor = 10; + // don't break. fall through. + case 1: + for ( int i = 0; i < 64; ++i ) { + state.qt_luma[i] = tjei_default_qt_luma_from_spec[i] / qt_factor; + if (state.qt_luma[i] == 0) { + state.qt_luma[i] = 1; + } + state.qt_chroma[i] = tjei_default_qt_chroma_from_paper[i] / qt_factor; + if (state.qt_chroma[i] == 0) { + state.qt_chroma[i] = 1; + } + } + break; + default: + assert(!"invalid code path"); + break; + } + + TJEWriteContext wc = { 0 }; + + wc.context = context; + wc.func = func; + + state.write_context = wc; + + + tjei_huff_expand(&state); + + int result = tjei_encode_main(&state, src_data, width, height, num_components); + + return result; +} +// ============================================================ +#endif // TJE_IMPLEMENTATION +// ============================================================ +// +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif + + +#ifdef __cplusplus +} // extern C +#endif + diff --git a/CameraParameterEstimation/apps/basics/gfx/camera.h b/CameraParameterEstimation/apps/basics/gfx/camera.h new file mode 100644 index 0000000..a442904 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/gfx/camera.h @@ -0,0 +1,420 @@ +#pragma once + +// TODO: implement first person controls +// TODO Fix trackball starting position bug +namespace bsc +{ + struct camera + { + vec3 position; + quatf orientation; + }; + + struct first_person_controls + { + r32 speed; + r32 Pitch; + r32 Yaw; + + bool rotate ( bsc::camera * cam, const bsc::mat3f * orientation ); + bool pan ( bsc::camera * cam, const bsc::mat3f * orientation ); + bool move ( bsc::camera * cam, const bsc::mat3f * orientation ); + + mat4 initialize ( bsc::camera * camera, + const bsc::vec3 & cam_pos, + const bsc::vec3 & center, + const bsc::vec3 & up ); + void update ( bsc::camera * cam, bsc::mat4 * view ); + }; + + struct trackball_controls + { + // hand tuned defaults + r32 rotation_speed = 2.0f; + r32 zoom_speed = 1.2f; + r32 pan_speed = 0.94f; + + // TODO: This helper is a hack that I do not necessarily understand. Need to look more into that. + vec3 helper; + + bool zoom ( bsc::camera * cam, + const bsc::mat4 * view ); + bool pan ( bsc::camera * cam, + const bsc::mat4 * view, + const bsc::vec4i * viewport ); + bool rotate ( bsc::camera * cam, + const bsc::mat4 * view, + const bsc::vec4i * viewport ); + + bsc::mat4 initialize ( bsc::camera * camera, + const bsc::vec3 & cam_pos, + const bsc::vec3 & center, + const bsc::vec3 & up ); + void update ( bsc::camera * cam, + bsc::mat4 * view, + const bsc::vec4i * viewport ); + + void set_front_view( bsc::camera * cam, bsc::mat4 * view ); + void set_back_view( bsc::camera * cam, bsc::mat4 * view ); + void set_right_view( bsc::camera * cam, bsc::mat4 * view ); + void set_left_view( bsc::camera * cam, bsc::mat4 * view ); + void set_top_view( bsc::camera * cam, bsc::mat4 * view ); + void set_bottom_view( bsc::camera * cam, bsc::mat4 * view ); + }; +} + + +#ifdef BSC_IMPLEMENTATION + +//////////////////////////////////////////////////////////////////////////////// +// Camera controls - Trackball +//////////////////////////////////////////////////////////////////////////////// + +static bsc::vec3 +click_to_sphere( float x, float y, const bsc::vec4i * viewport ) +{ + using namespace bsc; + r32 w = (*viewport)[2] - (*viewport)[0]; + r32 h = (*viewport)[3] - (*viewport)[1]; + + vec3 pos ( 2.0 * x / w - 1.0, + 1.0 - 2.0 * y / h , + 0.0 ); + + r32 length = norm( pos ); + r32 length_sq = square( length ); + + if ( length_sq > 0.5f ) pos.z = 0.5f / length; + else pos.z = sqrtf( 1.0f - length_sq ); + + pos = normalize( pos ); + + return pos; +} + +bsc::mat4 bsc::trackball_controls:: +initialize ( bsc::camera * camera, + const bsc::vec3 & cam_pos, + const bsc::vec3 & center, + const bsc::vec3 & up ) +{ + bsc::mat4 view = look_at( cam_pos, center, up ); + camera->position = cam_pos; + camera->orientation = to_quat( view ); + + helper = vec3( 0, 0, norm(cam_pos) ); + bsc::quatf p( 0, helper ); + p = camera->orientation * p * conjugate( camera->orientation ); + helper = p.im; + + return view; +} + +bool bsc::trackball_controls:: +zoom ( bsc::camera * cam, + const bsc::mat4 * view ) +{ + float step = 0.1f; + float wheel_state = bsc::ui::get_mouse_wheel_offset(); + + if ( wheel_state ) + { + vec3 forward = -(*view)[ 2 ] ; + helper += forward * step * zoom_speed * wheel_state; + return true; + } + return false; +} + +bool bsc::trackball_controls:: +pan( bsc::camera * cam, + const bsc::mat4 * view, + const bsc::vec4i * viewport ) +{ + ui::state & UI = get_UI(); + + i8 is_mmb = ui::is_mouse_held( ui::mmb ); + + if ( is_mmb ) + { + vec2d mouse_pos = UI.mouse_pos; + vec2d mouse_drag = ui::get_mouse_drag_delta ( ui::mmb ); + if ( norm( mouse_drag ) == 0 ) return false; + + r32 f = norm( helper ) * this->pan_speed; + r32 w = (*viewport)[2] - (*viewport)[0]; + r32 h = (*viewport)[3] - (*viewport)[1]; + vec3 offset = ( f * ( (*view)[0]) * (r32)( mouse_drag.x / w ) ) + + ( f * (-(*view)[1]) * (r32)( mouse_drag.y / h ) ); + + helper += offset; + + return true; + } + return false; +} + +bool bsc::trackball_controls:: +rotate ( bsc::camera * cam, + const bsc::mat4 * view, + const bsc::vec4i * viewport ) +{ + ui::state & UI = get_UI(); + + if ( ui::is_mouse_held( ui::lmb ) ) + { + vec2d mouse_pos = UI.mouse_pos; + vec2d mouse_drag = ui::get_mouse_drag_delta ( ui::lmb ); + if ( norm( mouse_drag ) == 0 ) return false; + + vec3 start = click_to_sphere( mouse_pos.x, + mouse_pos.y, + viewport ); + vec3 end = click_to_sphere( mouse_pos.x + mouse_drag.x, + mouse_pos.y + mouse_drag.y , + viewport ); + + // get rotation axis in world coordinates + vec3 axis = normalize( cross( start, end ) ); + + r32 angle = acosf( min( dot( start, end ), 1.0f ) ); + angle *= this->rotation_speed; + + // TODO: add quaternion from angle axis + bsc::quatf cur_rot( cosf( angle * 0.5f ), axis * sinf( angle * 0.5f ) ); + cam->orientation = cur_rot * cam->orientation ; + + // TODO: and point transform using quaternions + bsc::quatf tmp_camera_pos( 0, helper ); + tmp_camera_pos = cur_rot * tmp_camera_pos * conjugate( cur_rot ); + helper = tmp_camera_pos.im; + + return true; + } + return false; +} + +void bsc::trackball_controls:: +update( bsc::camera * cam, bsc::mat4 * view, const bsc::vec4i * viewport ) +{ + bsc::ui::state & UI = bsc::get_UI(); + + bool hover = ( UI.hot_item > 0 || UI.active_item > 0 ) ? 1 : 0; + bool update = false; + + if ( !hover ) + { + update |= zoom( cam, view ); + update |= pan( cam, view, viewport ); + update |= rotate( cam, view, viewport ); + + if ( update ) + { + mat4 cur_view = to_mat4( cam->orientation ); + + cur_view[3] = vec4f( dot( helper, vec3( cur_view[0] ) ), + dot( helper, vec3( cur_view[1] ) ), + -dot( helper, vec3( cur_view[2] ) ), 1.0f ); + (*view) = cur_view; + cam->position = vec3( inverse( *view )[3] ); + } + } +} + +void bsc::trackball_controls:: +set_front_view( bsc::camera * cam, bsc::mat4 * view ) +{ + (*view) = initialize( cam, bsc::vec3( 0.0f, 0.0f, 10.0f ), + bsc::vec3( 0.0f, 0.0f, 0.0f), + bsc::vec3( 0.0f, 1.0f, 0.0f) ); +} + +void bsc::trackball_controls:: +set_back_view( bsc::camera * cam, bsc::mat4 * view ) +{ + (*view) = initialize( cam, bsc::vec3( 0.0f, 0.0f, -10.0f ), + bsc::vec3( 0.0f, 0.0f, 0.0f), + bsc::vec3( 0.0f, 1.0f, 0.0f) ); +} + +void bsc::trackball_controls:: +set_right_view( bsc::camera * cam, bsc::mat4 * view ) +{ + (*view) = initialize( cam, bsc::vec3( 10.0f, 0.0f, 0.0f ), + bsc::vec3( 0.0f, 0.0f, 0.0f), + bsc::vec3( 0.0f, 1.0f, 0.0f) ); +} + +void bsc::trackball_controls:: +set_left_view( bsc::camera * cam, bsc::mat4 * view ) +{ + (*view) = initialize( cam, bsc::vec3( -10.0f, 0.0f, 0.0f ), + bsc::vec3( 0.0f, 0.0f, 0.0f), + bsc::vec3( 0.0f, 1.0f, 0.0f) ); +} + +void bsc::trackball_controls:: +set_top_view( bsc::camera * cam, bsc::mat4 * view ) +{ + // just move camera minimally along z, to prevent the degenerate case + (*view) = initialize( cam, bsc::vec3( 0.0f, 10.0f, 0.001f ), + bsc::vec3( 0.0f, 0.0f, 0.0f), + bsc::vec3( 0.0f, 1.0f, 0.0f) ); +} + + +void bsc::trackball_controls:: +set_bottom_view( bsc::camera * cam, bsc::mat4 * view ) +{ + // just move camera minimally along z, to prevent the degenerate case + (*view) = initialize( cam, bsc::vec3( 0.0f, -10.0f, -0.001f ), + bsc::vec3( 0.0f, 0.0f, 0.0f), + bsc::vec3( 0.0f, 1.0f, 0.0f) ); +} +//////////////////////////////////////////////////////////////////////////////// +// Camera controls - Firstperson +//////////////////////////////////////////////////////////////////////////////// + +// TODO: tighten first person camera controls. +// Maybe go back to pitch, roll, yaw setup? + +/* +bool bsc::first_person_controls:: +rotate ( bsc::camera * cam, const bsc::mat3f * orientation ) +{ + ui::state & UI = get_UI(); + + if ( ui::is_mouse_held( ui::lmb ) ) + { + vec2d mouse_pos = UI.mouse_pos; + vec2d mouse_drag = ui::get_mouse_drag_delta ( ui::lmb ); + if ( norm( mouse_drag ) == 0 ) return false; + + vec3 start = click_to_sphere( mouse_pos.x, mouse_pos.y ); + vec3 end = click_to_sphere( mouse_pos.x + mouse_drag.x, + mouse_pos.y + mouse_drag.y ); + + // get rotation axis in world coordinates + vec3 axis = normalize( cross( start, end ) ); + // axis = (*orientation) * axis; + + r32 angle = acosf( min( dot( start, end ), 1.0f ) ); + angle *= 2.4f; + + // TODO: add quaternion from angle axis + quatf cur_rot( cosf( angle * 0.5f ), axis * sinf( angle * 0.5f ) ); + + cam->orientation = cam->orientation * cur_rot ; + + return true; + } + return false; +} + + +bool bsc::first_person_controls:: +pan( bsc::camera * camera, const bsc::mat3f * orientation ) +{ + if ( ui::is_mouse_held( ui::rmb ) ) + { + vec2d mouse_drag = ui::get_mouse_drag_delta ( ui::rmb ); + if ( norm( mouse_drag ) == 0 ) return false; + + camera->position -= 0.03f * (r32)mouse_drag.x * + this->speed * (*orientation)[ 0 ]; + camera->position += 0.03f * (r32)mouse_drag.y * + this->speed * (*orientation)[ 1 ]; + + return true; + } + + return false; +} + +bool bsc::first_person_controls:: +move ( bsc::camera * camera, const bsc::mat3f * orientation ) +{ + + bool moved = false; + + if ( bsc::ui::is_key_down( bsc::ui::key_w ) ) + { + camera->position -= this->speed * (*orientation)[ 2 ]; + moved = true; + } + + if ( bsc::ui::is_key_down( bsc::ui::key_s ) ) + { + camera->position += this->speed * (*orientation)[ 2 ]; + moved = true; + } + + if ( bsc::ui::is_key_down( bsc::ui::key_a ) ) + { + camera->position -= this->speed * (*orientation)[ 0 ]; + moved = true; + } + + if ( bsc::ui::is_key_down( bsc::ui::key_d ) ) + { + camera->position += this->speed * (*orientation)[ 0 ]; + moved = true; + } + + if ( bsc::ui::is_key_down( bsc::ui::key_q ) ) + { + camera->position += this->speed * (*orientation)[ 1 ]; + moved = true; + } + + if ( bsc::ui::is_key_down( bsc::ui::key_e ) ) + { + camera->position -= this->speed * (*orientation)[ 1 ]; + moved = true; + } + + return moved; +} + +bsc::mat4 bsc::first_person_controls:: +initialize( bsc::camera * camera, + const bsc::vec3 & cam_pos, + const bsc::vec3 & center, + const bsc::vec3 & up ) +{ + this->speed = 0.2f; // change speed to velocity? + + mat4 view = look_at( cam_pos, center, up ); + camera->position = cam_pos; + camera->orientation = to_quat( view ); + + return view; +} + +void bsc::first_person_controls:: +update ( bsc::camera * cam, bsc::mat4 * view ) +{ + bsc::ui::state & UI = bsc::get_UI(); + + bool hover = ( UI.hot_item > 0 || UI.active_item > 0 ) ? 1 : 0; + bool update = false; + + mat3f orientation = to_mat3( cam->orientation ); + + if ( !hover ) + { + update |= rotate( cam, &orientation ); + update |= pan( cam, &orientation ); + } + + update |= move( cam, &orientation ); + + if ( update ) + { + mat4 cur_view = to_mat4( cam->orientation ); + cur_view[3] = vec4f( cam->position, 1.0 ); + (*view) = inverse( cur_view ); + } +} +*/ +#endif diff --git a/CameraParameterEstimation/apps/basics/gfx/draw2d.h b/CameraParameterEstimation/apps/basics/gfx/draw2d.h new file mode 100644 index 0000000..51cab69 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/gfx/draw2d.h @@ -0,0 +1,221 @@ +#pragma once + +//////////////////////////////////////////////////////////////////////////////// +// Interface +//////////////////////////////////////////////////////////////////////////////// + +// TODO: change this in favour to dynamic memory allocation? +#define MAX_CMDS 8192 + +namespace bsc +{ + // NOTE : Decide whether we want to have draw_2d and draw_3d or merge them. + + namespace draw2d + { + enum cmd_t + { + LINE_START, + LINE_TO, + LINE_END + }; + + struct cmd + { + cmd_t type; + bsc::vec3f pos; + r32 radius; + }; + + struct context + { + cmd cmds[ MAX_CMDS ]; + i32 cmd_idx; + }; + + void start_frame(); + + void start_line( bsc::vec2 point, r32 width = 1.0 ); + void line_to( bsc::vec2 point, r32 width = 1.0 ); + void end_line( i8 merge = false ); + + // NOTE: This should be renderer agnostic + void initialize(); + void render(); + } + + + // NOTE : Should context be private ? + static draw2d::context g_ctx2d; + draw2d::context * get_2d_context(); + +} + +//////////////////////////////////////////////////////////////////////////////// +// Implementation +//////////////////////////////////////////////////////////////////////////////// + +#ifdef BSC_IMPLEMENTATION + + +bsc::draw2d::context * bsc:: +get_2d_context() +{ + return &g_ctx2d; +} + +// we will be constructing command buffer each frame. +void bsc::draw2d:: +start_frame() // TODO: Take context? +{ + g_ctx2d.cmd_idx = 0; +} + +// TODO: maybe commands should be just enums and this should be closer to simplistic +// malloc? We can interpret the size and type by enum... +// NOTE: Lines are hard. I should start with circles or rectangles. + +void bsc::draw2d:: +start_line( bsc::vec2 point, r32 width ) +{ + g_ctx2d.cmds[ g_ctx2d.cmd_idx++ ] = { LINE_START, vec3( point, 0.0 ), width }; +} + +void bsc::draw2d:: +line_to( bsc::vec2 point, r32 width ) +{ + g_ctx2d.cmds[ g_ctx2d.cmd_idx++ ] = { LINE_TO, vec3( point, 0.0 ), width }; +} + +void bsc::draw2d:: +end_line( i8 merge ) +{ + g_ctx2d.cmds[ g_ctx2d.cmd_idx++ ] = { LINE_END, vec3(), (r32)merge }; +} + +static GLuint tmp_vao = 0; +static GLuint tmp_vbo = 0; +static bool initialized = false; + +char* tmp_vs = (char*) SHADER_HEAD STR +( + layout (location = 0) in vec3 position; + uniform mat4 mvp; + void main() + { + gl_Position = mvp * vec4( position, 1.0 ); + } +); + +char* tmp_fs = (char*) SHADER_HEAD STR +( + out vec4 frag_color; + void main() + { + frag_color = vec4( 1.0, 0.0, 0.0, 1.0 ); + } +); + +static bsc::shader_prog tmp_shader; +static bsc::mat4 tmp_proj; +static bsc::mat4 tmp_look_at; + +void bsc::draw2d:: +render() +{ + // TODO: initialization should do some shader initialization etc. + + if ( !initialized ) + { + glGenVertexArrays( 1, &tmp_vao ); + glGenBuffers( 1, &tmp_vbo ); + + glBindVertexArray( tmp_vao ); + glBindBuffer( GL_ARRAY_BUFFER, tmp_vbo ); + // TODO : We will have to have a size for this? + // NOTE : What does nanovg do to initialize these buffers, and how does it transfer commands. + // NOTE : Shouldn't we map the buffers? + glBufferData( GL_ARRAY_BUFFER, MAX_CMDS * sizeof( bsc::vec3 ), NULL, GL_STREAM_DRAW ); + glBindVertexArray( 0 ); + glBindBuffer( GL_ARRAY_BUFFER, 0 ); + + create_shader_prog_from_source( tmp_vs, tmp_fs, tmp_shader ); + + initialized = true; + } + + bsc::vec3 positions[ MAX_CMDS ]; + bsc::vec3 first_pos; + bsc::vec3 prev_pos; + i32 draw_count = 0; + + for ( int i = 0 ; i < g_ctx2d.cmd_idx ; ++i ) + { + cmd * cur_cmd = &( g_ctx2d.cmds[i] ); + + switch ( cur_cmd->type ) + { + case LINE_START: + first_pos = cur_cmd->pos; + prev_pos = cur_cmd->pos; + break; + case LINE_TO: + positions[ draw_count + 0 ] = prev_pos; + positions[ draw_count + 1 ] = cur_cmd->pos; + prev_pos = cur_cmd->pos; + draw_count += 2; + break; + case LINE_END: + if ( cur_cmd->radius > 0 ) + { + positions[ draw_count + 0 ] = prev_pos; + positions[ draw_count + 1 ] = first_pos; + draw_count += 2; + } + break; + default: + bsc::error( __FILE__, __LINE__, "Unknown error type!"); + break; + } + } + + + if ( draw_count > 0 ) + { + i64 size = draw_count * 3 * sizeof(r32); + + glBindVertexArray( tmp_vao ); + glBindBuffer( GL_ARRAY_BUFFER, tmp_vbo ); + + glBufferSubData( GL_ARRAY_BUFFER, 0, size, &( positions[0] ) ); + glEnableVertexAttribArray( 0 ); + glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, 0 ); + + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0 ); + + tmp_look_at = bsc::look_at( bsc::vec3( 0.0f, 0.0f, 0.0f ), + bsc::vec3( 0.0f, 0.0f, 1.0f ), + bsc::vec3( 0.0f, 1.0f, 0.0f ) ); + + // TODO: Change that to projective transform so that we can have floating + // huds + + bsc::vec2i res = bsc::get_window().fb_size; + r32 pixel_ratio = bsc::get_window().pixel_ratio; + + tmp_proj = bsc::ortho( 0.0f, -1.0f/pixel_ratio * res.x, + 1.0f/pixel_ratio * res.y, 0.0f, + 0.0f, 10.0f ); + bsc::use_program( tmp_shader ); + bsc::set_uniform( tmp_shader, "mvp", tmp_proj * tmp_look_at ); + + glBindVertexArray( tmp_vao ); + glDrawArrays( GL_LINES, 0, draw_count ); + + glBindVertexArray( 0 ); + } + +} + +#endif //BSC_IMPLEMENTATION \ No newline at end of file diff --git a/CameraParameterEstimation/apps/basics/gfx/gpu_assets.h b/CameraParameterEstimation/apps/basics/gfx/gpu_assets.h new file mode 100644 index 0000000..5eda197 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/gfx/gpu_assets.h @@ -0,0 +1,714 @@ +//////////////////////////////////////////////////////////////////////////////// +// Interface +//////////////////////////////////////////////////////////////////////////////// + +// TODO this will most likely go through many iterations to arrive at something +// good. +// TODO: Make methods create multiple by default! +// TODO: What happens if data is updated often? Run Experiments +// TODO: Look at ubo's + pipelines +// TODO: Look at instancing +// TODO: Add filtering options to textures +// TODO: Look at samplers +// TODO: Should texture units have specific properties? + +// This assumes 3d data. Probably will want this to have dimensionality as well +// We are also mixing describing input data and description of draw command. +// Need to add instanced drawing and see how the code changes. + +enum FilteringSetting +{ + TEST +}; + + + +enum Attachements +{ + TEST3 +}; + +enum GeometryPropertiesFlags_ +{ + POSITION = 1 << 0, // layout( location = 0 ) + NORMAL = 1 << 1, // layout( location = 1 ) + TANGENT = 1 << 2, // layout( location = 2 ) + TEX_COORD = 1 << 3, // layout( location = 3 ) + COLOR_A = 1 << 4, // layout( location = 4 ) + COLOR_B = 1 << 5, // layout( location = 5 ) + COLOR_C = 1 << 6, // layout( location = 6 ) + COLOR_D = 1 << 7, // layout( location = 7 ) + STRUCTURED = 1 << 8, + + SIMPLE_MESH = POSITION | NORMAL | STRUCTURED, + POINTCLOUD = POSITION, +}; + +enum FramebufferType_ +{ + DEFAULT, + RGB, + RGBA, +}; + +typedef i32 InternalDataType; +typedef i32 GeometryPropertiesFlags; +typedef i32 FramebufferType; + +namespace bsc +{ +// GEOMETRY + struct geometry_data + { + r32 * positions = NULL; + r32 * normals = NULL; + r32 * tangents = NULL; + r32 * texcoords = NULL; + u8 * colors_a = NULL; + u8 * colors_b = NULL; + u8 * colors_c = NULL; + u8 * colors_d = NULL; + u32 * indices = NULL; + i32 n_vertices = -1; + i32 n_elements = -1; + }; + + // TODO : Need to experiment with glMapBufferRange. + struct gpu_geometry + { + u32 vao = -1; + u32 vbo = -1; + u32 ebo = -1; + i32 n_indices = -1; + i32 n_elements = -1; + i32 buffer_size = -1; + GeometryPropertiesFlags flags; + }; + + i32 update_gpu_geo( const geometry_data * host_data, + const gpu_geometry * geo, + const i32 flags = SIMPLE_MESH ); + i32 init_gpu_geo( const geometry_data * host_data, + gpu_geometry * geo, + const i32 flags = SIMPLE_MESH ); + i32 free_gpu_geo( gpu_geometry * geo ); + + void draw( gpu_geometry * geo, + GLenum draw_mode = GL_TRIANGLES ); + + +// TEXTURES + // TODO: Should gpu texture store it's size? + struct gpu_texture + { + u32 id; + + i32 width; + i32 height; + i32 n_comp; + + // THESE ARE OPENGL SPECIFIC. + GLenum type; + u32 unit; + }; + + void init_gpu_tex( const u8 * data, + const i32 w, + const i32 h, + const i32 n_comp, + gpu_texture * tex, + const u32 unit = 1 ); + void update_gpu_tex( const u8 * data, + gpu_texture * tex ); + void init_gpu_tex( const u16 * data, + const i32 w, + const i32 h, + const i32 n_comp, + gpu_texture * tex, + const u32 unit = 1 ); + void update_gpu_tex( const u16 * data, + gpu_texture * tex ); + + void init_gpu_tex( const i32 w, + const i32 h, + const i32 n_comp, + const GLenum type, + const GLenum format, + const GLint internal_format, + gpu_texture * tex, + const u32 unit = 1 ); + + void use_texture( const gpu_texture * tex ); + + void free_gpu_tex( gpu_texture * tex ); + +// FRAMEBUFFERS +// TODO: Should framebuffer store it's size? + // struct gpu_framebuffer + // { + // u32 id; + // i32 width; + // i32 height; + // gpu_texture tex; + // }; + + // TODO: Add things like format and + // void init_framebuffer( const i32 w, + // const i32 h, + // const InternalDataType + // gpu_framebuffer * fb, + // const i23 flags ); + // void use_framebuffer( gpu_framebuffer * fb ); + // void free_framebuffer( gpu_framebuffer * fb ); + +// RENDERBUFFERS -> TODO : Should we disguise renderbuffer as framebuffer on a specific type / attachment? +// They can be bound to FBO... And it is their only use... + // struct gpu_renderbuffer + // { + // u32 id; + // i32 width; + // i32 height; + // }; + // void init_renderbuffer( const i32 w, + // const i32 h, + // gpu_renderbuffer * fb ); + // void use_renderbuffer( gpu_renderbuffer * fb ); + // void free_renderbuffer( gpu_renderbuffer * fb ); +} + +//////////////////////////////////////////////////////////////////////////////// +// Implementation +//////////////////////////////////////////////////////////////////////////////// +#ifdef BSC_IMPLEMENTATION + +// GEOMETRY +// calulates offset of requested flag into buffer stored in geo, +// depending on what has been requested +u64 _get_offset( const bsc::gpu_geometry * geo, const i32 flag ) +{ + u64 offset = 0; + if ( geo->flags & POSITION ) + { + if ( flag & POSITION ) return offset * geo->n_indices; + offset += 3 * sizeof(r32); + } + if ( geo->flags & NORMAL ) + { + if ( flag & NORMAL ) return offset * geo->n_indices; + offset += 3 * sizeof(r32); + } + if ( geo->flags & TANGENT ) + { + if ( flag & TANGENT ) return offset * geo->n_indices; + offset += 3 * sizeof(r32); + } + if ( geo->flags & TEX_COORD ) + { + if ( flag & TEX_COORD ) return offset * geo->n_indices; + offset += 2 * sizeof(r32); + } + if ( geo->flags & COLOR_A ) + { + if ( flag & COLOR_A ) return offset * geo->n_indices; + offset += 4 * sizeof(u8); + } + if ( geo->flags & COLOR_B ) + { + if ( flag & COLOR_B ) return offset * geo->n_indices; + offset += 4 * sizeof(u8); + } + if ( geo->flags & COLOR_C ) + { + if ( flag & COLOR_C ) return offset * geo->n_indices; + offset += 4 * sizeof(u8); + } + if ( geo->flags & COLOR_D ) + { + if ( flag & COLOR_D ) return offset * geo->n_indices; + offset += 4 * sizeof(u8); + } + return offset * geo->n_indices; +} + +i32 bsc:: +update_gpu_geo( const geometry_data * host_data, + const gpu_geometry * geo, + const i32 flags ) +{ + + if( !(flags & geo->flags) ) + { + error( "Flag mismatch", __LINE__, "Requested flag update was not" + "part of initialization" ); + return 0; + } + + glBindVertexArray( geo->vao ); + glBindBuffer( GL_ARRAY_BUFFER, geo->vbo ); + + if ( flags & POSITION ) + { + u64 offset = _get_offset( geo, flags & POSITION ); + u64 current_size = 3 * sizeof(r32) * geo->n_indices; + glBufferSubData( GL_ARRAY_BUFFER, offset, + current_size, + &(host_data->positions[0]) ); + glEnableVertexAttribArray( 0 ); + glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, + 0, (void*) offset ); + } + + if ( flags & NORMAL ) + { + u64 offset = _get_offset( geo, flags & NORMAL); + u64 current_size = 3 * sizeof(r32) * geo->n_indices; + glBufferSubData( GL_ARRAY_BUFFER, offset, + current_size, + &(host_data->normals[0]) ); + glEnableVertexAttribArray( 1 ); + glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, + 0, (void*) offset ); + } + + if ( flags & TANGENT ) + { + u64 offset = _get_offset( geo, flags & TANGENT); + u64 current_size = 3 * sizeof(r32) * geo->n_indices; + glBufferSubData( GL_ARRAY_BUFFER, offset, + current_size, + &(host_data->tangents[0]) ); + glEnableVertexAttribArray( 2 ); + glVertexAttribPointer( 2, 3, GL_FLOAT, GL_FALSE, + 0, (void*) offset ); + } + + if ( flags & TEX_COORD ) + { + u64 offset = _get_offset( geo, flags & TEX_COORD); + u64 current_size = 2 * sizeof(r32) * geo->n_indices; + glBufferSubData( GL_ARRAY_BUFFER, offset, + current_size, + &(host_data->texcoords[0]) ); + glEnableVertexAttribArray( 3 ); + glVertexAttribPointer( 3, 2, GL_FLOAT, GL_FALSE, + 0, (void*) offset ); + } + + if ( flags & COLOR_A ) + { + u64 offset = _get_offset( geo, flags & COLOR_A); + u64 current_size = 4 * sizeof(u8) * geo->n_indices; + glBufferSubData( GL_ARRAY_BUFFER, offset, + current_size, + &(host_data->colors_a[0]) ); + glEnableVertexAttribArray( 4 ); + glVertexAttribPointer( 4, 4, GL_UNSIGNED_BYTE, GL_TRUE, + 0, (void*) offset ); + } + + if ( flags & COLOR_B ) + { + u64 offset = _get_offset( geo, flags & COLOR_B); + u64 current_size = 4 * sizeof(u8) * geo->n_indices; + glBufferSubData( GL_ARRAY_BUFFER, offset, + current_size, + &(host_data->colors_b[0]) ); + glEnableVertexAttribArray( 5 ); + glVertexAttribPointer( 5, 4, GL_UNSIGNED_BYTE, GL_TRUE, + 0, (void*) offset ); + } + + if ( flags & COLOR_C ) + { + u64 offset = _get_offset( geo, flags & COLOR_C); + u64 current_size = 4 * sizeof(u8) * geo->n_indices; + glBufferSubData( GL_ARRAY_BUFFER, offset, + current_size, + &(host_data->colors_c[0]) ); + glEnableVertexAttribArray( 6 ); + glVertexAttribPointer( 6, 4, GL_UNSIGNED_BYTE, GL_TRUE, + 0, (void*) offset ); + } + + if ( flags & COLOR_D ) + { + u64 offset = _get_offset( geo, flags & COLOR_D); + u64 current_size = 4 * sizeof(u8) * geo->n_indices; + glBufferSubData( GL_ARRAY_BUFFER, offset, + current_size, + &(host_data->colors_d)[0] ); + glEnableVertexAttribArray( 7 ); + glVertexAttribPointer( 7, 4, GL_UNSIGNED_BYTE, GL_TRUE, + 0, (void*) offset ); + } + + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0 ); + + return 1; +} + +// TODO: Errors if creating data fails!! +i32 bsc:: +init_gpu_geo ( const geometry_data * host_data, + gpu_geometry * geo, + const i32 flags ) +{ + // Always use position + assert( flags & POSITION ); + + glGenVertexArrays( 1, &(geo->vao) ); + glGenBuffers( 1, &(geo->vbo) ); + if ( flags & STRUCTURED ) + { + glGenBuffers( 1, &(geo->ebo) ); + } + + // Initialize empty buffer + glBindVertexArray( geo->vao ); + glBindBuffer( GL_ARRAY_BUFFER, geo->vbo ); + + u64 buf_size = 0; + if ( flags & POSITION ) buf_size += 3 * sizeof(r32); + if ( flags & NORMAL ) buf_size += 3 * sizeof(r32); + if ( flags & TANGENT ) buf_size += 3 * sizeof(r32); + if ( flags & TEX_COORD ) buf_size += 2 * sizeof(r32); + if ( flags & COLOR_A ) buf_size += 4 * sizeof(u8); + if ( flags & COLOR_B ) buf_size += 4 * sizeof(u8); + if ( flags & COLOR_C ) buf_size += 4 * sizeof(u8); + if ( flags & COLOR_D ) buf_size += 4 * sizeof(u8); + buf_size *= host_data->n_vertices; + + glBufferData( GL_ARRAY_BUFFER, buf_size, NULL, GL_STATIC_DRAW); + + geo->flags = flags; + geo->n_indices = host_data->n_vertices; + geo->n_elements = host_data->n_elements; + geo->buffer_size = buf_size; + + if ( !update_gpu_geo( host_data, geo, flags ) ) + { + return 0; + } + + if ( flags & STRUCTURED ) + { + glBindVertexArray( geo->vao ); + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, geo->ebo ); + glBufferData( GL_ELEMENT_ARRAY_BUFFER, + geo->n_elements * sizeof( u32 ), + &(host_data->indices[0]), + GL_STATIC_DRAW ); + } + + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0 ); + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); + return 1; +} + +i32 bsc:: +free_gpu_geo( gpu_geometry * geo ) +{ + glDeleteBuffers(1, &(geo->vbo) ); + if ( geo->flags & STRUCTURED ) + { + glDeleteBuffers(1, &(geo->ebo) ); + } + glDeleteVertexArrays( 1, &(geo->vao) ); + geo->vao = -1; + geo->vbo = -1; + geo->ebo = -1; + geo->n_indices = -1; + geo->n_elements = -1; + return 1; +} + +void bsc:: +draw( gpu_geometry * geo, + GLenum draw_mode ) +{ + GeometryPropertiesFlags flags = geo->flags; + + glBindVertexArray( geo->vao ); + + if ( flags & STRUCTURED ) + { + glDrawElements( draw_mode, geo->n_elements, GL_UNSIGNED_INT, 0 ); + } + else + { + glDrawArrays( draw_mode, 0, geo->n_indices ); + } + + glBindVertexArray( 0 ); +} + +// TEXTURES +void bsc:: +update_gpu_tex( const u8 * data, + gpu_texture * tex ) +{ + glActiveTexture ( GL_TEXTURE0 + tex->unit ); + glBindTexture( GL_TEXTURE_2D, tex->id ); + + GLint internal_format; + GLenum format = 0; + switch( tex->n_comp ) + { + case 1: + internal_format = GL_R8; + format = GL_RED; + break; + case 2: + internal_format = GL_RG; + break; + case 3: + internal_format = GL_RGB; + format = GL_RGB; + break; + case 4: + internal_format = GL_RGBA; + format = GL_RGBA; + break; + default: + internal_format = GL_RGB; + format = GL_RGB; + } + + glTexImage2D( GL_TEXTURE_2D, 0, internal_format, + tex->width, tex->height, 0, format, GL_UNSIGNED_BYTE, data ); + glBindTexture( GL_TEXTURE_2D, 0 ); +} + +void bsc:: +init_gpu_tex( const u8 * data, + const i32 w, + const i32 h, + const i32 n_comp, + gpu_texture * tex, + const u32 unit ) +{ + tex->width = w; + tex->height = h; + tex->n_comp = n_comp; + tex->type = GL_UNSIGNED_BYTE; + tex->unit = unit; + glGenTextures( 1, &tex->id ); + + glActiveTexture ( GL_TEXTURE0 + tex->unit ); + glBindTexture( GL_TEXTURE_2D, tex->id ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + update_gpu_tex( data, tex ); + + glBindTexture( GL_TEXTURE_2D, 0 ); +} + +void bsc:: +update_gpu_tex( const u16 * data, + gpu_texture * tex ) +{ + assert( tex->n_comp > 0 && tex->n_comp <= 1 ); // TODO: Custom asserts? + + glActiveTexture ( GL_TEXTURE0 + tex->unit ); + glBindTexture( GL_TEXTURE_2D, tex->id ); + + GLint internal_format; + GLenum format; + switch( tex->n_comp ) + { + case 1: + internal_format = GL_R16; + format = GL_RED; + break; + case 2: + internal_format = GL_RG16; + format = GL_RG; + break; + case 3: + internal_format = GL_RGB16; + format = GL_RGB; + break; + case 4: + internal_format = GL_RGBA16; + format = GL_RGBA; + break; + default: + internal_format = GL_RGB; + format = GL_RGB; + } + + glTexImage2D( GL_TEXTURE_2D, 0, internal_format, + tex->width, tex->height, 0, format, GL_UNSIGNED_SHORT, data ); + glBindTexture( GL_TEXTURE_2D, 0 ); +} + +void bsc:: +init_gpu_tex( const u16 * data, + const i32 w, + const i32 h, + const i32 n_comp, + gpu_texture * tex, + const u32 unit ) +{ + tex->width = w; + tex->height = h; + tex->n_comp = n_comp; + tex->type = GL_UNSIGNED_SHORT; + tex->unit = unit; + glGenTextures( 1, &tex->id ); + + glActiveTexture ( GL_TEXTURE0 + tex->unit ); + glBindTexture( GL_TEXTURE_2D, tex->id ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + update_gpu_tex( data, tex ); + + glBindTexture( GL_TEXTURE_2D, 0 ); +} + +// TODO: Pass type, based on what exactly we want +// Need to build over opengl here. +// void bsc:: +// init_gpu_tex( const i32 w, +// const i32 h, +// const i32 n_comp, +// const InternalDataType type, +// gpu_texture * tex, +// const u32 unit ) +// { +// tex->width = w; +// tex->height = h; +// tex->n_comp = n_comp; +// tex->type = type; +// tex->unit = unit; +// glGenTextures( 1, &tex->id ); + +// glActiveTexture ( GL_TEXTURE0 + tex->unit ); +// glBindTexture( GL_TEXTURE_2D, tex->id ); +// glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); +// glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + +// GLint internal_format; +// GLenum format; + +// switch( tex->n_comp ) +// { +// case 1: +// format = GL_RED; +// break; +// case 2: +// format = GL_RG; +// break; +// case 3: +// format = GL_RGB; +// break; +// case 4: +// format = GL_RGBA; +// break; +// default: +// format = GL_RGB; +// } + +// // based on format decide internal format +// // switch ( tex->type ) +// // { +// // case U8: +// // PPCAT( ) +// // break; +// // default: +// // internal_format = GL_RGB +// // } +// glTexImage2D( GL_TEXTURE_2D, +// 0, +// internal_format, // TODO: should depend on format + n_comp +// tex->width, +// tex->height, +// 0, +// format, // TODO: Same +// tex->data_type, // THIS SHOULD BE FORMAT +// NULL ); + +// glBindTexture( GL_TEXTURE_2D, 0 ); +// } + + +void bsc:: +use_texture( const gpu_texture * tex) +{ + glActiveTexture( GL_TEXTURE0 + tex->unit ); + glBindTexture( GL_TEXTURE_2D, tex->id ); +} + +void bsc:: +free_gpu_tex( gpu_texture * tex ) +{ + glDeleteTextures( 1, &tex->id ); + tex->id = 0; +} + +//FrameBufferss + +// void bsc:: +// init_framebuffer( const i32 width, const i32 height, gpu_framebuffer * fb ) +// { +// glGenFramebuffers( 1, &(fb->id) ); +// fb->width = width; +// fb->height = height; +// init_gpu_tex( width, height, &(fb->tex), 1 ); +// glFramebufferTexture2D( GL_FRAMEBUFFER, +// GL_COLOR_ATTACHMENT0, +// GL_TEXTURE_2D, +// fb->tex.id, +// 0 ); +// glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->tex.id, 0 ); + +// // NOTE: If needed the rbo should be created here!! +// bool auto_depth = false; +// if ( auto_depth ) +// { +// // CREATE RBO +// } +// } + +// // TODO: In OpenGL framebuffer can be GL_READ_FRAMEBUFFER or GL_DRAW_FRAMEBUFFER +// void bsc:: +// use_framebuffer( gpu_framebuffer * fb ) +// { +// glBindFramebuffer( GL_FRAMEBUFFER, fb->id ); +// } + +// void bsc:: +// free_framebuffer( gpu_framebuffer * fb ) +// { +// glDeleteFramebuffers( 1, &(fb->id) ); +// } + +// // TODO: Format? +// void bsc:: +// init_renderbuffer( const i32 width, const i32 height, gpu_renderbuffer * rb ) +// { +// glGenRenderbuffers(1, &(rb->id) ); +// rb->width = width; +// rb->height = height; +// glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); +// // This will use currently bound framebuffer!! +// glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb->id ); +// } + +// void bsc:: +// use_renderbuffer( gpu_renderbuffer * rb ) +// { +// glBindRenderbuffer(GL_RENDERBUFFER, rb->id ); +// } + +// void bsc:: +// free_renderbuffer( gpu_renderbuffer * rb ) +// { +// glDeleteRenderbuffers( 1, &(rb->id) ); +// } + +#endif //BSC_IMPLEMENTATION \ No newline at end of file diff --git a/CameraParameterEstimation/apps/basics/gfx/image.h b/CameraParameterEstimation/apps/basics/gfx/image.h new file mode 100644 index 0000000..ec152ef --- /dev/null +++ b/CameraParameterEstimation/apps/basics/gfx/image.h @@ -0,0 +1,525 @@ +#pragma once + +// NOTE: This image class assumes image with top-left as the origin. This +// is unlike OpenGL, which uses bottom-right, but is consistent with how image +// formats store this info. Possibly will need to change that if deemed necessary. +// Note that this implies left-handed coordinate system. + +//////////////////////////////////////////////////////////////////////////////// +// Interface +//////////////////////////////////////////////////////////////////////////////// + +#ifndef BSC_IMAGE_H +#define BSC_IMAGE_H + +namespace bsc +{ + template + struct image + { + i32 width; + i32 height; + i32 ncomp; + i32 rowsize; + + T * data; + + image( void ); + image( i32 w, i32 h, i32 ncomp ); + image( i32 w, i32 h, i32 ncomp, T * data ); + image( const image &other ); + image( const char * filename ); + ~image(); + + image & operator= ( const image & other); + + const T* at( i32 i ) const; + T* at( i32 i ); + const T* at( i32 x, i32 y ) const; + T* at( i32 x, i32 y ); + + const T* operator()( i32 i ) const; + T* operator()( i32 i ); + const T* operator()( i32 x, i32 y ) const; + T* operator()( i32 x, i32 y ); + + void resize( i32 w, i32 h ); + + // TODO: those should be out of this struct + void vert_flip(); + T maximum(); + T minimum(); + i32 read( const char * filename ); + i32 write( const char * filename ); + }; + + typedef image img; + typedef image img_u8; + typedef image img_u16; + typedef image img_r32; +} + +#endif // BSC_IMAGE_H + +//////////////////////////////////////////////////////////////////////////////// +// Implementation +//////////////////////////////////////////////////////////////////////////////// +#ifdef BSC_IMPLEMENTATION + +template +bsc::image:: +image ( void ) : width( 0 ), + height( 0 ), + ncomp( 0 ), + rowsize( 0 ), + data( nullptr ) +{ + +} + +template +bsc::image:: +image ( i32 w, i32 h, i32 n ) : width( w ), + height( h ), + ncomp( n ) +{ + this->rowsize = n * w; + this->data = (T*)calloc( rowsize * h, sizeof( T ) ); +} + +template +bsc::image:: +image ( i32 w, i32 h, i32 n, T * d ) : width( w ), + height( h ), + ncomp( n ), + data( nullptr ) +{ + this->rowsize = w * n; + i32 mem_size = rowsize * h * sizeof( T ); + data = (T*)malloc( mem_size ); + memcpy(data, d, mem_size ); +} + +template +bsc::image:: +image ( const bsc::image & other ) : width( other.width ), + height( other.height ), + ncomp( other.ncomp ), + rowsize( other.rowsize ), + data( nullptr ) +{ + i32 mem_size = width * height * ncomp * sizeof( T ); + data = (T*)malloc( mem_size ); + memcpy( data, other.data, mem_size ); +} + +template +bsc::image:: +image ( const char * filename ): width( 0 ), + height( 0 ), + ncomp( 0 ), + data( nullptr ) +{ + read( filename ); +} + +template +bsc::image:: +~image () +{ + if ( this->data != nullptr ) free( data ); + this->data = nullptr; + this->width = 0; + this->height = 0; + this->rowsize = 0; + this->ncomp = 0; +} + +template +i32 +read_jpg( const char *filename, bsc::image * img ) +{ + if ( sizeof(T) > 1 ) + { + printf("Image reading warning -> JPEG do not support high precision!\n" ); + } + // jpgs will be assumed to be 3 channel u8 images + img->data = (T*)stbi_load( filename, &(img->width), + &(img->height), + &(img->ncomp), + 3 ); + // TODO: we might need to flip! + // TODO: check what happens if you have single channel + if ( img->data == NULL ) + { + printf("Image reading error -> Could not read image %s\n", filename ); + return 0; + } + return 1; +} + +template +i32 +read_png( const char *filename, bsc::image * img ) +{ + u8 * file_contents = 0; + size_t file_size; + u32 lode_error; + + // load file + lode_error = lodepng_load_file( &file_contents, &file_size, filename ); + if ( lode_error ) + { + printf("Image reading error -> %s\n", lodepng_error_text( lode_error ) ); + return 0; + } + + // inspect header to get the data + LodePNGState state; + lodepng_state_init( &state ); + lode_error = lodepng_inspect( (u32*)&(img->width), + (u32*)&(img->height), + &state, + file_contents, + file_size ); + if ( lode_error ) + { + printf("Image reading error -> %s\n", lodepng_error_text( lode_error ) ); + return 0; + } + + // extract colortype and bit_depth info + LodePNGColorType color_type = state.info_png.color.colortype; + i32 file_bit_depth = state.info_png.color.bitdepth; + + // compare what is in file and where we want to store + i32 type_bit_depth= sizeof(T) * 8; + if ( file_bit_depth > type_bit_depth ) + { + printf( "Image reading warning -> File stores data at higher" + " precision than provided type\n" ); + } + + // decide on number of components + switch( color_type ) + { + case LCT_GREY: + img->ncomp = 1; + break; + case LCT_GREY_ALPHA: + img->ncomp = 2; + break; + case LCT_RGB: + img->ncomp = 3; + break; + case LCT_RGBA: + img->ncomp = 4; + break; + default: + printf("Image reading error -> No support for pallete PNG\n" ); + return 0; + } + + lode_error = lodepng_decode_memory( (u8**)&(img->data), + (u32*)&(img->width), + (u32*)&(img->height), + file_contents, + file_size, + color_type, + type_bit_depth ); + img->rowsize = img->width * img->ncomp; + if ( lode_error ) + { + printf("Image reading error -> %s\n", lodepng_error_text( lode_error ) ); + return 0; + } + + // if file stores high precision data + if ( file_bit_depth > 8 ) + { + i32 total_n_values = img->width * img->height * img->ncomp; + for ( int i = 0 ; i < total_n_values ; ++i ) + { + u16 val = (u16)img->data[i]; + val = ( ((val & 0x00FF ) << 8 ) | + ((val & 0xFF00 ) >> 8 ) ); + img->data[i] = val; + } + } + + return 1; +} + +template +i32 bsc::image:: +read( const char * filename ) +{ + // clear image + // TODO: Realloc if requested image is different size... + width = 0; + height = 0; + ncomp = 0; + if ( data != nullptr ) { free( data ); data=nullptr; } + + // determine extension + char * period = strrchr( filename, '.' ); + if ( period == NULL ) + { + printf( "Image reading error -> No file extension\n" ); + return 0; + } + char * extension = period + 1; + + // call appropriate function + if ( !strcmp( extension, "jpg" ) || !strcmp( extension, "jpeg") ) + { + return read_jpg( filename, this ); + } + else if ( !strcmp( extension, "png") ) + { + return read_png ( filename, this ); + } + else + { + printf( "Image reading error -> Unsuported image format\n" ); + return 0; + } +} + +// TODO(maciej): This function should propably not be templated? +template +i32 +write_jpg( const char *filename, bsc::image * img ) +{ + if ( sizeof(T) > 1 ) + { + printf("Image writing warning -> JPG cannot store high precision!" + "Possible corruption!\n" ); + // TODO(maciej): just copy data temporarily and store as 8bits? + } + if ( img->ncomp != 3 && img->ncomp != 4 ) + { + printf("%d\nImage writing error -> Unsupported number of components\n", img->ncomp ); + return 0; + } + // NOTE(maciej): What happens if we try to do single channel jpg? + int success = tje_encode_to_file_at_quality( filename, 2, + img->width, + img->height, + img->ncomp, + (const u8*)img->data ); + if ( !success ) + { + printf("Image writing error -> Could not write file %s\n", filename ); + } + return success; +} + +template +i32 +write_png( const char *filename, bsc::image * img ) +{ + i32 type_bit_depth = sizeof(T) * 8; + if ( type_bit_depth > 16 ) + { + printf("Image writing warning -> PNG cannot store precision higher than" + " 16 bits. Possible loss of precision\n" ); + // TODO(maciej): Auto conversion? + type_bit_depth = 16; + } + LodePNGColorType color_type = LCT_RGB; + switch ( img->ncomp ) + { + case 1: + color_type = LCT_GREY; + break; + case 2: + color_type = LCT_GREY_ALPHA; + break; + case 3: + color_type = LCT_RGB; + break; + case 4: + color_type = LCT_RGBA; + break; + default: + printf( "Image writing error -> Image number of components is" + " unsupported by PNG format\n" ); + return 0; + } + + if ( type_bit_depth > 8 ) + { + i32 total_n_values = img->width * img->height * img->ncomp; + for ( int i = 0 ; i < total_n_values ; ++i ) + { + u16 val = (u16)img->data[i]; + val = ( ((val & 0x00FF ) << 8 ) | + ((val & 0xFF00 ) >> 8 ) ); + img->data[i] = val; + } + } + + u32 lode_error = lodepng_encode_file( filename, + (u8*)img->data, + (u32)(img->width), + (u32)(img->height), + color_type, + type_bit_depth ); + if ( lode_error ) + { + printf("Image writing error -> %s\n", lodepng_error_text( lode_error ) ); + return 0; + } + + return 1; +} + +template +i32 bsc::image:: +write( const char * filename ) +{ + char * period = strrchr( filename, '.' ); + if ( period == NULL ) + { + error( "Image writing error", __LINE__, "No file extension" ); + return 0; + } + + char * extension = period + 1; + if ( !strcmp( extension, "jpg" ) || !strcmp( extension, "jpeg") ) + { + return write_jpg( filename, this ); + } + else if ( !strcmp( extension, "png") ) + { + return write_png( filename, this ); + } + else + { + error( "Image writing error", __LINE__, "Unsupproted image format" ); + return 0; + } +} + +template +void bsc::image:: +vert_flip() +{ + for ( int j = 0 ; j < height / 2 ; ++j ) + { + for ( int i = 0 ; i < width ; ++i ) + { + T * val_A = (*this)( i, j ); + T * val_B = (*this)( i, height - j - 1 ); + for ( int k = 0 ; k < ncomp; ++k ) + { + swap( *(val_A+k), *(val_B+k) ); + } + } + } +} + + +template +T bsc::image:: +maximum() +{ + T max = -1e9; + for ( int i = 0 ; i < height * rowsize ; ++i ) + { + if ( data[i] > max ) + { + max = data[i]; + } + } + return max; +} + +template +T bsc::image:: +minimum() +{ + T min= 1e9; + for ( int i = 0 ; i < height * rowsize ; ++i ) + { + if ( data[i] < min ) + { + min = data[i]; + } + } + return min; +} + +template +inline bsc::image & bsc::image:: +operator= ( const bsc::image & other ) +{ + if ( this->data ) free( this->data ); + u64 size = other.width * other.height * other.ncomp * sizeof(T); + this->width = other.width; + this->height = other.height; + this->ncomp = other.ncomp; + this->rowsize = other.rowsize; + this->data = (T*)malloc( size ); + memcpy( this->data, other.data, size ); + return *this; +} + +template +inline const T* bsc::image:: +operator() ( i32 i ) const +{ + return &(this->data[ i ]); +} + +template +inline T* bsc::image:: +operator() ( i32 i ) +{ + return &(this->data[ i ]); +} + +template +inline const T* bsc::image:: +operator() ( i32 x, i32 y ) const +{ + return &(this->data[ y * this->rowsize + x * this->ncomp ]); +} + +template +inline T* bsc::image:: +operator() ( i32 x, i32 y ) +{ + return &(this->data[ y * this->rowsize + x * this->ncomp ]); +} + +template +inline const T* bsc::image:: +at ( i32 i ) const +{ + return &(this->data[ i ]); +} + +template +inline T* bsc::image:: +at ( i32 i ) +{ + return &(this->data[ i ]); +} + +template +inline const T* bsc::image:: +at ( i32 x, i32 y ) const +{ + return &(this->data[ this->ncomp * (y * this->width + x) ]); +} + +template +inline T* bsc::image:: +at ( i32 x, i32 y ) +{ + return &( this->data[ this->ncomp * (y * this->width + x )] ); +} + +#endif //BSC_IMAGE_H \ No newline at end of file diff --git a/CameraParameterEstimation/apps/basics/gfx/param_shapes.h b/CameraParameterEstimation/apps/basics/gfx/param_shapes.h new file mode 100644 index 0000000..be8dccf --- /dev/null +++ b/CameraParameterEstimation/apps/basics/gfx/param_shapes.h @@ -0,0 +1,414 @@ +#pragma once + +namespace bsc +{ +/* + gpu_asset create_plane( const u32 div_u = 1, const u32 div_v = 1 ); + gpu_asset create_cube(); + gpu_asset create_sphere( const u32 div_u = 32, const u32 div_v = 32 ); +*/ + + void create_extrusion( gpu_geometry * geo, + const vec3 * line_points, const i32 n_line_points, + const vec2 * shape_points, const i32 n_shape_points, + const r32 size, const vec3i * color_map ); + +}; + +#ifdef BSC_IMPLEMENTATION + +namespace bsc +{ + + void + create_extrusion( gpu_geometry * geo, + const vec3 * line_points, const i32 n_line_points, + const vec2 * shape_points, const i32 n_shape_points, + const r32 size, const vec3i * color_map ) + { + vec3 *tmp_pos = (vec3 *)malloc(n_shape_points * n_line_points * sizeof(vec3)); + vec4 *tmp_col = (vec4 *)malloc(n_line_points * sizeof(vec4)); + + for (i32 i = 0; i < n_line_points; i++) + { + // calculate current and next color + r32 cur_offset = 8.0f * (r32)i / (r32)n_line_points; + i32 col_idx = floor(cur_offset); + r32 b = cur_offset - col_idx; + r32 a = 1.0 - b; + + vec3 color_a( color_map[col_idx].r, + color_map[col_idx].g, + color_map[col_idx].b); + vec3 color_b( color_map[col_idx + 1].r, + color_map[col_idx + 1].g, + color_map[col_idx + 1].b); + + // figure out the base + vec3 point_a = line_points[i]; + vec3 point_b, point_c, n1, n2; + if (i == n_line_points - 1) + { + point_c = line_points[i-1]; + n2 = point_a - point_c; + point_b = point_a - n2; + n1 = point_b - point_a; + } + if (i == 0) + { + point_b = line_points[i+1]; + n1 = point_b - point_a; + point_c = point_a - n1; + n2 = point_a - point_c; + } + else + { + point_b = vec3(line_points[i+1]); + point_c = vec3(line_points[i-1]); + n1 = point_b - point_a; + n2 = point_a - point_c; + } + + vec3 up(0, 1, 0); + vec3 u1 = normalize(cross(up, n1)); + vec3 u2 = normalize(cross(up, n2)); + vec3 u = normalize(u1 + u2); + vec3 v = normalize(cross(u, n1)); + + // with the base we can push any shape really. + for ( i32 j = 0 ; j < n_shape_points ; ++j ) + { + r32 u_mul = shape_points[j].x * size; + r32 v_mul = shape_points[j].y * size; + tmp_pos[ n_shape_points * i + j ] = point_a + u_mul * u + v_mul * v; + } + // tmp_pos[4 * i + 0] = point_a + size * v; + // tmp_pos[4 * i + 1] = point_a + size * u; + // tmp_pos[4 * i + 2] = point_a - size * v; + // tmp_pos[4 * i + 3] = point_a - size * u; + + tmp_col[i] = vec4(a * color_a + b * color_b, 255.0f); + } + + const int n_tri_per_seg = n_shape_points * 2; + r32 positions[n_tri_per_seg * 3 * 3 * (n_line_points - 1)]; + u8 colors[n_tri_per_seg * 3 * 4 * (n_line_points - 1)]; + + i32 pos_idx = 0; + i32 col_idx = 0; + + // TODO: Use DrawElements?! + for (int i = 0; i < n_line_points - 1; ++i) + { + i32 ba = n_shape_points * i; + i32 bb = n_shape_points * (i + 1); + + for (int j = 0; j < n_shape_points; ++j) + { + vec3 cur_pos[6]; + vec4 cur_col[6]; + + cur_pos[0] = tmp_pos[ba + j]; + cur_pos[1] = tmp_pos[ba + (j + 1) % n_shape_points]; + cur_pos[2] = tmp_pos[bb + j]; + + cur_pos[3] = tmp_pos[ba + (j + 1) % n_shape_points]; + cur_pos[4] = tmp_pos[bb + j]; + cur_pos[5] = tmp_pos[bb + (j + 1) % n_shape_points]; + + cur_col[0] = tmp_col[i]; + cur_col[1] = tmp_col[i]; + cur_col[2] = tmp_col[i + 1]; + + cur_col[3] = tmp_col[i]; + cur_col[4] = tmp_col[i + 1]; + cur_col[5] = tmp_col[i + 1]; + + r32 *pos_cpy_loc = (r32 *)&(cur_pos[0]); + r32 *col_cpy_loc = (r32 *)&(cur_col[0]); + + for (i32 k = 0; k < 3 * 6; ++k) + { + positions[pos_idx++] = pos_cpy_loc[k]; + } + + for (i32 k = 0; k < 4 * 6; ++k) + { + colors[col_idx++] = (u8)col_cpy_loc[k]; + } + } + } + + bsc::geometry_data extrusion; + extrusion.positions = positions; + extrusion.colors_a = colors; + extrusion.n_vertices = n_tri_per_seg * 3 * (n_line_points - 1); + + bsc::init_gpu_geo(&extrusion, geo, POSITION | COLOR_A ); + free(tmp_pos); + free(tmp_col); + } + + +/* + gpu_asset + create_plane( const u32 div_u, const u32 div_v ) + { + // storage + const u32 vert_count = (div_u + 1) * (div_v + 1); + const u32 tri_count = 2 * div_u * div_v; + r32 positions[ 3 * vert_count ]; + r32 texcoords[ 2 * vert_count ]; + r32 normals[ 3 * vert_count ]; + r32 tangents[ 3 * vert_count ]; + u32 indices[ 2 * tri_count ]; + + // generate vertex data + for ( u32 v = 0 ; v < div_v + 1 ; ++v ) + { + u32 base = v * (div_u + 1); + for ( u32 u = 0 ; u < div_u + 1 ; ++u ) + { + u32 idx = base + u; + texcoords[ 2 * idx + 0 ] = (r32)u / div_u; + texcoords[ 2 * idx + 1 ] = (r32)v / div_v; + + positions[ 3 * idx + 0 ] = -0.5f + texcoords[ 2 * idx + 0 ]; + positions[ 3 * idx + 1 ] = -0.5f + texcoords[ 2 * idx + 1 ]; + positions[ 3 * idx + 2 ] = 0.0f; + + normals[ 3 * idx + 0 ] = 0.0f; + normals[ 3 * idx + 1 ] = 0.0f; + normals[ 3 * idx + 2 ] = 1.0f; + + tangents[ 3 * idx + 0 ] = 0.0f; + tangents[ 3 * idx + 1 ] = 1.0f; + tangents[ 3 * idx + 2 ] = 0.0f; + } + } + + // generate face data + int idx = 0; + for ( u32 v = 0 ; v < div_v ; ++v ) + { + u32 row_1 = v * ( div_u + 1 ); + u32 row_2 = ( v + 1 ) * ( div_u + 1 ); + for ( u32 u = 0 ; u < div_u ; ++u ) + { + u32 a = row_1 + u; + u32 b = row_1 + u + 1; + u32 c = row_2 + u; + u32 d = row_2 + u + 1; + + indices[ idx++ ] = a; + indices[ idx++ ] = b; + indices[ idx++ ] = c; + indices[ idx++ ] = c; + indices[ idx++ ] = b; + indices[ idx++ ] = d; + } + } + + // store in a helper structure + mesh_data host_plane; + host_plane.positions = &(positions[ 0 ]); + host_plane.texcoords = &(texcoords[ 0 ]); + host_plane.normals = &(normals[ 0 ]); + host_plane.tangents = &(tangents[ 0 ]); + host_plane.indices = &(indices[ 0 ]); + + // upload to gpu + gpu_asset device_plane; + device_plane.vert_count = vert_count; + device_plane.tri_count = tri_count; + init_gpu_mem( &host_plane, &device_plane ); + + return device_plane; + } + + gpu_asset + create_sphere( const u32 div_u, const u32 div_v ) + { + // storage + const u32 vert_count = (div_u + 1) * (div_v + 1); + const u32 tri_count = 2 * div_u * div_v; + r32 positions[ 3 * vert_count ]; + r32 texcoords[ 2 * vert_count ]; + r32 normals[ 3 * vert_count ]; + r32 tangents[ 3 * vert_count ]; + u32 indices[ 2 * tri_count ]; + + // generate vertex data + for ( u32 v = 0 ; v < div_v + 1 ; ++v ) + { + u32 base = v * (div_u + 1); + for ( u32 u = 0 ; u < div_u + 1 ; ++u ) + { + u32 idx = base + u; + texcoords[ 2 * idx + 0 ] = (r32)u / div_u; + texcoords[ 2 * idx + 1 ] = (r32)v / div_v; + float phi = texcoords[ 2 * idx + 0 ] * M_PI; + float theta = texcoords[ 2 * idx + 1 ] * 2 * M_PI; + + positions[ 3 * idx + 0 ] = cosf(theta) * sinf(phi); + positions[ 3 * idx + 1 ] = sinf(theta) * sinf(phi); + positions[ 3 * idx + 2 ] = cosf(phi); + + tangents[ 3 * idx + 0 ] = cosf(theta + M_PI/2.0f) * sinf(phi); + tangents[ 3 * idx + 1 ] = sinf(theta + M_PI/2.0f) * sinf(phi); + tangents[ 3 * idx + 2 ] = cosf(phi); + + normals[ 3 * idx + 0 ] = positions[ 3 * idx + 0 ]; + normals[ 3 * idx + 1 ] = positions[ 3 * idx + 1 ]; + normals[ 3 * idx + 2 ] = positions[ 3 * idx + 2 ]; + } + } + + // generate face data + int idx = 0; + for ( u32 v = 0 ; v < div_v ; ++v ) + { + u32 row_1 = v * ( div_u + 1 ); + u32 row_2 = ( v + 1 ) * ( div_u + 1 ); + for ( u32 u = 0 ; u < div_u ; ++u ) + { + u32 a = row_1 + u; + u32 b = row_1 + u + 1; + u32 c = row_2 + u; + u32 d = row_2 + u + 1; + + indices[ idx++ ] = a; + indices[ idx++ ] = b; + indices[ idx++ ] = c; + indices[ idx++ ] = b; + indices[ idx++ ] = d; + indices[ idx++ ] = c; + } + } + + // store in a helper structure + mesh_data host_sphere; + host_sphere.positions = &(positions[ 0 ]); + host_sphere.texcoords = &(texcoords[ 0 ]); + host_sphere.normals = &(normals[ 0 ]); + host_sphere.tangents = &(tangents[ 0 ]); + host_sphere.indices = &(indices[ 0 ]); + + // upload to gpu + gpu_asset device_sphere; + device_sphere.vert_count = vert_count; + device_sphere.tri_count = tri_count; + init_gpu_mem( &host_sphere, &device_sphere ); + + return device_sphere; + } + + +// Possibly it would be better to simply create a function +// that creates simple sphere with shared normals, and then add +// subdivision function, and unwelding function. +// For now this works + gpu_asset + create_cube() + { + // // storage + const u32 vert_count = 24; + const u32 tri_count = 12; + r32 positions[ 3 * vert_count ] = + { + // FRONT + -0.5, 0.5, -0.5, // 0 + 0.5, 0.5, -0.5, // 1 + -0.5, 0.5, 0.5, // 2 + 0.5, 0.5, 0.5, // 3 + // BACK + -0.5, -0.5, -0.5, // 4 + 0.5, -0.5, -0.5, // 5 + -0.5, -0.5, 0.5, // 6 + 0.5, -0.5, 0.5, // 7 + // LEFT + 0.5, 0.5, -0.5, // 8 + 0.5, -0.5, -0.5, // 9 + 0.5, 0.5, 0.5, // 10 + 0.5, -0.5, 0.5, // 11 + // RIGHT + -0.5, 0.5, -0.5, // 12 + -0.5, -0.5, -0.5, // 13 + -0.5, 0.5, 0.5, // 14 + -0.5, -0.5, 0.5, // 15 + // TOP + -0.5, 0.5, 0.5, // 16 + 0.5, 0.5, 0.5, // 17 + 0.5, -0.5, 0.5, // 18 + -0.5, -0.5, 0.5, // 19 + // BOTTOM + -0.5, 0.5, -0.5, // 20 + 0.5, 0.5, -0.5, // 21 + 0.5, -0.5, -0.5, // 22 + -0.5, -0.5, -0.5, // 23 + }; + r32 texcoords[ 2 * vert_count ]; // TODO + r32 normals[ 3 * vert_count ] = + { + // FRONT + 0.0, 1.0, 0.0, // 0 + 0.0, 1.0, 0.0, // 1 + 0.0, 1.0, 0.0, // 2 + 0.0, 1.0, 0.0, // 3 + // BACK + 0.0, -1.0, 0.0, // 4 + 0.0, -1.0, 0.0, // 5 + 0.0, -1.0, 0.0, // 6 + 0.0, -1.0, 0.0, // 7 + // LEFT + 1.0, 0.0, 0.0, // 8 + 1.0, 0.0, 0.0, // 9 + 1.0, 0.0, 0.0, // 10 + 1.0, 0.0, 0.0, // 11 + // RIGHT + -1.0, 0.0, 0.0, // 12 + -1.0, 0.0, 0.0, // 13 + -1.0, 0.0, 0.0, // 14 + -1.0, 0.0, 0.0, // 15 + // TOP + 0.0, 0.0, 1.0, // 16 + 0.0, 0.0, 1.0, // 17 + 0.0, 0.0, 1.0, // 18 + 0.0, 0.0, 1.0, // 19 + // BOTTOM + 0.0, 0.0, -1.0, // 20 + 0.0, 0.0, -1.0, // 21 + 0.0, 0.0, -1.0, // 22 + 0.0, 0.0, -1.0, // 23 + }; + r32 tangents[ 3 * vert_count ]; // TODO + u32 indices[ 3 * tri_count ] = + { + 0, 3, 1, 0, 2, 3, // front + 5, 6, 4, 5, 7, 6, // back + 8, 11, 9, 8, 10, 11, // left + 12, 13, 14, 13, 15, 14, // right + 16, 18, 17, 16, 19, 18, // top + 20, 21, 22, 20, 22, 23 // bottom + }; + + // store in a helper structure + mesh_data host_cube; + host_cube.positions = &(positions[ 0 ]); + host_cube.texcoords = &(texcoords[ 0 ]); + host_cube.normals = &(normals[ 0 ]); + host_cube.tangents = &(tangents[ 0 ]); + host_cube.indices = &(indices[ 0 ]); + + // // upload to gpu + gpu_asset device_cube; + device_cube.vert_count = vert_count; + device_cube.tri_count = tri_count; + init_gpu_mem( &host_cube, &device_cube ); + + return device_cube; + } +*/ +} + +#endif \ No newline at end of file diff --git a/CameraParameterEstimation/apps/basics/gfx/shader.h b/CameraParameterEstimation/apps/basics/gfx/shader.h new file mode 100644 index 0000000..afd629d --- /dev/null +++ b/CameraParameterEstimation/apps/basics/gfx/shader.h @@ -0,0 +1,572 @@ +// bascis shader program + +// TODO :Modify this to use more modern glProgramPipeline. + +#pragma once + +#define SHADER_HEAD "#version 330 core\n" + +namespace bsc +{ + enum shader_type + { + vertex_shader, + fragment_shader, + geometry_shader, + tess_control_shader, + tess_evaluation_shader + }; + + struct shader + { + GLuint id; + shader_type type; + GLint compiled; + }; + + struct shader_prog + { + GLuint id; + GLint linked; + }; + + // TODO : Should take pointers! + i32 create_shader_prog_from_source(const char *vertex_shader_source, + const char *fragment_shader_source, + shader_prog &p); + i32 create_shader_prog_from_source(const char *vertex_shader_source, + const char *geometry_shader_source, + const char *fragment_shader_source, + shader_prog &p); + + i32 create_shader_prog ( const char * vertex_shader_filename, + const char * fragment_shader_filename, + shader_prog & p ); + + i32 create_shader_prog ( const char * vertex_shader_filename, + const char * geometry_shader_filename, + const char * fragment_shader_filename, + shader_prog & p ); + + i32 compile_shader ( const char * source, shader & s ); + i32 link_program ( const shader & vs, const shader & fs, + shader_prog & p ); + i32 link_program ( const shader & vs, const shader & gs, const shader & fs, + shader_prog & p ); + i32 use_program ( const shader_prog & p ); + + void set_uniform ( const shader_prog & p, const char *attrib_name, r32 val ); + void set_uniform ( const shader_prog & p, const char *attrib_name, i32 val ); + void set_uniform ( const shader_prog & p, const char *attrib_name, u32 val ); + void set_uniform ( const shader_prog & p, const char *attrib_name, bool val ); + + void set_uniform ( const shader_prog & p, + const char *attrib_name, const r32 * val, + const u32 count = 1 ); + void set_uniform ( const shader_prog & p, + const char *attrib_name, const i32 * val, + const u32 count = 1 ); + void set_uniform ( const shader_prog & p, + const char *attrib_name, const u32 * val, + const u32 count = 1 ); + void set_uniform ( const shader_prog & p, + const char *attrib_name, const bool * val, + const u32 count = 1 ); + + void set_uniform ( const shader_prog & p, + const char *attrib_name, + float x, float y, float z); + void set_uniform ( const shader_prog & p, + const char *attrib_name, const vec2f &v ); + void set_uniform ( const shader_prog & p, + const char *attrib_name, const vec2f *v, + const u32 count = 1 ); + void set_uniform ( const shader_prog & p, + const char *attrib_name, const vec3f &v ); + void set_uniform ( const shader_prog & p, + const char *attrib_name, const vec3f *v, + const u32 count = 1 ); + void set_uniform ( const shader_prog & p, + const char *attrib_name, const vec4f &v); + void set_uniform ( const shader_prog & p, + const char *attrib_name, const vec4f *v, + const u32 count = 1 ); + + void set_uniform ( const shader_prog & p, + const char *attrib_name, const mat3f &m ); + void set_uniform ( const shader_prog & p, + const char *attrib_name, const mat3f *m, + const u32 count = 1 ); + void set_uniform ( const shader_prog & p, + const char *attrib_name, const mat4f &m ); + void set_uniform ( const shader_prog & p, + const char *attrib_name, const mat4f *m, + const u32 count = 1 ); + + // void PrintActiveUniforms( const shader_prog & p ); + // void PrintActiveAttribs( const shader_prog & p ); + + // void bindAttribLocation( GLuint location, const char * name); + // void bindFragDataLocation( GLuint location, const char * name ); + +} + +#ifdef BSC_IMPLEMENTATION + +// TODO: Move it to a dedication file loading location +inline i32 +text_file_read ( const char * filename, char ** file_contents ) +{ + FILE *fp; + long l_size; + + fp = fopen ( filename , "r" ); + if( !fp ) perror(filename),exit(1); + + fseek( fp , 0L , SEEK_END); + l_size = ftell( fp ); + rewind( fp ); + + // allocate memory for entire content + (*file_contents) = (char*)calloc( 1, l_size + 1 ); + if ( !(*file_contents) ) + { + fclose( fp ); + fputs( "memory alloc fails", stderr ); + exit( 1 ); + } + + // copy the file into the buffer + if ( fread( (*file_contents), l_size, 1, fp) != 1 ) + { + fclose(fp); + free( (*file_contents) ); + fputs( "entire read fails",stderr ); + exit( 1 ); + } + + fclose(fp); + return 1; +} + +i32 bsc:: +compile_shader ( const char * source, shader & s ) +{ + switch ( s.type ) { + case bsc::vertex_shader: + s.id = glCreateShader( GL_VERTEX_SHADER ); + break; + case bsc::fragment_shader: + s.id = glCreateShader( GL_FRAGMENT_SHADER ); + break; + + #ifndef __EMSCRIPTEN__ + case bsc::geometry_shader: + s.id = glCreateShader( GL_GEOMETRY_SHADER ); + break; + case bsc::tess_control_shader: + s.id = glCreateShader( GL_TESS_CONTROL_SHADER ); + break; + case bsc::tess_evaluation_shader: + s.id = glCreateShader( GL_TESS_EVALUATION_SHADER ); + break; + #endif + default: + return false; + } + + glShaderSource( s.id, 1, &source, NULL ); + + glCompileShader( s.id ); + glGetShaderiv( s.id, GL_COMPILE_STATUS, &s.compiled ); + + if ( !s.compiled ) + { + GLint log_len; + glGetShaderiv( s.id, GL_INFO_LOG_LENGTH, &log_len ); + if ( log_len > 0 ) + { + char* log_str = (char*) malloc( log_len ); + GLsizei written; + glGetShaderInfoLog( s.id, log_len, &written, log_str ); + char * shader_type_str; + switch ( s.type ) + { + case bsc::vertex_shader: + shader_type_str = (char*)"Vertex Shader"; + break; + case bsc::fragment_shader: + shader_type_str = (char*)"Fragment Shader"; + break; + case bsc::geometry_shader: + shader_type_str = (char*)"Geometry Shader"; + break; + case bsc::tess_control_shader: + shader_type_str = (char*)"Tess Control Shader"; + break; + case bsc::tess_evaluation_shader: + shader_type_str = (char*)"Tess Evaluation Shader"; + break; + } + printf( "%s Compilation Failure :\n%s\n", shader_type_str, log_str ); + free( log_str ); + } + return 0; + } + + return s.compiled; +} + +i32 bsc:: +link_program ( const shader & vs, const shader & fs, shader_prog & p ) +{ + // change to asserts? + if ( !vs.compiled || !fs.compiled ) + { + printf( "Compile shaders before linking program!\n" ); + return 1; + } + + p.id = glCreateProgram(); + if ( p.id == 0 ) + { + printf ( " Failed to create program!\n" ); + return 0; + } + + glAttachShader( p.id, vs.id ); + glAttachShader( p.id, fs.id ); + + glLinkProgram( p.id ); + glGetProgramiv( p.id, GL_LINK_STATUS, &p.linked ); + + if ( !p.linked ) + { + GLint log_len; + glGetProgramiv( p.id, GL_INFO_LOG_LENGTH, &log_len ); + if( log_len > 0 ) + { + char* log_str = (char*) malloc( log_len ); + GLsizei written; + glGetProgramInfoLog( p.id, log_len, &written, log_str ); + printf( "Program Linking Failure : %s\n", log_str ); + free( log_str ); + } + } + + glDetachShader( p.id, fs.id ); + glDetachShader( p.id, vs.id ); + + glDeleteShader( fs.id ); + glDeleteShader( vs.id ); + + return p.linked; +} + +i32 bsc:: +link_program ( const shader & vs, + const shader & gs, + const shader & fs, + shader_prog & p ) +{ + // change to asserts? + if ( !vs.compiled || !fs.compiled ) + { + printf( "Compile shaders before linking program!\n" ); + return 1; + } + + p.id = glCreateProgram(); + if ( p.id == 0 ) + { + printf ( " Failed to create program!\n" ); + return 0; + } + + glAttachShader( p.id, vs.id ); + glAttachShader( p.id, gs.id ); + glAttachShader( p.id, fs.id ); + + glLinkProgram( p.id ); + glGetProgramiv( p.id, GL_LINK_STATUS, &p.linked ); + + if ( !p.linked ) + { + GLint log_len; + glGetProgramiv( p.id, GL_INFO_LOG_LENGTH, &log_len ); + if( log_len > 0 ) + { + char* log_str = (char*) malloc( log_len ); + GLsizei written; + glGetProgramInfoLog( p.id, log_len, &written, log_str ); + printf( "Program Linking Failure : %s\n", log_str ); + free( log_str ); + } + } + + glDetachShader( p.id, fs.id ); + glDetachShader( p.id, gs.id ); + glDetachShader( p.id, vs.id ); + + glDeleteShader( fs.id ); + glDeleteShader( gs.id ); + glDeleteShader( vs.id ); + + return p.linked; +} + +// TODO: Create differentiation for those +i32 bsc:: +create_shader_prog_from_source ( const char * vs_src, + const char * fs_src, + shader_prog & p ) +{ + + shader vs, fs; + vs.type = bsc::vertex_shader; + fs.type = bsc::fragment_shader; + + if ( !compile_shader( vs_src, vs ) ) return 0; + if ( !compile_shader( fs_src, fs ) ) return 0; + if ( !link_program( vs, fs, p ) ) return 0; + + return 1; +} + +i32 bsc:: +create_shader_prog_from_source ( const char * vs_src, + const char * gs_src, + const char * fs_src, + shader_prog & p ) +{ + + shader vs, fs, gs; + vs.type = bsc::vertex_shader; + fs.type = bsc::fragment_shader; + gs.type = bsc::geometry_shader; + + if ( !compile_shader( vs_src, vs ) ) return 0; + if ( !compile_shader( gs_src, gs ) ) return 0; + if ( !compile_shader( fs_src, fs ) ) return 0; + if ( !link_program( vs, gs, fs, p ) ) return 0; + + return 1; +} + +i32 bsc:: +create_shader_prog ( const char * vs_filename, + const char * fs_filename, + shader_prog & p ) +{ + char * vs_source, * fs_source; + text_file_read( vs_filename, &vs_source ); + text_file_read( fs_filename, &fs_source ); + + shader vs, fs; + vs.type = bsc::vertex_shader; + fs.type = bsc::fragment_shader; + + if ( !compile_shader( vs_source, vs ) ) return 0; + if ( !compile_shader( fs_source, fs ) ) return 0; + if ( !link_program( vs, fs, p ) ) return 0; + + free( vs_source ); + free( fs_source ); + + return 1; +} + + +i32 bsc:: +create_shader_prog ( const char * vs_filename, + const char * gs_filename, + const char * fs_filename, + shader_prog & p ) +{ + char * vs_source, * gs_source, * fs_source; + text_file_read( vs_filename, &vs_source ); + text_file_read( gs_filename, &gs_source ); + text_file_read( fs_filename, &fs_source ); + + shader vs, gs, fs; + vs.type = bsc::vertex_shader; + gs.type = bsc::geometry_shader; + fs.type = bsc::fragment_shader; + + if ( !compile_shader( vs_source, vs ) ) return 0; + if ( !compile_shader( gs_source, gs ) ) return 0; + if ( !compile_shader( fs_source, fs ) ) return 0; + if ( !link_program( vs, gs, fs, p ) ) return 0; + + free( vs_source ); + free( gs_source ); + free( fs_source ); + + return 1; +} + +i32 bsc:: +use_program( const shader_prog & p ) +{ + if ( p.linked ) { + glUseProgram( p.id ); + return 1; + } + return 0; +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const vec2f & v) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniform2fv( location, 1, &(v.data[0]) ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const vec2f * v, const u32 count ) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniform2fv( location, count, &( v->data[0] ) ); +} + + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, float x, float y, float z ) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniform3f( location, x, y, z ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const vec3f & v) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniform3fv( location, 1, &(v.data[0]) ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const vec3f * v, const u32 count ) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniform3fv( location, count, &( v->data[0] ) ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const vec4f &v ) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniform4fv( location, 1, &(v.data[0]) ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const vec4f *v, const u32 count ) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniform4fv( location, count, &(v->data[0]) ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const mat3f &m ) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniformMatrix3fv( location, 1, GL_FALSE, &(m.data[0]) ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const mat3f *m, const u32 count ) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniformMatrix3fv( location, count, GL_FALSE, &(m->data[0]) ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const mat4f &m ) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniformMatrix4fv( location, 1, GL_FALSE, &(m.data[0]) ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const mat4f *m, const u32 count ) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniformMatrix4fv( location, 1, GL_FALSE, &(m->data[0]) ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, bool val ) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniform1i( location, (GLint)val ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, r32 val ) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniform1f( location, (GLfloat)val ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, i32 val ) +{ + GLuint location = glGetUniformLocation ( p.id, attrib_name ); + glUniform1i( location, (GLint)val ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, u32 val ) +{ + GLuint location = glGetUniformLocation ( p.id, attrib_name ); + glUniform1i( location, (GLint)val ); +} + + + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const bool * val, const u32 count ) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniform1iv( location, count, (GLint*)val ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const r32 * val, const u32 count ) +{ + GLuint location = glGetUniformLocation( p.id, attrib_name ); + glUniform1fv( location, count, (GLfloat*)val ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const i32 * val, const u32 count ) +{ + GLuint location = glGetUniformLocation ( p.id, attrib_name ); + glUniform1iv( location, count, (GLint*)val ); +} + +void bsc:: +set_uniform ( const shader_prog & p, + const char *attrib_name, const u32 * val, const u32 count ) +{ + GLuint location = glGetUniformLocation ( p.id, attrib_name ); + glUniform1uiv( location, count, (GLuint*)val ); +} +#endif diff --git a/CameraParameterEstimation/apps/basics/linalg/debug.h b/CameraParameterEstimation/apps/basics/linalg/debug.h new file mode 100644 index 0000000..6bdfb66 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/linalg/debug.h @@ -0,0 +1,55 @@ +#pragma once + +namespace bsc +{ + template + inline void + print_mat4( const T& mat, FILE * stream = stdout ) + { + fprintf ( stream, "%10.5f %10.5f %10.5f %10.5f\n", mat[0][0], mat[1][0], mat[2][0], mat[3][0] ); + fprintf ( stream, "%10.5f %10.5f %10.5f %10.5f\n", mat[0][1], mat[1][1], mat[2][1], mat[3][1] ); + fprintf ( stream, "%10.5f %10.5f %10.5f %10.5f\n", mat[0][2], mat[1][2], mat[2][2], mat[3][2] ); + fprintf ( stream, "%10.5f %10.5f %10.5f %10.5f\n", mat[0][3], mat[1][3], mat[2][3], mat[3][3] ); + fprintf ( stream, "\n" ); + } + + template + inline void + print_mat3( const T& mat, FILE * stream = stdout ) + { + fprintf ( stream, "%10.5f %10.5f %10.5f\n", mat[0][0], mat[1][0], mat[2][0] ); + fprintf ( stream, "%10.5f %10.5f %10.5f\n", mat[0][1], mat[1][1], mat[2][1] ); + fprintf ( stream, "%10.5f %10.5f %10.5f\n", mat[0][2], mat[1][2], mat[2][2] ); + fprintf ( stream, "\n" ); + } + + template + inline void + print_mat2( const T& mat, FILE * stream = stdout ) + { + fprintf ( stream, "%10.5f %10.5f\n", mat[0][0], mat[1][0] ); + fprintf ( stream, "%10.5f %10.5f\n", mat[0][1], mat[1][1] ); + fprintf ( stream, "\n" ); + } + + template + inline void + print_vec4( const T& vec, FILE * stream = stdout ) + { + fprintf ( stream, "%10.5f %10.5f %10.5f %10.5f\n", vec.x, vec.y, vec.z, vec.w ); + } + + template + inline void + print_vec3( const T& vec, FILE * stream = stdout ) + { + fprintf ( stream, "%10.5f %10.5f %10.5f\n", vec.x, vec.y, vec.z ); + } + + template + inline void + print_vec2( const T& vec, FILE * stream = stdout ) + { + fprintf ( stream, "%10.5f %10.5f\n", vec.x, vec.y ); + } +} diff --git a/CameraParameterEstimation/apps/basics/linalg/geometry.h b/CameraParameterEstimation/apps/basics/linalg/geometry.h new file mode 100644 index 0000000..275c539 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/linalg/geometry.h @@ -0,0 +1,103 @@ +#pragma once +//////////////////////////////////////////////////////////////////////////////// +// Interface +//////////////////////////////////////////////////////////////////////////////// + +namespace bsc +{ + + // TODO : How to draw this stuff by the way? + // Also shouldn't I have many by default? + + // GEOMETRIC ENTITIES + struct ray + { + vec3 o; + vec3 v; + }; + + struct plane + { + vec3 n; + r32 d; + }; + + struct aa_box + { + vec3 min_p; + vec3 max_p; + }; + + // ANGLES + r32 angle( const vec3 v1, const vec3 v2 ); + + // INTERSECTIONS + vec3 intersect( const ray r, const plane p ); + aa_box intersect( const aa_box *ba, const aa_box *bb ); + + // UNIONS + void merge( aa_box * box, vec3 p ); + + // DISTANCES + r32 distance( vec2 a, vec2 b ); + r32 distance( vec3 a, vec3 b ); + r32 distance( vec4 a, vec4 b ); + + // VOLUMES + r32 volume( const aa_box *b ); + +} +//////////////////////////////////////////////////////////////////////////////// +// Implementation +//////////////////////////////////////////////////////////////////////////////// +#ifdef BSC_IMPLEMENTATION + +namespace bsc +{ + // ANGLES + r32 + angle( const vec3 v1, const vec3 v2 ) + { + r32 dot_prod = dot(v1, v2); + r32 len_1 = norm(v1); + r32 len_2 = norm( v2 ); + return acos( dot_prod / len_1 * len_2 ); + } + + // INTERSECTIONS + vec3 + intersect( ray r, plane p ) + { + r32 t = -( dot( r.o, p.n ) + p.d ) / dot( r.v, p.n ); + return r.o + t * r.v; + } + + // UNIONS + void + merge( aa_box * box, vec3 p ) + { + // TODO: Implement min on vectors + box->min_p = vec3( min( box->min_p.x, p.x ), + min( box->min_p.y, p.y ), + min( box->min_p.z, p.z ) ); + box->max_p = vec3( max( box->max_p.x, p.x ), + max( box->max_p.y, p.y ), + max( box->max_p.z, p.z ) ); + } + + //DISTANCES + r32 + distance( vec3 a, vec3 b ) + { + return( norm( a-b ) ); + } + + r32 + distance( vec4 a, vec4 b ) + { + return( norm( a-b ) ); + } +} + + +#endif //BSC_IMPLEMENTATION \ No newline at end of file diff --git a/CameraParameterEstimation/apps/basics/linalg/matrix.h b/CameraParameterEstimation/apps/basics/linalg/matrix.h new file mode 100644 index 0000000..5c66fcd --- /dev/null +++ b/CameraParameterEstimation/apps/basics/linalg/matrix.h @@ -0,0 +1,2454 @@ +#pragma once + +//--------------------------------------------------- +// Interface +//--------------------------------------------------- + + +namespace bsc +{ + template struct matrix2; + template struct matrix3; + template struct matrix4; + + + // MATRIX 2 + template + struct matrix2 { + + union + { + T data[4]; + vector2 cols[2]; + }; + + matrix2 ( bool initialize = true ); + matrix2 ( const T constant ); + matrix2 ( const T *other ); + matrix2 ( const matrix2 & other ); + matrix2 ( const matrix3 & other ); + matrix2 ( const matrix4 & other ); + matrix2 ( const vector2 & diagonal ); + matrix2 ( const vector2 & col0, + const vector2 & col1 ); + + matrix2 & operator= ( const matrix2 & other ); + + void operator+= ( const matrix2 & other ); + void operator+= ( const T constant ); + + + void operator-=( const matrix2 & other ); + void operator-=( const T constant ); + + void operator*= ( const matrix2 & other ); + void operator*= ( const T constant ); + void pointwiseMultiply ( const matrix2 &other ); + + void operator/= ( const matrix2 & other ); + void operator/= ( const T constant ); + + vector2& operator[] ( unsigned int i ); + vector2 operator[] ( unsigned int i ) const; + + bool operator== ( const matrix2 & other ) const; + bool operator!= ( const matrix2 & other ) const; + + const constexpr int dimensionality () const { return 2; } // whats the point? + const constexpr int size () const { return 4; } + }; + // TODO: add forward declaration of other operators! + + // MATRIX 3 + template + struct matrix3 { + + union + { + T data[9]; + vector3 cols[3]; + }; + + matrix3 ( bool initialize = true ); + matrix3 ( const T constant ); + matrix3 ( const T * other ); + matrix3 ( const matrix2 & other ); + matrix3 ( const matrix3 & other ); + matrix3 ( const matrix4 & other ); + matrix3 ( const vector3 & diagonal ); + matrix3 ( const vector3 & col0, + const vector3 & col1, + const vector3 & col2 ); + + matrix3 & operator= ( const matrix3 & other ); + + void operator+= ( const matrix3 & other ); + void operator+= ( const T constant ); + + void operator-= ( const matrix3 & other ); + void operator-= ( const T constant ); + + void operator*= ( const matrix3 & other ); + void operator*= ( const T constant ); + void pointwiseMultiply( const matrix3 &other ); + + void operator/= ( const matrix3 & other ); + void operator/= ( const T constant ); + + vector3& operator[] ( unsigned int i ); + vector3 operator[] ( unsigned int i ) const; + + bool operator== ( const matrix2 & other ) const; + bool operator!= ( const matrix2 & other ) const; + + const constexpr int dimensionality () const { return 3; } + const constexpr int size () const { return 9; } + }; + + + // MATRIX 4 + template + struct matrix4 { + + union + { + T data[16]; + vector4 cols[4]; + }; + + matrix4 ( bool initialize = true ); + matrix4 ( const T constant ); + matrix4 ( const T * other ); + matrix4 ( const matrix2 & other ); + matrix4 ( const matrix3 & other ); + matrix4 ( const matrix4 & other ); + matrix4 ( const vector4 & diagonal ); + matrix4 ( const vector4 & col0, + const vector4 & col1, + const vector4 & col2, + const vector4 & col3 ); + + matrix4 & operator= ( const matrix4 & other ); + + void operator+= ( const matrix4 & other ); + void operator+= ( const T constant ); + + void operator-= ( const matrix4 & other ); + void operator-= ( const T constant ); + + void operator*= ( const matrix4 & other ); + void operator*= ( const T constant ); + void pointwiseMultiply ( const matrix4 &other ); + + void operator/= ( const matrix4 & other ); + void operator/= ( const T constant ); + + vector4& operator[] ( unsigned int i ); + vector4 operator[] ( unsigned int i ) const; + + bool operator== ( const matrix2 & other ) const; + bool operator!= ( const matrix2 & other ) const; + + const constexpr int dimensionality () const { return 4; } + const constexpr int size () const { return 16; } + }; + +//////////////////////////////////////////////////////////////////////////////// +// FUNCTIONS +//////////////////////////////////////////////////////////////////////////////// + + template< typename T, template class matrixX > + T determinant ( const matrixX & matrix ); + + template< typename T, template class matrixX > + T trace ( const matrixX & matrix ); + + template< typename T, template class matrixX > + matrixX inverse ( const matrixX & matrix ); + + template< typename T, template class matrixX > + matrixX transpose ( const matrixX & matrix ); + + template< typename T> + matrix4 look_at ( const vector3 & eye, + const vector3 & center, + const vector3 & up ); + + template< typename T> + matrix4 perspective ( const T & fovy, + const T & aspect, + const T & z_near, + const T & z_far); + + template< typename T> + matrix4 frustum ( const T & left, const T & right, + const T & bottom, const T & top, + const T & z_near, const T & z_far ); + + template< typename T> + matrix4 ortho ( const T & left, const T & right, + const T & bottom, const T & top, + const T & z_near, const T & z_far ); + + template< typename T> + vector3 project ( const vector4 & obj, + const matrix4 & model, + const matrix4 & project, + const vector4 & viewport ); + + template< typename T> + vector4 unproject ( const vector3 & win, + const matrix4 & model, + const matrix4 & project, + const vector4 & viewport ); + + template< typename T> + matrix4 translate( const matrix4 & m, const vector3 & t ); + + template< typename T> + matrix4 scale( const matrix4 & m, const vector3 & s ); + + template< typename T> + matrix4 rotate( const matrix4 & m, + const T & angle, + const vector3 & axis ); + + matrix4 + pca( const vector3 * points, + const i32 n_points ); + + void + eig( const matrix3 * mat, + matrix3 * eigvec, + vector3 * eigval ); + + typedef matrix2 mat2; + typedef matrix3 mat3; + typedef matrix4 mat4; + + typedef matrix2 mat2d; + typedef matrix2 mat2f; + typedef matrix2 mat2i; + + typedef matrix3 mat3d; + typedef matrix3 mat3f; + typedef matrix3 mat3i; + + typedef matrix4 mat4d; + typedef matrix4 mat4f; + typedef matrix4 mat4i; +} + +//--------------------------------------------------- +// Implementation +//--------------------------------------------------- +namespace bsc +{ + // MATRIX 2 + template + matrix2:: + matrix2 ( bool intialize ) + { + if ( intialize ) + { + this->data[ 0] = (T)1.0; + this->data[ 1] = (T)0.0; + this->data[ 2] = (T)0.0; + this->data[ 3] = (T)1.0; + } + } + + template + inline matrix2 :: + matrix2 ( const T c ) + { + for ( int i = 0 ; i < 4 ; ++i ) + { + data[i] = c; + } + } + + template + inline matrix2 :: + matrix2 ( const T * other ) + { + for ( int i = 0 ; i < 4 ; ++i ) + { + data[i] = other[i]; + } + } + + + template + matrix2:: + matrix2 ( const matrix2 & other ) + { + this->data[0] = other.data[0]; + this->data[1] = other.data[1]; + this->data[2] = other.data[2]; + this->data[3] = other.data[3]; + } + + template + matrix2:: + matrix2 ( const matrix3 & other ) + { + this->data[0] = other.data[0]; + this->data[1] = other.data[1]; + this->data[2] = other.data[3]; + this->data[3] = other.data[4]; + } + + template + matrix2:: + matrix2 ( const matrix4 & other ) + { + this->data[0] = other.data[0]; + this->data[1] = other.data[1]; + this->data[2] = other.data[4]; + this->data[3] = other.data[5]; + } + + + template + matrix2:: + matrix2 ( const vector2 & diagonal ) + { + for ( int i = 0 ; i < 4 ; ++i ) + { + data[i] = 0; + } + data[0] = diagonal.x; + data[3] = diagonal.y; + + } + + template + matrix2:: + matrix2 ( const vector2 & col0, const vector2 & col1 ) + { + cols[0] = col0; + cols[1] = col1; + } + + template + inline void matrix2:: + operator+= ( const matrix2 & other ) + { + for ( int i = 0 ; i < 4 ; i += 2 ) + { + this->data[i] += other.data[i]; + this->data[i+1] += other.data[i+1]; + } + } + + template + inline void matrix2:: + operator+= ( const T constant ) + { + for ( int i = 0 ; i < 4 ; i += 2 ) + { + this->data[i] += constant; + this->data[i+1] += constant; + this->data[i+2] += constant; + } + } + + template + inline matrix2 + operator+ ( const matrix2 & m1, const matrix2 & m2 ) + { + matrix2 result( m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2] ); + return result; + } + + template + inline matrix2 + operator+ ( const matrix2 & m, const T constant ) + { + matrix2 result( m[0] + constant, + m[1] + constant, + m[2] + constant); + return result; + } + + template + inline matrix2 + operator+ ( const T constant, const matrix2 & m ) + { + matrix2 result( m[0] + constant, + m[1] + constant, + m[2] + constant ); + return result; + } + + + + template + inline void matrix2:: + operator-= ( const matrix2 & other ) + { + for ( int i = 0 ; i < 4 ; i += 2 ) + { + this->data[i] -= other.data[i]; + this->data[i+1] -= other.data[i+1]; + this->data[i+2] -= other.data[i+2]; + } + } + + template + inline void matrix2:: + operator-= ( const T constant ) + { + for ( int i = 0 ; i < 4 ; i += 2 ) + { + this->data[i] -= constant; + this->data[i+1] -= constant; + this->data[i+2] -= constant; + } + } + + template + inline matrix2 + operator- ( const matrix2 & m1, const matrix2 & m2 ) + { + matrix2 result( m1[0] - m2[0], + m1[1] - m2[1] ); + return result; + } + + template + inline matrix2 + operator- ( const matrix2 & m, const T constant ) + { + matrix2 result( m[0] - constant, + m[1] - constant ); + return result; + } + + template + inline matrix2 + operator- ( const T constant, const matrix2 & m ) + { + matrix2 result( constant - m[0], + constant - m[1] ); + return result; + } + + template + inline matrix2 + operator- ( const matrix2 & m ) + { + matrix2 result( -m[0], + -m[1] ); + return result; + } + + template + inline void matrix2:: + operator*= ( const matrix2 & other ) + { + T vals[4]; + + vals[0] = other.data[0] * data[0] + other.data[1] * data[2]; + vals[1] = other.data[0] * data[1] + other.data[1] * data[3]; + + vals[2] = other.data[2] * data[0] + other.data[3] * data[2]; + vals[3] = other.data[2] * data[1] + other.data[3] * data[3]; + + for ( int i = 0 ; i < 4 ; i += 2 ) + { + this->data[i] = vals[i] ; + this->data[i+1] = vals[i+1]; + } + } + + template + inline void matrix2:: + operator*= ( const T constant ) + { + for ( int i = 0 ; i < 4 ; i += 2 ) + { + this->data[i] *= constant; + this->data[i+1] *= constant; + } + } + + template + inline matrix2 + operator* ( const matrix2 & m1, const matrix2 & m2 ) + { + T vals[4]; + + vals[0] = m2.data[0] * m1.data[0] + m2.data[1] * m1.data[2]; + vals[1] = m2.data[0] * m1.data[1] + m2.data[1] * m1.data[3]; + + vals[2] = m2.data[2] * m1.data[0] + m2.data[3] * m1.data[2]; + vals[3] = m2.data[2] * m1.data[1] + m2.data[3] * m1.data[3]; + + + matrix2 result( vals ); + return result; + } + + template + inline matrix2 + operator* ( const matrix2 & m, const T constant ) + { + matrix2 result( m[0] * constant, + m[1] * constant ); + return result; + } + + template + inline matrix2 + operator* ( const T constant, const matrix2 & m ) + { + matrix2 result( m[0] * constant, + m[1] * constant ); + return result; + } + + template + inline vector2 + operator* ( const matrix2 & m, const vector2 & v ) + { + vector2 output; + + output.x = m.data[0] * v.x + m.data[2] * v.y; + output.y = m.data[1] * v.x + m.data[3] * v.y; + + return output; + } + + template + inline void matrix2:: + pointwiseMultiply ( const matrix2 & other ) + { + for ( int i = 0 ; i < 4 ; i += 2 ) + { + this->data[i] *= other.data[i]; + this->data[i+1] *= other.data[i+1]; + } + } + + + template + inline void matrix2:: + operator/= ( const matrix2 & other ) + { + matrix2 inv_other = Inverse( other ); + (*this) *= inv_other; + } + + template + inline void matrix2:: + operator/= ( const T constant ) + { + float inv_constant = (T)1.0 / constant; + for ( int i = 0 ; i < 4 ; i += 2 ) + { + this->data[i] *= inv_constant; + this->data[i+1] *= inv_constant; + } + } + + template + inline matrix2 + operator/ ( const matrix2 & m1, const matrix2 & m2 ) + { + matrix2 result( m1 ); + result /= m2; + return result; + } + + template + inline matrix2 + operator/ ( const matrix2 & m, const T constant ) + { + float inv_constant = (T)1.0 / constant; + matrix2 result( m[0] * inv_constant, + m[1] * inv_constant, + m[2] * inv_constant ); + return result; + } + + template + inline matrix2 + operator/ ( const T constant, const matrix2 & m ) + { + matrix2 result( constant / m[0], + constant / m[1], + constant / m[2] ); + return result; + } + + template + inline vector2 & matrix2:: + operator[] ( unsigned int i ) + { + return cols[i]; + } + + template + inline vector2 matrix2:: + operator[] ( unsigned int i ) const + { + return cols[i]; + } + + + // MATRIX 3 + template + matrix3 :: + matrix3 ( bool intialize ) + { + if ( intialize ) + { + this->data[0] = (T)1.0; + this->data[1] = (T)0.0; + this->data[2] = (T)0.0; + + this->data[3] = (T)0.0; + this->data[4] = (T)1.0; + this->data[5] = (T)0.0; + + this->data[6] = (T)0.0; + this->data[7] = (T)0.0; + this->data[8] = (T)1.0; + } + } + + template + matrix3 :: + matrix3 ( const T c ) + { + for ( int i = 0 ; i < 9 ; ++i ) + { + data[i] = c; + } + } + + template + matrix3 :: + matrix3 ( const T * other ) + { + for ( int i = 0 ; i < 9 ; ++i ) + { + data[i] = other[i]; + } + } + + template + matrix3:: + matrix3 ( const matrix2 & other ) + { + this->data[0] = other.data[0]; + this->data[1] = other.data[1]; + this->data[2] = (T)0.0; + this->data[3] = other.data[2]; + this->data[4] = other.data[3]; + this->data[5] = (T)0.0; + this->data[6] = (T)0.0; + this->data[7] = (T)0.0; + this->data[8] = (T)1.0; + } + + template + matrix3 :: + matrix3 ( const matrix3 & other ) + { + this->data[0] = other.data[0]; + this->data[1] = other.data[1]; + this->data[2] = other.data[2]; + this->data[3] = other.data[3]; + this->data[4] = other.data[4]; + this->data[5] = other.data[5]; + this->data[6] = other.data[6]; + this->data[7] = other.data[7]; + this->data[8] = other.data[8]; + } + + + template + matrix3:: + matrix3 ( const matrix4 & other ) + { + this->data[ 0] = other.data[ 0]; + this->data[ 1] = other.data[ 1]; + this->data[ 2] = other.data[ 2]; + this->data[ 3] = other.data[ 4]; + this->data[ 4] = other.data[ 5]; + this->data[ 5] = other.data[ 6]; + this->data[ 6] = other.data[ 8]; + this->data[ 7] = other.data[ 9]; + this->data[ 8] = other.data[10]; + } + + template + matrix3 :: + matrix3 ( const vector3 & diagonal ) + { + for ( int i = 0 ; i < 9 ; ++i ) + { + data[i] = 0; + } + data[0] = diagonal.x; + data[4] = diagonal.y; + data[8] = diagonal.z; + } + + template + matrix3 :: + matrix3 ( const vector3 & col0, const vector3 & col1, const vector3 & col2 ) + { + cols[0] = col0; + cols[1] = col1; + cols[2] = col2; + } + + template + inline matrix3 & matrix3 :: + operator= ( const matrix3 & other ) + { + this->data[0] = other.data[0]; + this->data[1] = other.data[1]; + this->data[2] = other.data[2]; + this->data[3] = other.data[3]; + this->data[4] = other.data[4]; + this->data[5] = other.data[5]; + this->data[6] = other.data[6]; + this->data[7] = other.data[7]; + this->data[8] = other.data[8]; + return *this; + } + + template + inline void matrix3:: + operator+= ( const matrix3 & other ) + { + for ( int i = 0 ; i < 9 ; i += 3 ) + { + this->data[i] += other.data[i]; + this->data[i+1] += other.data[i+1]; + this->data[i+2] += other.data[i+2]; + } + } + + template + inline void matrix3:: + operator+= ( const T constant ) + { + for ( int i = 0 ; i < 9 ; i += 3 ) + { + this->data[i] += constant; + this->data[i+1] += constant; + this->data[i+2] += constant; + } + } + + template + inline matrix3 + operator+ ( const matrix3 & m1, const matrix3 & m2 ) + { + matrix3 result( m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2] ); + return result; + } + + template + inline matrix3 + operator+ ( const matrix3 & m, const T constant ) + { + matrix3 result( m[0] + constant, + m[1] + constant, + m[2] + constant); + return result; + } + + template + inline matrix3 + operator+ ( const T constant, const matrix3 & m ) + { + matrix3 result( m[0] + constant, + m[1] + constant, + m[2] + constant ); + return result; + } + + + + template + inline void matrix3:: + operator-= ( const matrix3 & other ) + { + for ( int i = 0 ; i < 9 ; i += 3 ) + { + this->data[i] -= other.data[i]; + this->data[i+1] -= other.data[i+1]; + this->data[i+2] -= other.data[i+2]; + } + } + + template + inline void matrix3:: + operator-= ( const T constant ) + { + for ( int i = 0 ; i < 9 ; i += 3 ) + { + this->data[i] -= constant; + this->data[i+1] -= constant; + this->data[i+2] -= constant; + } + } + + template + inline matrix3 + operator- ( const matrix3 & m1, const matrix3 & m2 ) + { + matrix3 result( m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2] ); + return result; + } + + template + inline matrix3 + operator- ( const matrix3 & m, const T constant ) + { + matrix3 result( m[0] - constant, + m[1] - constant, + m[2] - constant ); + return result; + } + + template + inline matrix3 + operator- ( const T constant, const matrix3 & m ) + { + matrix3 result( constant - m[0], + constant - m[1], + constant - m[2] ); + return result; + } + + template + inline matrix3 + operator- ( const matrix3 & m ) + { + matrix3 result( -m[0], + -m[1], + -m[2] ); + return result; + } + + template + inline void matrix3:: + operator*= ( const matrix3 & other ) + { + T vals[9]; + + + vals[0] = other.data[0] * data[0] + + other.data[1] * data[3] + + other.data[2] * data[6]; + vals[1] = other.data[0] * data[1] + + other.data[1] * data[4] + + other.data[2] * data[7]; + vals[2] = other.data[0] * data[2] + + other.data[1] * data[5] + + other.data[2] * data[8]; + + vals[3] = other.data[3] * data[0] + + other.data[4] * data[3] + + other.data[5] * data[6]; + vals[4] = other.data[3] * data[1] + + other.data[4] * data[4] + + other.data[5] * data[7]; + vals[5] = other.data[3] * data[2] + + other.data[4] * data[5] + + other.data[5] * data[8]; + + vals[6] = other.data[6] * data[0] + + other.data[7] * data[3] + + other.data[8] * data[6]; + vals[7] = other.data[6] * data[1] + + other.data[7] * data[4] + + other.data[8] * data[7]; + vals[8] = other.data[6] * data[2] + + other.data[7] * data[5] + + other.data[8] * data[8]; + + + for ( int i = 0 ; i < 9 ; i += 3 ) + { + this->data[i] = vals[i] ; + this->data[i+1] = vals[i+1]; + this->data[i+2] = vals[i+2]; + } + } + + template + inline void matrix3:: + operator*= ( const T constant ) + { + for ( int i = 0 ; i < 9 ; i += 3 ) + { + this->data[i] *= constant; + this->data[i+1] *= constant; + this->data[i+2] *= constant; + } + } + + template + inline matrix3 + operator* ( const matrix3 & m1, const matrix3 & m2 ) + { + T vals[9]; + + vals[0] = m2.data[0] * m1.data[0] + + m2.data[1] * m1.data[3] + + m2.data[2] * m1.data[6]; + vals[1] = m2.data[0] * m1.data[1] + + m2.data[1] * m1.data[4] + + m2.data[2] * m1.data[7]; + vals[2] = m2.data[0] * m1.data[2] + + m2.data[1] * m1.data[5] + + m2.data[2] * m1.data[8]; + + vals[3] = m2.data[3] * m1.data[0] + + m2.data[4] * m1.data[3] + + m2.data[5] * m1.data[6]; + vals[4] = m2.data[3] * m1.data[1] + + m2.data[4] * m1.data[4] + + m2.data[5] * m1.data[7]; + vals[5] = m2.data[3] * m1.data[2] + + m2.data[4] * m1.data[5] + + m2.data[5] * m1.data[8]; + + vals[6] = m2.data[6] * m1.data[0] + + m2.data[7] * m1.data[3] + + m2.data[8] * m1.data[6]; + vals[7] = m2.data[6] * m1.data[1] + + m2.data[7] * m1.data[4] + + m2.data[8] * m1.data[7]; + vals[8] = m2.data[6] * m1.data[2] + + m2.data[7] * m1.data[5] + + m2.data[8] * m1.data[8]; + + matrix3 result( vals ); + return result; + } + + template + inline matrix3 + operator* ( const matrix3 & m, const T constant ) + { + matrix3 result( m[0] * constant, + m[1] * constant, + m[2] * constant ); + return result; + } + + template + inline matrix3 + operator* ( const T constant, const matrix3 & m ) + { + matrix3 result( m[0] * constant, + m[1] * constant, + m[2] * constant ); + return result; + } + + template + inline vector3 + operator* ( const matrix3 & m, const vector3 & v ) + { + vector3 output; + + output.x = m.data[0] * v.x + m.data[3] * v.y + m.data[6] * v.z; + output.y = m.data[1] * v.x + m.data[4] * v.y + m.data[7] * v.z; + output.z = m.data[2] * v.x + m.data[5] * v.y + m.data[8] * v.z; + + return output; + } + + template + inline void matrix3:: + pointwiseMultiply ( const matrix3 & other ) + { + for ( int i = 0 ; i < 9 ; i += 3 ) + { + this->data[i] *= other.data[i]; + this->data[i+1] *= other.data[i+1]; + this->data[i+2] *= other.data[i+2]; + } + } + + + template + inline void matrix3:: + operator/= ( const matrix3 & other ) + { + matrix3 inv_other = Inverse( other ); + (*this) *= inv_other; + } + + template + inline void matrix3:: + operator/= ( const T constant ) + { + float inv_constant = (T)1.0 / constant; + for ( int i = 0 ; i < 9 ; i += 3 ) + { + this->data[i] *= inv_constant; + this->data[i+1] *= inv_constant; + this->data[i+2] *= inv_constant; + } + } + + template + inline matrix3 + operator/ ( const matrix3 & m1, const matrix3 & m2 ) + { + matrix3 result( m1 ); + result /= m2; + return result; + } + + template + inline matrix3 + operator/ ( const matrix3 & m, const T constant ) + { + float inv_constant = (T)1.0 / constant; + matrix3 result( m[0] * inv_constant, + m[1] * inv_constant, + m[2] * inv_constant ); + return result; + } + + template + inline matrix3 + operator/ ( const T constant, const matrix3 & m ) + { + matrix3 result( constant / m[0], + constant / m[1], + constant / m[2] ); + return result; + } + + template + inline vector3 & matrix3 :: + operator[] ( unsigned int i ) + { + return cols[i]; + } + + template + inline vector3 matrix3 :: + operator[] ( unsigned int i ) const + { + return cols[i]; + } + + + // MATRIX 4 + + template + matrix4:: + matrix4 ( bool intialize ) + { + if ( intialize ) + { + this->data[ 0] = (T)1.0; + this->data[ 1] = (T)0.0; + this->data[ 2] = (T)0.0; + this->data[ 3] = (T)0.0; + + this->data[ 4] = (T)0.0; + this->data[ 5] = (T)1.0; + this->data[ 6] = (T)0.0; + this->data[ 7] = (T)0.0; + + this->data[ 8] = (T)0.0; + this->data[ 9] = (T)0.0; + this->data[10] = (T)1.0; + this->data[11] = (T)0.0; + + this->data[12] = (T)0.0; + this->data[13] = (T)0.0; + this->data[14] = (T)0.0; + this->data[15] = (T)1.0; + } + } + + template + matrix4:: + matrix4 ( const T c ) + { + for ( int i = 0 ; i < 16 ; ++i ) + { + data[i] = c; + } + } + + template + matrix4:: + matrix4 ( const T * other ) + { + for ( int i = 0 ; i < 16 ; ++i ) + { + data[i] = other[i]; + } + } + + template + matrix4:: + matrix4 ( const matrix2 & other ) + { + this->data[ 0] = other.data[0]; + this->data[ 1] = other.data[1]; + this->data[ 2] = (T)0.0; + this->data[ 3] = (T)0.0; + this->data[ 4] = other.data[2]; + this->data[ 5] = other.data[3]; + this->data[ 6] = (T)0.0; + this->data[ 7] = (T)0.0; + this->data[ 8] = (T)0.0; + this->data[ 9] = (T)0.0; + this->data[10] = (T)1.0; + this->data[11] = (T)0.0; + this->data[12] = (T)0.0; + this->data[13] = (T)0.0; + this->data[14] = (T)0.0; + this->data[15] = (T)1.0; + } + + template + matrix4:: + matrix4 ( const matrix3 & other ) + { + this->data[ 0] = other.data[0]; + this->data[ 1] = other.data[1]; + this->data[ 2] = other.data[2]; + this->data[ 3] = (T)0.0; + this->data[ 4] = other.data[3]; + this->data[ 5] = other.data[4]; + this->data[ 6] = other.data[5]; + this->data[ 7] = (T)0.0; + this->data[ 8] = other.data[6]; + this->data[ 9] = other.data[7]; + this->data[10] = other.data[8]; + this->data[11] = (T)0.0; + this->data[12] = (T)0.0; + this->data[13] = (T)0.0; + this->data[14] = (T)0.0; + this->data[15] = (T)1.0; + } + + template + matrix4:: + matrix4 ( const matrix4 & other ) + { + this->data[ 0] = other.data[ 0]; + this->data[ 1] = other.data[ 1]; + this->data[ 2] = other.data[ 2]; + this->data[ 3] = other.data[ 3]; + this->data[ 4] = other.data[ 4]; + this->data[ 5] = other.data[ 5]; + this->data[ 6] = other.data[ 6]; + this->data[ 7] = other.data[ 7]; + this->data[ 8] = other.data[ 8]; + this->data[ 9] = other.data[ 9]; + this->data[10] = other.data[10]; + this->data[11] = other.data[11]; + this->data[12] = other.data[12]; + this->data[13] = other.data[13]; + this->data[14] = other.data[14]; + this->data[15] = other.data[15]; + } + + template + matrix4:: + matrix4 ( const vector4 & diagonal ) + { + for ( int i = 0 ; i < 16 ; ++i ) + { + data[i] = (T)0.0; + } + data[ 0] = diagonal.x; + data[ 5] = diagonal.y; + data[10] = diagonal.z; + data[15] = diagonal.w; + } + + template + matrix4:: + matrix4 ( const vector4 & col0, const vector4 & col1, const vector4 & col2, const vector4 & col3 ) + { + cols[0] = col0; + cols[1] = col1; + cols[2] = col2; + cols[3] = col3; + + } + + template + inline matrix4 & matrix4:: + operator= ( const matrix4 & other ) + { + this->data[ 0] = other.data[ 0]; + this->data[ 1] = other.data[ 1]; + this->data[ 2] = other.data[ 2]; + this->data[ 3] = other.data[ 3]; + this->data[ 4] = other.data[ 4]; + this->data[ 5] = other.data[ 5]; + this->data[ 6] = other.data[ 6]; + this->data[ 7] = other.data[ 7]; + this->data[ 8] = other.data[ 8]; + this->data[ 9] = other.data[ 9]; + this->data[10] = other.data[10]; + this->data[11] = other.data[11]; + this->data[12] = other.data[12]; + this->data[13] = other.data[13]; + this->data[14] = other.data[14]; + this->data[15] = other.data[15]; + return *this; + } + + template + inline void matrix4:: + operator+= ( const matrix4 & other ) + { + for ( int i = 0 ; i < 16 ; i += 4 ) + { + this->data[i] += other.data[i]; + this->data[i+1] += other.data[i+1]; + this->data[i+2] += other.data[i+2]; + this->data[i+3] += other.data[i+3]; + } + } + + template + inline void matrix4:: + operator+= ( const T constant ) + { + for ( int i = 0 ; i < 16 ; i += 4 ) + { + this->data[i] += constant; + this->data[i+1] += constant; + this->data[i+2] += constant; + this->data[i+3] += constant; + } + } + + template + inline matrix4 + operator+ ( const matrix4 & m1, const matrix4 & m2 ) + { + matrix4 result( m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2], + m1[3] + m2[3] ); + return result; + } + + template + inline matrix4 + operator+ ( const matrix4 & m, const T constant ) + { + matrix4 result( m[0] + constant, + m[1] + constant, + m[2] + constant, + m[3] + constant ); + return result; + } + + template + inline matrix4 + operator+ ( const T constant, const matrix4 & m ) + { + matrix4 result( m[0] + constant, + m[1] + constant, + m[2] + constant, + m[3] + constant ); + return result; + } + + + + template + inline void matrix4:: + operator-= ( const matrix4 & other ) + { + for ( int i = 0 ; i < 16 ; i += 4 ) + { + this->data[i] -= other.data[i]; + this->data[i+1] -= other.data[i+1]; + this->data[i+2] -= other.data[i+2]; + this->data[i+3] -= other.data[i+3]; + } + } + + template + inline void matrix4:: + operator-= ( const T constant ) + { + for ( int i = 0 ; i < 16 ; i += 4 ) + { + this->data[i] -= constant; + this->data[i+1] -= constant; + this->data[i+2] -= constant; + this->data[i+3] -= constant; + } + } + + template + inline matrix4 + operator- ( const matrix4 & m1, const matrix4 & m2 ) + { + matrix4 result( m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2], + m1[3] - m2[3] ); + return result; + } + + template + inline matrix4 + operator- ( const matrix4 & m, const T constant ) + { + matrix4 result( m[0] - constant, + m[1] - constant, + m[2] - constant, + m[3] - constant ); + return result; + } + + template + inline matrix4 + operator- ( const T constant, const matrix4 & m ) + { + matrix4 result( constant - m[0], + constant - m[1], + constant - m[2], + constant - m[3] ); + return result; + } + + template + inline matrix4 + operator- ( const matrix4 & m ) + { + matrix4 result( -m[0], + -m[1], + -m[2], + -m[3] ); + return result; + } + + template + inline void matrix4:: + operator*= ( const matrix4 & other ) + { + T vals[16]; + + vals[ 0] = other.data[ 0] * data[ 0] + other.data[ 1] * data[ 4] + + other.data[ 2] * data[ 8] + other.data[ 3] * data[12]; + vals[ 1] = other.data[ 0] * data[ 1] + other.data[ 1] * data[ 5] + + other.data[ 2] * data[ 9] + other.data[ 3] * data[13]; + vals[ 2] = other.data[ 0] * data[ 2] + other.data[ 1] * data[ 6] + + other.data[ 2] * data[10] + other.data[ 3] * data[14]; + vals[ 3] = other.data[ 0] * data[ 3] + other.data[ 1] * data[ 7] + + other.data[ 2] * data[11] + other.data[ 3] * data[15]; + + vals[ 4] = other.data[ 4] * data [0] + other.data[ 5] * data[ 4] + + other.data[ 6] * data[ 8] + other.data[ 7] * data[12]; + vals[ 5] = other.data[ 4] * data [1] + other.data[ 5] * data[ 5] + + other.data[ 6] * data[ 9] + other.data[ 7] * data[13]; + vals[ 6] = other.data[ 4] * data[ 2] + other.data[ 5] * data[ 6] + + other.data[ 6] * data[10] + other.data[ 7] * data[14]; + vals[ 7] = other.data[ 4] * data[ 3] + other.data[ 5] * data[ 7] + + other.data[ 6] * data[11] + other.data[ 7] * data[15]; + + vals[ 8] = other.data[ 8] * data [0] + other.data[ 9] * data[ 4] + + other.data[10] * data[ 8] + other.data[11] * data[12]; + vals[ 9] = other.data[ 8] * data[ 1] + other.data[ 9] * data[ 5] + + other.data[10] * data[ 9] + other.data[11] * data[13]; + vals[10] = other.data[ 8] * data[ 2] + other.data[ 9] * data[ 6] + + other.data[10] * data[10] + other.data[11] * data[14]; + vals[11] = other.data[ 8] * data[ 3] + other.data[ 9] * data[ 7] + + other.data[10] * data[11] + other.data[11] * data[15]; + + vals[12] = other.data[12] * data[ 0] + other.data[13] * data[ 4] + + other.data[14] * data[ 8] + other.data[15] * data[12]; + vals[13] = other.data[12] * data[ 1] + other.data[13] * data[ 5] + + other.data[14] * data[ 9] + other.data[15] * data[13]; + vals[14] = other.data[12] * data[ 2] + other.data[13] * data[ 6] + + other.data[14] * data[10] + other.data[15] * data[14]; + vals[15] = other.data[12] * data[ 3] + other.data[13] * data[ 7] + + other.data[14] * data[11] + other.data[15] * data[15]; + + for ( int i = 0 ; i < 16 ; i += 4 ) + { + this->data[i] = vals[i] ; + this->data[i+1] = vals[i+1]; + this->data[i+2] = vals[i+2]; + this->data[i+3] = vals[i+3]; + } + } + + template + inline void matrix4:: + operator*= ( const T constant ) + { + for ( int i = 0 ; i < 16 ; i += 4 ) + { + this->data[i] *= constant; + this->data[i+1] *= constant; + this->data[i+2] *= constant; + this->data[i+3] *= constant; + } + } + + template + inline matrix4 + operator* ( const matrix4 & m1, const matrix4 & m2 ) + { + T vals[16]; + + vals[ 0] = m2.data[ 0] * m1.data[ 0] + m2.data[ 1] * m1.data[ 4] + + m2.data[ 2] * m1.data[ 8] + m2.data[ 3] * m1.data[12]; + vals[ 1] = m2.data[ 0] * m1.data[ 1] + m2.data[ 1] * m1.data[ 5] + + m2.data[ 2] * m1.data[ 9] + m2.data[ 3] * m1.data[13]; + vals[ 2] = m2.data[ 0] * m1.data[ 2] + m2.data[ 1] * m1.data[ 6] + + m2.data[ 2] * m1.data[10] + m2.data[ 3] * m1.data[14]; + vals[ 3] = m2.data[ 0] * m1.data[ 3] + m2.data[ 1] * m1.data[ 7] + + m2.data[ 2] * m1.data[11] + m2.data[ 3] * m1.data[15]; + + vals[ 4] = m2.data[ 4] * m1.data[ 0] + m2.data[ 5] * m1.data[ 4] + + m2.data[ 6] * m1.data[ 8] + m2.data[ 7] * m1.data[12]; + vals[ 5] = m2.data[ 4] * m1.data[ 1] + m2.data[ 5] * m1.data[ 5] + + m2.data[ 6] * m1.data[ 9] + m2.data[ 7] * m1.data[13]; + vals[ 6] = m2.data[ 4] * m1.data[ 2] + m2.data[ 5] * m1.data[ 6] + + m2.data[ 6] * m1.data[10] + m2.data[ 7] * m1.data[14]; + vals[ 7] = m2.data[ 4] * m1.data[ 3] + m2.data[ 5] * m1.data[ 7] + + m2.data[ 6] * m1.data[11] + m2.data[ 7] * m1.data[15]; + + vals[ 8] = m2.data[ 8] * m1.data[ 0] + m2.data[ 9] * m1.data[ 4] + + m2.data[10] * m1.data[ 8] + m2.data[11] * m1.data[12]; + vals[ 9] = m2.data[ 8] * m1.data[ 1] + m2.data[ 9] * m1.data[ 5] + + m2.data[10] * m1.data[ 9] + m2.data[11] * m1.data[13]; + vals[10] = m2.data[ 8] * m1.data[ 2] + m2.data[ 9] * m1.data[ 6] + + m2.data[10] * m1.data[10] + m2.data[11] * m1.data[14]; + vals[11] = m2.data[ 8] * m1.data[ 3] + m2.data[ 9] * m1.data[ 7] + + m2.data[10] * m1.data[11] + m2.data[11] * m1.data[15]; + + vals[12] = m2.data[12] * m1.data[ 0] + m2.data[13] * m1.data[ 4] + + m2.data[14] * m1.data[ 8] + m2.data[15] * m1.data[12]; + vals[13] = m2.data[12] * m1.data[ 1] + m2.data[13] * m1.data[ 5] + + m2.data[14] * m1.data[ 9] + m2.data[15] * m1.data[13]; + vals[14] = m2.data[12] * m1.data[ 2] + m2.data[13] * m1.data[ 6] + + m2.data[14] * m1.data[10] + m2.data[15] * m1.data[14]; + vals[15] = m2.data[12] * m1.data[ 3] + m2.data[13] * m1.data[ 7] + + m2.data[14] * m1.data[11] + m2.data[15] * m1.data[15]; + + matrix4 result( vals ); + return result; + } + + template + inline matrix4 + operator* ( const matrix4 & m, const T constant ) + { + matrix4 result( m[0] * constant, + m[1] * constant, + m[2] * constant, + m[3] * constant ); + return result; + } + + template + inline matrix4 + operator* ( const T constant, const matrix4 & m ) + { + matrix4 result( m[0] * constant, + m[1] * constant, + m[2] * constant, + m[3] * constant ); + return result; + } +// TODO: this might be wrong - need to test it with rotations etc. + template + inline vector4 + operator* ( const matrix4 & m, const vector4 & v ) + { + vector4 output; + + output.x = m.data[0] * v.x + m.data[4] * v.y + m.data[ 8] * v.z + m.data[12] * v.w; + output.y = m.data[1] * v.x + m.data[5] * v.y + m.data[ 9] * v.z + m.data[13] * v.w; + output.z = m.data[2] * v.x + m.data[6] * v.y + m.data[10] * v.z + m.data[14] * v.w; + output.w = m.data[3] * v.x + m.data[7] * v.y + m.data[11] * v.z + m.data[15] * v.w; + + return output; + } + + template + inline void matrix4:: + pointwiseMultiply ( const matrix4 & other ) + { + for ( int i = 0 ; i < 16 ; i += 4 ) + { + this->data[i] *= other.data[i]; + this->data[i+1] *= other.data[i+1]; + this->data[i+2] *= other.data[i+2]; + this->data[i+3] *= other.data[i+3]; + } + } + + + template + inline void matrix4:: + operator/= ( const matrix4 & other ) + { + matrix4 inv_other = Inverse( other ); + (*this) *= inv_other; + } + + template + inline void matrix4:: + operator/= ( const T constant ) + { + float inv_constant = (T)1.0 / constant; + for ( int i = 0 ; i < 16 ; i += 4 ) + { + this->data[i] *= inv_constant; + this->data[i+1] *= inv_constant; + this->data[i+2] *= inv_constant; + this->data[i+3] *= inv_constant; + } + } + + template + inline matrix4 + operator/ ( const matrix4 & m1, const matrix4 & m2 ) + { + matrix4 result( m1 ); + result /= m2; + return result; + } + + template + inline matrix4 + operator/ ( const matrix4 & m, const T constant ) + { + float inv_constant = (T)1.0 / constant; + matrix4 result( m[0] * inv_constant, + m[1] * inv_constant, + m[2] * inv_constant, + m[3] * inv_constant ); + return result; + } + + template + inline matrix4 + operator/ ( const T constant, const matrix4 & m ) + { + matrix4 result( constant / m[0], + constant / m[1], + constant / m[2], + constant / m[3] ); + return result; + } + + template + inline vector4 & matrix4:: + operator[] ( unsigned int i ) + { + return cols[i]; + } + + template + inline vector4 matrix4:: + operator[] ( unsigned int i ) const + { + return cols[i]; + } + + // GENERAL FUNCTIONS + + //--------------------------------------------------- + // Implementation + //--------------------------------------------------- + + + template + inline T + compute_determinant ( const matrix2 & matrix ) + { + return ( matrix.data[0] * matrix.data[3] - matrix.data[2] * matrix.data[1] ); + } + + template + inline T + compute_determinant ( const matrix3 & matrix ) + { + // code folows same intuition as inverse calculation for 3d matrices, + // however we only compute informatrixion needed + // for determinant calculation. + + float C[3]; + + // get required cofactors + C[0] = matrix.data[4] * matrix.data[8] - matrix.data[5] * matrix.data[7]; + C[1] = matrix.data[5] * matrix.data[6] - matrix.data[3] * matrix.data[8]; // negated + C[2] = matrix.data[3] * matrix.data[7] - matrix.data[4] * matrix.data[6]; + + return ( matrix.data[0] * C[0] + matrix.data[1] * C[1] + matrix.data[2] * C[2] ); + } + + template + T compute_determinant ( const matrix4 & matrix ) + { + // code folows same intuition as inverse calculation for 4d matrices, + // however we only compute informatrixion needed + // for determinant calculation. + float C[4]; + float coeffs[6]; + + // coeffs are determinants of 2x2 matrices + coeffs[0] = matrix.data[10] * matrix.data[15] - matrix.data[14] * matrix.data[11]; + coeffs[1] = matrix.data[ 6] * matrix.data[11] - matrix.data[10] * matrix.data[ 7]; + coeffs[2] = matrix.data[ 2] * matrix.data[ 7] - matrix.data[ 6] * matrix.data[ 3]; + coeffs[3] = matrix.data[ 6] * matrix.data[15] - matrix.data[14] * matrix.data[ 7]; + coeffs[4] = matrix.data[ 2] * matrix.data[11] - matrix.data[10] * matrix.data[ 3]; + coeffs[5] = matrix.data[ 2] * matrix.data[15] - matrix.data[14] * matrix.data[ 3]; + + // Cofactor matrix + /*00*/ C[0] = matrix.data[ 5] * coeffs[0] - + matrix.data[ 9] * coeffs[3] + + matrix.data[13] * coeffs[1]; + /*01*/ C[1] = matrix.data[ 9] * coeffs[5] - + matrix.data[ 1] * coeffs[0] - + matrix.data[13] * coeffs[4]; // negated + /*02*/ C[2] = matrix.data[ 1] * coeffs[3] - + matrix.data[ 5] * coeffs[5] + + matrix.data[13] * coeffs[2]; + /*03*/ C[3] = matrix.data[ 5] * coeffs[4] - + matrix.data[ 9] * coeffs[2] - + matrix.data[ 1] * coeffs[1]; // negated + + // determinant + T det = matrix.data[0] * C[0] + matrix.data[4] * C[1] + matrix.data[8] * C[2] + matrix.data[12] * C[3]; + + return det; + } + + template< typename T, template class matrixX > + inline T + determinant ( const matrixX & matrix ) + { + return compute_determinant ( matrix ); + } + + + + + template< typename T, template class matrixX > + inline T + trace ( const matrixX & matrix ) + { + T trace = (T)0; + for ( int i = 0 ; i < matrix.Dimensionality() ; ++i ) + { + trace += matrix.cols[i][i]; + } + return trace; + } + + + template< typename T > + inline matrix2 + compute_transpose ( const matrix2 & src ) + { + matrix2 trg ( false ); + trg[0][0] = src[0][0]; + trg[0][1] = src[1][0]; + trg[1][0] = src[0][1]; + trg[1][1] = src[1][1]; + return trg; + } + + template< typename T > + inline matrix3 + compute_transpose ( const matrix3 & src ) + { + matrix3 trg ( false ); + trg[0][0] = src[0][0]; + trg[0][1] = src[1][0]; + trg[0][2] = src[2][0]; + + trg[1][0] = src[0][1]; + trg[1][1] = src[1][1]; + trg[1][2] = src[2][1]; + + trg[2][0] = src[0][2]; + trg[2][1] = src[1][2]; + trg[2][2] = src[2][2]; + + return trg; + } + + template< typename T > + inline matrix4 + compute_transpose ( const matrix4 & src ) + { + matrix4 trg ( false ); + trg[0][0] = src[0][0]; + trg[0][1] = src[1][0]; + trg[0][2] = src[2][0]; + trg[0][3] = src[3][0]; + + trg[1][0] = src[0][1]; + trg[1][1] = src[1][1]; + trg[1][2] = src[2][1]; + trg[1][3] = src[3][1]; + + trg[2][0] = src[0][2]; + trg[2][1] = src[1][2]; + trg[2][2] = src[2][2]; + trg[2][3] = src[3][2]; + + trg[3][0] = src[0][3]; + trg[3][1] = src[1][3]; + trg[3][2] = src[2][3]; + trg[3][3] = src[3][3]; + + return trg; + } + + template< typename T, template class matrixX > + inline matrixX + transpose ( const matrixX & matrix ) + { + return compute_transpose( matrix ); + } + + + template + void + compute_inverse ( matrix2 & matrix ) + { + T one_over_det = ((T)1.0) / Determinant( matrix ); + + T vals[4]; + vals[0] = matrix.data[3]; + vals[1] = -matrix.data[1]; + vals[2] = -matrix.data[2]; + vals[3] = matrix.data[0]; + + matrix.data[0] = one_over_det * vals[0]; + matrix.data[1] = one_over_det * vals[1]; + matrix.data[2] = one_over_det * vals[2]; + matrix.data[3] = one_over_det * vals[3]; + } + + template + void + compute_inverse ( matrix3 & matrix ) + { + // To calculate inverse : + // 1. Transpose M + // 2. Calculate cofactor matrix C + // 3. Caluclate determinant of M + // 4. Inverse is given as (1/det) * C + + // Access cheat sheat for transpose matrix: + // original indices + // 0 1 2 + // 3 4 5 + // 6 7 8 + + // transposed indices + // 0 3 6 + // 1 4 7 + // 2 5 8 + + // Calulate cofactor matrix + float C[9]; + + C[0] = matrix.data[4] * matrix.data[8] - matrix.data[7] * matrix.data[5]; + C[1] = matrix.data[7] * matrix.data[2] - matrix.data[1] * matrix.data[8]; // negated + C[2] = matrix.data[1] * matrix.data[5] - matrix.data[4] * matrix.data[2]; + + C[3] = matrix.data[6] * matrix.data[5] - matrix.data[3] * matrix.data[8]; // negated + C[4] = matrix.data[0] * matrix.data[8] - matrix.data[6] * matrix.data[2]; + C[5] = matrix.data[3] * matrix.data[2] - matrix.data[0] * matrix.data[5]; // negated + + C[6] = matrix.data[3] * matrix.data[7] - matrix.data[6] * matrix.data[4]; + C[7] = matrix.data[6] * matrix.data[1] - matrix.data[0] * matrix.data[7]; // negated + C[8] = matrix.data[0] * matrix.data[4] - matrix.data[3] * matrix.data[1]; + + // determinant + T det = matrix.data[0] * C[0] + matrix.data[3] * C[1] + matrix.data[6] * C[2]; + T one_over_det = (T)1.0 / det; + + // store result + matrix.data[ 0] = one_over_det * C[ 0]; + matrix.data[ 1] = one_over_det * C[ 1]; + matrix.data[ 2] = one_over_det * C[ 2]; + matrix.data[ 3] = one_over_det * C[ 3]; + matrix.data[ 4] = one_over_det * C[ 4]; + matrix.data[ 5] = one_over_det * C[ 5]; + matrix.data[ 6] = one_over_det * C[ 6]; + matrix.data[ 7] = one_over_det * C[ 7]; + matrix.data[ 8] = one_over_det * C[ 8]; + } + + template + void + compute_inverse ( matrix4 & matrix ) + { + // TODO(maciej) : find intel document that was describing that + // Inverse using cramers rule + // 1. Transpose M + // 2. Calculate cofactor matrix C + // 3. Caluclate determinant of M + // 4. Inverse is given as (1/det) * C + + // Access cheat sheat: + // original indices + // 0 1 2 3 + // 4 5 6 7 + // 8 9 10 11 + // 12 13 14 15 + + // transposed indices + // 0 4 8 12 + // 1 5 9 13 + // 2 6 10 14 + // 3 7 11 15 + + + // Calulate cofactor matrix + float C[16]; + float coeffs[6]; + + // First 8 + // coeffs are determinants of 2x2 matrices + coeffs[0] = matrix.data[10] * matrix.data[15] - matrix.data[14] * matrix.data[11]; + coeffs[1] = matrix.data[ 6] * matrix.data[11] - matrix.data[10] * matrix.data[ 7]; + coeffs[2] = matrix.data[ 2] * matrix.data[ 7] - matrix.data[ 6] * matrix.data[ 3]; + coeffs[3] = matrix.data[ 6] * matrix.data[15] - matrix.data[14] * matrix.data[ 7]; + coeffs[4] = matrix.data[ 2] * matrix.data[11] - matrix.data[10] * matrix.data[ 3]; + coeffs[5] = matrix.data[ 2] * matrix.data[15] - matrix.data[14] * matrix.data[ 3]; + + // Cofactor matrix + /*00*/ C[0] = matrix.data[ 5] * coeffs[0] - + matrix.data[ 9] * coeffs[3] + + matrix.data[13] * coeffs[1]; + /*01*/ C[1] = matrix.data[ 9] * coeffs[5] - + matrix.data[ 1] * coeffs[0] - + matrix.data[13] * coeffs[4]; // negated + /*02*/ C[2] = matrix.data[ 1] * coeffs[3] - + matrix.data[ 5] * coeffs[5] + + matrix.data[13] * coeffs[2]; + /*03*/ C[3] = matrix.data[ 5] * coeffs[4] - + matrix.data[ 9] * coeffs[2] - + matrix.data[ 1] * coeffs[1]; // negated + + /*10*/ C[4] = matrix.data[ 8] * coeffs[3] - + matrix.data[ 4] * coeffs[0] - + matrix.data[12] * coeffs[1]; // negated + /*11*/ C[5] = matrix.data[ 0] * coeffs[0] - + matrix.data[ 8] * coeffs[5] + + matrix.data[12] * coeffs[4]; + /*12*/ C[6] = matrix.data[ 4] * coeffs[5] - + matrix.data[ 0] * coeffs[3] - + matrix.data[12] * coeffs[2]; // negated + /*13*/ C[7] = matrix.data[ 0] * coeffs[1] - + matrix.data[ 4] * coeffs[4] + + matrix.data[ 8] * coeffs[2]; + + //Second 8 + + // coeffs are Determinants of 2x2 matrices + coeffs[0] = matrix.data[ 8] * matrix.data[13] - matrix.data[12] * matrix.data[ 9]; + coeffs[1] = matrix.data[ 4] * matrix.data[ 9] - matrix.data[ 8] * matrix.data[ 5]; + coeffs[2] = matrix.data[ 0] * matrix.data[ 5] - matrix.data[ 4] * matrix.data[ 1]; + coeffs[3] = matrix.data[ 4] * matrix.data[13] - matrix.data[12] * matrix.data[ 5]; + coeffs[4] = matrix.data[ 0] * matrix.data[ 9] - matrix.data[ 8] * matrix.data[ 1]; + coeffs[5] = matrix.data[ 0] * matrix.data[13] - matrix.data[12] * matrix.data[ 1]; + + // actual coefficient matrix + /*20*/ C[ 8] = matrix.data[ 7] * coeffs[0] - + matrix.data[11] * coeffs[3] + + matrix.data[15] * coeffs[1]; + /*21*/ C[ 9] = matrix.data[11] * coeffs[5] - + matrix.data[ 3] * coeffs[0] - + matrix.data[15] * coeffs[4]; // negated + /*22*/ C[10] = matrix.data[ 3] * coeffs[3] - + matrix.data[ 7] * coeffs[5] + + matrix.data[15] * coeffs[2]; + /*23*/ C[11] = matrix.data[ 7] * coeffs[4] - + matrix.data[ 3] * coeffs[1] - + matrix.data[11] * coeffs[2]; // negated + + /*30*/ C[12] = matrix.data[10] * coeffs[3] - + matrix.data[ 6] * coeffs[0] - + matrix.data[14] * coeffs[1]; // negated + /*31*/ C[13] = matrix.data[ 2] * coeffs[0] - + matrix.data[10] * coeffs[5] + + matrix.data[14] * coeffs[4]; + /*32*/ C[14] = matrix.data[ 6] * coeffs[5] - + matrix.data[ 2] * coeffs[3] - + matrix.data[14] * coeffs[2]; // negated + /*33*/ C[15] = matrix.data[ 2] * coeffs[1] - + matrix.data[ 6] * coeffs[4] + + matrix.data[10] * coeffs[2]; + + // determinant + T det = matrix.data[0] * C[0] + matrix.data[ 4] * C[1] + + matrix.data[8] * C[2] + matrix.data[12] * C[3]; + T one_over_det = ((T)1) / det; + + // store result + matrix.data[ 0] = one_over_det * C[ 0]; + matrix.data[ 1] = one_over_det * C[ 1]; + matrix.data[ 2] = one_over_det * C[ 2]; + matrix.data[ 3] = one_over_det * C[ 3]; + matrix.data[ 4] = one_over_det * C[ 4]; + matrix.data[ 5] = one_over_det * C[ 5]; + matrix.data[ 6] = one_over_det * C[ 6]; + matrix.data[ 7] = one_over_det * C[ 7]; + matrix.data[ 8] = one_over_det * C[ 8]; + matrix.data[ 9] = one_over_det * C[ 9]; + matrix.data[10] = one_over_det * C[10]; + matrix.data[11] = one_over_det * C[11]; + matrix.data[12] = one_over_det * C[12]; + matrix.data[13] = one_over_det * C[13]; + matrix.data[14] = one_over_det * C[14]; + matrix.data[15] = one_over_det * C[15]; + + } + + template< typename T, template class matrixX > + inline matrixX + inverse ( const matrixX & matrix ) + { + static_assert( std::numeric_limits::is_iec559, + "'Inverse' only accepts real numbers!" ); + matrixX matrix_copy ( matrix ); + compute_inverse( matrix_copy ); + return matrix_copy; + } + + template< typename T> + inline matrix4 + frustum ( const T & left, const T & right, const T & bottom, const T & top, const T & z_near, const T & z_far ) + { + T x_diff = right - left; + T y_diff = top - bottom; + T z_diff = z_far - z_near; + T a = (right + left) / x_diff; + T b = (top + bottom) / y_diff; + T c = -(z_far + z_near ) / z_diff; + T d = -(2 * z_far * z_near ) / z_diff; + + T tmp[16] = { + ((T)2 * z_near) / x_diff, 0.0, 0.0, 0.0, + 0.0, ((T)2 * z_near) / y_diff, 0.0, 0.0, + a, b, c, -1.0, + 0.0, 0.0, d, 0.0 }; + return matrix4( tmp ); + } + + template< typename T> + inline matrix4 + perspective ( const T & fovy, const T & aspect, const T & z_near, const T & z_far) + { + T xmin, xmax, ymin, ymax; + + ymax = z_near * tanf( fovy * T(0.5) ); + ymin = -ymax; + + xmin = ymin * aspect; + xmax = ymax * aspect; + + return frustum( xmin, xmax, ymin, ymax, z_near, z_far ); + } + + + template< typename T> + inline matrix4 + ortho ( const T & left, const T & right, const T & bottom, const T & top, const T & z_near, const T & z_far ) + { + T x_diff = right - left; + T y_diff = top - bottom; + T z_diff = z_far - z_near; + T tx = - ( right + left ) / x_diff; + T ty = - ( top + bottom ) / y_diff; + T tz = - ( z_near + z_far ) / z_diff; + + T tmp[16] = { (T)2 / x_diff, 0.0, 0.0, 0.0, + 0.0, (T)2 / y_diff, 0.0, 0.0, + 0.0, 0.0, -(T)2 / z_diff, 0.0, + tx, ty, tz, 1.0 } ; + return matrix4( tmp ); + } + + + template< typename T> + inline matrix4 + look_at ( const vector3 & eye, const vector3 & center, const vector3 & up ) + { + vector3 z = normalize( eye - center ); + vector3 x = normalize( cross( up, z ) ); + vector3 y = normalize( cross( z, x ) ); + + T tmp[16] = { x[0], y[0], z[0], 0.0, + x[1], y[1], z[1], 0.0, + x[2], y[2], z[2], 0.0, + -dot(eye,x), -dot(eye,y), -dot(eye,z), 1.0 }; + + + return matrix4( tmp ); + } + + + template< typename T> + inline vector3 + project ( const vector4 & obj, const matrix4 & modelview, + const matrix4 & project, const vector4 & viewport ) + { + vector4 tmp = project * modelview * obj; + tmp /= tmp.w; + + vector3 win; + win.x = viewport[0] + ( viewport[2] * (tmp.x + 1.0) ) / 2.0; + win.y = viewport[1] + ( viewport[3] * (tmp.y + 1.0) ) / 2.0; + win.z = (tmp.z + 1.0) / 2.0; + + return win; + } + + template< typename T> + inline vector4 + unproject ( const vector3 &win, const matrix4 & modelview, + const matrix4 & project, const vector4 & viewport ) + { + matrix4 inv_pm = inverse( project * modelview ); + vector4 tmp; + tmp.x = ( 2.0 * ( win.x - viewport[0] ) ) / viewport[2] - 1.0; + tmp.y = ( 2.0 * ( win.y - viewport[1] ) ) / viewport[3] - 1.0; + tmp.z = 2.0 * win.z - 1.0; + tmp.w = 1.0; + + vector4 obj = inv_pm * tmp; + obj /= obj.w; + return obj; + } + + template< typename T> + inline matrix4 + translate( const matrix4 & m, const vector3 & t ) + { + matrix4 result( m ); + result[3] = m[0] * t.x + m[1] * t.y + m[2] * t.z + m[3]; + return result; + } + + template< typename T> + inline matrix4 + scale( const matrix4 & m, const vector3 & s ) + { + matrix4 result( m ); + result[0] *= s.x; + result[1] *= s.y; + result[2] *= s.z; + return result; + } + + // derivation : http://www.euclideanspace.com/matrixhs/geometry/rotations/conversions/angleToMatrix/ + template< typename T> + matrix4 + rotate( const matrix4 & m, const T & angle, const vector3 & v ) + { + T c = cos ( angle ); + T s = sin ( angle ); + T t = 1.0 - c; + + vector3 axis = normalize( v ); + + matrix4 rotate( false ); + rotate[0][0] = c + axis.x * axis.x * t; + rotate[1][1] = c + axis.y * axis.y * t; + rotate[2][2] = c + axis.z * axis.z * t; + + T tmp_1 = axis.x * axis.y * t; + T tmp_2 = axis.z * s; + + rotate[0][1] = tmp_1 + tmp_2; + rotate[1][0] = tmp_1 - tmp_2; + + tmp_1 = axis.x * axis.z * t; + tmp_2 = axis.y * s; + + rotate[0][2] = tmp_1 - tmp_2; + rotate[2][0] = tmp_1 + tmp_2; + + tmp_1 = axis.y * axis.z * t; + tmp_2 = axis.x * s; + + rotate[1][2] = tmp_1 + tmp_2; + rotate[2][1] = tmp_1 - tmp_2; + + matrix4 result( m ); + result[0] = m[0] * rotate[0][0] + m[1] * rotate[0][1] + m[2] * rotate[0][2]; + result[1] = m[0] * rotate[1][0] + m[1] * rotate[1][1] + m[2] * rotate[1][2]; + result[2] = m[0] * rotate[2][0] + m[1] * rotate[2][1] + m[2] * rotate[2][2]; + result[3] = m[3]; + return result; + } + +//////////////////////////////////////////////////////////////////////////////// +// Eigendecomposition +//////////////////////////////////////////////////////////////////////////////// + // NOTE: Following code is taken from files distributed by Conelly Barnes + +// namespace eig_decomposition +// { +// static double +// hypot2( double x, double y ) { +// return sqrt(x*x+y*y); +// } + +// // Symmetric Householder reduction to tridiagonal form. + +// static void +// tred2( double V[3][3], double d[3], double e[3] ) +// { + +// // This is derived from the Algol procedures tred2 by +// // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for +// // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding +// // Fortran subroutine in EISPACK. + +// int n = 3; + +// for (int j = 0; j < n; j++) { +// d[j] = V[n-1][j]; +// } + +// // Householder reduction to tridiagonal form. + +// for (int i = n-1; i > 0; i--) { + +// // Scale to avoid under/overflow. + +// double scale = 0.0; +// double h = 0.0; +// for (int k = 0; k < i; k++) { +// scale = scale + fabs(d[k]); +// } +// if (scale == 0.0) { +// e[i] = d[i-1]; +// for (int j = 0; j < i; j++) { +// d[j] = V[i-1][j]; +// V[i][j] = 0.0; +// V[j][i] = 0.0; +// } +// } else { + +// // Generate Householder vector. + +// for (int k = 0; k < i; k++) { +// d[k] /= scale; +// h += d[k] * d[k]; +// } +// double f = d[i-1]; +// double g = sqrt(h); +// if (f > 0) { +// g = -g; +// } +// e[i] = scale * g; +// h = h - f * g; +// d[i-1] = f - g; +// for (int j = 0; j < i; j++) { +// e[j] = 0.0; +// } + +// // Apply similarity transformation to remaining columns. + +// for (int j = 0; j < i; j++) { +// f = d[j]; +// V[j][i] = f; +// g = e[j] + V[j][j] * f; +// for (int k = j+1; k <= i-1; k++) { +// g += V[k][j] * d[k]; +// e[k] += V[k][j] * f; +// } +// e[j] = g; +// } +// f = 0.0; +// for (int j = 0; j < i; j++) { +// e[j] /= h; +// f += e[j] * d[j]; +// } +// double hh = f / (h + h); +// for (int j = 0; j < i; j++) { +// e[j] -= hh * d[j]; +// } +// for (int j = 0; j < i; j++) { +// f = d[j]; +// g = e[j]; +// for (int k = j; k <= i-1; k++) { +// V[k][j] -= (f * e[k] + g * d[k]); +// } +// d[j] = V[i-1][j]; +// V[i][j] = 0.0; +// } +// } +// d[i] = h; +// } + +// // Accumulate transformations. + +// for (int i = 0; i < n-1; i++) +// { +// V[n-1][i] = V[i][i]; +// V[i][i] = 1.0; +// double h = d[i+1]; +// if (h != 0.0) { +// for (int k = 0; k <= i; k++) { +// d[k] = V[k][i+1] / h; +// } +// for (int j = 0; j <= i; j++) { +// double g = 0.0; +// for (int k = 0; k <= i; k++) { +// g += V[k][i+1] * V[k][j]; +// } +// for (int k = 0; k <= i; k++) { +// V[k][j] -= g * d[k]; +// } +// } +// } +// for (int k = 0; k <= i; k++) { +// V[k][i+1] = 0.0; +// } +// } +// for (int j = 0; j < n; j++) { +// d[j] = V[n-1][j]; +// V[n-1][j] = 0.0; +// } +// V[n-1][n-1] = 1.0; +// e[0] = 0.0; +// } + +// // Symmetric tridiagonal QL algorithm. + +// static void +// tql2(double V[3][3], double d[3], double e[3]) { + +// // This is derived from the Algol procedures tql2, by +// // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for +// // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding +// // Fortran subroutine in EISPACK. + +// int n = 3; + +// for (int i = 1; i < n; i++) { +// e[i-1] = e[i]; +// } +// e[n-1] = 0.0; + +// double f = 0.0; +// double tst1 = 0.0; +// double eps = pow(2.0,-52.0); +// for (int l = 0; l < n; l++) { + +// // Find small subdiagonal element + +// tst1 = max(tst1,fabs(d[l]) + fabs(e[l])); +// int m = l; +// while (m < n) { +// if (fabs(e[m]) <= eps*tst1) { +// break; +// } +// m++; +// } + +// // If m == l, d[l] is an eigenvalue, +// // otherwise, iterate. + +// if (m > l) { +// int iter = 0; +// do { +// iter = iter + 1; // (Could check iteration count here.) + +// // Compute implicit shift + +// double g = d[l]; +// double p = (d[l+1] - g) / (2.0 * e[l]); +// double r = hypot2(p,1.0); +// if (p < 0) { +// r = -r; +// } +// d[l] = e[l] / (p + r); +// d[l+1] = e[l] * (p + r); +// double dl1 = d[l+1]; +// double h = g - d[l]; +// for (int i = l+2; i < n; i++) { +// d[i] -= h; +// } +// f = f + h; + +// // Implicit QL transformation. + +// p = d[m]; +// double c = 1.0; +// double c2 = c; +// double c3 = c; +// double el1 = e[l+1]; +// double s = 0.0; +// double s2 = 0.0; +// for (int i = m-1; i >= l; i--) { +// c3 = c2; +// c2 = c; +// s2 = s; +// g = c * e[i]; +// h = c * p; +// r = hypot2(p,e[i]); +// e[i+1] = s * r; +// s = e[i] / r; +// c = p / r; +// p = c * d[i] - s * g; +// d[i+1] = h + s * (c * g + s * d[i]); + +// // Accumulate transformation. + +// for (int k = 0; k < n; k++) { +// h = V[k][i+1]; +// V[k][i+1] = s * V[k][i] + c * h; +// V[k][i] = c * V[k][i] - s * h; +// } +// } +// p = -s * s2 * c3 * el1 * e[l] / dl1; +// e[l] = s * p; +// d[l] = c * p; + +// // Check for convergence. + +// } while (fabs(e[l]) > eps*tst1); +// } +// d[l] = d[l] + f; +// e[l] = 0.0; +// } + +// // Sort eigenvalues and corresponding vectors. + +// for (int i = 0; i < n-1; i++) { +// int k = i; +// double p = d[i]; +// for (int j = i+1; j < n; j++) { +// if (d[j] < p) { +// k = j; +// p = d[j]; +// } +// } +// if (k != i) { +// d[k] = d[i]; +// d[i] = p; +// for (int j = 0; j < n; j++) { +// p = V[j][i]; +// V[j][i] = V[j][k]; +// V[j][k] = p; +// } +// } +// } +// } +// } + + +// void +// eig( const mat3f * mat, +// mat3f * eigvec, +// vec3f * eigval ) +// { +// bsc::stop_watch timer; +// timer.start(); +// // copy data into their format +// double V[3][3]; +// double d[3]; +// double e[3]; +// for ( int i = 0; i < 3 ; ++i ) +// { +// for ( int j = 0; j < 3 ; ++j ) +// { +// V[i][j] = (*mat)[i][j]; +// } +// } +// // perform the calculation +// eig_decomposition::tred2( V, d, e ); +// eig_decomposition::tql2( V, d, e ); + +// // copy data_back +// for ( int i = 0; i < 3 ; ++i ) +// { +// for ( int j = 0; j < 3 ; ++j ) +// { +// (*eigvec)[j][i] = V[i][j]; +// } +// (*eigval)[i] = d[i]; +// } +// printf("Eigen decomposition took : %f\n", timer.elapsed()); +// } +// // need to experiment more. Does not work that great :< +// mat4f +// pca( const vec3f * points, const i32 n_points ) +// { +// // centroid +// bsc::vec3f centroid; +// for ( i32 p_idx = 0 ; p_idx < n_points ; ++p_idx ) +// { +// centroid += points[p_idx]; +// } +// centroid /= (r32)n_points; + +// // covariance matrix +// bsc::mat3f cov; +// for (i32 p_idx = 0; p_idx < n_points; ++p_idx) { +// bsc::vec3f v = points[p_idx] - centroid; + +// cov[0][0] += v.x*v.x; +// cov[0][1] += v.x*v.y; +// cov[0][2] += v.x*v.z; + +// cov[1][0] += v.y*v.x; +// cov[1][1] += v.y*v.y; +// cov[2][2] += v.y*v.z; + +// cov[2][0] += v.z*v.x; +// cov[2][1] += v.z*v.y; +// cov[2][2] += v.z*v.z; +// } +// cov /= (r32)n_points; + +// // eigen decomposition +// bsc::mat3f evec; +// bsc::vec3f eval; +// bsc::eig( &cov, &evec, &eval ); + +// // build matrix +// bsc::mat4 ret; +// ret[0] = bsc::vec4( evec[2], 0.0f ); +// ret[1] = bsc::vec4( evec[0], 0.0f ); +// ret[2] = bsc::vec4( evec[1], 0.0f ); +// ret[3] = bsc::vec4f( centroid, 1.0); + +// return ret; +// } +} diff --git a/CameraParameterEstimation/apps/basics/linalg/quaternion.h b/CameraParameterEstimation/apps/basics/linalg/quaternion.h new file mode 100644 index 0000000..9cf52dc --- /dev/null +++ b/CameraParameterEstimation/apps/basics/linalg/quaternion.h @@ -0,0 +1,480 @@ +#pragma once + +//--------------------------------------------------- +// Interface +//--------------------------------------------------- + + +namespace bsc +{ + template + struct quaternion + { + union + { + struct { T x, y, z, w; }; + struct { vector3 im; T re; }; + }; + + quaternion(); + quaternion( const T re ); + quaternion( const vector3 & im ); + quaternion( const T re, const vector3 & im ); + quaternion( const T w, const T x, const T y, const T z ); + quaternion( const quaternion & other ); + + quaternion & operator= ( const quaternion & other ); + + void operator+=( const quaternion & other ); + void operator+=( const T constant ); + quaternion operator+( const quaternion & other ) const; + quaternion operator+( const T constant ) const; + + void operator-=( const quaternion & other ); + void operator-=( const T constant ); + quaternion operator- ( void ); + quaternion operator-( const quaternion & other ) const; + quaternion operator-( const T constant ) const; + + void operator*=( const quaternion & other ); + void operator*=( const T constant ); + quaternion operator*( const quaternion & other ) const; + quaternion operator*( const T constant ) const; + + void operator/=( const quaternion & other ); + void operator/=( const T constant ); + quaternion operator/( const quaternion & other ) const; + quaternion operator/( const T constant ) const; + + bool operator==( const quaternion & other ) const; + bool operator!=( const quaternion & other ) const; + + T operator[] ( const u32 i ) const; + T& operator[] ( const u32 i ); + }; + + template + T dot ( const quaternion & q1, const quaternion & q2 ); + + template + T norm ( const quaternion & q ); + + template + T normSq ( const quaternion & q ); + + template + quaternion normalize( const quaternion & q ); + + template + quaternion conjugate( const quaternion & q ); + + template + quaternion inverse( const quaternion & q ); + + template + quaternion slerp( const quaternion & q, + const quaternion & r, + const T t ); + + template + matrix3 to_mat3 ( const quaternion & q ); + + template + matrix4 to_mat4 ( const quaternion & q ); + + template + quaternion to_quat ( const matrix3 & m ); + + template + quaternion to_quat ( const matrix4 & m ); + + typedef quaternion quatd; + typedef quaternion quatf; + typedef quaternion quat; +} + +//--------------------------------------------------- +// Interface +//--------------------------------------------------- + +namespace bsc +{ + + template + quaternion:: + quaternion () + { + this->re = 0; + this->im = vector3(); + } + + template + quaternion:: + quaternion ( const T re ) + { + this->re = re; + this->im = vector3(); + } + + template + quaternion:: + quaternion ( const vector3 & im ) + { + this->re = (T)0; + this->im = im; + } + + template + quaternion:: + quaternion ( const T re, const vector3 & im ) + { + this->re = re; + this->im = im; + } + + template + quaternion:: + quaternion ( const T w, const T x, const T y, const T z ) + { + this->w = w; + this->x = x; + this->y = y; + this->z = z; + } + + template + quaternion:: + quaternion ( const quaternion & other ) + { + this->re = other.re; + this->im = other.im; + } + + template + inline T quaternion:: + operator[] ( const u32 i ) const + { + return *(&(this->x) + i); + } + + template + inline T& quaternion:: + operator[] ( const u32 i ) + { + return *(&(this->x) + i); + } + + template + inline quaternion & quaternion:: + operator= ( const quaternion & other ) + { + this->re = other.re; + this->im = other.im; + return *this; + } + + template + inline void quaternion:: + operator+=( const quaternion & other ) + { + this->re += other.re; + this->im += other.im; + } + + template + inline void quaternion:: + operator+=( const T constant ) + { + this->re += constant; + } + + template + inline quaternion quaternion:: + operator+( const quaternion & other ) const + { + return quaternion( this->re + other.re, + this->im + other.im ); + } + + template + inline quaternion quaternion:: + operator+( const T constant ) const + { + return quaternion( this->re + constant, + this->im ); + } + + template + inline void quaternion:: + operator-=( const quaternion & other ) + { + this->re -= other.re; + this->im -= other.im; + } + + template + inline void quaternion:: + operator-=( const T constant ) + { + this->re -= constant; + } + + template + inline quaternion quaternion:: + operator- ( void ) + { + this->re = -this->re; + this->im = -this->im ; + return *this; + } + + template + inline quaternion quaternion:: + operator- ( const quaternion & other ) const + { + return quaternion( this->re - other.re, + this->im - other.im ); + } + + template + inline quaternion quaternion:: + operator- ( const T constant ) const + { + return quaternion( this->re - constant, + this->im ); + } + + template + inline void quaternion:: + operator*= ( const quaternion & other ) + { + T tmp_re = this->re * other.re - bsc::dot( this->im, other.im ); + vector3 tmp_im = other.im * this->re + + this->im * other.re + + cross( this->im, other.im ); + + this->re = tmp_re; + this->im = tmp_im; + } + + template + inline void quaternion:: + operator*= ( const T constant ) + { + this->re *= constant; + this->im *= constant; + } + + template + inline quaternion quaternion:: + operator* ( const quaternion & other ) const + { + quaternion Result( *this ); + Result *= other; + return Result; + } + + template + inline quaternion quaternion:: + operator* ( const T constant ) const + { + return quaternion( this->re * constant, + this->im * constant ); + } + + + template + inline void quaternion:: + operator/= ( const quaternion & other ) + { + quaternion otherTmp ( other ); + otherTmp.inverse(); + + this *= otherTmp; + } + + template + inline void quaternion:: + operator/= ( const T constant ) + { + this->re /= constant; + this->im /= constant; + } + + template + inline quaternion quaternion :: + operator/ ( const quaternion & other ) const + { + quaternion Result( *this ); + Result /= other; + return Result; + } + + template + inline quaternion quaternion :: + operator/ ( const T constant ) const + { + return quaternion( this->re / constant, + this->im / constant ); + } + + // GENERAL FUNCTIONS + template + inline T + dot ( const quaternion & q1, const quaternion & q2 ) + { + return q1.re * q2.re + bsc::dot( q1.im, q2.im ); + } + + template + inline T + norm ( const quaternion & q ) + { + return sqrt( bsc::dot( q, q ) ); + } + + template + inline T + normSq ( const quaternion & q ) + { + return bsc::dot( q, q ); + } + + + template + inline bsc::quaternion + inverse ( const quaternion & q ) + { + quaternion p( q ); + T Normalization = bsc::normSq( p ); + p.re /= Normalization; + p.im = -p.im; + p.im /= Normalization; + return p; + } + + // NOTE: Can we simplify this? Inigo's avoiding trigonometry notes. + template + inline bsc::quaternion + slerp ( const quaternion & q, const quaternion & r, const T t ) + { + r32 a = acos( dot(q, r) ); + quaternion p; + if ( fabs( a ) > 1e-6 ) + { + p = q * (sin(a * (1.0-t)) / sin(a)) + r * (sin(a * t) / sin(a)); + } + else + { + p = q * (1.0 - t) + r * t; + } + return p; + } + + template + inline bsc::quaternion + conjugate ( const quaternion & q ) + { + quaternion p( q ); + p.im = -p.im; + return p; + } + + template + inline bsc::quaternion + normalize ( const quaternion & q ) + { + quaternion p( q ); + p.im /= bsc::norm( p ); + return p; + } + + + // derivation http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/ + template + inline matrix3 + to_mat3 ( const quaternion & q ) + { + matrix3 m(false); + T xx( q.x * q.x ); + T xy( q.x * q.y ); + T xz( q.x * q.z ); + T xw( q.x * q.w ); + + T yy( q.y * q.y ); + T yz( q.y * q.z ); + T yw( q.y * q.w ); + + T zz( q.z * q.z ); + T zw( q.z * q.w ); + + m[0][0] = 1 - 2 * (yy + zz); + m[0][1] = 2 * (xy + zw); + m[0][2] = 2 * (xz - yw); + + m[1][0] = 2 * (xy - zw); + m[1][1] = 1 - 2 * (xx + zz); + m[1][2] = 2 * (yz + xw); + + m[2][0] = 2 * (xz + yw); + m[2][1] = 2 * (yz - xw); + m[2][2] = 1 - 2 * (xx + yy); + return m; + } + + template + inline matrix4 + to_mat4 ( const quaternion & q ) + { + return matrix4( to_mat3( q ) ); + } + + // derivation http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ + template + inline bsc::quaternion + to_quat ( const matrix3 & m ) + { + r32 tr = m[0][0] + m[1][1] + m[2][2]; + quaternion q; + if (tr > 0) + { + r32 S = sqrtf( tr + 1.0f ) * 2; + q.w = 0.25f * S; + q.x = ( m[1][2] - m[2][1] ) / S; + q.y = ( m[2][0] - m[0][2] ) / S; + q.z = ( m[0][1] - m[1][0] ) / S; + } + else if ( ( m[0][0] > m[1][1]) && (m[0][0] > m[2][2] ) ) + { + r32 S = sqrtf( 1.0f + m[0][0] - m[1][1] - m[2][2]) * 2.0f; + q.w = ( m[1][2] - m[2][1] ) / S; + q.x = 0.25f * S; + q.y = ( m[1][0] + m[0][1] ) / S; + q.z = ( m[2][0] + m[0][2] ) / S; + } + else if ( m[1][1] > m[2][2] ) + { + r32 S = sqrtf( 1.0f + m[1][1] - m[0][0] - m[2][2]) * 2.0f; + q.w = ( m[2][0] - m[0][2] ) / S; + q.x = ( m[1][0] + m[0][1] ) / S; + q.y = 0.25f * S; + q.z = ( m[2][1] + m[1][2] ) / S; + } else + { + r32 S = sqrtf( 1.0f + m[2][2] - m[0][0] - m[1][1] ) * 2.0f; + q.w = ( m[0][1] - m[1][0] ) / S; + q.x = ( m[2][0] + m[0][2] ) / S; + q.y = ( m[2][1] + m[1][2] ) / S; + q.z = 0.25f * S; + } + return q; + } + + template + inline bsc::quaternion + to_quat ( const matrix4 & m ) + { + return to_quat( matrix3(m) ); + } + +} diff --git a/CameraParameterEstimation/apps/basics/linalg/vector.h b/CameraParameterEstimation/apps/basics/linalg/vector.h new file mode 100644 index 0000000..51fe9c4 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/linalg/vector.h @@ -0,0 +1,1237 @@ +#pragma once + +//////////////////////////////////////////////////////////////////////////////// +// Interface +//////////////////////////////////////////////////////////////////////////////// + +namespace bsc +{ + template struct vector2; + template struct vector3; + template struct vector4; + + // VECTOR 2 + template + struct vector2 + { + union + { + struct { T x, y; }; + struct { T r, g; }; + struct { T p, q; }; + T data[2]; + }; + + vector2 ( void ); + vector2 ( T v ); + vector2 ( T x, T y ); + vector2 ( const vector2 &other ); + vector2 ( const vector3 &other ); + vector2 ( const vector4 &other ); + + vector2 & operator= ( const vector2 & other ); + + void operator+= ( const vector2 & other ); + void operator+= ( const T constant ); + + void operator-= ( const vector2 & other ); + void operator-= ( const T constant ); + + void operator*= ( const vector2 & other ); + void operator*= ( const T constant ); + + void operator/= ( const vector2 & other ); + void operator/= ( const T constant ); + + bool operator== ( const vector2 & other ) const; + bool operator!= ( const vector2 & other ) const; + + T operator[] ( u32 i ) const; + T& operator[] ( u32 i ); + + const constexpr int size() const { return 2; } + }; + + // VECTOR 3 + template + struct vector3 + { + union + { + struct { T x, y, z; }; + struct { T r, g, b; }; + struct { T p, q, s; }; + T data[3]; + }; + + vector3 ( void ); + vector3 ( T v ); + vector3 ( T x, T y, T z ); + vector3 ( const vector3 & other ); + vector3 ( const T v, const vector2 & other ); + vector3 ( const vector2 & other, const T v ); + vector3 ( const vector4 & other ); + + vector3 & operator= ( const vector3 & other ); + + void operator+= ( const vector3 & other ); + void operator+= ( const T constant ); + + void operator-= ( const vector3 & other ); + void operator-= ( const T constant ); + + void operator*= ( const vector3 & other ); + void operator*= ( const T constant ); + + void operator/= ( const vector3 & other ); + void operator/= ( const T constant ); + + bool operator== ( const vector3 & other ) const; + bool operator!= ( const vector3 & other ) const; + + T operator[] ( u32 i ) const; + T& operator[] ( u32 i ); + + const constexpr int size() const { return 3; } + }; + + // VECTOR 4 + template + struct vector4 + { + union + { + struct { T x, y, z, w; }; + struct { T r, g, b, a; }; + struct { T p, q, s, t; }; + T data[4]; + }; + + vector4 ( void ); + vector4 ( T v ); + vector4 ( T x, T y, T z, T w ); + vector4 ( const vector4 &other ); + vector4 ( const vector2 &other, const T v ); + vector4 ( const vector2 &other, const T v1, const T v2 ); + vector4 ( const vector3 &other, const T v ); + vector4 ( const T v, const vector3 &other ); + + vector4 & operator= ( const vector4 & v ); + + void operator+= ( const vector4 & other ); + void operator+= ( const T constant ); + + void operator-= ( const vector4 & other ); + void operator-= ( const T constant ); + + void operator*= ( const vector4 & other ); + void operator*= ( const T constant ); + + void operator/= ( const vector4 & other ); + void operator/= ( const T constant ); + + bool operator== ( const vector4 & other ) const; + bool operator!= ( const vector4 & other ) const; + + T operator[] ( u32 i ) const; + T& operator[] ( u32 i ); + + const constexpr int size() const { return 4; } + }; + + template< typename T, template class vecX > + T dot ( const vecX & a, const vecX & b ); + + template< typename T, template class vecX > + T norm_sq ( const vecX & a ); + + template< typename T, template class vecX > + T norm ( const vecX & a ); + + template< typename T, template class vecX > + T distance ( const vecX & a, const vecX & b ); + + template< typename T, template class vecX > + vecX normalize ( const vecX & a ); + + template< typename T, template class vecX > + vecX abs ( const vecX & a ); + + template< typename T, template class vecX > + vecX clamp ( const vecX & a, const T val_min = 0.0, const T val_max = 1.0 ); + + template< typename T > + vector3 cross ( const vector3 & a, const vector3 & b ); + + template< typename T > + T parallelogramArea ( const vector3 & a, const vector3 & b ); + + template< typename T > + T parallelogramArea ( const vector2 & a, const vector2 & b ); + + template< typename T> + T scalarTripleProduct( const vector3 & a, const vector3 & b, const vector3 & c ); + + template< typename T> + T parallelepipedVolume( const vector3 & a, const vector3 & b, const vector3 & c ); + + template< typename T > + int ccw ( const vector2 & a, const vector2 & b ); + + typedef vector2 vec2; // the default + typedef vector3 vec3; // the default + typedef vector4 vec4; // the default + + typedef vector2 vec2d; + typedef vector2 vec2f; + typedef vector2 vec2i; + + typedef vector3 vec3d; + typedef vector3 vec3f; + typedef vector3 vec3i; + + typedef vector4 vec4d; + typedef vector4 vec4f; + typedef vector4 vec4i; +} + + +//////////////////////////////////////////////////////////////////////////////// +// Implementation +//////////////////////////////////////////////////////////////////////////////// + +// VECTOR 2 + +namespace bsc +{ + template + vector2 :: + vector2 ( void ) : x( (T) 0 ), y( (T) 0 ) + {} + + + template + vector2 :: + vector2 ( T v ) : x( v ), y( v ) + {} + + + template + vector2 :: + vector2 ( T x, T y ) : x( x ), y( y ) + {} + + + template + vector2 :: + vector2 ( const vector2 &other ) : x( other.x ), y( other.y ) + {} + + + template + vector2 :: + vector2 ( const vector3 &other ) : x( other.x ), y( other.y ) + {} + + + template + vector2 :: + vector2 ( const vector4 &other ) : x( other.x ), y( other.y ) + {} + + template + inline vector2 & vector2 :: + operator= ( const vector2 & v) + { + this->x = v.x; + this->y = v.y; + return *this; + } + + template + inline void vector2 :: + operator+= ( const vector2 & other ) + { + this->x += other.x; + this->y += other.y; + } + + + template + inline void vector2 :: + operator+= ( const T constant ) + { + this->x += constant; + this->y += constant; + } + + + template + inline vector2 + operator+ ( const vector2 & v1, const vector2 & v2 ) + { + vector2 result( v1.x + v2.x, + v1.y + v2.y ); + return result; + } + + template + inline vector2 + operator+ ( const vector2 & v, const T constant ) + { + vector2 result( v.x + constant, + v.y + constant ); + return result; + } + + template + inline vector2 + operator+ ( const T constant, const vector2 & v ) + { + vector2 result( v.x + constant, + v.y + constant ); + return result; + } + + + template + inline void vector2 :: + operator-= ( const vector2 & other ) + { + this->x -= other.x; + this->y -= other.y; + } + + template + inline void vector2 :: + operator-= ( const T constant ) + { + this->x -= constant; + this->y -= constant; + } + + + template + inline vector2 + operator- ( const vector2 & v1, const vector2 & v2 ) + { + vector2 result( v1.x - v2.x, + v1.y - v2.y ); + return result; + } + + template + inline vector2 + operator- ( const vector2 & v, const T constant ) + { + vector2 result( v.x - constant, + v.y - constant ); + return result; + } + + template + inline vector2 + operator- ( const T constant, const vector2 & v ) + { + vector2 result( constant - v.x, + constant - v.y ); + return result; + } + + + template + inline vector2 + operator- ( const vector2 & v ) + { + vector2 result( -v.x, + -v.y ); + return result; + } + + + template + inline void vector2 :: + operator*= ( const vector2 & other ) + { + this->x *= other.x; + this->y *= other.y; + } + + template + inline void vector2 :: + operator*= ( const T constant ) + { + this->x *= constant; + this->y *= constant; + } + + + template + inline vector2 + operator* ( const vector2 & v1, const vector2 & v2 ) + { + vector2 result( v1.x * v2.x, + v1.y * v2.y ); + return result; + } + + template + inline vector2 + operator* ( const vector2 & v, const T constant ) + { + vector2 result( v.x * constant, + v.y * constant ); + return result; + } + + template + inline vector2 + operator* ( const T constant, const vector2 & v ) + { + vector2 result( v.x * constant, + v.y * constant ); + return result; + } + + template + inline void vector2 :: + operator/= ( const vector2 & other ) + { + this->x /= other.x; + this->y /= other.y; + } + + template + inline void vector2 :: + operator/= ( const T constant ) + { + T inv_constant = 1.0f / constant; + this->x *= inv_constant; + this->y *= inv_constant; + } + + template + inline vector2 + operator/ ( const vector2 & v1, const vector2 & v2 ) + { + vector2 result( v1.x / v2.x, + v1.y / v2.y ); + return result; + } + + template + inline vector2 + operator/ ( const vector2 & v, const T constant ) + { + vector2 result( v.x / constant, + v.y / constant ); + return result; + } + + template + inline vector2 + operator/ ( const T constant, const vector2 & v ) + { + vector2 result( constant / v.x, + constant / v.y ); + return result; + } + + + template + inline T vector2 :: + operator[] ( u32 i ) const + { + return this->data[ i ]; + } + + + template + inline T& vector2 :: + operator[] ( u32 i ) + { + return this->data[ i ]; + } + + + template + inline bool vector2 :: + operator== ( const vector2& other ) const + { + if ( this->x == other.x && + this->y == other.y ) + { + return true; + } + else + { + return false; + } + } + + + template + inline bool vector2 :: + operator!= (const vector2& other) const + { + return !(*this == other); + } + + + // VECTOR 3 + + template + vector3 :: + vector3 ( void ) : x( (T)0 ), y( (T)0 ), z( (T)0 ) + {} + + template + vector3 :: + vector3 ( T v ) : x( v ), y( v ), z( v ) + {} + + template + vector3 :: + vector3( T x, T y, T z ) : x( x ), y( y ), z( z ) + { + } + + template + vector3 :: + vector3 ( const vector3 &other ) : x( other.x ), y( other.y ), z( other.z ) + { + } + + template + vector3 :: + vector3 ( const T v, const vector2 &other ) : x( v ), y( other.x ), z( other.y ) + {} + + template + vector3 :: + vector3 ( const vector2 &other, const T v ) : x( other.x ), y( other.y ), z( v ) + {} + + template + vector3 :: + vector3 ( const vector4 &other ) : x( other.x ), y( other.y ), z( other.z ) + {} + + template + inline vector3 & vector3 :: + operator=( const vector3 & other ) + { + this->x = other.x; + this->y = other.y; + this->z = other.z; + return *this; + } + + template + inline void vector3 :: + operator+= ( const vector3 & other ) + { + this->x += other.x; + this->y += other.y; + this->z += other.z; + } + + + template + inline void vector3 :: + operator+= ( const T constant ) + { + this->x += constant; + this->y += constant; + this->z += constant; + } + + + template + inline vector3 + operator+ ( const vector3 & v1, const vector3 & v2 ) + { + vector3 result( v1.x + v2.x, + v1.y + v2.y, + v1.z + v2.z ); + return result; + } + + template + inline vector3 + operator+ ( const vector3 & v, const T constant ) + { + vector3 result( v.x + constant, + v.y + constant, + v.z + constant ); + return result; + } + + template + inline vector3 + operator+ ( const T constant, const vector3 & v ) + { + vector3 result( v.x + constant, + v.y + constant, + v.z + constant ); + return result; + } + + + template + inline void vector3 :: + operator-= ( const vector3 & other ) + { + this->x -= other.x; + this->y -= other.y; + this->z -= other.z; + } + + template + inline void vector3 :: + operator-= ( const T constant ) + { + this->x -= constant; + this->y -= constant; + this->z -= constant; + } + + + template + inline vector3 + operator- ( const vector3 & v1, const vector3 & v2 ) + { + vector3 result( v1.x - v2.x, + v1.y - v2.y, + v1.z - v2.z ); + return result; + } + + template + inline vector3 + operator- ( const vector3 & v, const T constant ) + { + vector3 result( v.x - constant, + v.y - constant, + v.z - constant ); + return result; + } + + template + inline vector3 + operator- ( const T constant, const vector3 & v ) + { + vector3 result( constant - v.x, + constant - v.y, + constant - v.z ); + return result; + } + + + template + inline vector3 + operator- ( const vector3 & v ) + { + vector3 result( -v.x, + -v.y, + -v.z ); + return result; + } + + + template + inline void vector3 :: + operator*= ( const vector3 & other ) + { + this->x *= other.x; + this->y *= other.y; + this->z *= other.z; + } + + template + inline void vector3 :: + operator*= ( const T constant ) + { + this->x *= constant; + this->y *= constant; + this->z *= constant; + } + + + template + inline vector3 + operator* ( const vector3 & v1, const vector3 & v2 ) + { + vector3 result( v1.x * v2.x, + v1.y * v2.y, + v1.z * v2.z ); + return result; + } + + template + inline vector3 + operator* ( const vector3 & v, const T constant ) + { + vector3 result( v.x * constant, + v.y * constant, + v.z * constant ); + return result; + } + + template + inline vector3 + operator* ( const T constant, const vector3 & v ) + { + vector3 result( v.x * constant, + v.y * constant, + v.z * constant ); + return result; + } + + template + inline void vector3 :: + operator/= ( const vector3 & other ) + { + this->x /= other.x; + this->y /= other.y; + this->z /= other.z; + } + + template + inline void vector3 :: + operator/= ( const T constant ) + { + T inv_constant = 1.0f / constant; + this->x *= inv_constant; + this->y *= inv_constant; + this->z *= inv_constant; + } + + template + inline vector3 + operator/ ( const vector3 & v1, const vector3 & v2 ) + { + vector3 result( v1.x / v2.x, + v1.y / v2.y, + v1.z / v2.z ); + return result; + } + + template + inline vector3 + operator/ ( const vector3 & v, const T constant ) + { + vector3 result( v.x / constant, + v.y / constant, + v.z / constant ); + return result; + } + + template + inline vector3 + operator/ ( const T constant, const vector3 & v ) + { + vector3 result( constant / v.x, + constant / v.y, + constant / v.z ); + return result; + } + + template + inline T vector3 :: + operator[] ( u32 i ) const + { + return this->data[ i ]; + } + + + template + inline T& vector3 :: + operator[] ( u32 i ) + { + return this->data[ i ]; + } + + + template + inline bool vector3 :: + operator== ( const vector3& other ) const + { + if ( this->x == other.x && + this->y == other.y && + this->z == other.z ) + { + return true; + } + else + { + return false; + } + } + + + template + inline bool vector3 :: + operator!= ( const vector3& other ) const + { + return !(*this == other); + } + + + // VECTOR 4 + template + vector4 :: + vector4 ( void ) : x( (T)0 ), y( (T)0 ), z( (T)0 ), w( (T)0 ) + {} + + template + vector4 :: + vector4 ( T v ) : x( v ), y( v ), z( v ), w( v ) + {} + + template + vector4 :: + vector4 ( T x, T y, T z, T w ) : x( x ), y( y ), z( z ), w( w ) + {} + + template + vector4 :: + vector4 ( const vector4 &other ) : x( other.x ), y( other.y ), z( other.z ), w( other.w ) + {} + + template + vector4 :: + vector4( const vector2 &other, const T v ) : x( other.x ), y( other.y ), z( v ), w( v ) + {} + + template + vector4 :: + vector4 ( const vector2 &other, const T v1, const T v2 ) : x( other.x ), y( other.y ), z( v1 ), w( v2 ) + {} + + template + vector4 :: + vector4 ( const vector3 &other, const T v ) : x( other.x ),y( other.y ), z( other.z ), w( v ) {} + + template + vector4 :: + vector4 ( const T v, const vector3 &other ) : x( v ), y( other.x ), z( other.y ), w( other.z ) + {} + + template + inline vector4 & vector4 :: + operator= ( const vector4 & v) + { + this->x = v.x; + this->y = v.y; + this->z = v.z; + this->w = v.w; + return *this; + } + + template + inline void vector4 :: + operator+= ( const vector4 & other ) + { + this->x += other.x; + this->y += other.y; + this->z += other.z; + this->w += other.w; + } + + template + inline void vector4 :: + operator+= ( const T constant ) + { + this->x += constant; + this->y += constant; + this->z += constant; + this->w += constant; + } + + template + inline vector4 + operator+ ( const vector4 & v1, const vector4 & v2 ) + { + vector4 result( v1.x + v2.x, + v1.y + v2.y, + v1.z + v2.z, + v1.w + v2.w ); + return result; + } + + template + inline vector4 + operator+ ( const vector4 & v, const T constant ) + { + vector4 result( v.x + constant, + v.y + constant, + v.z + constant, + v.w + constant ); + return result; + } + + template + inline vector4 + operator+ ( const T constant, const vector4 & v ) + { + vector4 result( v.x + constant, + v.y + constant, + v.z + constant, + v.w + constant ); + return result; + } + + + template + inline void vector4 :: + operator-= ( const vector4 & other ) + { + this->x -= other.x; + this->y -= other.y; + this->z -= other.z; + this->w -= other.w; + } + + template + inline void vector4 :: + operator-= ( const T constant ) + { + this->x -= constant; + this->y -= constant; + this->z -= constant; + this->w -= constant; + } + + + template + inline vector4 + operator- ( const vector4 & v1, const vector4 & v2 ) + { + vector4 result( v1.x - v2.x, + v1.y - v2.y, + v1.z - v2.z, + v1.w - v2.w ); + return result; + } + + template + inline vector4 + operator- ( const vector4 & v, const T constant ) + { + vector4 result( v.x - constant, + v.y - constant, + v.z - constant, + v.w - constant ); + return result; + } + + template + inline vector4 + operator- ( const T constant, const vector4 & v ) + { + vector4 result( constant - v.x, + constant - v.y, + constant - v.z, + constant - v.w ); + return result; + } + + + template + inline vector4 + operator- ( const vector4 & v ) + { + vector4 result( -v.x, + -v.y, + -v.z, + -v.w ); + return result; + } + + + template + inline void vector4 :: + operator*= ( const vector4 & other ) + { + this->x *= other.x; + this->y *= other.y; + this->z *= other.z; + this->w *= other.w; + } + + template + inline void vector4 :: + operator*= ( const T constant ) + { + this->x *= constant; + this->y *= constant; + this->z *= constant; + this->w *= constant; + } + + + template + inline vector4 + operator* ( const vector4 & v1, const vector4 & v2 ) + { + vector4 result( v1.x * v2.x, + v1.y * v2.y, + v1.z * v2.z, + v1.w * v2.w ); + return result; + } + + template + inline vector4 + operator* ( const vector4 & v, const T constant ) + { + vector4 result( v.x * constant, + v.y * constant, + v.z * constant, + v.w * constant ); + return result; + } + + template + inline vector4 + operator* ( const T constant, const vector4 & v ) + { + vector4 result( v.x * constant, + v.y * constant, + v.z * constant, + v.w * constant ); + return result; + } + + template + inline void vector4 :: + operator/= ( const vector4 & other ) + { + this->x /= other.x; + this->y /= other.y; + this->z /= other.z; + this->w /= other.w; + } + + template + inline void vector4 :: + operator/= ( const T constant ) + { + T inv_constant = 1.0f / constant; + this->x *= inv_constant; + this->y *= inv_constant; + this->z *= inv_constant; + this->w *= inv_constant; + } + + template + inline vector4 + operator/ ( const vector4 & v1, const vector4 & v2 ) + { + vector4 result( v1.x / v2.x, + v1.y / v2.y, + v1.z / v2.z, + v1.w / v2.w ); + return result; + } + + template + inline vector4 + operator/ ( const vector4 & v, const T constant ) + { + vector4 result( v.x / constant, + v.y / constant, + v.z / constant, + v.w / constant ); + return result; + } + + template + inline vector4 + operator/ ( const T constant, const vector4 & v ) + { + vector4 result( constant / v.x, + constant / v.y, + constant / v.z, + constant / v.w ); + return result; + } + + template + inline T vector4 :: + operator[] ( u32 i ) const + { + return this->data[ i ]; + } + + template + inline T& vector4 :: + operator[] ( u32 i ) + { + return this->data[ i ]; + } + + template + inline bool vector4 :: + operator== ( const vector4& other ) const + { + if ( this->x == other.x && + this->y == other.y && + this->z == other.z && + this->w == other.z ) + { + return true; + } + else + { + return false; + } + } + + template + inline bool vector4 :: + operator!= ( const vector4& other ) const + { + return !(*this == other); + } + + + // Common Functions + + template< typename T> + inline T + compute_dot( const vector2 & a, const vector2 & b ) + { + return (a[0] * b[0]) + (a[1] * b[1]); + } + + + template< typename T> + inline T + compute_dot( const vector3 & a, const vector3 & b ) + { + return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]); + } + + template< typename T> + inline T + compute_dot( const vector4 & a, const vector4 & b ) + { + return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]) + (a[3] * b[3]); + } + + template< typename T, template class vecX > + inline T + dot ( const vecX & a, const vecX & b ) + { + return compute_dot( a, b ); + } + + template< typename T, template class vecX > + inline T + norm_sq ( const vecX & a ) + { + return compute_dot( a, a ); + } + + template< typename T, template class vecX > + inline T + norm ( const vecX & a ) + { + return std::sqrt( norm_sq( a ) ); + } + + template< typename T, template class vecX > + inline T + distance ( const vecX & a, const vecX & b ) + { + return norm( a - b ); + } + + template< typename T, template class vecX > + inline vecX + normalize ( const vecX & a ) + { + return a * (T)( 1.0 / std::sqrt( compute_dot( a, a ) ) ); + } + + + template< typename T, template class vecX > + inline vecX + abs ( const vecX & a ) + { + vecX b; + for ( int i = 0 ; i < a.size() ; ++i ) + { + b[i] = std::abs( a[i] ); + } + return b; + } + + + template< typename T, template class vecX > + inline vecX + clamp ( const vecX & a, const T val_min, const T val_max ) + { + vecX b; + for ( int i = 0 ; i < a.size() ; ++i ) + { + if ( a[i] < val_min ) b[i] = val_min; + else if ( a[i] > val_max ) b[i] = val_max; + else b[i] = a[i]; + } + return b; + } + + template< typename T > + inline vector3 + cross ( const vector3 & a, const vector3 & b ) + { + return vector3( ( a.y * b.z - a.z * b.y ), + ( a.z * b.x - a.x * b.z ), + ( a.x * b.y - a.y * b.x ) ); + } + template< typename T > + inline T + parallelogramArea ( const vector3 & a, const vector3 & b ) + { + return norm( cross( a, b ) ); + } + + template< typename T > + inline T + parallelogramArea ( const vector2 & a, + const vector2 & b ) + { + return a.x * b.y - a.y * b.x; + } + + template< typename T> + inline T + scalarTripleProduct( const vector3 & a, + const vector3 & b, + const vector3 & c ) + { + return dot( a, cross( b, c ) ); + } + + template< typename T> + inline T + parallelepipedVolume( const vector3 & a, + const vector3 & b, + const vector3 & c ) + { + return norm( scalarTripleProduct( a, b ) ); + } + + template< typename T > + inline int + ccw ( const vector2 & a, const vector2 & b ) + { + T area = parallelogramArea( a, b ); + if ( area > 0 ) return 1; + else if ( area < 0 ) return 0; + else return 2; + } +} diff --git a/CameraParameterEstimation/apps/basics/ubuntu_mono.h b/CameraParameterEstimation/apps/basics/ubuntu_mono.h new file mode 100644 index 0000000..ce6a884 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/ubuntu_mono.h @@ -0,0 +1,20579 @@ +const unsigned char ubuntu_mono_ttf[] = { +0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x04, +0x00, 0x10, 0x44, 0x53, 0x49, 0x47, 0x6f, 0xd2, 0x45, 0x30, +0x00, 0x03, 0x0a, 0x84, 0x00, 0x00, 0x19, 0x30, 0x47, 0x53, +0x55, 0x42, 0x0f, 0xff, 0x5a, 0xb8, 0x00, 0x02, 0xe1, 0x48, +0x00, 0x00, 0x29, 0x3c, 0x4f, 0x53, 0x2f, 0x32, 0x88, 0xc1, +0xfd, 0xd2, 0x00, 0x00, 0x01, 0x98, 0x00, 0x00, 0x00, 0x60, +0x56, 0x44, 0x4d, 0x58, 0x6c, 0xab, 0x74, 0x42, 0x00, 0x00, +0x0c, 0x1c, 0x00, 0x00, 0x05, 0xe0, 0x63, 0x6d, 0x61, 0x70, +0xf6, 0x78, 0x50, 0x3f, 0x00, 0x00, 0x11, 0xfc, 0x00, 0x00, +0x06, 0x86, 0x63, 0x76, 0x74, 0x20, 0x0b, 0x4f, 0x12, 0x4e, +0x00, 0x00, 0x20, 0x34, 0x00, 0x00, 0x02, 0x04, 0x66, 0x70, +0x67, 0x6d, 0x76, 0xbd, 0x44, 0xc4, 0x00, 0x00, 0x18, 0x84, +0x00, 0x00, 0x06, 0x23, 0x67, 0x61, 0x73, 0x70, 0xff, 0xff, +0x00, 0x03, 0x00, 0x02, 0xe1, 0x40, 0x00, 0x00, 0x00, 0x08, +0x67, 0x6c, 0x79, 0x66, 0xac, 0x29, 0x1e, 0x1e, 0x00, 0x00, +0x36, 0x7c, 0x00, 0x02, 0x77, 0x9c, 0x68, 0x65, 0x61, 0x64, +0xf5, 0x06, 0x1e, 0xdd, 0x00, 0x00, 0x01, 0x1c, 0x00, 0x00, +0x00, 0x36, 0x68, 0x68, 0x65, 0x61, 0x05, 0x35, 0x00, 0xa7, +0x00, 0x00, 0x01, 0x54, 0x00, 0x00, 0x00, 0x24, 0x68, 0x6d, +0x74, 0x78, 0x5f, 0xa6, 0x55, 0xed, 0x00, 0x00, 0x01, 0xf8, +0x00, 0x00, 0x0a, 0x22, 0x6c, 0x6f, 0x63, 0x61, 0x06, 0xed, +0x78, 0x24, 0x00, 0x00, 0x22, 0x38, 0x00, 0x00, 0x14, 0x44, +0x6d, 0x61, 0x78, 0x70, 0x0b, 0x80, 0x09, 0xa3, 0x00, 0x00, +0x01, 0x78, 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65, +0x87, 0x39, 0xfd, 0x82, 0x00, 0x02, 0xae, 0x18, 0x00, 0x00, +0x04, 0x74, 0x70, 0x6f, 0x73, 0x74, 0x33, 0xda, 0xb4, 0xf4, +0x00, 0x02, 0xb2, 0x8c, 0x00, 0x00, 0x2e, 0xb1, 0x70, 0x72, +0x65, 0x70, 0x92, 0x3e, 0x2f, 0xa4, 0x00, 0x00, 0x1e, 0xa8, +0x00, 0x00, 0x01, 0x8a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, +0xcc, 0xcc, 0x7a, 0xbd, 0x85, 0x0d, 0x5f, 0x0f, 0x3c, 0xf5, +0x00, 0x09, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, 0xc9, 0xe5, +0xbe, 0xcb, 0x00, 0x00, 0x00, 0x00, 0xca, 0xa6, 0x4f, 0xcb, +0xfe, 0xc4, 0xff, 0x56, 0x02, 0x99, 0x03, 0x3e, 0x00, 0x00, +0x00, 0x09, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x00, 0x03, 0x3e, 0xff, 0x56, 0x00, 0x00, +0x01, 0xf4, 0xff, 0x5b, 0xff, 0x5b, 0x02, 0x99, 0x00, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, +0x05, 0x10, 0x01, 0x54, 0x00, 0x55, 0x00, 0x6e, 0x00, 0x07, +0x00, 0x02, 0x00, 0x10, 0x00, 0x2f, 0x00, 0x59, 0x00, 0x00, +0x05, 0xa7, 0x07, 0xaf, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, +0x01, 0xf4, 0x01, 0x90, 0x00, 0x05, 0x00, 0x00, 0x02, 0xbc, +0x02, 0x8a, 0x00, 0x00, 0x00, 0x8c, 0x02, 0xbc, 0x02, 0x8a, +0x00, 0x00, 0x01, 0xdd, 0x00, 0x32, 0x00, 0xfa, 0x00, 0x00, +0x02, 0x0b, 0x05, 0x09, 0x03, 0x06, 0x02, 0x03, 0x02, 0x04, +0xe0, 0x00, 0x02, 0xff, 0x50, 0x00, 0x20, 0x5b, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x41, 0x4d, 0x41, +0x00, 0x40, 0x00, 0x00, 0xff, 0xfd, 0x02, 0xb5, 0xff, 0x5b, +0x00, 0x31, 0x03, 0x3e, 0x00, 0xaa, 0x20, 0x00, 0x00, 0x9f, +0x56, 0x01, 0x00, 0x00, 0x02, 0x08, 0x02, 0xb5, 0x00, 0x00, +0x00, 0x20, 0x00, 0x03, 0x01, 0xf4, 0x00, 0x32, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x81, 0x00, 0x1b, +0x00, 0x36, 0x00, 0x12, 0x00, 0x1f, 0x00, 0xce, 0x00, 0x71, +0x00, 0x71, 0x00, 0x39, 0x00, 0x2e, 0x00, 0x95, 0x00, 0x8c, +0x00, 0xb1, 0x00, 0x45, 0x00, 0x2e, 0x00, 0x4b, 0x00, 0x39, +0x00, 0x3b, 0x00, 0x24, 0x00, 0x42, 0x00, 0x36, 0x00, 0x3f, +0x00, 0x33, 0x00, 0x33, 0x00, 0xb1, 0x00, 0x7d, 0x00, 0x31, +0x00, 0x2e, 0x00, 0x31, 0x00, 0x5c, 0x00, 0x28, 0x00, 0x09, +0x00, 0x36, 0x00, 0x2e, 0x00, 0x36, 0x00, 0x5b, 0x00, 0x5b, +0x00, 0x2e, 0x00, 0x2d, 0x00, 0x59, 0x00, 0x36, 0x00, 0x40, +0x00, 0x5b, 0x00, 0x20, 0x00, 0x37, 0x00, 0x1d, 0x00, 0x49, +0x00, 0x1d, 0x00, 0x37, 0x00, 0x37, 0x00, 0x27, 0x00, 0x30, +0x00, 0x0d, 0x00, 0x20, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x36, +0x00, 0x8f, 0x00, 0x46, 0x00, 0x76, 0x00, 0x28, 0x00, 0x08, +0x00, 0xa3, 0x00, 0x3a, 0x00, 0x47, 0x00, 0x31, 0x00, 0x28, +0x00, 0x28, 0x00, 0x3f, 0x00, 0x28, 0x00, 0x47, 0x00, 0x36, +0x00, 0x47, 0x00, 0x47, 0x00, 0x36, 0x00, 0x29, 0x00, 0x47, +0x00, 0x28, 0x00, 0x47, 0x00, 0x28, 0x00, 0x6b, 0x00, 0x42, +0x00, 0x3f, 0x00, 0x44, 0x00, 0x1e, 0x00, 0x13, 0x00, 0x1d, +0x00, 0x24, 0x00, 0x49, 0x00, 0x4f, 0x00, 0xd4, 0x00, 0x49, +0x00, 0x25, 0x00, 0x24, 0x00, 0x94, 0x00, 0x07, 0x00, 0x2a, +0x00, 0x1f, 0x00, 0x48, 0x00, 0x48, 0x00, 0x81, 0x00, 0x09, +0x00, 0x37, 0x00, 0x90, 0x00, 0x1b, 0x00, 0x95, 0x00, 0x94, +0x00, 0x2b, 0x00, 0x2a, 0x00, 0x72, 0x00, 0x45, 0x00, 0x00, +0x00, 0x70, 0x00, 0x12, 0x00, 0x42, 0x00, 0x9f, 0x00, 0x1f, +0x00, 0x0d, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x31, 0x00, 0x2d, +0x00, 0x26, 0x00, 0x0d, 0x00, 0xd4, 0x00, 0x44, 0x00, 0x71, +0x00, 0x22, 0x00, 0x76, 0x00, 0x3f, 0x00, 0x29, 0x00, 0x8c, +0x00, 0x22, 0x00, 0x7b, 0x00, 0x7d, 0x00, 0x2e, 0x00, 0x7c, +0x00, 0x7e, 0x00, 0xaa, 0x00, 0x47, 0x00, 0x1c, 0x00, 0xb1, +0x00, 0x9c, 0x00, 0x7e, 0x00, 0x59, 0x00, 0x55, 0x00, 0x12, +0x00, 0x11, 0x00, 0x15, 0x00, 0x5c, 0x00, 0x09, 0x00, 0x09, +0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x1b, +0x00, 0x2e, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x5b, +0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x59, 0x00, 0x12, +0x00, 0x37, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x1d, +0x00, 0x1d, 0x00, 0x46, 0x00, 0x1d, 0x00, 0x30, 0x00, 0x30, +0x00, 0x30, 0x00, 0x30, 0x00, 0x0d, 0x00, 0x49, 0x00, 0x47, +0x00, 0x3a, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x3a, +0x00, 0x3a, 0x00, 0x1f, 0x00, 0x31, 0x00, 0x28, 0x00, 0x28, +0x00, 0x28, 0x00, 0x28, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, +0x00, 0x36, 0x00, 0x37, 0x00, 0x47, 0x00, 0x28, 0x00, 0x28, +0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x2e, 0x00, 0x28, +0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x24, +0x00, 0x47, 0x00, 0x24, 0x00, 0x09, 0x00, 0x3a, 0x00, 0x09, +0x00, 0x3a, 0x00, 0x09, 0x00, 0x3a, 0x00, 0x2e, 0x00, 0x31, +0x00, 0x2e, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x2e, +0x00, 0x31, 0x00, 0x36, 0x00, 0x14, 0x00, 0x12, 0x00, 0x28, +0x00, 0x5b, 0x00, 0x28, 0x00, 0x5b, 0x00, 0x28, 0x00, 0x5b, +0x00, 0x28, 0x00, 0x5b, 0x00, 0x28, 0x00, 0x5b, 0x00, 0x28, +0x00, 0x2e, 0x00, 0x28, 0x00, 0x2e, 0x00, 0x28, 0x00, 0x2e, +0x00, 0x28, 0x00, 0x2e, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x2c, +0x00, 0x12, 0x00, 0x14, 0x00, 0x59, 0x00, 0x36, 0x00, 0x59, +0x00, 0x36, 0x00, 0x59, 0x00, 0x36, 0x00, 0x59, 0x00, 0x36, +0x00, 0x59, 0x00, 0x36, 0x00, 0x36, 0x00, 0x2a, 0x00, 0x59, +0x00, 0x36, 0x00, 0x47, 0x00, 0x40, 0x00, 0x47, 0x00, 0x40, +0x00, 0x47, 0x00, 0x5b, 0x00, 0x36, 0x00, 0x5b, 0x00, 0x36, +0x00, 0x5b, 0x00, 0x36, 0x00, 0x5b, 0x00, 0x36, 0x00, 0x12, +0x00, 0x36, 0x00, 0x37, 0x00, 0x47, 0x00, 0x37, 0x00, 0x47, +0x00, 0x37, 0x00, 0x47, 0x00, 0x1d, 0x00, 0x0b, 0x00, 0x37, +0x00, 0x47, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x1d, 0x00, 0x28, +0x00, 0x1d, 0x00, 0x28, 0x00, 0x37, 0x00, 0x6b, 0x00, 0x37, +0x00, 0x2a, 0x00, 0x37, 0x00, 0x6b, 0x00, 0x37, 0x00, 0x42, +0x00, 0x37, 0x00, 0x42, 0x00, 0x37, 0x00, 0x42, 0x00, 0x27, +0x00, 0x3f, 0x00, 0x27, 0x00, 0x3f, 0x00, 0x27, 0x00, 0x3f, +0x00, 0x30, 0x00, 0x44, 0x00, 0x30, 0x00, 0x44, 0x00, 0x30, +0x00, 0x44, 0x00, 0x30, 0x00, 0x44, 0x00, 0x30, 0x00, 0x44, +0x00, 0x30, 0x00, 0x44, 0x00, 0x20, 0x00, 0x13, 0x00, 0x0d, +0x00, 0x24, 0x00, 0x36, 0x00, 0x49, 0x00, 0x36, 0x00, 0x49, +0x00, 0x36, 0x00, 0x49, 0x00, 0xa1, 0x00, 0x37, 0x00, 0x42, +0x00, 0x27, 0x00, 0x3f, 0x00, 0x47, 0x00, 0xc4, 0x00, 0x81, +0x00, 0x7b, 0x00, 0x82, 0x00, 0xbe, 0x00, 0x9e, 0x00, 0xab, +0x00, 0x64, 0x00, 0x20, 0x00, 0x13, 0x00, 0x20, 0x00, 0x13, +0x00, 0x20, 0x00, 0x13, 0x00, 0x0d, 0x00, 0x24, 0x00, 0x19, +0x00, 0x74, 0x00, 0x69, 0x00, 0x7f, 0x00, 0x7d, 0x00, 0x86, +0x00, 0x77, 0x00, 0x84, 0x00, 0x74, 0x00, 0x7e, 0x00, 0x7c, +0x00, 0x7e, 0x00, 0x69, 0x00, 0x7f, 0x00, 0x7d, 0x00, 0x86, +0x00, 0x77, 0x00, 0x84, 0x00, 0x35, 0x00, 0x1b, 0x00, 0x0c, +0x00, 0x15, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0b, +0x00, 0x0b, 0x00, 0x15, 0x00, 0x13, 0x00, 0x0f, 0xff, 0xff, +0x00, 0x1c, 0xff, 0xff, 0x00, 0x15, 0x00, 0x13, 0x00, 0x0f, +0x00, 0x0d, 0x00, 0x15, 0xff, 0xff, 0x00, 0x15, 0x00, 0x0f, +0x00, 0x0d, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x26, 0x00, 0x09, +0x00, 0x3a, 0x00, 0x31, 0x00, 0x12, 0x00, 0x2e, 0x00, 0x19, +0x00, 0xb1, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x4b, 0x00, 0x25, +0x00, 0x2e, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x27, 0x00, 0x1c, +0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x74, 0x00, 0x87, +0x00, 0x7c, 0x00, 0x80, 0x00, 0x69, 0x00, 0x77, 0x00, 0x75, +0x00, 0x7e, 0x00, 0x77, 0x00, 0x7c, 0x00, 0x74, 0x00, 0x87, +0x00, 0x7c, 0x00, 0x80, 0x00, 0x69, 0x00, 0x77, 0x00, 0x75, +0x00, 0x7e, 0x00, 0x77, 0x00, 0x7c, 0x00, 0xd2, 0x00, 0xab, +0x00, 0xb9, 0x00, 0xd2, 0x00, 0x71, 0x00, 0x71, 0x00, 0x8c, +0x00, 0x45, 0x00, 0x28, 0x00, 0x8f, 0x00, 0x46, 0x00, 0x76, +0x00, 0x4f, 0x00, 0x49, 0x00, 0x90, 0x00, 0x72, 0x00, 0x45, +0x00, 0x00, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0x3f, 0x00, 0x55, +0x00, 0x5c, 0x00, 0x14, 0x00, 0x12, 0x00, 0x36, 0x00, 0x47, +0x00, 0x0b, 0x00, 0x09, 0x00, 0x2a, 0x00, 0x2e, 0x00, 0x31, +0x00, 0x12, 0x00, 0x12, 0x00, 0x31, 0x00, 0x28, 0x00, 0x27, +0x00, 0x28, 0x00, 0x19, 0x00, 0x28, 0x00, 0x03, 0x00, 0x2e, +0x00, 0x0d, 0x00, 0x24, 0x00, 0x44, 0x00, 0x59, 0x00, 0x40, +0x00, 0x47, 0x00, 0x36, 0x00, 0x1d, 0x00, 0x2d, 0xff, 0xcf, +0x00, 0x47, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x2d, +0x00, 0x1b, 0x00, 0x12, 0x00, 0x47, 0x00, 0x37, 0x00, 0x37, +0x00, 0x41, 0x00, 0x28, 0x00, 0x2b, 0x00, 0x3f, 0x00, 0x12, +0x00, 0x3f, 0x00, 0x27, 0x00, 0x30, 0x00, 0x44, 0x00, 0x12, +0x00, 0x2d, 0x00, 0x0d, 0x00, 0x13, 0x00, 0x36, 0x00, 0x49, +0x00, 0x18, 0x00, 0x43, 0x00, 0x3f, 0x00, 0x31, 0x00, 0x39, +0x00, 0x28, 0x00, 0x3a, 0x00, 0x3e, 0x00, 0x47, 0x00, 0xd4, +0x00, 0x79, 0x00, 0x23, 0x00, 0xb5, 0x00, 0x1b, 0x00, 0x1b, +0x00, 0x05, 0x00, 0x24, 0x00, 0x36, 0x00, 0x63, 0x00, 0x24, +0x00, 0x24, 0x00, 0x24, 0x00, 0x09, 0x00, 0x3a, 0x00, 0x59, +0x00, 0x36, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x30, 0x00, 0x44, +0x00, 0x30, 0x00, 0x44, 0x00, 0x30, 0x00, 0x44, 0x00, 0x30, +0x00, 0x44, 0x00, 0x30, 0x00, 0x44, 0x00, 0x2d, 0x00, 0x09, +0x00, 0x3a, 0x00, 0x09, 0x00, 0x3a, 0x00, 0x1b, 0x00, 0x1f, +0x00, 0x2e, 0x00, 0x28, 0x00, 0x2e, 0x00, 0x28, 0x00, 0x40, +0x00, 0x2b, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x1d, 0x00, 0x28, +0x00, 0x18, 0x00, 0x2c, 0x00, 0x47, 0x00, 0x1b, 0x00, 0x1b, +0x00, 0x05, 0x00, 0x2e, 0x00, 0x28, 0x00, 0x24, 0x00, 0x49, +0x00, 0x37, 0x00, 0x47, 0x00, 0x09, 0x00, 0x3a, 0x00, 0x1b, +0x00, 0x1f, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x09, 0x00, 0x3a, +0x00, 0x09, 0x00, 0x3a, 0x00, 0x5b, 0x00, 0x28, 0x00, 0x5b, +0x00, 0x28, 0x00, 0x53, 0x00, 0x2f, 0x00, 0x59, 0x00, 0x36, +0x00, 0x1d, 0x00, 0x28, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x37, +0x00, 0x53, 0x00, 0x37, 0x00, 0x6b, 0x00, 0x30, 0x00, 0x44, +0x00, 0x30, 0x00, 0x44, 0x00, 0x1e, 0x00, 0x39, 0x00, 0x2d, +0x00, 0x2c, 0x00, 0x2d, 0x00, 0x19, 0x00, 0x24, 0x00, 0x21, +0x00, 0x36, 0x00, 0x49, 0x00, 0x09, 0x00, 0x3a, 0x00, 0x5b, +0x00, 0x28, 0x00, 0x1e, 0x00, 0x28, 0x00, 0x1e, 0x00, 0x28, +0x00, 0x1d, 0x00, 0x28, 0x00, 0x1e, 0x00, 0x28, 0x00, 0x0d, +0x00, 0x24, 0x00, 0x36, 0x00, 0x25, 0x00, 0x3f, 0x00, 0x1b, +0x00, 0x1b, 0x00, 0x09, 0x00, 0x2e, 0x00, 0x28, 0x00, 0x24, +0x00, 0x12, 0x00, 0x3f, 0x00, 0x4a, 0x00, 0x44, 0x00, 0x55, +0x00, 0x12, 0x00, 0x12, 0x00, 0x09, 0x00, 0x5b, 0x00, 0x26, +0x00, 0x36, 0x00, 0x47, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x12, +0x00, 0x21, 0x00, 0x15, 0x00, 0x2a, 0x00, 0x2c, 0x00, 0x82, +0x00, 0x64, 0x00, 0xa7, 0x00, 0x70, 0x00, 0x89, 0x00, 0x6b, +0x00, 0x6b, 0x00, 0x6b, 0x00, 0x71, 0x00, 0x9c, 0x00, 0x8c, +0x00, 0x8c, 0x00, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 0x5b, +0x00, 0x5b, 0x00, 0x12, 0x00, 0x36, 0x00, 0x26, 0x00, 0x37, +0x00, 0x5a, 0x00, 0x5a, 0x00, 0x36, 0x00, 0x09, 0x00, 0x2d, +0x00, 0x12, 0x00, 0x40, 0x00, 0x37, 0x00, 0x09, 0x00, 0x31, +0x00, 0x09, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x12, +0x00, 0x5b, 0x00, 0x04, 0x00, 0x26, 0x00, 0x37, 0x00, 0x37, +0x00, 0x40, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x1d, +0x00, 0x2d, 0x00, 0x49, 0x00, 0x2e, 0x00, 0x27, 0x00, 0x09, +0x00, 0x2a, 0x00, 0x19, 0x00, 0x2d, 0x00, 0x36, 0x00, 0x2d, +0x00, 0x2d, 0x00, 0x12, 0x00, 0x24, 0x00, 0x2d, 0x00, 0x2e, +0x00, 0x2d, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x2d, 0x00, 0x47, +0x00, 0x6b, 0x00, 0x1b, 0x00, 0x28, 0x00, 0x07, 0x00, 0x48, +0x00, 0x3f, 0x00, 0x3f, 0x00, 0x47, 0x00, 0x0d, 0x00, 0x1b, +0x00, 0x47, 0x00, 0x28, 0x00, 0x47, 0x00, 0x47, 0x00, 0x31, +0x00, 0x3a, 0x00, 0x24, 0x00, 0x1a, 0x00, 0x1d, 0x00, 0x47, +0x00, 0x36, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x12, 0x00, 0x2d, +0x00, 0x47, 0x00, 0x3b, 0x00, 0x36, 0x00, 0x28, 0x00, 0x28, +0x00, 0x28, 0x00, 0x14, 0x00, 0x6b, 0x00, 0x31, 0x00, 0x42, +0x00, 0x36, 0x00, 0x36, 0x00, 0x47, 0x00, 0x0d, 0x00, 0x36, +0x00, 0x14, 0x00, 0x47, 0x00, 0x3f, 0x00, 0x24, 0x00, 0x47, +0x00, 0x27, 0x00, 0x12, 0x00, 0x12, 0x00, 0x1d, 0x00, 0x28, +0x00, 0x0d, 0x00, 0x1e, 0x00, 0x37, 0x00, 0x3f, 0x00, 0x12, +0x00, 0x12, 0x00, 0x49, 0x00, 0x47, 0x00, 0x36, 0x00, 0x6b, +0x00, 0x36, 0x00, 0x21, 0x00, 0x2d, 0x00, 0x47, 0x00, 0x04, +0x00, 0x07, 0x00, 0x26, 0x00, 0x48, 0x00, 0x40, 0x00, 0x47, +0x00, 0x30, 0x00, 0x36, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12, +0x00, 0x11, 0x00, 0x2d, 0x00, 0x47, 0x00, 0x2d, 0x00, 0x47, +0x00, 0x36, 0x00, 0x36, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x2e, +0x00, 0x31, 0x00, 0x27, 0x00, 0x3a, 0x00, 0x0d, 0x00, 0x1e, +0x00, 0x0d, 0x00, 0x1e, 0x00, 0x19, 0x00, 0x1d, 0x00, 0x12, +0x00, 0x12, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, +0x00, 0x2d, 0x00, 0x47, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12, +0x00, 0x12, 0x00, 0x59, 0x00, 0x04, 0x00, 0x07, 0x00, 0x2e, +0x00, 0x47, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x2d, 0x00, 0x47, +0x00, 0x2d, 0x00, 0x47, 0x00, 0x36, 0x00, 0x36, 0x00, 0x20, +0x00, 0x1b, 0x00, 0x59, 0x00, 0x09, 0x00, 0x3a, 0x00, 0x09, +0x00, 0x3a, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x5b, 0x00, 0x28, +0x00, 0x19, 0x00, 0x2d, 0x00, 0x19, 0x00, 0x2d, 0x00, 0x04, +0x00, 0x07, 0x00, 0x26, 0x00, 0x48, 0x00, 0x18, 0x00, 0x2c, +0x00, 0x37, 0x00, 0x3f, 0x00, 0x37, 0x00, 0x3f, 0x00, 0x1d, +0x00, 0x28, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x1d, 0x00, 0x28, +0x00, 0x2e, 0x00, 0x3b, 0x00, 0x09, 0x00, 0x24, 0x00, 0x09, +0x00, 0x24, 0x00, 0x09, 0x00, 0x24, 0x00, 0x36, 0x00, 0x36, +0x00, 0x36, 0x00, 0x6b, 0x00, 0x24, 0x00, 0x2d, 0x00, 0x24, +0x00, 0x00, 0x00, 0x1f, 0x00, 0x21, 0x00, 0x28, 0x00, 0x1b, +0x00, 0x74, 0x00, 0x09, 0x00, 0x36, 0x00, 0x36, 0x00, 0x09, +0x00, 0x5b, 0x00, 0x36, 0x00, 0x2d, 0x00, 0x1d, 0x00, 0x59, +0x00, 0x40, 0x00, 0x09, 0x00, 0x22, 0x00, 0x37, 0x00, 0x25, +0x00, 0x1d, 0x00, 0x2d, 0x00, 0x49, 0x00, 0x28, 0x00, 0x24, +0x00, 0x0d, 0x00, 0x2a, 0x00, 0x16, 0x00, 0x2b, 0x00, 0x12, +0x00, 0x31, 0x00, 0x47, 0x00, 0x1d, 0x00, 0x27, 0x00, 0x45, +0x00, 0x3f, 0x00, 0x47, 0x00, 0x31, 0x00, 0x36, 0x00, 0x47, +0x00, 0x1d, 0x00, 0x47, 0x00, 0x1e, 0x00, 0x40, 0x00, 0x28, +0x00, 0x47, 0x00, 0x47, 0x00, 0x3f, 0x00, 0x28, 0x00, 0x3f, +0x00, 0x47, 0x00, 0x1a, 0x00, 0x1d, 0x00, 0x25, 0x00, 0x24, +0x00, 0x09, 0xff, 0xbc, 0xff, 0x88, 0xff, 0xb6, 0x00, 0x59, +0xff, 0xb8, 0xff, 0x7e, 0x00, 0x0d, 0xff, 0xb6, 0x00, 0x31, +0x00, 0x45, 0x00, 0x47, 0x00, 0x36, 0x00, 0x36, 0x00, 0x26, +0x00, 0x28, 0x00, 0x47, 0x00, 0x47, 0x00, 0x47, 0x00, 0x24, +0x00, 0xa4, 0x00, 0xce, 0x00, 0x40, 0x00, 0x31, 0x00, 0x31, +0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, +0x00, 0x31, 0x00, 0x06, 0xff, 0xf5, 0xff, 0x45, 0xff, 0x58, +0xff, 0x78, 0xff, 0x62, 0xff, 0xae, 0xff, 0xa4, 0x00, 0x45, +0x00, 0x45, 0x00, 0x45, 0x00, 0x45, 0x00, 0x45, 0x00, 0x45, +0xff, 0xb1, 0xff, 0xb5, 0xff, 0x07, 0xff, 0x19, 0xff, 0x1a, +0xff, 0x07, 0x00, 0x47, 0x00, 0x47, 0x00, 0x47, 0x00, 0x47, +0x00, 0x47, 0x00, 0x47, 0x00, 0x47, 0x00, 0x47, 0xff, 0x83, +0xff, 0x88, 0xfe, 0xd9, 0xfe, 0xea, 0xfe, 0xec, 0xfe, 0xd9, +0xff, 0x1a, 0xff, 0x1a, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, +0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, +0xff, 0xb0, 0xff, 0xb4, 0xff, 0x06, 0xff, 0x18, 0xff, 0x19, +0xff, 0x06, 0xff, 0x48, 0xff, 0x48, 0x00, 0x28, 0x00, 0x28, +0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0xff, 0xa2, +0xff, 0x86, 0xfe, 0xd6, 0xfe, 0xe8, 0xff, 0x19, 0xff, 0x04, +0x00, 0x47, 0x00, 0x47, 0x00, 0x47, 0x00, 0x47, 0x00, 0x47, +0x00, 0x47, 0x00, 0x47, 0x00, 0x47, 0xff, 0x85, 0xfe, 0xf3, +0xfe, 0xc4, 0xfe, 0xff, 0x00, 0x24, 0x00, 0x24, 0x00, 0x24, +0x00, 0x24, 0x00, 0x24, 0x00, 0x24, 0x00, 0x24, 0x00, 0x24, +0xff, 0x9f, 0xff, 0x84, 0xfe, 0xd5, 0xfe, 0xe7, 0xff, 0x17, +0xff, 0x02, 0xff, 0x56, 0xff, 0x3c, 0x00, 0x31, 0x00, 0x31, +0x00, 0x45, 0x00, 0x45, 0x00, 0x47, 0x00, 0x47, 0x00, 0x36, +0x00, 0x36, 0x00, 0x28, 0x00, 0x28, 0x00, 0x47, 0x00, 0x47, +0x00, 0x24, 0x00, 0x24, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, +0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, +0xff, 0xb9, 0xff, 0xa8, 0xfe, 0xf8, 0xff, 0x0b, 0xff, 0x2b, +0xff, 0x16, 0xff, 0x60, 0xff, 0x57, 0x00, 0x47, 0x00, 0x47, +0x00, 0x47, 0x00, 0x47, 0x00, 0x47, 0x00, 0x47, 0x00, 0x47, +0x00, 0x47, 0xff, 0x83, 0xff, 0x83, 0xfe, 0xd9, 0xfe, 0xea, +0xfe, 0xec, 0xfe, 0xd9, 0xff, 0x1a, 0xff, 0x1a, 0x00, 0x24, +0x00, 0x24, 0x00, 0x24, 0x00, 0x24, 0x00, 0x24, 0x00, 0x24, +0x00, 0x24, 0x00, 0x24, 0xff, 0x96, 0xff, 0x7b, 0xfe, 0xcc, +0xfe, 0xde, 0xff, 0x0e, 0xfe, 0xf9, 0xff, 0x44, 0xff, 0x2a, +0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, +0x00, 0x31, 0x00, 0x31, 0x00, 0x09, 0x00, 0x09, 0xff, 0xbf, +0xff, 0xe2, 0x00, 0x09, 0x00, 0xb9, 0x00, 0xb3, 0x00, 0xb9, +0x00, 0x82, 0x00, 0x70, 0x00, 0x47, 0x00, 0x47, 0x00, 0x47, +0x00, 0x47, 0x00, 0x47, 0xff, 0x84, 0xff, 0x86, 0xff, 0x55, +0xff, 0x59, 0x00, 0x2d, 0x00, 0x60, 0x00, 0x6a, 0x00, 0x83, +0x00, 0x36, 0x00, 0x36, 0x00, 0x26, 0x00, 0x36, 0x00, 0x36, +0x00, 0x36, 0x00, 0x59, 0x00, 0x59, 0xff, 0x83, 0xff, 0x85, +0x00, 0x69, 0x00, 0x60, 0x00, 0x83, 0x00, 0x47, 0x00, 0x47, +0x00, 0x47, 0x00, 0x47, 0x00, 0x47, 0x00, 0x47, 0x00, 0x47, +0x00, 0x47, 0x00, 0x0d, 0x00, 0x0d, 0xff, 0x66, 0xff, 0x42, +0xff, 0xa4, 0x00, 0x49, 0x00, 0x49, 0x00, 0x98, 0x00, 0x24, +0x00, 0x24, 0x00, 0x24, 0x00, 0x24, 0x00, 0x24, 0xff, 0x70, +0xff, 0x9c, 0xff, 0x6e, 0xff, 0x9a, 0x00, 0x12, 0x00, 0x98, +0x00, 0xb9, 0x00, 0x06, 0xff, 0xf5, 0xff, 0x45, 0xff, 0x58, +0xff, 0x78, 0xff, 0x62, 0xff, 0xae, 0xff, 0xa4, 0xff, 0x83, +0xff, 0x88, 0xfe, 0xd9, 0xfe, 0xea, 0xfe, 0xec, 0xfe, 0xd9, +0xff, 0x1a, 0xff, 0x1a, 0xff, 0x9f, 0xff, 0x84, 0xfe, 0xd5, +0xfe, 0xe7, 0xff, 0x17, 0xff, 0x02, 0xff, 0x56, 0xff, 0x3c, +0x00, 0x09, 0x00, 0x2d, 0x00, 0x12, 0x00, 0x3f, 0x00, 0x3a, +0xff, 0x5b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0xd2, +0x00, 0xd2, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x00, +0x00, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x82, +0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, +0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, +0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, +0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, +0x00, 0x0c, 0x00, 0xf8, 0x08, 0xff, 0x00, 0x08, 0x00, 0x0a, +0xff, 0xfd, 0x00, 0x09, 0x00, 0x0b, 0xff, 0xfd, 0x00, 0x0a, +0x00, 0x0b, 0xff, 0xfd, 0x00, 0x0b, 0x00, 0x0c, 0xff, 0xfd, +0x00, 0x0c, 0x00, 0x0c, 0xff, 0xfd, 0x00, 0x0d, 0x00, 0x0d, +0xff, 0xfd, 0x00, 0x0e, 0x00, 0x0e, 0xff, 0xfd, 0x00, 0x0f, +0x00, 0x0e, 0xff, 0xfd, 0x00, 0x10, 0x00, 0x0f, 0xff, 0xfd, +0x00, 0x11, 0x00, 0x10, 0xff, 0xfd, 0x00, 0x12, 0x00, 0x10, +0xff, 0xfd, 0x00, 0x13, 0x00, 0x11, 0xff, 0xfd, 0x00, 0x14, +0x00, 0x12, 0xff, 0xfc, 0x00, 0x15, 0x00, 0x13, 0xff, 0xfc, +0x00, 0x16, 0x00, 0x13, 0xff, 0xfc, 0x00, 0x17, 0x00, 0x14, +0xff, 0xfc, 0x00, 0x18, 0x00, 0x15, 0xff, 0xfc, 0x00, 0x19, +0x00, 0x15, 0xff, 0xfc, 0x00, 0x1a, 0x00, 0x16, 0xff, 0xfc, +0x00, 0x1b, 0x00, 0x18, 0xff, 0xfb, 0x00, 0x1c, 0x00, 0x18, +0xff, 0xfb, 0x00, 0x1d, 0x00, 0x19, 0xff, 0xfb, 0x00, 0x1e, +0x00, 0x1a, 0xff, 0xfb, 0x00, 0x1f, 0x00, 0x1a, 0xff, 0xfb, +0x00, 0x20, 0x00, 0x1c, 0xff, 0xfb, 0x00, 0x21, 0x00, 0x1d, +0xff, 0xfa, 0x00, 0x22, 0x00, 0x1d, 0xff, 0xfa, 0x00, 0x23, +0x00, 0x1f, 0xff, 0xfa, 0x00, 0x24, 0x00, 0x20, 0xff, 0xf9, +0x00, 0x25, 0x00, 0x21, 0xff, 0xf9, 0x00, 0x26, 0x00, 0x21, +0xff, 0xf9, 0x00, 0x27, 0x00, 0x22, 0xff, 0xf9, 0x00, 0x28, +0x00, 0x23, 0xff, 0xf9, 0x00, 0x29, 0x00, 0x23, 0xff, 0xf9, +0x00, 0x2a, 0x00, 0x25, 0xff, 0xf9, 0x00, 0x2b, 0x00, 0x25, +0xff, 0xf9, 0x00, 0x2c, 0x00, 0x26, 0xff, 0xf9, 0x00, 0x2d, +0x00, 0x27, 0xff, 0xf8, 0x00, 0x2e, 0x00, 0x28, 0xff, 0xf8, +0x00, 0x2f, 0x00, 0x29, 0xff, 0xf8, 0x00, 0x30, 0x00, 0x2a, +0xff, 0xf8, 0x00, 0x31, 0x00, 0x2a, 0xff, 0xf8, 0x00, 0x32, +0x00, 0x2b, 0xff, 0xf7, 0x00, 0x33, 0x00, 0x2c, 0xff, 0xf7, +0x00, 0x34, 0x00, 0x2d, 0xff, 0xf7, 0x00, 0x35, 0x00, 0x2e, +0xff, 0xf7, 0x00, 0x36, 0x00, 0x2e, 0xff, 0xf7, 0x00, 0x37, +0x00, 0x2f, 0xff, 0xf7, 0x00, 0x38, 0x00, 0x30, 0xff, 0xf6, +0x00, 0x39, 0x00, 0x31, 0xff, 0xf6, 0x00, 0x3a, 0x00, 0x32, +0xff, 0xf6, 0x00, 0x3b, 0x00, 0x33, 0xff, 0xf6, 0x00, 0x3c, +0x00, 0x35, 0xff, 0xf6, 0x00, 0x3d, 0x00, 0x35, 0xff, 0xf6, +0x00, 0x3e, 0x00, 0x36, 0xff, 0xf5, 0x00, 0x3f, 0x00, 0x37, +0xff, 0xf5, 0x00, 0x40, 0x00, 0x37, 0xff, 0xf5, 0x00, 0x41, +0x00, 0x38, 0xff, 0xf4, 0x00, 0x42, 0x00, 0x39, 0xff, 0xf4, +0x00, 0x43, 0x00, 0x39, 0xff, 0xf4, 0x00, 0x44, 0x00, 0x3b, +0xff, 0xf4, 0x00, 0x45, 0x00, 0x3c, 0xff, 0xf4, 0x00, 0x46, +0x00, 0x3d, 0xff, 0xf4, 0x00, 0x47, 0x00, 0x3d, 0xff, 0xf4, +0x00, 0x48, 0x00, 0x3d, 0xff, 0xf4, 0x00, 0x49, 0x00, 0x3e, +0xff, 0xf4, 0x00, 0x4a, 0x00, 0x3e, 0xff, 0xf3, 0x00, 0x4b, +0x00, 0x3f, 0xff, 0xf3, 0x00, 0x4c, 0x00, 0x41, 0xff, 0xf3, +0x00, 0x4d, 0x00, 0x41, 0xff, 0xf3, 0x00, 0x4e, 0x00, 0x42, +0xff, 0xf2, 0x00, 0x4f, 0x00, 0x43, 0xff, 0xf2, 0x00, 0x50, +0x00, 0x44, 0xff, 0xf2, 0x00, 0x51, 0x00, 0x45, 0xff, 0xf2, +0x00, 0x52, 0x00, 0x46, 0xff, 0xf2, 0x00, 0x53, 0x00, 0x46, +0xff, 0xf2, 0x00, 0x54, 0x00, 0x47, 0xff, 0xf1, 0x00, 0x55, +0x00, 0x48, 0xff, 0xf1, 0x00, 0x56, 0x00, 0x49, 0xff, 0xf1, +0x00, 0x57, 0x00, 0x4a, 0xff, 0xf1, 0x00, 0x58, 0x00, 0x4a, +0xff, 0xf1, 0x00, 0x59, 0x00, 0x4b, 0xff, 0xf1, 0x00, 0x5a, +0x00, 0x4c, 0xff, 0xf1, 0x00, 0x5b, 0x00, 0x4c, 0xff, 0xf1, +0x00, 0x5c, 0x00, 0x4e, 0xff, 0xf0, 0x00, 0x5d, 0x00, 0x4e, +0xff, 0xf0, 0x00, 0x5e, 0x00, 0x4f, 0xff, 0xf0, 0x00, 0x5f, +0x00, 0x50, 0xff, 0xf0, 0x00, 0x60, 0x00, 0x51, 0xff, 0xf0, +0x00, 0x61, 0x00, 0x52, 0xff, 0xf0, 0x00, 0x62, 0x00, 0x53, +0xff, 0xef, 0x00, 0x63, 0x00, 0x53, 0xff, 0xef, 0x00, 0x64, +0x00, 0x54, 0xff, 0xef, 0x00, 0x65, 0x00, 0x55, 0xff, 0xef, +0x00, 0x66, 0x00, 0x55, 0xff, 0xee, 0x00, 0x67, 0x00, 0x57, +0xff, 0xee, 0x00, 0x68, 0x00, 0x57, 0xff, 0xee, 0x00, 0x69, +0x00, 0x59, 0xff, 0xee, 0x00, 0x6a, 0x00, 0x5a, 0xff, 0xed, +0x00, 0x6b, 0x00, 0x5a, 0xff, 0xed, 0x00, 0x6c, 0x00, 0x5b, +0xff, 0xed, 0x00, 0x6d, 0x00, 0x5c, 0xff, 0xed, 0x00, 0x6e, +0x00, 0x5c, 0xff, 0xed, 0x00, 0x6f, 0x00, 0x5d, 0xff, 0xed, +0x00, 0x70, 0x00, 0x5e, 0xff, 0xed, 0x00, 0x71, 0x00, 0x5e, +0xff, 0xed, 0x00, 0x72, 0x00, 0x60, 0xff, 0xed, 0x00, 0x73, +0x00, 0x61, 0xff, 0xec, 0x00, 0x74, 0x00, 0x63, 0xff, 0xec, +0x00, 0x75, 0x00, 0x63, 0xff, 0xec, 0x00, 0x76, 0x00, 0x64, +0xff, 0xec, 0x00, 0x77, 0x00, 0x65, 0xff, 0xec, 0x00, 0x78, +0x00, 0x65, 0xff, 0xec, 0x00, 0x79, 0x00, 0x66, 0xff, 0xeb, +0x00, 0x7a, 0x00, 0x67, 0xff, 0xeb, 0x00, 0x7b, 0x00, 0x67, +0xff, 0xea, 0x00, 0x7c, 0x00, 0x68, 0xff, 0xea, 0x00, 0x7d, +0x00, 0x68, 0xff, 0xea, 0x00, 0x7e, 0x00, 0x69, 0xff, 0xea, +0x00, 0x7f, 0x00, 0x6a, 0xff, 0xea, 0x00, 0x80, 0x00, 0x6b, +0xff, 0xea, 0x00, 0x81, 0x00, 0x6c, 0xff, 0xea, 0x00, 0x82, +0x00, 0x6c, 0xff, 0xea, 0x00, 0x83, 0x00, 0x6e, 0xff, 0xea, +0x00, 0x84, 0x00, 0x6f, 0xff, 0xea, 0x00, 0x85, 0x00, 0x70, +0xff, 0xe9, 0x00, 0x86, 0x00, 0x70, 0xff, 0xe9, 0x00, 0x87, +0x00, 0x71, 0xff, 0xe9, 0x00, 0x88, 0x00, 0x71, 0xff, 0xe9, +0x00, 0x89, 0x00, 0x72, 0xff, 0xe9, 0x00, 0x8a, 0x00, 0x74, +0xff, 0xe9, 0x00, 0x8b, 0x00, 0x74, 0xff, 0xe8, 0x00, 0x8c, +0x00, 0x76, 0xff, 0xe8, 0x00, 0x8d, 0x00, 0x76, 0xff, 0xe8, +0x00, 0x8e, 0x00, 0x77, 0xff, 0xe8, 0x00, 0x8f, 0x00, 0x78, +0xff, 0xe8, 0x00, 0x90, 0x00, 0x78, 0xff, 0xe8, 0x00, 0x91, +0x00, 0x79, 0xff, 0xe7, 0x00, 0x92, 0x00, 0x7a, 0xff, 0xe7, +0x00, 0x93, 0x00, 0x7b, 0xff, 0xe7, 0x00, 0x94, 0x00, 0x7c, +0xff, 0xe6, 0x00, 0x95, 0x00, 0x7c, 0xff, 0xe6, 0x00, 0x96, +0x00, 0x7d, 0xff, 0xe6, 0x00, 0x97, 0x00, 0x7e, 0xff, 0xe6, +0x00, 0x98, 0x00, 0x7f, 0xff, 0xe6, 0x00, 0x99, 0x00, 0x80, +0xff, 0xe6, 0x00, 0x9a, 0x00, 0x81, 0xff, 0xe6, 0x00, 0x9b, +0x00, 0x82, 0xff, 0xe6, 0x00, 0x9c, 0x00, 0x82, 0xff, 0xe5, +0x00, 0x9d, 0x00, 0x84, 0xff, 0xe5, 0x00, 0x9e, 0x00, 0x84, +0xff, 0xe5, 0x00, 0x9f, 0x00, 0x85, 0xff, 0xe5, 0x00, 0xa0, +0x00, 0x85, 0xff, 0xe5, 0x00, 0xa1, 0x00, 0x87, 0xff, 0xe5, +0x00, 0xa2, 0x00, 0x87, 0xff, 0xe4, 0x00, 0xa3, 0x00, 0x88, +0xff, 0xe4, 0x00, 0xa4, 0x00, 0x89, 0xff, 0xe4, 0x00, 0xa5, +0x00, 0x8a, 0xff, 0xe4, 0x00, 0xa6, 0x00, 0x8a, 0xff, 0xe4, +0x00, 0xa7, 0x00, 0x8b, 0xff, 0xe3, 0x00, 0xa8, 0x00, 0x8c, +0xff, 0xe3, 0x00, 0xa9, 0x00, 0x8e, 0xff, 0xe3, 0x00, 0xaa, +0x00, 0x8e, 0xff, 0xe3, 0x00, 0xab, 0x00, 0x8f, 0xff, 0xe3, +0x00, 0xac, 0x00, 0x90, 0xff, 0xe3, 0x00, 0xad, 0x00, 0x91, +0xff, 0xe2, 0x00, 0xae, 0x00, 0x92, 0xff, 0xe2, 0x00, 0xaf, +0x00, 0x92, 0xff, 0xe2, 0x00, 0xb0, 0x00, 0x93, 0xff, 0xe1, +0x00, 0xb1, 0x00, 0x94, 0xff, 0xe1, 0x00, 0xb2, 0x00, 0x94, +0xff, 0xe1, 0x00, 0xb3, 0x00, 0x96, 0xff, 0xe1, 0x00, 0xb4, +0x00, 0x96, 0xff, 0xe1, 0x00, 0xb5, 0x00, 0x97, 0xff, 0xe1, +0x00, 0xb6, 0x00, 0x98, 0xff, 0xe1, 0x00, 0xb7, 0x00, 0x99, +0xff, 0xe1, 0x00, 0xb8, 0x00, 0x99, 0xff, 0xe1, 0x00, 0xb9, +0x00, 0x9b, 0xff, 0xe0, 0x00, 0xba, 0x00, 0x9b, 0xff, 0xe0, +0x00, 0xbb, 0x00, 0x9c, 0xff, 0xe0, 0x00, 0xbc, 0x00, 0x9d, +0xff, 0xe0, 0x00, 0xbd, 0x00, 0x9d, 0xff, 0xe0, 0x00, 0xbe, +0x00, 0x9e, 0xff, 0xe0, 0x00, 0xbf, 0x00, 0x9f, 0xff, 0xdf, +0x00, 0xc0, 0x00, 0xa0, 0xff, 0xdf, 0x00, 0xc1, 0x00, 0xa0, +0xff, 0xdf, 0x00, 0xc2, 0x00, 0xa1, 0xff, 0xdf, 0x00, 0xc3, +0x00, 0xa3, 0xff, 0xde, 0x00, 0xc4, 0x00, 0xa3, 0xff, 0xde, +0x00, 0xc5, 0x00, 0xa4, 0xff, 0xde, 0x00, 0xc6, 0x00, 0xa5, +0xff, 0xde, 0x00, 0xc7, 0x00, 0xa6, 0xff, 0xde, 0x00, 0xc8, +0x00, 0xa7, 0xff, 0xde, 0x00, 0xc9, 0x00, 0xa7, 0xff, 0xde, +0x00, 0xca, 0x00, 0xa8, 0xff, 0xde, 0x00, 0xcb, 0x00, 0xaa, +0xff, 0xdd, 0x00, 0xcc, 0x00, 0xaa, 0xff, 0xdd, 0x00, 0xcd, +0x00, 0xab, 0xff, 0xdd, 0x00, 0xce, 0x00, 0xac, 0xff, 0xdd, +0x00, 0xcf, 0x00, 0xad, 0xff, 0xdd, 0x00, 0xd0, 0x00, 0xae, +0xff, 0xdd, 0x00, 0xd1, 0x00, 0xae, 0xff, 0xdc, 0x00, 0xd2, +0x00, 0xaf, 0xff, 0xdc, 0x00, 0xd3, 0x00, 0xb0, 0xff, 0xdc, +0x00, 0xd4, 0x00, 0xb1, 0xff, 0xdc, 0x00, 0xd5, 0x00, 0xb1, +0xff, 0xdb, 0x00, 0xd6, 0x00, 0xb2, 0xff, 0xdb, 0x00, 0xd7, +0x00, 0xb3, 0xff, 0xdb, 0x00, 0xd8, 0x00, 0xb4, 0xff, 0xdb, +0x00, 0xd9, 0x00, 0xb5, 0xff, 0xdb, 0x00, 0xda, 0x00, 0xb5, +0xff, 0xdb, 0x00, 0xdb, 0x00, 0xb6, 0xff, 0xda, 0x00, 0xdc, +0x00, 0xb8, 0xff, 0xda, 0x00, 0xdd, 0x00, 0xb8, 0xff, 0xda, +0x00, 0xde, 0x00, 0xb9, 0xff, 0xda, 0x00, 0xdf, 0x00, 0xba, +0xff, 0xda, 0x00, 0xe0, 0x00, 0xba, 0xff, 0xda, 0x00, 0xe1, +0x00, 0xbc, 0xff, 0xda, 0x00, 0xe2, 0x00, 0xbd, 0xff, 0xda, +0x00, 0xe3, 0x00, 0xbd, 0xff, 0xd9, 0x00, 0xe4, 0x00, 0xbf, +0xff, 0xd9, 0x00, 0xe5, 0x00, 0xbf, 0xff, 0xd9, 0x00, 0xe6, +0x00, 0xc0, 0xff, 0xd9, 0x00, 0xe7, 0x00, 0xc1, 0xff, 0xd9, +0x00, 0xe8, 0x00, 0xc1, 0xff, 0xd9, 0x00, 0xe9, 0x00, 0xc2, +0xff, 0xd8, 0x00, 0xea, 0x00, 0xc4, 0xff, 0xd7, 0x00, 0xeb, +0x00, 0xc4, 0xff, 0xd7, 0x00, 0xec, 0x00, 0xc5, 0xff, 0xd7, +0x00, 0xed, 0x00, 0xc5, 0xff, 0xd7, 0x00, 0xee, 0x00, 0xc6, +0xff, 0xd7, 0x00, 0xef, 0x00, 0xc7, 0xff, 0xd7, 0x00, 0xf0, +0x00, 0xc8, 0xff, 0xd7, 0x00, 0xf1, 0x00, 0xc9, 0xff, 0xd7, +0x00, 0xf2, 0x00, 0xca, 0xff, 0xd7, 0x00, 0xf3, 0x00, 0xcb, +0xff, 0xd7, 0x00, 0xf4, 0x00, 0xcc, 0xff, 0xd7, 0x00, 0xf5, +0x00, 0xcc, 0xff, 0xd6, 0x00, 0xf6, 0x00, 0xcd, 0xff, 0xd6, +0x00, 0xf7, 0x00, 0xcd, 0xff, 0xd6, 0x00, 0xf8, 0x00, 0xce, +0xff, 0xd6, 0x00, 0xf9, 0x00, 0xcf, 0xff, 0xd6, 0x00, 0xfa, +0x00, 0xd1, 0xff, 0xd5, 0x00, 0xfb, 0x00, 0xd2, 0xff, 0xd5, +0x00, 0xfc, 0x00, 0xd2, 0xff, 0xd5, 0x00, 0xfd, 0x00, 0xd3, +0xff, 0xd5, 0x00, 0xfe, 0x00, 0xd4, 0xff, 0xd5, 0x00, 0xff, +0x00, 0xd4, 0xff, 0xd5, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, +0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x04, 0x7c, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, +0x00, 0x1c, 0x00, 0x04, 0x04, 0x60, 0x00, 0x00, 0x00, 0xe2, +0x00, 0x80, 0x00, 0x06, 0x00, 0x62, 0x00, 0x00, 0x00, 0x09, +0x00, 0x0d, 0x00, 0x1d, 0x00, 0x7e, 0x01, 0x31, 0x01, 0x37, +0x01, 0x48, 0x01, 0x51, 0x01, 0x53, 0x01, 0x5f, 0x01, 0x61, +0x01, 0x77, 0x01, 0x7f, 0x01, 0x91, 0x01, 0x92, 0x02, 0x17, +0x02, 0x1b, 0x02, 0x36, 0x02, 0x37, 0x02, 0x4f, 0x02, 0x92, +0x02, 0xbc, 0x02, 0xc7, 0x02, 0xc9, 0x02, 0xdd, 0x03, 0x11, +0x03, 0x86, 0x03, 0x8a, 0x03, 0x8c, 0x03, 0x90, 0x03, 0xa1, +0x03, 0xa9, 0x03, 0xb0, 0x03, 0xc9, 0x03, 0xce, 0x04, 0x5f, +0x04, 0x63, 0x04, 0x75, 0x04, 0xf9, 0x1e, 0x85, 0x1e, 0xf3, +0x1f, 0x15, 0x1f, 0x1d, 0x1f, 0x45, 0x1f, 0x4d, 0x1f, 0x57, +0x1f, 0x59, 0x1f, 0x5b, 0x1f, 0x5d, 0x1f, 0x7d, 0x1f, 0xb4, +0x1f, 0xc4, 0x1f, 0xd3, 0x1f, 0xdb, 0x1f, 0xef, 0x1f, 0xf4, +0x1f, 0xfe, 0x20, 0x15, 0x20, 0x1a, 0x20, 0x1e, 0x20, 0x22, +0x20, 0x26, 0x20, 0x30, 0x20, 0x3a, 0x20, 0x44, 0x20, 0x70, +0x20, 0x79, 0x20, 0x89, 0x20, 0xac, 0x20, 0xae, 0x20, 0xb4, +0x20, 0xb9, 0x21, 0x13, 0x21, 0x16, 0x21, 0x22, 0x21, 0x26, +0x21, 0x2e, 0x21, 0x5e, 0x22, 0x02, 0x22, 0x06, 0x22, 0x0f, +0x22, 0x12, 0x22, 0x15, 0x22, 0x1a, 0x22, 0x1e, 0x22, 0x2b, +0x22, 0x48, 0x22, 0x60, 0x22, 0x65, 0x25, 0x00, 0x25, 0x02, +0x25, 0x0c, 0x25, 0x10, 0x25, 0x14, 0x25, 0x18, 0x25, 0x1c, +0x25, 0x24, 0x25, 0x2c, 0x25, 0x34, 0x25, 0x3c, 0x25, 0x6c, +0x25, 0x88, 0x25, 0x93, 0x25, 0xca, 0xe0, 0xff, 0xef, 0xfd, +0xf0, 0x02, 0xf5, 0x11, 0xf8, 0x1d, 0xfb, 0x02, 0xff, 0xfd, +0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0d, +0x00, 0x1d, 0x00, 0x20, 0x00, 0xa0, 0x01, 0x32, 0x01, 0x38, +0x01, 0x49, 0x01, 0x52, 0x01, 0x54, 0x01, 0x60, 0x01, 0x62, +0x01, 0x78, 0x01, 0x80, 0x01, 0x92, 0x01, 0x93, 0x02, 0x18, +0x02, 0x1c, 0x02, 0x37, 0x02, 0x38, 0x02, 0x92, 0x02, 0xbc, +0x02, 0xc6, 0x02, 0xc9, 0x02, 0xd8, 0x03, 0x11, 0x03, 0x84, +0x03, 0x88, 0x03, 0x8c, 0x03, 0x8e, 0x03, 0x91, 0x03, 0xa3, +0x03, 0xaa, 0x03, 0xb1, 0x03, 0xca, 0x04, 0x00, 0x04, 0x62, +0x04, 0x72, 0x04, 0x8a, 0x1e, 0x80, 0x1e, 0xf2, 0x1f, 0x00, +0x1f, 0x18, 0x1f, 0x20, 0x1f, 0x48, 0x1f, 0x50, 0x1f, 0x59, +0x1f, 0x5b, 0x1f, 0x5d, 0x1f, 0x5f, 0x1f, 0x80, 0x1f, 0xb6, +0x1f, 0xc6, 0x1f, 0xd6, 0x1f, 0xdd, 0x1f, 0xf2, 0x1f, 0xf6, +0x20, 0x13, 0x20, 0x18, 0x20, 0x1c, 0x20, 0x20, 0x20, 0x26, +0x20, 0x30, 0x20, 0x39, 0x20, 0x44, 0x20, 0x70, 0x20, 0x74, +0x20, 0x80, 0x20, 0xac, 0x20, 0xae, 0x20, 0xb4, 0x20, 0xb9, +0x21, 0x13, 0x21, 0x16, 0x21, 0x22, 0x21, 0x26, 0x21, 0x2e, +0x21, 0x53, 0x22, 0x02, 0x22, 0x06, 0x22, 0x0f, 0x22, 0x11, +0x22, 0x15, 0x22, 0x19, 0x22, 0x1e, 0x22, 0x2b, 0x22, 0x48, +0x22, 0x60, 0x22, 0x64, 0x25, 0x00, 0x25, 0x02, 0x25, 0x0c, +0x25, 0x10, 0x25, 0x14, 0x25, 0x18, 0x25, 0x1c, 0x25, 0x24, +0x25, 0x2c, 0x25, 0x34, 0x25, 0x3c, 0x25, 0x50, 0x25, 0x88, +0x25, 0x91, 0x25, 0xca, 0xe0, 0xff, 0xef, 0xfd, 0xf0, 0x00, +0xf5, 0x06, 0xf8, 0x0a, 0xfb, 0x01, 0xff, 0xfd, 0xff, 0xff, +0x00, 0x01, 0xff, 0xf9, 0xff, 0xf5, 0xff, 0xe4, 0xff, 0xe3, +0xff, 0xdb, 0xff, 0xdc, 0xff, 0xdd, 0xff, 0xde, 0x00, 0x00, +0xff, 0xdc, 0x00, 0x00, 0xff, 0xda, 0x00, 0x00, 0x00, 0x59, +0xfe, 0xd2, 0x00, 0x58, 0xff, 0x41, 0x00, 0x54, 0xff, 0x26, +0x00, 0x53, 0x00, 0x11, 0xfe, 0xa2, 0x00, 0x00, 0xfe, 0x97, +0x00, 0x00, 0xff, 0x93, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x3b, +0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xf8, +0x00, 0x00, 0xfe, 0xb3, 0xfe, 0xb2, 0xfe, 0xa4, 0xfe, 0x90, +0xe2, 0xe6, 0xe2, 0x7a, 0xe4, 0xd9, 0xe4, 0xd7, 0xe4, 0xd5, +0xe4, 0xd3, 0xe4, 0xd1, 0xe4, 0xd0, 0xe4, 0xcf, 0xe4, 0xce, +0xe4, 0xcd, 0xe4, 0xcb, 0xe4, 0xca, 0xe4, 0xc9, 0xe4, 0xc7, +0xe4, 0xc6, 0xe4, 0xc4, 0xe4, 0xc3, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xe0, 0x40, 0xe0, 0x3a, 0x00, 0x00, +0xe1, 0x2a, 0xe0, 0xff, 0xe0, 0xfc, 0xe0, 0xf6, 0xdf, 0xb6, +0xe2, 0xdf, 0xe2, 0xd8, 0xe4, 0x24, 0xe0, 0x6d, 0xe2, 0x74, +0xdf, 0x54, 0xe0, 0x78, 0xe0, 0x53, 0x00, 0x00, 0xdf, 0x98, +0xdf, 0x95, 0xdf, 0x8d, 0x00, 0x00, 0xdf, 0x8b, 0xdf, 0x88, +0xdf, 0x85, 0xdf, 0x79, 0xdf, 0x5d, 0xdf, 0x46, 0xdf, 0x43, +0xdf, 0xe6, 0xdf, 0xe3, 0xdf, 0xd8, 0xdf, 0xde, 0xdf, 0xcf, +0xdf, 0xca, 0xdf, 0xce, 0xdf, 0xc3, 0xdf, 0xbc, 0xdf, 0xb5, +0xdf, 0xaf, 0x00, 0x00, 0xdf, 0x82, 0xdf, 0x7a, 0xdb, 0xdf, +0x23, 0xdf, 0x14, 0xe4, 0x00, 0x00, 0x0c, 0x88, 0x09, 0xa4, +0x00, 0x00, 0x04, 0xe3, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0xd0, +0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, +0x00, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, +0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xba, 0x00, 0xbe, 0x00, 0xc2, 0x00, 0xc6, +0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, +0x00, 0x00, 0x00, 0x6d, 0x00, 0x79, 0x00, 0x6b, 0x00, 0x77, +0x00, 0x7a, 0x01, 0x52, 0x01, 0x53, 0x01, 0x54, 0x01, 0x55, +0x01, 0x56, 0x01, 0x57, 0x01, 0x58, 0x00, 0x69, 0x01, 0x5f, +0x01, 0x61, 0x01, 0x62, 0x01, 0x63, 0x01, 0x64, 0x00, 0x75, +0x01, 0x65, 0x03, 0xd6, 0x03, 0xd8, 0x03, 0xc2, 0x03, 0xc8, +0x03, 0xca, 0x03, 0xd0, 0x03, 0xc6, 0x03, 0xc9, 0x03, 0xcb, +0x03, 0xcc, 0x03, 0xcd, 0x03, 0xce, 0x03, 0xd4, 0x03, 0xcf, +0x03, 0xd2, 0x03, 0xd1, 0x03, 0xd3, 0x03, 0xd5, 0x00, 0x73, +0x00, 0x74, 0x03, 0x8b, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x63, +0x00, 0x70, 0x00, 0x71, 0x00, 0x65, 0x00, 0x67, 0x00, 0x68, +0x00, 0x72, 0x00, 0x6c, 0x00, 0x78, 0x01, 0x82, 0x01, 0x83, +0x01, 0x88, 0x01, 0x89, 0x01, 0x8a, 0x01, 0x8b, 0x01, 0x8c, +0x01, 0x8d, 0x01, 0x84, 0x01, 0x85, 0x01, 0x86, 0x01, 0x87, +0x01, 0x9d, 0x01, 0x9f, 0x05, 0x01, 0x04, 0xf7, 0x04, 0xf6, +0x05, 0x09, 0x05, 0x00, 0x04, 0xf5, 0x05, 0x08, 0x04, 0xff, +0x04, 0xf3, 0x05, 0x06, 0x04, 0xfd, 0x04, 0xf2, 0x05, 0x05, +0x04, 0xfc, 0x04, 0xf0, 0x05, 0x03, 0x04, 0xfa, 0x04, 0xef, +0x05, 0x02, 0x04, 0xf9, 0x04, 0xf4, 0x05, 0x07, 0x04, 0xfe, +0x04, 0xf1, 0x05, 0x04, 0x04, 0xfb, 0x05, 0x0f, 0x05, 0x0e, +0x04, 0xf8, 0x04, 0xdf, 0x01, 0xaa, 0x01, 0xac, 0x01, 0xab, +0x01, 0xad, 0x00, 0x06, 0x02, 0x0a, 0x00, 0x00, 0x00, 0x00, +0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, +0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, +0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, +0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, +0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, +0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, +0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, +0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, +0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, +0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, +0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, +0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, +0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, +0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, +0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, +0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, +0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, +0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, +0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, +0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0x00, 0x00, 0x9f, +0x00, 0xa0, 0x00, 0xa2, 0x00, 0xa4, 0x00, 0xac, 0x00, 0xb1, +0x00, 0xb7, 0x00, 0xbc, 0x00, 0xbb, 0x00, 0xbd, 0x00, 0xbf, +0x00, 0xbe, 0x00, 0xc0, 0x00, 0xc2, 0x00, 0xc4, 0x00, 0xc3, +0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc8, 0x00, 0xc7, 0x00, 0xc9, +0x00, 0xca, 0x00, 0xcc, 0x00, 0xce, 0x00, 0xcd, 0x00, 0xcf, +0x00, 0xd1, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xd4, 0x00, 0xd6, +0x00, 0xd7, 0x00, 0x67, 0x00, 0x8b, 0x00, 0x7d, 0x00, 0x7e, +0x00, 0x82, 0x00, 0x72, 0x00, 0x91, 0x00, 0xba, 0x00, 0x89, +0x00, 0x84, 0x00, 0x76, 0x00, 0x8f, 0x00, 0x83, 0x01, 0xa6, +0x00, 0xa1, 0x00, 0xb3, 0x01, 0xa3, 0x00, 0x8c, 0x01, 0xa7, +0x01, 0xa8, 0x00, 0x80, 0x00, 0x90, 0x01, 0x9a, 0x01, 0x9d, +0x01, 0x9c, 0x03, 0xb8, 0x01, 0xa4, 0x00, 0x85, 0x00, 0x95, +0x01, 0x9e, 0x00, 0xc1, 0x00, 0xd3, 0x00, 0x9a, 0x00, 0x7c, +0x00, 0x87, 0x01, 0xa2, 0x00, 0x64, 0x01, 0xa5, 0x01, 0x9b, +0x00, 0x86, 0x00, 0x96, 0x00, 0x66, 0x00, 0x7b, 0x00, 0x9b, +0x00, 0x9e, 0x00, 0xb0, 0x00, 0x6d, 0x00, 0x79, 0x00, 0x73, +0x00, 0x74, 0x00, 0x70, 0x00, 0x71, 0x00, 0x6e, 0x00, 0x6f, +0x00, 0xd2, 0x01, 0xa9, 0x00, 0xda, 0x00, 0x7a, 0x01, 0x6e, +0x00, 0x62, 0x00, 0x6c, 0x00, 0x78, 0x01, 0xab, 0x01, 0xad, +0x00, 0x68, 0x00, 0x92, 0x00, 0x63, 0x00, 0x65, 0x00, 0x6a, +0x00, 0x9d, 0x00, 0xa5, 0x00, 0x9c, 0x00, 0xa6, 0x00, 0xa3, +0x00, 0xa8, 0x00, 0xa9, 0x00, 0xaa, 0x00, 0xa7, 0x00, 0xae, +0x00, 0xaf, 0x00, 0x00, 0x00, 0xad, 0x00, 0xb5, 0x00, 0xb6, +0x00, 0xb4, 0x01, 0x0c, 0x00, 0x69, 0x00, 0x75, 0x00, 0x8a, +0x01, 0x61, 0x01, 0x62, 0x01, 0x63, 0x00, 0x93, 0x01, 0x65, +0x01, 0x64, 0x01, 0x5f, 0x00, 0x00, 0x40, 0x3f, 0x58, 0x55, +0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x4e, 0x4d, 0x4c, 0x4b, +0x4a, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, +0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, +0x36, 0x35, 0x2f, 0x2e, 0x2d, 0x2c, 0x28, 0x26, 0x25, 0x24, +0x23, 0x22, 0x1f, 0x18, 0x14, 0x11, 0x10, 0x0f, 0x0d, 0x0b, +0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, +0x00, 0x2c, 0x45, 0x23, 0x46, 0x60, 0x20, 0xb0, 0x26, 0x60, +0xb0, 0x04, 0x26, 0x23, 0x48, 0x48, 0x2d, 0x2c, 0x45, 0x23, +0x46, 0x23, 0x61, 0x20, 0xb0, 0x26, 0x61, 0xb0, 0x04, 0x26, +0x23, 0x48, 0x48, 0x2d, 0x2c, 0x45, 0x23, 0x46, 0x60, 0xb0, +0x20, 0x61, 0x20, 0xb0, 0x46, 0x60, 0xb0, 0x04, 0x26, 0x23, +0x48, 0x48, 0x2d, 0x2c, 0x45, 0x23, 0x46, 0x23, 0x61, 0xb0, +0x20, 0x60, 0x20, 0xb0, 0x26, 0x61, 0xb0, 0x20, 0x61, 0xb0, +0x04, 0x26, 0x23, 0x48, 0x48, 0x2d, 0x2c, 0x45, 0x23, 0x46, +0x60, 0xb0, 0x40, 0x61, 0x20, 0xb0, 0x66, 0x60, 0xb0, 0x04, +0x26, 0x23, 0x48, 0x48, 0x2d, 0x2c, 0x45, 0x23, 0x46, 0x23, +0x61, 0xb0, 0x40, 0x60, 0x20, 0xb0, 0x26, 0x61, 0xb0, 0x40, +0x61, 0xb0, 0x04, 0x26, 0x23, 0x48, 0x48, 0x2d, 0x2c, 0x01, +0x10, 0x20, 0x3c, 0x00, 0x3c, 0x2d, 0x2c, 0x20, 0x45, 0x23, +0x20, 0xb0, 0xcd, 0x44, 0x23, 0x20, 0xb8, 0x01, 0x5a, 0x51, +0x58, 0x23, 0x20, 0xb0, 0x8d, 0x44, 0x23, 0x59, 0x20, 0xb0, +0xed, 0x51, 0x58, 0x23, 0x20, 0xb0, 0x4d, 0x44, 0x23, 0x59, +0x20, 0xb0, 0x04, 0x26, 0x51, 0x58, 0x23, 0x20, 0xb0, 0x0d, +0x44, 0x23, 0x59, 0x21, 0x21, 0x2d, 0x2c, 0x20, 0x20, 0x45, +0x18, 0x68, 0x44, 0x20, 0xb0, 0x01, 0x60, 0x20, 0x45, 0xb0, +0x46, 0x76, 0x68, 0x8a, 0x45, 0x60, 0x44, 0x2d, 0x2c, 0x01, +0xb1, 0x0b, 0x0a, 0x43, 0x23, 0x43, 0x65, 0x0a, 0x2d, 0x2c, +0x00, 0xb1, 0x0a, 0x0b, 0x43, 0x23, 0x43, 0x0b, 0x2d, 0x2c, +0x00, 0xb0, 0x28, 0x23, 0x70, 0xb1, 0x01, 0x28, 0x3e, 0x01, +0xb0, 0x28, 0x23, 0x70, 0xb1, 0x02, 0x28, 0x45, 0x3a, 0xb1, +0x02, 0x00, 0x08, 0x0d, 0x2d, 0x2c, 0x20, 0x45, 0xb0, 0x03, +0x25, 0x45, 0x61, 0x64, 0xb0, 0x50, 0x51, 0x58, 0x45, 0x44, +0x1b, 0x21, 0x21, 0x59, 0x2d, 0x2c, 0x20, 0x45, 0xb0, 0x00, +0x43, 0x60, 0x44, 0x2d, 0x2c, 0x01, 0xb0, 0x06, 0x43, 0xb0, +0x07, 0x43, 0x65, 0x0a, 0x2d, 0x2c, 0x20, 0x69, 0xb0, 0x40, +0x61, 0xb0, 0x00, 0x8b, 0x20, 0xb1, 0x2c, 0xc0, 0x8a, 0x8c, +0xb8, 0x10, 0x00, 0x62, 0x60, 0x2b, 0x0c, 0x64, 0x23, 0x64, +0x61, 0x5c, 0x58, 0xb0, 0x03, 0x61, 0x59, 0x2d, 0x2c, 0x8a, +0x03, 0x45, 0x8a, 0x8a, 0x87, 0xb0, 0x11, 0x2b, 0xb0, 0x29, +0x23, 0x44, 0xb0, 0x29, 0x7a, 0xe4, 0x18, 0x2d, 0x2c, 0x45, +0x65, 0xb0, 0x2c, 0x23, 0x44, 0x45, 0xb0, 0x2b, 0x23, 0x44, +0x2d, 0x2c, 0x4b, 0x52, 0x58, 0x45, 0x44, 0x1b, 0x21, 0x21, +0x59, 0x2d, 0x2c, 0x01, 0xb0, 0x05, 0x25, 0x10, 0x23, 0x20, +0x8a, 0xf5, 0x00, 0xb0, 0x01, 0x60, 0x23, 0xed, 0xec, 0x2d, +0x2c, 0x01, 0xb0, 0x05, 0x25, 0x10, 0x23, 0x20, 0x8a, 0xf5, +0x00, 0xb0, 0x01, 0x61, 0x23, 0xed, 0xec, 0x2d, 0x2c, 0x01, +0xb0, 0x06, 0x25, 0x10, 0xf5, 0x00, 0xed, 0xec, 0x2d, 0x2c, +0x20, 0xb0, 0x01, 0x60, 0x01, 0x10, 0x20, 0x3c, 0x00, 0x3c, +0x2d, 0x2c, 0x20, 0xb0, 0x01, 0x61, 0x01, 0x10, 0x20, 0x3c, +0x00, 0x3c, 0x2d, 0x2c, 0x00, 0xb0, 0x07, 0x43, 0xb0, 0x06, +0x43, 0x0b, 0x2d, 0x2c, 0x21, 0x21, 0x0c, 0x64, 0x23, 0x64, +0x8b, 0xb8, 0x40, 0x00, 0x62, 0x2d, 0x2c, 0x21, 0xb0, 0x80, +0x51, 0x58, 0x0c, 0x64, 0x23, 0x64, 0x8b, 0xb8, 0x20, 0x00, +0x62, 0x1b, 0xb2, 0x00, 0x40, 0x2f, 0x2b, 0x59, 0xb0, 0x02, +0x60, 0x2d, 0x2c, 0x21, 0xb0, 0xc0, 0x51, 0x58, 0x0c, 0x64, +0x23, 0x64, 0x8b, 0xb8, 0x15, 0x55, 0x62, 0x1b, 0xb2, 0x00, +0x80, 0x2f, 0x2b, 0x59, 0xb0, 0x02, 0x60, 0x2d, 0x2c, 0x0c, +0x64, 0x23, 0x64, 0x8b, 0xb8, 0x40, 0x00, 0x62, 0x60, 0x23, +0x21, 0x2d, 0x2c, 0x45, 0x23, 0x45, 0x60, 0x23, 0x45, 0x60, +0x23, 0x45, 0x60, 0x23, 0x76, 0x68, 0x18, 0xb0, 0x80, 0x62, +0x20, 0x2d, 0x2c, 0xb0, 0x04, 0x26, 0xb0, 0x04, 0x26, 0xb0, +0x04, 0x25, 0xb0, 0x04, 0x25, 0x45, 0x23, 0x45, 0x20, 0xb0, +0x03, 0x26, 0x60, 0x62, 0x63, 0x68, 0x20, 0xb0, 0x03, 0x26, +0x61, 0x65, 0x8a, 0x23, 0x44, 0x44, 0x2d, 0x2c, 0x20, 0x45, +0xb0, 0x00, 0x54, 0x58, 0xb0, 0x40, 0x44, 0x20, 0x45, 0xb0, +0x40, 0x61, 0x44, 0x1b, 0x21, 0x21, 0x59, 0x2d, 0x2c, 0x45, +0xb1, 0x30, 0x2f, 0x45, 0x23, 0x45, 0x61, 0x60, 0xb0, 0x01, +0x60, 0x69, 0x44, 0x2d, 0x2c, 0x4b, 0x51, 0x58, 0xb0, 0x2f, +0x23, 0x70, 0xb0, 0x14, 0x23, 0x42, 0x1b, 0x21, 0x21, 0x59, +0x2d, 0x2c, 0x4b, 0x51, 0x58, 0x20, 0xb0, 0x03, 0x25, 0x45, +0x69, 0x53, 0x58, 0x44, 0x1b, 0x21, 0x21, 0x59, 0x1b, 0x21, +0x21, 0x59, 0x2d, 0x2c, 0x45, 0xb0, 0x14, 0x43, 0xb0, 0x00, +0x60, 0x63, 0xb0, 0x01, 0x60, 0x69, 0x44, 0x2d, 0x2c, 0xb0, +0x2f, 0x45, 0x44, 0x2d, 0x2c, 0x45, 0x23, 0x20, 0x45, 0x8a, +0x60, 0x44, 0x2d, 0x2c, 0x45, 0x23, 0x45, 0x60, 0x44, 0x2d, +0x2c, 0x4b, 0x23, 0x51, 0x58, 0xb9, 0x00, 0x33, 0xff, 0xe0, +0xb1, 0x34, 0x20, 0x1b, 0xb3, 0x33, 0x00, 0x34, 0x00, 0x59, +0x44, 0x44, 0x2d, 0x2c, 0xb0, 0x16, 0x43, 0x58, 0xb0, 0x03, +0x26, 0x45, 0x8a, 0x58, 0x64, 0x66, 0xb0, 0x1f, 0x60, 0x1b, +0x64, 0xb0, 0x20, 0x60, 0x66, 0x20, 0x58, 0x1b, 0x21, 0xb0, +0x40, 0x59, 0xb0, 0x01, 0x61, 0x59, 0x23, 0x58, 0x65, 0x59, +0xb0, 0x29, 0x23, 0x44, 0x23, 0x10, 0xb0, 0x29, 0xe0, 0x1b, +0x21, 0x21, 0x21, 0x21, 0x21, 0x59, 0x2d, 0x2c, 0xb0, 0x16, +0x43, 0x58, 0xb0, 0x04, 0x25, 0x45, 0x64, 0xb0, 0x20, 0x60, +0x66, 0x20, 0x58, 0x1b, 0x21, 0xb0, 0x40, 0x59, 0xb0, 0x01, +0x61, 0x23, 0x58, 0x65, 0x59, 0xb0, 0x29, 0x23, 0x44, 0xb0, +0x04, 0x25, 0xb0, 0x07, 0x25, 0x08, 0x20, 0x58, 0x02, 0x1b, +0x03, 0x59, 0xb0, 0x05, 0x25, 0x10, 0xb0, 0x04, 0x25, 0x20, +0x46, 0xb0, 0x04, 0x25, 0x23, 0x42, 0x3c, 0xb0, 0x07, 0x25, +0x10, 0xb0, 0x06, 0x25, 0x20, 0x46, 0xb0, 0x04, 0x25, 0xb0, +0x01, 0x60, 0x23, 0x42, 0x3c, 0x20, 0x58, 0x01, 0x1b, 0x00, +0x59, 0xb0, 0x05, 0x25, 0x10, 0xb0, 0x04, 0x25, 0xb0, 0x29, +0xe0, 0xb0, 0x07, 0x25, 0x10, 0xb0, 0x06, 0x25, 0xb0, 0x29, +0xe0, 0xb0, 0x04, 0x25, 0xb0, 0x07, 0x25, 0x08, 0x20, 0x58, +0x02, 0x1b, 0x03, 0x59, 0xb0, 0x04, 0x25, 0xb0, 0x03, 0x25, +0x43, 0x48, 0xb0, 0x06, 0x25, 0xb0, 0x03, 0x25, 0xb0, 0x01, +0x60, 0x43, 0x48, 0x1b, 0x21, 0x59, 0x21, 0x21, 0x21, 0x21, +0x21, 0x21, 0x21, 0x2d, 0x2c, 0xb0, 0x16, 0x43, 0x58, 0xb0, +0x04, 0x25, 0x45, 0x64, 0xb0, 0x20, 0x60, 0x66, 0x20, 0x58, +0x1b, 0x21, 0xb0, 0x40, 0x59, 0xb0, 0x01, 0x61, 0x23, 0x58, +0x1b, 0x65, 0x59, 0xb0, 0x29, 0x23, 0x44, 0xb0, 0x05, 0x25, +0xb0, 0x08, 0x25, 0x08, 0x20, 0x58, 0x02, 0x1b, 0x03, 0x59, +0xb0, 0x04, 0x25, 0x10, 0xb0, 0x05, 0x25, 0x20, 0x46, 0xb0, +0x04, 0x25, 0x23, 0x42, 0x3c, 0xb0, 0x04, 0x25, 0xb0, 0x07, +0x25, 0x08, 0xb0, 0x07, 0x25, 0x10, 0xb0, 0x06, 0x25, 0x20, +0x46, 0xb0, 0x04, 0x25, 0xb0, 0x01, 0x60, 0x23, 0x42, 0x3c, +0x20, 0x58, 0x01, 0x1b, 0x00, 0x59, 0xb0, 0x04, 0x25, 0x10, +0xb0, 0x05, 0x25, 0xb0, 0x29, 0xe0, 0xb0, 0x29, 0x20, 0x45, +0x65, 0x44, 0xb0, 0x07, 0x25, 0x10, 0xb0, 0x06, 0x25, 0xb0, +0x29, 0xe0, 0xb0, 0x05, 0x25, 0xb0, 0x08, 0x25, 0x08, 0x20, +0x58, 0x02, 0x1b, 0x03, 0x59, 0xb0, 0x05, 0x25, 0xb0, 0x03, +0x25, 0x43, 0x48, 0xb0, 0x04, 0x25, 0xb0, 0x07, 0x25, 0x08, +0xb0, 0x06, 0x25, 0xb0, 0x03, 0x25, 0xb0, 0x01, 0x60, 0x43, +0x48, 0x1b, 0x21, 0x59, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, +0x21, 0x2d, 0x2c, 0x02, 0xb0, 0x04, 0x25, 0x20, 0x20, 0x46, +0xb0, 0x04, 0x25, 0x23, 0x42, 0xb0, 0x05, 0x25, 0x08, 0xb0, +0x03, 0x25, 0x45, 0x48, 0x21, 0x21, 0x21, 0x21, 0x2d, 0x2c, +0x02, 0xb0, 0x03, 0x25, 0x20, 0xb0, 0x04, 0x25, 0x08, 0xb0, +0x02, 0x25, 0x43, 0x48, 0x21, 0x21, 0x21, 0x2d, 0x2c, 0x45, +0x23, 0x20, 0x45, 0x18, 0x20, 0xb0, 0x00, 0x50, 0x20, 0x58, +0x23, 0x65, 0x23, 0x59, 0x23, 0x68, 0x20, 0xb0, 0x40, 0x50, +0x58, 0x21, 0xb0, 0x40, 0x59, 0x23, 0x58, 0x65, 0x59, 0x8a, +0x60, 0x44, 0x2d, 0x2c, 0x4b, 0x53, 0x23, 0x4b, 0x51, 0x5a, +0x58, 0x20, 0x45, 0x8a, 0x60, 0x44, 0x1b, 0x21, 0x21, 0x59, +0x2d, 0x2c, 0x4b, 0x54, 0x58, 0x20, 0x45, 0x8a, 0x60, 0x44, +0x1b, 0x21, 0x21, 0x59, 0x2d, 0x2c, 0x4b, 0x53, 0x23, 0x4b, +0x51, 0x5a, 0x58, 0x38, 0x1b, 0x21, 0x21, 0x59, 0x2d, 0x2c, +0x4b, 0x54, 0x58, 0x38, 0x1b, 0x21, 0x21, 0x59, 0x2d, 0x2c, +0xb0, 0x02, 0x43, 0x54, 0x58, 0xb0, 0x46, 0x2b, 0x1b, 0x21, +0x21, 0x21, 0x21, 0x59, 0x2d, 0x2c, 0xb0, 0x02, 0x43, 0x54, +0x58, 0xb0, 0x47, 0x2b, 0x1b, 0x21, 0x21, 0x21, 0x59, 0x2d, +0x2c, 0xb0, 0x02, 0x43, 0x54, 0x58, 0xb0, 0x48, 0x2b, 0x1b, +0x21, 0x21, 0x21, 0x21, 0x59, 0x2d, 0x2c, 0xb0, 0x02, 0x43, +0x54, 0x58, 0xb0, 0x49, 0x2b, 0x1b, 0x21, 0x21, 0x21, 0x59, +0x2d, 0x2c, 0x20, 0x8a, 0x08, 0x23, 0x4b, 0x53, 0x8a, 0x4b, +0x51, 0x5a, 0x58, 0x23, 0x38, 0x1b, 0x21, 0x21, 0x59, 0x2d, +0x2c, 0x00, 0x20, 0x8a, 0x49, 0xb0, 0x00, 0x51, 0x58, 0xb0, +0x40, 0x23, 0x20, 0x8a, 0x38, 0x12, 0x34, 0x1b, 0x21, 0x21, +0x59, 0x2d, 0x2c, 0x01, 0x46, 0x23, 0x46, 0x60, 0x23, 0x46, +0x61, 0x23, 0x20, 0x10, 0x20, 0x46, 0x8a, 0x61, 0xb8, 0xff, +0x80, 0x62, 0x8a, 0xb1, 0x40, 0x40, 0x8a, 0x70, 0x45, 0x60, +0x68, 0x3a, 0x2d, 0x2c, 0x20, 0x8a, 0x23, 0x49, 0x64, 0x8a, +0x23, 0x53, 0x58, 0x3c, 0x1b, 0x21, 0x59, 0x2d, 0x2c, 0x4b, +0x52, 0x58, 0x7d, 0x1b, 0x7a, 0x59, 0x2d, 0x2c, 0xb0, 0x12, +0x00, 0x4b, 0x01, 0x4b, 0x54, 0x42, 0x2d, 0x2c, 0xb1, 0x02, +0x00, 0x42, 0xb1, 0x23, 0x01, 0x88, 0x51, 0xb1, 0x40, 0x01, +0x88, 0x53, 0x5a, 0x58, 0xb9, 0x10, 0x00, 0x00, 0x20, 0x88, +0x54, 0x58, 0xb1, 0x02, 0x01, 0x42, 0x59, 0x59, 0x2d, 0x2c, +0x45, 0x18, 0x68, 0x23, 0x4b, 0x51, 0x58, 0x23, 0x20, 0x45, +0x20, 0x64, 0xb0, 0x40, 0x50, 0x58, 0x7c, 0x59, 0x68, 0x8a, +0x60, 0x59, 0x44, 0x2d, 0x2c, 0xb0, 0x00, 0x16, 0xb0, 0x02, +0x25, 0xb0, 0x02, 0x25, 0x01, 0xb0, 0x01, 0x23, 0x3e, 0x00, +0xb0, 0x02, 0x23, 0x3e, 0xb1, 0x01, 0x02, 0x06, 0x0c, 0xb0, +0x0a, 0x23, 0x65, 0x42, 0xb0, 0x0b, 0x23, 0x42, 0x01, 0xb0, +0x01, 0x23, 0x3f, 0x00, 0xb0, 0x02, 0x23, 0x3f, 0xb1, 0x01, +0x02, 0x06, 0x0c, 0xb0, 0x06, 0x23, 0x65, 0x42, 0xb0, 0x07, +0x23, 0x42, 0xb0, 0x01, 0x16, 0x01, 0x2d, 0x00, 0x40, 0x0e, +0x9f, 0xa3, 0xaf, 0xa3, 0x02, 0x40, 0x9d, 0x1a, 0x21, 0x46, +0x9b, 0x79, 0x2a, 0x1f, 0xb8, 0xff, 0xc0, 0x40, 0x0c, 0x9a, +0x0c, 0x12, 0x46, 0x97, 0x79, 0x48, 0x1f, 0x95, 0x73, 0x2a, +0x1f, 0xb8, 0xff, 0xc0, 0x40, 0x54, 0x94, 0x0c, 0x12, 0x46, +0x92, 0x73, 0x13, 0x1f, 0x91, 0x73, 0x48, 0x1f, 0x8f, 0x79, +0x2a, 0x1f, 0x8e, 0x79, 0x48, 0x1f, 0x8c, 0x73, 0x2a, 0x1f, +0x8b, 0x73, 0x48, 0x1f, 0x81, 0x73, 0x2a, 0x1f, 0x8a, 0x83, +0x2a, 0x1f, 0x89, 0x86, 0x48, 0x1f, 0x88, 0x79, 0x2a, 0x1f, +0x85, 0x79, 0x48, 0x1f, 0x83, 0x73, 0x13, 0x1f, 0x82, 0x73, +0x2a, 0x1f, 0x7f, 0x73, 0x48, 0x1f, 0x78, 0x73, 0x2a, 0x1f, +0x7c, 0x79, 0x2a, 0x1f, 0xaf, 0x79, 0xbf, 0x79, 0xcf, 0x79, +0x03, 0x40, 0x79, 0x1f, 0x23, 0x46, 0x76, 0x73, 0x2a, 0x1f, +0xba, 0x01, 0x01, 0x00, 0x43, 0x01, 0x00, 0x40, 0x22, 0x55, +0x68, 0x43, 0x67, 0x55, 0x66, 0x43, 0x65, 0x55, 0x64, 0x43, +0x61, 0x55, 0x63, 0x43, 0x60, 0x55, 0x62, 0x43, 0x5f, 0x55, +0x5e, 0x43, 0x5d, 0x55, 0x5c, 0x43, 0x5b, 0x55, 0x5a, 0x43, +0x59, 0x55, 0xb0, 0xb8, 0x01, 0x00, 0x40, 0x4a, 0x01, 0x0f, +0x65, 0x01, 0x0f, 0x65, 0x7f, 0x65, 0x8f, 0x65, 0x03, 0x30, +0x61, 0x01, 0x10, 0x61, 0x30, 0x61, 0x60, 0x61, 0x90, 0x61, +0xb0, 0x61, 0xe0, 0x61, 0x06, 0xaf, 0x5f, 0x01, 0x00, 0x5d, +0x01, 0x30, 0x5d, 0x60, 0x5d, 0x90, 0x5d, 0x03, 0x58, 0x43, +0x56, 0x55, 0x57, 0x43, 0x55, 0x55, 0x53, 0x90, 0x4d, 0x55, +0x52, 0x90, 0x4b, 0x55, 0x51, 0x90, 0x4a, 0x55, 0x50, 0x90, +0x49, 0x55, 0x46, 0x5b, 0x42, 0x55, 0x45, 0x5b, 0x41, 0x55, +0x54, 0x53, 0xb8, 0x01, 0x00, 0xb3, 0x16, 0x01, 0x05, 0x01, +0xb8, 0x01, 0x90, 0x4b, 0xb8, 0x03, 0xe7, 0x52, 0x4b, 0xb0, +0x08, 0x50, 0x5b, 0xb0, 0x01, 0x88, 0xb0, 0x25, 0x53, 0xb0, +0x01, 0x88, 0xb0, 0x40, 0x51, 0x5a, 0xb0, 0x06, 0x88, 0xb0, +0x00, 0x55, 0x5a, 0x5b, 0x58, 0xb1, 0x01, 0x01, 0x8e, 0x59, +0x85, 0x8d, 0x8d, 0x00, 0x42, 0x1d, 0x4b, 0xb0, 0x1d, 0x53, +0x58, 0xb0, 0xa0, 0x1d, 0x59, 0x4b, 0xb0, 0x48, 0x53, 0x58, +0xb0, 0x40, 0x1d, 0x59, 0x4b, 0xb0, 0x80, 0x53, 0x58, 0xb0, +0x00, 0x1d, 0xb1, 0x16, 0x00, 0x42, 0x59, 0x2b, 0x2b, 0x00, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x73, 0x74, +0x73, 0x73, 0x74, 0x73, 0x74, 0x73, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x00, 0x2b, 0x73, +0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x00, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x00, 0x2b, 0x2b, 0x01, 0x2b, +0x2b, 0x2b, 0x2b, 0x00, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x00, +0x74, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x02, 0x6b, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x0d, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, +0x01, 0xd0, 0x00, 0x00, 0xff, 0x5b, 0x00, 0x00, 0x02, 0xb5, +0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xff, 0xf6, 0xff, 0xf6, +0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x02, 0x6b, 0xff, 0xf2, +0x00, 0x0e, 0x02, 0x6b, 0x00, 0x0e, 0x00, 0x00, 0xff, 0xf2, +0x01, 0x34, 0xff, 0xf2, 0x01, 0x19, 0x02, 0x70, 0x01, 0x78, +0xff, 0xf2, 0x00, 0x09, 0xff, 0xf7, 0x00, 0xfa, 0x00, 0x09, +0x00, 0x00, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, +0x00, 0x54, 0x00, 0x00, 0x00, 0x52, 0x00, 0x46, 0x00, 0x00, +0x00, 0x3a, 0x00, 0x48, 0x00, 0x00, 0x00, 0x42, 0x00, 0x52, +0x00, 0x00, 0x00, 0x52, 0x00, 0x55, 0x00, 0x73, 0x00, 0x3d, +0x00, 0x46, 0x00, 0x43, 0x00, 0x00, 0x00, 0x48, 0x00, 0x43, +0x00, 0x78, 0x00, 0x52, 0x00, 0x54, 0x00, 0x43, 0x00, 0x46, +0x00, 0x48, 0x00, 0x00, 0x00, 0x52, 0x00, 0x60, 0x00, 0x00, +0x00, 0x87, 0x00, 0x54, 0x00, 0x3c, 0x00, 0x46, 0x00, 0x36, +0x00, 0x00, 0x00, 0x87, 0x00, 0x48, 0x00, 0x3c, 0x00, 0x2d, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x19, 0xff, 0xf7, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, +0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, +0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, +0x02, 0x20, 0x00, 0x00, 0x03, 0x6c, 0x00, 0x00, 0x04, 0x7c, +0x00, 0x00, 0x06, 0x50, 0x00, 0x00, 0x06, 0x98, 0x00, 0x00, +0x07, 0x58, 0x00, 0x00, 0x07, 0xf4, 0x00, 0x00, 0x08, 0xbc, +0x00, 0x00, 0x09, 0x08, 0x00, 0x00, 0x09, 0x68, 0x00, 0x00, +0x09, 0x90, 0x00, 0x00, 0x09, 0xcc, 0x00, 0x00, 0x0a, 0x0c, +0x00, 0x00, 0x0b, 0x84, 0x00, 0x00, 0x0c, 0x04, 0x00, 0x00, +0x0d, 0x18, 0x00, 0x00, 0x0e, 0x9c, 0x00, 0x00, 0x0f, 0x54, +0x00, 0x00, 0x10, 0x78, 0x00, 0x00, 0x11, 0xc8, 0x00, 0x00, +0x12, 0x24, 0x00, 0x00, 0x13, 0xf4, 0x00, 0x00, 0x15, 0x20, +0x00, 0x00, 0x15, 0x4c, 0x00, 0x00, 0x15, 0x64, 0x00, 0x00, +0x15, 0xf8, 0x00, 0x00, 0x16, 0x44, 0x00, 0x00, 0x16, 0xdc, +0x00, 0x00, 0x17, 0xd0, 0x00, 0x00, 0x19, 0x3c, 0x00, 0x00, +0x1a, 0x70, 0x00, 0x00, 0x1b, 0x8c, 0x00, 0x00, 0x1c, 0xa8, +0x00, 0x00, 0x1d, 0x4c, 0x00, 0x00, 0x1d, 0xac, 0x00, 0x00, +0x1e, 0x04, 0x00, 0x00, 0x1f, 0x18, 0x00, 0x00, 0x1f, 0x78, +0x00, 0x00, 0x1f, 0xd0, 0x00, 0x00, 0x20, 0x60, 0x00, 0x00, +0x21, 0x10, 0x00, 0x00, 0x21, 0x50, 0x00, 0x00, 0x22, 0xa4, +0x00, 0x00, 0x23, 0x30, 0x00, 0x00, 0x24, 0x2c, 0x00, 0x00, +0x24, 0xd8, 0x00, 0x00, 0x26, 0x20, 0x00, 0x00, 0x27, 0x00, +0x00, 0x00, 0x28, 0x68, 0x00, 0x00, 0x28, 0xac, 0x00, 0x00, +0x29, 0x48, 0x00, 0x00, 0x29, 0xd4, 0x00, 0x00, 0x2b, 0xfc, +0x00, 0x00, 0x2c, 0xb8, 0x00, 0x00, 0x2d, 0x44, 0x00, 0x00, +0x2d, 0xbc, 0x00, 0x00, 0x2d, 0xf8, 0x00, 0x00, 0x2e, 0x34, +0x00, 0x00, 0x2e, 0x70, 0x00, 0x00, 0x2e, 0xd8, 0x00, 0x00, +0x2f, 0x00, 0x00, 0x00, 0x2f, 0x34, 0x00, 0x00, 0x30, 0x34, +0x00, 0x00, 0x31, 0x1c, 0x00, 0x00, 0x31, 0xc4, 0x00, 0x00, +0x32, 0x90, 0x00, 0x00, 0x33, 0xc8, 0x00, 0x00, 0x34, 0x70, +0x00, 0x00, 0x35, 0xb8, 0x00, 0x00, 0x36, 0x60, 0x00, 0x00, +0x37, 0x08, 0x00, 0x00, 0x37, 0xa4, 0x00, 0x00, 0x38, 0x54, +0x00, 0x00, 0x38, 0xe4, 0x00, 0x00, 0x39, 0xa0, 0x00, 0x00, +0x3a, 0x40, 0x00, 0x00, 0x3b, 0x38, 0x00, 0x00, 0x3c, 0x18, +0x00, 0x00, 0x3c, 0xf8, 0x00, 0x00, 0x3d, 0x50, 0x00, 0x00, +0x3e, 0xac, 0x00, 0x00, 0x3f, 0x48, 0x00, 0x00, 0x3f, 0xe4, +0x00, 0x00, 0x40, 0x9c, 0x00, 0x00, 0x42, 0x64, 0x00, 0x00, +0x43, 0x24, 0x00, 0x00, 0x44, 0x94, 0x00, 0x00, 0x45, 0x14, +0x00, 0x00, 0x45, 0xf4, 0x00, 0x00, 0x46, 0x24, 0x00, 0x00, +0x47, 0x04, 0x00, 0x00, 0x47, 0xb4, 0x00, 0x00, 0x48, 0xd8, +0x00, 0x00, 0x49, 0x38, 0x00, 0x00, 0x49, 0xf8, 0x00, 0x00, +0x4a, 0x9c, 0x00, 0x00, 0x4b, 0x38, 0x00, 0x00, 0x4b, 0x98, +0x00, 0x00, 0x4c, 0x18, 0x00, 0x00, 0x4c, 0x94, 0x00, 0x00, +0x4e, 0x44, 0x00, 0x00, 0x4e, 0x70, 0x00, 0x00, 0x4e, 0xc4, +0x00, 0x00, 0x4f, 0xb8, 0x00, 0x00, 0x50, 0x18, 0x00, 0x00, +0x50, 0x74, 0x00, 0x00, 0x51, 0x1c, 0x00, 0x00, 0x51, 0xc0, +0x00, 0x00, 0x52, 0x10, 0x00, 0x00, 0x52, 0x38, 0x00, 0x00, +0x52, 0x60, 0x00, 0x00, 0x52, 0xf0, 0x00, 0x00, 0x53, 0xb0, +0x00, 0x00, 0x53, 0xd8, 0x00, 0x00, 0x54, 0x1c, 0x00, 0x00, +0x55, 0x6c, 0x00, 0x00, 0x55, 0xa0, 0x00, 0x00, 0x55, 0xa0, +0x00, 0x00, 0x56, 0x14, 0x00, 0x00, 0x56, 0xe0, 0x00, 0x00, +0x57, 0xb0, 0x00, 0x00, 0x58, 0x84, 0x00, 0x00, 0x59, 0x54, +0x00, 0x00, 0x59, 0x98, 0x00, 0x00, 0x5b, 0xb8, 0x00, 0x00, +0x5c, 0x28, 0x00, 0x00, 0x5d, 0xec, 0x00, 0x00, 0x5e, 0xec, +0x00, 0x00, 0x5f, 0x5c, 0x00, 0x00, 0x5f, 0x8c, 0x00, 0x00, +0x5f, 0x9c, 0x00, 0x00, 0x61, 0xd4, 0x00, 0x00, 0x61, 0xfc, +0x00, 0x00, 0x62, 0x98, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, +0x64, 0x48, 0x00, 0x00, 0x65, 0xc0, 0x00, 0x00, 0x65, 0xf4, +0x00, 0x00, 0x66, 0x88, 0x00, 0x00, 0x66, 0xf0, 0x00, 0x00, +0x67, 0x04, 0x00, 0x00, 0x67, 0x94, 0x00, 0x00, 0x67, 0xf8, +0x00, 0x00, 0x68, 0x94, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, +0x69, 0xd0, 0x00, 0x00, 0x6b, 0x18, 0x00, 0x00, 0x6c, 0xdc, +0x00, 0x00, 0x6d, 0xd8, 0x00, 0x00, 0x6e, 0x04, 0x00, 0x00, +0x6e, 0x30, 0x00, 0x00, 0x6e, 0x5c, 0x00, 0x00, 0x6e, 0x88, +0x00, 0x00, 0x6e, 0xd0, 0x00, 0x00, 0x6f, 0xf8, 0x00, 0x00, +0x70, 0xac, 0x00, 0x00, 0x72, 0x88, 0x00, 0x00, 0x72, 0xb8, +0x00, 0x00, 0x72, 0xe4, 0x00, 0x00, 0x73, 0x14, 0x00, 0x00, +0x73, 0x48, 0x00, 0x00, 0x73, 0x74, 0x00, 0x00, 0x73, 0xa0, +0x00, 0x00, 0x73, 0xcc, 0x00, 0x00, 0x74, 0x04, 0x00, 0x00, +0x74, 0xd4, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x75, 0x2c, +0x00, 0x00, 0x75, 0x58, 0x00, 0x00, 0x75, 0x84, 0x00, 0x00, +0x75, 0xb0, 0x00, 0x00, 0x75, 0xe4, 0x00, 0x00, 0x76, 0x44, +0x00, 0x00, 0x78, 0x40, 0x00, 0x00, 0x78, 0x70, 0x00, 0x00, +0x78, 0x9c, 0x00, 0x00, 0x78, 0xc8, 0x00, 0x00, 0x78, 0xfc, +0x00, 0x00, 0x79, 0x28, 0x00, 0x00, 0x79, 0xf4, 0x00, 0x00, +0x7b, 0xd8, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x7c, 0x28, +0x00, 0x00, 0x7c, 0x50, 0x00, 0x00, 0x7c, 0x78, 0x00, 0x00, +0x7c, 0xa8, 0x00, 0x00, 0x7c, 0xd4, 0x00, 0x00, 0x7e, 0x64, +0x00, 0x00, 0x7f, 0x94, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, +0x7f, 0xe8, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x80, 0x40, +0x00, 0x00, 0x80, 0x6c, 0x00, 0x00, 0x80, 0x98, 0x00, 0x00, +0x80, 0xc4, 0x00, 0x00, 0x80, 0xf8, 0x00, 0x00, 0x82, 0x6c, +0x00, 0x00, 0x82, 0x98, 0x00, 0x00, 0x82, 0xc0, 0x00, 0x00, +0x82, 0xe8, 0x00, 0x00, 0x83, 0x10, 0x00, 0x00, 0x83, 0x38, +0x00, 0x00, 0x83, 0x68, 0x00, 0x00, 0x83, 0xe8, 0x00, 0x00, +0x85, 0x18, 0x00, 0x00, 0x85, 0x44, 0x00, 0x00, 0x85, 0x6c, +0x00, 0x00, 0x85, 0x94, 0x00, 0x00, 0x85, 0xc4, 0x00, 0x00, +0x85, 0xec, 0x00, 0x00, 0x86, 0xdc, 0x00, 0x00, 0x87, 0x0c, +0x00, 0x00, 0x87, 0x38, 0x00, 0x00, 0x87, 0x60, 0x00, 0x00, +0x87, 0x8c, 0x00, 0x00, 0x87, 0xb4, 0x00, 0x00, 0x88, 0xac, +0x00, 0x00, 0x8a, 0x04, 0x00, 0x00, 0x8a, 0x30, 0x00, 0x00, +0x8a, 0x58, 0x00, 0x00, 0x8a, 0x84, 0x00, 0x00, 0x8a, 0xac, +0x00, 0x00, 0x8a, 0xd8, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, +0x8b, 0x2c, 0x00, 0x00, 0x8b, 0x54, 0x00, 0x00, 0x8b, 0x84, +0x00, 0x00, 0x8c, 0x64, 0x00, 0x00, 0x8c, 0x74, 0x00, 0x00, +0x8d, 0x6c, 0x00, 0x00, 0x8d, 0x9c, 0x00, 0x00, 0x8d, 0xc4, +0x00, 0x00, 0x8d, 0xf4, 0x00, 0x00, 0x8e, 0x1c, 0x00, 0x00, +0x8e, 0x4c, 0x00, 0x00, 0x8e, 0x74, 0x00, 0x00, 0x8f, 0x28, +0x00, 0x00, 0x90, 0x84, 0x00, 0x00, 0x90, 0xb0, 0x00, 0x00, +0x90, 0xd8, 0x00, 0x00, 0x91, 0x04, 0x00, 0x00, 0x91, 0x2c, +0x00, 0x00, 0x91, 0x58, 0x00, 0x00, 0x91, 0x80, 0x00, 0x00, +0x91, 0xac, 0x00, 0x00, 0x91, 0xd4, 0x00, 0x00, 0x91, 0xf8, +0x00, 0x00, 0x92, 0x20, 0x00, 0x00, 0x92, 0x4c, 0x00, 0x00, +0x93, 0x30, 0x00, 0x00, 0x93, 0xcc, 0x00, 0x00, 0x94, 0xac, +0x00, 0x00, 0x94, 0xd8, 0x00, 0x00, 0x95, 0x04, 0x00, 0x00, +0x95, 0x30, 0x00, 0x00, 0x95, 0x5c, 0x00, 0x00, 0x95, 0x88, +0x00, 0x00, 0x95, 0xb4, 0x00, 0x00, 0x96, 0x5c, 0x00, 0x00, +0x97, 0x3c, 0x00, 0x00, 0x97, 0x68, 0x00, 0x00, 0x97, 0xd8, +0x00, 0x00, 0x97, 0xe8, 0x00, 0x00, 0x98, 0x54, 0x00, 0x00, +0x99, 0x20, 0x00, 0x00, 0x99, 0x4c, 0x00, 0x00, 0x99, 0x74, +0x00, 0x00, 0x99, 0x9c, 0x00, 0x00, 0x99, 0xc4, 0x00, 0x00, +0x9a, 0xa0, 0x00, 0x00, 0x9b, 0x50, 0x00, 0x00, 0x9b, 0x80, +0x00, 0x00, 0x9c, 0x30, 0x00, 0x00, 0x9c, 0x58, 0x00, 0x00, +0x9c, 0x7c, 0x00, 0x00, 0x9c, 0xa0, 0x00, 0x00, 0x9c, 0xc4, +0x00, 0x00, 0x9c, 0xe8, 0x00, 0x00, 0x9d, 0x0c, 0x00, 0x00, +0x9d, 0x84, 0x00, 0x00, 0x9e, 0x4c, 0x00, 0x00, 0x9e, 0x78, +0x00, 0x00, 0x9e, 0xa0, 0x00, 0x00, 0x9e, 0xc8, 0x00, 0x00, +0x9e, 0xf0, 0x00, 0x00, 0x9f, 0x1c, 0x00, 0x00, 0x9f, 0x48, +0x00, 0x00, 0xa0, 0x50, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, +0xa1, 0x38, 0x00, 0x00, 0xa1, 0xf8, 0x00, 0x00, 0xa2, 0x24, +0x00, 0x00, 0xa2, 0x4c, 0x00, 0x00, 0xa2, 0x78, 0x00, 0x00, +0xa2, 0xa0, 0x00, 0x00, 0xa2, 0xd4, 0x00, 0x00, 0xa3, 0x04, +0x00, 0x00, 0xa3, 0x34, 0x00, 0x00, 0xa3, 0x5c, 0x00, 0x00, +0xa3, 0x84, 0x00, 0x00, 0xa3, 0xac, 0x00, 0x00, 0xa3, 0xdc, +0x00, 0x00, 0xa4, 0x04, 0x00, 0x00, 0xa4, 0x30, 0x00, 0x00, +0xa4, 0x58, 0x00, 0x00, 0xa4, 0x84, 0x00, 0x00, 0xa4, 0xac, +0x00, 0x00, 0xa6, 0x98, 0x00, 0x00, 0xa8, 0x44, 0x00, 0x00, +0xa8, 0xf0, 0x00, 0x00, 0xa9, 0xf8, 0x00, 0x00, 0xaa, 0x24, +0x00, 0x00, 0xaa, 0x48, 0x00, 0x00, 0xaa, 0xb4, 0x00, 0x00, +0xab, 0x78, 0x00, 0x00, 0xab, 0xa4, 0x00, 0x00, 0xab, 0xcc, +0x00, 0x00, 0xab, 0xf8, 0x00, 0x00, 0xac, 0x20, 0x00, 0x00, +0xac, 0x4c, 0x00, 0x00, 0xac, 0x74, 0x00, 0x00, 0xac, 0x9c, +0x00, 0x00, 0xac, 0xc0, 0x00, 0x00, 0xac, 0xf4, 0x00, 0x00, +0xad, 0x24, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0xae, 0xdc, +0x00, 0x00, 0xaf, 0x08, 0x00, 0x00, 0xaf, 0x34, 0x00, 0x00, +0xaf, 0x60, 0x00, 0x00, 0xaf, 0x88, 0x00, 0x00, 0xaf, 0xb4, +0x00, 0x00, 0xaf, 0xdc, 0x00, 0x00, 0xb0, 0x0c, 0x00, 0x00, +0xb0, 0x34, 0x00, 0x00, 0xb0, 0x64, 0x00, 0x00, 0xb0, 0x8c, +0x00, 0x00, 0xb0, 0xfc, 0x00, 0x00, 0xb1, 0x24, 0x00, 0x00, +0xb1, 0x4c, 0x00, 0x00, 0xb1, 0x74, 0x00, 0x00, 0xb1, 0x98, +0x00, 0x00, 0xb2, 0x0c, 0x00, 0x00, 0xb2, 0x5c, 0x00, 0x00, +0xb2, 0xa4, 0x00, 0x00, 0xb2, 0xb4, 0x00, 0x00, 0xb3, 0x10, +0x00, 0x00, 0xb3, 0x4c, 0x00, 0x00, 0xb3, 0xd4, 0x00, 0x00, +0xb4, 0x40, 0x00, 0x00, 0xb4, 0x8c, 0x00, 0x00, 0xb4, 0xbc, +0x00, 0x00, 0xb4, 0xe8, 0x00, 0x00, 0xb5, 0x14, 0x00, 0x00, +0xb5, 0x3c, 0x00, 0x00, 0xb5, 0x70, 0x00, 0x00, 0xb5, 0xa0, +0x00, 0x00, 0xb5, 0xd0, 0x00, 0x00, 0xb5, 0xfc, 0x00, 0x00, +0xb6, 0x38, 0x00, 0x00, 0xb7, 0x38, 0x00, 0x00, 0xb7, 0xf4, +0x00, 0x00, 0xb8, 0xd8, 0x00, 0x00, 0xba, 0xa0, 0x00, 0x00, +0xbb, 0x24, 0x00, 0x00, 0xbe, 0x68, 0x00, 0x00, 0xbf, 0x64, +0x00, 0x00, 0xbf, 0x78, 0x00, 0x00, 0xbf, 0x8c, 0x00, 0x00, +0xbf, 0xa0, 0x00, 0x00, 0xbf, 0xb4, 0x00, 0x00, 0xbf, 0xc8, +0x00, 0x00, 0xbf, 0xdc, 0x00, 0x00, 0xbf, 0xf0, 0x00, 0x00, +0xc0, 0x04, 0x00, 0x00, 0xc0, 0x18, 0x00, 0x00, 0xc0, 0x2c, +0x00, 0x00, 0xc1, 0x78, 0x00, 0x00, 0xc2, 0x48, 0x00, 0x00, +0xc4, 0x0c, 0x00, 0x00, 0xc6, 0x20, 0x00, 0x00, 0xc7, 0xe8, +0x00, 0x00, 0xca, 0xa8, 0x00, 0x00, 0xcd, 0x98, 0x00, 0x00, +0xcf, 0x3c, 0x00, 0x00, 0xd0, 0x5c, 0x00, 0x00, 0xd2, 0x20, +0x00, 0x00, 0xd3, 0xe4, 0x00, 0x00, 0xd5, 0x44, 0x00, 0x00, +0xd6, 0x94, 0x00, 0x00, 0xd8, 0x58, 0x00, 0x00, 0xd9, 0x20, +0x00, 0x00, 0xda, 0x2c, 0x00, 0x00, 0xdb, 0x80, 0x00, 0x00, +0xdc, 0x64, 0x00, 0x00, 0xdd, 0xdc, 0x00, 0x00, 0xdf, 0x3c, +0x00, 0x00, 0xe0, 0x8c, 0x00, 0x00, 0xe2, 0x1c, 0x00, 0x00, +0xe3, 0x70, 0x00, 0x00, 0xe5, 0x20, 0x00, 0x00, 0xe6, 0x50, +0x00, 0x00, 0xe8, 0xac, 0x00, 0x00, 0xe9, 0xd0, 0x00, 0x00, +0xea, 0x64, 0x00, 0x00, 0xea, 0xa4, 0x00, 0x00, 0xeb, 0x48, +0x00, 0x00, 0xec, 0x28, 0x00, 0x00, 0xec, 0x50, 0x00, 0x00, +0xec, 0x60, 0x00, 0x00, 0xec, 0x74, 0x00, 0x00, 0xec, 0xdc, +0x00, 0x00, 0xed, 0xb8, 0x00, 0x00, 0xee, 0x1c, 0x00, 0x00, +0xee, 0x34, 0x00, 0x00, 0xee, 0xb8, 0x00, 0x00, 0xee, 0xd0, +0x00, 0x00, 0xee, 0xe8, 0x00, 0x00, 0xef, 0xe4, 0x00, 0x00, +0xf0, 0xa4, 0x00, 0x00, 0xf1, 0x5c, 0x00, 0x00, 0xf2, 0x0c, +0x00, 0x00, 0xf2, 0xbc, 0x00, 0x00, 0xf2, 0xcc, 0x00, 0x00, +0xf2, 0xdc, 0x00, 0x00, 0xf2, 0xec, 0x00, 0x00, 0xf2, 0xfc, +0x00, 0x00, 0xf3, 0x0c, 0x00, 0x00, 0xf3, 0x1c, 0x00, 0x00, +0xf3, 0x2c, 0x00, 0x00, 0xf3, 0x3c, 0x00, 0x00, 0xf3, 0x4c, +0x00, 0x00, 0xf3, 0x5c, 0x00, 0x00, 0xf3, 0x70, 0x00, 0x00, +0xf3, 0x84, 0x00, 0x00, 0xf3, 0x98, 0x00, 0x00, 0xf3, 0xac, +0x00, 0x00, 0xf3, 0xc0, 0x00, 0x00, 0xf3, 0xd4, 0x00, 0x00, +0xf3, 0xe8, 0x00, 0x00, 0xf3, 0xfc, 0x00, 0x00, 0xf4, 0x10, +0x00, 0x00, 0xf4, 0x24, 0x00, 0x00, 0xf4, 0x50, 0x00, 0x00, +0xf4, 0x98, 0x00, 0x00, 0xf4, 0xe4, 0x00, 0x00, 0xf5, 0x10, +0x00, 0x00, 0xf5, 0x20, 0x00, 0x00, 0xf5, 0x30, 0x00, 0x00, +0xf5, 0x40, 0x00, 0x00, 0xf5, 0x50, 0x00, 0x00, 0xf5, 0x60, +0x00, 0x00, 0xf5, 0x70, 0x00, 0x00, 0xf5, 0x80, 0x00, 0x00, +0xf5, 0x90, 0x00, 0x00, 0xf5, 0xa0, 0x00, 0x00, 0xf5, 0xb0, +0x00, 0x00, 0xf5, 0xc0, 0x00, 0x00, 0xf5, 0xd0, 0x00, 0x00, +0xf5, 0xe0, 0x00, 0x00, 0xf5, 0xf0, 0x00, 0x00, 0xf6, 0x00, +0x00, 0x00, 0xf6, 0x14, 0x00, 0x00, 0xf6, 0x24, 0x00, 0x00, +0xf6, 0x34, 0x00, 0x00, 0xf6, 0x48, 0x00, 0x00, 0xf7, 0x5c, +0x00, 0x00, 0xf8, 0xd8, 0x00, 0x00, 0xf9, 0xb4, 0x00, 0x00, +0xfa, 0xac, 0x00, 0x00, 0xfb, 0xa0, 0x00, 0x00, 0xfc, 0xa0, +0x00, 0x00, 0xfd, 0x80, 0x00, 0x00, 0xfe, 0xa0, 0x00, 0x00, +0xff, 0x78, 0x00, 0x00, 0xff, 0x88, 0x00, 0x01, 0x00, 0x78, +0x00, 0x01, 0x01, 0x58, 0x00, 0x01, 0x02, 0x24, 0x00, 0x01, +0x03, 0xb4, 0x00, 0x01, 0x04, 0x10, 0x00, 0x01, 0x05, 0x28, +0x00, 0x01, 0x06, 0x7c, 0x00, 0x01, 0x06, 0xf4, 0x00, 0x01, +0x08, 0x24, 0x00, 0x01, 0x09, 0xf4, 0x00, 0x01, 0x0b, 0x0c, +0x00, 0x01, 0x0b, 0x98, 0x00, 0x01, 0x0c, 0x20, 0x00, 0x01, +0x0c, 0xf0, 0x00, 0x01, 0x0d, 0xbc, 0x00, 0x01, 0x0e, 0x58, +0x00, 0x01, 0x0f, 0x78, 0x00, 0x01, 0x10, 0x30, 0x00, 0x01, +0x10, 0xe0, 0x00, 0x01, 0x11, 0x74, 0x00, 0x01, 0x12, 0xb0, +0x00, 0x01, 0x13, 0xfc, 0x00, 0x01, 0x15, 0x14, 0x00, 0x01, +0x16, 0x58, 0x00, 0x01, 0x17, 0x90, 0x00, 0x01, 0x18, 0x78, +0x00, 0x01, 0x19, 0x9c, 0x00, 0x01, 0x1a, 0x90, 0x00, 0x01, +0x1c, 0x2c, 0x00, 0x01, 0x1d, 0x94, 0x00, 0x01, 0x1d, 0xa4, +0x00, 0x01, 0x1e, 0xb0, 0x00, 0x01, 0x1f, 0xd0, 0x00, 0x01, +0x20, 0x3c, 0x00, 0x01, 0x21, 0x08, 0x00, 0x01, 0x21, 0x78, +0x00, 0x01, 0x22, 0x5c, 0x00, 0x01, 0x23, 0x10, 0x00, 0x01, +0x24, 0x20, 0x00, 0x01, 0x24, 0xfc, 0x00, 0x01, 0x25, 0xac, +0x00, 0x01, 0x26, 0xa0, 0x00, 0x01, 0x27, 0x64, 0x00, 0x01, +0x28, 0x24, 0x00, 0x01, 0x29, 0x50, 0x00, 0x01, 0x2a, 0xa4, +0x00, 0x01, 0x2b, 0xcc, 0x00, 0x01, 0x2c, 0xe4, 0x00, 0x01, +0x2e, 0x20, 0x00, 0x01, 0x2f, 0x2c, 0x00, 0x01, 0x30, 0x34, +0x00, 0x01, 0x31, 0x6c, 0x00, 0x01, 0x32, 0x2c, 0x00, 0x01, +0x32, 0x3c, 0x00, 0x01, 0x32, 0x54, 0x00, 0x01, 0x32, 0xe4, +0x00, 0x01, 0x32, 0xf4, 0x00, 0x01, 0x34, 0x14, 0x00, 0x01, +0x35, 0x64, 0x00, 0x01, 0x36, 0xa8, 0x00, 0x01, 0x37, 0x14, +0x00, 0x01, 0x37, 0xb4, 0x00, 0x01, 0x38, 0x68, 0x00, 0x01, +0x38, 0xf0, 0x00, 0x01, 0x39, 0xe0, 0x00, 0x01, 0x3a, 0xc4, +0x00, 0x01, 0x3a, 0xf0, 0x00, 0x01, 0x3b, 0x18, 0x00, 0x01, +0x3b, 0x44, 0x00, 0x01, 0x3b, 0x70, 0x00, 0x01, 0x3b, 0x9c, +0x00, 0x01, 0x3b, 0xc4, 0x00, 0x01, 0x3b, 0xf0, 0x00, 0x01, +0x3c, 0x18, 0x00, 0x01, 0x3d, 0x08, 0x00, 0x01, 0x3d, 0x40, +0x00, 0x01, 0x3d, 0x78, 0x00, 0x01, 0x3d, 0xb0, 0x00, 0x01, +0x3d, 0xe8, 0x00, 0x01, 0x3e, 0x20, 0x00, 0x01, 0x3e, 0x58, +0x00, 0x01, 0x3e, 0x90, 0x00, 0x01, 0x3f, 0x5c, 0x00, 0x01, +0x40, 0x80, 0x00, 0x01, 0x40, 0xb8, 0x00, 0x01, 0x41, 0xb0, +0x00, 0x01, 0x41, 0xe0, 0x00, 0x01, 0x42, 0x0c, 0x00, 0x01, +0x42, 0x34, 0x00, 0x01, 0x43, 0x74, 0x00, 0x01, 0x44, 0xa0, +0x00, 0x01, 0x44, 0xcc, 0x00, 0x01, 0x44, 0xf4, 0x00, 0x01, +0x45, 0x24, 0x00, 0x01, 0x46, 0x0c, 0x00, 0x01, 0x47, 0x4c, +0x00, 0x01, 0x48, 0xa8, 0x00, 0x01, 0x48, 0xd4, 0x00, 0x01, +0x48, 0xfc, 0x00, 0x01, 0x49, 0x28, 0x00, 0x01, 0x49, 0x50, +0x00, 0x01, 0x49, 0x78, 0x00, 0x01, 0x4a, 0x90, 0x00, 0x01, +0x4b, 0x98, 0x00, 0x01, 0x4c, 0xa8, 0x00, 0x01, 0x4c, 0xd4, +0x00, 0x01, 0x4c, 0xfc, 0x00, 0x01, 0x4d, 0xa8, 0x00, 0x01, +0x4e, 0x68, 0x00, 0x01, 0x4e, 0x98, 0x00, 0x01, 0x4e, 0xc4, +0x00, 0x01, 0x4f, 0xf4, 0x00, 0x01, 0x50, 0x1c, 0x00, 0x01, +0x50, 0x48, 0x00, 0x01, 0x50, 0x70, 0x00, 0x01, 0x50, 0x9c, +0x00, 0x01, 0x50, 0xc4, 0x00, 0x01, 0x50, 0xf8, 0x00, 0x01, +0x51, 0x28, 0x00, 0x01, 0x51, 0x54, 0x00, 0x01, 0x51, 0x7c, +0x00, 0x01, 0x51, 0xb0, 0x00, 0x01, 0x51, 0xe0, 0x00, 0x01, +0x52, 0x0c, 0x00, 0x01, 0x52, 0x34, 0x00, 0x01, 0x52, 0x68, +0x00, 0x01, 0x52, 0x9c, 0x00, 0x01, 0x52, 0xc8, 0x00, 0x01, +0x52, 0xf4, 0x00, 0x01, 0x53, 0x28, 0x00, 0x01, 0x53, 0x5c, +0x00, 0x01, 0x53, 0x88, 0x00, 0x01, 0x53, 0xb0, 0x00, 0x01, +0x53, 0xe4, 0x00, 0x01, 0x54, 0x18, 0x00, 0x01, 0x54, 0x48, +0x00, 0x01, 0x54, 0x70, 0x00, 0x01, 0x54, 0xa4, 0x00, 0x01, +0x54, 0xd8, 0x00, 0x01, 0x55, 0x04, 0x00, 0x01, 0x55, 0x2c, +0x00, 0x01, 0x56, 0x78, 0x00, 0x01, 0x57, 0xc0, 0x00, 0x01, +0x57, 0xec, 0x00, 0x01, 0x58, 0xc8, 0x00, 0x01, 0x59, 0x48, +0x00, 0x01, 0x5a, 0xac, 0x00, 0x01, 0x5b, 0xe8, 0x00, 0x01, +0x5d, 0x20, 0x00, 0x01, 0x5d, 0xc8, 0x00, 0x01, 0x5e, 0x70, +0x00, 0x01, 0x5e, 0x9c, 0x00, 0x01, 0x5e, 0xc4, 0x00, 0x01, +0x5f, 0x94, 0x00, 0x01, 0x61, 0x18, 0x00, 0x01, 0x62, 0x84, +0x00, 0x01, 0x62, 0xbc, 0x00, 0x01, 0x64, 0x74, 0x00, 0x01, +0x64, 0xa4, 0x00, 0x01, 0x64, 0xd0, 0x00, 0x01, 0x64, 0xf8, +0x00, 0x01, 0x66, 0x3c, 0x00, 0x01, 0x66, 0x6c, 0x00, 0x01, +0x66, 0x98, 0x00, 0x01, 0x66, 0xc0, 0x00, 0x01, 0x67, 0x94, +0x00, 0x01, 0x68, 0xa4, 0x00, 0x01, 0x69, 0xa0, 0x00, 0x01, +0x6a, 0xfc, 0x00, 0x01, 0x6c, 0x20, 0x00, 0x01, 0x6d, 0x38, +0x00, 0x01, 0x6e, 0xa4, 0x00, 0x01, 0x6f, 0xf8, 0x00, 0x01, +0x70, 0x58, 0x00, 0x01, 0x70, 0xec, 0x00, 0x01, 0x72, 0x58, +0x00, 0x01, 0x73, 0x7c, 0x00, 0x01, 0x74, 0x58, 0x00, 0x01, +0x75, 0x58, 0x00, 0x01, 0x76, 0xd0, 0x00, 0x01, 0x77, 0xc4, +0x00, 0x01, 0x77, 0xd4, 0x00, 0x01, 0x78, 0x98, 0x00, 0x01, +0x79, 0xb8, 0x00, 0x01, 0x7a, 0x4c, 0x00, 0x01, 0x7b, 0x0c, +0x00, 0x01, 0x7c, 0x40, 0x00, 0x01, 0x7d, 0x44, 0x00, 0x01, +0x7e, 0x5c, 0x00, 0x01, 0x7e, 0xcc, 0x00, 0x01, 0x7f, 0xa0, +0x00, 0x01, 0x80, 0xd4, 0x00, 0x01, 0x81, 0xcc, 0x00, 0x01, +0x82, 0x28, 0x00, 0x01, 0x82, 0x78, 0x00, 0x01, 0x83, 0x24, +0x00, 0x01, 0x83, 0xa0, 0x00, 0x01, 0x83, 0xf4, 0x00, 0x01, +0x84, 0xb4, 0x00, 0x01, 0x85, 0x74, 0x00, 0x01, 0x86, 0x0c, +0x00, 0x01, 0x86, 0xc0, 0x00, 0x01, 0x86, 0xf0, 0x00, 0x01, +0x87, 0x34, 0x00, 0x01, 0x87, 0x78, 0x00, 0x01, 0x87, 0xfc, +0x00, 0x01, 0x88, 0x8c, 0x00, 0x01, 0x89, 0x28, 0x00, 0x01, +0x89, 0x58, 0x00, 0x01, 0x89, 0x8c, 0x00, 0x01, 0x8a, 0x70, +0x00, 0x01, 0x8a, 0x9c, 0x00, 0x01, 0x8b, 0xe8, 0x00, 0x01, +0x8d, 0x50, 0x00, 0x01, 0x8d, 0xa8, 0x00, 0x01, 0x8d, 0xdc, +0x00, 0x01, 0x8e, 0x6c, 0x00, 0x01, 0x8f, 0x3c, 0x00, 0x01, +0x8f, 0xf8, 0x00, 0x01, 0x90, 0xb4, 0x00, 0x01, 0x90, 0xe4, +0x00, 0x01, 0x91, 0x10, 0x00, 0x01, 0x91, 0x40, 0x00, 0x01, +0x91, 0x98, 0x00, 0x01, 0x91, 0xa8, 0x00, 0x01, 0x91, 0xb8, +0x00, 0x01, 0x91, 0xc8, 0x00, 0x01, 0x92, 0x14, 0x00, 0x01, +0x92, 0xcc, 0x00, 0x01, 0x92, 0xdc, 0x00, 0x01, 0x93, 0xec, +0x00, 0x01, 0x95, 0x38, 0x00, 0x01, 0x95, 0xc0, 0x00, 0x01, +0x95, 0xec, 0x00, 0x01, 0x95, 0xfc, 0x00, 0x01, 0x96, 0xa4, +0x00, 0x01, 0x96, 0xb4, 0x00, 0x01, 0x96, 0xc4, 0x00, 0x01, +0x96, 0xd4, 0x00, 0x01, 0x97, 0x18, 0x00, 0x01, 0x97, 0x28, +0x00, 0x01, 0x97, 0x38, 0x00, 0x01, 0x97, 0x48, 0x00, 0x01, +0x98, 0x30, 0x00, 0x01, 0x99, 0x34, 0x00, 0x01, 0x99, 0x44, +0x00, 0x01, 0x99, 0x98, 0x00, 0x01, 0x9a, 0x30, 0x00, 0x01, +0x9a, 0x8c, 0x00, 0x01, 0x9b, 0x04, 0x00, 0x01, 0x9b, 0xf4, +0x00, 0x01, 0x9c, 0xa4, 0x00, 0x01, 0x9d, 0x60, 0x00, 0x01, +0x9e, 0x78, 0x00, 0x01, 0x9f, 0x80, 0x00, 0x01, 0xa0, 0x94, +0x00, 0x01, 0xa0, 0xa4, 0x00, 0x01, 0xa1, 0xe0, 0x00, 0x01, +0xa2, 0xf4, 0x00, 0x01, 0xa3, 0x2c, 0x00, 0x01, 0xa3, 0xc8, +0x00, 0x01, 0xa3, 0xd8, 0x00, 0x01, 0xa5, 0x10, 0x00, 0x01, +0xa6, 0x1c, 0x00, 0x01, 0xa6, 0xac, 0x00, 0x01, 0xa6, 0xd4, +0x00, 0x01, 0xa6, 0xe4, 0x00, 0x01, 0xa7, 0x84, 0x00, 0x01, +0xa8, 0x74, 0x00, 0x01, 0xa8, 0xd8, 0x00, 0x01, 0xa8, 0xe8, +0x00, 0x01, 0xa9, 0x34, 0x00, 0x01, 0xa9, 0x44, 0x00, 0x01, +0xa9, 0x54, 0x00, 0x01, 0xa9, 0xa0, 0x00, 0x01, 0xa9, 0xb0, +0x00, 0x01, 0xaa, 0xc4, 0x00, 0x01, 0xaa, 0xd4, 0x00, 0x01, +0xab, 0x30, 0x00, 0x01, 0xab, 0xb4, 0x00, 0x01, 0xac, 0x10, +0x00, 0x01, 0xac, 0x88, 0x00, 0x01, 0xad, 0x54, 0x00, 0x01, +0xae, 0x10, 0x00, 0x01, 0xae, 0xd4, 0x00, 0x01, 0xaf, 0x94, +0x00, 0x01, 0xb0, 0x8c, 0x00, 0x01, 0xb1, 0x7c, 0x00, 0x01, +0xb1, 0xa4, 0x00, 0x01, 0xb1, 0xd4, 0x00, 0x01, 0xb2, 0xdc, +0x00, 0x01, 0xb3, 0x04, 0x00, 0x01, 0xb3, 0xc8, 0x00, 0x01, +0xb3, 0xd8, 0x00, 0x01, 0xb3, 0xe8, 0x00, 0x01, 0xb4, 0x1c, +0x00, 0x01, 0xb4, 0x2c, 0x00, 0x01, 0xb5, 0x1c, 0x00, 0x01, +0xb5, 0xe8, 0x00, 0x01, 0xb5, 0xf8, 0x00, 0x01, 0xb6, 0x20, +0x00, 0x01, 0xb6, 0x48, 0x00, 0x01, 0xb6, 0x70, 0x00, 0x01, +0xb6, 0xd0, 0x00, 0x01, 0xb8, 0x30, 0x00, 0x01, 0xb9, 0x38, +0x00, 0x01, 0xba, 0x10, 0x00, 0x01, 0xbb, 0x98, 0x00, 0x01, +0xbc, 0xd4, 0x00, 0x01, 0xbd, 0x7c, 0x00, 0x01, 0xbe, 0x24, +0x00, 0x01, 0xbf, 0x28, 0x00, 0x01, 0xc0, 0x24, 0x00, 0x01, +0xc1, 0x08, 0x00, 0x01, 0xc2, 0x1c, 0x00, 0x01, 0xc3, 0x60, +0x00, 0x01, 0xc4, 0x94, 0x00, 0x01, 0xc4, 0xe8, 0x00, 0x01, +0xc5, 0x28, 0x00, 0x01, 0xc5, 0x9c, 0x00, 0x01, 0xc5, 0xf8, +0x00, 0x01, 0xc6, 0xe8, 0x00, 0x01, 0xc7, 0xd0, 0x00, 0x01, +0xc9, 0x20, 0x00, 0x01, 0xca, 0x64, 0x00, 0x01, 0xcc, 0x80, +0x00, 0x01, 0xce, 0x18, 0x00, 0x01, 0xce, 0xd0, 0x00, 0x01, +0xcf, 0x60, 0x00, 0x01, 0xd0, 0x3c, 0x00, 0x01, 0xd1, 0x24, +0x00, 0x01, 0xd1, 0xf8, 0x00, 0x01, 0xd2, 0xd4, 0x00, 0x01, +0xd3, 0x8c, 0x00, 0x01, 0xd4, 0x3c, 0x00, 0x01, 0xd4, 0xb0, +0x00, 0x01, 0xd5, 0x24, 0x00, 0x01, 0xd5, 0x94, 0x00, 0x01, +0xd6, 0x00, 0x00, 0x01, 0xd6, 0xf4, 0x00, 0x01, 0xd7, 0xc4, +0x00, 0x01, 0xd9, 0x5c, 0x00, 0x01, 0xda, 0xe8, 0x00, 0x01, +0xda, 0xf8, 0x00, 0x01, 0xdb, 0x08, 0x00, 0x01, 0xdb, 0x60, +0x00, 0x01, 0xdb, 0xbc, 0x00, 0x01, 0xdb, 0xcc, 0x00, 0x01, +0xdc, 0x68, 0x00, 0x01, 0xdd, 0x0c, 0x00, 0x01, 0xdd, 0xb4, +0x00, 0x01, 0xde, 0x60, 0x00, 0x01, 0xdf, 0x0c, 0x00, 0x01, +0xdf, 0x7c, 0x00, 0x01, 0xdf, 0xec, 0x00, 0x01, 0xe0, 0x94, +0x00, 0x01, 0xe1, 0x28, 0x00, 0x01, 0xe1, 0xd4, 0x00, 0x01, +0xe2, 0x68, 0x00, 0x01, 0xe3, 0x04, 0x00, 0x01, 0xe3, 0x14, +0x00, 0x01, 0xe4, 0x64, 0x00, 0x01, 0xe5, 0x6c, 0x00, 0x01, +0xe6, 0xe8, 0x00, 0x01, 0xe8, 0x0c, 0x00, 0x01, 0xe8, 0x1c, +0x00, 0x01, 0xe8, 0x4c, 0x00, 0x01, 0xe8, 0x74, 0x00, 0x01, +0xe9, 0x7c, 0x00, 0x01, 0xea, 0x68, 0x00, 0x01, 0xeb, 0x38, +0x00, 0x01, 0xeb, 0xf4, 0x00, 0x01, 0xec, 0x7c, 0x00, 0x01, +0xed, 0x08, 0x00, 0x01, 0xed, 0xa0, 0x00, 0x01, 0xee, 0x2c, +0x00, 0x01, 0xee, 0xd0, 0x00, 0x01, 0xef, 0x68, 0x00, 0x01, +0xf0, 0xa8, 0x00, 0x01, 0xf1, 0xe0, 0x00, 0x01, 0xf1, 0xf0, +0x00, 0x01, 0xf2, 0x1c, 0x00, 0x01, 0xf2, 0x44, 0x00, 0x01, +0xf2, 0x78, 0x00, 0x01, 0xf2, 0xa8, 0x00, 0x01, 0xf2, 0xb8, +0x00, 0x01, 0xf2, 0xc8, 0x00, 0x01, 0xf2, 0xf8, 0x00, 0x01, +0xf3, 0x20, 0x00, 0x01, 0xf3, 0x30, 0x00, 0x01, 0xf3, 0x40, +0x00, 0x01, 0xf3, 0x74, 0x00, 0x01, 0xf3, 0xa8, 0x00, 0x01, +0xf3, 0xdc, 0x00, 0x01, 0xf4, 0x0c, 0x00, 0x01, 0xf4, 0x40, +0x00, 0x01, 0xf4, 0x74, 0x00, 0x01, 0xf4, 0x84, 0x00, 0x01, +0xf4, 0x94, 0x00, 0x01, 0xf4, 0xc0, 0x00, 0x01, 0xf4, 0xe8, +0x00, 0x01, 0xf5, 0x1c, 0x00, 0x01, 0xf5, 0x4c, 0x00, 0x01, +0xf5, 0x80, 0x00, 0x01, 0xf5, 0xb0, 0x00, 0x01, 0xf6, 0xa8, +0x00, 0x01, 0xf7, 0x88, 0x00, 0x01, 0xf7, 0xbc, 0x00, 0x01, +0xf7, 0xec, 0x00, 0x01, 0xf8, 0x20, 0x00, 0x01, 0xf8, 0x54, +0x00, 0x01, 0xf8, 0x80, 0x00, 0x01, 0xf8, 0xa8, 0x00, 0x01, +0xf8, 0xdc, 0x00, 0x01, 0xf9, 0x0c, 0x00, 0x01, 0xf9, 0x40, +0x00, 0x01, 0xf9, 0x70, 0x00, 0x01, 0xf9, 0xa4, 0x00, 0x01, +0xf9, 0xd4, 0x00, 0x01, 0xfa, 0x28, 0x00, 0x01, 0xfa, 0x74, +0x00, 0x01, 0xfa, 0xa8, 0x00, 0x01, 0xfa, 0xd8, 0x00, 0x01, +0xfb, 0xf0, 0x00, 0x01, 0xfc, 0x18, 0x00, 0x01, 0xfd, 0xac, +0x00, 0x01, 0xfe, 0x90, 0x00, 0x01, 0xfe, 0xec, 0x00, 0x01, +0xff, 0xf8, 0x00, 0x02, 0x00, 0x44, 0x00, 0x02, 0x00, 0x54, +0x00, 0x02, 0x01, 0x70, 0x00, 0x02, 0x01, 0x80, 0x00, 0x02, +0x02, 0x18, 0x00, 0x02, 0x02, 0x28, 0x00, 0x02, 0x02, 0xa0, +0x00, 0x02, 0x02, 0xb0, 0x00, 0x02, 0x03, 0xec, 0x00, 0x02, +0x03, 0xfc, 0x00, 0x02, 0x04, 0xb8, 0x00, 0x02, 0x05, 0x4c, +0x00, 0x02, 0x06, 0x40, 0x00, 0x02, 0x06, 0xcc, 0x00, 0x02, +0x07, 0x38, 0x00, 0x02, 0x07, 0x48, 0x00, 0x02, 0x07, 0x58, +0x00, 0x02, 0x08, 0x3c, 0x00, 0x02, 0x08, 0xe4, 0x00, 0x02, +0x09, 0x28, 0x00, 0x02, 0x09, 0x38, 0x00, 0x02, 0x09, 0x48, +0x00, 0x02, 0x09, 0xec, 0x00, 0x02, 0x0a, 0xb0, 0x00, 0x02, +0x0b, 0xc0, 0x00, 0x02, 0x0c, 0xb0, 0x00, 0x02, 0x0d, 0xf0, +0x00, 0x02, 0x0e, 0x70, 0x00, 0x02, 0x0f, 0xbc, 0x00, 0x02, +0x10, 0xa8, 0x00, 0x02, 0x11, 0xb4, 0x00, 0x02, 0x12, 0x48, +0x00, 0x02, 0x13, 0x84, 0x00, 0x02, 0x13, 0xec, 0x00, 0x02, +0x13, 0xfc, 0x00, 0x02, 0x14, 0xf8, 0x00, 0x02, 0x15, 0x08, +0x00, 0x02, 0x15, 0x18, 0x00, 0x02, 0x16, 0x90, 0x00, 0x02, +0x16, 0xa0, 0x00, 0x02, 0x16, 0xb0, 0x00, 0x02, 0x17, 0xb4, +0x00, 0x02, 0x18, 0xa0, 0x00, 0x02, 0x19, 0xdc, 0x00, 0x02, +0x1a, 0x58, 0x00, 0x02, 0x1a, 0xdc, 0x00, 0x02, 0x1b, 0xe4, +0x00, 0x02, 0x1b, 0xf4, 0x00, 0x02, 0x1c, 0xc0, 0x00, 0x02, +0x1d, 0xd8, 0x00, 0x02, 0x1e, 0x00, 0x00, 0x02, 0x1e, 0x18, +0x00, 0x02, 0x1e, 0x40, 0x00, 0x02, 0x1e, 0x68, 0x00, 0x02, +0x1e, 0x9c, 0x00, 0x02, 0x1e, 0xb4, 0x00, 0x02, 0x1e, 0xcc, +0x00, 0x02, 0x1f, 0x00, 0x00, 0x02, 0x1f, 0x28, 0x00, 0x02, +0x1f, 0x50, 0x00, 0x02, 0x1f, 0x78, 0x00, 0x02, 0x1f, 0xa0, +0x00, 0x02, 0x1f, 0xc8, 0x00, 0x02, 0x1f, 0xfc, 0x00, 0x02, +0x20, 0x38, 0x00, 0x02, 0x20, 0x60, 0x00, 0x02, 0x20, 0x90, +0x00, 0x02, 0x20, 0xb8, 0x00, 0x02, 0x20, 0xf0, 0x00, 0x02, +0x21, 0x18, 0x00, 0x02, 0x21, 0x50, 0x00, 0x02, 0x21, 0x80, +0x00, 0x02, 0x22, 0x0c, 0x00, 0x02, 0x22, 0x38, 0x00, 0x02, +0x22, 0x64, 0x00, 0x02, 0x22, 0x98, 0x00, 0x02, 0x22, 0xcc, +0x00, 0x02, 0x22, 0xfc, 0x00, 0x02, 0x23, 0x2c, 0x00, 0x02, +0x23, 0x5c, 0x00, 0x02, 0x23, 0x90, 0x00, 0x02, 0x23, 0xb8, +0x00, 0x02, 0x23, 0xe0, 0x00, 0x02, 0x24, 0x0c, 0x00, 0x02, +0x24, 0x38, 0x00, 0x02, 0x24, 0x64, 0x00, 0x02, 0x24, 0x90, +0x00, 0x02, 0x24, 0xbc, 0x00, 0x02, 0x24, 0xe8, 0x00, 0x02, +0x25, 0x10, 0x00, 0x02, 0x25, 0x3c, 0x00, 0x02, 0x25, 0x6c, +0x00, 0x02, 0x25, 0xa0, 0x00, 0x02, 0x25, 0xd4, 0x00, 0x02, +0x26, 0x04, 0x00, 0x02, 0x26, 0x2c, 0x00, 0x02, 0x26, 0x54, +0x00, 0x02, 0x26, 0x80, 0x00, 0x02, 0x26, 0xac, 0x00, 0x02, +0x26, 0xd8, 0x00, 0x02, 0x27, 0x04, 0x00, 0x02, 0x27, 0x30, +0x00, 0x02, 0x27, 0x58, 0x00, 0x02, 0x27, 0x8c, 0x00, 0x02, +0x27, 0xc0, 0x00, 0x02, 0x27, 0xf4, 0x00, 0x02, 0x28, 0x24, +0x00, 0x02, 0x28, 0x58, 0x00, 0x02, 0x28, 0x8c, 0x00, 0x02, +0x28, 0xb4, 0x00, 0x02, 0x28, 0xdc, 0x00, 0x02, 0x29, 0x08, +0x00, 0x02, 0x29, 0x34, 0x00, 0x02, 0x29, 0x60, 0x00, 0x02, +0x29, 0x8c, 0x00, 0x02, 0x29, 0xb8, 0x00, 0x02, 0x29, 0xe4, +0x00, 0x02, 0x2a, 0x10, 0x00, 0x02, 0x2a, 0x3c, 0x00, 0x02, +0x2a, 0x70, 0x00, 0x02, 0x2a, 0xa4, 0x00, 0x02, 0x2a, 0xd8, +0x00, 0x02, 0x2b, 0x0c, 0x00, 0x02, 0x2b, 0x40, 0x00, 0x02, +0x2b, 0x74, 0x00, 0x02, 0x2b, 0x9c, 0x00, 0x02, 0x2b, 0xc4, +0x00, 0x02, 0x2b, 0xf0, 0x00, 0x02, 0x2c, 0x1c, 0x00, 0x02, +0x2c, 0x48, 0x00, 0x02, 0x2c, 0x74, 0x00, 0x02, 0x2c, 0xa0, +0x00, 0x02, 0x2c, 0xcc, 0x00, 0x02, 0x2c, 0xf4, 0x00, 0x02, +0x2d, 0x1c, 0x00, 0x02, 0x2d, 0x4c, 0x00, 0x02, 0x2d, 0x7c, +0x00, 0x02, 0x2d, 0xac, 0x00, 0x02, 0x2d, 0xdc, 0x00, 0x02, +0x2e, 0x04, 0x00, 0x02, 0x2e, 0x2c, 0x00, 0x02, 0x2e, 0x58, +0x00, 0x02, 0x2e, 0x84, 0x00, 0x02, 0x2e, 0xb0, 0x00, 0x02, +0x2e, 0xdc, 0x00, 0x02, 0x2f, 0x04, 0x00, 0x02, 0x2f, 0x2c, +0x00, 0x02, 0x2f, 0x5c, 0x00, 0x02, 0x2f, 0x8c, 0x00, 0x02, +0x2f, 0xbc, 0x00, 0x02, 0x2f, 0xec, 0x00, 0x02, 0x30, 0x1c, +0x00, 0x02, 0x30, 0x4c, 0x00, 0x02, 0x30, 0x74, 0x00, 0x02, +0x30, 0xa0, 0x00, 0x02, 0x30, 0xcc, 0x00, 0x02, 0x30, 0xf8, +0x00, 0x02, 0x31, 0x24, 0x00, 0x02, 0x31, 0x4c, 0x00, 0x02, +0x31, 0x80, 0x00, 0x02, 0x31, 0xb4, 0x00, 0x02, 0x31, 0xe8, +0x00, 0x02, 0x32, 0x18, 0x00, 0x02, 0x32, 0x4c, 0x00, 0x02, +0x32, 0x80, 0x00, 0x02, 0x32, 0xa8, 0x00, 0x02, 0x32, 0xd0, +0x00, 0x02, 0x32, 0xfc, 0x00, 0x02, 0x33, 0x28, 0x00, 0x02, +0x33, 0x54, 0x00, 0x02, 0x33, 0x80, 0x00, 0x02, 0x33, 0xac, +0x00, 0x02, 0x33, 0xd8, 0x00, 0x02, 0x34, 0x04, 0x00, 0x02, +0x34, 0x2c, 0x00, 0x02, 0x34, 0x58, 0x00, 0x02, 0x34, 0x80, +0x00, 0x02, 0x34, 0xa8, 0x00, 0x02, 0x34, 0xd0, 0x00, 0x02, +0x34, 0xfc, 0x00, 0x02, 0x35, 0x28, 0x00, 0x02, 0x35, 0x50, +0x00, 0x02, 0x35, 0x78, 0x00, 0x02, 0x35, 0xa0, 0x00, 0x02, +0x35, 0xc8, 0x00, 0x02, 0x35, 0xf0, 0x00, 0x02, 0x36, 0x18, +0x00, 0x02, 0x36, 0x44, 0x00, 0x02, 0x36, 0x70, 0x00, 0x02, +0x36, 0xa0, 0x00, 0x02, 0x36, 0xd0, 0x00, 0x02, 0x37, 0x00, +0x00, 0x02, 0x37, 0x30, 0x00, 0x02, 0x37, 0x60, 0x00, 0x02, +0x37, 0x90, 0x00, 0x02, 0x37, 0xb8, 0x00, 0x02, 0x37, 0xe0, +0x00, 0x02, 0x38, 0x0c, 0x00, 0x02, 0x38, 0x38, 0x00, 0x02, +0x38, 0x64, 0x00, 0x02, 0x38, 0x90, 0x00, 0x02, 0x38, 0xbc, +0x00, 0x02, 0x38, 0xe8, 0x00, 0x02, 0x39, 0x18, 0x00, 0x02, +0x39, 0x48, 0x00, 0x02, 0x39, 0x78, 0x00, 0x02, 0x39, 0xa8, +0x00, 0x02, 0x39, 0xd8, 0x00, 0x02, 0x3a, 0x08, 0x00, 0x02, +0x3a, 0x38, 0x00, 0x02, 0x3a, 0x68, 0x00, 0x02, 0x3a, 0x80, +0x00, 0x02, 0x3a, 0x98, 0x00, 0x02, 0x3a, 0xc4, 0x00, 0x02, +0x3a, 0xf0, 0x00, 0x02, 0x3b, 0x1c, 0x00, 0x02, 0x3b, 0x48, +0x00, 0x02, 0x3b, 0x74, 0x00, 0x02, 0x3b, 0xa0, 0x00, 0x02, +0x3b, 0xcc, 0x00, 0x02, 0x3b, 0xf8, 0x00, 0x02, 0x3c, 0x28, +0x00, 0x02, 0x3c, 0x58, 0x00, 0x02, 0x3c, 0x88, 0x00, 0x02, +0x3c, 0xb8, 0x00, 0x02, 0x3c, 0xe8, 0x00, 0x02, 0x3d, 0x18, +0x00, 0x02, 0x3d, 0x40, 0x00, 0x02, 0x3d, 0x68, 0x00, 0x02, +0x3d, 0x94, 0x00, 0x02, 0x3d, 0xc0, 0x00, 0x02, 0x3d, 0xec, +0x00, 0x02, 0x3e, 0x18, 0x00, 0x02, 0x3e, 0x44, 0x00, 0x02, +0x3e, 0x70, 0x00, 0x02, 0x3e, 0x9c, 0x00, 0x02, 0x3e, 0xc8, +0x00, 0x02, 0x3e, 0xf8, 0x00, 0x02, 0x3f, 0x1c, 0x00, 0x02, +0x3f, 0x48, 0x00, 0x02, 0x3f, 0x70, 0x00, 0x02, 0x3f, 0x9c, +0x00, 0x02, 0x3f, 0xc8, 0x00, 0x02, 0x3f, 0xf4, 0x00, 0x02, +0x40, 0x1c, 0x00, 0x02, 0x40, 0x44, 0x00, 0x02, 0x41, 0x48, +0x00, 0x02, 0x41, 0xa0, 0x00, 0x02, 0x41, 0xe8, 0x00, 0x02, +0x41, 0xf8, 0x00, 0x02, 0x42, 0x54, 0x00, 0x02, 0x42, 0xfc, +0x00, 0x02, 0x43, 0x2c, 0x00, 0x02, 0x43, 0x54, 0x00, 0x02, +0x43, 0x84, 0x00, 0x02, 0x43, 0xb0, 0x00, 0x02, 0x43, 0xe0, +0x00, 0x02, 0x44, 0x08, 0x00, 0x02, 0x44, 0x30, 0x00, 0x02, +0x44, 0x58, 0x00, 0x02, 0x44, 0x80, 0x00, 0x02, 0x45, 0x20, +0x00, 0x02, 0x45, 0xa0, 0x00, 0x02, 0x46, 0x24, 0x00, 0x02, +0x46, 0xc0, 0x00, 0x02, 0x46, 0xec, 0x00, 0x02, 0x47, 0x18, +0x00, 0x02, 0x47, 0x54, 0x00, 0x02, 0x47, 0x90, 0x00, 0x02, +0x47, 0xbc, 0x00, 0x02, 0x47, 0xf8, 0x00, 0x02, 0x48, 0x24, +0x00, 0x02, 0x48, 0x50, 0x00, 0x02, 0x48, 0x78, 0x00, 0x02, +0x48, 0xa0, 0x00, 0x02, 0x49, 0x1c, 0x00, 0x02, 0x49, 0x98, +0x00, 0x02, 0x4a, 0x34, 0x00, 0x02, 0x4a, 0x5c, 0x00, 0x02, +0x4a, 0x84, 0x00, 0x02, 0x4a, 0xbc, 0x00, 0x02, 0x4a, 0xf4, +0x00, 0x02, 0x4b, 0x20, 0x00, 0x02, 0x4b, 0x4c, 0x00, 0x02, +0x4b, 0x74, 0x00, 0x02, 0x4b, 0xac, 0x00, 0x02, 0x4b, 0xd8, +0x00, 0x02, 0x4c, 0x04, 0x00, 0x02, 0x4c, 0x2c, 0x00, 0x02, +0x4c, 0x44, 0x00, 0x02, 0x4c, 0x6c, 0x00, 0x02, 0x4c, 0xf8, +0x00, 0x02, 0x4d, 0x88, 0x00, 0x02, 0x4d, 0xc0, 0x00, 0x02, +0x4d, 0xec, 0x00, 0x02, 0x4e, 0x10, 0x00, 0x02, 0x4e, 0x3c, +0x00, 0x02, 0x4e, 0x68, 0x00, 0x02, 0x4e, 0x98, 0x00, 0x02, +0x4e, 0xc0, 0x00, 0x02, 0x4e, 0xd8, 0x00, 0x02, 0x4f, 0x00, +0x00, 0x02, 0x4f, 0x28, 0x00, 0x02, 0x50, 0x84, 0x00, 0x02, +0x50, 0xbc, 0x00, 0x02, 0x51, 0x10, 0x00, 0x02, 0x51, 0x40, +0x00, 0x02, 0x51, 0x70, 0x00, 0x02, 0x51, 0xa4, 0x00, 0x02, +0x51, 0xd8, 0x00, 0x02, 0x52, 0x0c, 0x00, 0x02, 0x52, 0x40, +0x00, 0x02, 0x52, 0x74, 0x00, 0x02, 0x52, 0xa8, 0x00, 0x02, +0x52, 0xd8, 0x00, 0x02, 0x53, 0x08, 0x00, 0x02, 0x53, 0x3c, +0x00, 0x02, 0x53, 0x70, 0x00, 0x02, 0x53, 0xa4, 0x00, 0x02, +0x53, 0xd8, 0x00, 0x02, 0x54, 0x0c, 0x00, 0x02, 0x54, 0x40, +0x00, 0x02, 0x54, 0x70, 0x00, 0x02, 0x54, 0xa0, 0x00, 0x02, +0x54, 0xd4, 0x00, 0x02, 0x55, 0x08, 0x00, 0x02, 0x55, 0x3c, +0x00, 0x02, 0x55, 0x70, 0x00, 0x02, 0x55, 0xa4, 0x00, 0x02, +0x55, 0xd8, 0x00, 0x02, 0x55, 0xfc, 0x00, 0x02, 0x56, 0x20, +0x00, 0x02, 0x56, 0x44, 0x00, 0x02, 0x57, 0x30, 0x00, 0x02, +0x58, 0xb0, 0x00, 0x02, 0x61, 0x30, 0x00, 0x02, 0x61, 0xe0, +0x00, 0x02, 0x62, 0x04, 0x00, 0x02, 0x62, 0x34, 0x00, 0x02, +0x62, 0x64, 0x00, 0x02, 0x62, 0x94, 0x00, 0x02, 0x62, 0xbc, +0x00, 0x02, 0x62, 0xe4, 0x00, 0x02, 0x63, 0x1c, 0x00, 0x02, +0x63, 0x54, 0x00, 0x02, 0x63, 0x8c, 0x00, 0x02, 0x63, 0xc4, +0x00, 0x02, 0x64, 0x10, 0x00, 0x02, 0x64, 0x6c, 0x00, 0x02, +0x64, 0xc8, 0x00, 0x02, 0x64, 0xf8, 0x00, 0x02, 0x65, 0x48, +0x00, 0x02, 0x65, 0x98, 0x00, 0x02, 0x65, 0xe4, 0x00, 0x02, +0x66, 0x28, 0x00, 0x02, 0x66, 0x74, 0x00, 0x02, 0x66, 0xc0, +0x00, 0x02, 0x67, 0x04, 0x00, 0x02, 0x67, 0x4c, 0x00, 0x02, +0x67, 0x84, 0x00, 0x02, 0x68, 0x0c, 0x00, 0x02, 0x68, 0x70, +0x00, 0x02, 0x68, 0xd4, 0x00, 0x02, 0x69, 0x38, 0x00, 0x02, +0x69, 0x88, 0x00, 0x02, 0x69, 0xd8, 0x00, 0x02, 0x6a, 0x38, +0x00, 0x02, 0x6a, 0x88, 0x00, 0x02, 0x6a, 0xd8, 0x00, 0x02, +0x6b, 0x14, 0x00, 0x02, 0x6b, 0x60, 0x00, 0x02, 0x6b, 0xb0, +0x00, 0x02, 0x6b, 0xfc, 0x00, 0x02, 0x6c, 0x44, 0x00, 0x02, +0x6c, 0x8c, 0x00, 0x02, 0x6c, 0xd8, 0x00, 0x02, 0x6d, 0x1c, +0x00, 0x02, 0x6d, 0x64, 0x00, 0x02, 0x6d, 0x90, 0x00, 0x02, +0x6f, 0x98, 0x00, 0x02, 0x73, 0x58, 0x00, 0x02, 0x76, 0xc0, +0x00, 0x02, 0x77, 0x30, 0x00, 0x02, 0x77, 0x9c, 0x00, 0x02, +0x00, 0x32, 0x00, 0x00, 0x01, 0xc2, 0x02, 0xee, 0x00, 0x03, +0x00, 0x07, 0x00, 0x1b, 0x40, 0x0b, 0x04, 0x03, 0x09, 0x07, +0x00, 0x08, 0x05, 0x01, 0x04, 0x00, 0x44, 0x00, 0x3f, 0xcd, +0x2f, 0xcd, 0x01, 0x10, 0xd6, 0xcd, 0x10, 0xde, 0xcd, 0x31, +0x30, 0x33, 0x11, 0x21, 0x11, 0x27, 0x11, 0x21, 0x11, 0x32, +0x01, 0x90, 0x32, 0xfe, 0xd4, 0x02, 0xee, 0xfd, 0x12, 0x32, +0x02, 0x8a, 0xfd, 0x76, 0x00, 0x00, 0x00, 0x02, 0x00, 0xb5, +0xff, 0xf4, 0x01, 0x3b, 0x02, 0x6b, 0x00, 0x0d, 0x00, 0x19, +0x00, 0x23, 0x40, 0x11, 0x00, 0x91, 0x0b, 0x0b, 0x17, 0x94, +0x11, 0x11, 0x1b, 0x1a, 0x06, 0x14, 0x9a, 0x0e, 0x5c, 0x0c, +0x59, 0x00, 0x3f, 0x3f, 0xfd, 0xce, 0x01, 0x11, 0x12, 0x39, +0x2f, 0xed, 0x33, 0x2f, 0xed, 0x31, 0x30, 0x01, 0x14, 0x0e, +0x02, 0x07, 0x23, 0x2e, 0x03, 0x35, 0x35, 0x33, 0x03, 0x22, +0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, +0x01, 0x25, 0x02, 0x05, 0x06, 0x03, 0x39, 0x03, 0x06, 0x05, +0x02, 0x59, 0x2d, 0x1b, 0x28, 0x28, 0x1b, 0x1c, 0x27, 0x27, +0x01, 0xc3, 0x25, 0x3e, 0x38, 0x37, 0x1e, 0x1e, 0x37, 0x38, +0x3e, 0x25, 0xa8, 0xfd, 0x89, 0x25, 0x1f, 0x1f, 0x25, 0x25, +0x1f, 0x1f, 0x25, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x81, +0x01, 0xae, 0x01, 0x73, 0x02, 0xa7, 0x00, 0x09, 0x00, 0x13, +0x00, 0x15, 0xb7, 0x0a, 0x13, 0x00, 0x09, 0x0f, 0x04, 0x13, +0x00, 0x00, 0x2f, 0x32, 0xcd, 0x32, 0x01, 0x2f, 0xdd, 0xde, +0xcd, 0x31, 0x30, 0x13, 0x15, 0x14, 0x06, 0x07, 0x23, 0x26, +0x26, 0x35, 0x35, 0x33, 0x15, 0x14, 0x06, 0x07, 0x23, 0x26, +0x26, 0x35, 0x35, 0xce, 0x0a, 0x08, 0x2a, 0x07, 0x0a, 0xf2, +0x0a, 0x07, 0x2a, 0x08, 0x0a, 0x02, 0xa7, 0x2d, 0x2c, 0x71, +0x2f, 0x2f, 0x71, 0x2d, 0x2c, 0x2d, 0x2c, 0x71, 0x2f, 0x2f, +0x71, 0x2d, 0x2c, 0x00, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x00, +0x01, 0xd9, 0x02, 0x6b, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0xaf, +0x40, 0x5a, 0x0d, 0x0a, 0x09, 0x06, 0x05, 0x0e, 0x05, 0x0e, +0x91, 0x0f, 0x10, 0x1d, 0x1e, 0x03, 0x04, 0x0f, 0x04, 0x0f, +0x12, 0x14, 0x17, 0x18, 0x1b, 0x00, 0x13, 0x00, 0x02, 0x1f, +0x1c, 0x11, 0x12, 0x01, 0x12, 0x91, 0x13, 0x13, 0x16, 0x1a, +0x21, 0x00, 0x91, 0x01, 0x04, 0x91, 0x05, 0x05, 0x0b, 0x07, +0x20, 0x13, 0x59, 0x12, 0x59, 0x0f, 0x59, 0x1d, 0x1c, 0x17, +0x0a, 0x97, 0x0d, 0x14, 0x11, 0x10, 0x0d, 0x1b, 0x03, 0x02, +0x06, 0x97, 0x09, 0x1f, 0x1e, 0x18, 0x09, 0x0d, 0x09, 0x0d, +0x09, 0x05, 0x0e, 0x59, 0x05, 0x60, 0x04, 0x60, 0x01, 0x60, +0x00, 0x60, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x12, 0x39, +0x39, 0x2f, 0x2f, 0x11, 0x33, 0x33, 0x33, 0x10, 0xed, 0x32, +0x32, 0x32, 0x11, 0x33, 0x33, 0x33, 0x10, 0xed, 0x32, 0x32, +0x32, 0x3f, 0x3f, 0x3f, 0x01, 0x10, 0xc6, 0x32, 0x32, 0x2f, +0xfd, 0xde, 0xed, 0x10, 0xce, 0x32, 0x32, 0x2f, 0xfd, 0x7d, +0x87, 0xc4, 0xc4, 0xc4, 0xc4, 0x10, 0x87, 0xc4, 0xc4, 0xc4, +0xc4, 0x01, 0x18, 0x10, 0xce, 0x10, 0x7d, 0x87, 0xc4, 0xc4, +0xc4, 0xc4, 0x01, 0x18, 0x10, 0xed, 0x10, 0x7d, 0x87, 0xc4, +0xc4, 0xc4, 0xc4, 0x31, 0x30, 0x21, 0x23, 0x37, 0x23, 0x07, +0x23, 0x37, 0x23, 0x35, 0x33, 0x37, 0x23, 0x35, 0x33, 0x37, +0x33, 0x07, 0x33, 0x37, 0x33, 0x07, 0x33, 0x15, 0x23, 0x07, +0x33, 0x15, 0x23, 0x27, 0x23, 0x07, 0x33, 0x01, 0x41, 0x4b, +0x1f, 0x6f, 0x1f, 0x4b, 0x1f, 0x40, 0x4d, 0x1e, 0x6b, 0x79, +0x1f, 0x4b, 0x1f, 0x6f, 0x1e, 0x4b, 0x1e, 0x40, 0x4d, 0x1f, +0x6c, 0x79, 0x20, 0x6e, 0x1f, 0x6e, 0xa3, 0xa3, 0xa3, 0x43, +0x9f, 0x42, 0xa4, 0xa4, 0xa4, 0xa4, 0x42, 0x9f, 0x43, 0xe2, +0x9f, 0x00, 0x00, 0x01, 0x00, 0x36, 0xff, 0x9f, 0x01, 0xbf, +0x02, 0xb5, 0x00, 0x35, 0x00, 0xb3, 0x40, 0x11, 0x31, 0x18, +0x12, 0x00, 0x4d, 0x31, 0x20, 0x0f, 0x11, 0x00, 0x4c, 0x31, +0x28, 0x0e, 0x00, 0x4d, 0x2b, 0xb8, 0xff, 0xe8, 0xb4, 0x0b, +0x0c, 0x00, 0x4c, 0x2a, 0xb8, 0xff, 0xd8, 0xb4, 0x09, 0x0a, +0x00, 0x4c, 0x27, 0xb8, 0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, +0x27, 0xb8, 0xff, 0xe8, 0xb4, 0x0d, 0x0e, 0x00, 0x4c, 0x26, +0xb8, 0xff, 0xf0, 0xb3, 0x10, 0x00, 0x4d, 0x22, 0xb8, 0xff, +0xe8, 0x40, 0x3c, 0x0f, 0x00, 0x4d, 0x11, 0x28, 0x09, 0x0a, +0x00, 0x4c, 0x0d, 0x20, 0x10, 0x00, 0x4d, 0x09, 0x20, 0x0a, +0x00, 0x4d, 0x15, 0x2c, 0x8b, 0x12, 0x2f, 0x2f, 0x0f, 0x29, +0x18, 0x18, 0x05, 0x8c, 0x29, 0x37, 0x32, 0x32, 0x1f, 0x8c, +0x0f, 0x36, 0x0a, 0x2f, 0x1c, 0x24, 0x15, 0x33, 0x33, 0x00, +0x8f, 0x2c, 0x2f, 0x2e, 0x2e, 0x36, 0x19, 0x19, 0x1c, 0x8f, +0x12, 0x15, 0x13, 0x00, 0x2f, 0xdd, 0x32, 0xed, 0x32, 0x2f, +0x11, 0x33, 0x2f, 0xdd, 0x32, 0xed, 0x32, 0x2f, 0x11, 0x39, +0x11, 0x12, 0x39, 0x01, 0x10, 0xd6, 0xed, 0x33, 0x2f, 0x10, +0xde, 0xed, 0x33, 0x2f, 0x11, 0x12, 0x39, 0x2f, 0x33, 0xed, +0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x37, 0x32, 0x3e, 0x02, 0x35, +0x34, 0x2e, 0x02, 0x27, 0x2e, 0x03, 0x35, 0x34, 0x36, 0x37, +0x35, 0x33, 0x15, 0x16, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, +0x22, 0x06, 0x15, 0x14, 0x1e, 0x02, 0x17, 0x1e, 0x03, 0x15, +0x14, 0x06, 0x07, 0x15, 0x23, 0x35, 0x26, 0x26, 0x27, 0x37, +0x16, 0x16, 0xe9, 0x24, 0x31, 0x1c, 0x0c, 0x18, 0x29, 0x34, +0x1c, 0x1b, 0x35, 0x29, 0x1a, 0x4c, 0x48, 0x4a, 0x28, 0x43, +0x14, 0x11, 0x15, 0x40, 0x31, 0x36, 0x39, 0x11, 0x20, 0x2b, +0x1b, 0x22, 0x40, 0x30, 0x1d, 0x4e, 0x51, 0x4a, 0x3f, 0x4e, +0x13, 0x16, 0x1b, 0x4a, 0x55, 0x0b, 0x15, 0x1d, 0x11, 0x19, +0x23, 0x1b, 0x15, 0x0a, 0x0a, 0x18, 0x23, 0x31, 0x24, 0x40, +0x50, 0x0b, 0x67, 0x64, 0x02, 0x0f, 0x08, 0x46, 0x08, 0x11, +0x28, 0x26, 0x15, 0x1c, 0x16, 0x12, 0x0a, 0x0d, 0x1d, 0x28, +0x38, 0x27, 0x3b, 0x52, 0x0a, 0x73, 0x70, 0x02, 0x18, 0x0b, +0x45, 0x0d, 0x17, 0x00, 0x00, 0x05, 0x00, 0x12, 0xff, 0xf3, +0x01, 0xe2, 0x02, 0x78, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x1b, +0x00, 0x27, 0x00, 0x33, 0x00, 0x77, 0x40, 0x48, 0xe0, 0x1c, +0xf0, 0x1c, 0x02, 0x1c, 0xef, 0x2e, 0xff, 0x2e, 0x02, 0x2e, +0xe0, 0x28, 0xf0, 0x28, 0x02, 0x28, 0x22, 0x00, 0x02, 0x01, +0x02, 0x8d, 0x03, 0x00, 0x14, 0x03, 0x00, 0x03, 0x03, 0x22, +0x35, 0xef, 0x0a, 0xff, 0x0a, 0x02, 0x0a, 0xe0, 0x10, 0xf0, +0x10, 0x02, 0x10, 0xef, 0x16, 0xff, 0x16, 0x02, 0x16, 0x04, +0x01, 0x01, 0x04, 0x34, 0x2b, 0x1f, 0x31, 0x25, 0x57, 0x19, +0x0d, 0x13, 0x07, 0x58, 0x02, 0x03, 0x56, 0x00, 0x01, 0x55, +0x00, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0xcd, 0xdc, 0xcd, 0x3f, +0xcd, 0xdc, 0xcd, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xdd, +0x5d, 0xde, 0x5d, 0xcd, 0x5d, 0x10, 0xce, 0x32, 0x2f, 0x87, +0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, 0x10, 0xdd, 0x5d, 0xde, +0x5d, 0xcd, 0x5d, 0x31, 0x30, 0x33, 0x23, 0x01, 0x33, 0x05, +0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, +0x26, 0x37, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, +0x33, 0x32, 0x36, 0x13, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, +0x14, 0x06, 0x23, 0x22, 0x26, 0x37, 0x34, 0x26, 0x23, 0x22, +0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x5f, 0x46, 0x01, +0x7b, 0x46, 0xfe, 0x38, 0x3a, 0x33, 0x33, 0x3a, 0x3a, 0x33, +0x33, 0x3a, 0x9c, 0x18, 0x17, 0x17, 0x19, 0x19, 0x17, 0x17, +0x18, 0x5b, 0x39, 0x33, 0x33, 0x3a, 0x3a, 0x33, 0x33, 0x39, +0x9c, 0x19, 0x17, 0x17, 0x18, 0x18, 0x17, 0x17, 0x19, 0x02, +0x6b, 0x8e, 0x4c, 0x4f, 0x4f, 0x4c, 0x4c, 0x50, 0x50, 0x4c, +0x2d, 0x3a, 0x3a, 0x2d, 0x2d, 0x3a, 0x3a, 0xfe, 0xde, 0x4c, +0x4f, 0x4f, 0x4c, 0x4c, 0x4f, 0x4f, 0x4c, 0x2d, 0x3a, 0x3a, +0x2d, 0x2d, 0x3a, 0x3a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x1f, +0xff, 0xf8, 0x01, 0xd9, 0x02, 0x79, 0x00, 0x2b, 0x00, 0x36, +0x00, 0x42, 0x01, 0x0c, 0xb6, 0x41, 0x20, 0x11, 0x12, 0x00, +0x4c, 0x31, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, 0x31, +0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x31, 0xb8, 0xff, +0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x2d, 0xb8, 0xff, 0xe8, 0x40, +0x09, 0x0f, 0x00, 0x4d, 0x2c, 0x08, 0x08, 0x00, 0x4d, 0x26, +0xb8, 0xff, 0xe8, 0x40, 0x1f, 0x09, 0x0d, 0x00, 0x4c, 0x20, +0x18, 0x0c, 0x00, 0x4d, 0x20, 0x10, 0x0b, 0x00, 0x4d, 0x20, +0x18, 0x09, 0x0a, 0x00, 0x4c, 0x1a, 0x18, 0x11, 0x00, 0x4d, +0x1a, 0x30, 0x08, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xd8, 0xb3, +0x10, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, +0x4d, 0x02, 0xb8, 0xff, 0xd0, 0xb3, 0x12, 0x00, 0x4d, 0x02, +0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x02, 0xb8, 0xff, +0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xf0, 0xb3, +0x0e, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, +0x4d, 0x01, 0xb8, 0xff, 0xe8, 0x40, 0x3c, 0x11, 0x00, 0x4d, +0x37, 0x76, 0x28, 0x28, 0x07, 0x10, 0x34, 0x2c, 0x1b, 0x04, +0x1e, 0x0e, 0x76, 0x0a, 0x03, 0x2b, 0x40, 0x04, 0x3d, 0x0d, +0x0d, 0x06, 0x73, 0x07, 0x44, 0x3d, 0x76, 0x1e, 0x1e, 0x2f, +0x76, 0x18, 0x43, 0x40, 0x2c, 0x1b, 0x2b, 0x10, 0x0a, 0x03, +0x34, 0x2b, 0x34, 0x06, 0x06, 0x32, 0x3a, 0x7c, 0x23, 0x45, +0x32, 0x7c, 0x13, 0x46, 0x0d, 0x0e, 0x42, 0x00, 0x3f, 0x33, +0x3f, 0xed, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0x39, 0x39, 0x11, +0x33, 0x33, 0x33, 0x11, 0x33, 0x33, 0x33, 0x01, 0x10, 0xd6, +0xed, 0x33, 0x2f, 0xed, 0x10, 0xde, 0xed, 0x33, 0x2f, 0x12, +0x17, 0x39, 0xed, 0x11, 0x17, 0x39, 0x11, 0x33, 0x2f, 0xed, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x01, 0x16, 0x16, 0x17, 0x36, 0x36, 0x37, 0x17, +0x06, 0x06, 0x07, 0x16, 0x16, 0x17, 0x23, 0x26, 0x27, 0x06, +0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x36, 0x37, 0x26, +0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, +0x14, 0x06, 0x07, 0x07, 0x06, 0x06, 0x15, 0x14, 0x16, 0x16, +0x36, 0x37, 0x26, 0x26, 0x37, 0x34, 0x26, 0x23, 0x22, 0x06, +0x15, 0x14, 0x16, 0x17, 0x36, 0x36, 0x01, 0x10, 0x11, 0x25, +0x13, 0x08, 0x0c, 0x03, 0x45, 0x06, 0x17, 0x11, 0x17, 0x2a, +0x11, 0x57, 0x11, 0x15, 0x20, 0x4f, 0x2b, 0x26, 0x3c, 0x2a, +0x17, 0x31, 0x35, 0x1a, 0x20, 0x19, 0x2a, 0x37, 0x1d, 0x1a, +0x32, 0x26, 0x17, 0x3c, 0x41, 0x42, 0x1d, 0x1d, 0x28, 0x3a, +0x44, 0x1c, 0x21, 0x47, 0x54, 0x27, 0x19, 0x1a, 0x2d, 0x12, +0x1d, 0x30, 0x28, 0x01, 0x1b, 0x14, 0x29, 0x17, 0x1c, 0x42, +0x28, 0x09, 0x3a, 0x5b, 0x25, 0x20, 0x44, 0x26, 0x23, 0x20, +0x28, 0x23, 0x19, 0x2c, 0x3a, 0x20, 0x2f, 0x60, 0x29, 0x23, +0x48, 0x26, 0x27, 0x3a, 0x25, 0x13, 0x10, 0x21, 0x30, 0x1f, +0x2e, 0x61, 0x29, 0x24, 0x1a, 0x44, 0x20, 0x27, 0x33, 0x0d, +0x1d, 0x28, 0x2d, 0x4d, 0xf9, 0x24, 0x24, 0x29, 0x29, 0x1d, +0x32, 0x26, 0x1e, 0x44, 0x00, 0x01, 0x00, 0xce, 0x01, 0x9c, +0x01, 0x25, 0x02, 0xa7, 0x00, 0x0d, 0x00, 0x14, 0xb7, 0x01, +0x91, 0x0c, 0x0c, 0x0f, 0x0e, 0x07, 0x0d, 0x00, 0x2f, 0xcd, +0x01, 0x11, 0x12, 0x39, 0x2f, 0xed, 0x31, 0x30, 0x01, 0x15, +0x14, 0x0e, 0x02, 0x07, 0x23, 0x2e, 0x03, 0x35, 0x35, 0x01, +0x25, 0x03, 0x05, 0x06, 0x04, 0x33, 0x04, 0x06, 0x05, 0x03, +0x02, 0xa7, 0x2d, 0x16, 0x39, 0x3d, 0x3b, 0x17, 0x17, 0x3b, +0x3d, 0x3a, 0x16, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x71, +0xff, 0x59, 0x01, 0x82, 0x02, 0xbd, 0x00, 0x10, 0x00, 0x7f, +0xb9, 0x00, 0x07, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, 0x07, +0xb8, 0xff, 0xf0, 0xb3, 0x11, 0x00, 0x4d, 0x06, 0xb8, 0xff, +0xe0, 0xb3, 0x11, 0x00, 0x4d, 0x06, 0xb8, 0xff, 0xe0, 0xb3, +0x0e, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, +0x4d, 0x01, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x01, +0xb8, 0xff, 0xf0, 0xb3, 0x0e, 0x00, 0x4d, 0x0e, 0xb8, 0xff, +0xf0, 0x40, 0x09, 0x0d, 0x00, 0x4d, 0x0a, 0x18, 0x0d, 0x00, +0x4d, 0x05, 0xb8, 0xff, 0xe8, 0x40, 0x15, 0x0f, 0x00, 0x4d, +0x02, 0x20, 0x0f, 0x00, 0x4d, 0x0f, 0x09, 0x09, 0x00, 0x08, +0x03, 0x0c, 0x11, 0x00, 0x0f, 0x5a, 0x08, 0x09, 0x00, 0x2f, +0x33, 0x3f, 0x33, 0x01, 0x10, 0xd6, 0xdd, 0xce, 0x32, 0x32, +0x11, 0x33, 0x31, 0x30, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x06, 0x06, +0x15, 0x14, 0x1e, 0x02, 0x17, 0x07, 0x26, 0x26, 0x35, 0x34, +0x36, 0x37, 0x17, 0x01, 0x80, 0x5d, 0x62, 0x17, 0x2f, 0x49, +0x32, 0x2d, 0x73, 0x71, 0x72, 0x72, 0x2c, 0x02, 0x81, 0x48, +0xbc, 0x6f, 0x38, 0x64, 0x5c, 0x56, 0x2b, 0x3c, 0x55, 0xe1, +0x7d, 0x7c, 0xe2, 0x53, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x71, 0xff, 0x59, 0x01, 0x82, 0x02, 0xbd, 0x00, 0x12, +0x00, 0x58, 0xb9, 0x00, 0x0f, 0xff, 0xf0, 0xb3, 0x0d, 0x00, +0x4d, 0x0a, 0xb8, 0xff, 0xf0, 0x40, 0x2f, 0x0d, 0x00, 0x4d, +0x07, 0x18, 0x11, 0x00, 0x4d, 0x06, 0x18, 0x12, 0x00, 0x4d, +0x05, 0x10, 0x0f, 0x00, 0x4d, 0x02, 0x10, 0x0f, 0x00, 0x4d, +0x01, 0x10, 0x11, 0x12, 0x00, 0x4c, 0x07, 0x18, 0x12, 0x00, +0x4d, 0x11, 0x09, 0x09, 0x12, 0x08, 0x03, 0x0c, 0x14, 0x00, +0x11, 0x08, 0x09, 0x5a, 0x00, 0x3f, 0x33, 0x2f, 0x33, 0x01, +0x10, 0xd6, 0xdd, 0xce, 0x32, 0x32, 0x11, 0x33, 0x31, 0x30, +0x00, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x17, 0x36, 0x36, 0x35, 0x34, 0x2e, 0x02, 0x27, 0x37, 0x16, +0x16, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x27, 0x73, 0x5d, 0x63, +0x17, 0x30, 0x49, 0x32, 0x2d, 0x73, 0x71, 0x1d, 0x39, 0x55, +0x39, 0x2c, 0x6b, 0x48, 0xbc, 0x6f, 0x38, 0x64, 0x5c, 0x56, +0x2b, 0x3c, 0x55, 0xe1, 0x7d, 0x3e, 0x78, 0x6f, 0x63, 0x29, +0x3c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x39, 0x00, 0xfa, +0x01, 0xbb, 0x02, 0x6b, 0x00, 0x2c, 0x00, 0x33, 0x40, 0x17, +0x29, 0x20, 0x04, 0x04, 0x20, 0x16, 0x1f, 0x0e, 0x0e, 0x1f, +0x1f, 0x2e, 0x2d, 0x29, 0x09, 0x16, 0x28, 0x17, 0x17, 0x05, +0x0d, 0x1f, 0x59, 0x00, 0x3f, 0xcc, 0x32, 0x39, 0x2f, 0x33, +0xcd, 0x32, 0x32, 0x01, 0x11, 0x12, 0x39, 0x2f, 0x33, 0x2f, +0x10, 0xcc, 0xcd, 0x32, 0x2f, 0x10, 0xcc, 0x31, 0x30, 0x01, +0x16, 0x16, 0x17, 0x17, 0x07, 0x27, 0x26, 0x26, 0x27, 0x06, +0x06, 0x07, 0x07, 0x27, 0x37, 0x36, 0x36, 0x37, 0x26, 0x26, +0x27, 0x27, 0x37, 0x17, 0x16, 0x16, 0x17, 0x26, 0x26, 0x35, +0x35, 0x33, 0x15, 0x14, 0x06, 0x07, 0x36, 0x36, 0x37, 0x37, +0x17, 0x07, 0x06, 0x06, 0x01, 0x1f, 0x1b, 0x3a, 0x14, 0x04, +0x46, 0x05, 0x15, 0x22, 0x0f, 0x10, 0x22, 0x17, 0x05, 0x45, +0x05, 0x16, 0x38, 0x1b, 0x25, 0x4e, 0x23, 0x07, 0x1b, 0x07, +0x23, 0x47, 0x20, 0x08, 0x0d, 0x56, 0x0d, 0x08, 0x20, 0x46, +0x23, 0x07, 0x1a, 0x06, 0x24, 0x4d, 0x01, 0xa1, 0x19, 0x37, +0x1f, 0x05, 0x33, 0x06, 0x1e, 0x47, 0x21, 0x21, 0x47, 0x1e, +0x05, 0x32, 0x06, 0x1f, 0x36, 0x19, 0x05, 0x0b, 0x0c, 0x02, +0x52, 0x03, 0x0e, 0x22, 0x12, 0x24, 0x4e, 0x26, 0x07, 0x07, +0x26, 0x4e, 0x24, 0x13, 0x21, 0x0d, 0x03, 0x52, 0x02, 0x0b, +0x0c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x2b, +0x01, 0xc7, 0x01, 0xe2, 0x00, 0x0b, 0x00, 0x24, 0x40, 0x0f, +0x06, 0x04, 0x07, 0x0b, 0x01, 0x0a, 0x0a, 0x0d, 0x0c, 0x04, +0x02, 0x01, 0x09, 0x07, 0x0a, 0x00, 0x2f, 0x33, 0xcd, 0xdd, +0xcd, 0x33, 0x01, 0x11, 0x12, 0x39, 0x2f, 0x33, 0xcd, 0xdd, +0x32, 0xcd, 0x31, 0x30, 0x13, 0x33, 0x35, 0x33, 0x15, 0x33, +0x15, 0x23, 0x15, 0x23, 0x35, 0x23, 0x2e, 0xa8, 0x48, 0xa9, +0xa9, 0x48, 0xa8, 0x01, 0x2a, 0xb8, 0xb8, 0x46, 0xb9, 0xb9, +0x00, 0x01, 0x00, 0x95, 0xff, 0x70, 0x01, 0x5f, 0x00, 0x8b, +0x00, 0x13, 0x00, 0x1f, 0x40, 0x0e, 0x05, 0x0e, 0x94, 0x00, +0x08, 0x08, 0x15, 0x14, 0x00, 0x13, 0x0b, 0x9a, 0x05, 0x5c, +0x00, 0x3f, 0xed, 0xdc, 0xcd, 0x01, 0x11, 0x12, 0x39, 0x2f, +0xce, 0xed, 0x39, 0x31, 0x30, 0x17, 0x3e, 0x03, 0x37, 0x26, +0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, +0x02, 0x07, 0x95, 0x12, 0x23, 0x1e, 0x18, 0x07, 0x20, 0x1d, +0x2d, 0x1d, 0x25, 0x26, 0x17, 0x2f, 0x46, 0x30, 0x4f, 0x04, +0x08, 0x0f, 0x17, 0x14, 0x03, 0x2b, 0x15, 0x28, 0x29, 0x35, +0x26, 0x1d, 0x3f, 0x37, 0x27, 0x06, 0x00, 0x01, 0x00, 0x8c, +0x00, 0xd7, 0x01, 0x68, 0x01, 0x25, 0x00, 0x03, 0x00, 0x0d, +0xb3, 0x02, 0x03, 0x00, 0x03, 0x00, 0x2f, 0xcd, 0x01, 0x2f, +0xcd, 0x31, 0x30, 0x13, 0x33, 0x15, 0x23, 0x8c, 0xdc, 0xdc, +0x01, 0x25, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb1, +0xff, 0xf4, 0x01, 0x44, 0x00, 0x8d, 0x00, 0x0b, 0x00, 0x10, +0xb6, 0x00, 0x94, 0x06, 0x09, 0x9a, 0x03, 0x5c, 0x00, 0x3f, +0xed, 0x01, 0x2f, 0xed, 0x31, 0x30, 0x25, 0x14, 0x06, 0x23, +0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x01, 0x44, +0x28, 0x21, 0x22, 0x28, 0x28, 0x22, 0x21, 0x28, 0x40, 0x1e, +0x2e, 0x2e, 0x1e, 0x1f, 0x2e, 0x2e, 0x00, 0x01, 0x00, 0x45, +0xff, 0x5b, 0x01, 0xaf, 0x02, 0xbb, 0x00, 0x03, 0x00, 0x23, +0x40, 0x11, 0x02, 0x00, 0x03, 0x00, 0x8d, 0x01, 0x02, 0x14, +0x01, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, +0x2f, 0x33, 0x2f, 0x33, 0x01, 0x2f, 0x2f, 0x87, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x31, 0x30, 0x17, 0x23, 0x01, 0x33, 0x9a, +0x55, 0x01, 0x17, 0x53, 0xa5, 0x03, 0x60, 0x00, 0x00, 0x00, +0x00, 0x03, 0x00, 0x2e, 0xff, 0xf3, 0x01, 0xc6, 0x02, 0x79, +0x00, 0x0b, 0x00, 0x17, 0x00, 0x2b, 0x00, 0xf6, 0xb6, 0x29, +0x10, 0x0d, 0x0e, 0x00, 0x4c, 0x25, 0xb8, 0xff, 0xe8, 0xb3, +0x0e, 0x00, 0x4d, 0x25, 0xb8, 0xff, 0xf0, 0xb3, 0x0d, 0x00, +0x4d, 0x1f, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x1f, +0xb8, 0xff, 0xf0, 0x40, 0x14, 0x0d, 0x00, 0x4d, 0x1b, 0x10, +0x0d, 0x0e, 0x00, 0x4c, 0x16, 0x18, 0x10, 0x00, 0x4d, 0x16, +0x20, 0x0f, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xe8, 0xb4, 0x0f, +0x10, 0x00, 0x4c, 0x10, 0xb8, 0xff, 0xf0, 0xb3, 0x10, 0x00, +0x4d, 0x10, 0xb8, 0xff, 0xd0, 0x40, 0x0e, 0x0f, 0x00, 0x4d, +0x0e, 0x18, 0x10, 0x00, 0x4d, 0x0e, 0x10, 0x0f, 0x00, 0x4d, +0x08, 0xb8, 0xff, 0xf0, 0xb3, 0x22, 0x00, 0x4d, 0x08, 0xb8, +0xff, 0xf0, 0xb3, 0x1e, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xe8, +0xb4, 0x1b, 0x1d, 0x00, 0x4c, 0x00, 0xb8, 0xff, 0xc0, 0x40, +0x27, 0x1b, 0x1c, 0x00, 0x4c, 0x90, 0x00, 0x01, 0x50, 0x00, +0x80, 0x00, 0x90, 0x00, 0xc0, 0x00, 0xe0, 0x00, 0xf0, 0x00, +0x06, 0x00, 0x40, 0x09, 0x0c, 0x48, 0x00, 0x8f, 0x06, 0x9f, +0x06, 0xcf, 0x06, 0x03, 0x06, 0x40, 0x1b, 0x1e, 0x48, 0x06, +0xb8, 0xff, 0xc0, 0x40, 0x20, 0x09, 0x0c, 0x48, 0x06, 0x06, +0x22, 0x18, 0x8c, 0x12, 0x2d, 0x22, 0x8c, 0x0c, 0x2c, 0x3f, +0x03, 0x01, 0x03, 0xa0, 0x09, 0x01, 0x09, 0x09, 0x0f, 0x27, +0x8f, 0x15, 0x57, 0x1d, 0x8f, 0x0f, 0x58, 0x00, 0x3f, 0xed, +0x3f, 0xed, 0x11, 0x39, 0x2f, 0x5d, 0xcd, 0x5d, 0x01, 0x10, +0xd6, 0xed, 0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, 0x2b, 0x2b, +0x5d, 0xcd, 0x2b, 0x5d, 0x71, 0x2b, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x14, 0x06, 0x23, 0x22, 0x26, +0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x05, 0x34, 0x36, 0x33, +0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x25, 0x34, +0x2e, 0x02, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, +0x33, 0x32, 0x3e, 0x02, 0x01, 0x34, 0x1f, 0x19, 0x1a, 0x20, +0x20, 0x1a, 0x19, 0x1f, 0xfe, 0xfa, 0x6b, 0x61, 0x62, 0x6a, +0x6a, 0x62, 0x61, 0x6b, 0x01, 0x44, 0x0c, 0x1c, 0x2e, 0x22, +0x22, 0x2e, 0x1c, 0x0c, 0x0c, 0x1c, 0x2e, 0x22, 0x22, 0x2e, +0x1c, 0x0c, 0x01, 0x41, 0x1a, 0x26, 0x26, 0x1a, 0x1a, 0x28, +0x28, 0x25, 0x9c, 0xa7, 0xa7, 0x9c, 0x9c, 0xa7, 0xa7, 0x9c, +0x33, 0x5b, 0x44, 0x28, 0x28, 0x44, 0x5b, 0x33, 0x33, 0x5b, +0x44, 0x28, 0x28, 0x44, 0x5b, 0x00, 0x00, 0x01, 0x00, 0x4b, +0x00, 0x00, 0x01, 0xb6, 0x02, 0x6b, 0x00, 0x10, 0x00, 0x42, +0x40, 0x26, 0x02, 0x18, 0x0c, 0x00, 0x4d, 0x01, 0x28, 0x12, +0x00, 0x4d, 0x01, 0x20, 0x0d, 0x00, 0x4d, 0x00, 0x00, 0x09, +0x0a, 0x06, 0x05, 0x8b, 0x03, 0x0a, 0x0a, 0x12, 0x11, 0x05, +0x0a, 0x8e, 0x08, 0x55, 0x00, 0x10, 0x10, 0x0b, 0x03, 0x56, +0x00, 0x3f, 0x33, 0x33, 0x2f, 0xcd, 0x3f, 0xed, 0x32, 0x01, +0x11, 0x12, 0x39, 0x2f, 0x33, 0xfd, 0xcd, 0x10, 0xcd, 0x32, +0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x13, 0x36, 0x36, 0x37, +0x33, 0x11, 0x33, 0x15, 0x21, 0x35, 0x33, 0x11, 0x0e, 0x03, +0x07, 0x4b, 0x33, 0x60, 0x29, 0x3a, 0x75, 0xfe, 0xb3, 0x86, +0x0b, 0x1f, 0x25, 0x28, 0x13, 0x01, 0xeb, 0x14, 0x3d, 0x2f, +0xfd, 0xdb, 0x46, 0x46, 0x01, 0xb2, 0x0a, 0x15, 0x14, 0x12, +0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x39, 0x00, 0x00, +0x01, 0xbd, 0x02, 0x79, 0x00, 0x2c, 0x00, 0x90, 0xb9, 0x00, +0x2c, 0xff, 0xf0, 0xb4, 0x0b, 0x0c, 0x00, 0x4c, 0x2c, 0xb8, +0xff, 0xe0, 0x40, 0x0b, 0x09, 0x0a, 0x00, 0x4c, 0x27, 0x18, +0x09, 0x0a, 0x00, 0x4c, 0x22, 0xb8, 0xff, 0xe0, 0x40, 0x0f, +0x12, 0x00, 0x4d, 0x1d, 0x18, 0x11, 0x12, 0x00, 0x4c, 0x16, +0x08, 0x0f, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb3, 0x0f, +0x00, 0x4d, 0x03, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, +0x03, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x02, 0xb8, +0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe8, +0x40, 0x1b, 0x11, 0x00, 0x4d, 0x1a, 0x8c, 0x00, 0x0b, 0x0b, +0x00, 0x2e, 0x0a, 0x8c, 0x0f, 0x2d, 0x25, 0x25, 0x10, 0x24, +0x24, 0x1f, 0x8f, 0x2a, 0x58, 0x0a, 0x8e, 0x0d, 0x55, 0x00, +0x3f, 0xed, 0x3f, 0xed, 0x32, 0x2f, 0x01, 0x2f, 0x33, 0x2f, +0x10, 0xd6, 0xed, 0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x01, 0x14, 0x0e, 0x02, 0x07, 0x0e, 0x03, 0x15, +0x21, 0x15, 0x21, 0x26, 0x34, 0x35, 0x34, 0x3e, 0x02, 0x37, +0x3e, 0x03, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x0e, 0x02, +0x07, 0x27, 0x3e, 0x03, 0x33, 0x32, 0x16, 0x01, 0xa4, 0x19, +0x29, 0x34, 0x1b, 0x0f, 0x28, 0x24, 0x18, 0x01, 0x1d, 0xfe, +0x89, 0x01, 0x1c, 0x2c, 0x37, 0x1b, 0x16, 0x29, 0x1f, 0x13, +0x11, 0x1d, 0x26, 0x16, 0x1a, 0x2b, 0x21, 0x18, 0x06, 0x29, +0x08, 0x20, 0x2d, 0x38, 0x20, 0x61, 0x5d, 0x01, 0xcd, 0x20, +0x3c, 0x3a, 0x38, 0x1b, 0x0f, 0x2a, 0x2c, 0x2a, 0x0f, 0x46, +0x05, 0x0b, 0x05, 0x2a, 0x48, 0x40, 0x39, 0x1b, 0x16, 0x2a, +0x2a, 0x2d, 0x18, 0x1b, 0x26, 0x19, 0x0c, 0x0e, 0x14, 0x13, +0x06, 0x3a, 0x09, 0x1a, 0x17, 0x10, 0x59, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x3b, 0xff, 0xf3, 0x01, 0xba, 0x02, 0x79, +0x00, 0x32, 0x00, 0xf4, 0xb5, 0x2e, 0x28, 0x12, 0x00, 0x4d, +0x27, 0xb8, 0xff, 0xd8, 0xb3, 0x12, 0x00, 0x4d, 0x27, 0xb8, +0xff, 0xd0, 0xb3, 0x11, 0x00, 0x4d, 0x27, 0xb8, 0xff, 0xe8, +0xb4, 0x09, 0x0a, 0x00, 0x4c, 0x27, 0xb8, 0xff, 0xd8, 0xb3, +0x08, 0x00, 0x4d, 0x24, 0xb8, 0xff, 0xd8, 0xb4, 0x11, 0x12, +0x00, 0x4c, 0x21, 0xb8, 0xff, 0xe0, 0xb4, 0x11, 0x12, 0x00, +0x4c, 0x1d, 0xb8, 0xff, 0xd0, 0xb3, 0x12, 0x00, 0x4d, 0x1d, +0xb8, 0xff, 0xe0, 0xb3, 0x11, 0x00, 0x4d, 0x1d, 0xb8, 0xff, +0xe0, 0xb4, 0x08, 0x0a, 0x00, 0x4c, 0x1c, 0xb8, 0xff, 0xe8, +0xb3, 0x12, 0x00, 0x4d, 0x1c, 0xb8, 0xff, 0xe0, 0xb3, 0x11, +0x00, 0x4d, 0x15, 0xb8, 0xff, 0xf0, 0x40, 0x28, 0x12, 0x00, +0x4d, 0x0e, 0x18, 0x0f, 0x10, 0x00, 0x4c, 0x05, 0x18, 0x10, +0x00, 0x4d, 0x05, 0x10, 0x0f, 0x00, 0x4d, 0x05, 0x10, 0x0d, +0x00, 0x4d, 0x01, 0x20, 0x10, 0x00, 0x4d, 0x2d, 0x10, 0x11, +0x00, 0x4d, 0x15, 0x10, 0x11, 0x00, 0x4d, 0x22, 0xb8, 0xff, +0xd0, 0x40, 0x29, 0x11, 0x00, 0x4d, 0x22, 0x10, 0x8c, 0x1f, +0x1f, 0x03, 0x8c, 0x25, 0x34, 0x17, 0x17, 0x09, 0x09, 0x2f, +0x33, 0x22, 0x09, 0x8e, 0x0a, 0x0a, 0x1a, 0x30, 0x30, 0x00, +0x8f, 0x2a, 0x57, 0x6f, 0x16, 0x7f, 0x16, 0x02, 0x16, 0x16, +0x13, 0x8f, 0x1a, 0x58, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x5d, +0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x2f, 0xed, 0x39, 0x01, +0x10, 0xc6, 0x32, 0x2f, 0x32, 0x2f, 0x10, 0xde, 0xed, 0x33, +0x2f, 0xed, 0x32, 0x2b, 0x31, 0x30, 0x00, 0x2b, 0x2b, 0x01, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x37, 0x32, +0x36, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x23, 0x35, 0x33, 0x32, +0x3e, 0x02, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, +0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, +0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, +0x27, 0x37, 0x16, 0x16, 0xd4, 0x4f, 0x43, 0x1c, 0x2e, 0x3c, +0x21, 0x15, 0x1d, 0x16, 0x2f, 0x27, 0x18, 0x3f, 0x2a, 0x2b, +0x3c, 0x14, 0x20, 0x15, 0x55, 0x34, 0x31, 0x46, 0x2d, 0x16, +0x33, 0x28, 0x30, 0x46, 0x1b, 0x37, 0x57, 0x3c, 0x17, 0x31, +0x2a, 0x21, 0x07, 0x10, 0x10, 0x46, 0x3c, 0x3f, 0x35, 0x22, +0x2e, 0x1c, 0x0c, 0x43, 0x09, 0x17, 0x28, 0x1f, 0x33, 0x2b, +0x19, 0x0d, 0x3f, 0x0f, 0x21, 0x18, 0x2c, 0x3b, 0x23, 0x31, +0x44, 0x12, 0x0e, 0x51, 0x43, 0x28, 0x45, 0x32, 0x1c, 0x07, +0x0b, 0x0b, 0x03, 0x47, 0x08, 0x16, 0x00, 0x00, 0x00, 0x02, +0x00, 0x24, 0x00, 0x00, 0x01, 0xd2, 0x02, 0x6b, 0x00, 0x0e, +0x00, 0x15, 0x00, 0x6d, 0x40, 0x42, 0xc2, 0x0f, 0x01, 0xd3, +0x05, 0x01, 0x03, 0xb2, 0x05, 0x01, 0x02, 0xa2, 0x05, 0x01, +0xdd, 0x14, 0x01, 0xbc, 0x14, 0xcc, 0x14, 0x02, 0xad, 0x14, +0x01, 0x05, 0x14, 0x0f, 0x14, 0x8d, 0x00, 0x05, 0x14, 0x00, +0x00, 0x05, 0x0f, 0x0d, 0x15, 0x8b, 0x0a, 0x07, 0x08, 0x17, +0x00, 0x16, 0x07, 0x00, 0x14, 0x8e, 0x0a, 0x0d, 0x0d, 0x0c, +0x55, 0xb0, 0x0f, 0xd0, 0x0f, 0x02, 0xa3, 0x0f, 0x01, 0x0f, +0x05, 0x56, 0x00, 0x3f, 0x33, 0x5d, 0x5d, 0x3f, 0x33, 0x2f, +0x33, 0xed, 0x32, 0x32, 0x01, 0x10, 0xc6, 0x10, 0xde, 0xd5, +0x32, 0xed, 0x32, 0x32, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x01, 0x5d, 0x5d, 0x5d, 0x5d, 0x5f, 0x5d, 0x5f, 0x5d, 0x31, +0x30, 0x00, 0x5d, 0x37, 0x3e, 0x03, 0x37, 0x33, 0x11, 0x33, +0x15, 0x23, 0x15, 0x23, 0x35, 0x21, 0x01, 0x0e, 0x03, 0x07, +0x33, 0x24, 0x11, 0x3b, 0x4a, 0x54, 0x2b, 0x50, 0x49, 0x49, +0x50, 0xfe, 0xeb, 0x01, 0x15, 0x1b, 0x37, 0x34, 0x2d, 0x12, +0xc5, 0xd6, 0x28, 0x68, 0x6f, 0x6b, 0x2b, 0xfe, 0x77, 0x44, +0x9e, 0x9e, 0x01, 0x6b, 0x1d, 0x46, 0x4d, 0x50, 0x27, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0xff, 0xf3, 0x01, 0xba, +0x02, 0x6b, 0x00, 0x27, 0x00, 0xb0, 0x40, 0x0c, 0x18, 0x20, +0x0d, 0x00, 0x4d, 0x0c, 0x28, 0x11, 0x12, 0x00, 0x4c, 0x06, +0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x06, 0xb8, 0xff, +0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x06, 0xb8, 0xff, 0xf0, 0xb3, +0x0e, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, +0x4d, 0x05, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x05, +0xb8, 0xff, 0xd0, 0xb3, 0x0e, 0x00, 0x4d, 0x05, 0xb8, 0xff, +0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xf0, 0xb3, +0x09, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe0, 0xb3, 0x10, 0x00, +0x4d, 0x02, 0xb8, 0xff, 0xe8, 0xb3, 0x0f, 0x00, 0x4d, 0x02, +0xb8, 0xff, 0xe0, 0x40, 0x24, 0x0e, 0x00, 0x4d, 0x22, 0x22, +0x16, 0x8c, 0x03, 0x29, 0x23, 0x00, 0x8b, 0x1b, 0x20, 0x0d, +0x0d, 0x10, 0x1b, 0x01, 0x1b, 0x28, 0x1b, 0x8f, 0x00, 0x00, +0x11, 0x23, 0x8e, 0x20, 0x56, 0x0e, 0x0e, 0x11, 0x8f, 0x08, +0x57, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x12, 0x39, +0x2f, 0xed, 0x01, 0x10, 0xc6, 0x5d, 0x32, 0x2f, 0x32, 0x10, +0xed, 0x32, 0x10, 0xde, 0xed, 0x33, 0x2f, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x13, 0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x2e, 0x02, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x3e, +0x02, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x3e, 0x03, 0x37, 0x21, +0x15, 0x23, 0x0e, 0x03, 0xba, 0x86, 0x7a, 0x1a, 0x37, 0x55, +0x3a, 0x18, 0x2f, 0x2a, 0x20, 0x07, 0x10, 0x10, 0x43, 0x33, +0x28, 0x36, 0x21, 0x0f, 0x17, 0x39, 0x63, 0x4b, 0x06, 0x07, +0x05, 0x03, 0x02, 0x01, 0x2a, 0xe2, 0x01, 0x03, 0x04, 0x04, +0x01, 0x7c, 0x05, 0x6c, 0x5b, 0x29, 0x46, 0x32, 0x1c, 0x07, +0x0a, 0x0b, 0x04, 0x47, 0x08, 0x16, 0x12, 0x1f, 0x28, 0x16, +0x22, 0x35, 0x24, 0x13, 0x2c, 0x4d, 0x49, 0x48, 0x28, 0x46, +0x0e, 0x2d, 0x32, 0x2e, 0x00, 0x02, 0x00, 0x36, 0xff, 0xf3, +0x01, 0xc1, 0x02, 0x6e, 0x00, 0x1a, 0x00, 0x2d, 0x00, 0xc9, +0xb9, 0x00, 0x24, 0xff, 0xf0, 0x40, 0x13, 0x0e, 0x00, 0x4d, +0x1a, 0x18, 0x08, 0x00, 0x4d, 0x19, 0x20, 0x10, 0x00, 0x4d, +0x19, 0x28, 0x0f, 0x00, 0x4d, 0x16, 0xb8, 0xff, 0xd8, 0xb4, +0x0f, 0x10, 0x00, 0x4c, 0x15, 0xb8, 0xff, 0xe8, 0xb3, 0x10, +0x00, 0x4d, 0x15, 0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, +0x15, 0xb8, 0xff, 0xe8, 0xb3, 0x08, 0x00, 0x4d, 0x11, 0xb8, +0xff, 0xe8, 0xb3, 0x0b, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xe8, +0xb3, 0x09, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xd8, 0xb3, 0x08, +0x00, 0x4d, 0x10, 0xb8, 0xff, 0xd8, 0xb3, 0x12, 0x00, 0x4d, +0x10, 0xb8, 0xff, 0xc0, 0xb3, 0x11, 0x00, 0x4d, 0x10, 0xb8, +0xff, 0xe8, 0xb3, 0x0c, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xe8, +0xb4, 0x0d, 0x0e, 0x00, 0x4c, 0x04, 0xb8, 0xff, 0xe0, 0x40, +0x26, 0x0e, 0x00, 0x4d, 0x03, 0x20, 0x10, 0x00, 0x4d, 0x2b, +0x8c, 0x13, 0x06, 0x06, 0x13, 0x2f, 0x0b, 0x21, 0x8c, 0x10, +0x00, 0x01, 0x00, 0x2e, 0x1e, 0x1b, 0x8f, 0x0b, 0x0e, 0x0e, +0x05, 0x26, 0x8f, 0x18, 0x57, 0x06, 0x8f, 0x05, 0x56, 0x00, +0x3f, 0xed, 0x3f, 0xed, 0x11, 0x39, 0x2f, 0x33, 0xed, 0x32, +0x01, 0x10, 0xd6, 0x5d, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, +0x10, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x37, 0x34, 0x3e, 0x02, 0x37, 0x17, 0x0e, 0x03, 0x07, +0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x26, 0x37, 0x22, 0x06, 0x07, 0x06, 0x14, 0x15, +0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x26, +0x36, 0x31, 0x5b, 0x82, 0x52, 0x07, 0x35, 0x57, 0x44, 0x2e, +0x0c, 0x18, 0x39, 0x20, 0x34, 0x49, 0x2c, 0x14, 0x16, 0x2e, +0x48, 0x32, 0x67, 0x66, 0xc5, 0x20, 0x35, 0x1b, 0x01, 0x0b, +0x1b, 0x2e, 0x24, 0x1e, 0x28, 0x1a, 0x0b, 0x37, 0xf8, 0x5a, +0x8b, 0x5e, 0x32, 0x01, 0x46, 0x01, 0x15, 0x2f, 0x4a, 0x36, +0x0b, 0x0e, 0x20, 0x35, 0x46, 0x25, 0x22, 0x47, 0x3b, 0x25, +0x8a, 0xbb, 0x0c, 0x0c, 0x0a, 0x13, 0x0b, 0x27, 0x45, 0x35, +0x1f, 0x19, 0x26, 0x2f, 0x15, 0x3d, 0x40, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x3f, 0x00, 0x00, 0x01, 0xc7, 0x02, 0x6b, +0x00, 0x0e, 0x00, 0x25, 0x40, 0x12, 0x0e, 0x8c, 0x00, 0x00, +0x06, 0x05, 0x8c, 0x09, 0x10, 0x06, 0x0f, 0x09, 0x05, 0x8e, +0x07, 0x56, 0x00, 0x55, 0x00, 0x3f, 0x3f, 0xed, 0x32, 0x01, +0x10, 0xc6, 0x10, 0xde, 0xed, 0x12, 0x39, 0x2f, 0xed, 0x31, +0x30, 0x33, 0x3e, 0x03, 0x37, 0x21, 0x35, 0x21, 0x15, 0x0e, +0x03, 0x07, 0x9b, 0x05, 0x29, 0x3a, 0x46, 0x22, 0xfe, 0xd4, +0x01, 0x88, 0x1e, 0x46, 0x3f, 0x2e, 0x06, 0x47, 0x9f, 0x95, +0x7f, 0x29, 0x48, 0x45, 0x23, 0x76, 0x93, 0xa7, 0x53, 0x00, +0x00, 0x00, 0x00, 0x03, 0x00, 0x33, 0xff, 0xf3, 0x01, 0xc1, +0x02, 0x79, 0x00, 0x1b, 0x00, 0x2b, 0x00, 0x3b, 0x01, 0x20, +0xb5, 0x3a, 0x18, 0x0e, 0x00, 0x4d, 0x38, 0xb8, 0xff, 0xe0, +0xb3, 0x0f, 0x00, 0x4d, 0x38, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, +0x00, 0x4d, 0x33, 0xb8, 0xff, 0xe0, 0x40, 0x28, 0x11, 0x12, +0x00, 0x4c, 0x2f, 0x18, 0x12, 0x00, 0x4d, 0x2f, 0x28, 0x11, +0x00, 0x4d, 0x28, 0x30, 0x0f, 0x00, 0x4d, 0x28, 0x18, 0x0a, +0x00, 0x4d, 0x28, 0x28, 0x09, 0x00, 0x4d, 0x23, 0x28, 0x12, +0x00, 0x4d, 0x23, 0x30, 0x11, 0x00, 0x4d, 0x1f, 0xb8, 0xff, +0xe0, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x1b, 0xb8, 0xff, 0xe8, +0xb3, 0x0d, 0x00, 0x4d, 0x19, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, +0x00, 0x4d, 0x15, 0xb8, 0xff, 0xe0, 0xb3, 0x0a, 0x00, 0x4d, +0x15, 0xb8, 0xff, 0xf0, 0xb3, 0x09, 0x00, 0x4d, 0x15, 0xb8, +0xff, 0xe0, 0x40, 0x33, 0x08, 0x00, 0x4d, 0x0f, 0x20, 0x0a, +0x00, 0x4d, 0x0f, 0x20, 0x08, 0x00, 0x4d, 0x0c, 0x20, 0x0d, +0x00, 0x4d, 0x0c, 0x38, 0x09, 0x0a, 0x00, 0x4c, 0x09, 0x08, +0x11, 0x12, 0x00, 0x4c, 0x06, 0x18, 0x0b, 0x00, 0x4d, 0x06, +0x20, 0x0a, 0x00, 0x4d, 0x06, 0x18, 0x09, 0x00, 0x4d, 0x06, +0x20, 0x08, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xe8, 0xb4, 0x09, +0x0a, 0x00, 0x4c, 0x01, 0xb8, 0xff, 0xe0, 0x40, 0x2c, 0x08, +0x00, 0x4d, 0x0b, 0x29, 0x0d, 0x26, 0x8c, 0x00, 0x39, 0x1a, +0x36, 0x00, 0x2c, 0x8c, 0x17, 0x17, 0x00, 0x3d, 0x36, 0x8c, +0x0d, 0x0d, 0x1c, 0x8c, 0x08, 0x3c, 0x1a, 0x39, 0x39, 0x12, +0x21, 0x0b, 0x29, 0x29, 0x03, 0x31, 0x8f, 0x12, 0x58, 0x21, +0x8f, 0x03, 0x57, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x11, 0x39, +0x11, 0x33, 0x11, 0x12, 0x39, 0x11, 0x33, 0x01, 0x10, 0xd6, +0xed, 0x33, 0x2f, 0xed, 0x10, 0xce, 0x32, 0x2f, 0xed, 0x11, +0x12, 0x39, 0x39, 0x10, 0xed, 0x11, 0x39, 0x39, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x14, +0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x36, 0x37, 0x26, +0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, +0x06, 0x07, 0x16, 0x05, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, +0x02, 0x35, 0x34, 0x26, 0x27, 0x06, 0x06, 0x13, 0x34, 0x2e, +0x02, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x16, 0x17, 0x36, +0x36, 0x01, 0xc1, 0x63, 0x65, 0x3a, 0x4c, 0x2d, 0x13, 0x3a, +0x28, 0x55, 0x1a, 0x30, 0x45, 0x2b, 0x32, 0x47, 0x2c, 0x14, +0x36, 0x23, 0x67, 0xfe, 0xc2, 0x0c, 0x1c, 0x2e, 0x21, 0x1f, +0x2d, 0x1d, 0x0e, 0x52, 0x48, 0x28, 0x2c, 0xe0, 0x0c, 0x19, +0x28, 0x1c, 0x1d, 0x27, 0x1a, 0x0b, 0x3b, 0x44, 0x26, 0x2d, +0xa1, 0x4e, 0x60, 0x1f, 0x31, 0x3c, 0x1d, 0x35, 0x52, 0x19, +0x30, 0x63, 0x22, 0x3e, 0x2e, 0x1c, 0x1e, 0x2f, 0x39, 0x1b, +0x35, 0x4d, 0x17, 0x31, 0x73, 0x10, 0x23, 0x1e, 0x13, 0x11, +0x1d, 0x24, 0x12, 0x39, 0x3d, 0x10, 0x16, 0x42, 0x01, 0x0f, +0x0d, 0x21, 0x1b, 0x13, 0x12, 0x1b, 0x21, 0x10, 0x29, 0x47, +0x10, 0x16, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, +0xff, 0xfe, 0x01, 0xbf, 0x02, 0x79, 0x00, 0x16, 0x00, 0x29, +0x00, 0xad, 0xb9, 0x00, 0x24, 0xff, 0xe8, 0xb3, 0x10, 0x00, +0x4d, 0x24, 0xb8, 0xff, 0xf0, 0x40, 0x0e, 0x0f, 0x00, 0x4d, +0x20, 0x20, 0x0f, 0x00, 0x4d, 0x20, 0x10, 0x0e, 0x00, 0x4d, +0x16, 0xb8, 0xff, 0xe8, 0xb3, 0x08, 0x00, 0x4d, 0x15, 0xb8, +0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x15, 0xb8, 0xff, 0xe8, +0x40, 0x28, 0x0a, 0x00, 0x4d, 0x11, 0x18, 0x0a, 0x00, 0x4d, +0x11, 0x18, 0x08, 0x00, 0x4d, 0x0c, 0x30, 0x12, 0x00, 0x4d, +0x0c, 0x38, 0x11, 0x00, 0x4d, 0x0c, 0x10, 0x0c, 0x00, 0x4d, +0x0c, 0x18, 0x0a, 0x0b, 0x00, 0x4c, 0x0c, 0x10, 0x09, 0x00, +0x4d, 0x02, 0xb8, 0xff, 0xd8, 0xb3, 0x10, 0x00, 0x4d, 0x02, +0xb8, 0xff, 0xe0, 0x40, 0x1e, 0x0f, 0x00, 0x4d, 0x07, 0x1d, +0x8c, 0x00, 0x2b, 0x27, 0x8c, 0x0f, 0x04, 0x04, 0x0f, 0x2a, +0x1a, 0x17, 0x8f, 0x07, 0x0a, 0x0a, 0x03, 0x22, 0x8f, 0x14, +0x58, 0x04, 0x8f, 0x03, 0x55, 0x00, 0x3f, 0xed, 0x3f, 0xed, +0x11, 0x39, 0x2f, 0x33, 0xed, 0x32, 0x01, 0x10, 0xc6, 0x32, +0x2f, 0x10, 0xed, 0x10, 0xde, 0xed, 0x32, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x14, 0x06, 0x07, 0x27, +0x32, 0x36, 0x37, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x07, 0x32, 0x36, 0x37, +0x36, 0x34, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x0e, 0x02, +0x15, 0x14, 0x16, 0x01, 0xbf, 0xb4, 0xb5, 0x03, 0x70, 0x89, +0x16, 0x18, 0x3a, 0x20, 0x35, 0x48, 0x2c, 0x14, 0x16, 0x2e, +0x48, 0x32, 0x66, 0x68, 0xc6, 0x20, 0x37, 0x1a, 0x01, 0x0b, +0x1b, 0x2f, 0x24, 0x1e, 0x28, 0x1a, 0x0b, 0x37, 0x01, 0x73, +0xb9, 0xbb, 0x01, 0x46, 0x59, 0x6d, 0x0b, 0x0d, 0x1f, 0x35, +0x44, 0x26, 0x22, 0x47, 0x3a, 0x26, 0x8c, 0xb7, 0x0c, 0x0b, +0x0a, 0x12, 0x0a, 0x27, 0x46, 0x34, 0x1f, 0x19, 0x25, 0x2e, +0x15, 0x3d, 0x3f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb1, +0xff, 0xf4, 0x01, 0x44, 0x01, 0xd0, 0x02, 0x26, 0x00, 0x11, +0x00, 0x00, 0x01, 0x07, 0x00, 0x11, 0x00, 0x00, 0x01, 0x43, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x11, 0x0c, 0x05, 0x00, +0x50, 0x01, 0x08, 0x0e, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x7d, 0xff, 0x70, 0x01, 0x47, 0x01, 0xd0, +0x02, 0x36, 0x00, 0x0f, 0xe8, 0x00, 0x00, 0x07, 0x00, 0x11, +0x00, 0x00, 0x01, 0x43, 0x00, 0x01, 0x00, 0x31, 0x00, 0x37, +0x01, 0xca, 0x01, 0xc6, 0x00, 0x06, 0x00, 0x6c, 0x40, 0x0b, +0x05, 0x18, 0x12, 0x00, 0x4d, 0x02, 0x28, 0x12, 0x00, 0x4d, +0x00, 0xb8, 0xff, 0xd0, 0x40, 0x12, 0x11, 0x12, 0x00, 0x4c, +0x06, 0x10, 0x11, 0x00, 0x4d, 0xbb, 0x05, 0x01, 0x04, 0x08, +0x13, 0x00, 0x4d, 0x03, 0xb8, 0xff, 0xf0, 0xb6, 0x13, 0x00, +0x4d, 0xb4, 0x02, 0x01, 0x01, 0xb8, 0xff, 0xf0, 0x40, 0x16, +0x11, 0x00, 0x4d, 0x06, 0x01, 0x08, 0x00, 0x03, 0x07, 0x06, +0x05, 0x00, 0x01, 0x1f, 0x02, 0x6f, 0x02, 0x02, 0x02, 0x04, +0x03, 0x00, 0x00, 0x19, 0x2f, 0x32, 0x32, 0xdd, 0x5d, 0x18, +0xcd, 0x19, 0x10, 0xdd, 0x18, 0xcd, 0x01, 0x10, 0xc6, 0x32, +0x10, 0xce, 0x32, 0x31, 0x30, 0x00, 0x2b, 0x71, 0x2b, 0x2b, +0x71, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x37, 0x05, 0x07, 0x25, +0x35, 0x25, 0x17, 0x8d, 0x01, 0x3d, 0x17, 0xfe, 0x7e, 0x01, +0x82, 0x17, 0xff, 0x83, 0x45, 0xa4, 0x47, 0xa4, 0x45, 0x00, +0x00, 0x00, 0x00, 0x02, 0x00, 0x2e, 0x00, 0x84, 0x01, 0xc7, +0x01, 0x89, 0x00, 0x03, 0x00, 0x07, 0x00, 0x26, 0x40, 0x13, +0x06, 0x01, 0x09, 0x07, 0x00, 0x08, 0x04, 0x07, 0x03, 0xa0, +0x00, 0x01, 0xe0, 0x00, 0x01, 0x3f, 0x00, 0x01, 0x00, 0x00, +0x2f, 0x5d, 0x5d, 0x71, 0xcd, 0xde, 0xcd, 0x01, 0x10, 0xc6, +0x32, 0x10, 0xce, 0x32, 0x31, 0x30, 0x37, 0x21, 0x15, 0x21, +0x11, 0x21, 0x15, 0x21, 0x2e, 0x01, 0x99, 0xfe, 0x67, 0x01, +0x99, 0xfe, 0x67, 0xcb, 0x47, 0x01, 0x05, 0x47, 0x00, 0x01, +0x00, 0x31, 0x00, 0x37, 0x01, 0xca, 0x01, 0xc6, 0x00, 0x06, +0x00, 0x70, 0x40, 0x0b, 0x06, 0x30, 0x12, 0x00, 0x4d, 0x06, +0x38, 0x11, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb3, 0x12, +0x00, 0x4d, 0x05, 0xb8, 0xff, 0xd8, 0xb3, 0x11, 0x00, 0x4d, +0x04, 0xb8, 0xff, 0xf0, 0x40, 0x2b, 0x13, 0x00, 0x4d, 0xb3, +0x04, 0x01, 0x01, 0x10, 0x13, 0x00, 0x4d, 0xbb, 0x01, 0x01, +0x00, 0x10, 0x12, 0x00, 0x4d, 0x00, 0x30, 0x11, 0x00, 0x4d, +0x06, 0x03, 0x08, 0x00, 0x05, 0x07, 0x05, 0x1f, 0x04, 0x6f, +0x04, 0x02, 0x04, 0x06, 0x00, 0x01, 0x03, 0x02, 0x06, 0x00, +0x19, 0x2f, 0x33, 0x33, 0xdd, 0x18, 0xcd, 0x19, 0x10, 0xdd, +0x5d, 0x18, 0xcd, 0x01, 0x10, 0xc6, 0x32, 0x10, 0xce, 0x32, +0x31, 0x30, 0x00, 0x2b, 0x2b, 0x71, 0x2b, 0x71, 0x2b, 0x2b, +0x2b, 0x01, 0x2b, 0x2b, 0x13, 0x37, 0x05, 0x15, 0x05, 0x27, +0x25, 0x31, 0x17, 0x01, 0x82, 0xfe, 0x7e, 0x17, 0x01, 0x3d, +0x01, 0x81, 0x45, 0xa4, 0x47, 0xa4, 0x45, 0x83, 0x00, 0x00, +0x00, 0x02, 0x00, 0x5c, 0xff, 0xf4, 0x01, 0x9a, 0x02, 0x79, +0x00, 0x1c, 0x00, 0x28, 0x00, 0x7c, 0xb9, 0x00, 0x1a, 0xff, +0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xf8, 0xb3, +0x11, 0x00, 0x4d, 0x19, 0xb8, 0xff, 0xe8, 0xb3, 0x0f, 0x00, +0x4d, 0x19, 0xb8, 0xff, 0xf0, 0xb3, 0x0e, 0x00, 0x4d, 0x13, +0xb8, 0xff, 0xe8, 0xb3, 0x0c, 0x00, 0x4d, 0x13, 0xb8, 0xff, +0xf0, 0xb3, 0x0b, 0x00, 0x4d, 0x13, 0xb8, 0xff, 0xe8, 0x40, +0x26, 0x0a, 0x00, 0x4d, 0x0e, 0x10, 0x12, 0x00, 0x4d, 0x0e, +0x18, 0x11, 0x00, 0x4d, 0x06, 0x95, 0x15, 0x1c, 0x95, 0x0d, +0x01, 0x01, 0x26, 0x94, 0x20, 0x20, 0x2a, 0x29, 0x1c, 0x23, +0x9a, 0x1d, 0x5c, 0x0c, 0x0c, 0x09, 0x9b, 0x10, 0x5a, 0x00, +0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xfd, 0xce, 0x01, 0x11, 0x12, +0x39, 0x2f, 0xed, 0x33, 0x2f, 0xce, 0xfd, 0xdc, 0xed, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x37, 0x27, 0x34, 0x3e, 0x02, 0x35, 0x34, 0x26, 0x23, 0x22, +0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, +0x14, 0x0e, 0x04, 0x15, 0x07, 0x22, 0x26, 0x35, 0x34, 0x36, +0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0xb9, 0x01, 0x2c, 0x35, +0x2c, 0x30, 0x2f, 0x1d, 0x39, 0x1d, 0x17, 0x1e, 0x4c, 0x2b, +0x33, 0x41, 0x26, 0x0f, 0x17, 0x22, 0x28, 0x22, 0x17, 0x1c, +0x1c, 0x27, 0x27, 0x1c, 0x1b, 0x28, 0x28, 0xd3, 0x13, 0x2b, +0x3f, 0x36, 0x36, 0x23, 0x26, 0x2e, 0x0e, 0x10, 0x40, 0x11, +0x13, 0x1c, 0x2b, 0x34, 0x18, 0x1e, 0x2f, 0x2a, 0x26, 0x29, +0x30, 0x1d, 0xdf, 0x25, 0x1f, 0x1f, 0x25, 0x25, 0x1f, 0x1f, +0x25, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0xff, 0x79, +0x01, 0xd4, 0x02, 0x79, 0x00, 0x2d, 0x00, 0x3c, 0x00, 0xc3, +0xb9, 0x00, 0x3b, 0xff, 0xe0, 0xb4, 0x11, 0x12, 0x00, 0x4c, +0x31, 0xb8, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x31, 0xb8, +0xff, 0xf0, 0xb3, 0x11, 0x00, 0x4d, 0x2c, 0xb8, 0xff, 0xf0, +0x40, 0x1f, 0x0a, 0x00, 0x4d, 0x28, 0x20, 0x0e, 0x00, 0x4d, +0x28, 0x10, 0x0c, 0x0d, 0x00, 0x4c, 0x22, 0x10, 0x12, 0x00, +0x4d, 0x22, 0x08, 0x11, 0x00, 0x4d, 0x22, 0x10, 0x0b, 0x0c, +0x00, 0x4c, 0x19, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, +0x19, 0xb8, 0xff, 0xe0, 0xb3, 0x09, 0x00, 0x4d, 0x14, 0xb8, +0xff, 0xf8, 0xb3, 0x10, 0x00, 0x4d, 0x13, 0xb8, 0xff, 0xf0, +0x40, 0x3c, 0x0b, 0x00, 0x4d, 0x10, 0x18, 0x12, 0x00, 0x4d, +0x10, 0x08, 0x11, 0x00, 0x4d, 0x09, 0x08, 0x0c, 0x00, 0x4d, +0x09, 0x10, 0x0b, 0x00, 0x4d, 0x06, 0x08, 0x0c, 0x00, 0x4d, +0x06, 0x10, 0x0b, 0x00, 0x4d, 0x0e, 0x36, 0x73, 0x00, 0x1e, +0x1e, 0x00, 0x3e, 0x2e, 0x08, 0x16, 0x73, 0x25, 0x3d, 0x3a, +0x7c, 0x0b, 0x11, 0x7c, 0x2a, 0x45, 0x33, 0x7c, 0x03, 0x1b, +0x7c, 0x20, 0x00, 0x2f, 0xfd, 0xde, 0xed, 0x3f, 0xfd, 0xde, +0xed, 0x01, 0x10, 0xd6, 0xfd, 0xde, 0xcd, 0x10, 0xce, 0x32, +0x2f, 0x10, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x06, 0x06, 0x23, 0x22, +0x2e, 0x02, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x17, 0x34, +0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x33, +0x32, 0x37, 0x17, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, +0x3e, 0x02, 0x33, 0x32, 0x16, 0x15, 0x07, 0x14, 0x1e, 0x02, +0x33, 0x32, 0x36, 0x37, 0x35, 0x26, 0x26, 0x23, 0x22, 0x06, +0x01, 0xd4, 0x1e, 0x3e, 0x1a, 0x23, 0x3c, 0x2d, 0x19, 0x60, +0x4d, 0x08, 0x0f, 0x08, 0x34, 0x39, 0x23, 0x3a, 0x2a, 0x18, +0x18, 0x33, 0x4f, 0x37, 0x28, 0x2b, 0x08, 0x35, 0x2d, 0x49, +0x6b, 0x45, 0x22, 0x25, 0x41, 0x56, 0x32, 0x58, 0x66, 0xcb, +0x05, 0x12, 0x21, 0x1d, 0x08, 0x14, 0x0b, 0x09, 0x11, 0x08, +0x2b, 0x2f, 0x3f, 0x0c, 0x09, 0x17, 0x30, 0x4b, 0x34, 0x5d, +0x61, 0x01, 0x01, 0x3f, 0x4a, 0x22, 0x4b, 0x76, 0x54, 0x3f, +0x75, 0x58, 0x35, 0x0d, 0x43, 0x0e, 0x41, 0x6a, 0x88, 0x47, +0x67, 0x94, 0x5e, 0x2d, 0x77, 0x6a, 0xa8, 0x14, 0x2e, 0x27, +0x1b, 0x02, 0x03, 0xf5, 0x03, 0x02, 0x43, 0x00, 0x00, 0x02, +0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x02, 0x6b, 0x00, 0x0f, +0x00, 0x16, 0x00, 0xe4, 0x40, 0x17, 0x16, 0x18, 0x11, 0x12, +0x00, 0x4c, 0x16, 0x10, 0x10, 0x00, 0x4d, 0x16, 0x18, 0x0d, +0x0e, 0x00, 0x4c, 0x14, 0x10, 0x11, 0x00, 0x4d, 0x13, 0xb8, +0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x12, 0xb8, 0xff, 0xf8, +0xb3, 0x19, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xf8, 0xb3, 0x1a, +0x00, 0x4d, 0x11, 0xb8, 0xff, 0xe8, 0xb4, 0x11, 0x12, 0x00, +0x4c, 0x11, 0xb8, 0xff, 0xf0, 0xb3, 0x10, 0x00, 0x4d, 0x11, +0xb8, 0xff, 0xf0, 0x40, 0x0f, 0x0d, 0x0e, 0x00, 0x4c, 0x0d, +0x10, 0x1e, 0x00, 0x4d, 0x0b, 0x10, 0x0e, 0x00, 0x4d, 0x08, +0xb8, 0xff, 0xf8, 0xb3, 0x0e, 0x00, 0x4d, 0x02, 0xb8, 0xff, +0xf0, 0x40, 0x40, 0x11, 0x00, 0x4d, 0x01, 0x10, 0x11, 0x00, +0x4d, 0x02, 0x13, 0x11, 0x10, 0x09, 0x03, 0x10, 0x03, 0x78, +0x04, 0x09, 0x14, 0x04, 0x04, 0x09, 0x01, 0x14, 0x10, 0x0a, +0x00, 0x10, 0x00, 0x78, 0x0f, 0x0a, 0x14, 0x0f, 0x0f, 0x0a, +0x10, 0x10, 0x04, 0x8f, 0x0f, 0x01, 0x0f, 0x18, 0x04, 0x17, +0x01, 0x02, 0x79, 0x14, 0x13, 0x13, 0x03, 0x10, 0x0a, 0x09, +0x41, 0x04, 0x03, 0x44, 0x0f, 0x00, 0x44, 0x00, 0x3f, 0x32, +0x3f, 0x33, 0x3f, 0x33, 0x33, 0x12, 0x39, 0x2f, 0x33, 0xed, +0x32, 0x01, 0x10, 0xc6, 0x10, 0xce, 0x5d, 0x11, 0x39, 0x3d, +0x2f, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x10, 0xc4, +0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x10, 0x0e, +0xc4, 0x05, 0xc4, 0xc4, 0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x21, 0x27, 0x23, 0x07, 0x23, 0x3e, 0x03, 0x37, +0x33, 0x1e, 0x03, 0x17, 0x03, 0x06, 0x06, 0x07, 0x33, 0x26, +0x26, 0x01, 0x94, 0x25, 0xee, 0x24, 0x54, 0x11, 0x2a, 0x31, +0x36, 0x1e, 0x66, 0x1d, 0x35, 0x2f, 0x2a, 0x11, 0xf2, 0x17, +0x36, 0x18, 0xc8, 0x17, 0x35, 0xa2, 0xa2, 0x42, 0x9a, 0xa2, +0xa3, 0x4a, 0x4a, 0xa3, 0xa2, 0x9a, 0x42, 0x02, 0x23, 0x3f, +0xa6, 0x58, 0x5a, 0xa7, 0x00, 0x00, 0x00, 0x03, 0x00, 0x36, +0xff, 0xfb, 0x01, 0xc3, 0x02, 0x71, 0x00, 0x1a, 0x00, 0x29, +0x00, 0x38, 0x00, 0x7a, 0x40, 0x51, 0x7b, 0x32, 0x01, 0x6a, +0x32, 0x01, 0x79, 0x2e, 0x01, 0x6a, 0x2e, 0x01, 0x6a, 0x26, +0x7a, 0x26, 0x02, 0x6b, 0x22, 0x7b, 0x22, 0x02, 0x85, 0x19, +0x95, 0x19, 0x02, 0x95, 0x17, 0x01, 0x81, 0x16, 0x01, 0x94, +0x13, 0x01, 0x85, 0x13, 0x01, 0x90, 0x0e, 0x01, 0x14, 0x0e, +0x84, 0x0e, 0x02, 0x05, 0x0e, 0x01, 0x15, 0x30, 0x76, 0x10, +0x10, 0x24, 0x76, 0x18, 0x3a, 0x2a, 0x1b, 0x73, 0x10, 0x05, +0x01, 0x05, 0x39, 0x15, 0x1b, 0x79, 0x2a, 0x2a, 0x1f, 0x35, +0x7c, 0x0b, 0x41, 0x1f, 0x7c, 0x00, 0x43, 0x00, 0x3f, 0xed, +0x3f, 0xed, 0x12, 0x39, 0x2f, 0xed, 0x39, 0x01, 0x10, 0xd6, +0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, 0x33, 0x2f, 0xed, 0x32, +0x31, 0x30, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, +0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x17, 0x22, 0x2e, 0x02, +0x27, 0x11, 0x3e, 0x03, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, +0x0e, 0x02, 0x07, 0x16, 0x16, 0x15, 0x14, 0x06, 0x03, 0x15, +0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, +0x23, 0x27, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, +0x23, 0x22, 0x06, 0x07, 0xcc, 0x0f, 0x28, 0x28, 0x28, 0x0f, +0x0f, 0x27, 0x29, 0x27, 0x10, 0x2e, 0x50, 0x3b, 0x21, 0x0e, +0x19, 0x21, 0x13, 0x33, 0x45, 0x76, 0xc5, 0x02, 0x29, 0x1f, +0x1f, 0x39, 0x2c, 0x1b, 0x19, 0x29, 0x36, 0x1d, 0x54, 0x41, +0x19, 0x32, 0x28, 0x18, 0x16, 0x24, 0x2f, 0x1a, 0x1a, 0x27, +0x08, 0x05, 0x02, 0x03, 0x06, 0x04, 0x02, 0x58, 0x04, 0x06, +0x03, 0x02, 0x10, 0x26, 0x3e, 0x2e, 0x16, 0x29, 0x24, 0x1b, +0x07, 0x0e, 0x4b, 0x3c, 0x5c, 0x5e, 0x01, 0x26, 0xdd, 0x01, +0x03, 0x0a, 0x1b, 0x2c, 0x23, 0x1f, 0x2a, 0x19, 0x0b, 0x44, +0x0a, 0x16, 0x26, 0x1d, 0x1b, 0x26, 0x18, 0x0a, 0x01, 0x02, +0x00, 0x01, 0x00, 0x2e, 0xff, 0xf3, 0x01, 0xcc, 0x02, 0x79, +0x00, 0x20, 0x00, 0xb7, 0xb9, 0x00, 0x1b, 0xff, 0xf0, 0xb3, +0x12, 0x00, 0x4d, 0x1b, 0xb8, 0xff, 0xf8, 0xb3, 0x11, 0x00, +0x4d, 0x1b, 0xb8, 0xff, 0xf0, 0xb4, 0x0b, 0x0c, 0x00, 0x4c, +0x16, 0xb8, 0xff, 0xf8, 0xb3, 0x10, 0x00, 0x4d, 0x16, 0xb8, +0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x15, 0xb8, 0xff, 0xe0, +0xb3, 0x12, 0x00, 0x4d, 0x15, 0xb8, 0xff, 0xe8, 0xb3, 0x11, +0x00, 0x4d, 0x15, 0xb8, 0xff, 0xe8, 0xb7, 0x0b, 0x0c, 0x00, +0x4c, 0x28, 0x15, 0x01, 0x0f, 0xb8, 0xff, 0xe8, 0xb3, 0x12, +0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xc8, 0xb3, 0x11, 0x00, 0x4d, +0x0f, 0xb8, 0xff, 0xe0, 0x40, 0x0b, 0x0e, 0x10, 0x00, 0x4c, +0x05, 0x18, 0x0d, 0x0e, 0x00, 0x4c, 0x01, 0xb8, 0xff, 0xf0, +0xb3, 0x12, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xe0, 0xb4, 0x10, +0x11, 0x00, 0x4c, 0x01, 0xb8, 0xff, 0xe8, 0x40, 0x17, 0x0f, +0x00, 0x4d, 0x10, 0x10, 0x00, 0x22, 0x18, 0x76, 0x08, 0x21, +0x11, 0x11, 0x13, 0x7c, 0x0d, 0x45, 0x20, 0x20, 0x1d, 0x7c, +0x03, 0x46, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x32, +0x2f, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xce, 0x32, 0x2f, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x5d, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x06, 0x06, +0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, +0x16, 0x17, 0x07, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, +0x1e, 0x02, 0x33, 0x32, 0x36, 0x37, 0x01, 0xcc, 0x23, 0x4f, +0x2d, 0x37, 0x5d, 0x44, 0x27, 0x29, 0x46, 0x5e, 0x35, 0x25, +0x4d, 0x25, 0x18, 0x42, 0x3a, 0x29, 0x41, 0x2e, 0x19, 0x1b, +0x30, 0x43, 0x27, 0x1d, 0x40, 0x22, 0x1a, 0x14, 0x13, 0x27, +0x4f, 0x7a, 0x53, 0x4f, 0x78, 0x52, 0x2a, 0x14, 0x17, 0x44, +0x26, 0x23, 0x42, 0x5c, 0x39, 0x40, 0x5e, 0x3e, 0x1e, 0x0f, +0x13, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x36, 0xff, 0xfb, +0x01, 0xcc, 0x02, 0x71, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x45, +0x40, 0x0d, 0x18, 0x28, 0x11, 0x12, 0x00, 0x4c, 0x13, 0x18, +0x11, 0x12, 0x00, 0x4c, 0x0c, 0xb8, 0xff, 0xf0, 0xb3, 0x0d, +0x00, 0x4d, 0x03, 0xb8, 0xff, 0xf0, 0x40, 0x16, 0x0d, 0x00, +0x4d, 0x16, 0x76, 0x00, 0x1e, 0x0f, 0x73, 0x10, 0x07, 0x01, +0x07, 0x1d, 0x19, 0x7c, 0x0a, 0x41, 0x11, 0x7c, 0x05, 0x43, +0x00, 0x3f, 0xed, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0x5d, 0xed, +0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, +0x14, 0x0e, 0x02, 0x23, 0x22, 0x27, 0x11, 0x36, 0x33, 0x32, +0x1e, 0x02, 0x01, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, +0x26, 0x23, 0x22, 0x06, 0x07, 0x01, 0xcc, 0x2b, 0x4b, 0x67, +0x3c, 0x3e, 0x3f, 0x3f, 0x3e, 0x3c, 0x67, 0x4b, 0x2b, 0xfe, +0xbc, 0x19, 0x1a, 0x2d, 0x46, 0x30, 0x1a, 0x61, 0x5f, 0x0d, +0x19, 0x0a, 0x01, 0x36, 0x56, 0x78, 0x4b, 0x22, 0x0f, 0x02, +0x58, 0x0f, 0x22, 0x4c, 0x78, 0xfe, 0xba, 0x03, 0x1b, 0x3b, +0x5d, 0x41, 0x7e, 0x76, 0x01, 0x02, 0x00, 0x00, 0x00, 0x01, +0x00, 0x5b, 0x00, 0x00, 0x01, 0xcc, 0x02, 0x6b, 0x00, 0x0b, +0x00, 0x36, 0x40, 0x1d, 0x07, 0x07, 0x03, 0x03, 0x0a, 0x0d, +0x05, 0x09, 0x73, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x0c, +0x08, 0x79, 0x05, 0x05, 0x09, 0x04, 0x79, 0x01, 0x41, 0x09, +0x79, 0x00, 0x44, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x12, 0x39, +0x2f, 0xed, 0x01, 0x10, 0xd6, 0x5d, 0xed, 0x32, 0x10, 0xce, +0x32, 0x2f, 0x32, 0x2f, 0x31, 0x30, 0x33, 0x11, 0x21, 0x15, +0x21, 0x15, 0x33, 0x15, 0x23, 0x15, 0x21, 0x15, 0x5b, 0x01, +0x5b, 0xfe, 0xf7, 0xe8, 0xe8, 0x01, 0x1f, 0x02, 0x6b, 0x46, +0xbe, 0x46, 0xdb, 0x46, 0x00, 0x01, 0x00, 0x5b, 0x00, 0x00, +0x01, 0xba, 0x02, 0x6b, 0x00, 0x09, 0x00, 0x2f, 0x40, 0x19, +0x06, 0x06, 0x03, 0x0b, 0x05, 0x09, 0x73, 0x00, 0x00, 0x10, +0x00, 0x02, 0x00, 0x0a, 0x08, 0x79, 0x05, 0x05, 0x00, 0x04, +0x79, 0x01, 0x41, 0x00, 0x44, 0x00, 0x3f, 0x3f, 0xed, 0x12, +0x39, 0x2f, 0xed, 0x01, 0x10, 0xd6, 0x5d, 0xed, 0x32, 0x10, +0xce, 0x32, 0x2f, 0x31, 0x30, 0x33, 0x11, 0x21, 0x15, 0x21, +0x15, 0x33, 0x15, 0x23, 0x11, 0x5b, 0x01, 0x5f, 0xfe, 0xf3, +0xed, 0xed, 0x02, 0x6b, 0x46, 0xc1, 0x45, 0xfe, 0xe1, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x2e, 0xff, 0xf3, 0x01, 0xc7, +0x02, 0x79, 0x00, 0x25, 0x00, 0xa2, 0xb9, 0x00, 0x20, 0xff, +0xe0, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x20, 0xb8, 0xff, 0xe8, +0xb3, 0x0c, 0x00, 0x4d, 0x20, 0xb8, 0xff, 0xf0, 0xb3, 0x0b, +0x00, 0x4d, 0x1f, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, +0x1b, 0xb8, 0xff, 0xf8, 0xb3, 0x10, 0x00, 0x4d, 0x1a, 0xb8, +0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe0, +0xb3, 0x11, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe8, 0xb4, 0x0b, +0x0c, 0x00, 0x4c, 0x12, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, +0x4d, 0x12, 0xb8, 0xff, 0xc0, 0xb3, 0x11, 0x00, 0x4d, 0x12, +0xb8, 0xff, 0xe8, 0x40, 0x26, 0x0d, 0x10, 0x00, 0x4c, 0x07, +0x18, 0x0e, 0x00, 0x4d, 0x07, 0x10, 0x0d, 0x00, 0x4d, 0x14, +0x14, 0x00, 0x73, 0x01, 0x27, 0x1d, 0x76, 0x0a, 0x26, 0x00, +0x00, 0x22, 0x15, 0x15, 0x18, 0x7c, 0x0f, 0x45, 0x25, 0x22, +0x7c, 0x05, 0x46, 0x00, 0x3f, 0xed, 0x32, 0x3f, 0xed, 0x32, +0x2f, 0x11, 0x39, 0x2f, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, +0xed, 0x33, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x33, +0x11, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, +0x02, 0x33, 0x32, 0x1e, 0x02, 0x17, 0x07, 0x26, 0x26, 0x23, +0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x36, +0x37, 0x01, 0x75, 0x52, 0x13, 0x54, 0x39, 0x38, 0x5c, 0x41, +0x24, 0x28, 0x45, 0x5c, 0x35, 0x22, 0x34, 0x25, 0x18, 0x06, +0x1b, 0x17, 0x3f, 0x23, 0x26, 0x41, 0x2e, 0x1a, 0x17, 0x2c, +0x41, 0x2a, 0x1d, 0x20, 0x08, 0x01, 0x31, 0xfe, 0xde, 0x07, +0x15, 0x2b, 0x52, 0x79, 0x4d, 0x4e, 0x78, 0x52, 0x2b, 0x0a, +0x0e, 0x0f, 0x04, 0x45, 0x12, 0x17, 0x24, 0x42, 0x5d, 0x39, +0x38, 0x5c, 0x42, 0x25, 0x08, 0x04, 0x00, 0x00, 0x00, 0x01, +0x00, 0x2d, 0x00, 0x00, 0x01, 0xc7, 0x02, 0x6b, 0x00, 0x0b, +0x00, 0x31, 0x40, 0x1a, 0x0b, 0x03, 0x73, 0x02, 0x0d, 0x0a, +0x06, 0x73, 0x07, 0x0c, 0x05, 0x79, 0x0f, 0x0a, 0x1f, 0x0a, +0x02, 0x0a, 0x0a, 0x07, 0x00, 0x08, 0x41, 0x03, 0x07, 0x44, +0x00, 0x3f, 0x33, 0x3f, 0x33, 0x12, 0x39, 0x2f, 0x5d, 0xed, +0x01, 0x10, 0xd6, 0xed, 0x32, 0x10, 0xde, 0xed, 0x32, 0x31, +0x30, 0x01, 0x33, 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, +0x33, 0x11, 0x33, 0x01, 0x75, 0x52, 0x52, 0xf6, 0x52, 0x52, +0xf6, 0x02, 0x6b, 0xfd, 0x95, 0x01, 0x20, 0xfe, 0xe0, 0x02, +0x6b, 0xfe, 0xfb, 0x00, 0x00, 0x01, 0x00, 0x59, 0x00, 0x00, +0x01, 0x9b, 0x02, 0x6b, 0x00, 0x0b, 0x00, 0x2b, 0x40, 0x15, +0x08, 0x05, 0x06, 0x0b, 0x02, 0x01, 0x73, 0x06, 0x06, 0x0c, +0x0d, 0x00, 0x07, 0x79, 0x09, 0x41, 0x01, 0x06, 0x79, 0x04, +0x44, 0x00, 0x3f, 0xed, 0x32, 0x3f, 0xed, 0x32, 0x01, 0x11, +0x12, 0x39, 0x2f, 0xfd, 0xcd, 0x32, 0x10, 0xcd, 0x32, 0x31, +0x30, 0x01, 0x11, 0x33, 0x15, 0x21, 0x35, 0x33, 0x11, 0x23, +0x35, 0x21, 0x15, 0x01, 0x23, 0x78, 0xfe, 0xbe, 0x78, 0x78, +0x01, 0x42, 0x02, 0x25, 0xfe, 0x21, 0x46, 0x46, 0x01, 0xdf, +0x46, 0x46, 0x00, 0x01, 0x00, 0x36, 0xff, 0xf3, 0x01, 0xa4, +0x02, 0x6b, 0x00, 0x13, 0x00, 0x4a, 0x40, 0x17, 0x10, 0x18, +0x0f, 0x10, 0x00, 0x4c, 0x0a, 0x18, 0x0e, 0x00, 0x4d, 0x0a, +0x20, 0x0c, 0x0d, 0x00, 0x4c, 0x0a, 0x18, 0x0b, 0x00, 0x4d, +0x05, 0xb8, 0xff, 0xf0, 0x40, 0x16, 0x11, 0x12, 0x00, 0x4c, +0x12, 0x73, 0x03, 0x15, 0x00, 0x00, 0x0b, 0x14, 0x0c, 0x0c, +0x0f, 0x7c, 0x08, 0x46, 0x00, 0x79, 0x01, 0x41, 0x00, 0x3f, +0xed, 0x3f, 0xed, 0x32, 0x2f, 0x01, 0x10, 0xc6, 0x32, 0x2f, +0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x13, 0x35, 0x21, 0x11, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, +0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, 0x7f, +0x01, 0x25, 0x13, 0x2f, 0x4f, 0x3c, 0x3c, 0x52, 0x13, 0x21, +0x13, 0x3f, 0x2a, 0x40, 0x3f, 0x02, 0x25, 0x46, 0xfe, 0x5c, +0x2c, 0x4e, 0x39, 0x21, 0x22, 0x10, 0x43, 0x0e, 0x20, 0x44, +0x51, 0x01, 0x56, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, +0x00, 0x00, 0x01, 0xeb, 0x02, 0x6b, 0x00, 0x16, 0x00, 0x61, +0x40, 0x37, 0x03, 0x1e, 0x52, 0x03, 0x00, 0x09, 0x0e, 0x09, +0x78, 0x08, 0x03, 0x14, 0x08, 0x08, 0x03, 0x16, 0x03, 0x00, +0x03, 0x78, 0x13, 0x16, 0x14, 0x13, 0x13, 0x16, 0x00, 0x00, +0x08, 0x18, 0x13, 0x0e, 0x73, 0x00, 0x10, 0x10, 0x10, 0x02, +0x10, 0x17, 0x00, 0x16, 0x41, 0x13, 0x0e, 0x03, 0x03, 0x10, +0x11, 0x41, 0x10, 0x44, 0x08, 0x09, 0x44, 0x00, 0x3f, 0x33, +0x3f, 0x3f, 0x12, 0x39, 0x19, 0x2f, 0x33, 0x33, 0x18, 0x3f, +0x33, 0x01, 0x10, 0xd6, 0x5d, 0xed, 0x32, 0x10, 0xce, 0x32, +0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x87, 0x18, 0x10, +0x2b, 0x87, 0x08, 0x2b, 0xc4, 0x31, 0x30, 0x01, 0x06, 0x06, +0x07, 0x1e, 0x03, 0x17, 0x23, 0x2e, 0x03, 0x27, 0x11, 0x23, +0x11, 0x33, 0x11, 0x36, 0x36, 0x37, 0x01, 0xd6, 0x31, 0x75, +0x44, 0x20, 0x48, 0x45, 0x3d, 0x15, 0x5d, 0x19, 0x3a, 0x41, +0x45, 0x23, 0x52, 0x52, 0x41, 0x77, 0x2d, 0x02, 0x6b, 0x49, +0x90, 0x48, 0x1b, 0x48, 0x55, 0x60, 0x32, 0x2e, 0x58, 0x4c, +0x3f, 0x17, 0xfe, 0xd8, 0x02, 0x6b, 0xfe, 0xec, 0x43, 0x92, +0x3f, 0x00, 0x00, 0x01, 0x00, 0x5b, 0x00, 0x00, 0x01, 0xcc, +0x02, 0x6b, 0x00, 0x05, 0x00, 0x20, 0x40, 0x11, 0x00, 0x07, +0x05, 0x73, 0x00, 0x02, 0x10, 0x02, 0x02, 0x02, 0x06, 0x03, +0x41, 0x05, 0x79, 0x02, 0x44, 0x00, 0x3f, 0xed, 0x3f, 0x01, +0x10, 0xd6, 0x5d, 0xed, 0x10, 0xce, 0x31, 0x30, 0x25, 0x15, +0x21, 0x11, 0x33, 0x11, 0x01, 0xcc, 0xfe, 0x8f, 0x52, 0x46, +0x46, 0x02, 0x6b, 0xfd, 0xdb, 0x00, 0x00, 0x01, 0x00, 0x20, +0x00, 0x00, 0x01, 0xd4, 0x02, 0x6b, 0x00, 0x1a, 0x00, 0xf9, +0xb9, 0x00, 0x1a, 0xff, 0xf8, 0xb3, 0x19, 0x00, 0x4d, 0x1a, +0xb8, 0xff, 0xf8, 0xb3, 0x13, 0x00, 0x4d, 0x1a, 0xb8, 0xff, +0xe0, 0xb3, 0x0a, 0x00, 0x4d, 0x18, 0xb8, 0xff, 0xf8, 0x40, +0x1a, 0x1b, 0x1c, 0x00, 0x4c, 0x18, 0x08, 0x10, 0x00, 0x4d, +0x17, 0x08, 0x0e, 0x00, 0x4d, 0x04, 0x0d, 0x01, 0x0c, 0x0c, +0x01, 0x03, 0x08, 0x1b, 0x00, 0x4d, 0x03, 0xb8, 0xff, 0xf8, +0xb4, 0x0f, 0x11, 0x00, 0x4c, 0x03, 0xb8, 0xff, 0xf0, 0x40, +0x4e, 0x0e, 0x00, 0x4d, 0x01, 0x38, 0x0a, 0x00, 0x4d, 0x3d, +0x01, 0x01, 0x2c, 0x01, 0x01, 0x0c, 0x01, 0x00, 0x01, 0x7b, +0x0b, 0x0c, 0x14, 0x0b, 0x0b, 0x0c, 0x0b, 0x06, 0x36, 0x1a, +0x01, 0x25, 0x1a, 0x01, 0x0d, 0x1a, 0x00, 0x1a, 0x7b, 0x0e, +0x0d, 0x14, 0x0e, 0x0e, 0x0d, 0x00, 0x00, 0x13, 0x06, 0x73, +0x02, 0x18, 0x1d, 0x00, 0x4d, 0x02, 0x20, 0x1b, 0x1c, 0x00, +0x4c, 0x02, 0x18, 0x1a, 0x00, 0x4d, 0x0b, 0x02, 0x01, 0x46, +0x02, 0x01, 0x02, 0x05, 0x1c, 0x0e, 0x13, 0x73, 0x19, 0xb8, +0xff, 0xe0, 0x40, 0x1a, 0x1a, 0x1d, 0x00, 0x4c, 0x03, 0x19, +0x01, 0x19, 0x14, 0x1b, 0x0e, 0x1a, 0x41, 0x0c, 0x0f, 0x00, +0x01, 0x00, 0x0d, 0x0d, 0x06, 0x14, 0x44, 0x0b, 0x01, 0x41, +0x00, 0x3f, 0x33, 0x3f, 0x33, 0x33, 0x2f, 0x33, 0x71, 0x33, +0x3f, 0x33, 0x01, 0x10, 0xd6, 0x32, 0x71, 0x2b, 0xed, 0x32, +0x10, 0xde, 0x32, 0x5d, 0x71, 0x2b, 0x2b, 0x2b, 0xed, 0x11, +0x39, 0x3d, 0x2f, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x01, 0x5d, 0x5d, 0x11, 0x33, 0x87, 0x18, 0x10, 0x2b, 0x87, +0x7d, 0xc4, 0x01, 0x5d, 0x5d, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x71, 0x71, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, +0x13, 0x33, 0x16, 0x12, 0x17, 0x23, 0x2e, 0x03, 0x27, 0x03, +0x23, 0x03, 0x0e, 0x03, 0x07, 0x23, 0x3e, 0x03, 0x37, 0x33, +0xfb, 0x60, 0x4d, 0x14, 0x11, 0x07, 0x50, 0x01, 0x02, 0x03, +0x03, 0x02, 0x5a, 0x48, 0x5c, 0x01, 0x03, 0x03, 0x03, 0x01, +0x50, 0x03, 0x08, 0x0b, 0x0f, 0x09, 0x4c, 0x01, 0x37, 0x01, +0x34, 0x92, 0xfe, 0xce, 0xa7, 0x36, 0x7e, 0x86, 0x8a, 0x41, +0xfe, 0xe6, 0x01, 0x1a, 0x41, 0x89, 0x87, 0x7e, 0x36, 0x4c, +0xa0, 0x9e, 0x9a, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, +0x00, 0x00, 0x01, 0xbd, 0x02, 0x6b, 0x00, 0x11, 0x00, 0x4e, +0x40, 0x30, 0x1a, 0x00, 0x01, 0x0d, 0x00, 0x01, 0x26, 0x09, +0x01, 0x04, 0x09, 0x14, 0x09, 0x02, 0x09, 0x00, 0x05, 0x00, +0x7e, 0x0e, 0x09, 0x14, 0x0e, 0x09, 0x0e, 0x73, 0x11, 0x13, +0x05, 0x73, 0x10, 0x07, 0x01, 0x01, 0x07, 0x01, 0x07, 0x12, +0x0f, 0x41, 0x05, 0x09, 0x41, 0x07, 0x44, 0x0e, 0x00, 0x44, +0x00, 0x3f, 0x32, 0x3f, 0x3f, 0x33, 0x3f, 0x01, 0x10, 0xd6, +0x5d, 0x5d, 0xed, 0x10, 0xde, 0xfd, 0x87, 0x2b, 0x87, 0x7d, +0xc4, 0x01, 0x5d, 0x5d, 0x5d, 0x5d, 0x31, 0x30, 0x21, 0x2e, +0x03, 0x27, 0x11, 0x23, 0x11, 0x33, 0x1e, 0x03, 0x17, 0x11, +0x33, 0x11, 0x01, 0x69, 0x22, 0x3c, 0x37, 0x36, 0x1c, 0x4b, +0x54, 0x29, 0x3d, 0x33, 0x30, 0x1e, 0x4b, 0x53, 0x87, 0x76, +0x69, 0x35, 0xfe, 0x12, 0x02, 0x6b, 0x4b, 0x70, 0x69, 0x6f, +0x49, 0x01, 0xdc, 0xfd, 0x95, 0x00, 0x00, 0x02, 0x00, 0x1d, +0xff, 0xf3, 0x01, 0xd8, 0x02, 0x79, 0x00, 0x13, 0x00, 0x1f, +0x00, 0x9a, 0xb9, 0x00, 0x1e, 0xff, 0xe8, 0xb3, 0x0e, 0x00, +0x4d, 0x1e, 0xb8, 0xff, 0xf0, 0x40, 0x10, 0x0d, 0x00, 0x4d, +0x1c, 0x18, 0x0d, 0x0e, 0x00, 0x4c, 0x18, 0x18, 0x0d, 0x0e, +0x00, 0x4c, 0x16, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, +0x16, 0xb8, 0xff, 0xf0, 0x40, 0x0f, 0x0d, 0x00, 0x4d, 0x11, +0x18, 0x0f, 0x10, 0x00, 0x4c, 0x11, 0x18, 0x08, 0x00, 0x4d, +0x0d, 0xb8, 0xff, 0xe8, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x0d, +0xb8, 0xff, 0xe8, 0xb3, 0x08, 0x00, 0x4d, 0x07, 0xb8, 0xff, +0xe8, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x07, 0xb8, 0xff, 0xf8, +0x40, 0x23, 0x08, 0x00, 0x4d, 0x03, 0x18, 0x0f, 0x10, 0x00, +0x4c, 0x03, 0x18, 0x08, 0x00, 0x4d, 0x1a, 0x76, 0x0a, 0x21, +0x14, 0x76, 0x00, 0x40, 0x0b, 0x10, 0x48, 0x00, 0x20, 0x17, +0x7c, 0x0f, 0x46, 0x1d, 0x7c, 0x05, 0x45, 0x00, 0x3f, 0xed, +0x3f, 0xed, 0x01, 0x10, 0xd6, 0x2b, 0xed, 0x10, 0xde, 0xed, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x34, 0x3e, 0x02, +0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, +0x2e, 0x02, 0x37, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, +0x26, 0x23, 0x22, 0x06, 0x1d, 0x20, 0x3a, 0x51, 0x32, 0x31, +0x52, 0x3a, 0x21, 0x21, 0x3a, 0x52, 0x31, 0x32, 0x51, 0x3a, +0x20, 0x54, 0x42, 0x45, 0x46, 0x46, 0x46, 0x46, 0x45, 0x42, +0x01, 0x36, 0x53, 0x7a, 0x4f, 0x27, 0x27, 0x4f, 0x7a, 0x53, +0x53, 0x7a, 0x50, 0x26, 0x26, 0x50, 0x7a, 0x53, 0x7a, 0x82, +0x82, 0x7a, 0x7a, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00, 0x02, +0x00, 0x49, 0x00, 0x00, 0x01, 0xc7, 0x02, 0x71, 0x00, 0x10, +0x00, 0x1a, 0x00, 0x5a, 0x40, 0x11, 0x1a, 0x10, 0x10, 0x00, +0x4d, 0x1a, 0x18, 0x0f, 0x00, 0x4d, 0x17, 0x18, 0x0f, 0x10, +0x00, 0x4c, 0x07, 0xb8, 0xff, 0xe8, 0xb3, 0x08, 0x00, 0x4d, +0x02, 0xb8, 0xff, 0xe8, 0x40, 0x20, 0x08, 0x00, 0x4d, 0x19, +0x76, 0x05, 0x1c, 0x15, 0x15, 0x0a, 0x73, 0x00, 0x0b, 0x10, +0x0b, 0x20, 0x0b, 0x03, 0x08, 0x0b, 0x1b, 0x09, 0x79, 0x15, +0x15, 0x00, 0x0b, 0x44, 0x11, 0x7c, 0x00, 0x41, 0x00, 0x3f, +0xed, 0x3f, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xd6, 0x5e, +0x5d, 0xed, 0x32, 0x2f, 0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x32, 0x1e, 0x02, 0x15, 0x14, +0x06, 0x23, 0x23, 0x15, 0x23, 0x11, 0x3e, 0x03, 0x17, 0x22, +0x06, 0x07, 0x15, 0x33, 0x32, 0x36, 0x35, 0x34, 0xeb, 0x37, +0x53, 0x37, 0x1b, 0x72, 0x72, 0x48, 0x52, 0x12, 0x2b, 0x2b, +0x29, 0x17, 0x1a, 0x30, 0x0c, 0x44, 0x4b, 0x49, 0x02, 0x71, +0x1c, 0x33, 0x46, 0x2b, 0x61, 0x69, 0xe7, 0x02, 0x62, 0x04, +0x06, 0x04, 0x01, 0x47, 0x01, 0x02, 0xfa, 0x3c, 0x45, 0x7c, +0x00, 0x02, 0x00, 0x1d, 0xff, 0x5b, 0x01, 0xd8, 0x02, 0x78, +0x00, 0x1c, 0x00, 0x28, 0x00, 0xcf, 0xb9, 0x00, 0x27, 0xff, +0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x27, 0xb8, 0xff, 0xe0, 0x40, +0x18, 0x0d, 0x00, 0x4d, 0x25, 0x10, 0x0e, 0x00, 0x4d, 0x25, +0x20, 0x0d, 0x00, 0x4d, 0x21, 0x10, 0x0e, 0x00, 0x4d, 0x21, +0x18, 0x0d, 0x00, 0x4d, 0x1f, 0xb8, 0xff, 0xf0, 0xb3, 0x0e, +0x00, 0x4d, 0x1f, 0xb8, 0xff, 0xe8, 0x40, 0x1f, 0x0d, 0x00, +0x4d, 0x1b, 0x28, 0x0f, 0x10, 0x00, 0x4c, 0x1b, 0x08, 0x0c, +0x00, 0x4d, 0x1b, 0x10, 0x09, 0x0a, 0x00, 0x4c, 0x1b, 0x18, +0x08, 0x00, 0x4d, 0x0d, 0x20, 0x0d, 0x00, 0x4d, 0x0d, 0xb8, +0xff, 0xe8, 0xb3, 0x08, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xe8, +0x40, 0x0a, 0x0f, 0x10, 0x00, 0x4c, 0x07, 0x10, 0x0d, 0x00, +0x4d, 0x07, 0xb8, 0xff, 0xe0, 0x40, 0x33, 0x08, 0x00, 0x4d, +0x03, 0x18, 0x10, 0x00, 0x4d, 0x03, 0x20, 0x0f, 0x00, 0x4d, +0x03, 0x18, 0x08, 0x00, 0x4d, 0x0f, 0x76, 0x1a, 0x1a, 0x00, +0x23, 0x76, 0x0a, 0x14, 0x14, 0x0a, 0x2a, 0x1d, 0x76, 0x00, +0x40, 0x0c, 0x10, 0x48, 0x00, 0x29, 0x14, 0x7c, 0x15, 0x20, +0x7c, 0x1a, 0x0f, 0x46, 0x26, 0x7c, 0x05, 0x45, 0x00, 0x3f, +0xed, 0x3f, 0x33, 0xed, 0xdc, 0xed, 0x01, 0x10, 0xd6, 0x2b, +0xed, 0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, 0x11, 0x39, 0x2f, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x13, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, +0x02, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x1e, 0x03, 0x17, 0x07, +0x2e, 0x03, 0x27, 0x26, 0x26, 0x37, 0x14, 0x16, 0x33, 0x32, +0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x1d, 0x20, 0x3a, +0x51, 0x32, 0x31, 0x52, 0x3a, 0x21, 0x1a, 0x30, 0x44, 0x29, +0x03, 0x1c, 0x2b, 0x37, 0x1e, 0x13, 0x29, 0x4b, 0x3c, 0x2a, +0x07, 0x51, 0x5e, 0x54, 0x42, 0x45, 0x46, 0x46, 0x46, 0x46, +0x45, 0x42, 0x01, 0x35, 0x53, 0x7a, 0x4f, 0x27, 0x27, 0x4f, +0x7a, 0x53, 0x4a, 0x71, 0x50, 0x2e, 0x07, 0x14, 0x1d, 0x15, +0x0e, 0x04, 0x42, 0x07, 0x16, 0x24, 0x34, 0x26, 0x11, 0x9b, +0x93, 0x7a, 0x82, 0x82, 0x7a, 0x7a, 0x82, 0x82, 0x00, 0x02, +0x00, 0x37, 0x00, 0x00, 0x01, 0xcf, 0x02, 0x71, 0x00, 0x1a, +0x00, 0x29, 0x00, 0x65, 0x40, 0x3d, 0x28, 0x20, 0x10, 0x00, +0x4d, 0x23, 0x18, 0x10, 0x00, 0x4d, 0x02, 0x20, 0x10, 0x00, +0x4d, 0x03, 0x09, 0x0c, 0x09, 0x78, 0x08, 0x03, 0x14, 0x08, +0x08, 0x03, 0x0c, 0x0c, 0x00, 0x08, 0x08, 0x25, 0x76, 0x00, +0x2b, 0x1f, 0x11, 0x73, 0x00, 0x12, 0x10, 0x12, 0x02, 0x12, +0x2a, 0x0c, 0x03, 0x10, 0x79, 0x1f, 0x1f, 0x12, 0x1b, 0x7c, +0x18, 0x41, 0x12, 0x44, 0x08, 0x09, 0x44, 0x00, 0x3f, 0x33, +0x3f, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0xed, 0x32, 0x32, 0x01, +0x10, 0xd6, 0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, 0x33, 0x2f, +0x11, 0x33, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, +0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x01, 0x14, 0x06, 0x07, 0x1e, +0x03, 0x17, 0x23, 0x26, 0x26, 0x27, 0x06, 0x22, 0x23, 0x23, +0x15, 0x23, 0x11, 0x3e, 0x03, 0x33, 0x32, 0x16, 0x27, 0x22, +0x06, 0x07, 0x15, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, +0x02, 0x01, 0xaf, 0x3c, 0x33, 0x0f, 0x25, 0x26, 0x25, 0x10, +0x58, 0x1e, 0x47, 0x21, 0x06, 0x17, 0x04, 0x46, 0x53, 0x0f, +0x27, 0x29, 0x28, 0x10, 0x70, 0x71, 0xda, 0x17, 0x2b, 0x09, +0x35, 0x24, 0x39, 0x29, 0x16, 0x16, 0x24, 0x31, 0x01, 0xae, +0x39, 0x57, 0x18, 0x18, 0x3d, 0x45, 0x49, 0x23, 0x48, 0x84, +0x29, 0x01, 0xf4, 0x02, 0x62, 0x04, 0x06, 0x03, 0x02, 0x62, +0x1b, 0x01, 0x02, 0xef, 0x0a, 0x1b, 0x2f, 0x26, 0x24, 0x2e, +0x1b, 0x0b, 0x00, 0x01, 0x00, 0x37, 0xff, 0xf3, 0x01, 0xbd, +0x02, 0x79, 0x00, 0x31, 0x00, 0xd8, 0x40, 0x0b, 0x2c, 0x18, +0x0e, 0x00, 0x4d, 0x2c, 0x10, 0x0d, 0x00, 0x4d, 0x27, 0xb8, +0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x27, 0xb8, 0xff, 0xf0, +0xb3, 0x09, 0x00, 0x4d, 0x24, 0xb8, 0xff, 0xf0, 0xb3, 0x0d, +0x00, 0x4d, 0x24, 0xb8, 0xff, 0xd0, 0xb3, 0x0a, 0x00, 0x4d, +0x23, 0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x1b, 0xb8, +0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe0, +0xb3, 0x12, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xe8, 0xb3, 0x12, +0x00, 0x4d, 0x14, 0xb8, 0xff, 0xf0, 0xb3, 0x11, 0x00, 0x4d, +0x14, 0xb8, 0xff, 0xe0, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x14, +0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x13, 0xb8, 0xff, +0xe0, 0x40, 0x3e, 0x0e, 0x00, 0x4d, 0x0b, 0x10, 0x0e, 0x0f, +0x00, 0x4c, 0x0b, 0x20, 0x09, 0x0a, 0x00, 0x4c, 0x02, 0x10, +0x11, 0x00, 0x4d, 0x01, 0x28, 0x12, 0x00, 0x4d, 0x15, 0x15, +0x03, 0x76, 0x26, 0x33, 0x2e, 0x2e, 0x1c, 0x76, 0x00, 0x0d, +0x10, 0x0d, 0x02, 0x0d, 0x32, 0x59, 0x08, 0x01, 0x08, 0x29, +0x19, 0x21, 0x10, 0x2f, 0x2f, 0x00, 0x7c, 0x29, 0x46, 0x16, +0x16, 0x19, 0x7c, 0x10, 0x45, 0x00, 0x3f, 0xed, 0x32, 0x2f, +0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x11, 0x12, 0x39, 0x5d, +0x01, 0x10, 0xd6, 0x5d, 0xed, 0x33, 0x2f, 0x10, 0xde, 0xed, +0x33, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x37, 0x32, 0x36, 0x35, 0x34, 0x2e, 0x02, 0x27, +0x2e, 0x03, 0x35, 0x34, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x17, +0x07, 0x26, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x1e, 0x02, +0x17, 0x1e, 0x03, 0x15, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x02, +0x27, 0x37, 0x16, 0x16, 0xea, 0x3f, 0x42, 0x18, 0x28, 0x32, +0x1a, 0x1e, 0x37, 0x2b, 0x19, 0x66, 0x5b, 0x19, 0x31, 0x2a, +0x21, 0x0a, 0x1a, 0x14, 0x46, 0x2b, 0x2d, 0x42, 0x13, 0x21, +0x2c, 0x1a, 0x26, 0x3f, 0x2d, 0x19, 0x6d, 0x66, 0x21, 0x3a, +0x2d, 0x22, 0x09, 0x19, 0x14, 0x4e, 0x3a, 0x30, 0x30, 0x1d, +0x29, 0x1f, 0x17, 0x0a, 0x0c, 0x1e, 0x28, 0x36, 0x25, 0x51, +0x5b, 0x07, 0x0a, 0x0e, 0x07, 0x45, 0x0c, 0x18, 0x2d, 0x2d, +0x1a, 0x24, 0x1b, 0x16, 0x0b, 0x10, 0x20, 0x2c, 0x3c, 0x2b, +0x51, 0x57, 0x09, 0x0e, 0x0e, 0x06, 0x44, 0x0b, 0x1d, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x00, 0x00, 0x01, 0xcd, +0x02, 0x6b, 0x00, 0x07, 0x00, 0x20, 0x40, 0x0f, 0x01, 0x03, +0x73, 0x06, 0x04, 0x04, 0x09, 0x08, 0x02, 0x05, 0x79, 0x07, +0x41, 0x04, 0x44, 0x00, 0x3f, 0x3f, 0xed, 0x32, 0x01, 0x11, +0x12, 0x39, 0x2f, 0xce, 0xfd, 0xce, 0x31, 0x30, 0x01, 0x15, +0x23, 0x11, 0x23, 0x11, 0x23, 0x35, 0x01, 0xcd, 0xaa, 0x52, +0xaa, 0x02, 0x6b, 0x46, 0xfd, 0xdb, 0x02, 0x25, 0x46, 0x00, +0x00, 0x01, 0x00, 0x30, 0xff, 0xf3, 0x01, 0xc4, 0x02, 0x6b, +0x00, 0x19, 0x00, 0x4a, 0x40, 0x0d, 0x0f, 0x20, 0x11, 0x12, +0x00, 0x4c, 0x0f, 0x10, 0x0f, 0x10, 0x00, 0x4c, 0x0b, 0xb8, +0xff, 0xd8, 0xb3, 0x12, 0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xe0, +0xb3, 0x11, 0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xf0, 0x40, 0x13, +0x0f, 0x10, 0x00, 0x4c, 0x12, 0x73, 0x15, 0x1b, 0x08, 0x73, +0x05, 0x1a, 0x13, 0x06, 0x41, 0x0d, 0x7c, 0x00, 0x46, 0x00, +0x3f, 0xed, 0x3f, 0x33, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x17, 0x22, +0x2e, 0x02, 0x35, 0x11, 0x33, 0x11, 0x14, 0x1e, 0x02, 0x33, +0x32, 0x3e, 0x02, 0x35, 0x11, 0x33, 0x11, 0x14, 0x0e, 0x02, +0xfa, 0x37, 0x4d, 0x30, 0x16, 0x52, 0x11, 0x1f, 0x2c, 0x1c, +0x1c, 0x2c, 0x1f, 0x11, 0x52, 0x16, 0x30, 0x4d, 0x0d, 0x20, +0x3a, 0x54, 0x34, 0x01, 0x96, 0xfe, 0x73, 0x2f, 0x3f, 0x26, +0x10, 0x10, 0x26, 0x3f, 0x2f, 0x01, 0x8d, 0xfe, 0x6a, 0x34, +0x54, 0x3a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0d, +0x00, 0x00, 0x01, 0xe8, 0x02, 0x6b, 0x00, 0x16, 0x00, 0x41, +0x40, 0x23, 0x05, 0x00, 0x05, 0x0a, 0x00, 0x78, 0x16, 0x11, +0x14, 0x16, 0x16, 0x11, 0x05, 0x0a, 0x0a, 0x78, 0x0b, 0x10, +0x14, 0x0b, 0x10, 0x0b, 0x18, 0x16, 0x17, 0x00, 0x16, 0x41, +0x10, 0x05, 0x11, 0x44, 0x0a, 0x0b, 0x41, 0x00, 0x3f, 0x33, +0x3f, 0x33, 0x33, 0x3f, 0x33, 0x01, 0x10, 0xc6, 0x10, 0xde, +0x87, 0x2b, 0x7d, 0x10, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x08, +0x7d, 0x10, 0xc4, 0x31, 0x30, 0x13, 0x1e, 0x03, 0x17, 0x3e, +0x03, 0x37, 0x33, 0x0e, 0x03, 0x07, 0x23, 0x2e, 0x03, 0x27, +0x66, 0x0c, 0x25, 0x29, 0x2a, 0x12, 0x10, 0x2b, 0x2a, 0x25, +0x0c, 0x56, 0x08, 0x24, 0x32, 0x3d, 0x21, 0x66, 0x1f, 0x3b, +0x32, 0x24, 0x09, 0x02, 0x6b, 0x3f, 0x95, 0x95, 0x88, 0x33, +0x33, 0x8a, 0x95, 0x94, 0x3e, 0x28, 0x87, 0xa7, 0xbb, 0x5a, +0x5a, 0xba, 0xa7, 0x88, 0x28, 0x00, 0x00, 0x01, 0x00, 0x20, +0x00, 0x00, 0x01, 0xd4, 0x02, 0x6b, 0x00, 0x14, 0x01, 0xdf, +0xb9, 0x00, 0x13, 0xff, 0xe0, 0xb3, 0x19, 0x00, 0x4d, 0x13, +0xb8, 0xff, 0xe8, 0xb3, 0x17, 0x00, 0x4d, 0x13, 0xb8, 0xff, +0xf0, 0x40, 0x18, 0x14, 0x00, 0x4d, 0x13, 0x28, 0x12, 0x00, +0x4d, 0x13, 0x18, 0x11, 0x00, 0x4d, 0x13, 0x10, 0x10, 0x00, +0x4d, 0x13, 0x28, 0x0d, 0x00, 0x4d, 0x12, 0xb8, 0xff, 0xf8, +0xb3, 0x0d, 0x00, 0x4d, 0x12, 0xb8, 0xff, 0xe8, 0x40, 0x14, +0x0b, 0x0c, 0x00, 0x4c, 0x0a, 0x20, 0x19, 0x00, 0x4d, 0x0a, +0x10, 0x17, 0x00, 0x4d, 0x0a, 0x10, 0x15, 0x00, 0x4d, 0x0a, +0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x0a, 0xb8, 0xff, +0xf0, 0xb3, 0x0d, 0x00, 0x4d, 0x09, 0xb8, 0xff, 0xf0, 0xb3, +0x19, 0x00, 0x4d, 0x09, 0xb8, 0xff, 0xf0, 0x40, 0x23, 0x17, +0x00, 0x4d, 0x09, 0x20, 0x0d, 0x0e, 0x00, 0x4c, 0x01, 0x10, +0x0d, 0x00, 0x4d, 0x01, 0x28, 0x0c, 0x00, 0x4d, 0x01, 0x10, +0x0b, 0x00, 0x4d, 0x00, 0x20, 0x19, 0x00, 0x4d, 0x00, 0x10, +0x17, 0x00, 0x4d, 0x00, 0xb8, 0xff, 0xe0, 0xb4, 0x11, 0x12, +0x00, 0x4c, 0x00, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, +0x00, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x00, 0xb8, +0xff, 0xf8, 0xb3, 0x0e, 0x00, 0x4d, 0x00, 0xb8, 0xff, 0xc8, +0xb3, 0x0d, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xb0, 0xb3, 0x19, +0x00, 0x4d, 0x14, 0xb8, 0xff, 0xd0, 0xb3, 0x18, 0x00, 0x4d, +0x14, 0xb8, 0xff, 0xa0, 0xb3, 0x17, 0x00, 0x4d, 0x14, 0xb8, +0xff, 0xa0, 0xb3, 0x15, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xb0, +0xb3, 0x14, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0x90, 0xb3, 0x13, +0x00, 0x4d, 0x14, 0xb8, 0xff, 0x98, 0xb3, 0x0e, 0x00, 0x4d, +0x14, 0xb8, 0xff, 0xd0, 0x40, 0x09, 0x0d, 0x00, 0x4d, 0x0b, +0x58, 0x13, 0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xd0, 0x40, 0x09, +0x0e, 0x00, 0x4d, 0x08, 0x38, 0x13, 0x00, 0x4d, 0x08, 0xb8, +0xff, 0xe8, 0x40, 0x5e, 0x0e, 0x00, 0x4d, 0x01, 0x06, 0x07, +0x08, 0x01, 0x08, 0x06, 0x78, 0x07, 0x08, 0x14, 0x07, 0x08, +0x07, 0x08, 0x7c, 0x12, 0x01, 0x6e, 0x12, 0x01, 0x12, 0x0d, +0x0c, 0x0b, 0x12, 0x0b, 0x0d, 0x78, 0x0c, 0x0b, 0x14, 0x0c, +0x0b, 0x0c, 0x0a, 0x1f, 0x52, 0x13, 0x14, 0x13, 0x7b, 0x0b, +0x0a, 0x14, 0x0b, 0x0b, 0x0a, 0x09, 0x1f, 0x52, 0x00, 0x14, +0x00, 0x7b, 0x08, 0x09, 0x14, 0x08, 0x08, 0x09, 0xbb, 0x08, +0x01, 0x08, 0x15, 0xb4, 0x0b, 0x01, 0x0b, 0x16, 0x14, 0x14, +0x15, 0x16, 0x0b, 0x13, 0x44, 0x0d, 0x0c, 0x41, 0x14, 0x0a, +0x09, 0x09, 0x07, 0x06, 0x41, 0x08, 0x00, 0x44, 0x00, 0x3f, +0x32, 0x3f, 0x33, 0x33, 0x2f, 0x33, 0x33, 0x3f, 0x33, 0x3f, +0x33, 0x01, 0x11, 0x12, 0x39, 0x3d, 0x2f, 0x12, 0x39, 0x5d, +0x12, 0x39, 0x5d, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x2b, 0xc4, +0x87, 0x18, 0x10, 0x2b, 0x87, 0x2b, 0xc4, 0x01, 0x18, 0xd5, +0x87, 0x2b, 0x10, 0x00, 0xc1, 0x87, 0x05, 0x7d, 0x10, 0xc4, +0x01, 0x71, 0x71, 0x18, 0x10, 0xd5, 0x87, 0x2b, 0x10, 0x00, +0xc1, 0x87, 0x05, 0x7d, 0x10, 0xc4, 0x31, 0x30, 0x00, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x33, +0x23, 0x2e, 0x03, 0x27, 0x33, 0x13, 0x13, 0x33, 0x13, 0x13, +0x33, 0x0e, 0x03, 0x07, 0x23, 0x03, 0x99, 0x4d, 0x09, 0x0d, +0x0b, 0x08, 0x03, 0x50, 0x0b, 0x5a, 0x48, 0x5c, 0x0b, 0x50, +0x03, 0x09, 0x0c, 0x0e, 0x08, 0x4c, 0x61, 0x3d, 0x93, 0xa0, +0xa8, 0x53, 0xfd, 0xfb, 0x01, 0x1a, 0xfe, 0xe6, 0x02, 0x05, +0x54, 0xa8, 0x9f, 0x92, 0x3e, 0x01, 0x34, 0x00, 0x00, 0x01, +0x00, 0x19, 0x00, 0x00, 0x01, 0xdb, 0x02, 0x6b, 0x00, 0x15, +0x00, 0x6c, 0x40, 0x41, 0x12, 0x15, 0x0e, 0x08, 0x11, 0x0f, +0x09, 0x10, 0x15, 0x0e, 0x0c, 0x09, 0x10, 0x0d, 0x00, 0x05, +0x08, 0x11, 0x0d, 0x00, 0x08, 0x10, 0x09, 0x10, 0x78, 0x11, +0x08, 0x14, 0x11, 0x08, 0x11, 0x11, 0x15, 0x01, 0x0d, 0x00, +0x00, 0x0e, 0x15, 0x0e, 0x78, 0x0d, 0x00, 0x14, 0x0d, 0x0d, +0x00, 0x15, 0x17, 0x0d, 0x0d, 0x09, 0x16, 0x11, 0x10, 0x41, +0x0e, 0x0d, 0x41, 0x09, 0x08, 0x44, 0x15, 0x00, 0x44, 0x00, +0x3f, 0x32, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0x33, 0x01, 0x10, +0xc6, 0x32, 0x2f, 0x10, 0xce, 0x87, 0x10, 0x2b, 0x87, 0x7d, +0xc4, 0x87, 0x0e, 0xc4, 0x01, 0x11, 0x33, 0x18, 0x2f, 0x87, +0x2b, 0x87, 0x7d, 0xc4, 0x0f, 0x0f, 0x0f, 0x0f, 0x31, 0x30, +0x21, 0x2e, 0x03, 0x27, 0x06, 0x06, 0x07, 0x23, 0x36, 0x36, +0x37, 0x03, 0x33, 0x17, 0x37, 0x33, 0x03, 0x16, 0x16, 0x17, +0x01, 0x80, 0x0b, 0x1e, 0x22, 0x27, 0x15, 0x23, 0x46, 0x1e, +0x59, 0x21, 0x58, 0x32, 0xa1, 0x5b, 0x79, 0x82, 0x59, 0xa4, +0x30, 0x5a, 0x23, 0x1b, 0x44, 0x48, 0x48, 0x1f, 0x38, 0x91, +0x45, 0x4a, 0xad, 0x50, 0x01, 0x24, 0xed, 0xed, 0xfe, 0xdf, +0x4e, 0xa8, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0d, +0x00, 0x00, 0x01, 0xe8, 0x02, 0x6b, 0x00, 0x10, 0x00, 0x4d, +0x40, 0x29, 0x08, 0x0b, 0x08, 0x05, 0x0b, 0x78, 0x0c, 0x0f, +0x14, 0x0c, 0x0f, 0x0c, 0x0f, 0x73, 0x01, 0x08, 0x05, 0x05, +0x78, 0x04, 0x01, 0x14, 0x04, 0x01, 0x04, 0x01, 0x01, 0x11, +0x12, 0x0c, 0x0b, 0x41, 0x0f, 0x08, 0x01, 0x01, 0x05, 0x04, +0x41, 0x00, 0x44, 0x00, 0x3f, 0x3f, 0x33, 0x39, 0x11, 0x33, +0x33, 0x3f, 0x33, 0x01, 0x11, 0x12, 0x39, 0x2f, 0xdd, 0x87, +0x2b, 0x7d, 0x10, 0xc4, 0x01, 0x18, 0x10, 0xfd, 0xdd, 0x87, +0x2b, 0x08, 0x7d, 0x10, 0xc4, 0x31, 0x30, 0x33, 0x35, 0x26, +0x26, 0x27, 0x33, 0x16, 0x16, 0x17, 0x36, 0x36, 0x37, 0x33, +0x06, 0x06, 0x07, 0x15, 0xd2, 0x3d, 0x63, 0x25, 0x5c, 0x1d, +0x4b, 0x2b, 0x2e, 0x47, 0x1d, 0x5a, 0x26, 0x62, 0x3c, 0xe6, +0x64, 0xbe, 0x63, 0x54, 0x99, 0x51, 0x55, 0x99, 0x50, 0x62, +0xba, 0x67, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, +0x00, 0x00, 0x01, 0xc7, 0x02, 0x6b, 0x00, 0x11, 0x00, 0x37, +0x40, 0x1d, 0x05, 0x0e, 0x09, 0x0e, 0x78, 0x00, 0x05, 0x14, +0x00, 0x00, 0x05, 0x06, 0x06, 0x00, 0x13, 0x0f, 0x0f, 0x09, +0x12, 0x00, 0x0e, 0x79, 0x10, 0x41, 0x09, 0x05, 0x79, 0x08, +0x44, 0x00, 0x3f, 0xed, 0x32, 0x3f, 0xed, 0x32, 0x01, 0x10, +0xc6, 0x32, 0x2f, 0x10, 0xce, 0x32, 0x2f, 0x87, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x31, 0x30, 0x01, 0x0e, 0x03, 0x07, 0x21, +0x15, 0x21, 0x35, 0x3e, 0x03, 0x37, 0x21, 0x35, 0x21, 0x01, +0xbf, 0x20, 0x4f, 0x52, 0x4d, 0x1d, 0x01, 0x33, 0xfe, 0x6f, +0x1f, 0x4b, 0x4e, 0x4e, 0x24, 0xfe, 0xe5, 0x01, 0x7a, 0x02, +0x2b, 0x2c, 0x79, 0x84, 0x85, 0x37, 0x46, 0x36, 0x3f, 0x85, +0x80, 0x78, 0x33, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x8f, +0xff, 0x5b, 0x01, 0x7e, 0x02, 0xbb, 0x00, 0x07, 0x00, 0x1b, +0x40, 0x0b, 0x02, 0x02, 0x05, 0x04, 0x07, 0x08, 0x04, 0x07, +0x03, 0x00, 0x5a, 0x00, 0x3f, 0xcd, 0x2f, 0xcd, 0x01, 0x10, +0xd6, 0xdd, 0xcd, 0x32, 0x2f, 0x31, 0x30, 0x13, 0x33, 0x15, +0x23, 0x11, 0x33, 0x15, 0x23, 0x8f, 0xef, 0xa1, 0xa1, 0xef, +0x02, 0xbb, 0x41, 0xfd, 0x22, 0x41, 0x00, 0x01, 0x00, 0x46, +0xff, 0x5b, 0x01, 0xae, 0x02, 0xbb, 0x00, 0x03, 0x00, 0x21, +0x40, 0x10, 0x01, 0x03, 0x00, 0x03, 0x8d, 0x02, 0x01, 0x14, +0x02, 0x01, 0x02, 0x00, 0x03, 0x02, 0x01, 0x00, 0x00, 0x2f, +0x32, 0x2f, 0x33, 0x01, 0x2f, 0x2f, 0x87, 0x2b, 0x87, 0x7d, +0xc4, 0x31, 0x30, 0x13, 0x33, 0x01, 0x23, 0x46, 0x53, 0x01, +0x15, 0x54, 0x02, 0xbb, 0xfc, 0xa0, 0x00, 0x01, 0x00, 0x76, +0xff, 0x5b, 0x01, 0x65, 0x02, 0xbb, 0x00, 0x07, 0x00, 0x1b, +0x40, 0x0b, 0x05, 0x05, 0x02, 0x03, 0x00, 0x09, 0x04, 0x07, +0x5a, 0x03, 0x00, 0x00, 0x2f, 0xcd, 0x3f, 0xcd, 0x01, 0x10, +0xd6, 0xdd, 0xcd, 0x32, 0x2f, 0x31, 0x30, 0x05, 0x23, 0x35, +0x33, 0x11, 0x23, 0x35, 0x33, 0x01, 0x65, 0xef, 0xa1, 0xa1, +0xef, 0xa5, 0x41, 0x02, 0xde, 0x41, 0x00, 0x01, 0x00, 0x28, +0x01, 0x19, 0x01, 0xcc, 0x02, 0x6b, 0x00, 0x06, 0x00, 0x41, +0xb9, 0x00, 0x04, 0xff, 0xf0, 0x40, 0x21, 0x0e, 0x00, 0x4d, +0x02, 0x10, 0x0e, 0x00, 0x4d, 0x03, 0x38, 0x10, 0x00, 0x4d, +0x03, 0x30, 0x0f, 0x00, 0x4d, 0x03, 0x20, 0x0e, 0x00, 0x4d, +0x04, 0x05, 0x03, 0x02, 0x01, 0x03, 0x02, 0x04, 0x03, 0x06, +0x00, 0x2f, 0x33, 0xcd, 0x32, 0x01, 0x19, 0x2f, 0xdd, 0x18, +0xcd, 0x19, 0x10, 0xdd, 0x18, 0xcd, 0x31, 0x30, 0x00, 0x2b, +0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x01, 0x13, 0x07, 0x27, 0x07, +0x27, 0x13, 0x01, 0x1f, 0xad, 0x42, 0x90, 0x90, 0x42, 0xad, +0x02, 0x6b, 0xfe, 0xd0, 0x22, 0xfc, 0xfc, 0x22, 0x01, 0x30, +0x00, 0x01, 0x00, 0x08, 0xff, 0x5b, 0x01, 0xec, 0xff, 0xa1, +0x00, 0x03, 0x00, 0x0f, 0xb4, 0x01, 0x00, 0x03, 0x00, 0x04, +0x00, 0x10, 0xde, 0xcd, 0x01, 0x2f, 0x2f, 0x31, 0x30, 0x17, +0x21, 0x15, 0x21, 0x08, 0x01, 0xe4, 0xfe, 0x1c, 0x5f, 0x46, +0x00, 0x01, 0x00, 0xa3, 0x02, 0x06, 0x01, 0x4a, 0x02, 0xb5, +0x00, 0x03, 0x00, 0x18, 0x40, 0x09, 0x00, 0x03, 0x02, 0x01, +0x03, 0x00, 0x80, 0x01, 0x02, 0x00, 0x2f, 0x33, 0x1a, 0xcd, +0x32, 0x01, 0x2f, 0x33, 0xcd, 0x32, 0x31, 0x30, 0x13, 0x17, +0x07, 0x27, 0xd8, 0x72, 0x2a, 0x7d, 0x02, 0xb5, 0x8a, 0x25, +0x7a, 0x00, 0x00, 0x02, 0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb0, +0x01, 0xdb, 0x00, 0x0e, 0x00, 0x30, 0x00, 0x73, 0x40, 0x16, +0x28, 0x18, 0x12, 0x00, 0x4d, 0x1f, 0x18, 0x0a, 0x0b, 0x00, +0x4c, 0x1b, 0x20, 0x0b, 0x00, 0x4d, 0x1b, 0x18, 0x0a, 0x00, +0x4d, 0x12, 0xb8, 0xff, 0xe8, 0xb4, 0x0a, 0x0c, 0x00, 0x4c, +0x12, 0xb8, 0xff, 0xe0, 0xb4, 0x08, 0x09, 0x00, 0x4c, 0x0a, +0xb8, 0xff, 0xe8, 0x40, 0x24, 0x11, 0x12, 0x00, 0x4c, 0x04, +0x24, 0x7f, 0x14, 0x32, 0x2e, 0x2e, 0x0c, 0x82, 0x1d, 0x31, +0x07, 0x89, 0x00, 0x22, 0x10, 0x22, 0x02, 0x08, 0x22, 0x22, +0x0f, 0x00, 0x88, 0x18, 0x51, 0x2d, 0x2d, 0x2a, 0x88, 0x0f, +0x50, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x11, 0x39, +0x2f, 0x5e, 0x5d, 0xed, 0x01, 0x10, 0xd6, 0xed, 0x33, 0x2f, +0x10, 0xde, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x37, 0x32, 0x36, 0x37, 0x35, 0x26, 0x26, +0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x16, 0x13, 0x32, 0x1e, +0x02, 0x15, 0x11, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x34, 0x3e, 0x02, 0x33, 0x32, 0x17, 0x35, 0x34, 0x2e, 0x02, +0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0xff, 0x1f, 0x31, +0x10, 0x10, 0x2d, 0x19, 0x17, 0x2c, 0x22, 0x16, 0x3d, 0x2c, +0x34, 0x47, 0x2c, 0x12, 0x1d, 0x5f, 0x32, 0x26, 0x48, 0x38, +0x22, 0x23, 0x37, 0x47, 0x24, 0x31, 0x2f, 0x09, 0x19, 0x2b, +0x22, 0x2b, 0x40, 0x11, 0x0a, 0x11, 0x4f, 0x3b, 0x04, 0x03, +0x8a, 0x05, 0x06, 0x07, 0x12, 0x1d, 0x16, 0x2d, 0x23, 0x01, +0xa0, 0x1a, 0x2e, 0x42, 0x27, 0xfe, 0xde, 0x05, 0x0e, 0x0d, +0x21, 0x3a, 0x2d, 0x28, 0x37, 0x22, 0x0f, 0x0b, 0x17, 0x15, +0x27, 0x20, 0x13, 0x0c, 0x06, 0x44, 0x08, 0x0c, 0x00, 0x02, +0x00, 0x47, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0xb5, 0x00, 0x12, +0x00, 0x21, 0x00, 0x7e, 0x40, 0x2a, 0x1c, 0x30, 0x10, 0x00, +0x4d, 0x1c, 0x20, 0x0f, 0x00, 0x4d, 0x1c, 0x18, 0x0e, 0x00, +0x4d, 0x17, 0x30, 0x10, 0x00, 0x4d, 0x17, 0x38, 0x0f, 0x00, +0x4d, 0x17, 0x18, 0x0d, 0x0e, 0x00, 0x4c, 0x0a, 0x10, 0x10, +0x00, 0x4d, 0x0a, 0x18, 0x0f, 0x00, 0x4d, 0x06, 0xb8, 0xff, +0xe8, 0xb3, 0x08, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xf0, 0xb3, +0x0a, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe8, 0x40, 0x1d, 0x09, +0x00, 0x4d, 0x19, 0x82, 0x08, 0x23, 0x00, 0x13, 0x7f, 0x00, +0x10, 0x01, 0x08, 0x10, 0x22, 0x11, 0x12, 0x4d, 0x16, 0x88, +0x0d, 0x51, 0x21, 0x1e, 0x88, 0x00, 0x03, 0x50, 0x00, 0x3f, +0x33, 0xed, 0x32, 0x3f, 0xed, 0x3f, 0x33, 0x01, 0x10, 0xd6, +0x5e, 0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x13, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, +0x02, 0x23, 0x22, 0x26, 0x27, 0x11, 0x37, 0x11, 0x16, 0x16, +0x33, 0x32, 0x36, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, +0x07, 0x9a, 0x0f, 0x39, 0x23, 0x2f, 0x4a, 0x33, 0x1b, 0x20, +0x3a, 0x52, 0x32, 0x37, 0x56, 0x1a, 0x53, 0x13, 0x26, 0x11, +0x45, 0x4e, 0x0e, 0x1e, 0x2f, 0x21, 0x1d, 0x36, 0x0e, 0x01, +0xbf, 0x09, 0x13, 0x24, 0x40, 0x59, 0x36, 0x38, 0x5a, 0x3f, +0x22, 0x10, 0x08, 0x02, 0x9a, 0x0e, 0xfd, 0x93, 0x05, 0x05, +0x55, 0x55, 0x24, 0x3f, 0x2d, 0x1a, 0x17, 0x0d, 0x00, 0x00, +0x00, 0x01, 0x00, 0x31, 0xff, 0xf5, 0x01, 0xc3, 0x01, 0xdb, +0x00, 0x21, 0x00, 0x43, 0xb9, 0x00, 0x14, 0xff, 0xe0, 0xb4, +0x0d, 0x0e, 0x00, 0x4c, 0x0e, 0xb8, 0xff, 0xe0, 0x40, 0x1d, +0x0d, 0x0e, 0x00, 0x4c, 0x08, 0x08, 0x1a, 0x23, 0x11, 0x82, +0x0f, 0x00, 0x1f, 0x00, 0x02, 0x00, 0x22, 0x19, 0x19, 0x16, +0x88, 0x1d, 0x51, 0x09, 0x09, 0x0c, 0x88, 0x05, 0x50, 0x00, +0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x32, 0x2f, 0x01, 0x10, +0xd6, 0x5d, 0xed, 0x10, 0xce, 0x32, 0x2f, 0x31, 0x30, 0x2b, +0x2b, 0x37, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x07, +0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, +0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x06, 0x23, 0x22, 0x2e, +0x02, 0x31, 0x28, 0x46, 0x5d, 0x35, 0x22, 0x43, 0x26, 0x13, +0x21, 0x37, 0x1c, 0x24, 0x40, 0x2f, 0x1c, 0x1a, 0x2f, 0x42, +0x28, 0x20, 0x3b, 0x23, 0x0c, 0x23, 0x48, 0x2a, 0x38, 0x5d, +0x43, 0x25, 0xe7, 0x3f, 0x5c, 0x3c, 0x1d, 0x09, 0x0c, 0x47, +0x0c, 0x07, 0x13, 0x29, 0x41, 0x2e, 0x2c, 0x3f, 0x29, 0x14, +0x07, 0x0c, 0x45, 0x0d, 0x0b, 0x1f, 0x3c, 0x5b, 0x00, 0x02, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xad, 0x02, 0xb5, 0x00, 0x0e, +0x00, 0x21, 0x00, 0x61, 0x40, 0x12, 0x1c, 0x20, 0x0f, 0x10, +0x00, 0x4c, 0x1b, 0x10, 0x0a, 0x00, 0x4d, 0x1b, 0x18, 0x08, +0x09, 0x00, 0x4c, 0x0a, 0xb8, 0xff, 0xd8, 0xb3, 0x0e, 0x00, +0x4d, 0x0a, 0xb8, 0xff, 0xf0, 0xb3, 0x0d, 0x00, 0x4d, 0x05, +0xb8, 0xff, 0xf0, 0x40, 0x1e, 0x0e, 0x00, 0x4d, 0x21, 0x0e, +0x7f, 0x11, 0x23, 0x08, 0x82, 0x19, 0x40, 0x09, 0x0c, 0x48, +0x19, 0x22, 0x00, 0x03, 0x88, 0x21, 0x1e, 0x50, 0x0b, 0x88, +0x14, 0x51, 0x0f, 0x10, 0x4d, 0x00, 0x3f, 0x33, 0x3f, 0xed, +0x3f, 0x33, 0xed, 0x32, 0x01, 0x10, 0xd6, 0x2b, 0xed, 0x10, +0xde, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x01, 0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, +0x16, 0x33, 0x32, 0x36, 0x37, 0x11, 0x37, 0x11, 0x06, 0x06, +0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, +0x16, 0x17, 0x01, 0x5a, 0x0e, 0x36, 0x1d, 0x21, 0x2f, 0x1e, +0x0e, 0x4c, 0x3d, 0x1f, 0x2b, 0x0a, 0x53, 0x1b, 0x54, 0x38, +0x32, 0x52, 0x3a, 0x20, 0x1b, 0x34, 0x49, 0x2f, 0x25, 0x38, +0x0e, 0x01, 0x6e, 0x0d, 0x17, 0x1a, 0x2d, 0x3f, 0x24, 0x51, +0x58, 0x06, 0x03, 0x02, 0x5f, 0x0e, 0xfd, 0x58, 0x08, 0x10, +0x22, 0x3f, 0x5a, 0x38, 0x36, 0x59, 0x40, 0x24, 0x12, 0x0a, +0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xc7, +0x01, 0xdb, 0x00, 0x18, 0x00, 0x21, 0x00, 0xcf, 0xb9, 0x00, +0x1e, 0xff, 0xd8, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x1e, 0xb8, +0xff, 0xe0, 0x40, 0x0e, 0x0e, 0x00, 0x4d, 0x1b, 0x18, 0x10, +0x00, 0x4d, 0x1b, 0x10, 0x0f, 0x00, 0x4d, 0x16, 0xb8, 0xff, +0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x16, 0xb8, 0xff, 0xf0, 0x40, +0x09, 0x0f, 0x00, 0x4d, 0x16, 0x10, 0x08, 0x00, 0x4d, 0x12, +0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x11, 0xb8, 0xff, +0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xe8, 0xb3, +0x10, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xd0, 0xb3, 0x0f, 0x00, +0x4d, 0x07, 0xb8, 0xff, 0xe0, 0xb4, 0x0d, 0x0e, 0x00, 0x4c, +0x02, 0xb8, 0xff, 0xe8, 0xb3, 0x09, 0x00, 0x4d, 0x02, 0xb8, +0xff, 0xe0, 0xb3, 0x08, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xd8, +0xb3, 0x12, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xd0, 0xb3, 0x11, +0x00, 0x4d, 0x01, 0xb8, 0xff, 0xf0, 0x40, 0x23, 0x0a, 0x00, +0x4d, 0x19, 0x82, 0x04, 0x0c, 0x0c, 0x04, 0x23, 0x21, 0x05, +0x82, 0x14, 0x40, 0x09, 0x0c, 0x48, 0x14, 0x22, 0x05, 0x86, +0x21, 0x21, 0x00, 0x0b, 0x0b, 0x08, 0x88, 0x0f, 0x51, 0x1c, +0x88, 0x00, 0x50, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x32, 0x2f, +0x11, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xd6, 0x2b, 0xed, 0x32, +0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x32, 0x16, 0x15, 0x15, +0x21, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x06, +0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x17, 0x34, +0x26, 0x23, 0x22, 0x0e, 0x02, 0x07, 0x01, 0x03, 0x5e, 0x66, +0xfe, 0xb4, 0x05, 0x55, 0x4d, 0x2c, 0x3e, 0x10, 0x0b, 0x0f, +0x4e, 0x31, 0x3c, 0x5b, 0x3c, 0x1e, 0x26, 0x3e, 0x4e, 0x99, +0x3e, 0x33, 0x1d, 0x2f, 0x22, 0x14, 0x03, 0x01, 0xdb, 0x75, +0x77, 0x1d, 0x48, 0x4b, 0x0e, 0x08, 0x46, 0x08, 0x12, 0x25, +0x40, 0x59, 0x34, 0x3e, 0x5c, 0x3c, 0x1e, 0xc6, 0x3b, 0x45, +0x16, 0x24, 0x2e, 0x18, 0x00, 0x01, 0x00, 0x3f, 0x00, 0x00, +0x01, 0xe2, 0x02, 0xb5, 0x00, 0x1b, 0x00, 0x56, 0xb9, 0x00, +0x14, 0xff, 0xf0, 0xb3, 0x11, 0x00, 0x4d, 0x13, 0xb8, 0xff, +0xe0, 0x40, 0x2a, 0x12, 0x00, 0x4d, 0x07, 0x10, 0x0c, 0x00, +0x4d, 0x07, 0x18, 0x0a, 0x00, 0x4d, 0x0d, 0x0d, 0x19, 0x1d, +0x17, 0x1a, 0x7f, 0x04, 0x01, 0x00, 0x02, 0x01, 0x08, 0x02, +0x1c, 0x0e, 0x0e, 0x11, 0x88, 0x0a, 0x4d, 0x1a, 0x01, 0x85, +0x17, 0x04, 0x49, 0x00, 0x4a, 0x00, 0x3f, 0x3f, 0x33, 0xed, +0x32, 0x3f, 0xed, 0x32, 0x2f, 0x01, 0x10, 0xd6, 0x5e, 0x5d, +0xd5, 0x32, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x33, 0x11, 0x23, 0x35, 0x33, 0x35, +0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x26, +0x23, 0x22, 0x0e, 0x02, 0x15, 0x15, 0x33, 0x15, 0x23, 0x11, +0xa1, 0x62, 0x62, 0x1e, 0x31, 0x41, 0x24, 0x24, 0x49, 0x20, +0x0f, 0x16, 0x42, 0x22, 0x15, 0x25, 0x1c, 0x10, 0xbb, 0xbb, +0x01, 0x8b, 0x45, 0x2a, 0x36, 0x47, 0x2c, 0x12, 0x10, 0x0b, +0x47, 0x0b, 0x10, 0x0b, 0x1b, 0x2d, 0x22, 0x29, 0x45, 0xfe, +0x75, 0x00, 0x00, 0x02, 0x00, 0x28, 0xff, 0x58, 0x01, 0xad, +0x01, 0xdb, 0x00, 0x1e, 0x00, 0x2d, 0x00, 0xc2, 0xb9, 0x00, +0x28, 0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x28, 0xb8, 0xff, +0xe8, 0xb3, 0x0f, 0x00, 0x4d, 0x28, 0xb8, 0xff, 0xf0, 0xb3, +0x0e, 0x00, 0x4d, 0x23, 0xb8, 0xff, 0xd0, 0xb3, 0x10, 0x00, +0x4d, 0x23, 0xb8, 0xff, 0xd8, 0xb3, 0x0f, 0x00, 0x4d, 0x23, +0xb8, 0xff, 0xf0, 0xb3, 0x0e, 0x00, 0x4d, 0x23, 0xb8, 0xff, +0xe8, 0xb3, 0x0d, 0x00, 0x4d, 0x23, 0xb8, 0xff, 0xf0, 0x40, +0x09, 0x0c, 0x00, 0x4d, 0x1c, 0x18, 0x10, 0x00, 0x4d, 0x12, +0xb8, 0xff, 0xf0, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x12, 0xb8, +0xff, 0xe0, 0xb4, 0x08, 0x09, 0x00, 0x4c, 0x0a, 0xb8, 0xff, +0xf0, 0x40, 0x39, 0x0f, 0x10, 0x00, 0x4c, 0x0a, 0x10, 0x09, +0x00, 0x4d, 0x0a, 0x18, 0x08, 0x00, 0x4d, 0x06, 0x18, 0x09, +0x00, 0x4d, 0x06, 0x20, 0x08, 0x00, 0x4d, 0x2d, 0x1e, 0x7f, +0x11, 0x2f, 0x25, 0x82, 0x08, 0x17, 0x17, 0x08, 0x2e, 0x2a, +0x88, 0x0f, 0x03, 0x1f, 0x03, 0x02, 0x08, 0x03, 0x03, 0x2e, +0x18, 0x18, 0x1b, 0x88, 0x14, 0x4b, 0x22, 0x88, 0x0d, 0x50, +0x00, 0x3f, 0xed, 0x3f, 0xed, 0x32, 0x2f, 0x11, 0x33, 0x2f, +0x5e, 0x5d, 0xed, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xed, +0x10, 0xde, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x25, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x11, 0x14, 0x06, +0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, +0x35, 0x11, 0x26, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x1e, +0x02, 0x33, 0x32, 0x36, 0x37, 0x01, 0x5a, 0x0e, 0x3a, 0x26, +0x29, 0x47, 0x35, 0x1f, 0x1d, 0x37, 0x50, 0x33, 0x3c, 0x55, +0x1d, 0x6d, 0x6e, 0x2d, 0x49, 0x1c, 0x0f, 0x1a, 0x43, 0x28, +0x48, 0x3e, 0x0c, 0x2a, 0x24, 0x40, 0x43, 0x13, 0x21, 0x2a, +0x18, 0x1f, 0x37, 0x11, 0x2b, 0x08, 0x12, 0x1b, 0x37, 0x55, +0x3a, 0x33, 0x55, 0x3e, 0x23, 0x11, 0x08, 0xfe, 0x62, 0x6c, +0x60, 0x0e, 0x0a, 0x49, 0x0b, 0x0e, 0x3a, 0x41, 0x01, 0x6c, +0x04, 0x07, 0x58, 0x49, 0x28, 0x39, 0x25, 0x11, 0x12, 0x0c, +0x00, 0x01, 0x00, 0x47, 0x00, 0x00, 0x01, 0xb0, 0x02, 0xb5, +0x00, 0x15, 0x00, 0x60, 0x40, 0x15, 0x10, 0x20, 0x12, 0x00, +0x4d, 0x10, 0x28, 0x11, 0x00, 0x4d, 0x10, 0x18, 0x10, 0x00, +0x4d, 0x10, 0x10, 0x0f, 0x00, 0x4d, 0x09, 0xb8, 0xff, 0xd8, +0xb3, 0x08, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, +0x00, 0x4d, 0x08, 0xb8, 0xff, 0xd8, 0x40, 0x1a, 0x09, 0x00, +0x4d, 0x0d, 0x7f, 0x0c, 0x17, 0x03, 0x15, 0x7f, 0x00, 0x00, +0x01, 0x08, 0x00, 0x16, 0x11, 0x88, 0x06, 0x50, 0x01, 0x02, +0x4d, 0x0d, 0x00, 0x4a, 0x00, 0x3f, 0x32, 0x3f, 0x33, 0x3f, +0xed, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x10, 0xde, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x33, 0x11, 0x37, 0x15, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, +0x15, 0x11, 0x23, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, +0x11, 0x47, 0x53, 0x14, 0x32, 0x18, 0x35, 0x47, 0x2a, 0x12, +0x52, 0x30, 0x3e, 0x1a, 0x31, 0x0b, 0x02, 0xa7, 0x0e, 0xec, +0x08, 0x09, 0x1f, 0x38, 0x4e, 0x2f, 0xfe, 0xfa, 0xf4, 0x56, +0x47, 0x0b, 0x05, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x02, +0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0x9e, 0x00, 0x0b, +0x00, 0x21, 0x00, 0x44, 0x40, 0x29, 0x1f, 0x18, 0x0b, 0x0d, +0x00, 0x4c, 0x1f, 0x28, 0x0a, 0x00, 0x4d, 0x1f, 0x20, 0x09, +0x00, 0x4d, 0x03, 0x83, 0x09, 0x0f, 0x7f, 0x0c, 0x0c, 0x0d, +0x17, 0x23, 0x0d, 0x22, 0x16, 0x16, 0x13, 0x88, 0x1c, 0x51, +0x06, 0x8a, 0x00, 0x0c, 0x85, 0x0f, 0x49, 0x00, 0x3f, 0xed, +0xde, 0xed, 0x3f, 0xed, 0x32, 0x2f, 0x01, 0x10, 0xc6, 0x10, +0xce, 0x11, 0x39, 0x2f, 0xfd, 0xd4, 0xed, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x13, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, +0x16, 0x15, 0x14, 0x06, 0x07, 0x23, 0x35, 0x33, 0x11, 0x14, +0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x0e, 0x03, 0x23, 0x22, +0x2e, 0x02, 0x35, 0xd1, 0x1a, 0x26, 0x26, 0x1a, 0x1b, 0x25, +0x25, 0x30, 0x86, 0xd8, 0x26, 0x26, 0x1d, 0x31, 0x0e, 0x0c, +0x06, 0x16, 0x1d, 0x23, 0x13, 0x2c, 0x3a, 0x23, 0x0e, 0x02, +0x18, 0x24, 0x1f, 0x1f, 0x24, 0x24, 0x1f, 0x1f, 0x24, 0x8d, +0x45, 0xfe, 0xe3, 0x45, 0x2f, 0x0e, 0x08, 0x46, 0x03, 0x09, +0x08, 0x06, 0x18, 0x30, 0x47, 0x2f, 0x00, 0x02, 0x00, 0x47, +0xff, 0x56, 0x01, 0x80, 0x02, 0x9e, 0x00, 0x0b, 0x00, 0x1f, +0x00, 0x39, 0xb9, 0x00, 0x11, 0xff, 0xe8, 0x40, 0x1c, 0x09, +0x0a, 0x00, 0x4c, 0x09, 0x83, 0x03, 0x03, 0x1e, 0x7f, 0x0f, +0x21, 0x17, 0x17, 0x0c, 0x20, 0x18, 0x1b, 0x88, 0x14, 0x52, +0x06, 0x8a, 0x00, 0x1f, 0x85, 0x0e, 0x49, 0x00, 0x3f, 0xed, +0xde, 0xed, 0x3f, 0xed, 0x32, 0x01, 0x10, 0xc6, 0x32, 0x2f, +0x10, 0xde, 0xed, 0x32, 0x2f, 0xed, 0x31, 0x30, 0x2b, 0x01, +0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, +0x06, 0x07, 0x35, 0x21, 0x11, 0x14, 0x0e, 0x02, 0x23, 0x22, +0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, +0x01, 0x34, 0x1a, 0x26, 0x26, 0x1a, 0x1b, 0x25, 0x25, 0xdd, +0x01, 0x0e, 0x1b, 0x2d, 0x3b, 0x21, 0x26, 0x4d, 0x22, 0x19, +0x19, 0x3d, 0x1c, 0x28, 0x34, 0x02, 0x18, 0x24, 0x1f, 0x1f, +0x24, 0x24, 0x1f, 0x1f, 0x24, 0x8d, 0x45, 0xfe, 0x35, 0x30, +0x43, 0x2a, 0x12, 0x10, 0x11, 0x46, 0x0c, 0x11, 0x29, 0x3b, +0x01, 0x87, 0x00, 0x01, 0x00, 0x47, 0x00, 0x00, 0x01, 0xde, +0x02, 0xb5, 0x00, 0x16, 0x00, 0x65, 0x40, 0x36, 0x06, 0x00, +0x05, 0x00, 0x81, 0x0b, 0x06, 0x14, 0x0b, 0x00, 0x14, 0x0b, +0x06, 0x13, 0x10, 0x00, 0x14, 0x13, 0x14, 0x00, 0x81, 0x10, +0x13, 0x14, 0x10, 0x13, 0x00, 0x10, 0x14, 0x14, 0x05, 0x18, +0x10, 0x0b, 0x7f, 0x00, 0x0d, 0x01, 0x08, 0x0d, 0x17, 0x0b, +0x10, 0x05, 0x14, 0x49, 0x0e, 0x0f, 0x4d, 0x0d, 0x4a, 0x05, +0x06, 0x4a, 0x00, 0x3f, 0x33, 0x3f, 0x3f, 0x33, 0x3f, 0x12, +0x39, 0x39, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x10, +0xce, 0x32, 0x2f, 0x10, 0xc1, 0x87, 0x04, 0x2b, 0x10, 0x00, +0xc1, 0x87, 0x05, 0x7d, 0x10, 0xc4, 0x87, 0x08, 0x18, 0x10, +0x2b, 0x87, 0x05, 0x7d, 0xc4, 0x31, 0x30, 0x37, 0x1e, 0x03, +0x17, 0x23, 0x2e, 0x03, 0x27, 0x15, 0x23, 0x11, 0x37, 0x11, +0x36, 0x36, 0x37, 0x33, 0x06, 0x06, 0xee, 0x1b, 0x44, 0x43, +0x3c, 0x12, 0x62, 0x13, 0x38, 0x3f, 0x3f, 0x19, 0x53, 0x53, +0x37, 0x6e, 0x2c, 0x61, 0x2b, 0x79, 0xff, 0x14, 0x3d, 0x46, +0x49, 0x1f, 0x1f, 0x41, 0x3c, 0x32, 0x11, 0xdf, 0x02, 0xa7, +0x0e, 0xfe, 0x59, 0x30, 0x5f, 0x33, 0x33, 0x6c, 0x00, 0x01, +0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0xb0, 0x00, 0x17, +0x00, 0x45, 0x40, 0x2c, 0x03, 0x18, 0x0e, 0x00, 0x4d, 0x03, +0x20, 0x0d, 0x00, 0x4d, 0x03, 0x18, 0x0c, 0x00, 0x4d, 0x03, +0x20, 0x0b, 0x00, 0x4d, 0x03, 0x20, 0x09, 0x00, 0x4d, 0x09, +0x7f, 0x06, 0x06, 0x07, 0x13, 0x19, 0x07, 0x18, 0x06, 0x85, +0x09, 0x4d, 0x12, 0x12, 0x0f, 0x88, 0x00, 0x51, 0x00, 0x3f, +0xed, 0x32, 0x2f, 0x3f, 0xed, 0x01, 0x10, 0xc6, 0x10, 0xce, +0x11, 0x39, 0x2f, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x05, 0x22, 0x2e, 0x02, 0x35, 0x11, 0x23, 0x35, 0x33, +0x11, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x36, 0x37, 0x17, 0x0e, +0x03, 0x01, 0x52, 0x2c, 0x3a, 0x22, 0x0e, 0x86, 0xd8, 0x09, +0x13, 0x1c, 0x13, 0x1d, 0x32, 0x0e, 0x0c, 0x06, 0x16, 0x1e, +0x23, 0x0b, 0x18, 0x30, 0x47, 0x2f, 0x01, 0xb7, 0x46, 0xfe, +0x03, 0x23, 0x2c, 0x1b, 0x0a, 0x0e, 0x08, 0x46, 0x03, 0x09, +0x08, 0x06, 0x00, 0x01, 0x00, 0x29, 0x00, 0x00, 0x01, 0xd0, +0x01, 0xda, 0x00, 0x21, 0x00, 0x56, 0xb9, 0x00, 0x0a, 0xff, +0xe8, 0xb4, 0x0d, 0x10, 0x00, 0x4c, 0x0a, 0xb8, 0xff, 0xf0, +0xb3, 0x0c, 0x00, 0x4d, 0x0a, 0xb8, 0xff, 0xe8, 0x40, 0x21, +0x0b, 0x00, 0x4d, 0x15, 0x05, 0x18, 0x7f, 0x19, 0x19, 0x21, +0x0e, 0x7f, 0x0d, 0x23, 0x20, 0x7f, 0x21, 0x22, 0x19, 0x19, +0x0e, 0x21, 0x4a, 0x12, 0x88, 0x07, 0x50, 0x15, 0x1d, 0x88, +0x05, 0x02, 0x50, 0x00, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0xed, +0x3f, 0x33, 0x33, 0x2f, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, +0xed, 0x11, 0x39, 0x2f, 0xed, 0x32, 0x32, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x13, 0x36, 0x33, 0x32, 0x16, 0x17, 0x36, 0x33, +0x32, 0x1e, 0x02, 0x15, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, +0x22, 0x06, 0x07, 0x16, 0x15, 0x15, 0x23, 0x35, 0x34, 0x26, +0x23, 0x22, 0x07, 0x11, 0x23, 0x29, 0x3c, 0x35, 0x1d, 0x33, +0x12, 0x2b, 0x31, 0x18, 0x2b, 0x21, 0x14, 0x4b, 0x20, 0x18, +0x0c, 0x1a, 0x0b, 0x06, 0x4b, 0x16, 0x20, 0x14, 0x19, 0x4b, +0x01, 0xc3, 0x17, 0x11, 0x12, 0x23, 0x12, 0x24, 0x36, 0x24, +0xfe, 0xb6, 0x01, 0x4c, 0x24, 0x26, 0x0c, 0x0d, 0x17, 0x1c, +0x97, 0x98, 0x23, 0x28, 0x09, 0xfe, 0x73, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x47, 0x00, 0x00, 0x01, 0xb0, 0x01, 0xda, +0x00, 0x13, 0x00, 0x5e, 0x40, 0x0c, 0x0c, 0x08, 0x16, 0x00, +0x4d, 0x0c, 0x10, 0x0f, 0x10, 0x00, 0x4c, 0x05, 0xb8, 0xff, +0xe0, 0xb3, 0x12, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb3, +0x11, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb4, 0x08, 0x0a, +0x00, 0x4c, 0x04, 0xb8, 0xff, 0xe0, 0x40, 0x1b, 0x11, 0x00, +0x4d, 0x08, 0x7f, 0xef, 0x07, 0x01, 0x07, 0x15, 0x12, 0x7f, +0x00, 0x13, 0xe0, 0x13, 0x02, 0x08, 0x13, 0x14, 0x08, 0x13, +0x4a, 0x0e, 0x88, 0x03, 0x50, 0x00, 0x3f, 0xed, 0x3f, 0x33, +0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x10, 0xde, 0x5d, 0xed, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x36, +0x36, 0x33, 0x32, 0x16, 0x15, 0x11, 0x23, 0x11, 0x34, 0x2e, +0x02, 0x23, 0x22, 0x06, 0x07, 0x11, 0x23, 0x47, 0x2d, 0x59, +0x27, 0x5d, 0x5f, 0x52, 0x10, 0x1d, 0x29, 0x18, 0x14, 0x2d, +0x15, 0x53, 0x01, 0xc3, 0x0b, 0x0c, 0x60, 0x6a, 0xfe, 0xf0, +0x01, 0x01, 0x2d, 0x38, 0x1f, 0x0c, 0x05, 0x04, 0xfe, 0x78, +0x00, 0x02, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x01, 0xdb, +0x00, 0x13, 0x00, 0x1f, 0x00, 0x98, 0x40, 0x10, 0x1e, 0x18, +0x10, 0x00, 0x4d, 0x1e, 0x20, 0x0f, 0x00, 0x4d, 0x1e, 0x08, +0x0e, 0x00, 0x4d, 0x1c, 0xb8, 0xff, 0xe0, 0xb4, 0x0f, 0x10, +0x00, 0x4c, 0x1c, 0xb8, 0xff, 0xf0, 0xb3, 0x0e, 0x00, 0x4d, +0x18, 0xb8, 0xff, 0xe0, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x18, +0xb8, 0xff, 0xf8, 0x40, 0x0f, 0x0e, 0x00, 0x4d, 0x16, 0x20, +0x0f, 0x10, 0x00, 0x4c, 0x16, 0x08, 0x0e, 0x00, 0x4d, 0x12, +0xb8, 0xff, 0xe8, 0x40, 0x11, 0x08, 0x09, 0x00, 0x4c, 0x0c, +0x10, 0x08, 0x09, 0x00, 0x4c, 0x07, 0x10, 0x08, 0x09, 0x00, +0x4c, 0x03, 0xb8, 0xff, 0xe0, 0xb3, 0x09, 0x00, 0x4d, 0x03, +0xb8, 0xff, 0xf0, 0x40, 0x18, 0x08, 0x00, 0x4d, 0x14, 0x82, +0x00, 0x21, 0x1a, 0x82, 0x0a, 0x40, 0x09, 0x0c, 0x48, 0x0a, +0x20, 0x17, 0x88, 0x0f, 0x50, 0x1d, 0x88, 0x05, 0x51, 0x00, +0x3f, 0xed, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0x2b, 0xed, 0x10, +0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x14, +0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, +0x33, 0x32, 0x1e, 0x02, 0x07, 0x34, 0x26, 0x23, 0x22, 0x06, +0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x01, 0xcc, 0x1f, 0x38, +0x4e, 0x2e, 0x2d, 0x4d, 0x38, 0x1f, 0x1f, 0x38, 0x4d, 0x2d, +0x2e, 0x4e, 0x38, 0x1f, 0x55, 0x44, 0x3a, 0x39, 0x43, 0x43, +0x39, 0x3a, 0x44, 0xe8, 0x37, 0x59, 0x40, 0x23, 0x23, 0x40, +0x59, 0x37, 0x37, 0x5a, 0x3f, 0x23, 0x23, 0x3f, 0x5a, 0x37, +0x4f, 0x5b, 0x5b, 0x4f, 0x4e, 0x5b, 0x5b, 0x00, 0x00, 0x02, +0x00, 0x47, 0xff, 0x5b, 0x01, 0xcc, 0x01, 0xda, 0x00, 0x0e, +0x00, 0x21, 0x00, 0x76, 0xb9, 0x00, 0x20, 0xff, 0xf0, 0xb4, +0x08, 0x09, 0x00, 0x4c, 0x1f, 0xb8, 0xff, 0xf8, 0xb3, 0x10, +0x00, 0x4d, 0x1f, 0xb8, 0xff, 0xe8, 0xb3, 0x0f, 0x00, 0x4d, +0x12, 0xb8, 0xff, 0xe8, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x12, +0xb8, 0xff, 0xf0, 0xb4, 0x09, 0x0a, 0x00, 0x4c, 0x11, 0xb8, +0xff, 0xe0, 0x40, 0x29, 0x08, 0x00, 0x4d, 0x0c, 0x08, 0x0e, +0x00, 0x4d, 0x02, 0x18, 0x0e, 0x00, 0x4d, 0x02, 0x10, 0x0d, +0x00, 0x4d, 0x00, 0x82, 0x0f, 0x23, 0x07, 0x18, 0x7f, 0x00, +0x19, 0x01, 0x08, 0x19, 0x22, 0x03, 0x88, 0x1d, 0x50, 0x19, +0x4b, 0x0a, 0x88, 0x14, 0x51, 0x00, 0x3f, 0xed, 0x3f, 0x3f, +0xed, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x10, 0xde, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x25, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x11, +0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x37, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x26, 0x27, 0x15, 0x23, 0x11, 0x36, 0x36, 0x33, +0x32, 0x1e, 0x02, 0x01, 0x77, 0x4c, 0x3d, 0x22, 0x27, 0x0b, +0x0e, 0x36, 0x1d, 0x21, 0x2f, 0x1e, 0x0e, 0x55, 0x1b, 0x33, +0x4a, 0x2f, 0x25, 0x38, 0x0e, 0x53, 0x1b, 0x55, 0x37, 0x32, +0x52, 0x3a, 0x20, 0xe7, 0x51, 0x59, 0x06, 0x04, 0xfe, 0xdb, +0x0d, 0x16, 0x1a, 0x2d, 0x3d, 0x24, 0x35, 0x59, 0x40, 0x24, +0x12, 0x0b, 0xb7, 0x02, 0x67, 0x08, 0x10, 0x22, 0x3f, 0x5a, +0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0xff, 0x5b, 0x01, 0xad, +0x01, 0xda, 0x00, 0x0e, 0x00, 0x21, 0x00, 0x78, 0x40, 0x2a, +0x20, 0x18, 0x09, 0x00, 0x4d, 0x1f, 0x28, 0x10, 0x00, 0x4d, +0x1f, 0x20, 0x0f, 0x00, 0x4d, 0x1f, 0x18, 0x0a, 0x00, 0x4d, +0x1f, 0x18, 0x08, 0x00, 0x4d, 0x12, 0x08, 0x10, 0x00, 0x4d, +0x12, 0x20, 0x0f, 0x00, 0x4d, 0x11, 0x10, 0x08, 0x09, 0x00, +0x4c, 0x0d, 0xb8, 0xff, 0xe0, 0xb3, 0x0e, 0x00, 0x4d, 0x0d, +0xb8, 0xff, 0xf0, 0xb3, 0x0d, 0x00, 0x4d, 0x03, 0xb8, 0xff, +0xe8, 0x40, 0x1b, 0x0e, 0x00, 0x4d, 0x08, 0x19, 0x7f, 0x18, +0x23, 0x00, 0x82, 0x0f, 0x40, 0x09, 0x0c, 0x48, 0x0f, 0x22, +0x05, 0x88, 0x1d, 0x51, 0x19, 0x4b, 0x0c, 0x88, 0x14, 0x50, +0x00, 0x3f, 0xed, 0x3f, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0x2b, +0xed, 0x10, 0xde, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x37, 0x14, +0x1e, 0x02, 0x33, 0x32, 0x36, 0x37, 0x11, 0x26, 0x26, 0x23, +0x22, 0x06, 0x07, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, +0x11, 0x23, 0x35, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x7d, +0x0f, 0x1e, 0x2f, 0x21, 0x1d, 0x36, 0x0e, 0x0b, 0x27, 0x22, +0x3d, 0x4d, 0x55, 0x20, 0x3a, 0x53, 0x32, 0x36, 0x53, 0x1d, +0x53, 0x0f, 0x38, 0x23, 0x2f, 0x4a, 0x33, 0x1c, 0xe7, 0x24, +0x3d, 0x2d, 0x1a, 0x16, 0x0d, 0x01, 0x25, 0x04, 0x06, 0x59, +0x51, 0x38, 0x5a, 0x3f, 0x22, 0x11, 0x08, 0xfd, 0x9a, 0xb7, +0x0a, 0x13, 0x24, 0x40, 0x59, 0x00, 0x00, 0x01, 0x00, 0x6b, +0x00, 0x00, 0x01, 0xb6, 0x01, 0xda, 0x00, 0x0d, 0x00, 0x24, +0x40, 0x12, 0x06, 0x0f, 0x0d, 0x7f, 0x00, 0x00, 0x01, 0x08, +0x00, 0x0e, 0x07, 0x07, 0x0a, 0x88, 0x03, 0x50, 0x00, 0x4a, +0x00, 0x3f, 0x3f, 0xed, 0x32, 0x2f, 0x01, 0x10, 0xd6, 0x5e, +0x5d, 0xed, 0x10, 0xce, 0x31, 0x30, 0x33, 0x11, 0x36, 0x33, +0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x07, 0x11, +0x6b, 0x66, 0x68, 0x20, 0x3a, 0x23, 0x0f, 0x20, 0x31, 0x1d, +0x3d, 0x3f, 0x01, 0xb7, 0x23, 0x05, 0x08, 0x49, 0x09, 0x05, +0x11, 0xfe, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x42, 0xff, 0xf5, +0x01, 0xb2, 0x01, 0xdb, 0x00, 0x27, 0x00, 0xec, 0x40, 0x12, +0x22, 0x20, 0x10, 0x12, 0x00, 0x4c, 0x22, 0x28, 0x0e, 0x0f, +0x00, 0x4c, 0x21, 0x08, 0x0e, 0x00, 0x4d, 0x1d, 0xb8, 0xff, +0xe0, 0xb3, 0x0c, 0x00, 0x4d, 0x1d, 0xb8, 0xff, 0xe8, 0xb3, +0x0b, 0x00, 0x4d, 0x1d, 0xb8, 0xff, 0xe0, 0xb3, 0x0a, 0x00, +0x4d, 0x1d, 0xb8, 0xff, 0xc8, 0xb3, 0x09, 0x00, 0x4d, 0x1d, +0xb8, 0xff, 0xe0, 0xb3, 0x08, 0x00, 0x4d, 0x1b, 0xb8, 0xff, +0xe0, 0xb3, 0x0d, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xd0, 0xb3, +0x0c, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, +0x4d, 0x19, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x17, +0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x17, 0xb8, 0xff, +0xf0, 0x40, 0x51, 0x0e, 0x00, 0x4d, 0x08, 0x18, 0x0b, 0x00, +0x4d, 0x08, 0x20, 0x09, 0x0a, 0x00, 0x4c, 0x08, 0x18, 0x08, +0x00, 0x4d, 0x06, 0x28, 0x0d, 0x00, 0x4d, 0x05, 0x30, 0x0c, +0x00, 0x4d, 0x05, 0x18, 0x0a, 0x00, 0x4d, 0x04, 0x10, 0x0f, +0x00, 0x4d, 0x03, 0x20, 0x08, 0x09, 0x00, 0x4c, 0x02, 0x10, +0x10, 0x00, 0x4d, 0x0d, 0x0d, 0x00, 0x82, 0x1c, 0x29, 0x22, +0x22, 0x15, 0x82, 0x01, 0x07, 0x01, 0x08, 0x07, 0x28, 0x18, +0x0a, 0x23, 0x23, 0x26, 0x88, 0x03, 0x1f, 0x51, 0x0e, 0x0e, +0x13, 0x88, 0x0a, 0x50, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, +0x39, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x01, 0x10, 0xd6, 0x5e, +0x5d, 0xed, 0x33, 0x2f, 0x10, 0xde, 0xed, 0x33, 0x2f, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x34, 0x2e, 0x04, 0x35, 0x34, +0x36, 0x33, 0x32, 0x16, 0x17, 0x07, 0x2e, 0x03, 0x23, 0x22, +0x15, 0x14, 0x1e, 0x04, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, +0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x01, 0x5f, 0x29, 0x3d, +0x48, 0x3d, 0x29, 0x5b, 0x61, 0x26, 0x51, 0x1d, 0x0f, 0x08, +0x1c, 0x24, 0x29, 0x13, 0x6c, 0x29, 0x3e, 0x48, 0x3e, 0x29, +0x62, 0x6a, 0x30, 0x50, 0x24, 0x10, 0x23, 0x4d, 0x2c, 0x71, +0x74, 0x19, 0x20, 0x18, 0x17, 0x22, 0x32, 0x28, 0x38, 0x4b, +0x0b, 0x09, 0x4a, 0x04, 0x09, 0x07, 0x04, 0x3b, 0x15, 0x1d, +0x18, 0x19, 0x24, 0x33, 0x27, 0x3f, 0x45, 0x10, 0x10, 0x4b, +0x10, 0x15, 0x00, 0x01, 0x00, 0x3f, 0xff, 0xf5, 0x01, 0xc2, +0x02, 0x60, 0x00, 0x1b, 0x00, 0x49, 0x40, 0x29, 0x13, 0x18, +0x0c, 0x00, 0x4d, 0x13, 0x20, 0x0b, 0x00, 0x4d, 0x00, 0x03, +0x7f, 0x19, 0x16, 0x16, 0x17, 0x0d, 0x0d, 0x02, 0x1d, 0x00, +0x17, 0x01, 0x08, 0x17, 0x1c, 0x1a, 0x1b, 0x03, 0x16, 0x85, +0x00, 0x19, 0x49, 0x0c, 0x0c, 0x09, 0x88, 0x10, 0x51, 0x00, +0x3f, 0xed, 0x32, 0x2f, 0x3f, 0x33, 0xed, 0x32, 0xcd, 0x32, +0x01, 0x10, 0xc6, 0x5e, 0x5d, 0x10, 0xce, 0x32, 0x2f, 0x11, +0x39, 0x2f, 0x33, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x13, +0x33, 0x15, 0x23, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x36, +0x37, 0x17, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x35, +0x23, 0x35, 0x33, 0x35, 0x37, 0xf3, 0xc4, 0xc4, 0x0a, 0x17, +0x24, 0x1a, 0x24, 0x2c, 0x14, 0x0c, 0x0e, 0x3d, 0x2d, 0x34, +0x42, 0x25, 0x0e, 0x62, 0x62, 0x52, 0x01, 0xd0, 0x45, 0xd8, +0x23, 0x2c, 0x1b, 0x0a, 0x0c, 0x0a, 0x46, 0x06, 0x14, 0x18, +0x30, 0x47, 0x2f, 0xd8, 0x45, 0x82, 0x0e, 0x00, 0x00, 0x01, +0x00, 0x44, 0xff, 0xf6, 0x01, 0xad, 0x01, 0xd0, 0x00, 0x15, +0x00, 0x56, 0xb9, 0x00, 0x0d, 0xff, 0xd8, 0xb3, 0x11, 0x00, +0x4d, 0x0d, 0xb8, 0xff, 0xe8, 0x40, 0x30, 0x0f, 0x10, 0x00, +0x4c, 0x06, 0x18, 0x12, 0x00, 0x4d, 0x06, 0x20, 0x09, 0x00, +0x4d, 0x06, 0x18, 0x08, 0x00, 0x4d, 0x05, 0x20, 0x12, 0x00, +0x4d, 0x05, 0x10, 0x0a, 0x00, 0x4d, 0x13, 0x7f, 0x00, 0x17, +0x0b, 0x7f, 0x00, 0x08, 0x01, 0x08, 0x08, 0x16, 0x14, 0x09, +0x49, 0x0e, 0x88, 0x03, 0x51, 0x00, 0x3f, 0xed, 0x3f, 0x33, +0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x10, 0xde, 0xed, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x06, +0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x11, 0x33, 0x15, 0x14, +0x16, 0x33, 0x32, 0x3e, 0x02, 0x37, 0x11, 0x33, 0x01, 0xad, +0x1b, 0x59, 0x3c, 0x35, 0x46, 0x2c, 0x12, 0x52, 0x33, 0x3c, +0x0d, 0x1b, 0x18, 0x12, 0x03, 0x53, 0x0d, 0x07, 0x10, 0x1f, +0x39, 0x4e, 0x2f, 0x01, 0x05, 0xf3, 0x56, 0x48, 0x02, 0x03, +0x03, 0x01, 0x01, 0x88, 0x00, 0x01, 0x00, 0x1e, 0x00, 0x00, +0x01, 0xd6, 0x01, 0xd0, 0x00, 0x14, 0x00, 0x6e, 0xb9, 0x00, +0x0b, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, 0x0f, 0xb8, 0xff, +0xe0, 0xb4, 0x10, 0x12, 0x00, 0x4c, 0x0f, 0xb8, 0xff, 0xe8, +0x40, 0x2f, 0x0f, 0x00, 0x4d, 0x06, 0x0a, 0x0f, 0x0a, 0x81, +0x09, 0x06, 0x14, 0x09, 0x09, 0x06, 0x05, 0x14, 0x0f, 0x14, +0x81, 0x00, 0x05, 0x14, 0x00, 0x00, 0x05, 0x0f, 0x0f, 0x09, +0x4f, 0x00, 0x5f, 0x00, 0x02, 0x00, 0x16, 0x09, 0x15, 0x00, +0x14, 0x49, 0x0a, 0x09, 0x49, 0x0f, 0x05, 0x06, 0x4a, 0x00, +0x3f, 0x33, 0x33, 0x3f, 0x33, 0x3f, 0x33, 0x01, 0x10, 0xc6, +0x10, 0xce, 0x5d, 0x11, 0x39, 0x3d, 0x2f, 0x87, 0x18, 0x10, +0x2b, 0x87, 0x7d, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, +0xc4, 0x31, 0x30, 0x00, 0x2b, 0x2b, 0x01, 0x2b, 0x01, 0x0e, +0x03, 0x07, 0x23, 0x26, 0x26, 0x27, 0x33, 0x1e, 0x03, 0x17, +0x3e, 0x03, 0x37, 0x01, 0xd6, 0x12, 0x2e, 0x30, 0x32, 0x17, +0x4b, 0x2f, 0x60, 0x25, 0x5a, 0x0c, 0x1f, 0x22, 0x23, 0x11, +0x11, 0x25, 0x24, 0x21, 0x0c, 0x01, 0xd0, 0x41, 0x7d, 0x77, +0x6c, 0x2f, 0x5e, 0xf0, 0x82, 0x2c, 0x62, 0x62, 0x5b, 0x24, +0x24, 0x5b, 0x62, 0x62, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x13, 0x00, 0x00, 0x01, 0xe1, 0x01, 0xd0, 0x00, 0x2a, +0x01, 0x48, 0xb5, 0x28, 0x18, 0x0f, 0x00, 0x4d, 0x28, 0xb8, +0xff, 0xf0, 0x40, 0x1b, 0x09, 0x00, 0x4d, 0x20, 0x20, 0x0f, +0x00, 0x4d, 0x1c, 0x10, 0x17, 0x00, 0x4d, 0x1b, 0x20, 0x17, +0x00, 0x4d, 0x1a, 0x18, 0x17, 0x00, 0x4d, 0xec, 0x1a, 0x01, +0x19, 0xb8, 0xff, 0xe0, 0xb6, 0x17, 0x00, 0x4d, 0xe6, 0x19, +0x01, 0x18, 0xb8, 0xff, 0xe8, 0xb3, 0x17, 0x00, 0x4d, 0x17, +0xb8, 0xff, 0xf8, 0x40, 0x0e, 0x17, 0x00, 0x4d, 0x16, 0x10, +0x10, 0x00, 0x4d, 0x15, 0x18, 0x10, 0x00, 0x4d, 0x15, 0xb8, +0xff, 0xf0, 0xb3, 0x09, 0x00, 0x4d, 0x13, 0xb8, 0xff, 0xe8, +0xb3, 0x0f, 0x00, 0x4d, 0x0c, 0xb8, 0xff, 0xf0, 0x40, 0x13, +0x0f, 0x00, 0x4d, 0x0c, 0x18, 0x0b, 0x00, 0x4d, 0x0c, 0x18, +0x09, 0x00, 0x4d, 0x0b, 0x08, 0x0b, 0x00, 0x4d, 0x08, 0xb8, +0xff, 0xd0, 0xb3, 0x12, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xe8, +0xb3, 0x0f, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xe0, 0xb3, 0x0e, +0x00, 0x4d, 0x07, 0xb8, 0xff, 0xe8, 0x40, 0x4d, 0x0f, 0x00, +0x4d, 0x03, 0x18, 0x0f, 0x00, 0x4d, 0x02, 0x18, 0x12, 0x00, +0x4d, 0x02, 0x08, 0x0f, 0x00, 0x4d, 0x02, 0x18, 0x0e, 0x00, +0x4d, 0x00, 0x1a, 0x1f, 0x1a, 0x84, 0x05, 0x00, 0x14, 0x05, +0x05, 0x00, 0x1f, 0x24, 0x7f, 0x25, 0x0a, 0x19, 0x14, 0x19, +0x84, 0x05, 0x0a, 0x14, 0x05, 0x0a, 0x05, 0x05, 0x0e, 0x2a, +0x0f, 0x25, 0x1f, 0x25, 0x4f, 0x25, 0x5f, 0x25, 0xdf, 0x25, +0x05, 0x25, 0x2c, 0x14, 0x0f, 0x7f, 0x0b, 0x0e, 0x2b, 0x25, +0x24, 0x49, 0x1a, 0x19, 0x05, 0xb8, 0xff, 0xc8, 0x40, 0x13, +0x16, 0x00, 0x4d, 0x05, 0x05, 0x19, 0x19, 0x0f, 0x0e, 0x49, +0x14, 0x14, 0x0a, 0x0b, 0x4a, 0x2a, 0x1f, 0x1f, 0x00, 0x00, +0x2f, 0x32, 0x2f, 0x32, 0x3f, 0x33, 0x33, 0x2f, 0x3f, 0x33, +0x33, 0x2f, 0x33, 0x2f, 0x2b, 0x11, 0x33, 0x3f, 0x33, 0x01, +0x10, 0xd6, 0x32, 0xed, 0x32, 0x10, 0xce, 0x5d, 0x32, 0x11, +0x39, 0x3d, 0x2f, 0x87, 0x18, 0x2b, 0x87, 0x7d, 0xc4, 0x01, +0x18, 0x10, 0xed, 0x32, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x5d, 0x2b, 0x5d, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x21, 0x2e, 0x03, 0x27, 0x0e, 0x03, 0x07, 0x23, 0x26, 0x26, +0x27, 0x33, 0x1e, 0x03, 0x17, 0x3e, 0x03, 0x37, 0x33, 0x1e, +0x03, 0x17, 0x3e, 0x03, 0x37, 0x33, 0x0e, 0x03, 0x07, 0x01, +0x57, 0x0f, 0x16, 0x15, 0x15, 0x0e, 0x0e, 0x16, 0x15, 0x17, +0x0f, 0x3e, 0x1c, 0x25, 0x09, 0x4e, 0x03, 0x07, 0x0a, 0x0d, +0x08, 0x10, 0x16, 0x12, 0x11, 0x0a, 0x3e, 0x0a, 0x10, 0x12, +0x14, 0x0f, 0x09, 0x0e, 0x0a, 0x08, 0x03, 0x4b, 0x05, 0x0e, +0x14, 0x18, 0x0d, 0x22, 0x38, 0x38, 0x3d, 0x27, 0x27, 0x3d, +0x38, 0x38, 0x22, 0x7b, 0xf1, 0x64, 0x27, 0x4b, 0x52, 0x60, +0x3c, 0x28, 0x3c, 0x36, 0x38, 0x23, 0x23, 0x38, 0x36, 0x3c, +0x27, 0x37, 0x5e, 0x53, 0x4e, 0x29, 0x32, 0x72, 0x78, 0x7b, +0x39, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1d, 0x00, 0x00, +0x01, 0xd8, 0x01, 0xd0, 0x00, 0x17, 0x00, 0x70, 0x40, 0x41, +0x14, 0x0a, 0x13, 0x17, 0x10, 0x11, 0x0b, 0x12, 0x17, 0x10, +0x0e, 0x00, 0x0f, 0x0b, 0x12, 0x05, 0x06, 0x09, 0x0a, 0x13, +0x0a, 0x12, 0x0b, 0x12, 0x81, 0x13, 0x0a, 0x14, 0x13, 0x0a, +0x13, 0x13, 0x17, 0x01, 0x00, 0x0f, 0x00, 0x10, 0x17, 0x10, +0x81, 0x0f, 0x00, 0x14, 0x0f, 0x0f, 0x00, 0x17, 0x19, 0x0f, +0x0f, 0x0b, 0x18, 0x13, 0x12, 0x49, 0x10, 0x0f, 0x49, 0x0b, +0x0a, 0x4a, 0x17, 0x00, 0x4a, 0x00, 0x3f, 0x32, 0x3f, 0x33, +0x3f, 0x33, 0x3f, 0x33, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, +0xce, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x87, 0x0e, 0xc4, +0x01, 0x11, 0x33, 0x18, 0x2f, 0x87, 0x2b, 0x87, 0x7d, 0xc4, +0x87, 0x0e, 0xc4, 0xc4, 0xc4, 0x0f, 0x0f, 0x0f, 0x31, 0x30, +0x21, 0x2e, 0x03, 0x27, 0x0e, 0x03, 0x07, 0x23, 0x36, 0x36, +0x37, 0x27, 0x33, 0x17, 0x37, 0x33, 0x07, 0x16, 0x16, 0x17, +0x01, 0x7c, 0x0a, 0x1d, 0x22, 0x25, 0x12, 0x12, 0x28, 0x25, +0x20, 0x0b, 0x55, 0x21, 0x5f, 0x2e, 0xa7, 0x5d, 0x7d, 0x73, +0x58, 0x99, 0x2d, 0x5b, 0x20, 0x14, 0x30, 0x33, 0x32, 0x16, +0x17, 0x32, 0x33, 0x30, 0x13, 0x3c, 0x7f, 0x39, 0xdc, 0xa2, +0xa2, 0xd7, 0x3b, 0x80, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x24, +0xff, 0x58, 0x01, 0xcd, 0x01, 0xd0, 0x00, 0x20, 0x01, 0x08, +0x40, 0x42, 0x19, 0x10, 0x11, 0x00, 0x4d, 0x18, 0x10, 0x10, +0x00, 0x4d, 0x17, 0x18, 0x12, 0x00, 0x4d, 0x17, 0x10, 0x0f, +0x00, 0x4d, 0x17, 0x18, 0x0c, 0x00, 0x4d, 0x16, 0x10, 0x0c, +0x00, 0x4d, 0x12, 0x10, 0x0f, 0x00, 0x4d, 0x11, 0x18, 0x0c, +0x00, 0x4d, 0x10, 0x20, 0x12, 0x00, 0x4d, 0x10, 0x18, 0x11, +0x00, 0x4d, 0x10, 0x20, 0x0f, 0x00, 0x4d, 0x10, 0x20, 0x0c, +0x00, 0x4d, 0x0f, 0x18, 0x0c, 0x00, 0x4d, 0x0c, 0xb8, 0xff, +0xe8, 0x40, 0x2a, 0x11, 0x00, 0x4d, 0x07, 0x38, 0x10, 0x00, +0x4d, 0x06, 0x18, 0x11, 0x00, 0x4d, 0x06, 0x10, 0x0f, 0x10, +0x00, 0x4c, 0x06, 0x28, 0x0c, 0x00, 0x4d, 0x06, 0x18, 0x0a, +0x0b, 0x00, 0x4c, 0x05, 0x28, 0x0c, 0x00, 0x4d, 0x05, 0x20, +0x0a, 0x0b, 0x00, 0x4c, 0x0f, 0xb8, 0xff, 0xd0, 0xb3, 0x12, +0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xd8, 0xb3, 0x11, 0x00, 0x4d, +0x0f, 0xb8, 0xff, 0xc8, 0x40, 0x3c, 0x0e, 0x00, 0x4d, 0x06, +0x30, 0x12, 0x00, 0x4d, 0x18, 0x14, 0x0f, 0x14, 0x81, 0x15, +0x18, 0x14, 0x15, 0x15, 0x18, 0x06, 0x0a, 0x0f, 0x0a, 0x81, +0x09, 0x06, 0x14, 0x09, 0x09, 0x06, 0x0f, 0x0f, 0x09, 0x1f, +0x15, 0x01, 0x15, 0x22, 0x20, 0x20, 0x20, 0x09, 0x01, 0x09, +0x21, 0x18, 0x0f, 0x06, 0x06, 0x09, 0x03, 0x88, 0x1d, 0x4b, +0x15, 0x14, 0x49, 0x0a, 0x09, 0x49, 0x00, 0x3f, 0x33, 0x3f, +0x33, 0x3f, 0xed, 0x12, 0x39, 0x11, 0x33, 0x33, 0x01, 0x10, +0xc6, 0x5d, 0x32, 0x2f, 0x10, 0xce, 0x5d, 0x11, 0x39, 0x3d, +0x2f, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x87, 0x18, +0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x00, 0x2b, 0x2b, +0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x17, 0x16, 0x16, 0x33, 0x32, 0x36, +0x37, 0x26, 0x26, 0x27, 0x33, 0x1e, 0x03, 0x17, 0x3e, 0x03, +0x37, 0x33, 0x06, 0x06, 0x07, 0x0e, 0x03, 0x23, 0x22, 0x26, +0x27, 0x33, 0x09, 0x21, 0x0e, 0x31, 0x37, 0x17, 0x38, 0x62, +0x20, 0x5a, 0x0a, 0x1b, 0x22, 0x27, 0x16, 0x10, 0x1c, 0x18, +0x18, 0x0d, 0x56, 0x20, 0x4f, 0x2d, 0x11, 0x27, 0x2e, 0x3a, +0x25, 0x13, 0x2d, 0x08, 0x57, 0x05, 0x06, 0x2b, 0x31, 0x6a, +0xf3, 0x79, 0x28, 0x5d, 0x62, 0x63, 0x2d, 0x2e, 0x5a, 0x5b, +0x5f, 0x35, 0x82, 0xf4, 0x68, 0x28, 0x3a, 0x26, 0x12, 0x0a, +0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x49, 0x00, 0x00, +0x01, 0xab, 0x01, 0xd0, 0x00, 0x11, 0x00, 0x42, 0x40, 0x24, +0x15, 0x05, 0x01, 0x05, 0x0e, 0x09, 0x0e, 0x81, 0x00, 0x05, +0x14, 0x00, 0x00, 0x05, 0x06, 0x06, 0x00, 0x13, 0x0f, 0x0f, +0x00, 0x09, 0x01, 0x08, 0x09, 0x12, 0x00, 0x0e, 0x85, 0x10, +0x49, 0x09, 0x05, 0x85, 0x08, 0x4a, 0x00, 0x3f, 0xed, 0x32, +0x3f, 0xed, 0x32, 0x01, 0x10, 0xc6, 0x5e, 0x5d, 0x32, 0x2f, +0x10, 0xc6, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x01, 0x5d, 0x31, 0x30, 0x01, 0x0e, 0x03, 0x07, 0x33, 0x15, +0x21, 0x35, 0x3e, 0x03, 0x37, 0x23, 0x35, 0x21, 0x01, 0xa4, +0x12, 0x3e, 0x47, 0x46, 0x1b, 0xff, 0xfe, 0x9e, 0x15, 0x3f, +0x44, 0x41, 0x18, 0xe4, 0x01, 0x4e, 0x01, 0x92, 0x15, 0x4b, +0x5b, 0x64, 0x2d, 0x46, 0x37, 0x28, 0x5f, 0x5d, 0x54, 0x1c, +0x45, 0x00, 0x00, 0x01, 0x00, 0x4f, 0xff, 0x5b, 0x01, 0xab, +0x02, 0xbb, 0x00, 0x2c, 0x00, 0x67, 0x40, 0x44, 0x23, 0x10, +0x0f, 0x00, 0x4d, 0x23, 0x18, 0x0e, 0x00, 0x4d, 0x23, 0x10, +0x0d, 0x00, 0x4d, 0x23, 0x18, 0x0a, 0x0c, 0x00, 0x4c, 0x09, +0x18, 0x0f, 0x00, 0x4d, 0x09, 0x10, 0x0d, 0x0e, 0x00, 0x4c, +0x09, 0x18, 0x0c, 0x00, 0x4d, 0x09, 0x20, 0x0b, 0x00, 0x4d, +0x09, 0x18, 0x0a, 0x00, 0x4d, 0x0e, 0x1e, 0x13, 0x1a, 0x7f, +0x2c, 0x16, 0x06, 0x25, 0x25, 0x2e, 0x2d, 0x16, 0x2c, 0x00, +0x00, 0x0d, 0x1e, 0x1f, 0x0e, 0x0d, 0x00, 0x2f, 0xcd, 0x2f, +0xcd, 0x11, 0x39, 0x2f, 0xcd, 0x39, 0x01, 0x11, 0x12, 0x39, +0x2f, 0x33, 0x33, 0xce, 0xfd, 0x32, 0xce, 0x32, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, +0x33, 0x32, 0x3e, 0x02, 0x35, 0x35, 0x34, 0x3e, 0x02, 0x33, +0x33, 0x15, 0x23, 0x22, 0x06, 0x15, 0x15, 0x14, 0x06, 0x07, +0x16, 0x16, 0x15, 0x15, 0x14, 0x16, 0x33, 0x33, 0x15, 0x23, +0x22, 0x2e, 0x02, 0x35, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x23, +0x4f, 0x28, 0x11, 0x1a, 0x11, 0x09, 0x0f, 0x24, 0x3d, 0x2e, +0x51, 0x55, 0x2a, 0x23, 0x28, 0x1a, 0x1a, 0x28, 0x24, 0x2a, +0x54, 0x51, 0x2e, 0x3d, 0x24, 0x0f, 0x09, 0x11, 0x19, 0x11, +0x29, 0x01, 0x2b, 0x0f, 0x19, 0x1f, 0x10, 0xa1, 0x25, 0x38, +0x27, 0x14, 0x41, 0x26, 0x32, 0x8a, 0x43, 0x3f, 0x0b, 0x0c, +0x42, 0x3f, 0x8a, 0x32, 0x26, 0x41, 0x14, 0x27, 0x38, 0x25, +0xa1, 0x0f, 0x1f, 0x19, 0x10, 0x00, 0x00, 0x01, 0x00, 0xd4, +0xff, 0x5b, 0x01, 0x21, 0x02, 0xbb, 0x00, 0x03, 0x00, 0x14, +0xb7, 0x02, 0x7f, 0x03, 0x03, 0x05, 0x04, 0x03, 0x00, 0x00, +0x2f, 0x2f, 0x01, 0x11, 0x12, 0x39, 0x2f, 0xed, 0x31, 0x30, +0x13, 0x33, 0x11, 0x23, 0xd4, 0x4d, 0x4d, 0x02, 0xbb, 0xfc, +0xa0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x49, 0xff, 0x5b, +0x01, 0xa5, 0x02, 0xbb, 0x00, 0x2c, 0x00, 0x67, 0xb9, 0x00, +0x23, 0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x23, 0xb8, 0xff, +0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x23, 0xb8, 0xff, 0xe0, 0xb3, +0x0d, 0x00, 0x4d, 0x23, 0xb8, 0xff, 0xe8, 0xb4, 0x0a, 0x0c, +0x00, 0x4c, 0x09, 0xb8, 0xff, 0xe8, 0xb4, 0x0b, 0x0d, 0x00, +0x4c, 0x09, 0xb8, 0xff, 0xe0, 0x40, 0x18, 0x0a, 0x00, 0x4d, +0x1e, 0x0e, 0x19, 0x12, 0x91, 0x26, 0x16, 0x00, 0x07, 0x07, +0x2e, 0x2d, 0x16, 0x00, 0x2c, 0x2c, 0x0e, 0x1e, 0x1f, 0x0e, +0x0d, 0x00, 0x2f, 0xcd, 0x2f, 0xcd, 0x12, 0x39, 0x2f, 0xcd, +0x39, 0x01, 0x11, 0x12, 0x39, 0x2f, 0xce, 0x33, 0x33, 0xfd, +0x32, 0xce, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x25, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x15, 0x14, 0x0e, +0x02, 0x23, 0x23, 0x35, 0x33, 0x32, 0x36, 0x35, 0x35, 0x34, +0x36, 0x37, 0x26, 0x26, 0x35, 0x35, 0x34, 0x26, 0x23, 0x23, +0x35, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x15, 0x14, 0x1e, 0x02, +0x33, 0x33, 0x01, 0xa5, 0x28, 0x11, 0x19, 0x11, 0x09, 0x0f, +0x25, 0x3d, 0x2e, 0x51, 0x55, 0x2a, 0x23, 0x28, 0x1a, 0x1a, +0x28, 0x24, 0x2a, 0x54, 0x51, 0x2e, 0x3d, 0x25, 0x0f, 0x08, +0x11, 0x19, 0x11, 0x29, 0xeb, 0x0f, 0x19, 0x1f, 0x10, 0xa1, +0x25, 0x38, 0x27, 0x14, 0x41, 0x26, 0x32, 0x8a, 0x43, 0x3f, +0x0b, 0x0c, 0x42, 0x3f, 0x8a, 0x32, 0x26, 0x41, 0x14, 0x27, +0x38, 0x25, 0xa1, 0x0f, 0x1f, 0x19, 0x10, 0x00, 0x00, 0x01, +0x00, 0x25, 0x00, 0xbd, 0x01, 0xcf, 0x01, 0x51, 0x00, 0x21, +0x00, 0x46, 0xb9, 0x00, 0x19, 0xff, 0xe8, 0xb3, 0x11, 0x00, +0x4d, 0x19, 0xb8, 0xff, 0xf0, 0x40, 0x0a, 0x10, 0x00, 0x4d, +0x14, 0x18, 0x09, 0x0c, 0x00, 0x4c, 0x03, 0xb8, 0xff, 0xe0, +0x40, 0x13, 0x09, 0x0c, 0x00, 0x4c, 0x21, 0x00, 0x10, 0x11, +0x21, 0x21, 0x16, 0x88, 0x0b, 0x1c, 0x88, 0x05, 0x10, 0x10, +0x05, 0x00, 0x2f, 0x33, 0x2f, 0x10, 0xed, 0xdc, 0xed, 0x32, +0x2f, 0x01, 0x2f, 0xcd, 0xdc, 0xcd, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x2b, 0x01, 0x0e, 0x03, 0x23, 0x22, 0x26, 0x27, 0x26, +0x26, 0x23, 0x22, 0x0e, 0x02, 0x07, 0x27, 0x3e, 0x03, 0x33, +0x32, 0x16, 0x17, 0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x37, +0x01, 0xcf, 0x03, 0x0f, 0x1d, 0x2c, 0x1f, 0x1b, 0x2d, 0x15, +0x18, 0x2c, 0x1a, 0x0e, 0x14, 0x0d, 0x0a, 0x03, 0x39, 0x03, +0x10, 0x1c, 0x2b, 0x20, 0x1b, 0x2d, 0x15, 0x18, 0x2d, 0x19, +0x0e, 0x14, 0x0d, 0x0a, 0x03, 0x01, 0x3a, 0x11, 0x2c, 0x26, +0x1a, 0x15, 0x0d, 0x0e, 0x1c, 0x0d, 0x14, 0x19, 0x0b, 0x10, +0x11, 0x2c, 0x26, 0x1a, 0x15, 0x0d, 0x0e, 0x1c, 0x0d, 0x14, +0x19, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x24, 0xff, 0xf4, +0x01, 0xd3, 0x02, 0x76, 0x00, 0x31, 0x00, 0x96, 0x40, 0x0c, +0x24, 0x10, 0x10, 0x00, 0x4d, 0x24, 0x18, 0x0d, 0x0e, 0x00, +0x4c, 0x1a, 0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, 0x1a, +0xb8, 0xff, 0xf8, 0xb3, 0x11, 0x00, 0x4d, 0x0c, 0xb8, 0xff, +0xf0, 0x40, 0x3f, 0x13, 0x00, 0x4d, 0x17, 0x17, 0x0e, 0x0e, +0x06, 0x06, 0x20, 0x33, 0x30, 0x30, 0x28, 0x19, 0x0d, 0x13, +0x76, 0x26, 0x00, 0x2c, 0x32, 0x19, 0x26, 0x79, 0x29, 0x16, +0x29, 0x10, 0x2f, 0x79, 0x00, 0x0d, 0x00, 0x0f, 0x29, 0x1f, +0x29, 0x02, 0x4f, 0x00, 0xaf, 0x00, 0xbf, 0x00, 0x03, 0x29, +0x00, 0x29, 0x00, 0x03, 0x1f, 0x1f, 0x1c, 0x7c, 0x23, 0x46, +0x07, 0x07, 0x0a, 0x7c, 0x03, 0x45, 0x00, 0x3f, 0xed, 0x32, +0x2f, 0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x39, 0x2f, 0x2f, +0x5d, 0x5d, 0x11, 0x33, 0x10, 0xed, 0x32, 0x11, 0x33, 0x10, +0xed, 0x32, 0x01, 0x10, 0xd4, 0x32, 0x32, 0xed, 0x32, 0x32, +0xce, 0x32, 0x2f, 0x10, 0xce, 0x32, 0x2f, 0x32, 0x2f, 0x33, +0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x36, +0x36, 0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, +0x06, 0x07, 0x33, 0x07, 0x23, 0x06, 0x14, 0x15, 0x14, 0x14, +0x17, 0x33, 0x07, 0x23, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, +0x17, 0x06, 0x06, 0x23, 0x22, 0x26, 0x27, 0x23, 0x35, 0x33, +0x26, 0x34, 0x35, 0x34, 0x34, 0x37, 0x23, 0x35, 0x6a, 0x12, +0x73, 0x5f, 0x28, 0x33, 0x18, 0x10, 0x15, 0x33, 0x1b, 0x44, +0x40, 0x0a, 0xc7, 0x0c, 0xc4, 0x01, 0x01, 0xb3, 0x0c, 0xa0, +0x0d, 0x49, 0x3c, 0x26, 0x36, 0x15, 0x12, 0x0f, 0x4b, 0x2e, +0x68, 0x6d, 0x0e, 0x44, 0x3d, 0x01, 0x01, 0x3d, 0x01, 0xa5, +0x6a, 0x67, 0x0a, 0x09, 0x46, 0x08, 0x0a, 0x4b, 0x3f, 0x40, +0x0b, 0x17, 0x0d, 0x0b, 0x16, 0x0a, 0x40, 0x50, 0x3e, 0x0d, +0x0b, 0x47, 0x08, 0x12, 0x72, 0x65, 0x40, 0x0a, 0x16, 0x0b, +0x0d, 0x17, 0x0b, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x94, +0xff, 0x70, 0x01, 0x5e, 0x00, 0x8b, 0x00, 0x13, 0x00, 0x1f, +0x40, 0x0e, 0x05, 0x0e, 0x94, 0x00, 0x08, 0x08, 0x15, 0x14, +0x00, 0x13, 0x0b, 0x9a, 0x05, 0x5c, 0x00, 0x3f, 0xed, 0xdc, +0xcd, 0x01, 0x11, 0x12, 0x39, 0x2f, 0xce, 0xed, 0x39, 0x31, +0x30, 0x17, 0x3e, 0x03, 0x37, 0x26, 0x26, 0x35, 0x34, 0x36, +0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x94, 0x12, +0x23, 0x1e, 0x18, 0x07, 0x20, 0x1d, 0x2e, 0x1c, 0x25, 0x26, +0x17, 0x2f, 0x46, 0x2f, 0x4f, 0x04, 0x08, 0x0f, 0x17, 0x14, +0x03, 0x2b, 0x15, 0x28, 0x29, 0x35, 0x26, 0x1d, 0x3f, 0x37, +0x27, 0x06, 0x00, 0x01, 0x00, 0x07, 0xff, 0x56, 0x01, 0xe2, +0x02, 0xb5, 0x00, 0x28, 0x00, 0x4a, 0xb9, 0x00, 0x1b, 0xff, +0xe0, 0x40, 0x29, 0x08, 0x09, 0x00, 0x4c, 0x05, 0x10, 0x0c, +0x00, 0x4d, 0x05, 0x18, 0x08, 0x0a, 0x00, 0x4c, 0x17, 0x15, +0x0b, 0x19, 0x7f, 0x21, 0x02, 0x00, 0x27, 0x27, 0x2a, 0x29, +0x24, 0x88, 0x1e, 0x52, 0x0f, 0x88, 0x08, 0x4d, 0x18, 0x28, +0x85, 0x15, 0x02, 0x49, 0x00, 0x3f, 0x33, 0xed, 0x32, 0x3f, +0xed, 0x3f, 0xed, 0x01, 0x11, 0x12, 0x39, 0x2f, 0xce, 0x33, +0xcc, 0xfd, 0xcc, 0x33, 0xce, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x13, 0x35, 0x33, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, +0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x15, +0x33, 0x15, 0x23, 0x11, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, +0x27, 0x37, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, 0x3f, 0x62, +0x1e, 0x31, 0x41, 0x24, 0x24, 0x49, 0x20, 0x0f, 0x16, 0x42, +0x22, 0x15, 0x25, 0x1c, 0x10, 0xbb, 0xbb, 0x1b, 0x2d, 0x3c, +0x20, 0x1c, 0x1e, 0x0e, 0x12, 0x15, 0x17, 0x27, 0x35, 0x01, +0x8b, 0x45, 0x2a, 0x36, 0x47, 0x2c, 0x12, 0x10, 0x0b, 0x47, +0x0b, 0x10, 0x0b, 0x1b, 0x2d, 0x22, 0x29, 0x45, 0xfe, 0x78, +0x30, 0x42, 0x29, 0x12, 0x06, 0x03, 0x47, 0x08, 0x2b, 0x3b, +0x01, 0x87, 0x00, 0x00, 0x00, 0x02, 0x00, 0x2a, 0xff, 0x7c, +0x01, 0xca, 0x00, 0x79, 0x00, 0x11, 0x00, 0x25, 0x00, 0x30, +0x40, 0x17, 0x17, 0x20, 0x12, 0x1a, 0x94, 0x20, 0x27, 0x03, +0x0c, 0x94, 0x00, 0x06, 0x26, 0x12, 0x00, 0x25, 0x11, 0x1d, +0x09, 0x9a, 0x17, 0x03, 0x5c, 0x00, 0x3f, 0x33, 0xed, 0x32, +0xdc, 0x32, 0xcd, 0x32, 0x01, 0x10, 0xd6, 0xce, 0xed, 0x39, +0x10, 0xd6, 0xfd, 0xce, 0x12, 0x39, 0x31, 0x30, 0x17, 0x36, +0x36, 0x37, 0x26, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, +0x15, 0x14, 0x0e, 0x02, 0x07, 0x37, 0x3e, 0x03, 0x37, 0x26, +0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, +0x02, 0x07, 0x2a, 0x22, 0x39, 0x0d, 0x1d, 0x1d, 0x21, 0x21, +0x1d, 0x2b, 0x11, 0x27, 0x41, 0x31, 0xda, 0x11, 0x20, 0x1c, +0x16, 0x06, 0x1d, 0x1d, 0x20, 0x22, 0x1d, 0x2a, 0x11, 0x27, +0x41, 0x31, 0x4a, 0x07, 0x16, 0x23, 0x03, 0x27, 0x17, 0x19, +0x29, 0x27, 0x2c, 0x1d, 0x37, 0x2e, 0x22, 0x06, 0x3a, 0x04, +0x07, 0x0e, 0x15, 0x12, 0x03, 0x27, 0x17, 0x19, 0x29, 0x27, +0x2c, 0x1d, 0x37, 0x2e, 0x22, 0x06, 0x00, 0x00, 0x00, 0x03, +0x00, 0x1f, 0xff, 0xf4, 0x01, 0xd5, 0x00, 0x60, 0x00, 0x0b, +0x00, 0x17, 0x00, 0x23, 0x00, 0x33, 0x40, 0x1a, 0x18, 0x95, +0x1e, 0x0c, 0x95, 0x12, 0x00, 0x95, 0x06, 0x1e, 0x12, 0x06, +0x06, 0x12, 0x1e, 0x03, 0x25, 0x24, 0x21, 0x15, 0x09, 0x9a, +0x1b, 0x0f, 0x03, 0x5c, 0x00, 0x3f, 0x33, 0x33, 0xed, 0x32, +0x32, 0x01, 0x11, 0x12, 0x17, 0x39, 0x2f, 0x2f, 0x2f, 0x10, +0xed, 0x10, 0xed, 0x10, 0xed, 0x31, 0x30, 0x37, 0x14, 0x06, +0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x17, +0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, +0x16, 0x17, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, +0x33, 0x32, 0x16, 0x89, 0x1d, 0x18, 0x18, 0x1d, 0x1d, 0x18, +0x18, 0x1d, 0xa6, 0x1c, 0x18, 0x18, 0x1c, 0x1c, 0x18, 0x18, +0x1c, 0xa6, 0x1c, 0x18, 0x18, 0x1c, 0x1c, 0x18, 0x18, 0x1c, +0x2a, 0x16, 0x20, 0x20, 0x16, 0x16, 0x20, 0x20, 0x16, 0x16, +0x20, 0x20, 0x16, 0x16, 0x20, 0x20, 0x16, 0x16, 0x20, 0x20, +0x16, 0x16, 0x20, 0x20, 0x00, 0x01, 0x00, 0x48, 0xff, 0x7f, +0x01, 0xac, 0x02, 0x6b, 0x00, 0x11, 0x00, 0x24, 0x40, 0x0f, +0x11, 0x0f, 0x00, 0x0c, 0x0a, 0x09, 0x09, 0x13, 0x12, 0x00, +0x09, 0x0f, 0x0c, 0x0d, 0x05, 0x00, 0x2f, 0x2f, 0xdd, 0x32, +0xcd, 0x32, 0x01, 0x11, 0x12, 0x39, 0x2f, 0xcd, 0x33, 0xdd, +0x32, 0xcd, 0x31, 0x30, 0x01, 0x15, 0x14, 0x06, 0x07, 0x23, +0x26, 0x26, 0x35, 0x35, 0x23, 0x35, 0x33, 0x35, 0x33, 0x15, +0x33, 0x15, 0x01, 0x1e, 0x07, 0x08, 0x29, 0x08, 0x08, 0x8e, +0x8e, 0x48, 0x8e, 0x01, 0x64, 0xe3, 0x4b, 0x7a, 0x3d, 0x3d, +0x7a, 0x4b, 0xe3, 0x45, 0xc2, 0xc2, 0x45, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x48, 0xff, 0x7f, 0x01, 0xac, 0x02, 0x6b, +0x00, 0x17, 0x00, 0x3c, 0x40, 0x1c, 0x0c, 0x08, 0x07, 0x13, +0x17, 0x15, 0x11, 0x00, 0x0e, 0x0a, 0x07, 0x07, 0x19, 0x18, +0x14, 0x0b, 0x11, 0x0f, 0x0e, 0x01, 0x08, 0x0e, 0x0f, 0x15, +0x0a, 0x00, 0x07, 0x04, 0x00, 0x2f, 0xdd, 0x32, 0xcd, 0x32, +0x2f, 0xdd, 0x5e, 0x5d, 0x32, 0xcd, 0x32, 0x01, 0x11, 0x12, +0x39, 0x2f, 0x33, 0x33, 0xdd, 0x32, 0x32, 0xcd, 0x32, 0x10, +0xcd, 0x32, 0x31, 0x30, 0x25, 0x14, 0x06, 0x07, 0x23, 0x26, +0x26, 0x35, 0x23, 0x35, 0x33, 0x35, 0x23, 0x35, 0x33, 0x35, +0x33, 0x15, 0x33, 0x15, 0x23, 0x15, 0x33, 0x15, 0x01, 0x1e, +0x08, 0x07, 0x29, 0x08, 0x08, 0x8e, 0x8e, 0x8e, 0x8e, 0x48, +0x8e, 0x8e, 0x8e, 0x78, 0x49, 0x75, 0x3b, 0x3b, 0x75, 0x49, +0x44, 0xa8, 0x45, 0xc2, 0xc2, 0x45, 0xa8, 0x44, 0x00, 0x01, +0x00, 0x81, 0x02, 0x08, 0x01, 0x73, 0x02, 0xaf, 0x00, 0x05, +0x00, 0x5b, 0x40, 0x1b, 0x05, 0x08, 0x10, 0x00, 0x4d, 0x03, +0x20, 0x12, 0x00, 0x4d, 0x03, 0x18, 0x11, 0x00, 0x4d, 0x03, +0x10, 0x10, 0x00, 0x4d, 0x04, 0x60, 0x05, 0x70, 0x05, 0x02, +0x05, 0xb8, 0xff, 0xc0, 0x40, 0x1b, 0x15, 0x18, 0x48, 0x05, +0x02, 0x6f, 0x01, 0x7f, 0x01, 0x02, 0x01, 0x40, 0x15, 0x18, +0x48, 0x01, 0x40, 0x00, 0x03, 0x01, 0x02, 0x02, 0x03, 0x00, +0x80, 0x05, 0x04, 0x00, 0x2f, 0x33, 0x1a, 0xcd, 0x32, 0x33, +0x11, 0x33, 0x01, 0x19, 0x2f, 0x33, 0x1a, 0xcd, 0x2b, 0x5d, +0x32, 0xcd, 0x2b, 0x5d, 0x32, 0x31, 0x30, 0x00, 0x2b, 0x2b, +0x2b, 0x01, 0x2b, 0x13, 0x17, 0x07, 0x27, 0x07, 0x27, 0xfa, +0x79, 0x22, 0x57, 0x57, 0x22, 0x02, 0xaf, 0x80, 0x27, 0x4e, +0x4e, 0x27, 0x00, 0x07, 0x00, 0x09, 0xff, 0xf3, 0x01, 0xeb, +0x02, 0x78, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x1f, 0x00, 0x27, +0x00, 0x33, 0x00, 0x3b, 0x00, 0x3f, 0x00, 0xfa, 0xb6, 0x3b, +0x28, 0x0d, 0x13, 0x00, 0x4c, 0x39, 0xb8, 0xff, 0xd8, 0xb4, +0x0d, 0x13, 0x00, 0x4c, 0x37, 0xb8, 0xff, 0xd0, 0x40, 0x11, +0x0d, 0x13, 0x00, 0x4c, 0x35, 0x28, 0x0d, 0x13, 0x00, 0x4c, +0x27, 0x30, 0x0d, 0x13, 0x00, 0x4c, 0x25, 0xb8, 0xff, 0xd8, +0xb4, 0x0d, 0x13, 0x00, 0x4c, 0x23, 0xb8, 0xff, 0xd8, 0x40, +0x11, 0x0d, 0x13, 0x00, 0x4c, 0x21, 0x28, 0x0d, 0x13, 0x00, +0x4c, 0x13, 0x28, 0x0d, 0x13, 0x00, 0x4c, 0x11, 0xb8, 0xff, +0xe0, 0xb4, 0x0d, 0x13, 0x00, 0x4c, 0x0f, 0xb8, 0xff, 0xe0, +0x40, 0x64, 0x0d, 0x13, 0x00, 0x4c, 0x0d, 0x20, 0x0d, 0x13, +0x00, 0x4c, 0x3e, 0x3f, 0x3f, 0x38, 0x14, 0x96, 0x40, 0x20, +0x50, 0x20, 0x60, 0x20, 0x03, 0x20, 0x1a, 0x96, 0x4f, 0x24, +0x5f, 0x24, 0x6f, 0x24, 0x03, 0x24, 0x28, 0x96, 0x40, 0x34, +0x50, 0x34, 0x60, 0x34, 0x03, 0x34, 0x2e, 0x96, 0x38, 0x41, +0x3c, 0x3d, 0x3d, 0x0c, 0x06, 0x96, 0x4f, 0x10, 0x5f, 0x10, +0x6f, 0x10, 0x03, 0x10, 0x00, 0x96, 0x0c, 0x40, 0x3f, 0x3e, +0x3d, 0x3c, 0x3e, 0x3c, 0x3e, 0x3c, 0x0e, 0x26, 0x31, 0x1d, +0x98, 0x36, 0x40, 0x22, 0x01, 0x22, 0x2b, 0x17, 0x98, 0x3a, +0x26, 0x5c, 0x03, 0x98, 0x4f, 0x12, 0x01, 0x12, 0x09, 0x98, +0x0e, 0x5a, 0x00, 0x3f, 0xed, 0xd4, 0x5d, 0xed, 0x3f, 0x33, +0xed, 0x32, 0xd4, 0x5d, 0x32, 0xed, 0x32, 0x11, 0x12, 0x39, +0x39, 0x2f, 0x2f, 0x10, 0xcd, 0x10, 0xcd, 0x01, 0x10, 0xd6, +0xfd, 0xdc, 0x5d, 0xed, 0x11, 0x33, 0x2f, 0x33, 0x10, 0xd6, +0xfd, 0xdc, 0x5d, 0xed, 0xde, 0x5d, 0xfd, 0xdc, 0x5d, 0xed, +0x11, 0x33, 0x2f, 0x33, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x14, +0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, +0x07, 0x34, 0x33, 0x32, 0x15, 0x14, 0x23, 0x22, 0x17, 0x14, +0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, +0x07, 0x34, 0x33, 0x32, 0x15, 0x14, 0x23, 0x22, 0x37, 0x14, +0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, +0x07, 0x34, 0x33, 0x32, 0x15, 0x14, 0x23, 0x22, 0x25, 0x27, +0x01, 0x17, 0x46, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0d, 0x0d, +0x0d, 0x35, 0x4e, 0x51, 0x50, 0x4f, 0xa2, 0x0e, 0x0d, 0x0e, +0x0e, 0x0e, 0x0e, 0x0d, 0x0e, 0x33, 0x4d, 0x51, 0x4f, 0x4f, +0xf9, 0x0e, 0x0d, 0x0d, 0x0e, 0x0e, 0x0d, 0x0d, 0x0e, 0x34, +0x4e, 0x50, 0x4e, 0x50, 0xfe, 0xe1, 0x1d, 0x01, 0xc5, 0x1d, +0x01, 0xef, 0x33, 0x27, 0x27, 0x33, 0x33, 0x26, 0x26, 0x33, +0x89, 0x89, 0x8a, 0xe9, 0x33, 0x26, 0x26, 0x33, 0x33, 0x26, +0x26, 0x33, 0x8a, 0x8a, 0x89, 0x89, 0x33, 0x26, 0x26, 0x33, +0x33, 0x26, 0x26, 0x33, 0x8a, 0x8a, 0x89, 0xda, 0x2d, 0x01, +0x28, 0x2d, 0x00, 0x00, 0xff, 0xff, 0x00, 0x37, 0xff, 0xf3, +0x01, 0xbd, 0x03, 0x3d, 0x02, 0x26, 0x00, 0x36, 0x00, 0x00, +0x01, 0x07, 0x01, 0x5f, 0x00, 0x12, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x00, 0x32, 0x36, 0x2e, 0x25, 0x50, 0x01, +0x0f, 0x37, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x01, +0x00, 0x90, 0x00, 0x38, 0x01, 0x55, 0x01, 0xc3, 0x00, 0x05, +0x00, 0x34, 0xb9, 0x00, 0x03, 0xff, 0xe8, 0xb3, 0x0c, 0x00, +0x4d, 0x03, 0xb8, 0xff, 0xf8, 0x40, 0x10, 0x0b, 0x00, 0x4d, +0x01, 0x05, 0x04, 0x02, 0x02, 0x04, 0x03, 0x00, 0x06, 0x05, +0x01, 0x00, 0x03, 0x00, 0x19, 0x2f, 0x33, 0xcd, 0xcd, 0x01, +0x18, 0x10, 0xd6, 0x32, 0xcd, 0x32, 0x2f, 0x10, 0xcd, 0x32, +0x31, 0x30, 0x2b, 0x2b, 0x37, 0x37, 0x17, 0x07, 0x17, 0x07, +0x90, 0x8b, 0x3a, 0x63, 0x63, 0x3a, 0xfe, 0xc5, 0x1f, 0xa6, +0xa6, 0x20, 0x00, 0x02, 0x00, 0x1b, 0xff, 0xfa, 0x01, 0xe2, +0x02, 0x71, 0x00, 0x0e, 0x00, 0x24, 0x00, 0x87, 0xb5, 0x14, +0x08, 0x0f, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xe8, 0x40, 0x0e, +0x0e, 0x00, 0x4d, 0x10, 0x10, 0x10, 0x00, 0x4d, 0x10, 0x18, +0x0f, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xf0, 0xb4, 0x0d, 0x0e, +0x00, 0x4c, 0x02, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, +0x02, 0xb8, 0xff, 0xf0, 0xb3, 0x0d, 0x00, 0x4d, 0x02, 0xb8, +0xff, 0xf8, 0x40, 0x29, 0x0b, 0x0c, 0x00, 0x4c, 0x1c, 0x20, +0x73, 0x0b, 0x0b, 0x12, 0x1e, 0x1e, 0x1a, 0x1a, 0x21, 0x26, +0x05, 0x76, 0x12, 0x25, 0x1f, 0x79, 0x1c, 0x1c, 0x18, 0x20, +0x79, 0x23, 0x42, 0x1b, 0x79, 0x18, 0x41, 0x00, 0x7c, 0x15, +0x41, 0x08, 0x7c, 0x0f, 0x42, 0x00, 0x3f, 0xed, 0x3f, 0xed, +0x3f, 0xed, 0x3f, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x01, 0x10, +0xd6, 0xed, 0x10, 0xce, 0x32, 0x2f, 0x32, 0x2f, 0x11, 0x39, +0x2f, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x13, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x16, +0x33, 0x32, 0x36, 0x37, 0x11, 0x26, 0x26, 0x03, 0x22, 0x26, +0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x17, 0x33, 0x15, 0x23, +0x15, 0x33, 0x15, 0x23, 0x15, 0x33, 0x15, 0x23, 0x06, 0xdc, +0x1b, 0x2b, 0x1c, 0x0f, 0x39, 0x38, 0x14, 0x14, 0x03, 0x0d, +0x15, 0x09, 0x59, 0x68, 0x68, 0x5a, 0x0b, 0x1e, 0x0e, 0xc1, +0x80, 0x69, 0x69, 0x8d, 0xce, 0x1d, 0x02, 0x2a, 0x24, 0x42, +0x5d, 0x3a, 0x74, 0x78, 0x06, 0x01, 0x01, 0xdb, 0x05, 0x02, +0xfd, 0xd0, 0x93, 0xa0, 0xa0, 0xa4, 0x04, 0x02, 0x46, 0xbe, +0x46, 0xdb, 0x46, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x95, +0x01, 0xab, 0x01, 0x5f, 0x02, 0xc6, 0x00, 0x13, 0x00, 0x1b, +0x40, 0x0c, 0x05, 0x0e, 0x00, 0x08, 0x94, 0x0e, 0x0b, 0x9a, +0x05, 0x00, 0x13, 0x5a, 0x00, 0x3f, 0xcd, 0xdc, 0xed, 0x01, +0x2f, 0xfd, 0xce, 0x12, 0x39, 0x31, 0x30, 0x01, 0x0e, 0x03, +0x07, 0x16, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, +0x34, 0x3e, 0x02, 0x37, 0x01, 0x5f, 0x12, 0x23, 0x1e, 0x18, +0x07, 0x20, 0x1d, 0x2e, 0x1c, 0x25, 0x26, 0x17, 0x2e, 0x47, +0x2f, 0x02, 0x85, 0x04, 0x08, 0x0f, 0x18, 0x13, 0x03, 0x2b, +0x15, 0x28, 0x29, 0x35, 0x26, 0x1d, 0x3f, 0x37, 0x27, 0x06, +0x00, 0x00, 0x00, 0x01, 0x00, 0x94, 0x01, 0xa8, 0x01, 0x5e, +0x02, 0xc3, 0x00, 0x13, 0x00, 0x19, 0x40, 0x0b, 0x05, 0x0e, +0x94, 0x00, 0x08, 0x00, 0x13, 0x05, 0x9a, 0x0b, 0x5a, 0x00, +0x3f, 0xfd, 0xdc, 0xcd, 0x01, 0x2f, 0xce, 0xed, 0x39, 0x31, +0x30, 0x13, 0x3e, 0x03, 0x37, 0x26, 0x26, 0x35, 0x34, 0x36, +0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x94, 0x12, +0x23, 0x1e, 0x18, 0x07, 0x20, 0x1d, 0x2e, 0x1c, 0x25, 0x26, +0x17, 0x2f, 0x46, 0x2f, 0x01, 0xe9, 0x04, 0x08, 0x0f, 0x17, +0x14, 0x03, 0x2b, 0x15, 0x28, 0x29, 0x35, 0x26, 0x1d, 0x3f, +0x37, 0x27, 0x06, 0x00, 0x00, 0x02, 0x00, 0x2b, 0x01, 0xb7, +0x01, 0xca, 0x02, 0xb5, 0x00, 0x13, 0x00, 0x27, 0x00, 0x2e, +0x40, 0x16, 0x19, 0x22, 0x94, 0x1c, 0x05, 0x0e, 0x00, 0x08, +0x94, 0x0e, 0x14, 0x1c, 0x0b, 0x1f, 0x9a, 0x05, 0x19, 0x00, +0x14, 0x13, 0x27, 0x5a, 0x00, 0x3f, 0x33, 0xcd, 0x32, 0xdc, +0x32, 0xed, 0x32, 0x01, 0x2f, 0xce, 0xde, 0xfd, 0xce, 0x12, +0x39, 0x10, 0xed, 0x39, 0x31, 0x30, 0x01, 0x0e, 0x03, 0x07, +0x16, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, +0x3e, 0x02, 0x37, 0x07, 0x0e, 0x03, 0x07, 0x16, 0x16, 0x15, +0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x3e, 0x02, 0x37, +0x01, 0xca, 0x11, 0x20, 0x1b, 0x16, 0x06, 0x1d, 0x1d, 0x21, +0x21, 0x1d, 0x2b, 0x11, 0x27, 0x41, 0x31, 0xd9, 0x11, 0x20, +0x1c, 0x16, 0x06, 0x1d, 0x1d, 0x20, 0x22, 0x1d, 0x2a, 0x11, +0x27, 0x41, 0x31, 0x02, 0x7b, 0x04, 0x07, 0x0e, 0x15, 0x12, +0x03, 0x27, 0x18, 0x19, 0x29, 0x28, 0x2c, 0x1c, 0x38, 0x2e, +0x22, 0x06, 0x3a, 0x04, 0x07, 0x0e, 0x15, 0x12, 0x03, 0x27, +0x18, 0x19, 0x29, 0x28, 0x2c, 0x1c, 0x38, 0x2e, 0x22, 0x06, +0x00, 0x00, 0x00, 0x02, 0x00, 0x2a, 0x01, 0xb7, 0x01, 0xc9, +0x02, 0xb5, 0x00, 0x13, 0x00, 0x27, 0x00, 0x2a, 0x40, 0x14, +0x19, 0x22, 0x94, 0x14, 0x1c, 0x05, 0x0e, 0x94, 0x00, 0x08, +0x14, 0x00, 0x27, 0x13, 0x19, 0x05, 0x9a, 0x1f, 0x0b, 0x5a, +0x00, 0x3f, 0x33, 0xfd, 0x32, 0xdc, 0x32, 0xcd, 0x32, 0x01, +0x2f, 0xce, 0xfd, 0x39, 0xde, 0xce, 0xed, 0x39, 0x31, 0x30, +0x13, 0x3e, 0x03, 0x37, 0x26, 0x26, 0x35, 0x34, 0x36, 0x33, +0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x37, 0x3e, 0x03, +0x37, 0x26, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, +0x14, 0x0e, 0x02, 0x07, 0x2a, 0x11, 0x20, 0x1b, 0x16, 0x06, +0x1d, 0x1d, 0x21, 0x21, 0x1d, 0x2b, 0x11, 0x27, 0x41, 0x31, +0xd9, 0x11, 0x20, 0x1c, 0x16, 0x06, 0x1d, 0x1d, 0x20, 0x22, +0x1d, 0x2a, 0x11, 0x27, 0x41, 0x30, 0x01, 0xf1, 0x04, 0x07, +0x0e, 0x16, 0x12, 0x02, 0x28, 0x17, 0x19, 0x29, 0x28, 0x2c, +0x1d, 0x37, 0x2e, 0x22, 0x06, 0x3a, 0x04, 0x07, 0x0e, 0x16, +0x12, 0x02, 0x28, 0x17, 0x19, 0x29, 0x28, 0x2c, 0x1d, 0x37, +0x2e, 0x22, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x72, +0x00, 0xad, 0x01, 0x82, 0x01, 0xcb, 0x00, 0x13, 0x00, 0x0d, +0xb3, 0x00, 0x0a, 0x0f, 0x05, 0x00, 0x2f, 0xcd, 0x01, 0x2f, +0xcd, 0x31, 0x30, 0x01, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, +0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x01, +0x82, 0x13, 0x23, 0x33, 0x1f, 0x20, 0x32, 0x23, 0x13, 0x13, +0x23, 0x32, 0x20, 0x1f, 0x33, 0x23, 0x13, 0x01, 0x3c, 0x1d, +0x34, 0x27, 0x17, 0x17, 0x27, 0x34, 0x1d, 0x1c, 0x34, 0x28, +0x17, 0x17, 0x28, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x45, +0x00, 0xec, 0x01, 0xaf, 0x01, 0x32, 0x00, 0x03, 0x00, 0x0d, +0xb3, 0x01, 0x03, 0x00, 0x03, 0x00, 0x2f, 0xcd, 0x01, 0x2f, +0xcd, 0x31, 0x30, 0x13, 0x21, 0x15, 0x21, 0x45, 0x01, 0x6a, +0xfe, 0x96, 0x01, 0x32, 0x46, 0x00, 0x00, 0x01, 0x00, 0x00, +0x00, 0xec, 0x01, 0xf4, 0x01, 0x32, 0x00, 0x03, 0x00, 0x0d, +0xb3, 0x03, 0x02, 0x00, 0x03, 0x00, 0x2f, 0xcd, 0x01, 0x2f, +0x2f, 0x31, 0x30, 0x11, 0x21, 0x15, 0x21, 0x01, 0xf4, 0xfe, +0x0c, 0x01, 0x32, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, +0x02, 0x24, 0x01, 0x84, 0x02, 0x91, 0x00, 0x1b, 0x00, 0x37, +0xb6, 0x11, 0x18, 0x0b, 0x10, 0x00, 0x4c, 0x02, 0xb8, 0xff, +0xe0, 0x40, 0x16, 0x0b, 0x10, 0x00, 0x4c, 0x1b, 0x2f, 0x00, +0x3f, 0x00, 0x02, 0x00, 0x0d, 0x0e, 0x1b, 0x1b, 0x13, 0x0a, +0x18, 0x05, 0x0d, 0x0d, 0x05, 0x00, 0x2f, 0x33, 0x2f, 0x10, +0xcd, 0xdc, 0xcd, 0x32, 0x2f, 0x01, 0x2f, 0xcd, 0xdc, 0x5d, +0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x01, 0x0e, 0x03, 0x23, 0x22, +0x26, 0x27, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x3e, 0x03, +0x33, 0x32, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, 0x37, 0x01, +0x84, 0x03, 0x0f, 0x16, 0x1e, 0x13, 0x0d, 0x23, 0x0b, 0x1a, +0x10, 0x0d, 0x18, 0x06, 0x2b, 0x03, 0x0f, 0x16, 0x1e, 0x12, +0x0d, 0x23, 0x0b, 0x1a, 0x10, 0x0d, 0x19, 0x06, 0x02, 0x7b, +0x0b, 0x1c, 0x18, 0x11, 0x0e, 0x05, 0x0e, 0x1a, 0x0e, 0x17, +0x0b, 0x1c, 0x18, 0x11, 0x0f, 0x05, 0x0e, 0x1a, 0x0e, 0x00, +0x00, 0x02, 0x00, 0x12, 0x01, 0x65, 0x01, 0xdc, 0x02, 0x6b, +0x00, 0x07, 0x00, 0x24, 0x00, 0x53, 0x40, 0x28, 0x23, 0x1e, +0x1d, 0x24, 0x08, 0x16, 0x16, 0x1d, 0x09, 0x0d, 0x14, 0x80, +0x0f, 0x01, 0x0f, 0x18, 0x1d, 0x26, 0x01, 0x02, 0x05, 0x06, +0x25, 0x23, 0x17, 0x17, 0x09, 0x15, 0x15, 0x02, 0x05, 0x07, +0x59, 0x16, 0x08, 0x08, 0x0f, 0x0f, 0x1e, 0x04, 0x00, 0x2f, +0x33, 0x33, 0x11, 0x33, 0x2f, 0x33, 0x3f, 0xcd, 0x32, 0x33, +0x11, 0x33, 0x33, 0x11, 0x33, 0x01, 0x10, 0xd6, 0xdd, 0xdd, +0xcd, 0x10, 0xd6, 0x32, 0xdc, 0x5d, 0x32, 0xcd, 0x32, 0x12, +0x39, 0x11, 0x33, 0x33, 0x10, 0xcd, 0x32, 0x31, 0x30, 0x13, +0x15, 0x23, 0x15, 0x23, 0x35, 0x23, 0x35, 0x05, 0x27, 0x0e, +0x03, 0x15, 0x23, 0x3e, 0x03, 0x37, 0x33, 0x17, 0x37, 0x33, +0x1e, 0x03, 0x17, 0x23, 0x34, 0x2e, 0x02, 0x27, 0x07, 0xcc, +0x40, 0x3a, 0x40, 0x01, 0x34, 0x27, 0x02, 0x02, 0x01, 0x01, +0x3a, 0x03, 0x06, 0x07, 0x07, 0x05, 0x36, 0x2c, 0x2f, 0x36, +0x05, 0x07, 0x06, 0x05, 0x03, 0x3a, 0x01, 0x01, 0x02, 0x01, +0x2a, 0x02, 0x6b, 0x32, 0xd4, 0xd4, 0x32, 0xc1, 0x74, 0x14, +0x3c, 0x39, 0x2c, 0x04, 0x32, 0x4a, 0x3c, 0x33, 0x1b, 0x88, +0x88, 0x1b, 0x34, 0x3c, 0x4a, 0x31, 0x04, 0x2c, 0x39, 0x3c, +0x14, 0x74, 0xff, 0xff, 0x00, 0x42, 0xff, 0xf5, 0x01, 0xb2, +0x02, 0xb2, 0x02, 0x26, 0x00, 0x56, 0x00, 0x00, 0x01, 0x06, +0x01, 0x5f, 0x0a, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x0a, +0x28, 0x2c, 0x22, 0x1b, 0x50, 0x01, 0x09, 0x2d, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x01, 0x00, 0x9f, 0x00, 0x38, 0x01, 0x64, +0x01, 0xc3, 0x00, 0x05, 0x00, 0x21, 0x40, 0x0f, 0x02, 0x10, +0x0b, 0x0c, 0x00, 0x4c, 0x02, 0x05, 0x04, 0x00, 0x03, 0x01, +0x04, 0x00, 0x02, 0x00, 0x19, 0x2f, 0xcd, 0xcd, 0x01, 0x18, +0x2f, 0x33, 0xcd, 0x32, 0xcd, 0x32, 0x31, 0x30, 0x2b, 0x37, +0x27, 0x37, 0x27, 0x37, 0x17, 0xd9, 0x3a, 0x63, 0x63, 0x3a, +0x8b, 0x38, 0x20, 0xa6, 0xa6, 0x1f, 0xc5, 0x00, 0x00, 0x00, +0x00, 0x03, 0x00, 0x1f, 0xff, 0xf5, 0x01, 0xde, 0x01, 0xdb, +0x00, 0x27, 0x00, 0x3b, 0x00, 0x42, 0x00, 0x93, 0xb9, 0x00, +0x22, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x22, 0xb8, 0xff, +0xf0, 0xb3, 0x11, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xf0, 0xb3, +0x0d, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe8, 0xb3, 0x0c, 0x00, +0x4d, 0x1a, 0xb8, 0xff, 0xf0, 0x40, 0x40, 0x0b, 0x00, 0x4d, +0x11, 0x10, 0x09, 0x0b, 0x00, 0x4c, 0x0b, 0x10, 0x0b, 0x00, +0x4d, 0x0b, 0x18, 0x09, 0x0a, 0x00, 0x4c, 0x16, 0x06, 0x42, +0x1f, 0x82, 0x2d, 0x2d, 0x0e, 0x3c, 0x82, 0x1b, 0x00, 0x00, +0x1b, 0x44, 0x37, 0x82, 0x0e, 0x43, 0x1f, 0x86, 0x42, 0x42, +0x24, 0x16, 0x3f, 0x88, 0x19, 0x50, 0x32, 0x88, 0x13, 0x50, +0x28, 0x88, 0x09, 0x51, 0x27, 0x27, 0x06, 0x24, 0x88, 0x03, +0x51, 0x00, 0x3f, 0xed, 0x32, 0x32, 0x2f, 0x3f, 0xed, 0x3f, +0xed, 0x3f, 0xed, 0x32, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, +0xd6, 0xed, 0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, 0x11, 0x39, +0x2f, 0xed, 0x32, 0x39, 0x39, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x06, 0x06, 0x23, 0x22, +0x26, 0x27, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, +0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x36, 0x36, 0x33, 0x32, +0x15, 0x14, 0x14, 0x07, 0x23, 0x14, 0x1e, 0x02, 0x33, 0x32, +0x36, 0x37, 0x05, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, +0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x37, 0x34, +0x26, 0x23, 0x22, 0x06, 0x15, 0x01, 0xd1, 0x14, 0x2e, 0x16, +0x23, 0x3c, 0x14, 0x11, 0x2e, 0x2a, 0x21, 0x2f, 0x1f, 0x0f, +0x0f, 0x1e, 0x30, 0x21, 0x25, 0x36, 0x0e, 0x12, 0x30, 0x1d, +0x79, 0x01, 0xb0, 0x0b, 0x15, 0x21, 0x16, 0x0d, 0x1e, 0x17, +0xfe, 0xe3, 0x0f, 0x14, 0x0d, 0x05, 0x06, 0x0e, 0x17, 0x10, +0x0f, 0x16, 0x0d, 0x06, 0x07, 0x0f, 0x17, 0xfb, 0x1a, 0x14, +0x19, 0x1d, 0x0f, 0x0e, 0x0c, 0x27, 0x33, 0x2e, 0x2c, 0x2a, +0x45, 0x58, 0x2e, 0x2d, 0x57, 0x44, 0x29, 0x2a, 0x30, 0x2f, +0x2b, 0xec, 0x06, 0x0e, 0x09, 0x1c, 0x35, 0x29, 0x19, 0x08, +0x0e, 0x17, 0x1c, 0x2f, 0x3c, 0x20, 0x20, 0x3f, 0x31, 0x1f, +0x1d, 0x2e, 0x3d, 0x1f, 0x21, 0x3e, 0x32, 0x1e, 0xd7, 0x3b, +0x45, 0x47, 0x39, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0d, +0x00, 0x00, 0x01, 0xe8, 0x03, 0x1a, 0x02, 0x26, 0x00, 0x3c, +0x00, 0x00, 0x01, 0x07, 0x00, 0x83, 0x00, 0x02, 0x00, 0x8b, +0x00, 0x17, 0x40, 0x10, 0x02, 0x01, 0x01, 0x13, 0x25, 0x04, +0x0c, 0x50, 0x02, 0x04, 0x1d, 0x4f, 0x01, 0x04, 0x11, 0x4f, +0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0x00, 0x02, +0x00, 0xb6, 0xff, 0x5b, 0x01, 0x3c, 0x01, 0xd1, 0x00, 0x0d, +0x00, 0x19, 0x00, 0x21, 0x40, 0x0f, 0x0b, 0x91, 0x00, 0x00, +0x11, 0x94, 0x17, 0x17, 0x1b, 0x1a, 0x05, 0x14, 0x9a, 0x0e, +0x0d, 0x00, 0x2f, 0x2f, 0xfd, 0xce, 0x01, 0x11, 0x12, 0x39, +0x2f, 0xed, 0x33, 0x2f, 0xed, 0x31, 0x30, 0x37, 0x34, 0x3e, +0x02, 0x37, 0x33, 0x1e, 0x03, 0x15, 0x15, 0x23, 0x13, 0x32, +0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, +0xcc, 0x03, 0x04, 0x07, 0x03, 0x39, 0x03, 0x06, 0x05, 0x02, +0x5a, 0x2d, 0x1c, 0x27, 0x27, 0x1c, 0x1b, 0x28, 0x28, 0x03, +0x25, 0x3e, 0x38, 0x37, 0x1e, 0x1e, 0x37, 0x38, 0x3e, 0x25, +0xa8, 0x02, 0x76, 0x25, 0x1f, 0x1f, 0x24, 0x24, 0x1f, 0x1f, +0x25, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x31, 0xff, 0x9f, +0x01, 0xc2, 0x02, 0x6b, 0x00, 0x23, 0x00, 0x60, 0xb9, 0x00, +0x16, 0xff, 0xc8, 0xb3, 0x0f, 0x00, 0x4d, 0x16, 0xb8, 0xff, +0xe0, 0xb3, 0x0e, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xd0, 0xb3, +0x0f, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xe8, 0x40, 0x20, 0x0e, +0x00, 0x4d, 0x08, 0x1e, 0x7f, 0x05, 0x21, 0x21, 0x00, 0x0b, +0x0b, 0x1b, 0x25, 0x14, 0x82, 0x00, 0x24, 0x1a, 0x1a, 0x17, +0x89, 0x1e, 0x21, 0x20, 0x0c, 0x0c, 0x0f, 0x88, 0x05, 0x08, +0x06, 0x00, 0x2f, 0xdd, 0x32, 0xed, 0x32, 0x2f, 0x2f, 0xdd, +0x32, 0xed, 0x32, 0x2f, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xce, +0x32, 0x2f, 0x11, 0x39, 0x2f, 0x33, 0xed, 0x32, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x34, 0x3e, 0x02, 0x37, 0x35, +0x33, 0x15, 0x16, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, +0x0e, 0x02, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, +0x06, 0x06, 0x07, 0x15, 0x23, 0x35, 0x26, 0x26, 0x31, 0x1e, +0x36, 0x4b, 0x2c, 0x4a, 0x1b, 0x36, 0x1f, 0x12, 0x21, 0x36, +0x1c, 0x24, 0x3f, 0x2e, 0x1a, 0x63, 0x50, 0x20, 0x3a, 0x23, +0x0c, 0x1e, 0x3c, 0x22, 0x4a, 0x5c, 0x6f, 0x01, 0x04, 0x35, +0x51, 0x3a, 0x22, 0x06, 0x7f, 0x7c, 0x02, 0x09, 0x0a, 0x45, +0x0c, 0x07, 0x13, 0x27, 0x3f, 0x2b, 0x53, 0x4f, 0x08, 0x0c, +0x44, 0x0b, 0x0a, 0x02, 0x7c, 0x7e, 0x0d, 0x74, 0x00, 0x01, +0x00, 0x2d, 0x00, 0x00, 0x01, 0xc7, 0x02, 0x76, 0x00, 0x22, +0x00, 0x6a, 0xb9, 0x00, 0x1f, 0xff, 0xf0, 0xb3, 0x12, 0x00, +0x4d, 0x1f, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x1f, +0xb8, 0xff, 0xf0, 0x40, 0x31, 0x10, 0x00, 0x4d, 0x14, 0x10, +0x0b, 0x0c, 0x00, 0x4c, 0x14, 0x18, 0x0a, 0x00, 0x4d, 0x14, +0x10, 0x09, 0x00, 0x4d, 0x1a, 0x1a, 0x01, 0x01, 0x08, 0x24, +0x03, 0x00, 0x91, 0x0e, 0x11, 0x0f, 0x23, 0x1b, 0x1b, 0x1d, +0x9b, 0x17, 0x03, 0x0e, 0x97, 0x00, 0x11, 0x11, 0x17, 0x5a, +0x07, 0x97, 0x0a, 0x60, 0x00, 0x3f, 0xed, 0x3f, 0x39, 0x2f, +0x33, 0xed, 0x32, 0x10, 0xed, 0x32, 0x2f, 0x01, 0x10, 0xd6, +0xdd, 0x32, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, 0x32, 0x2f, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x33, +0x15, 0x23, 0x15, 0x14, 0x06, 0x07, 0x21, 0x15, 0x21, 0x36, +0x36, 0x35, 0x35, 0x23, 0x35, 0x33, 0x35, 0x34, 0x3e, 0x02, +0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x23, 0x22, 0x0e, 0x02, +0x15, 0xd2, 0xaa, 0xaa, 0x07, 0x07, 0x01, 0x03, 0xfe, 0xa0, +0x0a, 0x0f, 0x53, 0x53, 0x1c, 0x32, 0x47, 0x2c, 0x27, 0x35, +0x19, 0x14, 0x2d, 0x38, 0x18, 0x27, 0x1d, 0x0f, 0x01, 0x4d, +0x43, 0x07, 0x2d, 0x62, 0x2d, 0x47, 0x40, 0x7d, 0x40, 0x0d, +0x43, 0x4a, 0x42, 0x57, 0x32, 0x14, 0x0d, 0x0b, 0x47, 0x16, +0x0e, 0x22, 0x39, 0x2b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x26, +0x00, 0x61, 0x01, 0xcf, 0x02, 0x0a, 0x00, 0x1c, 0x00, 0x28, +0x00, 0x53, 0x40, 0x23, 0x04, 0x19, 0x19, 0x03, 0x1a, 0x1a, +0x00, 0x0a, 0x13, 0x13, 0x0b, 0x12, 0x12, 0x1d, 0x0e, 0x23, +0x00, 0x29, 0x12, 0x1a, 0x1a, 0x13, 0x19, 0x19, 0x16, 0x0b, +0x03, 0x03, 0x0a, 0x04, 0x04, 0x20, 0x07, 0x26, 0x16, 0x00, +0x2f, 0xcd, 0xdc, 0xcd, 0x33, 0x2f, 0x33, 0x33, 0x19, 0x2f, +0x33, 0x11, 0x33, 0x18, 0x2f, 0x33, 0x33, 0x19, 0x2f, 0x33, +0x01, 0x18, 0x10, 0xd6, 0xcd, 0xdc, 0xcd, 0x33, 0x2f, 0x33, +0x33, 0x19, 0x2f, 0x33, 0x11, 0x33, 0x18, 0x2f, 0x33, 0x33, +0x19, 0x2f, 0x33, 0x31, 0x30, 0x13, 0x34, 0x37, 0x27, 0x37, +0x17, 0x36, 0x33, 0x32, 0x17, 0x37, 0x17, 0x07, 0x16, 0x15, +0x14, 0x06, 0x07, 0x17, 0x07, 0x27, 0x06, 0x23, 0x22, 0x27, +0x07, 0x27, 0x37, 0x26, 0x25, 0x34, 0x26, 0x23, 0x22, 0x06, +0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x4e, 0x19, 0x41, 0x33, +0x42, 0x2b, 0x34, 0x33, 0x2b, 0x43, 0x34, 0x43, 0x1a, 0x0d, +0x0d, 0x43, 0x34, 0x43, 0x2b, 0x33, 0x36, 0x29, 0x42, 0x33, +0x41, 0x19, 0x01, 0x15, 0x3e, 0x2b, 0x2b, 0x3e, 0x3e, 0x2b, +0x2b, 0x3e, 0x01, 0x36, 0x37, 0x28, 0x42, 0x33, 0x43, 0x1a, +0x1a, 0x43, 0x33, 0x42, 0x28, 0x37, 0x1d, 0x2e, 0x14, 0x42, +0x34, 0x42, 0x19, 0x19, 0x42, 0x34, 0x41, 0x28, 0x38, 0x33, +0x3c, 0x3c, 0x33, 0x33, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x01, +0x00, 0x0d, 0x00, 0x00, 0x01, 0xe8, 0x02, 0x6b, 0x00, 0x1e, +0x00, 0x76, 0x40, 0x3e, 0x18, 0x1c, 0x1d, 0x16, 0x12, 0x0f, +0x12, 0x78, 0x13, 0x16, 0x14, 0x13, 0x16, 0x13, 0x19, 0x1d, +0x73, 0x01, 0x08, 0x0c, 0x0f, 0x0c, 0x78, 0x0b, 0x08, 0x14, +0x0b, 0x08, 0x0b, 0x06, 0x02, 0x05, 0x01, 0x01, 0x20, 0x1f, +0x0f, 0x12, 0x13, 0x41, 0x19, 0x05, 0x79, 0x08, 0x16, 0x0f, +0x08, 0x1d, 0x01, 0x79, 0x04, 0x1a, 0x04, 0x08, 0x04, 0x08, +0x04, 0x0c, 0x0b, 0x41, 0x00, 0x42, 0x00, 0x3f, 0x3f, 0x33, +0x39, 0x39, 0x2f, 0x2f, 0x11, 0x33, 0x10, 0xed, 0x32, 0x11, +0x33, 0x33, 0x10, 0xed, 0x32, 0x3f, 0x33, 0x01, 0x2f, 0x11, +0x12, 0x39, 0x2f, 0x33, 0xcd, 0x32, 0xdc, 0x87, 0x2b, 0x87, +0x7d, 0xc4, 0x01, 0x18, 0x10, 0xfd, 0x32, 0xdc, 0x87, 0x2b, +0x87, 0x7d, 0xc4, 0x01, 0x18, 0x10, 0xcd, 0x32, 0x31, 0x30, +0x33, 0x35, 0x23, 0x35, 0x33, 0x35, 0x23, 0x35, 0x33, 0x26, +0x26, 0x27, 0x33, 0x16, 0x16, 0x17, 0x36, 0x36, 0x37, 0x33, +0x06, 0x06, 0x07, 0x33, 0x15, 0x23, 0x15, 0x33, 0x15, 0x23, +0x15, 0xd2, 0x91, 0x91, 0x91, 0x7a, 0x31, 0x57, 0x26, 0x5b, +0x20, 0x4c, 0x29, 0x27, 0x49, 0x20, 0x5b, 0x28, 0x56, 0x31, +0x7b, 0x90, 0x90, 0x90, 0x5f, 0x3f, 0x5b, 0x40, 0x4e, 0x9b, +0x49, 0x46, 0x8b, 0x40, 0x40, 0x8b, 0x46, 0x4b, 0x99, 0x4e, +0x40, 0x5b, 0x3f, 0x5f, 0x00, 0x00, 0x00, 0x02, 0x00, 0xd4, +0xff, 0x5b, 0x01, 0x21, 0x02, 0xbb, 0x00, 0x03, 0x00, 0x07, +0x00, 0x1d, 0x40, 0x0c, 0x06, 0x01, 0x91, 0x07, 0x00, 0x00, +0x09, 0x08, 0x07, 0x04, 0x00, 0x03, 0x00, 0x2f, 0xcd, 0x2f, +0xcd, 0x01, 0x11, 0x12, 0x39, 0x2f, 0x33, 0xed, 0x32, 0x31, +0x30, 0x37, 0x33, 0x11, 0x23, 0x11, 0x33, 0x11, 0x23, 0xd4, +0x4d, 0x4d, 0x4d, 0x4d, 0xb1, 0xfe, 0xaa, 0x03, 0x60, 0xfe, +0xaa, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x44, 0xff, 0x9f, +0x01, 0xaf, 0x02, 0x79, 0x00, 0x38, 0x00, 0x4a, 0x01, 0x4b, +0xb5, 0x47, 0x20, 0x12, 0x00, 0x4d, 0x3a, 0xb8, 0xff, 0xe8, +0xb3, 0x10, 0x00, 0x4d, 0x3a, 0xb8, 0xff, 0xf0, 0xb3, 0x0d, +0x00, 0x4d, 0x33, 0xb8, 0xff, 0xe8, 0xb4, 0x0b, 0x0c, 0x00, +0x4c, 0x33, 0xb8, 0xff, 0xe0, 0xb4, 0x09, 0x0a, 0x00, 0x4c, +0x30, 0xb8, 0xff, 0xd8, 0xb3, 0x12, 0x00, 0x4d, 0x30, 0xb8, +0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x30, 0xb8, 0xff, 0xd8, +0xb3, 0x0d, 0x00, 0x4d, 0x30, 0xb8, 0xff, 0xd0, 0xb3, 0x0c, +0x00, 0x4d, 0x30, 0xb8, 0xff, 0xe0, 0xb3, 0x0b, 0x00, 0x4d, +0x2f, 0xb8, 0xff, 0xe0, 0xb3, 0x11, 0x00, 0x4d, 0x2e, 0xb8, +0xff, 0xd0, 0xb3, 0x11, 0x00, 0x4d, 0x28, 0xb8, 0xff, 0xd8, +0xb3, 0x11, 0x00, 0x4d, 0x28, 0xb8, 0xff, 0xd8, 0xb3, 0x0f, +0x00, 0x4d, 0x28, 0xb8, 0xff, 0xe8, 0xb3, 0x0d, 0x00, 0x4d, +0x28, 0xb8, 0xff, 0xe0, 0xb3, 0x0c, 0x00, 0x4d, 0x27, 0xb8, +0xff, 0xe0, 0xb3, 0x11, 0x00, 0x4d, 0x24, 0xb8, 0xff, 0xf8, +0x40, 0x72, 0x0e, 0x00, 0x4d, 0x16, 0x18, 0x0b, 0x00, 0x4d, +0x16, 0x20, 0x0a, 0x00, 0x4d, 0x16, 0x18, 0x09, 0x00, 0x4d, +0x13, 0x18, 0x12, 0x00, 0x4d, 0x13, 0x20, 0x10, 0x11, 0x00, +0x4c, 0x13, 0x28, 0x0c, 0x0d, 0x00, 0x4c, 0x13, 0x18, 0x0b, +0x00, 0x4d, 0x0b, 0x18, 0x12, 0x00, 0x4d, 0x0b, 0x20, 0x11, +0x00, 0x4d, 0x0b, 0x10, 0x0f, 0x00, 0x4d, 0x0b, 0x10, 0x0d, +0x00, 0x4d, 0x0b, 0x18, 0x0c, 0x00, 0x4d, 0x2f, 0x05, 0x76, +0x32, 0x32, 0x45, 0x76, 0x2a, 0x1b, 0x1b, 0x2a, 0x4c, 0x12, +0x22, 0x76, 0x15, 0x15, 0x3c, 0x76, 0x0d, 0x38, 0x38, 0x00, +0x0d, 0x01, 0x08, 0x0d, 0x4b, 0x12, 0x4a, 0x08, 0x4a, 0x35, +0x1f, 0x2f, 0x41, 0x25, 0x41, 0x18, 0x00, 0x00, 0x03, 0x7c, +0x35, 0x1c, 0x1c, 0x1f, 0x7c, 0x18, 0x00, 0x2f, 0xed, 0x32, +0x2f, 0x2f, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x39, 0x11, 0x33, +0x11, 0x12, 0x39, 0x39, 0x11, 0x33, 0x01, 0x10, 0xc6, 0x5e, +0x5d, 0x32, 0x2f, 0x10, 0xed, 0x33, 0x2f, 0xed, 0x32, 0x10, +0xce, 0x32, 0x2f, 0x10, 0xed, 0x33, 0x2f, 0xed, 0x32, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x17, 0x16, 0x16, 0x33, 0x32, 0x35, 0x34, 0x26, 0x27, +0x2e, 0x03, 0x35, 0x34, 0x3e, 0x02, 0x37, 0x26, 0x26, 0x35, +0x34, 0x36, 0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, +0x22, 0x06, 0x15, 0x14, 0x16, 0x17, 0x1e, 0x03, 0x15, 0x14, +0x0e, 0x02, 0x07, 0x16, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, +0x26, 0x27, 0x13, 0x06, 0x06, 0x15, 0x14, 0x1e, 0x02, 0x17, +0x17, 0x36, 0x36, 0x35, 0x34, 0x2e, 0x02, 0x27, 0x5a, 0x1b, +0x40, 0x32, 0x65, 0x30, 0x39, 0x21, 0x39, 0x2c, 0x19, 0x0f, +0x17, 0x1c, 0x0d, 0x16, 0x1a, 0x57, 0x4e, 0x2e, 0x4e, 0x18, +0x13, 0x16, 0x3d, 0x2f, 0x23, 0x32, 0x2c, 0x32, 0x21, 0x39, +0x2c, 0x19, 0x0e, 0x16, 0x1b, 0x0d, 0x1a, 0x20, 0x5f, 0x58, +0x3c, 0x4d, 0x17, 0x84, 0x1a, 0x20, 0x15, 0x24, 0x32, 0x1d, +0x11, 0x1a, 0x20, 0x15, 0x23, 0x2f, 0x1a, 0x01, 0x0b, 0x11, +0x3e, 0x20, 0x23, 0x13, 0x0b, 0x19, 0x23, 0x32, 0x24, 0x17, +0x28, 0x21, 0x19, 0x08, 0x12, 0x2e, 0x1e, 0x3e, 0x48, 0x11, +0x08, 0x45, 0x08, 0x12, 0x1d, 0x1e, 0x1f, 0x22, 0x10, 0x0b, +0x19, 0x24, 0x31, 0x24, 0x16, 0x27, 0x21, 0x1a, 0x08, 0x13, +0x32, 0x21, 0x43, 0x44, 0x13, 0x0b, 0x01, 0xb8, 0x11, 0x2d, +0x1b, 0x17, 0x20, 0x18, 0x12, 0x0a, 0x06, 0x11, 0x2c, 0x1c, +0x17, 0x1f, 0x16, 0x12, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x02, +0x00, 0x71, 0x02, 0x26, 0x01, 0x83, 0x02, 0x8f, 0x00, 0x0b, +0x00, 0x17, 0x00, 0x25, 0xb9, 0x00, 0x15, 0xff, 0xc0, 0x40, +0x10, 0x0f, 0x12, 0x48, 0x15, 0x0f, 0x03, 0x40, 0x0f, 0x12, +0x48, 0x03, 0x09, 0x12, 0x06, 0x0c, 0x00, 0x00, 0x2f, 0x32, +0xcd, 0x32, 0x01, 0x2f, 0xcd, 0x2b, 0xde, 0xcd, 0x2b, 0x31, +0x30, 0x13, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, +0x15, 0x14, 0x06, 0x33, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, +0x32, 0x16, 0x15, 0x14, 0x06, 0xa5, 0x14, 0x20, 0x20, 0x14, +0x15, 0x1f, 0x1f, 0x95, 0x15, 0x1f, 0x1f, 0x15, 0x15, 0x1f, +0x1f, 0x02, 0x26, 0x1e, 0x17, 0x17, 0x1d, 0x1d, 0x17, 0x17, +0x1e, 0x1e, 0x17, 0x17, 0x1d, 0x1d, 0x17, 0x17, 0x1e, 0x00, +0x00, 0x03, 0x00, 0x22, 0xff, 0xf5, 0x01, 0xd2, 0x01, 0xdb, +0x00, 0x13, 0x00, 0x31, 0x00, 0x45, 0x01, 0x02, 0xb5, 0x43, +0x10, 0x10, 0x00, 0x4d, 0x39, 0xb8, 0xff, 0xe8, 0x40, 0x28, +0x10, 0x00, 0x4d, 0x35, 0x10, 0x10, 0x00, 0x4d, 0x1f, 0x18, +0x0f, 0x00, 0x4d, 0x1f, 0x20, 0x0b, 0x00, 0x4d, 0x1a, 0x20, +0x0b, 0x00, 0x4d, 0x19, 0x08, 0x0f, 0x00, 0x4d, 0x11, 0x30, +0x0f, 0x00, 0x4d, 0x11, 0x20, 0x0b, 0x0c, 0x00, 0x4c, 0x0d, +0xb8, 0xff, 0xd0, 0xb3, 0x0f, 0x00, 0x4d, 0x0d, 0xb8, 0xff, +0xe0, 0xb4, 0x0b, 0x0c, 0x00, 0x4c, 0x0c, 0xb8, 0xff, 0xf8, +0xb3, 0x11, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xd8, 0xb3, 0x0f, +0x00, 0x4d, 0x07, 0xb8, 0xff, 0xe0, 0xb3, 0x0c, 0x00, 0x4d, +0x07, 0xb8, 0xff, 0xd8, 0x40, 0x18, 0x0b, 0x00, 0x4d, 0x03, +0x28, 0x0f, 0x00, 0x4d, 0x03, 0x18, 0x0d, 0x00, 0x4d, 0x03, +0x20, 0x0c, 0x00, 0x4d, 0x03, 0x28, 0x0b, 0x00, 0x4d, 0x0a, +0xb8, 0xff, 0xe8, 0xb3, 0x15, 0x00, 0x4d, 0x0a, 0xb8, 0xff, +0xe8, 0x40, 0x0e, 0x0d, 0x00, 0x4d, 0x00, 0x18, 0x15, 0x00, +0x4d, 0x00, 0x18, 0x0d, 0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xe8, +0xb3, 0x16, 0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xf0, 0x40, 0x2b, +0x15, 0x00, 0x4d, 0x05, 0x18, 0x16, 0x00, 0x4d, 0x05, 0x10, +0x15, 0x00, 0x4d, 0x24, 0x24, 0x14, 0x00, 0x96, 0x3c, 0x47, +0x2b, 0x96, 0x1c, 0x0a, 0x96, 0x32, 0x46, 0x2e, 0x98, 0x17, +0x0f, 0x98, 0x41, 0x5c, 0x28, 0x98, 0x21, 0x05, 0x98, 0x4f, +0x37, 0x01, 0x37, 0x00, 0x2f, 0x5d, 0xfd, 0xde, 0xed, 0x3f, +0xfd, 0xde, 0xed, 0x01, 0x10, 0xd6, 0xfd, 0xde, 0xed, 0x10, +0xd6, 0xfd, 0xce, 0x32, 0x2f, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, +0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x34, 0x2e, 0x02, +0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, +0x3e, 0x02, 0x07, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x26, +0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, +0x25, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, +0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x01, 0x98, 0x1b, 0x2d, +0x38, 0x1e, 0x1e, 0x38, 0x2d, 0x1b, 0x1b, 0x2d, 0x38, 0x1e, +0x1e, 0x39, 0x2c, 0x1b, 0x51, 0x11, 0x25, 0x11, 0x1d, 0x2b, +0x1c, 0x0e, 0x0e, 0x1c, 0x2b, 0x1e, 0x10, 0x23, 0x11, 0x14, +0x0b, 0x16, 0x09, 0x20, 0x1b, 0x21, 0x1e, 0x09, 0x17, 0x0b, +0xfe, 0xec, 0x26, 0x3d, 0x4e, 0x28, 0x28, 0x4e, 0x3c, 0x25, +0x26, 0x3d, 0x4e, 0x28, 0x29, 0x4d, 0x3c, 0x25, 0xe7, 0x30, +0x47, 0x2f, 0x18, 0x18, 0x2f, 0x47, 0x2e, 0x30, 0x47, 0x2f, +0x18, 0x18, 0x2f, 0x46, 0x40, 0x08, 0x08, 0x15, 0x23, 0x2d, +0x18, 0x18, 0x2e, 0x24, 0x16, 0x05, 0x08, 0x36, 0x05, 0x03, +0x28, 0x19, 0x20, 0x25, 0x04, 0x05, 0x3a, 0x3d, 0x5c, 0x3d, +0x1e, 0x1e, 0x3d, 0x5b, 0x3c, 0x3d, 0x5b, 0x3d, 0x1f, 0x1f, +0x3c, 0x5b, 0x00, 0x02, 0x00, 0x76, 0x01, 0x26, 0x01, 0x80, +0x02, 0x76, 0x00, 0x0e, 0x00, 0x2d, 0x00, 0x77, 0x40, 0x1b, +0x25, 0x18, 0x15, 0x00, 0x4d, 0x1b, 0x18, 0x10, 0x00, 0x4d, +0x1b, 0x10, 0x0f, 0x00, 0x4d, 0x1b, 0x18, 0x0e, 0x00, 0x4d, +0x18, 0x20, 0x0e, 0x10, 0x00, 0x4c, 0x11, 0xb8, 0xff, 0xc8, +0xb3, 0x10, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xe8, 0xb3, 0x0f, +0x00, 0x4d, 0x11, 0xb8, 0xff, 0xd8, 0xb3, 0x0e, 0x00, 0x4d, +0x11, 0xb8, 0xff, 0xe0, 0x40, 0x1e, 0x0b, 0x0d, 0x00, 0x4c, +0x21, 0x04, 0x12, 0x2f, 0x2b, 0x2b, 0x0c, 0x19, 0x2e, 0x07, +0x20, 0x1e, 0x30, 0x1e, 0x40, 0x1e, 0x03, 0x1e, 0x1e, 0x0f, +0x00, 0x16, 0x5e, 0x27, 0x0f, 0x5a, 0x00, 0x3f, 0xcd, 0x3f, +0xcd, 0x11, 0x39, 0x2f, 0x5d, 0xcd, 0x01, 0x10, 0xd6, 0xcd, +0x33, 0x2f, 0x10, 0xde, 0xcd, 0x32, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x32, 0x36, +0x37, 0x35, 0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, +0x16, 0x13, 0x32, 0x16, 0x15, 0x15, 0x06, 0x06, 0x23, 0x22, +0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x35, +0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, +0x01, 0x03, 0x14, 0x26, 0x05, 0x0a, 0x1e, 0x0e, 0x0f, 0x1f, +0x1a, 0x10, 0x2a, 0x1f, 0x49, 0x3a, 0x16, 0x48, 0x25, 0x3b, +0x4c, 0x17, 0x28, 0x33, 0x1d, 0x0d, 0x1d, 0x13, 0x05, 0x10, +0x1d, 0x17, 0x15, 0x30, 0x12, 0x09, 0x11, 0x36, 0x01, 0x5d, +0x02, 0x02, 0x59, 0x02, 0x02, 0x04, 0x0a, 0x13, 0x0f, 0x1a, +0x17, 0x01, 0x19, 0x44, 0x38, 0xc8, 0x05, 0x07, 0x30, 0x38, +0x1c, 0x27, 0x18, 0x0b, 0x02, 0x02, 0x02, 0x0d, 0x1b, 0x15, +0x0d, 0x05, 0x06, 0x38, 0x05, 0x08, 0x00, 0x00, 0x00, 0x02, +0x00, 0x3f, 0x00, 0x4f, 0x01, 0x9d, 0x01, 0xae, 0x00, 0x05, +0x00, 0x0b, 0x00, 0x3a, 0x40, 0x19, 0x07, 0x0b, 0x40, 0x08, +0x0a, 0x09, 0x06, 0x00, 0x80, 0x01, 0x05, 0x40, 0x02, 0x04, +0x80, 0x03, 0x00, 0x0b, 0x05, 0x07, 0x01, 0x09, 0x06, 0x00, +0x03, 0x00, 0x19, 0x2f, 0x33, 0x33, 0x33, 0xcd, 0x32, 0xcd, +0x32, 0x01, 0x18, 0x2f, 0x33, 0x1a, 0xdd, 0x32, 0x1a, 0xcd, +0x32, 0x1a, 0x10, 0xdc, 0x32, 0xdd, 0x32, 0x1a, 0xcd, 0x32, +0x31, 0x30, 0x37, 0x37, 0x17, 0x07, 0x17, 0x07, 0x37, 0x37, +0x17, 0x07, 0x17, 0x07, 0x3f, 0x77, 0x34, 0x54, 0x50, 0x32, +0x3e, 0x78, 0x33, 0x53, 0x50, 0x32, 0xfe, 0xb0, 0x1b, 0x95, +0x90, 0x1f, 0xaf, 0xb0, 0x1b, 0x95, 0x90, 0x1f, 0x00, 0x00, +0x00, 0x01, 0x00, 0x29, 0x00, 0x2b, 0x01, 0xc2, 0x01, 0x5b, +0x00, 0x05, 0x00, 0x11, 0xb5, 0x03, 0x00, 0x04, 0x02, 0x00, +0x03, 0x00, 0x2f, 0xcd, 0xcd, 0x01, 0x2f, 0xdd, 0xcd, 0x31, +0x30, 0x01, 0x11, 0x23, 0x35, 0x21, 0x35, 0x01, 0xc2, 0x47, +0xfe, 0xae, 0x01, 0x5b, 0xfe, 0xd0, 0xea, 0x46, 0xff, 0xff, +0x00, 0x8c, 0x00, 0xd7, 0x01, 0x68, 0x01, 0x25, 0x02, 0x06, +0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x22, 0xff, 0xf5, +0x01, 0xd2, 0x01, 0xdb, 0x00, 0x13, 0x00, 0x27, 0x00, 0x3a, +0x00, 0x45, 0x01, 0x72, 0x40, 0x0b, 0x38, 0x10, 0x13, 0x00, +0x4d, 0x37, 0x08, 0x13, 0x00, 0x4d, 0x30, 0xb8, 0xff, 0xf0, +0xb3, 0x12, 0x00, 0x4d, 0x30, 0xb8, 0xff, 0xe8, 0xb3, 0x11, +0x00, 0x4d, 0x30, 0xb8, 0xff, 0xe8, 0x40, 0x0f, 0x0e, 0x00, +0x4d, 0x26, 0x08, 0x11, 0x12, 0x00, 0x4c, 0x25, 0x10, 0x10, +0x00, 0x4d, 0x1c, 0xb8, 0xff, 0xf8, 0xb3, 0x12, 0x00, 0x4d, +0x1b, 0xb8, 0xff, 0xf0, 0x40, 0x15, 0x10, 0x00, 0x4d, 0x17, +0x10, 0x10, 0x00, 0x4d, 0x11, 0x10, 0x13, 0x14, 0x00, 0x4c, +0x11, 0x28, 0x0b, 0x0c, 0x00, 0x4c, 0x0d, 0xb8, 0xff, 0xe8, +0xb4, 0x13, 0x14, 0x00, 0x4c, 0x0d, 0xb8, 0xff, 0xe0, 0xb4, +0x0b, 0x0d, 0x00, 0x4c, 0x07, 0xb8, 0xff, 0xe8, 0xb4, 0x13, +0x14, 0x00, 0x4c, 0x07, 0xb8, 0xff, 0xe8, 0xb3, 0x0d, 0x00, +0x4d, 0x07, 0xb8, 0xff, 0xe0, 0x40, 0x15, 0x0b, 0x0c, 0x00, +0x4c, 0x03, 0x18, 0x14, 0x00, 0x4d, 0x03, 0x20, 0x13, 0x00, +0x4d, 0x03, 0x28, 0x0b, 0x0c, 0x00, 0x4c, 0x11, 0xb8, 0xff, +0xe8, 0xb3, 0x16, 0x00, 0x4d, 0x0d, 0xb8, 0xff, 0xe8, 0x40, +0x0e, 0x16, 0x00, 0x4d, 0x07, 0x18, 0x16, 0x00, 0x4d, 0x03, +0x10, 0x16, 0x00, 0x4d, 0x0a, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, +0x00, 0x4d, 0x0a, 0xb8, 0xff, 0xe8, 0x40, 0x09, 0x0d, 0x00, +0x4d, 0x00, 0x20, 0x0f, 0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xe8, +0x40, 0x30, 0x15, 0x00, 0x4d, 0x05, 0x18, 0x15, 0x00, 0x4d, +0x3a, 0x5f, 0x33, 0x01, 0x33, 0x37, 0x4b, 0x36, 0x01, 0x36, +0x3f, 0x96, 0x3f, 0x31, 0x01, 0x31, 0x40, 0x19, 0x1c, 0x48, +0x40, 0x31, 0x01, 0x31, 0x00, 0x20, 0x0d, 0x00, 0x4d, 0x00, +0x96, 0x1e, 0x47, 0x3b, 0x29, 0x96, 0x30, 0x2a, 0x01, 0x2a, +0xb8, 0xff, 0xc0, 0x40, 0x29, 0x19, 0x1c, 0x48, 0x2a, 0x0a, +0x96, 0x30, 0x14, 0x01, 0x14, 0x46, 0x33, 0x3f, 0x3a, 0x01, +0x3a, 0x98, 0x30, 0x3b, 0x01, 0x3b, 0x3b, 0x2e, 0x36, 0xdf, +0x2a, 0x01, 0x2a, 0x0f, 0x98, 0x23, 0x46, 0x42, 0x98, 0x2e, +0x05, 0x98, 0x4f, 0x19, 0x01, 0x19, 0x00, 0x2f, 0x5d, 0xfd, +0xde, 0xed, 0x3f, 0xfd, 0xce, 0x5d, 0x32, 0x11, 0x39, 0x2f, +0x71, 0xed, 0x71, 0x32, 0x01, 0x10, 0xd6, 0x72, 0xfd, 0xde, +0x2b, 0x72, 0xed, 0x32, 0x10, 0xd6, 0xfd, 0x2b, 0xde, 0x5d, +0x2b, 0x72, 0xed, 0xd6, 0x5d, 0x32, 0xc5, 0x71, 0x32, 0x00, +0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x31, 0x30, 0x00, 0x2b, +0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x34, 0x2e, 0x02, 0x23, 0x22, +0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, +0x25, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, +0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x37, 0x15, 0x23, 0x35, +0x36, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x07, 0x16, 0x16, +0x17, 0x23, 0x26, 0x26, 0x27, 0x27, 0x33, 0x32, 0x36, 0x35, +0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x01, 0x98, 0x1b, 0x2d, +0x38, 0x1e, 0x1e, 0x38, 0x2d, 0x1b, 0x1b, 0x2d, 0x38, 0x1e, +0x1e, 0x39, 0x2c, 0x1b, 0xfe, 0x8a, 0x26, 0x3d, 0x4e, 0x28, +0x28, 0x4e, 0x3c, 0x25, 0x26, 0x3d, 0x4e, 0x28, 0x29, 0x4d, +0x3c, 0x25, 0xba, 0x36, 0x0e, 0x22, 0x13, 0x39, 0x37, 0x28, +0x0c, 0x1a, 0x0d, 0x39, 0x0d, 0x14, 0x0a, 0x24, 0x12, 0x1b, +0x1a, 0x20, 0x11, 0x06, 0x0b, 0x05, 0xe7, 0x30, 0x47, 0x2f, +0x18, 0x18, 0x2f, 0x47, 0x2e, 0x30, 0x47, 0x2f, 0x18, 0x18, +0x2f, 0x46, 0x2f, 0x3d, 0x5c, 0x3d, 0x1e, 0x1e, 0x3d, 0x5b, +0x3c, 0x3d, 0x5b, 0x3d, 0x1f, 0x1f, 0x3c, 0x5b, 0x10, 0x4d, +0xee, 0x04, 0x05, 0x2c, 0x2a, 0x30, 0x17, 0x11, 0x2f, 0x1a, +0x18, 0x25, 0x10, 0x32, 0x0e, 0x17, 0x14, 0x0d, 0x01, 0x01, +0x00, 0x00, 0x00, 0x01, 0x00, 0x7b, 0x02, 0x3b, 0x01, 0x79, +0x02, 0x7b, 0x00, 0x03, 0x00, 0x0d, 0xb3, 0x02, 0x03, 0x00, +0x03, 0x00, 0x2f, 0xcd, 0x01, 0x2f, 0xcd, 0x31, 0x30, 0x13, +0x33, 0x15, 0x23, 0x7b, 0xfe, 0xfe, 0x02, 0x7b, 0x40, 0x00, +0x00, 0x00, 0x00, 0x02, 0x00, 0x7d, 0x01, 0xbd, 0x01, 0x77, +0x02, 0xb5, 0x00, 0x13, 0x00, 0x1f, 0x00, 0x39, 0xb9, 0x00, +0x12, 0xff, 0xe0, 0x40, 0x11, 0x08, 0x0b, 0x00, 0x4c, 0x0c, +0x20, 0x08, 0x0b, 0x00, 0x4c, 0x08, 0x20, 0x08, 0x0b, 0x00, +0x4c, 0x02, 0xb8, 0xff, 0xe0, 0x40, 0x0c, 0x08, 0x0b, 0x00, +0x4c, 0x00, 0x14, 0x0a, 0x1a, 0x0f, 0x17, 0x1d, 0x05, 0x00, +0x2f, 0xdd, 0xde, 0xcd, 0x01, 0x2f, 0xcd, 0xde, 0xcd, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, +0x02, 0x07, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, +0x33, 0x32, 0x36, 0x01, 0x77, 0x14, 0x23, 0x2d, 0x19, 0x19, +0x2d, 0x23, 0x14, 0x14, 0x23, 0x2d, 0x19, 0x19, 0x2d, 0x23, +0x14, 0x3c, 0x26, 0x1b, 0x1b, 0x26, 0x26, 0x1b, 0x1b, 0x26, +0x02, 0x39, 0x1d, 0x2e, 0x20, 0x11, 0x11, 0x20, 0x2e, 0x1d, +0x1d, 0x2e, 0x20, 0x11, 0x11, 0x20, 0x2e, 0x1d, 0x20, 0x24, +0x24, 0x20, 0x20, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x02, +0x00, 0x2e, 0x00, 0x00, 0x01, 0xc7, 0x02, 0x2a, 0x00, 0x0b, +0x00, 0x0f, 0x00, 0x33, 0x40, 0x17, 0x0c, 0x0c, 0x0b, 0x0a, +0x0d, 0x0d, 0x06, 0x04, 0x07, 0x01, 0x0a, 0x0a, 0x10, 0x11, +0x0c, 0x0f, 0x5b, 0x04, 0x02, 0x01, 0x09, 0x07, 0x0a, 0x00, +0x2f, 0x33, 0xcd, 0xdd, 0xcd, 0x33, 0x3f, 0xcd, 0x01, 0x11, +0x12, 0x39, 0x2f, 0x33, 0xdd, 0x32, 0xcd, 0x32, 0x2f, 0x10, +0xcd, 0x32, 0x2f, 0x31, 0x30, 0x13, 0x33, 0x35, 0x33, 0x15, +0x33, 0x15, 0x23, 0x15, 0x23, 0x35, 0x23, 0x15, 0x21, 0x15, +0x21, 0x2e, 0xa8, 0x48, 0xa9, 0xa9, 0x48, 0xa8, 0x01, 0x99, +0xfe, 0x67, 0x01, 0x76, 0xb4, 0xb4, 0x46, 0xb4, 0xb4, 0xe9, +0x47, 0x00, 0x00, 0x01, 0x00, 0x7c, 0x01, 0x19, 0x01, 0x78, +0x02, 0x79, 0x00, 0x20, 0x00, 0xe1, 0xb9, 0x00, 0x20, 0xff, +0xe8, 0xb3, 0x14, 0x00, 0x4d, 0x20, 0xb8, 0xff, 0xf0, 0xb3, +0x13, 0x00, 0x4d, 0x20, 0xb8, 0xff, 0xe8, 0xb3, 0x12, 0x00, +0x4d, 0x20, 0xb8, 0xff, 0xe0, 0xb3, 0x11, 0x00, 0x4d, 0x20, +0xb8, 0xff, 0xd8, 0xb3, 0x10, 0x00, 0x4d, 0x20, 0xb8, 0xff, +0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x20, 0xb8, 0xff, 0xd8, 0xb4, +0x0c, 0x0e, 0x00, 0x4c, 0x20, 0xb8, 0xff, 0xd0, 0x40, 0x27, +0x0b, 0x00, 0x4d, 0x1c, 0x10, 0x0f, 0x00, 0x4d, 0x10, 0x10, +0x12, 0x00, 0x4d, 0x0f, 0x18, 0x13, 0x00, 0x4d, 0x0f, 0x10, +0x11, 0x00, 0x4d, 0x0e, 0x20, 0x13, 0x00, 0x4d, 0x0e, 0x18, +0x12, 0x00, 0x4d, 0x0d, 0x10, 0x11, 0x00, 0x4d, 0x12, 0xb8, +0xff, 0xe0, 0xb3, 0x1a, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xe0, +0xb3, 0x1b, 0x00, 0x4d, 0x10, 0xb8, 0xff, 0xf0, 0xb3, 0x1a, +0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xe0, 0xb3, 0x1b, 0x00, 0x4d, +0x0e, 0xb8, 0xff, 0xe8, 0x40, 0x28, 0x1a, 0x00, 0x4d, 0x04, +0x20, 0x19, 0x00, 0x4d, 0x03, 0x20, 0x19, 0x00, 0x4d, 0x02, +0x18, 0x19, 0x00, 0x4d, 0x13, 0x96, 0x00, 0x09, 0x09, 0x00, +0x0b, 0x1b, 0x1b, 0x08, 0x96, 0x0b, 0x1a, 0x1a, 0x15, 0x98, +0x1e, 0x5a, 0x08, 0x98, 0x0b, 0x5f, 0x00, 0x3f, 0xed, 0x3f, +0xed, 0x32, 0x2f, 0x01, 0x2f, 0xed, 0x33, 0x2f, 0x10, 0xcd, +0x32, 0x2f, 0x10, 0xed, 0x31, 0x30, 0x00, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x01, 0x14, 0x0e, 0x02, 0x07, 0x06, 0x06, 0x07, 0x33, +0x15, 0x23, 0x26, 0x3e, 0x02, 0x37, 0x36, 0x36, 0x35, 0x34, +0x23, 0x22, 0x0e, 0x02, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, +0x16, 0x01, 0x6a, 0x11, 0x1d, 0x26, 0x15, 0x0f, 0x1e, 0x02, +0xa6, 0xee, 0x03, 0x0e, 0x1a, 0x23, 0x12, 0x1e, 0x26, 0x37, +0x0f, 0x1b, 0x16, 0x10, 0x05, 0x20, 0x10, 0x3d, 0x28, 0x3e, +0x3b, 0x02, 0x16, 0x13, 0x23, 0x23, 0x24, 0x12, 0x0d, 0x1d, +0x0b, 0x39, 0x1e, 0x2d, 0x26, 0x1f, 0x10, 0x1a, 0x2c, 0x15, +0x2d, 0x08, 0x0b, 0x0c, 0x04, 0x2c, 0x10, 0x1f, 0x33, 0x00, +0x00, 0x01, 0x00, 0x7e, 0x01, 0x12, 0x01, 0x76, 0x02, 0x79, +0x00, 0x2b, 0x00, 0xf8, 0xb5, 0x24, 0x20, 0x1b, 0x00, 0x4d, +0x23, 0xb8, 0xff, 0xe8, 0xb4, 0x0b, 0x10, 0x00, 0x4c, 0x1e, +0xb8, 0xff, 0xe8, 0xb3, 0x1b, 0x00, 0x4d, 0x1c, 0xb8, 0xff, +0xe8, 0xb4, 0x11, 0x14, 0x00, 0x4c, 0x1c, 0xb8, 0xff, 0xe0, +0x40, 0x28, 0x0e, 0x10, 0x00, 0x4c, 0x1b, 0x08, 0x24, 0x00, +0x4d, 0x18, 0x18, 0x17, 0x00, 0x4d, 0x18, 0x10, 0x16, 0x00, +0x4d, 0x0e, 0x08, 0x1a, 0x00, 0x4d, 0x05, 0x18, 0x1b, 0x00, +0x4d, 0x05, 0x10, 0x1a, 0x00, 0x4d, 0x28, 0x18, 0x1b, 0x00, +0x4d, 0x18, 0xb8, 0xff, 0xf8, 0xb3, 0x18, 0x00, 0x4d, 0x17, +0xb8, 0xff, 0xd8, 0x40, 0x3c, 0x1b, 0x00, 0x4d, 0x15, 0x18, +0x1b, 0x00, 0x4d, 0x15, 0x18, 0x17, 0x18, 0x00, 0x4c, 0x05, +0x18, 0x19, 0x00, 0x4d, 0x05, 0x10, 0x18, 0x00, 0x4d, 0x05, +0x18, 0x17, 0x00, 0x4d, 0x1f, 0x10, 0x96, 0x1d, 0x40, 0x22, +0x2d, 0x48, 0x1d, 0x40, 0x1a, 0x20, 0x48, 0x1d, 0x03, 0x96, +0x22, 0x2d, 0x17, 0x17, 0x28, 0x09, 0x09, 0x28, 0x1f, 0x09, +0x98, 0x0a, 0x0a, 0x1a, 0x29, 0xb8, 0xff, 0xc0, 0x40, 0x23, +0x1c, 0x00, 0x4d, 0x29, 0x40, 0x1b, 0x00, 0x4d, 0x29, 0x38, +0x1a, 0x00, 0x4d, 0x29, 0x40, 0x19, 0x00, 0x4d, 0x29, 0x29, +0x00, 0x98, 0x25, 0x62, 0x16, 0x40, 0x1c, 0x00, 0x4d, 0x16, +0x16, 0x13, 0x98, 0x1a, 0x5a, 0x00, 0x3f, 0xed, 0x32, 0x2f, +0x2b, 0x3f, 0xed, 0x32, 0x2f, 0x2b, 0x2b, 0x2b, 0x2b, 0x11, +0x39, 0x2f, 0xed, 0x39, 0x01, 0x2f, 0x33, 0x2f, 0x11, 0x33, +0x2f, 0x10, 0xde, 0xed, 0xd4, 0x2b, 0x2b, 0xed, 0x32, 0x31, +0x30, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x13, 0x32, 0x36, 0x35, 0x34, 0x2e, 0x02, 0x23, +0x23, 0x35, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x26, 0x23, +0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, 0x16, 0x15, +0x14, 0x07, 0x16, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, +0x27, 0x37, 0x16, 0x16, 0xe2, 0x30, 0x23, 0x10, 0x1b, 0x24, +0x13, 0x11, 0x16, 0x0d, 0x1b, 0x16, 0x0f, 0x21, 0x1a, 0x18, +0x29, 0x0f, 0x17, 0x0e, 0x3d, 0x1e, 0x41, 0x36, 0x31, 0x20, +0x24, 0x44, 0x4f, 0x1c, 0x39, 0x10, 0x0d, 0x14, 0x2c, 0x01, +0x4a, 0x1d, 0x17, 0x0f, 0x15, 0x0e, 0x06, 0x33, 0x05, 0x0b, +0x12, 0x0e, 0x16, 0x13, 0x11, 0x07, 0x31, 0x0a, 0x14, 0x34, +0x2a, 0x2b, 0x1c, 0x0a, 0x2d, 0x20, 0x2d, 0x3e, 0x0d, 0x08, +0x35, 0x08, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xaa, +0x02, 0x06, 0x01, 0x52, 0x02, 0xb5, 0x00, 0x03, 0x00, 0x18, +0x40, 0x09, 0x03, 0x00, 0x01, 0x02, 0x00, 0x03, 0x80, 0x02, +0x01, 0x00, 0x2f, 0x33, 0x1a, 0xcd, 0x32, 0x01, 0x2f, 0x33, +0xcd, 0x32, 0x31, 0x30, 0x01, 0x07, 0x27, 0x37, 0x01, 0x52, +0x7e, 0x2a, 0x72, 0x02, 0x80, 0x7a, 0x25, 0x8a, 0x00, 0x01, +0x00, 0x47, 0xff, 0x5b, 0x01, 0xad, 0x01, 0xd0, 0x00, 0x1a, +0x00, 0x3e, 0xb9, 0x00, 0x11, 0xff, 0xe0, 0xb4, 0x11, 0x12, +0x00, 0x4c, 0x11, 0xb8, 0xff, 0xf0, 0x40, 0x1a, 0x0f, 0x10, +0x00, 0x4c, 0x17, 0x7f, 0x00, 0x1c, 0x09, 0x0d, 0x7f, 0x00, +0x0c, 0x01, 0x08, 0x0c, 0x1b, 0x19, 0x0c, 0x49, 0x0b, 0x4b, +0x13, 0x88, 0x03, 0x51, 0x00, 0x3f, 0xed, 0x3f, 0x3f, 0x33, +0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, +0x31, 0x30, 0x2b, 0x2b, 0x25, 0x06, 0x06, 0x23, 0x22, 0x26, +0x27, 0x16, 0x16, 0x15, 0x15, 0x23, 0x11, 0x33, 0x15, 0x14, +0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x37, 0x11, 0x33, 0x01, +0xad, 0x1b, 0x59, 0x3c, 0x29, 0x2d, 0x11, 0x03, 0x01, 0x53, +0x53, 0x0b, 0x19, 0x29, 0x1e, 0x0d, 0x1b, 0x18, 0x12, 0x03, +0x53, 0x0d, 0x07, 0x11, 0x12, 0x0f, 0x17, 0x2e, 0x1a, 0x5c, +0x02, 0x75, 0xf3, 0x2b, 0x3c, 0x26, 0x11, 0x02, 0x02, 0x03, +0x01, 0x01, 0x89, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, +0xff, 0x5b, 0x01, 0xbf, 0x02, 0x71, 0x00, 0x12, 0x00, 0x26, +0x40, 0x11, 0x05, 0x0f, 0x02, 0x01, 0x08, 0x02, 0x00, 0x10, +0x14, 0x08, 0x13, 0x05, 0x05, 0x02, 0x0d, 0x12, 0x04, 0x00, +0x2f, 0x33, 0x2f, 0xcd, 0x33, 0x2f, 0x01, 0x10, 0xc6, 0x10, +0xde, 0xdd, 0xde, 0x5e, 0x5d, 0xcd, 0x31, 0x30, 0x01, 0x26, +0x07, 0x11, 0x23, 0x11, 0x26, 0x26, 0x35, 0x34, 0x3e, 0x02, +0x33, 0x32, 0x16, 0x17, 0x11, 0x23, 0x01, 0x79, 0x2e, 0x29, +0x45, 0x5d, 0x64, 0x25, 0x46, 0x63, 0x3e, 0x23, 0x50, 0x24, +0x46, 0x02, 0x29, 0x06, 0x04, 0xfd, 0x30, 0x01, 0x8f, 0x0a, +0x5c, 0x5c, 0x31, 0x49, 0x32, 0x19, 0x06, 0x0a, 0xfc, 0xfa, +0xff, 0xff, 0x00, 0xb1, 0x00, 0xb8, 0x01, 0x44, 0x01, 0x51, +0x02, 0x07, 0x00, 0x11, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, +0x00, 0x01, 0x00, 0x9c, 0xff, 0x57, 0x01, 0x41, 0x00, 0x12, +0x00, 0x1c, 0x00, 0x34, 0x40, 0x18, 0x11, 0x03, 0x1a, 0x00, +0x19, 0x0b, 0x14, 0x14, 0x1e, 0x00, 0x00, 0x14, 0x14, 0x1d, +0x08, 0x19, 0x19, 0x1d, 0x0f, 0x00, 0x08, 0x01, 0x08, 0x08, +0x00, 0x2f, 0x5e, 0x5d, 0xcd, 0x11, 0x33, 0x2f, 0x11, 0x12, +0x39, 0x2f, 0x33, 0x2f, 0x01, 0x11, 0x39, 0x2f, 0xcc, 0x33, +0xdd, 0x32, 0xdd, 0xcd, 0x31, 0x30, 0x05, 0x16, 0x16, 0x15, +0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, +0x33, 0x32, 0x35, 0x34, 0x27, 0x27, 0x3e, 0x03, 0x37, 0x33, +0x06, 0x06, 0x01, 0x10, 0x1a, 0x17, 0x09, 0x15, 0x23, 0x1a, +0x17, 0x28, 0x0b, 0x0a, 0x0b, 0x18, 0x0f, 0x20, 0x25, 0x07, +0x03, 0x0b, 0x0b, 0x0a, 0x02, 0x39, 0x05, 0x10, 0x21, 0x0c, +0x1e, 0x1d, 0x0a, 0x17, 0x13, 0x0d, 0x07, 0x05, 0x33, 0x04, +0x05, 0x14, 0x14, 0x0b, 0x02, 0x09, 0x18, 0x18, 0x13, 0x04, +0x0b, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7e, 0x01, 0x19, +0x01, 0x7f, 0x02, 0x72, 0x00, 0x0e, 0x00, 0x2e, 0x40, 0x17, +0x05, 0x05, 0x2f, 0x0e, 0x01, 0x0e, 0x00, 0x0b, 0x0a, 0x96, +0x08, 0x00, 0x0a, 0x00, 0x98, 0x0d, 0x5f, 0x05, 0x04, 0x04, +0x01, 0x08, 0x59, 0x00, 0x3f, 0x33, 0x33, 0x2f, 0xcd, 0x3f, +0xed, 0x32, 0x01, 0x2f, 0x32, 0xfd, 0xcd, 0x10, 0xcd, 0x71, +0x32, 0x2f, 0x31, 0x30, 0x13, 0x35, 0x06, 0x06, 0x07, 0x27, +0x36, 0x36, 0x37, 0x33, 0x11, 0x33, 0x15, 0x23, 0x35, 0xe7, +0x14, 0x32, 0x12, 0x11, 0x22, 0x42, 0x18, 0x2c, 0x59, 0xfa, +0x01, 0x52, 0xce, 0x0d, 0x14, 0x05, 0x31, 0x0b, 0x25, 0x17, +0xfe, 0xe0, 0x39, 0x39, 0x00, 0x02, 0x00, 0x59, 0x01, 0x25, +0x01, 0x9b, 0x02, 0x78, 0x00, 0x13, 0x00, 0x1f, 0x00, 0x3b, +0xb9, 0x00, 0x12, 0xff, 0xe8, 0x40, 0x11, 0x08, 0x0b, 0x00, +0x4c, 0x0c, 0x18, 0x08, 0x0b, 0x00, 0x4c, 0x08, 0x18, 0x08, +0x0b, 0x00, 0x4c, 0x02, 0xb8, 0xff, 0xe0, 0x40, 0x0e, 0x08, +0x0b, 0x00, 0x4c, 0x14, 0x00, 0x1a, 0x0a, 0x17, 0x0f, 0x5a, +0x1d, 0x05, 0x5e, 0x00, 0x3f, 0xcd, 0x3f, 0xcd, 0x01, 0x2f, +0xcd, 0xdc, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, +0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, +0x02, 0x33, 0x32, 0x1e, 0x02, 0x07, 0x34, 0x26, 0x23, 0x22, +0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x01, 0x9b, 0x18, +0x2b, 0x3b, 0x23, 0x23, 0x3b, 0x2b, 0x18, 0x18, 0x2b, 0x3b, +0x23, 0x23, 0x3b, 0x2b, 0x18, 0x42, 0x31, 0x2e, 0x2d, 0x32, +0x31, 0x2e, 0x2e, 0x31, 0x01, 0xcf, 0x27, 0x3e, 0x2d, 0x18, +0x18, 0x2d, 0x3e, 0x27, 0x27, 0x3e, 0x2c, 0x18, 0x18, 0x2c, +0x3e, 0x27, 0x33, 0x3a, 0x3a, 0x33, 0x32, 0x3c, 0x3c, 0x00, +0x00, 0x02, 0x00, 0x55, 0x00, 0x4f, 0x01, 0xb5, 0x01, 0xae, +0x00, 0x05, 0x00, 0x0b, 0x00, 0x36, 0x40, 0x17, 0x0b, 0x07, +0x08, 0x05, 0x01, 0x40, 0x04, 0x02, 0x03, 0x00, 0x09, 0x06, +0x80, 0x0a, 0x08, 0x05, 0x0b, 0x01, 0x07, 0x06, 0x03, 0x00, +0x09, 0x00, 0x19, 0x2f, 0x33, 0x33, 0x33, 0xcd, 0x32, 0xcd, +0x32, 0x01, 0x18, 0x2f, 0x33, 0x1a, 0xdd, 0x32, 0xdc, 0x32, +0xdd, 0x32, 0x1a, 0xcd, 0x32, 0x10, 0xcd, 0x32, 0x31, 0x30, +0x25, 0x07, 0x27, 0x37, 0x27, 0x37, 0x07, 0x07, 0x27, 0x37, +0x27, 0x37, 0x01, 0xb5, 0x78, 0x34, 0x54, 0x50, 0x32, 0x3f, +0x77, 0x34, 0x54, 0x51, 0x32, 0xff, 0xb0, 0x1b, 0x95, 0x90, +0x1f, 0xaf, 0xb0, 0x1b, 0x95, 0x90, 0x1f, 0x00, 0x00, 0x04, +0x00, 0x12, 0xff, 0xfc, 0x01, 0xdd, 0x02, 0x72, 0x00, 0x0a, +0x00, 0x17, 0x00, 0x1c, 0x00, 0x20, 0x00, 0x63, 0x40, 0x34, +0x1d, 0x1f, 0x1e, 0x1f, 0x9c, 0x20, 0x1d, 0x14, 0x20, 0x1d, +0x20, 0x1e, 0x17, 0x18, 0x18, 0x0c, 0x0f, 0x12, 0x12, 0x1b, +0x14, 0x0e, 0x05, 0x03, 0x06, 0x00, 0x1f, 0x20, 0x59, 0x1d, +0x1e, 0x67, 0x0f, 0x13, 0x14, 0x0c, 0x1b, 0x1b, 0x11, 0x18, +0x17, 0x65, 0x11, 0x67, 0x06, 0x61, 0x00, 0x0a, 0x0a, 0x07, +0x03, 0x60, 0x00, 0x3f, 0x33, 0x33, 0x2f, 0xcd, 0x3f, 0x3f, +0x3f, 0x33, 0x12, 0x39, 0x2f, 0x33, 0x33, 0xcd, 0x32, 0x3f, +0x33, 0x3f, 0x33, 0x01, 0x2f, 0xdc, 0x32, 0xcd, 0x2f, 0xcd, +0x32, 0x39, 0x2f, 0xcd, 0x32, 0x33, 0x11, 0x33, 0x2f, 0x2f, +0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x13, 0x36, 0x36, +0x37, 0x33, 0x15, 0x23, 0x35, 0x06, 0x06, 0x07, 0x01, 0x15, +0x33, 0x15, 0x23, 0x15, 0x23, 0x35, 0x23, 0x35, 0x36, 0x36, +0x37, 0x17, 0x06, 0x06, 0x07, 0x33, 0x05, 0x23, 0x01, 0x33, +0x12, 0x22, 0x30, 0x18, 0x28, 0x3b, 0x14, 0x20, 0x12, 0x01, +0x96, 0x24, 0x24, 0x3b, 0x81, 0x1a, 0x30, 0x1f, 0x18, 0x15, +0x22, 0x0f, 0x46, 0xfe, 0xe1, 0x46, 0x01, 0x7b, 0x46, 0x02, +0x31, 0x0e, 0x1c, 0x17, 0xfa, 0xa8, 0x0b, 0x0e, 0x06, 0xfe, +0xf9, 0x98, 0x32, 0x30, 0x30, 0x29, 0x2e, 0x4b, 0x28, 0x2b, +0x1b, 0x38, 0x1a, 0x66, 0x02, 0x6b, 0x00, 0x03, 0x00, 0x11, +0x00, 0x00, 0x01, 0xe2, 0x02, 0x72, 0x00, 0x1e, 0x00, 0x29, +0x00, 0x2d, 0x00, 0xb8, 0xb9, 0x00, 0x1e, 0xff, 0xf0, 0xb3, +0x16, 0x00, 0x4d, 0x1c, 0xb8, 0xff, 0xe0, 0xb3, 0x15, 0x00, +0x4d, 0x1b, 0xb8, 0xff, 0xd8, 0xb3, 0x15, 0x00, 0x4d, 0x1b, +0xb8, 0xff, 0xd8, 0xb3, 0x13, 0x00, 0x4d, 0x18, 0xb8, 0xff, +0xe8, 0xb3, 0x15, 0x00, 0x4d, 0x18, 0xb8, 0xff, 0xe0, 0xb3, +0x14, 0x00, 0x4d, 0x18, 0xb8, 0xff, 0xe8, 0xb3, 0x13, 0x00, +0x4d, 0x18, 0xb8, 0xff, 0xe0, 0x40, 0x44, 0x0e, 0x12, 0x00, +0x4c, 0x14, 0x30, 0x14, 0x00, 0x4d, 0x08, 0x10, 0x16, 0x17, +0x00, 0x4c, 0x07, 0x10, 0x14, 0x00, 0x4d, 0x2a, 0x2c, 0x2b, +0x2c, 0x9c, 0x2d, 0x2a, 0x14, 0x2d, 0x2a, 0x2d, 0x2b, 0x24, +0x22, 0x25, 0x1f, 0x0c, 0x04, 0x19, 0x00, 0x00, 0x19, 0x1e, +0x05, 0x13, 0x13, 0x05, 0x2c, 0x2d, 0x59, 0x2a, 0x2b, 0x67, +0x25, 0x61, 0x1f, 0x29, 0x29, 0x26, 0x22, 0x60, 0x12, 0x0f, +0x16, 0x66, 0x1e, 0x03, 0x5b, 0x00, 0x3f, 0xcd, 0x3f, 0xcd, +0x32, 0x3f, 0x33, 0x33, 0x2f, 0xcd, 0x3f, 0x3f, 0x33, 0x3f, +0x33, 0x01, 0x2f, 0x33, 0x2f, 0x10, 0xcd, 0x2f, 0x33, 0x2f, +0x10, 0xcd, 0xcd, 0x2f, 0xdc, 0x32, 0xcd, 0x2f, 0x2f, 0x87, +0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x15, +0x23, 0x26, 0x34, 0x35, 0x34, 0x36, 0x37, 0x37, 0x36, 0x36, +0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, +0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x01, 0x36, +0x36, 0x37, 0x33, 0x15, 0x23, 0x35, 0x06, 0x06, 0x07, 0x13, +0x23, 0x01, 0x33, 0x01, 0xe2, 0xc5, 0x01, 0x28, 0x1a, 0x16, +0x18, 0x12, 0x17, 0x10, 0x0f, 0x20, 0x0c, 0x20, 0x11, 0x34, +0x1a, 0x2f, 0x2f, 0x1a, 0x26, 0x28, 0x0d, 0xfe, 0xb4, 0x23, +0x2f, 0x18, 0x29, 0x3b, 0x14, 0x21, 0x12, 0x2e, 0x46, 0x01, +0x7b, 0x46, 0x32, 0x32, 0x03, 0x11, 0x03, 0x20, 0x23, 0x10, +0x0f, 0x0e, 0x19, 0x0e, 0x11, 0x10, 0x0d, 0x0d, 0x28, 0x13, +0x13, 0x32, 0x20, 0x1a, 0x25, 0x1c, 0x18, 0x0c, 0x01, 0xff, +0x0e, 0x1c, 0x17, 0xfa, 0xa8, 0x0b, 0x0e, 0x06, 0xfd, 0xff, +0x02, 0x6b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, +0x01, 0xdf, 0x02, 0x79, 0x00, 0x0c, 0x00, 0x37, 0x00, 0x3c, +0x00, 0x40, 0x01, 0x07, 0xb9, 0x00, 0x32, 0xff, 0xe0, 0xb4, +0x14, 0x15, 0x00, 0x4c, 0x32, 0xb8, 0xff, 0xe8, 0xb3, 0x13, +0x00, 0x4d, 0x32, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, +0x32, 0xb8, 0xff, 0xe8, 0xb4, 0x10, 0x11, 0x00, 0x4c, 0x32, +0xb8, 0xff, 0xd8, 0xb3, 0x0f, 0x00, 0x4d, 0x32, 0xb8, 0xff, +0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x2e, 0xb8, 0xff, 0xe8, 0xb4, +0x0e, 0x10, 0x00, 0x4c, 0x2d, 0xb8, 0xff, 0xd8, 0xb3, 0x0e, +0x00, 0x4d, 0x2b, 0xb8, 0xff, 0xf8, 0xb3, 0x0f, 0x00, 0x4d, +0x29, 0xb8, 0xff, 0xe0, 0xb3, 0x18, 0x00, 0x4d, 0x29, 0xb8, +0xff, 0xe8, 0xb3, 0x17, 0x00, 0x4d, 0x29, 0xb8, 0xff, 0xd8, +0xb3, 0x16, 0x00, 0x4d, 0x29, 0xb8, 0xff, 0xe0, 0xb4, 0x13, +0x15, 0x00, 0x4c, 0x29, 0xb8, 0xff, 0xe8, 0x40, 0x48, 0x11, +0x12, 0x00, 0x4c, 0x3d, 0x3f, 0x3e, 0x3f, 0x9c, 0x40, 0x3d, +0x14, 0x40, 0x3d, 0x40, 0x3e, 0x2e, 0x1c, 0x2b, 0x2b, 0x13, +0x30, 0x37, 0x23, 0x23, 0x37, 0x17, 0x17, 0x37, 0x0c, 0x38, +0x38, 0x01, 0x04, 0x07, 0x07, 0x3b, 0x09, 0x03, 0x3f, 0x40, +0x59, 0x3d, 0x3e, 0x67, 0x2e, 0x17, 0x18, 0x18, 0x26, 0x0d, +0x0d, 0x10, 0x35, 0x64, 0x22, 0x22, 0x1f, 0x26, 0x63, 0x04, +0x08, 0x09, 0x01, 0x3b, 0x3b, 0x06, 0x38, 0x0c, 0x65, 0x06, +0x67, 0x00, 0x3f, 0x3f, 0x33, 0x12, 0x39, 0x2f, 0x33, 0x33, +0xcd, 0x32, 0x3f, 0xcd, 0x32, 0x2f, 0x3f, 0xcd, 0x32, 0x2f, +0x11, 0x39, 0x2f, 0xcd, 0x39, 0x3f, 0x33, 0x3f, 0x33, 0x01, +0x2f, 0xcd, 0x32, 0x39, 0x2f, 0xcd, 0x32, 0x33, 0x11, 0x33, +0x2f, 0x33, 0x2f, 0x11, 0x33, 0x2f, 0x10, 0xdd, 0xcd, 0x33, +0x2f, 0xcd, 0x32, 0x2f, 0x2f, 0x87, 0x2b, 0x87, 0x7d, 0xc4, +0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x15, 0x33, +0x15, 0x23, 0x15, 0x23, 0x35, 0x23, 0x35, 0x36, 0x36, 0x37, +0x25, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, +0x23, 0x35, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, +0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, +0x14, 0x06, 0x07, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, +0x27, 0x05, 0x06, 0x06, 0x07, 0x33, 0x05, 0x23, 0x01, 0x33, +0x01, 0xb9, 0x24, 0x24, 0x3b, 0x81, 0x1a, 0x30, 0x1f, 0xfe, +0xbe, 0x0b, 0x21, 0x14, 0x16, 0x21, 0x26, 0x26, 0x0c, 0x16, +0x1a, 0x1c, 0x19, 0x0e, 0x0e, 0x24, 0x0c, 0x13, 0x0f, 0x31, +0x1a, 0x11, 0x20, 0x19, 0x0f, 0x0f, 0x10, 0x2b, 0x0c, 0x1a, +0x2a, 0x1e, 0x2e, 0x25, 0x01, 0x69, 0x15, 0x22, 0x0f, 0x46, +0xfe, 0xe6, 0x46, 0x01, 0x7b, 0x46, 0xfa, 0x98, 0x32, 0x30, +0x30, 0x29, 0x2e, 0x4b, 0x28, 0xb4, 0x05, 0x08, 0x0d, 0x11, +0x15, 0x0c, 0x32, 0x0b, 0x12, 0x0f, 0x09, 0x0a, 0x05, 0x2b, +0x09, 0x0d, 0x07, 0x0f, 0x19, 0x12, 0x0f, 0x1e, 0x0b, 0x14, +0x2d, 0x0e, 0x1d, 0x17, 0x0e, 0x0e, 0xae, 0x1b, 0x38, 0x1a, +0x62, 0x02, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x5c, +0xff, 0x56, 0x01, 0x9a, 0x01, 0xd1, 0x00, 0x1d, 0x00, 0x29, +0x00, 0x84, 0x40, 0x10, 0x1b, 0x18, 0x12, 0x00, 0x4d, 0x14, +0x20, 0x0a, 0x00, 0x4d, 0x14, 0x28, 0x09, 0x00, 0x4d, 0x05, +0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x05, 0xb8, 0xff, +0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe0, 0xb3, +0x0d, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb3, 0x0c, 0x00, +0x4d, 0x03, 0xb8, 0xff, 0xe8, 0x40, 0x0a, 0x0c, 0x0d, 0x00, +0x4c, 0x0f, 0x18, 0x12, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xe8, +0x40, 0x1b, 0x11, 0x00, 0x4d, 0x08, 0x95, 0x16, 0x16, 0x1d, +0x91, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x21, 0x94, 0x27, 0x27, +0x2b, 0x2a, 0x1d, 0x24, 0x9a, 0x1e, 0x0b, 0x9b, 0x11, 0x00, +0x2f, 0xed, 0x2f, 0xfd, 0xce, 0x01, 0x11, 0x12, 0x39, 0x2f, +0xed, 0x32, 0x2f, 0x33, 0x2f, 0x10, 0xed, 0x32, 0x2f, 0xed, +0x2b, 0x31, 0x30, 0x00, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x17, 0x14, 0x0e, 0x04, 0x15, +0x14, 0x16, 0x33, 0x32, 0x37, 0x17, 0x06, 0x06, 0x23, 0x22, +0x2e, 0x02, 0x35, 0x34, 0x3e, 0x04, 0x35, 0x37, 0x32, 0x16, +0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x01, +0x3d, 0x01, 0x15, 0x1f, 0x25, 0x1f, 0x15, 0x30, 0x2e, 0x3b, +0x39, 0x17, 0x1e, 0x4c, 0x2b, 0x33, 0x41, 0x26, 0x0f, 0x17, +0x22, 0x28, 0x22, 0x17, 0x1c, 0x1c, 0x27, 0x27, 0x1c, 0x1b, +0x28, 0x28, 0xf3, 0x14, 0x1d, 0x2c, 0x26, 0x21, 0x22, 0x26, +0x17, 0x26, 0x2e, 0x1e, 0x40, 0x10, 0x14, 0x1c, 0x2b, 0x34, +0x18, 0x1e, 0x2e, 0x27, 0x24, 0x28, 0x2d, 0x1e, 0xde, 0x25, +0x1f, 0x1f, 0x24, 0x24, 0x1f, 0x1f, 0x25, 0x00, 0xff, 0xff, +0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x03, 0x3e, 0x02, 0x26, +0x00, 0x24, 0x00, 0x00, 0x01, 0x07, 0x00, 0x43, 0x00, 0x04, +0x00, 0x89, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x1a, 0x18, +0x04, 0x0f, 0x50, 0x02, 0x09, 0x19, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, +0x03, 0x3e, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x01, 0x07, +0x00, 0x8f, 0xff, 0xfd, 0x00, 0x89, 0x00, 0x10, 0x40, 0x0b, +0x02, 0x01, 0x19, 0x17, 0x04, 0x0f, 0x50, 0x02, 0x09, 0x18, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x09, +0x00, 0x00, 0x01, 0xeb, 0x03, 0x3a, 0x02, 0x26, 0x00, 0x24, +0x00, 0x00, 0x01, 0x07, 0x00, 0x69, 0x00, 0x00, 0x00, 0x8b, +0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x1a, 0x1a, 0x09, 0x0a, +0x50, 0x02, 0x09, 0x19, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x03, 0x1c, +0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x01, 0x07, 0x00, 0x75, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, +0x25, 0x17, 0x04, 0x0f, 0x50, 0x02, 0x09, 0x24, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x00, +0x01, 0xeb, 0x03, 0x1a, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, +0x01, 0x07, 0x00, 0x83, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x2c, +0x40, 0x22, 0x10, 0x20, 0x10, 0x26, 0x02, 0x30, 0x26, 0x01, +0x30, 0x20, 0x40, 0x20, 0x50, 0x20, 0x90, 0x20, 0xc0, 0x20, +0xd0, 0x20, 0xe0, 0x20, 0xf0, 0x20, 0x08, 0x20, 0x03, 0x09, +0x23, 0x4f, 0x02, 0x09, 0x17, 0x4f, 0x2b, 0x2b, 0x01, 0x10, +0x5d, 0x5d, 0x71, 0x31, 0x00, 0x00, 0x00, 0x03, 0x00, 0x09, +0x00, 0x00, 0x01, 0xeb, 0x02, 0xed, 0x00, 0x1a, 0x00, 0x21, +0x00, 0x2d, 0x00, 0x9f, 0xb9, 0x00, 0x11, 0xff, 0xd8, 0x40, +0x5d, 0x08, 0x0f, 0x00, 0x4c, 0x0d, 0x28, 0x08, 0x0f, 0x00, +0x4c, 0x12, 0x9d, 0x22, 0x0c, 0x9d, 0x28, 0x28, 0x02, 0x1e, +0x1c, 0x1b, 0x09, 0x03, 0x1b, 0x03, 0x78, 0x04, 0x09, 0x14, +0x04, 0x04, 0x09, 0x01, 0x1f, 0x1b, 0x15, 0x00, 0x1b, 0x00, +0x78, 0x1a, 0x15, 0x14, 0x1a, 0x15, 0x1b, 0x04, 0x8f, 0x1a, +0x9f, 0x1a, 0x02, 0x4f, 0x1a, 0x5f, 0x1a, 0x7f, 0x1a, 0xaf, +0x1a, 0xbf, 0x1a, 0xef, 0x1a, 0xff, 0x1a, 0x07, 0x1a, 0x2f, +0x04, 0x2e, 0x0f, 0xa3, 0x25, 0x2b, 0x01, 0x02, 0x79, 0x1f, +0x1e, 0x1e, 0x04, 0x1b, 0x15, 0x09, 0x2b, 0x41, 0x00, 0x1a, +0x42, 0x03, 0x04, 0x42, 0x00, 0x3f, 0x33, 0x3f, 0x33, 0x3f, +0x33, 0x33, 0x33, 0x12, 0x39, 0x2f, 0x33, 0xed, 0x32, 0x10, +0xde, 0xed, 0x01, 0x10, 0xc6, 0x10, 0xde, 0x5d, 0x71, 0x11, +0x39, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x10, 0xc4, 0xc4, 0x87, +0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x10, 0x0e, 0xc4, 0x05, +0xc4, 0xc4, 0x01, 0x33, 0x18, 0x2f, 0xed, 0xde, 0xed, 0x31, +0x30, 0x2b, 0x2b, 0x21, 0x27, 0x23, 0x07, 0x23, 0x3e, 0x03, +0x37, 0x26, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, +0x14, 0x06, 0x07, 0x1e, 0x03, 0x17, 0x03, 0x06, 0x06, 0x07, +0x33, 0x26, 0x26, 0x37, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, +0x14, 0x16, 0x33, 0x32, 0x36, 0x01, 0x94, 0x25, 0xee, 0x24, +0x54, 0x10, 0x2b, 0x30, 0x33, 0x1a, 0x0e, 0x14, 0x37, 0x25, +0x25, 0x37, 0x13, 0x0e, 0x19, 0x33, 0x2f, 0x29, 0x11, 0xf2, +0x17, 0x36, 0x18, 0xc8, 0x17, 0x35, 0x1a, 0x1b, 0x14, 0x14, +0x1b, 0x1b, 0x14, 0x14, 0x1b, 0xa2, 0xa2, 0x3f, 0x9b, 0x9f, +0x96, 0x3b, 0x0c, 0x25, 0x17, 0x2a, 0x31, 0x31, 0x2a, 0x16, +0x26, 0x0b, 0x3b, 0x97, 0xa0, 0x9b, 0x3e, 0x02, 0x23, 0x3f, +0xa6, 0x58, 0x5a, 0xa7, 0xab, 0x17, 0x1a, 0x1a, 0x17, 0x17, +0x1a, 0x1a, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x00, 0x01, 0xe2, +0x02, 0x6b, 0x00, 0x11, 0x00, 0x16, 0x00, 0x6a, 0x40, 0x38, +0x13, 0x15, 0x02, 0x03, 0x07, 0x03, 0x12, 0x03, 0x78, 0x04, +0x07, 0x14, 0x04, 0x04, 0x07, 0x12, 0x0b, 0x0f, 0x73, 0x00, +0x00, 0x04, 0x0d, 0x0d, 0x09, 0x09, 0x10, 0x18, 0x04, 0x17, +0x0e, 0x79, 0x0b, 0x01, 0x02, 0x79, 0x15, 0x16, 0x15, 0x0b, +0x15, 0x0b, 0x15, 0x0f, 0x12, 0x0a, 0x79, 0x07, 0x41, 0x03, +0x04, 0x42, 0x0f, 0x79, 0x00, 0x42, 0x00, 0x3f, 0xed, 0x3f, +0x33, 0x3f, 0xed, 0x32, 0x12, 0x39, 0x39, 0x2f, 0x2f, 0x11, +0x33, 0x10, 0xed, 0x32, 0x10, 0xed, 0x01, 0x10, 0xc6, 0x10, +0xce, 0x32, 0x2f, 0x32, 0x2f, 0x11, 0x39, 0x2f, 0xed, 0x32, +0x33, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x10, 0xc4, 0xc4, +0x0e, 0xc4, 0x31, 0x30, 0x21, 0x35, 0x23, 0x07, 0x23, 0x36, +0x12, 0x37, 0x33, 0x15, 0x23, 0x15, 0x33, 0x15, 0x23, 0x15, +0x33, 0x15, 0x03, 0x06, 0x06, 0x07, 0x33, 0x01, 0x07, 0x76, +0x25, 0x51, 0x2d, 0x5c, 0x37, 0xfa, 0x80, 0x69, 0x69, 0x8d, +0xdb, 0x1c, 0x33, 0x15, 0x64, 0xa2, 0xa2, 0xae, 0x01, 0x31, +0x8c, 0x46, 0xbe, 0x46, 0xdb, 0x46, 0x02, 0x36, 0x58, 0xae, +0x4a, 0x00, 0x00, 0x01, 0x00, 0x2e, 0xff, 0x57, 0x01, 0xcc, +0x02, 0x79, 0x00, 0x37, 0x01, 0x3a, 0xb9, 0x00, 0x36, 0xff, +0xc8, 0xb3, 0x10, 0x00, 0x4d, 0x36, 0xb8, 0xff, 0xd0, 0xb3, +0x0f, 0x00, 0x4d, 0x35, 0xb8, 0xff, 0xe8, 0xb4, 0x11, 0x12, +0x00, 0x4c, 0x2f, 0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, +0x2f, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x2f, 0xb8, +0xff, 0xe8, 0xb4, 0x0b, 0x0c, 0x00, 0x4c, 0x2a, 0xb8, 0xff, +0xf8, 0xb3, 0x10, 0x00, 0x4d, 0x29, 0xb8, 0xff, 0xe8, 0xb4, +0x11, 0x12, 0x00, 0x4c, 0x29, 0xb8, 0xff, 0xf0, 0xb3, 0x0c, +0x00, 0x4d, 0x29, 0xb8, 0xff, 0xe8, 0xb3, 0x0b, 0x00, 0x4d, +0x24, 0xb8, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x24, 0xb8, +0xff, 0xe0, 0xb3, 0x11, 0x00, 0x4d, 0x23, 0xb8, 0xff, 0xe0, +0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x23, 0xb8, 0xff, 0xc8, 0x40, +0x15, 0x0e, 0x00, 0x4d, 0x1a, 0x08, 0x11, 0x12, 0x00, 0x4c, +0x19, 0x28, 0x0d, 0x0e, 0x00, 0x4c, 0x19, 0x10, 0x08, 0x00, +0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb4, 0x14, 0x15, 0x00, 0x4c, +0x05, 0xb8, 0xff, 0xd8, 0xb3, 0x13, 0x00, 0x4d, 0x05, 0xb8, +0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe8, +0xb4, 0x10, 0x11, 0x00, 0x4c, 0x05, 0xb8, 0xff, 0xd0, 0xb3, +0x0f, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xc8, 0xb4, 0x13, 0x14, +0x00, 0x4c, 0x02, 0xb8, 0xff, 0xd0, 0xb3, 0x12, 0x00, 0x4d, +0x02, 0xb8, 0xff, 0xd8, 0x40, 0x32, 0x0f, 0x11, 0x00, 0x4c, +0x11, 0x30, 0x03, 0x40, 0x03, 0x50, 0x03, 0x03, 0x03, 0x37, +0x00, 0x17, 0x0b, 0x14, 0x14, 0x1c, 0x24, 0x24, 0x35, 0x39, +0x2c, 0x76, 0x1c, 0x38, 0x00, 0x14, 0x14, 0x38, 0x0f, 0x40, +0x08, 0x38, 0x80, 0x34, 0x34, 0x31, 0x7c, 0x17, 0x37, 0x46, +0x25, 0x25, 0x27, 0x7c, 0x21, 0x45, 0x00, 0x3f, 0xed, 0x32, +0x2f, 0x3f, 0x33, 0xed, 0x32, 0x2f, 0x1a, 0x10, 0xdc, 0x1a, +0xcd, 0x12, 0x39, 0x2f, 0xcd, 0x01, 0x10, 0xd6, 0xed, 0x10, +0xce, 0x32, 0x2f, 0x11, 0x39, 0x2f, 0xcc, 0x33, 0xdd, 0x32, +0xd5, 0x5d, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x05, 0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, +0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x35, 0x34, 0x27, 0x27, +0x36, 0x36, 0x37, 0x2e, 0x03, 0x35, 0x34, 0x3e, 0x02, 0x33, +0x32, 0x16, 0x17, 0x07, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, +0x14, 0x1e, 0x02, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x07, +0x01, 0x3d, 0x1a, 0x17, 0x09, 0x15, 0x23, 0x1a, 0x17, 0x28, +0x0b, 0x0a, 0x0b, 0x18, 0x0f, 0x20, 0x25, 0x07, 0x04, 0x0c, +0x06, 0x31, 0x53, 0x3c, 0x21, 0x29, 0x46, 0x5e, 0x35, 0x25, +0x4d, 0x25, 0x18, 0x42, 0x3a, 0x29, 0x41, 0x2e, 0x19, 0x1b, +0x30, 0x43, 0x27, 0x1d, 0x40, 0x22, 0x16, 0x3a, 0x4a, 0x21, +0x0c, 0x1e, 0x1d, 0x0a, 0x17, 0x13, 0x0d, 0x07, 0x05, 0x33, +0x04, 0x05, 0x14, 0x14, 0x0b, 0x02, 0x0b, 0x1b, 0x0d, 0x05, +0x2b, 0x50, 0x74, 0x4d, 0x4f, 0x78, 0x52, 0x2a, 0x14, 0x17, +0x44, 0x26, 0x23, 0x42, 0x5c, 0x39, 0x40, 0x5e, 0x3e, 0x1e, +0x0f, 0x13, 0x44, 0x21, 0x05, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x5b, 0x00, 0x00, 0x01, 0xcc, 0x03, 0x3e, 0x02, 0x26, +0x00, 0x28, 0x00, 0x00, 0x01, 0x07, 0x00, 0x43, 0x00, 0x0e, +0x00, 0x89, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xf1, 0x40, +0x09, 0x0f, 0x0d, 0x00, 0x0a, 0x50, 0x01, 0x01, 0x0e, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x5b, +0x00, 0x00, 0x01, 0xcc, 0x03, 0x3e, 0x02, 0x26, 0x00, 0x28, +0x00, 0x00, 0x01, 0x07, 0x00, 0x8f, 0x00, 0x1a, 0x00, 0x89, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x04, 0x0e, 0x0c, 0x00, 0x0a, +0x50, 0x01, 0x01, 0x0d, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x5b, 0x00, 0x00, 0x01, 0xcc, 0x03, 0x3a, +0x02, 0x26, 0x00, 0x28, 0x00, 0x00, 0x01, 0x07, 0x00, 0x69, +0x00, 0x12, 0x00, 0x8b, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, +0xf9, 0x40, 0x09, 0x11, 0x0d, 0x00, 0x0a, 0x50, 0x01, 0x01, +0x0e, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x5b, 0x00, 0x00, 0x01, 0xcc, 0x03, 0x1a, 0x02, 0x26, +0x00, 0x28, 0x00, 0x00, 0x01, 0x07, 0x00, 0x83, 0x00, 0x12, +0x00, 0x8b, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, 0xff, 0xf9, +0x40, 0x0d, 0x0e, 0x20, 0x00, 0x0a, 0x50, 0x02, 0x01, 0x18, +0x4f, 0x01, 0x01, 0x0c, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, +0xff, 0xff, 0x00, 0x59, 0x00, 0x00, 0x01, 0x9b, 0x03, 0x3e, +0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x07, 0x00, 0x43, +0x00, 0x05, 0x00, 0x89, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x01, +0x0f, 0x0d, 0x04, 0x02, 0x50, 0x01, 0x09, 0x0e, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x59, 0x00, 0x00, +0x01, 0x9b, 0x03, 0x3e, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, +0x01, 0x07, 0x00, 0x8f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x0e, 0x0e, 0x0c, 0x04, 0x02, 0x50, 0x01, +0x09, 0x0d, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x59, 0x00, 0x00, 0x01, 0x9b, 0x03, 0x3a, 0x02, 0x26, +0x00, 0x2c, 0x00, 0x00, 0x01, 0x07, 0x00, 0x69, 0x00, 0x00, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x11, 0x0d, +0x04, 0x02, 0x50, 0x01, 0x09, 0x0e, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x59, 0x00, 0x00, 0x01, 0x9b, +0x03, 0x1a, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x07, +0x00, 0x83, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x1e, 0x40, 0x15, +0x10, 0x15, 0x50, 0x15, 0x50, 0x1b, 0x6f, 0x1b, 0x04, 0xaf, +0x1b, 0x01, 0x15, 0x02, 0x09, 0x18, 0x4f, 0x01, 0x09, 0x0c, +0x4f, 0x2b, 0x2b, 0x01, 0x10, 0x5d, 0x71, 0x31, 0x00, 0x02, +0x00, 0x12, 0xff, 0xfb, 0x01, 0xcc, 0x02, 0x71, 0x00, 0x12, +0x00, 0x24, 0x00, 0x60, 0x40, 0x15, 0x1d, 0x28, 0x12, 0x00, +0x4d, 0x1d, 0x20, 0x11, 0x00, 0x4d, 0x18, 0x18, 0x12, 0x00, +0x4d, 0x18, 0x20, 0x11, 0x00, 0x4d, 0x10, 0xb8, 0xff, 0xe8, +0xb3, 0x0d, 0x00, 0x4d, 0x03, 0xb8, 0xff, 0xe8, 0x40, 0x1e, +0x0d, 0x00, 0x4d, 0x1b, 0x76, 0x00, 0x26, 0x23, 0x21, 0x13, +0x73, 0x0b, 0x09, 0x07, 0x25, 0x24, 0x08, 0x79, 0x21, 0x0b, +0x0b, 0x16, 0x1e, 0x7c, 0x0e, 0x41, 0x16, 0x7c, 0x05, 0x42, +0x00, 0x3f, 0xed, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0x33, 0xed, +0x32, 0x01, 0x10, 0xd6, 0xce, 0x33, 0xfd, 0x32, 0xce, 0x10, +0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x01, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x27, 0x11, 0x23, 0x35, +0x33, 0x35, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x01, 0x16, 0x16, +0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x26, 0x23, 0x22, 0x07, +0x15, 0x33, 0x15, 0x23, 0x01, 0xcc, 0x29, 0x47, 0x62, 0x39, +0x3d, 0x3d, 0x35, 0x35, 0x3d, 0x3d, 0x39, 0x62, 0x47, 0x29, +0xfe, 0xce, 0x0b, 0x18, 0x0b, 0x2a, 0x41, 0x2d, 0x18, 0x5b, +0x58, 0x19, 0x12, 0x62, 0x62, 0x01, 0x36, 0x56, 0x78, 0x4b, +0x22, 0x0f, 0x01, 0x19, 0x40, 0xff, 0x0f, 0x22, 0x4c, 0x78, +0xfe, 0xba, 0x02, 0x01, 0x1b, 0x3b, 0x5d, 0x41, 0x7e, 0x76, +0x03, 0xc4, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x37, +0x00, 0x00, 0x01, 0xbd, 0x03, 0x1c, 0x02, 0x26, 0x00, 0x31, +0x00, 0x00, 0x01, 0x07, 0x00, 0x75, 0x00, 0x00, 0x00, 0x8b, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x20, 0x12, 0x07, 0x10, +0x50, 0x01, 0x08, 0x1f, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, 0x03, 0x3e, +0x02, 0x26, 0x00, 0x32, 0x00, 0x00, 0x01, 0x07, 0x00, 0x43, +0x00, 0x05, 0x00, 0x89, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x01, +0x23, 0x21, 0x00, 0x09, 0x50, 0x02, 0x04, 0x22, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1d, 0xff, 0xf3, +0x01, 0xd8, 0x03, 0x3e, 0x02, 0x26, 0x00, 0x32, 0x00, 0x00, +0x01, 0x07, 0x00, 0x8f, 0x00, 0x09, 0x00, 0x89, 0x00, 0x10, +0x40, 0x0b, 0x02, 0x0c, 0x22, 0x20, 0x00, 0x09, 0x50, 0x02, +0x04, 0x21, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, 0x03, 0x3a, 0x02, 0x26, +0x00, 0x32, 0x00, 0x00, 0x01, 0x07, 0x00, 0x69, 0x00, 0x00, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x25, 0x21, +0x00, 0x09, 0x50, 0x02, 0x04, 0x22, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, +0x03, 0x1c, 0x02, 0x26, 0x00, 0x32, 0x00, 0x00, 0x01, 0x07, +0x00, 0x75, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, +0x02, 0x00, 0x2e, 0x20, 0x00, 0x09, 0x50, 0x02, 0x04, 0x2d, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1d, +0xff, 0xf3, 0x01, 0xd8, 0x03, 0x1a, 0x02, 0x26, 0x00, 0x32, +0x00, 0x00, 0x01, 0x07, 0x00, 0x83, 0x00, 0x00, 0x00, 0x8b, +0x00, 0x17, 0x40, 0x10, 0x03, 0x02, 0x00, 0x22, 0x34, 0x00, +0x09, 0x50, 0x03, 0x04, 0x2c, 0x4f, 0x02, 0x04, 0x20, 0x4f, +0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x46, 0x00, 0x52, 0x01, 0xae, 0x01, 0xbb, 0x00, 0x0b, +0x00, 0x2d, 0x40, 0x10, 0x08, 0x00, 0x09, 0x0b, 0x06, 0x02, +0x05, 0x03, 0x09, 0x05, 0x08, 0x06, 0x0b, 0x03, 0x00, 0x02, +0x00, 0x2f, 0x33, 0x19, 0xc5, 0x32, 0x18, 0xdc, 0x32, 0x19, +0xc5, 0x32, 0x01, 0x18, 0x2f, 0x33, 0x19, 0xc5, 0x32, 0x18, +0xdc, 0x32, 0x19, 0xc5, 0x32, 0x31, 0x30, 0x25, 0x27, 0x07, +0x27, 0x37, 0x27, 0x37, 0x17, 0x37, 0x17, 0x07, 0x17, 0x01, +0x7c, 0x82, 0x82, 0x32, 0x82, 0x82, 0x32, 0x82, 0x82, 0x32, +0x82, 0x82, 0x52, 0x83, 0x83, 0x32, 0x83, 0x82, 0x32, 0x82, +0x82, 0x32, 0x82, 0x83, 0x00, 0x03, 0x00, 0x1d, 0xff, 0xdf, +0x01, 0xd8, 0x02, 0x8b, 0x00, 0x19, 0x00, 0x23, 0x00, 0x2d, +0x01, 0x67, 0xb9, 0x00, 0x2c, 0xff, 0xf0, 0xb3, 0x0c, 0x00, +0x4d, 0x2c, 0xb8, 0xff, 0xf8, 0x40, 0x2c, 0x0b, 0x00, 0x4d, +0x29, 0x38, 0x11, 0x00, 0x4d, 0x28, 0x18, 0x13, 0x00, 0x4d, +0x28, 0x18, 0x0f, 0x00, 0x4d, 0x28, 0x10, 0x0e, 0x00, 0x4d, +0x27, 0x20, 0x14, 0x00, 0x4d, 0x23, 0x08, 0x11, 0x00, 0x4d, +0x22, 0x10, 0x0c, 0x00, 0x4d, 0x22, 0x08, 0x0b, 0x00, 0x4d, +0x1e, 0xb8, 0xff, 0xe0, 0xb3, 0x13, 0x00, 0x4d, 0x1d, 0xb8, +0xff, 0xd8, 0x40, 0x1d, 0x14, 0x00, 0x4d, 0x1c, 0x10, 0x11, +0x00, 0x4d, 0x18, 0x28, 0x0d, 0x00, 0x4d, 0x18, 0x20, 0x0c, +0x00, 0x4d, 0x17, 0x20, 0x11, 0x00, 0x4d, 0x17, 0x18, 0x0e, +0x00, 0x4d, 0x10, 0xb8, 0xff, 0xe8, 0xb3, 0x0d, 0x00, 0x4d, +0x0b, 0xb8, 0xff, 0xd0, 0xb3, 0x0f, 0x00, 0x4d, 0x0b, 0xb8, +0xff, 0xe0, 0xb3, 0x0e, 0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xd8, +0x40, 0x09, 0x0d, 0x00, 0x4d, 0x03, 0x10, 0x0d, 0x00, 0x4d, +0x28, 0xb8, 0xff, 0xd0, 0xb3, 0x0c, 0x00, 0x4d, 0x27, 0xb8, +0xff, 0xd0, 0xb3, 0x0e, 0x00, 0x4d, 0x27, 0xb8, 0xff, 0xe8, +0xb3, 0x0c, 0x00, 0x4d, 0x27, 0xb8, 0xff, 0xd8, 0xb3, 0x0b, +0x00, 0x4d, 0x26, 0xb8, 0xff, 0xb8, 0x40, 0x09, 0x12, 0x00, +0x4d, 0x1d, 0x40, 0x11, 0x00, 0x4d, 0x1d, 0xb8, 0xff, 0xd0, +0x40, 0x1d, 0x0c, 0x00, 0x4d, 0x1c, 0x20, 0x12, 0x00, 0x4d, +0x1c, 0x40, 0x11, 0x00, 0x4d, 0x1c, 0x28, 0x10, 0x00, 0x4d, +0x17, 0x28, 0x11, 0x00, 0x4d, 0x0b, 0x20, 0x11, 0x00, 0x4d, +0x07, 0xb8, 0xff, 0xc8, 0xb3, 0x0c, 0x00, 0x4d, 0x06, 0xb8, +0xff, 0xa8, 0x40, 0x31, 0x10, 0x00, 0x4d, 0x0a, 0x1d, 0x1e, +0x14, 0x15, 0x09, 0x15, 0x07, 0x28, 0x27, 0x17, 0x16, 0x15, +0x08, 0x16, 0x08, 0x78, 0x09, 0x15, 0x14, 0x09, 0x15, 0x09, +0x09, 0x1a, 0x76, 0x0d, 0x2f, 0x16, 0x16, 0x24, 0x76, 0x00, +0x2e, 0x16, 0x15, 0x21, 0x7c, 0x12, 0x46, 0x09, 0x08, 0x2b, +0x7c, 0x05, 0x45, 0x00, 0x3f, 0xed, 0xc6, 0x32, 0x3f, 0xed, +0xc6, 0x32, 0x01, 0x10, 0xd6, 0xed, 0x33, 0x2f, 0x10, 0xde, +0xed, 0x33, 0x2f, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x10, 0x0e, +0xc4, 0xc4, 0xc4, 0xc4, 0x10, 0x87, 0x0e, 0xc4, 0xc4, 0xc4, +0xc4, 0x31, 0x30, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x13, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x17, 0x37, 0x17, +0x07, 0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x27, +0x07, 0x27, 0x37, 0x26, 0x26, 0x25, 0x34, 0x26, 0x27, 0x03, +0x16, 0x16, 0x33, 0x32, 0x36, 0x25, 0x14, 0x16, 0x17, 0x13, +0x26, 0x26, 0x23, 0x22, 0x06, 0x1d, 0x20, 0x3a, 0x51, 0x32, +0x38, 0x2f, 0x15, 0x3e, 0x1e, 0x1f, 0x23, 0x21, 0x3a, 0x52, +0x31, 0x3e, 0x2e, 0x17, 0x3d, 0x20, 0x1e, 0x1f, 0x01, 0x67, +0x0b, 0x0c, 0xbf, 0x0f, 0x27, 0x14, 0x46, 0x46, 0xfe, 0xed, +0x06, 0x0b, 0xbe, 0x0f, 0x24, 0x15, 0x45, 0x42, 0x01, 0x36, +0x53, 0x7a, 0x4f, 0x27, 0x1b, 0x2d, 0x1f, 0x3d, 0x29, 0x7b, +0x55, 0x53, 0x7a, 0x50, 0x26, 0x1c, 0x30, 0x1f, 0x42, 0x28, +0x79, 0x55, 0x32, 0x54, 0x1f, 0xfe, 0x76, 0x0d, 0x0a, 0x82, +0x7a, 0x30, 0x53, 0x1f, 0x01, 0x88, 0x0c, 0x0a, 0x82, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x30, 0xff, 0xf3, 0x01, 0xc4, +0x03, 0x3e, 0x02, 0x26, 0x00, 0x38, 0x00, 0x00, 0x01, 0x07, +0x00, 0x43, 0x00, 0x00, 0x00, 0x89, 0x00, 0x13, 0xb9, 0x00, +0x01, 0xff, 0xfd, 0x40, 0x09, 0x1d, 0x1b, 0x04, 0x14, 0x50, +0x01, 0x06, 0x1c, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x30, 0xff, 0xf3, 0x01, 0xc4, 0x03, 0x3e, +0x02, 0x26, 0x00, 0x38, 0x00, 0x00, 0x01, 0x07, 0x00, 0x8f, +0x00, 0x09, 0x00, 0x89, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x0d, +0x1c, 0x1a, 0x04, 0x14, 0x50, 0x01, 0x06, 0x1b, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x30, 0xff, 0xf3, +0x01, 0xc4, 0x03, 0x3a, 0x02, 0x26, 0x00, 0x38, 0x00, 0x00, +0x01, 0x07, 0x00, 0x69, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x00, 0x1f, 0x1b, 0x04, 0x14, 0x50, 0x01, +0x06, 0x1c, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x30, 0xff, 0xf3, 0x01, 0xc4, 0x03, 0x1a, 0x02, 0x26, +0x00, 0x38, 0x00, 0x00, 0x01, 0x07, 0x00, 0x83, 0x00, 0x00, +0x00, 0x8b, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, 0x00, 0x1c, +0x2e, 0x04, 0x14, 0x50, 0x02, 0x06, 0x26, 0x4f, 0x01, 0x06, +0x1a, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x0d, 0x00, 0x00, 0x01, 0xe8, 0x03, 0x3e, +0x02, 0x26, 0x00, 0x3c, 0x00, 0x00, 0x01, 0x07, 0x00, 0x8f, +0x00, 0x09, 0x00, 0x89, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x0c, +0x13, 0x11, 0x04, 0x0c, 0x50, 0x01, 0x04, 0x12, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0x00, 0x02, 0x00, 0x49, 0x00, 0x00, +0x01, 0xc7, 0x02, 0x6b, 0x00, 0x0f, 0x00, 0x1e, 0x00, 0x6f, +0x40, 0x15, 0x1c, 0x10, 0x10, 0x00, 0x4d, 0x18, 0x28, 0x10, +0x00, 0x4d, 0x18, 0x18, 0x0f, 0x00, 0x4d, 0x18, 0x10, 0x0e, +0x00, 0x4d, 0x09, 0xb8, 0xff, 0xe8, 0xb3, 0x08, 0x00, 0x4d, +0x06, 0xb8, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x06, 0xb8, +0xff, 0xf0, 0xb3, 0x11, 0x00, 0x4d, 0x06, 0xb8, 0xff, 0xe0, +0x40, 0x1f, 0x08, 0x00, 0x4d, 0x1a, 0x76, 0x07, 0x20, 0x14, +0x02, 0x0d, 0x73, 0x00, 0x0f, 0x10, 0x0f, 0x20, 0x0f, 0x03, +0x08, 0x0f, 0x1f, 0x14, 0x79, 0x0d, 0x0f, 0x42, 0x13, 0x79, +0x02, 0x00, 0x41, 0x00, 0x3f, 0xdd, 0xed, 0x3f, 0xdd, 0xed, +0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x32, 0x10, 0xde, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x13, 0x33, 0x15, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, +0x0e, 0x02, 0x23, 0x23, 0x15, 0x23, 0x13, 0x22, 0x22, 0x07, +0x15, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, 0x49, +0x52, 0x1f, 0x1e, 0x73, 0x7c, 0x23, 0x40, 0x5b, 0x37, 0x37, +0x52, 0x9c, 0x19, 0x23, 0x0e, 0x3a, 0x23, 0x3a, 0x2a, 0x17, +0x19, 0x28, 0x33, 0x02, 0x6b, 0x67, 0x03, 0x5b, 0x58, 0x3b, +0x50, 0x33, 0x16, 0x80, 0x01, 0xbf, 0x01, 0xf9, 0x0d, 0x20, +0x35, 0x29, 0x21, 0x2b, 0x19, 0x0a, 0x00, 0x00, 0x00, 0x01, +0x00, 0x47, 0xff, 0xf5, 0x01, 0xdc, 0x02, 0xb5, 0x00, 0x3f, +0x01, 0x35, 0xb9, 0x00, 0x3e, 0xff, 0xf0, 0xb3, 0x0d, 0x00, +0x4d, 0x3e, 0xb8, 0xff, 0xd8, 0xb3, 0x0c, 0x00, 0x4d, 0x3e, +0xb8, 0xff, 0xe0, 0xb4, 0x0a, 0x0b, 0x00, 0x4c, 0x3e, 0xb8, +0xff, 0xd8, 0xb3, 0x09, 0x00, 0x4d, 0x3e, 0xb8, 0xff, 0xe0, +0x40, 0x0e, 0x08, 0x00, 0x4d, 0x39, 0x08, 0x0c, 0x00, 0x4d, +0x39, 0x10, 0x0a, 0x00, 0x4d, 0x31, 0xb8, 0xff, 0xe8, 0xb3, +0x12, 0x00, 0x4d, 0x31, 0xb8, 0xff, 0xe0, 0x40, 0x18, 0x11, +0x00, 0x4d, 0x2a, 0x18, 0x0d, 0x00, 0x4d, 0x25, 0x10, 0x0d, +0x00, 0x4d, 0x24, 0x10, 0x0b, 0x00, 0x4d, 0x23, 0x10, 0x0d, +0x00, 0x4d, 0x10, 0xb8, 0xff, 0xe8, 0xb4, 0x0c, 0x0e, 0x00, +0x4c, 0x10, 0xb8, 0xff, 0xe0, 0xb3, 0x0b, 0x00, 0x4d, 0x10, +0xb8, 0xff, 0xd8, 0xb3, 0x0a, 0x00, 0x4d, 0x10, 0xb8, 0xff, +0xe0, 0xb4, 0x08, 0x09, 0x00, 0x4c, 0x0d, 0xb8, 0xff, 0xe0, +0xb3, 0x11, 0x00, 0x4d, 0x0d, 0xb8, 0xff, 0xd8, 0xb3, 0x10, +0x00, 0x4d, 0x0d, 0xb8, 0xff, 0xf8, 0xb3, 0x0e, 0x00, 0x4d, +0x0d, 0xb8, 0xff, 0xe8, 0xb3, 0x0d, 0x00, 0x4d, 0x0c, 0xb8, +0xff, 0xe0, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x0c, 0xb8, 0xff, +0xd0, 0xb3, 0x10, 0x00, 0x4d, 0x03, 0xb8, 0xff, 0xe0, 0x40, +0x41, 0x0b, 0x00, 0x4d, 0x17, 0x17, 0x27, 0x82, 0x08, 0x40, +0x09, 0x00, 0x4d, 0x2f, 0x08, 0x3f, 0x08, 0x6f, 0x08, 0x03, +0x08, 0x08, 0x0f, 0x2d, 0x82, 0x00, 0x40, 0x08, 0x0b, 0x48, +0x00, 0x00, 0x20, 0x82, 0x0f, 0x41, 0x34, 0x7f, 0x00, 0x35, +0x01, 0x08, 0x35, 0x40, 0x00, 0x2d, 0x27, 0x08, 0x0f, 0x20, +0x2d, 0x3b, 0x20, 0x08, 0x08, 0x1d, 0x30, 0x88, 0x3b, 0x4d, +0x35, 0x4a, 0x1d, 0x88, 0x12, 0x51, 0x00, 0x3f, 0xed, 0x3f, +0x3f, 0xed, 0x12, 0x39, 0x2f, 0x39, 0x12, 0x39, 0x11, 0x33, +0x11, 0x33, 0x11, 0x33, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, +0x10, 0xde, 0xed, 0x33, 0x2f, 0x2b, 0xed, 0x11, 0x33, 0x2f, +0x5d, 0x2b, 0xed, 0x32, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x01, 0x14, 0x0e, 0x02, 0x07, 0x06, 0x06, 0x15, 0x14, +0x1e, 0x04, 0x15, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x27, +0x37, 0x1e, 0x03, 0x33, 0x32, 0x36, 0x35, 0x34, 0x2e, 0x04, +0x35, 0x34, 0x36, 0x37, 0x36, 0x36, 0x35, 0x34, 0x26, 0x23, +0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x34, 0x3e, 0x02, 0x33, +0x32, 0x1e, 0x02, 0x01, 0x90, 0x0f, 0x16, 0x1c, 0x0c, 0x0e, +0x0d, 0x1b, 0x28, 0x2e, 0x28, 0x1b, 0x52, 0x57, 0x10, 0x21, +0x1d, 0x15, 0x05, 0x0e, 0x05, 0x14, 0x1a, 0x1e, 0x0f, 0x29, +0x26, 0x1b, 0x28, 0x30, 0x28, 0x1b, 0x1e, 0x17, 0x15, 0x21, +0x24, 0x28, 0x2a, 0x2d, 0x53, 0x17, 0x2a, 0x3d, 0x26, 0x2e, +0x40, 0x26, 0x11, 0x02, 0x26, 0x18, 0x28, 0x21, 0x1c, 0x0d, +0x10, 0x15, 0x0f, 0x14, 0x1a, 0x17, 0x18, 0x23, 0x33, 0x27, +0x4c, 0x4d, 0x06, 0x08, 0x08, 0x03, 0x49, 0x03, 0x09, 0x09, +0x06, 0x28, 0x26, 0x1b, 0x23, 0x1b, 0x17, 0x1d, 0x27, 0x1e, +0x24, 0x30, 0x17, 0x14, 0x28, 0x17, 0x26, 0x2d, 0x44, 0x3c, +0xfe, 0x13, 0x01, 0xef, 0x2c, 0x49, 0x34, 0x1d, 0x17, 0x28, +0x34, 0x00, 0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb0, +0x02, 0xb5, 0x02, 0x26, 0x00, 0x44, 0x00, 0x00, 0x01, 0x06, +0x00, 0x43, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x01, +0x34, 0x32, 0x1c, 0x13, 0x50, 0x02, 0x0f, 0x33, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb0, +0x02, 0xb5, 0x02, 0x26, 0x00, 0x44, 0x00, 0x00, 0x01, 0x06, +0x00, 0x8f, 0x12, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x1b, +0x33, 0x31, 0x1c, 0x13, 0x50, 0x02, 0x0f, 0x32, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb0, +0x02, 0xaf, 0x02, 0x26, 0x00, 0x44, 0x00, 0x00, 0x01, 0x06, +0x00, 0x69, 0x09, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x0e, +0x36, 0x32, 0x1c, 0x13, 0x50, 0x02, 0x0f, 0x33, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb0, +0x02, 0x91, 0x02, 0x26, 0x00, 0x44, 0x00, 0x00, 0x01, 0x06, +0x00, 0x75, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x05, +0x3f, 0x31, 0x1c, 0x13, 0x50, 0x02, 0x0f, 0x3e, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb0, +0x02, 0x8f, 0x02, 0x26, 0x00, 0x44, 0x00, 0x00, 0x01, 0x06, +0x00, 0x83, 0x00, 0x00, 0x00, 0x17, 0x40, 0x10, 0x03, 0x02, +0x05, 0x33, 0x45, 0x1c, 0x13, 0x50, 0x03, 0x0f, 0x3d, 0x4f, +0x02, 0x0f, 0x31, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb0, 0x02, 0xb8, +0x02, 0x26, 0x00, 0x44, 0x00, 0x00, 0x01, 0x06, 0x01, 0x63, +0x00, 0x00, 0x00, 0x14, 0x40, 0x0d, 0x03, 0x02, 0x05, 0x36, +0x31, 0x1c, 0x13, 0x50, 0x03, 0x02, 0x0f, 0x34, 0x4f, 0x2b, +0x34, 0x2b, 0x34, 0x34, 0x00, 0x03, 0x00, 0x1f, 0xff, 0xf5, +0x01, 0xde, 0x01, 0xdb, 0x00, 0x34, 0x00, 0x42, 0x00, 0x4b, +0x00, 0xbb, 0x40, 0x2b, 0x25, 0x18, 0x10, 0x00, 0x4d, 0x25, +0x10, 0x0d, 0x0e, 0x00, 0x4c, 0x24, 0x18, 0x0b, 0x0c, 0x00, +0x4c, 0x20, 0x20, 0x0d, 0x00, 0x4d, 0x20, 0x10, 0x0c, 0x00, +0x4d, 0x20, 0x20, 0x0b, 0x00, 0x4d, 0x1f, 0x10, 0x0e, 0x00, +0x4d, 0x19, 0x18, 0x12, 0x00, 0x4d, 0x0e, 0xb8, 0xff, 0xe8, +0xb3, 0x11, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xe8, 0x40, 0x19, +0x0b, 0x0c, 0x00, 0x4c, 0x4b, 0x03, 0x0c, 0x82, 0x3e, 0x2a, +0x1a, 0x41, 0x41, 0x22, 0x43, 0x82, 0x0b, 0x12, 0x12, 0x0b, +0x4d, 0x38, 0x82, 0x22, 0x32, 0xb8, 0xff, 0xc0, 0x40, 0x28, +0x13, 0x16, 0x48, 0x32, 0x32, 0x22, 0x4c, 0x35, 0x89, 0x27, +0x0c, 0x86, 0x4b, 0x27, 0x4b, 0x27, 0x4b, 0x00, 0x3b, 0x88, +0x1a, 0x1d, 0x51, 0x11, 0x11, 0x0f, 0x88, 0x17, 0x51, 0x03, +0x48, 0x88, 0x06, 0x50, 0x31, 0x31, 0x2e, 0x88, 0x00, 0x50, +0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x32, 0x3f, 0xed, +0x32, 0x2f, 0x3f, 0x33, 0xed, 0x11, 0x39, 0x39, 0x2f, 0x2f, +0x10, 0xed, 0x10, 0xed, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x2b, +0x10, 0xed, 0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, 0x11, 0x39, +0x2f, 0x33, 0x33, 0x33, 0xed, 0x32, 0x32, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, +0x32, 0x16, 0x17, 0x36, 0x36, 0x33, 0x32, 0x15, 0x14, 0x14, +0x07, 0x23, 0x14, 0x16, 0x33, 0x32, 0x37, 0x17, 0x0e, 0x03, +0x23, 0x22, 0x26, 0x27, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, +0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x35, 0x34, +0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x13, 0x22, +0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x26, 0x26, +0x27, 0x26, 0x37, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x15, +0x96, 0x2c, 0x38, 0x0f, 0x10, 0x2a, 0x1a, 0x81, 0x01, 0xb9, +0x34, 0x29, 0x20, 0x25, 0x0b, 0x04, 0x13, 0x18, 0x1c, 0x0d, +0x21, 0x33, 0x13, 0x1b, 0x38, 0x1d, 0x21, 0x31, 0x21, 0x10, +0x11, 0x22, 0x31, 0x21, 0x0c, 0x1d, 0x0c, 0x24, 0x26, 0x16, +0x2a, 0x08, 0x09, 0x09, 0x35, 0x30, 0x21, 0x21, 0x1f, 0x20, +0x11, 0x27, 0x0e, 0x0b, 0x0c, 0x02, 0x14, 0xd1, 0x09, 0x0f, +0x12, 0x08, 0x17, 0x24, 0x01, 0xdb, 0x22, 0x1e, 0x1e, 0x22, +0xec, 0x05, 0x11, 0x07, 0x48, 0x4b, 0x16, 0x46, 0x04, 0x09, +0x08, 0x05, 0x17, 0x14, 0x17, 0x14, 0x19, 0x28, 0x33, 0x1b, +0x1f, 0x37, 0x29, 0x17, 0x05, 0x06, 0x17, 0x2f, 0x40, 0x0c, +0x06, 0x44, 0x08, 0x0c, 0xfe, 0xfc, 0x2a, 0x24, 0x1e, 0x30, +0x10, 0x0d, 0x19, 0x3b, 0x20, 0x0b, 0x3e, 0x25, 0x31, 0x1e, +0x0c, 0x3a, 0x46, 0x00, 0x00, 0x01, 0x00, 0x31, 0xff, 0x57, +0x01, 0xc3, 0x01, 0xdb, 0x00, 0x37, 0x00, 0x8c, 0xb9, 0x00, +0x2e, 0xff, 0xe0, 0xb4, 0x0d, 0x0e, 0x00, 0x4c, 0x28, 0xb8, +0xff, 0xe0, 0xb3, 0x0e, 0x00, 0x4d, 0x28, 0xb8, 0xff, 0xe8, +0x40, 0x09, 0x0d, 0x00, 0x4d, 0x18, 0x18, 0x08, 0x00, 0x4d, +0x05, 0xb8, 0xff, 0xe0, 0xb4, 0x0f, 0x15, 0x00, 0x4c, 0x02, +0xb8, 0xff, 0xd8, 0x40, 0x30, 0x0f, 0x15, 0x00, 0x4c, 0x11, +0x40, 0x03, 0x50, 0x03, 0x02, 0x03, 0x37, 0x00, 0x17, 0x0b, +0x14, 0x14, 0x1a, 0x22, 0x22, 0x34, 0x39, 0x2b, 0x82, 0x1a, +0x38, 0x00, 0x14, 0x14, 0x38, 0x0f, 0x40, 0x08, 0x38, 0x80, +0x33, 0x33, 0x30, 0x88, 0x17, 0x37, 0x51, 0x23, 0x23, 0x26, +0x88, 0x1f, 0x50, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0x33, +0xed, 0x32, 0x2f, 0x1a, 0x10, 0xdc, 0x1a, 0xcd, 0x12, 0x39, +0x2f, 0xcd, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xce, 0x32, 0x2f, +0x11, 0x39, 0x2f, 0xcc, 0x33, 0xcd, 0x32, 0xd4, 0x5d, 0xcd, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x05, 0x16, +0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, +0x16, 0x16, 0x33, 0x32, 0x35, 0x34, 0x27, 0x27, 0x36, 0x36, +0x37, 0x26, 0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, +0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, +0x1e, 0x02, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x06, 0x07, +0x01, 0x26, 0x1a, 0x17, 0x09, 0x15, 0x23, 0x1a, 0x17, 0x28, +0x0b, 0x0a, 0x0b, 0x18, 0x0f, 0x20, 0x25, 0x07, 0x04, 0x0d, +0x07, 0x5b, 0x6e, 0x28, 0x46, 0x5d, 0x35, 0x22, 0x43, 0x26, +0x13, 0x21, 0x37, 0x1c, 0x24, 0x40, 0x2f, 0x1c, 0x1a, 0x2f, +0x42, 0x28, 0x20, 0x3b, 0x23, 0x0c, 0x22, 0x46, 0x2a, 0x21, +0x0c, 0x1e, 0x1d, 0x0a, 0x17, 0x13, 0x0d, 0x07, 0x05, 0x33, +0x04, 0x05, 0x14, 0x14, 0x0b, 0x02, 0x0b, 0x1e, 0x0e, 0x0d, +0x77, 0x6a, 0x3f, 0x5c, 0x3c, 0x1d, 0x09, 0x0c, 0x47, 0x0c, +0x07, 0x13, 0x29, 0x41, 0x2e, 0x2c, 0x3f, 0x29, 0x14, 0x07, +0x0c, 0x45, 0x0c, 0x0b, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xc7, 0x02, 0xb5, 0x02, 0x26, +0x00, 0x48, 0x00, 0x00, 0x01, 0x06, 0x00, 0x43, 0x00, 0x00, +0x00, 0x13, 0xb9, 0x00, 0x02, 0xff, 0xff, 0x40, 0x09, 0x25, +0x23, 0x13, 0x02, 0x50, 0x02, 0x00, 0x24, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xc7, +0x02, 0xb5, 0x02, 0x26, 0x00, 0x48, 0x00, 0x00, 0x01, 0x06, +0x00, 0x8f, 0x12, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x18, +0x24, 0x22, 0x13, 0x02, 0x50, 0x02, 0x00, 0x23, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xc7, +0x02, 0xaf, 0x02, 0x26, 0x00, 0x48, 0x00, 0x00, 0x01, 0x06, +0x00, 0x69, 0x0d, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x0f, +0x27, 0x23, 0x13, 0x02, 0x50, 0x02, 0x00, 0x24, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xc7, +0x02, 0x8f, 0x02, 0x26, 0x00, 0x48, 0x00, 0x00, 0x01, 0x06, +0x00, 0x83, 0x0d, 0x00, 0x00, 0x17, 0x40, 0x10, 0x03, 0x02, +0x0f, 0x24, 0x36, 0x13, 0x02, 0x50, 0x03, 0x00, 0x2e, 0x4f, +0x02, 0x00, 0x22, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0xb5, +0x02, 0x26, 0x01, 0x0c, 0x00, 0x00, 0x01, 0x06, 0x00, 0x43, +0xdd, 0x00, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xd8, 0x40, +0x09, 0x19, 0x17, 0x01, 0x0b, 0x50, 0x01, 0x02, 0x18, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, +0x01, 0xc2, 0x02, 0xb5, 0x02, 0x26, 0x01, 0x0c, 0x00, 0x00, +0x01, 0x06, 0x00, 0x8f, 0xe6, 0x00, 0x00, 0x13, 0xb9, 0x00, +0x01, 0xff, 0xe8, 0x40, 0x09, 0x18, 0x16, 0x01, 0x0b, 0x50, +0x01, 0x02, 0x17, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, +0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0xaf, 0x02, 0x26, +0x01, 0x0c, 0x00, 0x00, 0x01, 0x06, 0x00, 0x69, 0xdd, 0x00, +0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xdb, 0x40, 0x09, 0x1b, +0x17, 0x01, 0x0b, 0x50, 0x01, 0x02, 0x18, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, +0x02, 0x8f, 0x02, 0x26, 0x01, 0x0c, 0x00, 0x00, 0x01, 0x06, +0x00, 0x83, 0xdd, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, +0xff, 0xdb, 0x40, 0x0d, 0x18, 0x2a, 0x01, 0x0b, 0x50, 0x02, +0x02, 0x22, 0x4f, 0x01, 0x02, 0x16, 0x4f, 0x2b, 0x2b, 0x2b, +0x34, 0x34, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0xff, 0xf5, +0x01, 0xcc, 0x02, 0xb5, 0x00, 0x22, 0x00, 0x35, 0x00, 0xd0, +0x40, 0x10, 0x33, 0x18, 0x0f, 0x00, 0x4d, 0x33, 0x10, 0x0e, +0x00, 0x4d, 0x33, 0x08, 0x0d, 0x00, 0x4d, 0x2f, 0xb8, 0xff, +0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x2a, 0xb8, 0xff, 0xe8, 0x40, +0x28, 0x0f, 0x00, 0x4d, 0x10, 0x18, 0x10, 0x00, 0x4d, 0x10, +0x18, 0x0a, 0x00, 0x4d, 0x0f, 0x28, 0x08, 0x09, 0x00, 0x4c, +0x0c, 0x20, 0x09, 0x00, 0x4d, 0x0c, 0x18, 0x08, 0x00, 0x4d, +0x0b, 0x20, 0x10, 0x00, 0x4d, 0x0b, 0x10, 0x0a, 0x00, 0x4d, +0x07, 0xb8, 0xff, 0xf0, 0xb3, 0x10, 0x00, 0x4d, 0x07, 0xb8, +0xff, 0xf0, 0x40, 0x3e, 0x08, 0x09, 0x00, 0x4c, 0x21, 0x01, +0x1e, 0x04, 0x1e, 0x1d, 0x00, 0x00, 0x19, 0x19, 0x1a, 0x17, +0x1d, 0x1d, 0x14, 0x23, 0x82, 0x04, 0x37, 0x2c, 0x82, 0x0e, +0x36, 0x17, 0x01, 0x18, 0x00, 0x22, 0x21, 0x1a, 0x22, 0x19, +0x18, 0x29, 0x88, 0x11, 0x00, 0x11, 0x10, 0x11, 0x20, 0x11, +0x03, 0x08, 0x22, 0x18, 0x11, 0x11, 0x18, 0x22, 0x03, 0x1d, +0x1e, 0x4d, 0x31, 0x88, 0x09, 0x51, 0x00, 0x3f, 0xed, 0x3f, +0x33, 0x17, 0x39, 0x2f, 0x2f, 0x2f, 0x5e, 0x5d, 0x10, 0xed, +0x10, 0xcd, 0x11, 0x39, 0x39, 0x10, 0xcd, 0x11, 0x39, 0x39, +0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, 0x32, 0x32, 0x2f, +0x39, 0x39, 0x33, 0x2f, 0x33, 0x2f, 0x11, 0x33, 0x11, 0x12, +0x39, 0x39, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x07, +0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, +0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x17, 0x26, 0x26, 0x27, +0x07, 0x27, 0x37, 0x26, 0x26, 0x27, 0x37, 0x16, 0x16, 0x17, +0x37, 0x03, 0x34, 0x26, 0x35, 0x26, 0x26, 0x23, 0x22, 0x06, +0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x01, 0xcc, +0x60, 0x1d, 0x27, 0x11, 0x2c, 0x4c, 0x3b, 0x2d, 0x44, 0x2d, +0x17, 0x60, 0x53, 0x26, 0x3a, 0x0e, 0x05, 0x1c, 0x14, 0x6b, +0x15, 0x5c, 0x0f, 0x1f, 0x17, 0x2e, 0x14, 0x33, 0x1a, 0x6e, +0x58, 0x01, 0x19, 0x39, 0x17, 0x38, 0x34, 0x0d, 0x19, 0x25, +0x18, 0x22, 0x2d, 0x1a, 0x0a, 0x02, 0x4b, 0x21, 0x31, 0x8d, +0x5a, 0x31, 0x65, 0x53, 0x34, 0x26, 0x3e, 0x4c, 0x27, 0x72, +0x78, 0x1d, 0x0d, 0x24, 0x42, 0x1f, 0x25, 0x38, 0x20, 0x11, +0x1f, 0x11, 0x30, 0x0d, 0x2b, 0x20, 0x26, 0xfe, 0x8c, 0x16, +0x12, 0x08, 0x1b, 0x16, 0x5a, 0x47, 0x1d, 0x36, 0x29, 0x18, +0x25, 0x3c, 0x4c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x47, +0x00, 0x00, 0x01, 0xb0, 0x02, 0x91, 0x02, 0x26, 0x00, 0x51, +0x00, 0x00, 0x01, 0x06, 0x00, 0x75, 0x00, 0x00, 0x00, 0x13, +0xb9, 0x00, 0x01, 0xff, 0xff, 0x40, 0x09, 0x22, 0x14, 0x00, +0x05, 0x50, 0x01, 0x02, 0x21, 0x4f, 0x2b, 0x2b, 0x34, 0x00, +0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0xb5, +0x02, 0x26, 0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x00, 0x43, +0x09, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x05, 0x23, 0x21, +0x09, 0x00, 0x50, 0x02, 0x0e, 0x22, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0xb5, +0x02, 0x26, 0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x00, 0x8f, +0x09, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x0d, 0x22, 0x20, +0x09, 0x00, 0x50, 0x02, 0x0e, 0x21, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0xaf, +0x02, 0x26, 0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x00, 0x69, +0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x25, 0x21, +0x09, 0x00, 0x50, 0x02, 0x0e, 0x22, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0x91, +0x02, 0x26, 0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x00, 0x75, +0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x2e, 0x20, +0x09, 0x00, 0x50, 0x02, 0x0e, 0x2d, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0x8f, +0x02, 0x26, 0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x00, 0x83, +0x00, 0x00, 0x00, 0x17, 0x40, 0x10, 0x03, 0x02, 0x00, 0x22, +0x34, 0x09, 0x00, 0x50, 0x03, 0x0e, 0x2c, 0x4f, 0x02, 0x0e, +0x20, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x03, +0x00, 0x2e, 0x00, 0x24, 0x01, 0xc7, 0x01, 0xe9, 0x00, 0x03, +0x00, 0x0f, 0x00, 0x1b, 0x00, 0x26, 0x40, 0x10, 0x10, 0x02, +0x04, 0x16, 0x03, 0x0a, 0x0a, 0x1d, 0x1c, 0x07, 0x0d, 0x03, +0x19, 0x13, 0x00, 0x03, 0x00, 0x2f, 0xdd, 0xde, 0xcd, 0x10, +0xde, 0xcd, 0x01, 0x11, 0x12, 0x39, 0x2f, 0xce, 0x33, 0xdd, +0xce, 0x33, 0x31, 0x30, 0x13, 0x21, 0x15, 0x21, 0x05, 0x14, +0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, +0x11, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, +0x32, 0x16, 0x2e, 0x01, 0x99, 0xfe, 0x67, 0x01, 0x06, 0x20, +0x1a, 0x1b, 0x21, 0x21, 0x1b, 0x1a, 0x20, 0x20, 0x1a, 0x1b, +0x21, 0x21, 0x1b, 0x1a, 0x20, 0x01, 0x2a, 0x46, 0x84, 0x18, +0x24, 0x24, 0x18, 0x19, 0x25, 0x25, 0x01, 0x33, 0x18, 0x25, +0x25, 0x18, 0x19, 0x24, 0x24, 0x00, 0x00, 0x03, 0x00, 0x28, +0xff, 0xe0, 0x01, 0xcc, 0x01, 0xf0, 0x00, 0x1a, 0x00, 0x24, +0x00, 0x2e, 0x00, 0x9d, 0xb9, 0x00, 0x2d, 0xff, 0xe8, 0xb4, +0x0f, 0x10, 0x00, 0x4c, 0x2d, 0xb8, 0xff, 0xf0, 0x40, 0x0f, +0x0e, 0x00, 0x4d, 0x23, 0x18, 0x0f, 0x10, 0x00, 0x4c, 0x23, +0x10, 0x0e, 0x00, 0x4d, 0x1e, 0xb8, 0xff, 0xf8, 0xb3, 0x0f, +0x00, 0x4d, 0x14, 0xb8, 0xff, 0xf0, 0x40, 0x40, 0x08, 0x00, +0x4d, 0x07, 0x10, 0x08, 0x00, 0x4d, 0x19, 0x1f, 0x1e, 0x0e, +0x04, 0x0d, 0x1a, 0x01, 0x28, 0x29, 0x0b, 0x04, 0x0c, 0x00, +0x0c, 0x0d, 0x0d, 0x1b, 0x82, 0x11, 0x30, 0x1a, 0x00, 0x00, +0x25, 0x82, 0x04, 0x2f, 0x1f, 0x28, 0x1e, 0x29, 0x04, 0x2c, +0x22, 0x88, 0x16, 0x00, 0x1a, 0x1a, 0x0b, 0x0e, 0x01, 0x19, +0x04, 0x09, 0x16, 0x51, 0x2c, 0x88, 0x09, 0x0d, 0x0c, 0x0c, +0x09, 0x50, 0x00, 0x3f, 0x33, 0x2f, 0x33, 0x10, 0xed, 0x3f, +0x12, 0x17, 0x39, 0x33, 0x2f, 0x33, 0x10, 0xed, 0x11, 0x17, +0x39, 0x01, 0x10, 0xd6, 0xed, 0x33, 0x2f, 0x33, 0x10, 0xde, +0xed, 0x33, 0x2f, 0x33, 0x11, 0x12, 0x17, 0x39, 0x11, 0x12, +0x17, 0x39, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x37, 0x37, 0x26, 0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, +0x32, 0x17, 0x37, 0x17, 0x07, 0x16, 0x16, 0x15, 0x14, 0x0e, +0x02, 0x23, 0x22, 0x26, 0x27, 0x07, 0x01, 0x34, 0x26, 0x27, +0x07, 0x16, 0x16, 0x33, 0x32, 0x36, 0x27, 0x14, 0x16, 0x17, +0x37, 0x26, 0x26, 0x23, 0x22, 0x06, 0x2d, 0x2d, 0x17, 0x1b, +0x1f, 0x38, 0x4d, 0x2d, 0x45, 0x30, 0x2a, 0x2f, 0x2e, 0x18, +0x1b, 0x1f, 0x38, 0x4e, 0x2e, 0x21, 0x3a, 0x19, 0x2a, 0x01, +0x1c, 0x07, 0x09, 0xb5, 0x0e, 0x24, 0x15, 0x3a, 0x44, 0xfa, +0x07, 0x09, 0xb4, 0x0e, 0x25, 0x15, 0x39, 0x43, 0x04, 0x3e, +0x20, 0x53, 0x33, 0x37, 0x5a, 0x3f, 0x23, 0x24, 0x39, 0x24, +0x3f, 0x1f, 0x53, 0x33, 0x37, 0x59, 0x40, 0x23, 0x13, 0x11, +0x39, 0x01, 0x08, 0x1c, 0x32, 0x14, 0xf5, 0x0c, 0x0a, 0x5b, +0x4e, 0x1f, 0x2e, 0x14, 0xf4, 0x0c, 0x0b, 0x5b, 0x00, 0x00, +0xff, 0xff, 0x00, 0x44, 0xff, 0xf6, 0x01, 0xad, 0x02, 0xb5, +0x02, 0x26, 0x00, 0x58, 0x00, 0x00, 0x01, 0x06, 0x00, 0x43, +0x00, 0x00, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xfe, 0x40, +0x09, 0x19, 0x17, 0x07, 0x00, 0x50, 0x01, 0x09, 0x18, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, 0x00, 0x44, 0xff, 0xf6, +0x01, 0xad, 0x02, 0xb5, 0x02, 0x26, 0x00, 0x58, 0x00, 0x00, +0x01, 0x06, 0x00, 0x8f, 0x09, 0x00, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x0e, 0x18, 0x16, 0x07, 0x00, 0x50, 0x01, 0x09, 0x17, +0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x44, 0xff, 0xf6, +0x01, 0xad, 0x02, 0xaf, 0x02, 0x26, 0x00, 0x58, 0x00, 0x00, +0x01, 0x06, 0x00, 0x69, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x01, 0x1b, 0x17, 0x07, 0x00, 0x50, 0x01, 0x09, 0x18, +0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x44, 0xff, 0xf6, +0x01, 0xad, 0x02, 0x8f, 0x02, 0x26, 0x00, 0x58, 0x00, 0x00, +0x01, 0x06, 0x00, 0x83, 0x00, 0x00, 0x00, 0x17, 0x40, 0x10, +0x02, 0x01, 0x01, 0x18, 0x2a, 0x07, 0x00, 0x50, 0x02, 0x09, +0x22, 0x4f, 0x01, 0x09, 0x16, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, +0x34, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0x58, 0x01, 0xcd, +0x02, 0xb5, 0x02, 0x26, 0x00, 0x5c, 0x00, 0x00, 0x01, 0x06, +0x00, 0x8f, 0x0f, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x14, +0x23, 0x21, 0x20, 0x15, 0x50, 0x01, 0x09, 0x22, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x02, 0x00, 0x47, 0xff, 0x5b, 0x01, 0xcc, +0x02, 0xb5, 0x00, 0x14, 0x00, 0x25, 0x00, 0x7c, 0x40, 0x1f, +0x23, 0x20, 0x10, 0x00, 0x4d, 0x23, 0x18, 0x0f, 0x00, 0x4d, +0x23, 0x10, 0x0e, 0x00, 0x4d, 0x18, 0x20, 0x10, 0x00, 0x4d, +0x18, 0x28, 0x0f, 0x00, 0x4d, 0x18, 0x10, 0x0e, 0x00, 0x4d, +0x13, 0xb8, 0xff, 0xe8, 0xb4, 0x08, 0x0a, 0x00, 0x4c, 0x02, +0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x02, 0xb8, 0xff, +0xe0, 0xb3, 0x09, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe8, 0x40, +0x1e, 0x08, 0x00, 0x4d, 0x15, 0x82, 0x00, 0x27, 0x1e, 0x0d, +0x08, 0x7f, 0x00, 0x0a, 0x01, 0x08, 0x0a, 0x26, 0x1a, 0x88, +0x10, 0x50, 0x0b, 0x0c, 0x4d, 0x0a, 0x4b, 0x21, 0x88, 0x05, +0x51, 0x00, 0x3f, 0xed, 0x3f, 0x3f, 0x33, 0x3f, 0xed, 0x01, +0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x32, 0x10, 0xde, 0xed, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x25, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, +0x15, 0x23, 0x11, 0x37, 0x15, 0x36, 0x36, 0x33, 0x32, 0x1e, +0x02, 0x07, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0x11, +0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x01, 0xcc, 0x1b, 0x33, +0x4a, 0x2f, 0x25, 0x38, 0x0e, 0x53, 0x53, 0x1d, 0x36, 0x1a, +0x2a, 0x48, 0x35, 0x1e, 0x55, 0x12, 0x21, 0x2d, 0x1a, 0x1a, +0x2f, 0x1a, 0x0e, 0x36, 0x1d, 0x21, 0x2f, 0x1e, 0x0e, 0xe7, +0x35, 0x59, 0x40, 0x24, 0x12, 0x0b, 0xb7, 0x03, 0x4c, 0x0e, +0xf6, 0x0f, 0x0d, 0x21, 0x3f, 0x5a, 0x3a, 0x2b, 0x41, 0x2a, +0x15, 0x12, 0x11, 0xfe, 0xf3, 0x0d, 0x16, 0x1a, 0x2d, 0x3d, +0x00, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0x58, 0x01, 0xcd, +0x02, 0x8f, 0x02, 0x26, 0x00, 0x5c, 0x00, 0x00, 0x01, 0x06, +0x00, 0x83, 0x0f, 0x00, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, +0x10, 0x23, 0x35, 0x20, 0x15, 0x50, 0x02, 0x09, 0x2d, 0x4f, +0x01, 0x09, 0x21, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0xff, 0xff, 0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x03, 0x06, +0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x01, 0x07, 0x00, 0x8a, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, +0x17, 0x18, 0x04, 0x0f, 0x50, 0x02, 0x09, 0x19, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, +0x01, 0xb0, 0x02, 0x7b, 0x02, 0x26, 0x00, 0x44, 0x00, 0x00, +0x01, 0x06, 0x00, 0x8a, 0x09, 0x00, 0x00, 0x10, 0x40, 0x0b, +0x02, 0x0e, 0x31, 0x32, 0x1c, 0x13, 0x50, 0x02, 0x0f, 0x33, +0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x09, 0x00, 0x00, +0x01, 0xeb, 0x03, 0x28, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, +0x01, 0x07, 0x01, 0x61, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x02, 0x00, 0x1b, 0x29, 0x04, 0x0f, 0x50, 0x02, +0x09, 0x17, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb0, 0x02, 0x9d, 0x02, 0x26, +0x00, 0x44, 0x00, 0x00, 0x01, 0x06, 0x01, 0x61, 0x00, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x02, 0x05, 0x35, 0x43, 0x1c, 0x13, +0x50, 0x02, 0x0f, 0x31, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x02, +0x00, 0x09, 0xff, 0x59, 0x01, 0xf0, 0x02, 0x6b, 0x00, 0x22, +0x00, 0x29, 0x00, 0x75, 0x40, 0x3d, 0x16, 0x26, 0x24, 0x23, +0x1d, 0x17, 0x23, 0x17, 0x78, 0x18, 0x1d, 0x14, 0x18, 0x18, +0x1d, 0x15, 0x27, 0x23, 0x1e, 0x14, 0x23, 0x14, 0x78, 0x00, +0x1e, 0x14, 0x00, 0x00, 0x1e, 0x23, 0x00, 0x18, 0x11, 0x0c, +0x06, 0x00, 0x2b, 0x18, 0x2a, 0x08, 0x40, 0x0e, 0x2a, 0x80, +0x15, 0x16, 0x79, 0x27, 0x26, 0x26, 0x18, 0x23, 0x1e, 0x1d, +0x41, 0x17, 0x18, 0x42, 0x14, 0x00, 0x44, 0x00, 0x3f, 0x32, +0x3f, 0x33, 0x3f, 0x33, 0x33, 0x12, 0x39, 0x2f, 0x33, 0xed, +0x32, 0x1a, 0x10, 0xdc, 0x1a, 0xcd, 0x01, 0x10, 0xc6, 0x10, +0xde, 0xde, 0xcc, 0xcd, 0x11, 0x12, 0x39, 0x87, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x10, 0xc4, 0xc4, 0x87, 0x18, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x10, 0x0e, 0xc4, 0x05, 0xc4, 0xc4, 0x31, +0x30, 0x25, 0x06, 0x06, 0x07, 0x06, 0x06, 0x15, 0x14, 0x33, +0x32, 0x36, 0x37, 0x17, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, +0x36, 0x37, 0x27, 0x23, 0x07, 0x23, 0x3e, 0x03, 0x37, 0x33, +0x1e, 0x03, 0x03, 0x06, 0x06, 0x07, 0x33, 0x26, 0x26, 0x01, +0xea, 0x0e, 0x15, 0x0b, 0x0d, 0x0e, 0x24, 0x06, 0x14, 0x0a, +0x07, 0x17, 0x24, 0x33, 0x2c, 0x28, 0x17, 0x26, 0xee, 0x24, +0x54, 0x11, 0x2a, 0x31, 0x36, 0x1e, 0x66, 0x1d, 0x35, 0x2f, +0x29, 0xe0, 0x17, 0x36, 0x18, 0xc8, 0x17, 0x35, 0x02, 0x08, +0x12, 0x0b, 0x0e, 0x15, 0x0d, 0x1a, 0x03, 0x03, 0x36, 0x0a, +0x22, 0x20, 0x1d, 0x32, 0x13, 0xa5, 0xa2, 0x42, 0x9a, 0xa2, +0xa3, 0x4a, 0x4a, 0xa2, 0xa2, 0x99, 0x01, 0xdf, 0x3f, 0xa6, +0x58, 0x5a, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3a, +0xff, 0x59, 0x01, 0xb1, 0x01, 0xdb, 0x00, 0x34, 0x00, 0x43, +0x00, 0x9a, 0xb9, 0x00, 0x3f, 0xff, 0xf0, 0xb3, 0x12, 0x00, +0x4d, 0x3f, 0xb8, 0xff, 0xe8, 0x40, 0x1a, 0x11, 0x00, 0x4d, +0x2c, 0x10, 0x11, 0x12, 0x00, 0x4c, 0x23, 0x18, 0x0b, 0x00, +0x4d, 0x1f, 0x18, 0x0b, 0x00, 0x4d, 0x18, 0x18, 0x0f, 0x11, +0x00, 0x4c, 0x03, 0xb8, 0xff, 0xe0, 0xb3, 0x0c, 0x00, 0x4d, +0x03, 0xb8, 0xff, 0xe8, 0xb4, 0x09, 0x0b, 0x00, 0x4c, 0x03, +0xb8, 0xff, 0xe0, 0x40, 0x2e, 0x08, 0x00, 0x4d, 0x39, 0x19, +0x29, 0x7f, 0x05, 0x16, 0x11, 0x0b, 0x05, 0x45, 0x41, 0x82, +0x21, 0x32, 0x32, 0x21, 0x44, 0x0d, 0x40, 0x13, 0x44, 0x80, +0x3c, 0x89, 0x00, 0x26, 0x10, 0x26, 0x02, 0x08, 0x26, 0x26, +0x00, 0x35, 0x88, 0x1c, 0x51, 0x31, 0x31, 0x2e, 0x88, 0x00, +0x50, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x11, 0x39, +0x2f, 0x5e, 0x5d, 0xed, 0x1a, 0x10, 0xdc, 0x1a, 0xcd, 0x01, +0x10, 0xc6, 0x32, 0x2f, 0x10, 0xed, 0x10, 0xde, 0xdc, 0xcc, +0xcd, 0x10, 0xed, 0x32, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x32, 0x1e, 0x02, +0x15, 0x11, 0x0e, 0x03, 0x15, 0x14, 0x33, 0x32, 0x36, 0x37, +0x17, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37, 0x06, +0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, +0x32, 0x17, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, +0x27, 0x36, 0x36, 0x13, 0x32, 0x36, 0x37, 0x35, 0x26, 0x26, +0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x16, 0xf7, 0x34, 0x47, +0x2c, 0x12, 0x09, 0x1a, 0x18, 0x12, 0x23, 0x06, 0x14, 0x0b, +0x06, 0x16, 0x25, 0x33, 0x2f, 0x1b, 0x1b, 0x11, 0x25, 0x12, +0x26, 0x48, 0x38, 0x22, 0x23, 0x37, 0x47, 0x24, 0x31, 0x2f, +0x09, 0x19, 0x2b, 0x22, 0x2b, 0x40, 0x11, 0x0a, 0x11, 0x4f, +0x35, 0x1f, 0x31, 0x10, 0x10, 0x2d, 0x19, 0x17, 0x2c, 0x22, +0x16, 0x3d, 0x01, 0xdb, 0x1a, 0x2e, 0x42, 0x27, 0xfe, 0xde, +0x06, 0x15, 0x19, 0x1b, 0x0c, 0x1a, 0x03, 0x03, 0x36, 0x0a, +0x24, 0x20, 0x15, 0x2a, 0x1d, 0x02, 0x02, 0x0d, 0x21, 0x3a, +0x2d, 0x28, 0x37, 0x22, 0x0f, 0x0b, 0x17, 0x15, 0x27, 0x20, +0x13, 0x0c, 0x06, 0x44, 0x08, 0x0c, 0xfe, 0x60, 0x04, 0x03, +0x8a, 0x05, 0x06, 0x07, 0x12, 0x1d, 0x16, 0x2d, 0x23, 0x00, +0xff, 0xff, 0x00, 0x2e, 0xff, 0xf3, 0x01, 0xcc, 0x03, 0x3e, +0x02, 0x26, 0x00, 0x26, 0x00, 0x00, 0x01, 0x07, 0x00, 0x8f, +0x00, 0x36, 0x00, 0x89, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x37, +0x23, 0x21, 0x07, 0x00, 0x50, 0x01, 0x0c, 0x22, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x31, 0xff, 0xf5, +0x01, 0xc3, 0x02, 0xb5, 0x02, 0x26, 0x00, 0x46, 0x00, 0x00, +0x01, 0x06, 0x00, 0x8f, 0x2d, 0x00, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x31, 0x24, 0x22, 0x00, 0x1a, 0x50, 0x01, 0x04, 0x23, +0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x2e, 0xff, 0xf3, +0x01, 0xcc, 0x03, 0x3a, 0x02, 0x26, 0x00, 0x26, 0x00, 0x00, +0x01, 0x07, 0x00, 0x69, 0x00, 0x36, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x33, 0x26, 0x22, 0x07, 0x00, 0x50, 0x01, +0x0c, 0x23, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x31, 0xff, 0xf5, 0x01, 0xc3, 0x02, 0xaf, 0x02, 0x26, +0x00, 0x46, 0x00, 0x00, 0x01, 0x06, 0x00, 0x69, 0x32, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x32, 0x27, 0x23, 0x00, 0x1a, +0x50, 0x01, 0x04, 0x24, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x2e, 0xff, 0xf3, 0x01, 0xcc, 0x03, 0x22, 0x02, 0x26, +0x00, 0x26, 0x00, 0x00, 0x01, 0x07, 0x01, 0x62, 0x00, 0x36, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x33, 0x23, 0x29, +0x07, 0x00, 0x50, 0x01, 0x0c, 0x21, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x31, 0xff, 0xf5, 0x01, 0xc3, +0x02, 0x97, 0x02, 0x26, 0x00, 0x46, 0x00, 0x00, 0x01, 0x06, +0x01, 0x62, 0x36, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x36, +0x24, 0x2a, 0x00, 0x1a, 0x50, 0x01, 0x04, 0x22, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x2e, 0xff, 0xf3, 0x01, 0xcc, +0x03, 0x3d, 0x02, 0x26, 0x00, 0x26, 0x00, 0x00, 0x01, 0x07, +0x01, 0x5f, 0x00, 0x36, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x33, 0x21, 0x25, 0x07, 0x00, 0x50, 0x01, 0x0c, 0x26, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x31, +0xff, 0xf5, 0x01, 0xc3, 0x02, 0xb2, 0x02, 0x26, 0x00, 0x46, +0x00, 0x00, 0x01, 0x06, 0x01, 0x5f, 0x32, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x32, 0x22, 0x26, 0x00, 0x1a, 0x50, 0x01, +0x04, 0x27, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x36, +0xff, 0xfb, 0x01, 0xcc, 0x03, 0x3d, 0x02, 0x26, 0x00, 0x27, +0x00, 0x00, 0x01, 0x07, 0x01, 0x5f, 0xff, 0xdd, 0x00, 0x8b, +0x00, 0x13, 0xb9, 0x00, 0x02, 0xff, 0xd6, 0x40, 0x09, 0x1d, +0x21, 0x07, 0x00, 0x50, 0x02, 0x09, 0x22, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x14, 0xff, 0xf5, +0x01, 0xf4, 0x02, 0xb5, 0x00, 0x0e, 0x00, 0x21, 0x00, 0x25, +0x00, 0x6a, 0x40, 0x12, 0x1c, 0x20, 0x0f, 0x10, 0x00, 0x4c, +0x1b, 0x10, 0x0a, 0x00, 0x4d, 0x1b, 0x18, 0x08, 0x09, 0x00, +0x4c, 0x0a, 0xb8, 0xff, 0xd8, 0xb3, 0x0e, 0x00, 0x4d, 0x0a, +0xb8, 0xff, 0xf0, 0xb3, 0x0d, 0x00, 0x4d, 0x05, 0xb8, 0xff, +0xf0, 0x40, 0x23, 0x0e, 0x00, 0x4d, 0x22, 0x25, 0x21, 0x0e, +0x7f, 0x11, 0x27, 0x08, 0x82, 0x19, 0x40, 0x09, 0x0c, 0x48, +0x19, 0x26, 0x24, 0x25, 0x4d, 0x00, 0x03, 0x88, 0x21, 0x1e, +0x50, 0x0b, 0x88, 0x14, 0x51, 0x0f, 0x10, 0x4d, 0x00, 0x3f, +0x33, 0x3f, 0xed, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0xcd, 0x01, +0x10, 0xd6, 0x2b, 0xed, 0x10, 0xde, 0xed, 0x32, 0xde, 0xcd, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x26, +0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x16, 0x33, 0x32, +0x36, 0x37, 0x11, 0x37, 0x11, 0x06, 0x06, 0x23, 0x22, 0x2e, +0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x37, +0x07, 0x23, 0x35, 0x01, 0x19, 0x0b, 0x2c, 0x19, 0x1a, 0x24, +0x17, 0x0b, 0x3c, 0x30, 0x19, 0x23, 0x08, 0x52, 0x18, 0x4b, +0x33, 0x2c, 0x47, 0x32, 0x1c, 0x17, 0x2c, 0x40, 0x28, 0x20, +0x2e, 0x0c, 0xdb, 0x18, 0x37, 0x01, 0x6e, 0x0d, 0x17, 0x1a, +0x2d, 0x3f, 0x24, 0x51, 0x58, 0x06, 0x03, 0x02, 0x5f, 0x0e, +0xfd, 0x58, 0x08, 0x10, 0x22, 0x3f, 0x5a, 0x38, 0x36, 0x59, +0x40, 0x24, 0x12, 0x0a, 0xf6, 0xc7, 0xc7, 0x00, 0xff, 0xff, +0x00, 0x12, 0xff, 0xfb, 0x01, 0xcc, 0x02, 0x71, 0x02, 0x06, +0x00, 0xab, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0xff, 0xf5, +0x01, 0xe0, 0x02, 0xb5, 0x00, 0x1a, 0x00, 0x29, 0x00, 0x7e, +0xb9, 0x00, 0x25, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x25, +0xb8, 0xff, 0xf0, 0xb3, 0x0d, 0x00, 0x4d, 0x20, 0xb8, 0xff, +0xf0, 0x40, 0x42, 0x0e, 0x00, 0x4d, 0x15, 0x18, 0x0f, 0x10, +0x00, 0x4c, 0x14, 0x10, 0x09, 0x00, 0x4d, 0x14, 0x20, 0x08, +0x00, 0x4d, 0x10, 0x20, 0x08, 0x00, 0x4d, 0x1b, 0x03, 0x01, +0x00, 0x7f, 0x07, 0x06, 0x09, 0x2b, 0x23, 0x82, 0x12, 0x2a, +0x09, 0x00, 0x86, 0x06, 0x03, 0x03, 0x05, 0x1e, 0x88, 0x41, +0x17, 0x01, 0x00, 0x17, 0x10, 0x17, 0x20, 0x17, 0x03, 0x08, +0x17, 0x50, 0x26, 0x88, 0x0d, 0x51, 0x04, 0x05, 0x4d, 0x00, +0x3f, 0x33, 0x3f, 0xed, 0x3f, 0x5e, 0x5d, 0x5d, 0xed, 0x12, +0x39, 0x2f, 0x33, 0xed, 0x32, 0x01, 0x10, 0xd6, 0xed, 0x10, +0xde, 0x32, 0xcd, 0xfd, 0xcd, 0x33, 0x33, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x23, 0x35, 0x33, +0x35, 0x37, 0x15, 0x33, 0x15, 0x23, 0x11, 0x06, 0x06, 0x23, +0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, +0x17, 0x15, 0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, +0x16, 0x33, 0x32, 0x36, 0x37, 0x01, 0x4c, 0xb1, 0xb1, 0x52, +0x42, 0x42, 0x1a, 0x50, 0x36, 0x30, 0x4f, 0x38, 0x1f, 0x1a, +0x32, 0x47, 0x2c, 0x23, 0x34, 0x0e, 0x0e, 0x31, 0x1c, 0x1f, +0x2c, 0x1c, 0x0d, 0x48, 0x39, 0x1d, 0x28, 0x09, 0x02, 0x24, +0x3e, 0x45, 0x0e, 0x53, 0x3e, 0xfd, 0xe9, 0x08, 0x10, 0x22, +0x3f, 0x5a, 0x38, 0x36, 0x59, 0x40, 0x24, 0x12, 0x0a, 0x51, +0x0d, 0x17, 0x1a, 0x2d, 0x3f, 0x24, 0x51, 0x58, 0x06, 0x03, +0x00, 0x00, 0xff, 0xff, 0x00, 0x5b, 0x00, 0x00, 0x01, 0xcc, +0x03, 0x06, 0x02, 0x26, 0x00, 0x28, 0x00, 0x00, 0x01, 0x07, +0x00, 0x8a, 0x00, 0x12, 0x00, 0x8b, 0x00, 0x13, 0xb9, 0x00, +0x01, 0xff, 0xf9, 0x40, 0x09, 0x0c, 0x0d, 0x00, 0x0a, 0x50, +0x01, 0x01, 0x0e, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xc7, 0x02, 0x7b, +0x02, 0x26, 0x00, 0x48, 0x00, 0x00, 0x01, 0x06, 0x00, 0x8a, +0x09, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x0b, 0x22, 0x23, +0x13, 0x02, 0x50, 0x02, 0x00, 0x24, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x5b, 0x00, 0x00, 0x01, 0xcc, 0x03, 0x28, +0x02, 0x26, 0x00, 0x28, 0x00, 0x00, 0x01, 0x07, 0x01, 0x61, +0x00, 0x12, 0x00, 0x8b, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, +0xf9, 0x40, 0x09, 0x10, 0x1e, 0x00, 0x0a, 0x50, 0x01, 0x01, +0x0c, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xc7, 0x02, 0x9d, 0x02, 0x26, +0x00, 0x48, 0x00, 0x00, 0x01, 0x06, 0x01, 0x61, 0x09, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x02, 0x0b, 0x26, 0x34, 0x13, 0x02, +0x50, 0x02, 0x00, 0x22, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x5b, 0x00, 0x00, 0x01, 0xcc, 0x03, 0x22, 0x02, 0x26, +0x00, 0x28, 0x00, 0x00, 0x01, 0x07, 0x01, 0x62, 0x00, 0x16, +0x00, 0x8b, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xfd, 0x40, +0x09, 0x0e, 0x14, 0x00, 0x0a, 0x50, 0x01, 0x01, 0x0c, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x28, +0xff, 0xf5, 0x01, 0xc7, 0x02, 0x97, 0x02, 0x26, 0x00, 0x48, +0x00, 0x00, 0x01, 0x06, 0x01, 0x62, 0x09, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x02, 0x0b, 0x24, 0x2a, 0x13, 0x02, 0x50, 0x02, +0x00, 0x22, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x01, 0x00, 0x5b, +0xff, 0x59, 0x01, 0xcf, 0x02, 0x6b, 0x00, 0x21, 0x00, 0x4a, +0x40, 0x25, 0x10, 0x0b, 0x05, 0x21, 0x1e, 0x1e, 0x1a, 0x1a, +0x16, 0x21, 0x23, 0x1c, 0x20, 0x73, 0x17, 0x22, 0x1f, 0x79, +0x1c, 0x1c, 0x20, 0x1b, 0x79, 0x18, 0x41, 0x20, 0x20, 0x21, +0x79, 0x17, 0x07, 0x40, 0x0d, 0x80, 0x00, 0x17, 0x42, 0x00, +0x3f, 0x33, 0x1a, 0xdc, 0x1a, 0xcd, 0x10, 0xed, 0x32, 0x2f, +0x3f, 0xed, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xd6, 0xed, +0x32, 0x10, 0xce, 0x32, 0x32, 0x2f, 0x32, 0x2f, 0x10, 0xdc, +0xcc, 0xcd, 0x31, 0x30, 0x25, 0x06, 0x07, 0x06, 0x06, 0x15, +0x14, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x23, 0x22, 0x26, +0x35, 0x34, 0x36, 0x37, 0x36, 0x36, 0x37, 0x21, 0x11, 0x21, +0x15, 0x21, 0x15, 0x33, 0x15, 0x23, 0x15, 0x21, 0x01, 0xcc, +0x19, 0x17, 0x0d, 0x0e, 0x24, 0x06, 0x14, 0x0a, 0x06, 0x16, +0x24, 0x33, 0x2c, 0x15, 0x10, 0x08, 0x0e, 0x05, 0xfe, 0xe5, +0x01, 0x5b, 0xfe, 0xf7, 0xe8, 0xe8, 0x01, 0x1f, 0x02, 0x0e, +0x17, 0x0e, 0x15, 0x0d, 0x1a, 0x03, 0x03, 0x36, 0x0a, 0x22, +0x20, 0x15, 0x26, 0x10, 0x08, 0x0e, 0x04, 0x02, 0x6b, 0x46, +0xbe, 0x46, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, +0xff, 0x59, 0x01, 0xc7, 0x01, 0xdb, 0x00, 0x2e, 0x00, 0x37, +0x00, 0xb7, 0xb9, 0x00, 0x34, 0xff, 0xe8, 0x40, 0x1d, 0x0e, +0x00, 0x4d, 0x2d, 0x10, 0x10, 0x00, 0x4d, 0x2d, 0x18, 0x0f, +0x00, 0x4d, 0x2d, 0x10, 0x08, 0x00, 0x4d, 0x28, 0x10, 0x10, +0x00, 0x4d, 0x27, 0x20, 0x10, 0x00, 0x4d, 0x07, 0xb8, 0xff, +0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xe0, 0xb4, +0x0c, 0x0d, 0x00, 0x4c, 0x02, 0xb8, 0xff, 0xe0, 0xb3, 0x11, +0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe0, 0xb3, 0x09, 0x00, 0x4d, +0x02, 0xb8, 0xff, 0xe8, 0xb3, 0x08, 0x00, 0x4d, 0x01, 0xb8, +0xff, 0xd0, 0xb3, 0x12, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xe8, +0xb3, 0x11, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xd8, 0x40, 0x27, +0x0f, 0x10, 0x00, 0x4c, 0x1d, 0x18, 0x12, 0x22, 0x0c, 0x0c, +0x2f, 0x82, 0x03, 0x39, 0x37, 0x05, 0x82, 0x2a, 0x38, 0x14, +0x40, 0x1a, 0x38, 0x80, 0x05, 0x86, 0x37, 0x37, 0x00, 0x0b, +0x0b, 0x08, 0x88, 0x25, 0x51, 0x32, 0x88, 0x00, 0x50, 0x00, +0x3f, 0xed, 0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x2f, 0xed, +0x1a, 0x10, 0xdc, 0x1a, 0xcd, 0x01, 0x10, 0xd6, 0xed, 0x32, +0x10, 0xde, 0xed, 0x33, 0x2f, 0x33, 0xde, 0xcc, 0xcd, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x32, 0x16, 0x15, 0x15, +0x21, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x06, +0x07, 0x06, 0x06, 0x15, 0x14, 0x33, 0x32, 0x36, 0x37, 0x17, +0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, +0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, +0x17, 0x36, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x07, 0x01, 0x03, +0x5e, 0x66, 0xfe, 0xb4, 0x05, 0x55, 0x4d, 0x2c, 0x3e, 0x10, +0x0b, 0x0a, 0x23, 0x0f, 0x0d, 0x0f, 0x24, 0x06, 0x14, 0x0a, +0x06, 0x16, 0x24, 0x33, 0x30, 0x17, 0x10, 0x09, 0x09, 0x08, +0x10, 0x08, 0x3c, 0x5b, 0x3c, 0x1e, 0x26, 0x3e, 0x4e, 0x99, +0x01, 0x3f, 0x33, 0x1d, 0x2f, 0x22, 0x14, 0x03, 0x01, 0xdb, +0x75, 0x77, 0x1d, 0x48, 0x4b, 0x0e, 0x08, 0x46, 0x08, 0x19, +0x11, 0x0e, 0x15, 0x0d, 0x1a, 0x03, 0x03, 0x36, 0x0a, 0x24, +0x20, 0x15, 0x24, 0x10, 0x0a, 0x07, 0x01, 0x01, 0x25, 0x40, +0x59, 0x34, 0x3e, 0x5c, 0x3c, 0x1e, 0xc6, 0x39, 0x47, 0x16, +0x24, 0x2e, 0x18, 0x00, 0xff, 0xff, 0x00, 0x5b, 0x00, 0x00, +0x01, 0xcc, 0x03, 0x3d, 0x02, 0x26, 0x00, 0x28, 0x00, 0x00, +0x01, 0x07, 0x01, 0x5f, 0x00, 0x1b, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x01, 0x0c, 0x10, 0x00, 0x0a, 0x50, 0x01, +0x01, 0x11, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xc7, 0x02, 0xb2, 0x02, 0x26, +0x00, 0x48, 0x00, 0x00, 0x01, 0x06, 0x01, 0x5f, 0x09, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x02, 0x0b, 0x22, 0x26, 0x13, 0x02, +0x50, 0x02, 0x00, 0x27, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x2e, 0xff, 0xf3, 0x01, 0xc7, 0x03, 0x3a, 0x02, 0x26, +0x00, 0x2a, 0x00, 0x00, 0x01, 0x07, 0x00, 0x69, 0x00, 0x2d, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x2c, 0x2b, 0x27, +0x09, 0x01, 0x50, 0x01, 0x0e, 0x28, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x28, 0xff, 0x58, 0x01, 0xad, +0x02, 0xaf, 0x02, 0x26, 0x00, 0x4a, 0x00, 0x00, 0x01, 0x06, +0x00, 0x69, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x0f, +0x33, 0x2f, 0x07, 0x10, 0x50, 0x02, 0x0c, 0x30, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x2e, 0xff, 0xf3, 0x01, 0xc7, +0x03, 0x28, 0x02, 0x26, 0x00, 0x2a, 0x00, 0x00, 0x01, 0x07, +0x01, 0x61, 0x00, 0x36, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x35, 0x2a, 0x38, 0x09, 0x01, 0x50, 0x01, 0x0e, 0x26, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x28, +0xff, 0x58, 0x01, 0xad, 0x02, 0x9d, 0x02, 0x26, 0x00, 0x4a, +0x00, 0x00, 0x01, 0x06, 0x01, 0x61, 0x00, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x02, 0x0f, 0x32, 0x40, 0x07, 0x10, 0x50, 0x02, +0x0c, 0x2e, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x2e, +0xff, 0xf3, 0x01, 0xc7, 0x03, 0x22, 0x02, 0x26, 0x00, 0x2a, +0x00, 0x00, 0x01, 0x07, 0x01, 0x62, 0x00, 0x2d, 0x00, 0x8b, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x2c, 0x28, 0x2e, 0x09, 0x01, +0x50, 0x01, 0x0e, 0x26, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x28, 0xff, 0x58, 0x01, 0xad, 0x02, 0x97, +0x02, 0x26, 0x00, 0x4a, 0x00, 0x00, 0x01, 0x06, 0x01, 0x62, +0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x0f, 0x30, 0x36, +0x07, 0x10, 0x50, 0x02, 0x0c, 0x2e, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x2e, 0xff, 0x56, 0x01, 0xc7, 0x02, 0x79, +0x02, 0x26, 0x00, 0x2a, 0x00, 0x00, 0x01, 0x06, 0x01, 0xc3, +0x12, 0x00, 0x00, 0x0a, 0xb6, 0x01, 0x0d, 0x2f, 0x29, 0x09, +0x01, 0x50, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x28, +0xff, 0x58, 0x01, 0xad, 0x02, 0xb9, 0x02, 0x26, 0x00, 0x4a, +0x00, 0x00, 0x01, 0x06, 0x01, 0xc4, 0x16, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x02, 0x25, 0x30, 0x38, 0x07, 0x10, 0x50, 0x02, +0x0c, 0x2e, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x2d, +0x00, 0x00, 0x01, 0xc7, 0x03, 0x3a, 0x02, 0x26, 0x00, 0x2b, +0x00, 0x00, 0x01, 0x07, 0x00, 0x69, 0x00, 0x00, 0x00, 0x8b, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x11, 0x0d, 0x07, 0x01, +0x50, 0x01, 0x00, 0x0e, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0x00, 0x02, 0x00, 0x2c, 0x00, 0x00, 0x01, 0xb0, 0x03, 0x3e, +0x00, 0x15, 0x00, 0x1b, 0x00, 0x8a, 0x40, 0x15, 0x10, 0x20, +0x12, 0x00, 0x4d, 0x10, 0x28, 0x11, 0x00, 0x4d, 0x10, 0x18, +0x10, 0x00, 0x4d, 0x10, 0x10, 0x0f, 0x00, 0x4d, 0x09, 0xb8, +0xff, 0xd8, 0xb3, 0x08, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xe8, +0xb3, 0x0a, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xd8, 0x40, 0x2e, +0x09, 0x00, 0x4d, 0x0d, 0x7f, 0x0c, 0x1d, 0x40, 0x1a, 0x1b, +0x18, 0x17, 0x60, 0x16, 0x19, 0x19, 0x1c, 0x03, 0x15, 0x7f, +0x00, 0x00, 0x01, 0x08, 0x00, 0x1c, 0x11, 0x88, 0x06, 0x50, +0x1b, 0x17, 0x40, 0x19, 0x16, 0x18, 0x80, 0x1a, 0x1a, 0x18, +0x01, 0x02, 0x4d, 0x0d, 0x00, 0x4a, 0x00, 0x3f, 0x32, 0x3f, +0x33, 0xce, 0x32, 0x2f, 0x1a, 0x10, 0xcd, 0x32, 0x1a, 0xcd, +0x32, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, +0x11, 0x33, 0x19, 0x2f, 0x33, 0x1a, 0xcd, 0x32, 0xcd, 0x32, +0x1a, 0x18, 0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x33, 0x11, 0x37, 0x15, 0x36, 0x36, +0x33, 0x32, 0x1e, 0x02, 0x15, 0x11, 0x23, 0x35, 0x34, 0x26, +0x23, 0x22, 0x06, 0x07, 0x11, 0x11, 0x17, 0x07, 0x27, 0x07, +0x27, 0x47, 0x53, 0x14, 0x32, 0x18, 0x35, 0x47, 0x2a, 0x12, +0x52, 0x30, 0x3e, 0x1a, 0x31, 0x0b, 0x6e, 0x1a, 0x54, 0x54, +0x1a, 0x02, 0x9d, 0x0e, 0xe2, 0x08, 0x09, 0x1f, 0x38, 0x4e, +0x2f, 0xfe, 0xfa, 0xf4, 0x56, 0x47, 0x0b, 0x05, 0xfe, 0x7f, +0x03, 0x3e, 0x55, 0x28, 0x37, 0x37, 0x28, 0x00, 0x00, 0x02, +0x00, 0x12, 0x00, 0x00, 0x01, 0xe2, 0x02, 0x6b, 0x00, 0x13, +0x00, 0x17, 0x00, 0x55, 0x40, 0x2c, 0x17, 0x0e, 0x02, 0x73, +0x13, 0x11, 0x01, 0x19, 0x16, 0x0d, 0x05, 0x73, 0x0a, 0x08, +0x00, 0x06, 0x01, 0x06, 0x18, 0x15, 0x00, 0x07, 0x0a, 0x11, +0x0d, 0x0a, 0x04, 0x79, 0x16, 0x00, 0x16, 0x01, 0x08, 0x0a, +0x16, 0x0a, 0x16, 0x06, 0x0f, 0x0b, 0x41, 0x02, 0x06, 0x42, +0x00, 0x3f, 0x33, 0x3f, 0x33, 0x12, 0x39, 0x39, 0x2f, 0x2f, +0x5e, 0x5d, 0x10, 0xed, 0x11, 0x33, 0x33, 0x10, 0xcd, 0x32, +0x32, 0x01, 0x10, 0xd6, 0x5d, 0xce, 0x33, 0xed, 0x32, 0x32, +0x10, 0xde, 0x32, 0xce, 0xed, 0x32, 0x32, 0x31, 0x30, 0x01, +0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, 0x33, +0x35, 0x33, 0x15, 0x33, 0x35, 0x33, 0x15, 0x33, 0x15, 0x23, +0x23, 0x15, 0x33, 0x01, 0xad, 0x53, 0xc0, 0x53, 0x35, 0x35, +0x53, 0xc0, 0x53, 0x35, 0x88, 0xc0, 0xc0, 0x01, 0xd4, 0xfe, +0x2c, 0x01, 0x20, 0xfe, 0xe0, 0x01, 0xd4, 0x3d, 0x5a, 0x5a, +0x5a, 0x5a, 0x3d, 0x6e, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, +0x01, 0xb0, 0x02, 0xb5, 0x00, 0x1d, 0x00, 0x87, 0xb6, 0x15, +0x18, 0x0f, 0x10, 0x00, 0x4c, 0x0e, 0xb8, 0xff, 0xd8, 0xb3, +0x12, 0x00, 0x4d, 0x0e, 0xb8, 0xff, 0xf0, 0xb3, 0x11, 0x00, +0x4d, 0x0e, 0xb8, 0xff, 0xd8, 0xb3, 0x09, 0x00, 0x4d, 0x0e, +0xb8, 0xff, 0xe0, 0xb3, 0x08, 0x00, 0x4d, 0x0d, 0xb8, 0xff, +0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x0d, 0xb8, 0xff, 0xe0, 0x40, +0x2d, 0x0a, 0x00, 0x4d, 0x12, 0x7f, 0x11, 0x1f, 0x08, 0x06, +0x04, 0x1a, 0x7f, 0x1d, 0x01, 0x00, 0x1b, 0x01, 0x1b, 0x1e, +0x12, 0x1b, 0x4a, 0x07, 0x1c, 0x04, 0x01, 0x01, 0x03, 0x16, +0x88, 0x00, 0x0b, 0x10, 0x0b, 0x20, 0x0b, 0x40, 0x0b, 0x04, +0x08, 0x0b, 0x50, 0x02, 0x03, 0x4d, 0x00, 0x3f, 0x33, 0x3f, +0x5e, 0x5d, 0xed, 0x12, 0x39, 0x2f, 0x33, 0xcd, 0x32, 0x3f, +0x33, 0x01, 0x10, 0xd6, 0x5d, 0x32, 0xce, 0xfd, 0x32, 0xcc, +0x33, 0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x13, 0x33, 0x35, 0x37, 0x15, 0x33, 0x15, +0x23, 0x15, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x11, +0x23, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x11, 0x23, +0x11, 0x23, 0x14, 0x42, 0x52, 0xa2, 0xa2, 0x13, 0x31, 0x16, +0x31, 0x43, 0x28, 0x12, 0x52, 0x2d, 0x37, 0x17, 0x31, 0x0a, +0x52, 0x42, 0x02, 0x62, 0x45, 0x0e, 0x53, 0x3e, 0x5b, 0x08, +0x09, 0x1f, 0x38, 0x4e, 0x2f, 0xfe, 0xfa, 0xf4, 0x56, 0x47, +0x0b, 0x05, 0xfe, 0x7f, 0x02, 0x24, 0x00, 0x00, 0xff, 0xff, +0x00, 0x59, 0x00, 0x00, 0x01, 0x9b, 0x03, 0x1c, 0x02, 0x26, +0x00, 0x2c, 0x00, 0x00, 0x01, 0x07, 0x00, 0x75, 0x00, 0x00, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x1a, 0x0c, +0x04, 0x02, 0x50, 0x01, 0x09, 0x19, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, +0x02, 0x91, 0x02, 0x26, 0x01, 0x0c, 0x00, 0x00, 0x01, 0x06, +0x00, 0x75, 0xdd, 0x00, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, +0xdb, 0x40, 0x09, 0x24, 0x16, 0x01, 0x0b, 0x50, 0x01, 0x02, +0x23, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, 0x00, 0x59, +0x00, 0x00, 0x01, 0x9b, 0x03, 0x06, 0x02, 0x26, 0x00, 0x2c, +0x00, 0x00, 0x01, 0x07, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x8b, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x0c, 0x0d, 0x04, 0x02, +0x50, 0x01, 0x09, 0x0e, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0x7b, +0x02, 0x26, 0x01, 0x0c, 0x00, 0x00, 0x01, 0x06, 0x00, 0x8a, +0xdd, 0x00, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xdb, 0x40, +0x09, 0x16, 0x17, 0x01, 0x0b, 0x50, 0x01, 0x02, 0x18, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, 0x00, 0x59, 0x00, 0x00, +0x01, 0x9b, 0x03, 0x28, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, +0x01, 0x07, 0x01, 0x61, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x00, 0x10, 0x1e, 0x04, 0x02, 0x50, 0x01, +0x09, 0x0c, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0x9d, 0x02, 0x26, +0x01, 0x0c, 0x00, 0x00, 0x01, 0x06, 0x01, 0x61, 0xdd, 0x00, +0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xdb, 0x40, 0x09, 0x1a, +0x28, 0x01, 0x0b, 0x50, 0x01, 0x02, 0x16, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0x00, 0x01, 0x00, 0x59, 0xff, 0x59, 0x01, 0x9b, +0x02, 0x6b, 0x00, 0x21, 0x00, 0x41, 0x40, 0x20, 0x1e, 0x1b, +0x1c, 0x19, 0x14, 0x0f, 0x09, 0x21, 0x02, 0x04, 0x01, 0x73, +0x1c, 0x1c, 0x23, 0x22, 0x0b, 0x40, 0x11, 0x22, 0x80, 0x00, +0x1d, 0x79, 0x1f, 0x41, 0x01, 0x1c, 0x79, 0x04, 0x19, 0x42, +0x00, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0xed, 0x32, 0x1a, 0x10, +0xdc, 0x1a, 0xcd, 0x01, 0x11, 0x12, 0x39, 0x2f, 0xfd, 0x32, +0xcd, 0x32, 0xdc, 0xcc, 0xcd, 0x32, 0x10, 0xcd, 0x32, 0x31, +0x30, 0x01, 0x11, 0x33, 0x15, 0x23, 0x06, 0x07, 0x06, 0x06, +0x15, 0x14, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x23, 0x22, +0x26, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, 0x23, 0x35, 0x33, +0x11, 0x23, 0x35, 0x21, 0x15, 0x01, 0x23, 0x78, 0x77, 0x10, +0x17, 0x0d, 0x10, 0x24, 0x06, 0x14, 0x0a, 0x07, 0x17, 0x24, +0x33, 0x2f, 0x16, 0x10, 0x0d, 0x0b, 0x77, 0x78, 0x78, 0x01, +0x42, 0x02, 0x25, 0xfe, 0x21, 0x46, 0x0c, 0x17, 0x0e, 0x15, +0x0d, 0x1a, 0x03, 0x03, 0x36, 0x0a, 0x24, 0x20, 0x15, 0x25, +0x11, 0x10, 0x08, 0x46, 0x01, 0xdf, 0x46, 0x46, 0x00, 0x00, +0x00, 0x02, 0x00, 0x36, 0xff, 0x59, 0x01, 0xc2, 0x02, 0x9e, +0x00, 0x27, 0x00, 0x33, 0x00, 0x48, 0x40, 0x26, 0x25, 0x18, +0x09, 0x0d, 0x00, 0x4c, 0x31, 0x2b, 0x2b, 0x27, 0x1c, 0x17, +0x11, 0x22, 0x0b, 0x04, 0x7f, 0x01, 0x27, 0x27, 0x35, 0x34, +0x13, 0x40, 0x19, 0x34, 0x80, 0x0b, 0x07, 0x88, 0x22, 0x51, +0x2e, 0x28, 0x00, 0x85, 0x03, 0x49, 0x00, 0x3f, 0xed, 0xde, +0xcd, 0x3f, 0xed, 0x33, 0x1a, 0x10, 0xdc, 0x1a, 0xcd, 0x01, +0x11, 0x12, 0x39, 0x2f, 0xce, 0xfd, 0xdc, 0x32, 0xde, 0xcc, +0xcd, 0x11, 0x33, 0x2f, 0xcd, 0x31, 0x30, 0x2b, 0x13, 0x23, +0x35, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, +0x06, 0x06, 0x07, 0x06, 0x06, 0x15, 0x14, 0x33, 0x32, 0x36, +0x37, 0x17, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37, +0x36, 0x36, 0x37, 0x22, 0x2e, 0x02, 0x35, 0x13, 0x22, 0x26, +0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0xbc, +0x86, 0xd8, 0x26, 0x26, 0x1d, 0x31, 0x0e, 0x0c, 0x1e, 0x17, +0x07, 0x0d, 0x0f, 0x23, 0x06, 0x15, 0x0a, 0x06, 0x16, 0x25, +0x33, 0x2f, 0x18, 0x10, 0x04, 0x08, 0x04, 0x2c, 0x3a, 0x23, +0x0e, 0x15, 0x1a, 0x26, 0x26, 0x1a, 0x1b, 0x25, 0x25, 0x01, +0x8b, 0x45, 0xfe, 0xe3, 0x45, 0x2f, 0x0e, 0x08, 0x46, 0x15, +0x15, 0x08, 0x0e, 0x15, 0x0d, 0x1a, 0x03, 0x03, 0x36, 0x0a, +0x24, 0x20, 0x15, 0x25, 0x11, 0x03, 0x08, 0x02, 0x18, 0x30, +0x47, 0x2f, 0x01, 0x65, 0x24, 0x1f, 0x1f, 0x24, 0x24, 0x1f, +0x1f, 0x24, 0x00, 0x00, 0xff, 0xff, 0x00, 0x59, 0x00, 0x00, +0x01, 0x9b, 0x03, 0x22, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, +0x01, 0x07, 0x01, 0x62, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x00, 0x0e, 0x14, 0x04, 0x02, 0x50, 0x01, +0x09, 0x0c, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x01, +0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x01, 0xd0, 0x00, 0x15, +0x00, 0x28, 0x40, 0x16, 0x13, 0x20, 0x09, 0x0d, 0x00, 0x4c, +0x0b, 0x04, 0x7f, 0x01, 0x15, 0x15, 0x17, 0x16, 0x07, 0x88, +0x10, 0x51, 0x00, 0x85, 0x03, 0x49, 0x00, 0x3f, 0xed, 0x3f, +0xed, 0x01, 0x11, 0x12, 0x39, 0x2f, 0xce, 0xfd, 0xcc, 0x31, +0x30, 0x2b, 0x13, 0x23, 0x35, 0x33, 0x11, 0x14, 0x16, 0x33, +0x32, 0x36, 0x37, 0x17, 0x0e, 0x03, 0x23, 0x22, 0x2e, 0x02, +0x35, 0xbc, 0x86, 0xd8, 0x26, 0x26, 0x1d, 0x31, 0x0e, 0x0c, +0x06, 0x16, 0x1d, 0x23, 0x13, 0x2c, 0x3a, 0x23, 0x0e, 0x01, +0x8b, 0x45, 0xfe, 0xe3, 0x45, 0x2f, 0x0e, 0x08, 0x46, 0x03, +0x09, 0x08, 0x06, 0x18, 0x30, 0x47, 0x2f, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0x9e, +0x02, 0x06, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x2a, +0xff, 0xf3, 0x01, 0xd7, 0x02, 0x6b, 0x00, 0x03, 0x00, 0x13, +0x00, 0x28, 0x40, 0x14, 0x0b, 0x0b, 0x00, 0x12, 0x73, 0x05, +0x15, 0x00, 0x73, 0x01, 0x14, 0x0f, 0x7c, 0x08, 0x46, 0x13, +0x02, 0x41, 0x01, 0x42, 0x00, 0x3f, 0x3f, 0x33, 0x3f, 0xed, +0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, +0x31, 0x30, 0x33, 0x23, 0x11, 0x33, 0x21, 0x11, 0x14, 0x06, +0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, +0x35, 0x11, 0x7c, 0x52, 0x52, 0x01, 0x5b, 0x57, 0x4b, 0x23, +0x46, 0x1b, 0x21, 0x11, 0x2f, 0x22, 0x27, 0x29, 0x02, 0x6b, +0xfe, 0x40, 0x62, 0x56, 0x19, 0x19, 0x43, 0x13, 0x1b, 0x33, +0x3f, 0x01, 0xbf, 0x00, 0x00, 0x04, 0x00, 0x59, 0xff, 0x59, +0x01, 0x9c, 0x02, 0x97, 0x00, 0x03, 0x00, 0x13, 0x00, 0x1f, +0x00, 0x2b, 0x00, 0x47, 0x40, 0x27, 0x1d, 0x83, 0x17, 0x17, +0x0e, 0x7f, 0x11, 0x2d, 0x29, 0x83, 0x23, 0x23, 0x00, 0x07, +0x07, 0x03, 0x7f, 0x00, 0x00, 0x01, 0x08, 0x00, 0x2c, 0x1a, +0x8a, 0x14, 0x0f, 0x49, 0x0b, 0x88, 0x04, 0x4b, 0x26, 0x8a, +0x20, 0x01, 0x49, 0x00, 0x4a, 0x00, 0x3f, 0x3f, 0xde, 0xed, +0x3f, 0xed, 0x3f, 0xde, 0xed, 0x01, 0x10, 0xd6, 0x5e, 0x5d, +0xed, 0x33, 0x2f, 0x11, 0x33, 0x2f, 0xed, 0x10, 0xde, 0xed, +0x32, 0x2f, 0xed, 0x31, 0x30, 0x33, 0x11, 0x33, 0x11, 0x17, +0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, +0x11, 0x33, 0x11, 0x14, 0x06, 0x13, 0x22, 0x26, 0x35, 0x34, +0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, +0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x6c, +0x52, 0x2c, 0x0b, 0x22, 0x0b, 0x0a, 0x09, 0x17, 0x0a, 0x2c, +0x25, 0x52, 0x51, 0x28, 0x19, 0x23, 0x23, 0x19, 0x19, 0x23, +0x23, 0xe4, 0x19, 0x23, 0x23, 0x19, 0x19, 0x23, 0x23, 0x01, +0xd0, 0xfe, 0x30, 0xa7, 0x05, 0x05, 0x44, 0x03, 0x04, 0x35, +0x33, 0x01, 0xc8, 0xfe, 0x39, 0x5a, 0x56, 0x02, 0xc5, 0x21, +0x1c, 0x1b, 0x21, 0x21, 0x1b, 0x1c, 0x21, 0x21, 0x1c, 0x1b, +0x21, 0x21, 0x1b, 0x1c, 0x21, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x36, 0xff, 0xf3, 0x01, 0xa5, 0x03, 0x3a, 0x02, 0x26, +0x00, 0x2d, 0x00, 0x00, 0x01, 0x07, 0x00, 0x69, 0x00, 0x32, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x3f, 0x19, 0x15, +0x0b, 0x02, 0x50, 0x01, 0x01, 0x16, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x47, 0xff, 0x56, 0x01, 0x87, +0x02, 0xaf, 0x02, 0x26, 0x01, 0x5d, 0x00, 0x00, 0x01, 0x06, +0x00, 0x69, 0x14, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x2a, +0x19, 0x15, 0x0b, 0x02, 0x50, 0x01, 0x01, 0x16, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x40, 0xff, 0x56, 0x01, 0xeb, +0x02, 0x6b, 0x02, 0x26, 0x00, 0x2e, 0x00, 0x00, 0x01, 0x06, +0x01, 0xc3, 0xef, 0x00, 0x00, 0x0d, 0xb9, 0x00, 0x01, 0xff, +0xcf, 0xb4, 0x20, 0x1a, 0x10, 0x08, 0x50, 0x2b, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x47, 0xff, 0x56, 0x01, 0xde, +0x02, 0xb5, 0x02, 0x26, 0x00, 0x4e, 0x00, 0x00, 0x01, 0x06, +0x01, 0xc3, 0xef, 0x00, 0x00, 0x0d, 0xb9, 0x00, 0x01, 0xff, +0xd2, 0xb4, 0x20, 0x1a, 0x0d, 0x05, 0x50, 0x2b, 0x34, 0x00, +0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x02, 0x06, +0x02, 0xa7, 0x00, 0x0d, 0x00, 0x22, 0x00, 0x69, 0x40, 0x37, +0x1f, 0x0e, 0x11, 0x0e, 0x78, 0x22, 0x1f, 0x14, 0x22, 0x22, +0x1f, 0x17, 0x11, 0x16, 0x11, 0x78, 0x1a, 0x17, 0x14, 0x1a, +0x1a, 0x17, 0x06, 0x07, 0x0d, 0x00, 0x00, 0x0e, 0x0e, 0x16, +0x24, 0x1f, 0x1a, 0x73, 0x1c, 0x23, 0x11, 0x1f, 0x1a, 0x11, +0x11, 0x1c, 0x1d, 0x41, 0x1c, 0x42, 0x17, 0x16, 0x42, 0x0c, +0x06, 0x06, 0x22, 0x0e, 0x41, 0x00, 0x3f, 0x33, 0x33, 0x2f, +0xcd, 0x3f, 0x33, 0x3f, 0x3f, 0x12, 0x39, 0x19, 0x2f, 0x33, +0x33, 0x01, 0x18, 0x2f, 0x10, 0xd6, 0xed, 0x32, 0x10, 0xce, +0x32, 0x2f, 0x33, 0x2f, 0xdd, 0xde, 0xcd, 0x87, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x04, 0x7d, +0xc4, 0x31, 0x30, 0x01, 0x34, 0x34, 0x37, 0x36, 0x36, 0x37, +0x17, 0x06, 0x06, 0x15, 0x14, 0x16, 0x17, 0x27, 0x06, 0x06, +0x07, 0x1e, 0x03, 0x17, 0x23, 0x26, 0x26, 0x27, 0x11, 0x23, +0x11, 0x33, 0x11, 0x36, 0x36, 0x37, 0x01, 0x87, 0x01, 0x03, +0x22, 0x19, 0x40, 0x13, 0x13, 0x01, 0x01, 0x5d, 0x26, 0x50, +0x33, 0x1f, 0x34, 0x2d, 0x2a, 0x15, 0x5d, 0x22, 0x57, 0x33, +0x52, 0x52, 0x2a, 0x4d, 0x1e, 0x01, 0xd0, 0x0b, 0x12, 0x09, +0x2e, 0x5b, 0x28, 0x15, 0x28, 0x4f, 0x23, 0x09, 0x14, 0x0b, +0x9b, 0x4d, 0x87, 0x4d, 0x1e, 0x46, 0x51, 0x5e, 0x37, 0x5d, +0x9e, 0x2d, 0xfe, 0xd8, 0x02, 0x6b, 0xfe, 0xec, 0x43, 0x92, +0x3f, 0x00, 0x00, 0x01, 0x00, 0x47, 0x00, 0x00, 0x01, 0xde, +0x01, 0xd0, 0x00, 0x16, 0x00, 0x65, 0x40, 0x36, 0x06, 0x00, +0x05, 0x00, 0x81, 0x0b, 0x06, 0x14, 0x0b, 0x00, 0x14, 0x0b, +0x06, 0x13, 0x10, 0x00, 0x14, 0x13, 0x14, 0x00, 0x81, 0x10, +0x13, 0x14, 0x10, 0x13, 0x00, 0x10, 0x14, 0x14, 0x05, 0x18, +0x10, 0x0b, 0x7f, 0x00, 0x0d, 0x01, 0x08, 0x0d, 0x17, 0x0b, +0x10, 0x05, 0x14, 0x49, 0x0e, 0x0f, 0x49, 0x0d, 0x4a, 0x05, +0x06, 0x4a, 0x00, 0x3f, 0x33, 0x3f, 0x3f, 0x33, 0x3f, 0x12, +0x39, 0x39, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x10, +0xce, 0x32, 0x2f, 0x10, 0xc1, 0x87, 0x04, 0x2b, 0x10, 0x00, +0xc1, 0x87, 0x05, 0x7d, 0x10, 0xc4, 0x87, 0x08, 0x18, 0x10, +0x2b, 0x87, 0x05, 0x7d, 0xc4, 0x31, 0x30, 0x37, 0x1e, 0x03, +0x17, 0x23, 0x2e, 0x03, 0x27, 0x15, 0x23, 0x11, 0x33, 0x15, +0x36, 0x36, 0x37, 0x33, 0x06, 0x06, 0xee, 0x1b, 0x44, 0x43, +0x3c, 0x12, 0x62, 0x13, 0x38, 0x3f, 0x3f, 0x19, 0x53, 0x53, +0x37, 0x6e, 0x2c, 0x61, 0x2b, 0x79, 0xff, 0x14, 0x3d, 0x46, +0x49, 0x1f, 0x1f, 0x41, 0x3c, 0x32, 0x11, 0xdf, 0x01, 0xd0, +0xc2, 0x30, 0x5f, 0x33, 0x33, 0x6c, 0x00, 0x00, 0xff, 0xff, +0x00, 0x5b, 0x00, 0x00, 0x01, 0xcc, 0x03, 0x3e, 0x02, 0x26, +0x00, 0x2f, 0x00, 0x00, 0x01, 0x07, 0x00, 0x8f, 0xff, 0xc2, +0x00, 0x89, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xad, 0x40, +0x09, 0x08, 0x06, 0x02, 0x00, 0x50, 0x01, 0x03, 0x07, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x36, +0xff, 0xf5, 0x01, 0xc2, 0x03, 0x3e, 0x00, 0x17, 0x00, 0x1b, +0x00, 0x55, 0x40, 0x34, 0x03, 0x18, 0x0e, 0x00, 0x4d, 0x03, +0x20, 0x0d, 0x00, 0x4d, 0x03, 0x18, 0x0c, 0x00, 0x4d, 0x03, +0x20, 0x0b, 0x00, 0x4d, 0x03, 0x20, 0x09, 0x00, 0x4d, 0x18, +0x80, 0x1a, 0x1a, 0x09, 0x7f, 0x06, 0x06, 0x07, 0x13, 0x1d, +0x07, 0x1c, 0x18, 0x1b, 0x1a, 0x19, 0x06, 0x85, 0x09, 0x4d, +0x12, 0x12, 0x0f, 0x88, 0x00, 0x51, 0x00, 0x3f, 0xed, 0x32, +0x2f, 0x3f, 0xed, 0xde, 0xcd, 0xdd, 0xcd, 0x01, 0x10, 0xc6, +0x10, 0xce, 0x11, 0x39, 0x2f, 0xed, 0x33, 0x2f, 0x1a, 0xcd, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x05, 0x22, 0x2e, +0x02, 0x35, 0x11, 0x23, 0x35, 0x33, 0x11, 0x14, 0x1e, 0x02, +0x33, 0x32, 0x36, 0x37, 0x17, 0x0e, 0x03, 0x03, 0x07, 0x27, +0x37, 0x01, 0x52, 0x2c, 0x3a, 0x22, 0x0e, 0x86, 0xd8, 0x09, +0x13, 0x1c, 0x13, 0x1d, 0x32, 0x0e, 0x0c, 0x06, 0x16, 0x1e, +0x23, 0x20, 0x96, 0x13, 0x90, 0x0b, 0x18, 0x30, 0x47, 0x2f, +0x01, 0xad, 0x46, 0xfe, 0x0d, 0x23, 0x2c, 0x1b, 0x0a, 0x0e, +0x08, 0x46, 0x03, 0x09, 0x08, 0x06, 0x03, 0x08, 0x36, 0x31, +0x46, 0x00, 0xff, 0xff, 0x00, 0x5b, 0xff, 0x56, 0x01, 0xcc, +0x02, 0x6b, 0x02, 0x26, 0x00, 0x2f, 0x00, 0x00, 0x01, 0x06, +0x01, 0xc3, 0x00, 0x00, 0x00, 0x0d, 0xb9, 0x00, 0x01, 0xff, +0xe2, 0xb4, 0x0f, 0x09, 0x02, 0x00, 0x50, 0x2b, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0x56, 0x01, 0xc2, +0x02, 0xb0, 0x02, 0x26, 0x00, 0x4f, 0x00, 0x00, 0x01, 0x06, +0x01, 0xc3, 0x36, 0x00, 0x00, 0x0a, 0xb6, 0x01, 0x2f, 0x21, +0x1b, 0x07, 0x13, 0x50, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x5b, 0x00, 0x00, 0x01, 0xcc, 0x02, 0x6c, 0x02, 0x26, +0x00, 0x2f, 0x00, 0x00, 0x01, 0x06, 0x01, 0xc2, 0x2c, 0xb7, +0x00, 0x0a, 0xb6, 0x01, 0x12, 0x08, 0x06, 0x02, 0x00, 0x50, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, +0x01, 0xc2, 0x02, 0xb5, 0x02, 0x26, 0x00, 0x4f, 0x00, 0x00, +0x01, 0x07, 0x01, 0xc2, 0x00, 0x83, 0x00, 0x00, 0x00, 0x0a, +0xb6, 0x01, 0x80, 0x1a, 0x18, 0x07, 0x13, 0x50, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x5b, 0x00, 0x00, 0x01, 0xcc, 0x02, 0x6b, +0x02, 0x26, 0x00, 0x2f, 0x00, 0x00, 0x01, 0x07, 0x01, 0x62, +0x00, 0x71, 0xfe, 0xea, 0x00, 0x0a, 0xb6, 0x01, 0x57, 0x08, +0x0e, 0x02, 0x00, 0x50, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x36, +0xff, 0xf5, 0x02, 0x1b, 0x02, 0xb0, 0x02, 0x26, 0x00, 0x4f, +0x00, 0x00, 0x01, 0x07, 0x01, 0x62, 0x00, 0xe5, 0xfe, 0xea, +0x00, 0x0a, 0xb6, 0x01, 0xe3, 0x1a, 0x20, 0x07, 0x13, 0x50, +0x2b, 0x34, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x01, 0xcc, +0x02, 0x6b, 0x00, 0x0d, 0x00, 0x42, 0x40, 0x20, 0x00, 0x0f, +0x0a, 0x0b, 0x09, 0x0c, 0x73, 0x04, 0x05, 0x06, 0x03, 0x0e, +0x0c, 0x03, 0x04, 0x0b, 0x0a, 0x09, 0x06, 0x0a, 0x05, 0x04, +0x0a, 0x04, 0x0a, 0x04, 0x07, 0x41, 0x0d, 0x79, 0x02, 0x42, +0x00, 0x3f, 0xed, 0x3f, 0x39, 0x39, 0x2f, 0x2f, 0x10, 0xcd, +0x11, 0x39, 0x39, 0x10, 0xcd, 0x11, 0x39, 0x39, 0x01, 0x10, +0xd6, 0x32, 0xcd, 0x32, 0xfd, 0x32, 0xcd, 0x32, 0x10, 0xce, +0x31, 0x30, 0x25, 0x15, 0x21, 0x11, 0x07, 0x27, 0x37, 0x11, +0x33, 0x15, 0x37, 0x17, 0x07, 0x15, 0x01, 0xcc, 0xfe, 0xa5, +0x42, 0x1d, 0x5f, 0x53, 0x6b, 0x1c, 0x87, 0x46, 0x46, 0x01, +0x00, 0x22, 0x3b, 0x31, 0x01, 0x21, 0xf6, 0x37, 0x3b, 0x46, +0xe5, 0x00, 0x00, 0x01, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, +0x02, 0xb0, 0x00, 0x1f, 0x00, 0x65, 0x40, 0x3a, 0x03, 0x18, +0x0b, 0x0c, 0x00, 0x4c, 0x03, 0x20, 0x09, 0x0a, 0x00, 0x4c, +0x02, 0x10, 0x0d, 0x00, 0x4d, 0x0f, 0x10, 0x1b, 0x0e, 0x11, +0x7f, 0x07, 0x08, 0x0b, 0x09, 0x00, 0x06, 0x01, 0x08, 0x06, +0x06, 0x21, 0x20, 0x11, 0x06, 0x07, 0x10, 0x0f, 0x0e, 0x09, +0x0f, 0x08, 0x07, 0x0f, 0x07, 0x0f, 0x07, 0x17, 0x0a, 0x85, +0x0d, 0x4d, 0x17, 0x88, 0x00, 0x51, 0x00, 0x3f, 0xed, 0x3f, +0xed, 0x12, 0x39, 0x39, 0x2f, 0x2f, 0x10, 0xcd, 0x11, 0x39, +0x39, 0x10, 0xcd, 0x11, 0x39, 0x39, 0x01, 0x11, 0x12, 0x39, +0x2f, 0x5e, 0x5d, 0x33, 0xcc, 0xcd, 0x32, 0xfd, 0x32, 0xcc, +0xcd, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x05, 0x22, 0x2e, +0x02, 0x35, 0x35, 0x07, 0x27, 0x37, 0x35, 0x23, 0x35, 0x33, +0x11, 0x37, 0x17, 0x07, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, +0x36, 0x37, 0x17, 0x0e, 0x03, 0x01, 0x52, 0x2c, 0x3a, 0x22, +0x0e, 0x42, 0x1c, 0x5e, 0x86, 0xd8, 0x4e, 0x1c, 0x6a, 0x09, +0x13, 0x1c, 0x13, 0x1d, 0x32, 0x0e, 0x0c, 0x06, 0x16, 0x1e, +0x23, 0x0b, 0x18, 0x30, 0x47, 0x2f, 0x7e, 0x22, 0x37, 0x30, +0xf4, 0x46, 0xfe, 0xf1, 0x28, 0x37, 0x37, 0xa8, 0x23, 0x2c, +0x1b, 0x0a, 0x0e, 0x08, 0x46, 0x03, 0x09, 0x08, 0x06, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x37, 0x00, 0x00, 0x01, 0xbd, +0x03, 0x3e, 0x02, 0x26, 0x00, 0x31, 0x00, 0x00, 0x01, 0x07, +0x00, 0x8f, 0x00, 0x09, 0x00, 0x89, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x0d, 0x14, 0x12, 0x07, 0x10, 0x50, 0x01, 0x08, 0x13, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x47, +0x00, 0x00, 0x01, 0xb0, 0x02, 0xb5, 0x02, 0x26, 0x00, 0x51, +0x00, 0x00, 0x01, 0x06, 0x00, 0x8f, 0x09, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x0b, 0x16, 0x14, 0x00, 0x05, 0x50, 0x01, +0x02, 0x15, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x37, +0xff, 0x56, 0x01, 0xbd, 0x02, 0x6b, 0x02, 0x26, 0x00, 0x31, +0x00, 0x00, 0x01, 0x06, 0x01, 0xc3, 0xf8, 0x00, 0x00, 0x0d, +0xb9, 0x00, 0x01, 0xff, 0xf4, 0xb4, 0x1b, 0x15, 0x07, 0x10, +0x50, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x47, +0xff, 0x56, 0x01, 0xb0, 0x01, 0xda, 0x02, 0x26, 0x00, 0x51, +0x00, 0x00, 0x01, 0x06, 0x01, 0xc3, 0xef, 0x00, 0x00, 0x0d, +0xb9, 0x00, 0x01, 0xff, 0xe9, 0xb4, 0x1d, 0x17, 0x00, 0x05, +0x50, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x37, +0x00, 0x00, 0x01, 0xbd, 0x03, 0x3d, 0x02, 0x26, 0x00, 0x31, +0x00, 0x00, 0x01, 0x07, 0x01, 0x5f, 0x00, 0x00, 0x00, 0x8b, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x12, 0x16, 0x07, 0x10, +0x50, 0x01, 0x08, 0x17, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x47, 0x00, 0x00, 0x01, 0xb0, 0x02, 0xb2, +0x02, 0x26, 0x00, 0x51, 0x00, 0x00, 0x01, 0x06, 0x01, 0x5f, +0x00, 0x00, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xff, 0x40, +0x09, 0x14, 0x18, 0x00, 0x05, 0x50, 0x01, 0x02, 0x19, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0x00, 0x02, 0x00, 0x1d, 0x00, 0x00, +0x01, 0xbd, 0x02, 0xb5, 0x00, 0x0f, 0x00, 0x1b, 0x00, 0xaa, +0xb9, 0x00, 0x0b, 0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x09, +0xb8, 0xff, 0xf8, 0xb3, 0x0e, 0x00, 0x4d, 0x08, 0xb8, 0xff, +0xd0, 0x40, 0x09, 0x0e, 0x00, 0x4d, 0x02, 0x18, 0x10, 0x00, +0x4d, 0x02, 0xb8, 0xff, 0xe8, 0x40, 0x30, 0x0f, 0x00, 0x4d, +0x01, 0x20, 0x0f, 0x00, 0x4d, 0x01, 0x10, 0x0e, 0x00, 0x4d, +0x00, 0x0c, 0x73, 0x4f, 0x0f, 0x01, 0x0f, 0x1d, 0x14, 0x15, +0x1b, 0x0f, 0x10, 0x1f, 0x10, 0x2f, 0x10, 0x03, 0x10, 0x07, +0x03, 0x73, 0x00, 0x06, 0x10, 0x06, 0x20, 0x06, 0xb0, 0x06, +0xc0, 0x06, 0x05, 0x08, 0x06, 0xb8, 0xff, 0xc0, 0x40, 0x16, +0x0d, 0x10, 0x48, 0x06, 0x1c, 0x14, 0x10, 0x07, 0x03, 0x40, +0x0f, 0x00, 0x4d, 0x7f, 0x03, 0x01, 0x03, 0x07, 0x07, 0x0d, +0x41, 0x0c, 0xb8, 0xff, 0xc0, 0x40, 0x0a, 0x0f, 0x00, 0x4d, +0x70, 0x0c, 0x01, 0x0c, 0x00, 0x04, 0x42, 0x00, 0x3f, 0x33, +0x32, 0x5d, 0x2b, 0x3f, 0x33, 0x11, 0x33, 0x5d, 0x2b, 0x10, +0xd6, 0xcd, 0x01, 0x10, 0xd6, 0x2b, 0x5e, 0x5d, 0xed, 0x32, +0xde, 0x5d, 0xdd, 0xd6, 0xc5, 0x10, 0xde, 0x71, 0xed, 0x32, +0x31, 0x30, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x21, 0x26, 0x26, 0x27, 0x11, 0x23, 0x11, 0x33, 0x1e, 0x03, +0x17, 0x11, 0x33, 0x11, 0x01, 0x15, 0x14, 0x06, 0x07, 0x27, +0x36, 0x36, 0x35, 0x34, 0x26, 0x27, 0x01, 0x72, 0x16, 0x35, +0x1c, 0x46, 0x4b, 0x0e, 0x1d, 0x1b, 0x18, 0x09, 0x46, 0xfe, +0xd0, 0x1c, 0x1c, 0x38, 0x11, 0x0f, 0x01, 0x01, 0x60, 0xd3, +0x72, 0xfe, 0x5b, 0x02, 0x6b, 0x32, 0x67, 0x66, 0x61, 0x2c, +0x01, 0x8c, 0xfd, 0x95, 0x02, 0xb5, 0x09, 0x33, 0x52, 0x2e, +0x15, 0x23, 0x3f, 0x23, 0x09, 0x14, 0x05, 0x00, 0xff, 0xff, +0x00, 0x0b, 0x00, 0x00, 0x01, 0xb0, 0x02, 0xb5, 0x02, 0x26, +0x00, 0x51, 0x00, 0x00, 0x01, 0x07, 0x01, 0x5e, 0xff, 0x47, +0x00, 0x00, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0x48, 0x40, +0x09, 0x1b, 0x14, 0x00, 0x05, 0x50, 0x01, 0x02, 0x1a, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, +0xff, 0x59, 0x01, 0xbd, 0x02, 0x6b, 0x00, 0x20, 0x00, 0x53, +0x40, 0x2f, 0x15, 0x09, 0x25, 0x09, 0x02, 0x09, 0x00, 0x05, +0x00, 0x7e, 0x0e, 0x09, 0x14, 0x0e, 0x09, 0x00, 0x0e, 0x19, +0x19, 0x0e, 0x73, 0x11, 0x22, 0x05, 0x73, 0x10, 0x07, 0x20, +0x07, 0x02, 0x07, 0x21, 0x0f, 0x05, 0x09, 0x41, 0x1d, 0x7c, +0x16, 0x0f, 0x0e, 0x01, 0x08, 0x0e, 0x00, 0x07, 0x42, 0x00, +0x3f, 0x33, 0x32, 0x5e, 0x5d, 0xdc, 0xed, 0x3f, 0x33, 0x33, +0x01, 0x10, 0xd6, 0x5d, 0xed, 0x10, 0xde, 0xed, 0x32, 0x2f, +0x10, 0xc1, 0x87, 0x04, 0x2b, 0x87, 0x05, 0x7d, 0xc4, 0x01, +0x5d, 0x31, 0x30, 0x25, 0x2e, 0x03, 0x27, 0x11, 0x23, 0x11, +0x33, 0x1e, 0x03, 0x17, 0x11, 0x33, 0x11, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, +0x35, 0x01, 0x72, 0x14, 0x37, 0x40, 0x45, 0x20, 0x4b, 0x54, +0x1c, 0x40, 0x3f, 0x38, 0x14, 0x4b, 0x08, 0x19, 0x31, 0x28, +0x0d, 0x20, 0x0a, 0x08, 0x08, 0x17, 0x07, 0x21, 0x17, 0x15, +0x2c, 0x73, 0x7e, 0x81, 0x3b, 0xfe, 0x12, 0x02, 0x6b, 0x31, +0x76, 0x79, 0x73, 0x2f, 0x01, 0xc2, 0xfd, 0x95, 0x25, 0x3e, +0x2c, 0x18, 0x05, 0x02, 0x41, 0x02, 0x02, 0x2b, 0x29, 0x00, +0x00, 0x01, 0x00, 0x47, 0xff, 0x59, 0x01, 0xb0, 0x01, 0xda, +0x00, 0x21, 0x00, 0x59, 0x40, 0x10, 0x1a, 0x40, 0x12, 0x00, +0x4d, 0x1a, 0x28, 0x11, 0x00, 0x4d, 0x1a, 0x20, 0x10, 0x00, +0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x05, +0xb8, 0xff, 0xe0, 0xb3, 0x09, 0x00, 0x4d, 0x05, 0xb8, 0xff, +0xd8, 0x40, 0x1a, 0x08, 0x00, 0x4d, 0x0f, 0x16, 0x7f, 0x07, +0x23, 0x20, 0x7f, 0x00, 0x21, 0x01, 0x08, 0x21, 0x22, 0x21, +0x4a, 0x13, 0x89, 0x0c, 0x4b, 0x1c, 0x88, 0x03, 0x50, 0x00, +0x3f, 0xed, 0x3f, 0xed, 0x3f, 0x01, 0x10, 0xd6, 0x5e, 0x5d, +0xed, 0x10, 0xde, 0xfd, 0xcc, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x13, 0x36, 0x36, 0x33, 0x32, 0x16, 0x15, +0x11, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, +0x16, 0x33, 0x32, 0x36, 0x35, 0x11, 0x34, 0x2e, 0x02, 0x23, +0x22, 0x06, 0x07, 0x11, 0x23, 0x47, 0x2d, 0x59, 0x27, 0x5d, +0x5f, 0x0b, 0x1e, 0x33, 0x28, 0x0d, 0x20, 0x0a, 0x08, 0x08, +0x16, 0x08, 0x21, 0x1a, 0x10, 0x1d, 0x29, 0x18, 0x14, 0x2d, +0x15, 0x53, 0x01, 0xc3, 0x0b, 0x0c, 0x60, 0x6a, 0xfe, 0xf0, +0x29, 0x3f, 0x2a, 0x15, 0x05, 0x02, 0x41, 0x02, 0x02, 0x2b, +0x29, 0x01, 0x10, 0x2d, 0x38, 0x1f, 0x0c, 0x05, 0x04, 0xfe, +0x78, 0x00, 0xff, 0xff, 0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, +0x03, 0x06, 0x02, 0x26, 0x00, 0x32, 0x00, 0x00, 0x01, 0x07, +0x00, 0x8a, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, +0x02, 0x00, 0x20, 0x21, 0x00, 0x09, 0x50, 0x02, 0x04, 0x22, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x28, +0xff, 0xf5, 0x01, 0xcc, 0x02, 0x7b, 0x02, 0x26, 0x00, 0x52, +0x00, 0x00, 0x01, 0x06, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x02, 0x00, 0x20, 0x21, 0x09, 0x00, 0x50, 0x02, +0x0e, 0x22, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x1d, +0xff, 0xf3, 0x01, 0xd8, 0x03, 0x28, 0x02, 0x26, 0x00, 0x32, +0x00, 0x00, 0x01, 0x07, 0x01, 0x61, 0x00, 0x00, 0x00, 0x8b, +0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x24, 0x32, 0x00, 0x09, +0x50, 0x02, 0x04, 0x20, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0x9d, +0x02, 0x26, 0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x01, 0x61, +0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x24, 0x32, +0x09, 0x00, 0x50, 0x02, 0x0e, 0x20, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, 0x03, 0x3e, +0x02, 0x26, 0x00, 0x32, 0x00, 0x00, 0x01, 0x07, 0x01, 0x65, +0x00, 0x24, 0x00, 0x89, 0x00, 0x17, 0x40, 0x10, 0x03, 0x02, +0x23, 0x22, 0x24, 0x00, 0x09, 0x50, 0x03, 0x04, 0x25, 0x4f, +0x02, 0x04, 0x21, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, +0x02, 0xb5, 0x02, 0x26, 0x00, 0x52, 0x00, 0x00, 0x01, 0x06, +0x01, 0x65, 0x24, 0x00, 0x00, 0x17, 0x40, 0x10, 0x03, 0x02, +0x24, 0x22, 0x24, 0x09, 0x00, 0x50, 0x03, 0x0e, 0x25, 0x4f, +0x02, 0x0e, 0x21, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0xff, 0xff, 0x00, 0x37, 0x00, 0x00, 0x01, 0xcf, 0x03, 0x3e, +0x02, 0x26, 0x00, 0x35, 0x00, 0x00, 0x01, 0x07, 0x00, 0x8f, +0x00, 0x00, 0x00, 0x89, 0x00, 0x13, 0xb9, 0x00, 0x02, 0xff, +0xfb, 0x40, 0x09, 0x2c, 0x2a, 0x12, 0x08, 0x50, 0x02, 0x17, +0x2b, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x6b, 0x00, 0x00, 0x01, 0xb6, 0x02, 0xb5, 0x02, 0x26, +0x00, 0x55, 0x00, 0x00, 0x01, 0x06, 0x00, 0x8f, 0x2d, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x1a, 0x10, 0x0e, 0x00, 0x06, +0x50, 0x01, 0x02, 0x0f, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x37, 0xff, 0x56, 0x01, 0xcf, 0x02, 0x71, 0x02, 0x26, +0x00, 0x35, 0x00, 0x00, 0x01, 0x06, 0x01, 0xc3, 0xdd, 0x00, +0x00, 0x0d, 0xb9, 0x00, 0x02, 0xff, 0xd0, 0xb4, 0x33, 0x2d, +0x12, 0x08, 0x50, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x2a, 0xff, 0x56, 0x01, 0xb6, 0x01, 0xda, 0x02, 0x26, +0x00, 0x55, 0x00, 0x00, 0x01, 0x07, 0x01, 0xc3, 0xff, 0x7f, +0x00, 0x00, 0x00, 0x0d, 0xb9, 0x00, 0x01, 0xff, 0x64, 0xb4, +0x17, 0x11, 0x00, 0x06, 0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, +0x00, 0x37, 0x00, 0x00, 0x01, 0xcf, 0x03, 0x3d, 0x02, 0x26, +0x00, 0x35, 0x00, 0x00, 0x01, 0x07, 0x01, 0x5f, 0xff, 0xe6, +0x00, 0x8b, 0x00, 0x13, 0xb9, 0x00, 0x02, 0xff, 0xdd, 0x40, +0x09, 0x2a, 0x2e, 0x12, 0x08, 0x50, 0x02, 0x17, 0x2f, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x6b, +0x00, 0x00, 0x01, 0xb6, 0x02, 0xb2, 0x02, 0x26, 0x00, 0x55, +0x00, 0x00, 0x01, 0x06, 0x01, 0x5f, 0x24, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x0d, 0x0e, 0x12, 0x00, 0x06, 0x50, 0x01, +0x02, 0x13, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x37, +0xff, 0xf3, 0x01, 0xbd, 0x03, 0x3e, 0x02, 0x26, 0x00, 0x36, +0x00, 0x00, 0x01, 0x07, 0x00, 0x8f, 0x00, 0x12, 0x00, 0x89, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x16, 0x34, 0x32, 0x2e, 0x25, +0x50, 0x01, 0x0f, 0x33, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x42, 0xff, 0xf5, 0x01, 0xb2, 0x02, 0xb5, +0x02, 0x26, 0x00, 0x56, 0x00, 0x00, 0x01, 0x06, 0x00, 0x8f, +0x09, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x0d, 0x2a, 0x28, +0x22, 0x1b, 0x50, 0x01, 0x09, 0x29, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x37, 0xff, 0xf3, 0x01, 0xbd, 0x03, 0x3a, +0x02, 0x26, 0x00, 0x36, 0x00, 0x00, 0x01, 0x07, 0x00, 0x69, +0x00, 0x09, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x09, +0x37, 0x33, 0x2e, 0x25, 0x50, 0x01, 0x0f, 0x34, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x42, 0xff, 0xf5, +0x01, 0xb2, 0x02, 0xaf, 0x02, 0x26, 0x00, 0x56, 0x00, 0x00, +0x01, 0x06, 0x00, 0x69, 0x09, 0x00, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x09, 0x2d, 0x29, 0x22, 0x1b, 0x50, 0x01, 0x09, 0x2a, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x01, 0x00, 0x37, 0xff, 0x57, +0x01, 0xbd, 0x02, 0x79, 0x00, 0x47, 0x01, 0x21, 0xb9, 0x00, +0x46, 0xff, 0xe8, 0xb4, 0x09, 0x0a, 0x00, 0x4c, 0x46, 0xb8, +0xff, 0xe0, 0xb3, 0x08, 0x00, 0x4d, 0x45, 0xb8, 0xff, 0xf0, +0xb3, 0x12, 0x00, 0x4d, 0x45, 0xb8, 0xff, 0xe8, 0xb3, 0x11, +0x00, 0x4d, 0x42, 0xb8, 0xff, 0xf0, 0xb3, 0x0d, 0x00, 0x4d, +0x41, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x41, 0xb8, +0xff, 0xd8, 0xb3, 0x08, 0x00, 0x4d, 0x3f, 0xb8, 0xff, 0xd0, +0xb3, 0x09, 0x00, 0x4d, 0x3d, 0xb8, 0xff, 0xe0, 0xb3, 0x0e, +0x00, 0x4d, 0x38, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, +0x38, 0xb8, 0xff, 0xd8, 0xb3, 0x11, 0x00, 0x4d, 0x32, 0xb8, +0xff, 0xe0, 0xb3, 0x11, 0x00, 0x4d, 0x32, 0xb8, 0xff, 0xe0, +0xb3, 0x0f, 0x00, 0x4d, 0x32, 0xb8, 0xff, 0xd8, 0x40, 0x2f, +0x0e, 0x00, 0x4d, 0x2c, 0x18, 0x09, 0x0a, 0x00, 0x4c, 0x2c, +0x20, 0x08, 0x00, 0x4d, 0x29, 0x18, 0x0f, 0x00, 0x4d, 0x25, +0x20, 0x0a, 0x00, 0x4d, 0x24, 0x18, 0x0e, 0x00, 0x4d, 0x19, +0x20, 0x10, 0x00, 0x4d, 0x19, 0x18, 0x0e, 0x0f, 0x00, 0x4c, +0x19, 0x10, 0x0d, 0x00, 0x4d, 0x11, 0x03, 0xb8, 0xff, 0xc0, +0x40, 0x36, 0x0b, 0x0e, 0x48, 0x03, 0x47, 0x00, 0x17, 0x0b, +0x14, 0x14, 0x44, 0x1a, 0x33, 0x33, 0x21, 0x76, 0x44, 0x49, +0x1a, 0x1a, 0x3a, 0x76, 0x00, 0x2b, 0x01, 0x08, 0x2b, 0x48, +0x00, 0x14, 0x14, 0x17, 0x0f, 0x40, 0x08, 0x48, 0x80, 0x3f, +0x2e, 0x1e, 0x26, 0x17, 0x34, 0x34, 0x37, 0x7c, 0x2e, 0x45, +0x1b, 0x1b, 0x1e, 0x7c, 0x17, 0x46, 0x00, 0x3f, 0xed, 0x32, +0x2f, 0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x11, 0x12, 0x39, +0x1a, 0x10, 0xdc, 0x1a, 0xcd, 0x12, 0x39, 0x2f, 0xcd, 0x01, +0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x33, 0x2f, 0x10, 0xde, 0xed, +0x33, 0x2f, 0x11, 0x12, 0x39, 0x2f, 0xcc, 0x33, 0xdd, 0x32, +0xd5, 0x2b, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x05, 0x16, 0x16, +0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, +0x16, 0x33, 0x32, 0x35, 0x34, 0x27, 0x27, 0x36, 0x36, 0x37, +0x26, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, +0x34, 0x2e, 0x02, 0x27, 0x2e, 0x03, 0x35, 0x34, 0x36, 0x33, +0x32, 0x1e, 0x02, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x06, +0x15, 0x14, 0x1e, 0x02, 0x17, 0x1e, 0x03, 0x15, 0x14, 0x06, +0x07, 0x01, 0x07, 0x1a, 0x17, 0x09, 0x15, 0x23, 0x1a, 0x17, +0x28, 0x0b, 0x0a, 0x0b, 0x18, 0x0f, 0x20, 0x25, 0x07, 0x04, +0x0b, 0x06, 0x3c, 0x54, 0x11, 0x19, 0x14, 0x4e, 0x38, 0x3f, +0x42, 0x18, 0x28, 0x32, 0x1a, 0x1e, 0x37, 0x2b, 0x19, 0x66, +0x5b, 0x19, 0x31, 0x2a, 0x21, 0x0a, 0x1a, 0x14, 0x46, 0x2b, +0x2d, 0x42, 0x13, 0x21, 0x2c, 0x1a, 0x26, 0x3f, 0x2d, 0x19, +0x58, 0x53, 0x21, 0x0c, 0x1e, 0x1d, 0x0a, 0x17, 0x13, 0x0d, +0x07, 0x05, 0x33, 0x04, 0x05, 0x14, 0x14, 0x0b, 0x02, 0x0a, +0x1b, 0x0c, 0x03, 0x1d, 0x0b, 0x44, 0x0b, 0x1d, 0x30, 0x30, +0x1d, 0x29, 0x1f, 0x17, 0x0a, 0x0c, 0x1e, 0x28, 0x36, 0x25, +0x51, 0x5b, 0x07, 0x0a, 0x0e, 0x07, 0x45, 0x0c, 0x18, 0x2d, +0x2d, 0x1a, 0x24, 0x1b, 0x16, 0x0b, 0x10, 0x20, 0x2c, 0x3c, +0x2b, 0x48, 0x56, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, +0xff, 0x57, 0x01, 0xb2, 0x01, 0xdb, 0x00, 0x3e, 0x00, 0xff, +0xb9, 0x00, 0x3c, 0xff, 0xe0, 0xb3, 0x0d, 0x00, 0x4d, 0x3c, +0xb8, 0xff, 0xf0, 0xb3, 0x0c, 0x00, 0x4d, 0x3c, 0xb8, 0xff, +0xe8, 0xb3, 0x0b, 0x00, 0x4d, 0x3c, 0xb8, 0xff, 0xd8, 0xb4, +0x09, 0x0a, 0x00, 0x4c, 0x3c, 0xb8, 0xff, 0xd0, 0xb3, 0x08, +0x00, 0x4d, 0x3a, 0xb8, 0xff, 0xe0, 0xb3, 0x0d, 0x00, 0x4d, +0x39, 0xb8, 0xff, 0xd8, 0xb3, 0x0c, 0x00, 0x4d, 0x39, 0xb8, +0xff, 0xe0, 0xb3, 0x0a, 0x00, 0x4d, 0x37, 0xb8, 0xff, 0xc8, +0xb3, 0x09, 0x00, 0x4d, 0x37, 0xb8, 0xff, 0xe0, 0xb3, 0x08, +0x00, 0x4d, 0x36, 0xb8, 0xff, 0xe8, 0x40, 0x65, 0x0e, 0x10, +0x00, 0x4c, 0x27, 0x18, 0x0b, 0x00, 0x4d, 0x27, 0x20, 0x0a, +0x00, 0x4d, 0x27, 0x28, 0x09, 0x00, 0x4d, 0x24, 0x20, 0x0d, +0x00, 0x4d, 0x24, 0x28, 0x0c, 0x00, 0x4d, 0x24, 0x18, 0x0a, +0x00, 0x4d, 0x21, 0x10, 0x10, 0x00, 0x4d, 0x21, 0x18, 0x0f, +0x00, 0x4d, 0x19, 0x28, 0x10, 0x12, 0x00, 0x4c, 0x11, 0x03, +0x3e, 0x00, 0x17, 0x0b, 0x14, 0x14, 0x3b, 0x19, 0x2c, 0x2c, +0x1f, 0x82, 0x3b, 0x40, 0x19, 0x19, 0x34, 0x82, 0x00, 0x26, +0x01, 0x08, 0x26, 0x3f, 0x14, 0x14, 0x17, 0x0f, 0x40, 0x08, +0x3f, 0x80, 0x37, 0x29, 0x1d, 0x22, 0x17, 0x32, 0x88, 0x29, +0x50, 0x1d, 0x88, 0x3e, 0x17, 0x51, 0x00, 0x15, 0x51, 0x00, +0x3f, 0x33, 0x3f, 0x33, 0xed, 0x3f, 0xed, 0x11, 0x39, 0x11, +0x12, 0x39, 0x1a, 0x10, 0xdc, 0x1a, 0xcd, 0x11, 0x39, 0x2f, +0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x33, 0x2f, 0x10, 0xde, +0xed, 0x33, 0x2f, 0x11, 0x12, 0x39, 0x2f, 0xcc, 0x33, 0xdd, +0x32, 0xd5, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x05, 0x16, 0x16, 0x15, 0x14, +0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, +0x32, 0x35, 0x34, 0x27, 0x27, 0x36, 0x36, 0x37, 0x26, 0x27, +0x37, 0x16, 0x16, 0x33, 0x32, 0x35, 0x34, 0x2e, 0x04, 0x35, +0x34, 0x36, 0x33, 0x32, 0x16, 0x17, 0x07, 0x2e, 0x03, 0x23, +0x22, 0x15, 0x14, 0x1e, 0x04, 0x15, 0x14, 0x06, 0x07, 0x01, +0x07, 0x1a, 0x17, 0x09, 0x15, 0x23, 0x1a, 0x17, 0x28, 0x0b, +0x0a, 0x0b, 0x18, 0x0f, 0x20, 0x25, 0x07, 0x04, 0x0c, 0x06, +0x56, 0x41, 0x10, 0x23, 0x4d, 0x2c, 0x71, 0x29, 0x3d, 0x48, +0x3d, 0x29, 0x5b, 0x61, 0x26, 0x51, 0x1d, 0x0f, 0x08, 0x1c, +0x24, 0x29, 0x13, 0x6c, 0x29, 0x3e, 0x48, 0x3e, 0x29, 0x4d, +0x52, 0x21, 0x0c, 0x1e, 0x1d, 0x0a, 0x17, 0x13, 0x0d, 0x07, +0x05, 0x33, 0x04, 0x05, 0x14, 0x14, 0x0b, 0x02, 0x0b, 0x1b, +0x0d, 0x03, 0x1d, 0x4b, 0x10, 0x15, 0x39, 0x19, 0x20, 0x18, +0x17, 0x22, 0x32, 0x28, 0x38, 0x4b, 0x0b, 0x09, 0x4a, 0x04, +0x09, 0x07, 0x04, 0x3b, 0x15, 0x1d, 0x18, 0x19, 0x24, 0x33, +0x27, 0x39, 0x42, 0x07, 0x00, 0x01, 0x00, 0x27, 0xff, 0x57, +0x01, 0xcd, 0x02, 0x6b, 0x00, 0x20, 0x00, 0x48, 0xb4, 0x1d, +0x1f, 0x18, 0x11, 0x03, 0xb8, 0xff, 0xc0, 0x40, 0x1d, 0x0b, +0x0e, 0x48, 0x03, 0x00, 0x0b, 0x14, 0x14, 0x1a, 0x18, 0x18, +0x22, 0x21, 0x1e, 0x19, 0x79, 0x1b, 0x41, 0x00, 0x14, 0x14, +0x18, 0x0f, 0x40, 0x08, 0x80, 0x1f, 0x18, 0x42, 0x00, 0x3f, +0x33, 0x1a, 0xdc, 0x1a, 0xcd, 0x11, 0x39, 0x2f, 0xcd, 0x3f, +0xed, 0x32, 0x01, 0x11, 0x12, 0x39, 0x2f, 0xce, 0x33, 0x2f, +0xcc, 0xdd, 0xd5, 0x2b, 0xcd, 0x10, 0xd4, 0xce, 0x31, 0x30, +0x05, 0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, +0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x35, 0x34, 0x27, 0x27, +0x36, 0x36, 0x37, 0x23, 0x11, 0x23, 0x35, 0x21, 0x15, 0x23, +0x11, 0x23, 0x01, 0x07, 0x1a, 0x17, 0x09, 0x15, 0x23, 0x1a, +0x17, 0x28, 0x0b, 0x0a, 0x0b, 0x18, 0x0f, 0x20, 0x25, 0x07, +0x05, 0x0f, 0x07, 0x0d, 0xaa, 0x01, 0xa6, 0xaa, 0x0b, 0x21, +0x0c, 0x1e, 0x1d, 0x0a, 0x17, 0x13, 0x0d, 0x07, 0x05, 0x33, +0x04, 0x05, 0x14, 0x14, 0x0b, 0x02, 0x0d, 0x23, 0x0e, 0x02, +0x25, 0x46, 0x46, 0xfd, 0xdb, 0x00, 0x00, 0x01, 0x00, 0x3f, +0xff, 0x57, 0x01, 0xc2, 0x02, 0x60, 0x00, 0x33, 0x00, 0x76, +0x40, 0x44, 0x19, 0x18, 0x0e, 0x10, 0x00, 0x4c, 0x19, 0x20, +0x0d, 0x00, 0x4d, 0x19, 0x18, 0x0c, 0x00, 0x4d, 0x19, 0x20, +0x0b, 0x00, 0x4d, 0x11, 0x03, 0x00, 0x0b, 0x14, 0x14, 0x1d, +0x30, 0x30, 0x25, 0x23, 0x26, 0x7f, 0x20, 0x1d, 0x1d, 0x1e, +0x25, 0x35, 0x00, 0x1e, 0x01, 0x08, 0x1e, 0x34, 0x00, 0x14, +0x14, 0x33, 0x0f, 0x40, 0x08, 0x34, 0x80, 0x2c, 0x88, 0x17, +0x33, 0x51, 0x21, 0x22, 0x26, 0x1d, 0x85, 0x23, 0x20, 0x49, +0x00, 0x3f, 0x33, 0xed, 0x32, 0xcd, 0x32, 0x3f, 0x33, 0xed, +0x1a, 0x10, 0xdc, 0x1a, 0xcd, 0x11, 0x39, 0x2f, 0xcd, 0x01, +0x10, 0xc6, 0x5e, 0x5d, 0x10, 0xce, 0x11, 0x39, 0x2f, 0x33, +0xed, 0x32, 0x11, 0x33, 0x2f, 0x12, 0x39, 0x2f, 0xcc, 0xdd, +0xd5, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x05, 0x16, +0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, +0x16, 0x16, 0x33, 0x32, 0x35, 0x34, 0x27, 0x27, 0x36, 0x36, +0x37, 0x2e, 0x03, 0x35, 0x35, 0x23, 0x35, 0x33, 0x35, 0x37, +0x15, 0x33, 0x15, 0x23, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, +0x36, 0x37, 0x17, 0x06, 0x06, 0x07, 0x01, 0x46, 0x1a, 0x17, +0x09, 0x15, 0x23, 0x1a, 0x17, 0x28, 0x0b, 0x0a, 0x0b, 0x18, +0x0f, 0x20, 0x25, 0x07, 0x04, 0x0d, 0x07, 0x25, 0x2f, 0x1b, +0x0a, 0x62, 0x62, 0x52, 0xc4, 0xc4, 0x0a, 0x17, 0x24, 0x1a, +0x24, 0x2c, 0x14, 0x0c, 0x0d, 0x3a, 0x2a, 0x21, 0x0c, 0x1e, +0x1d, 0x0a, 0x17, 0x13, 0x0d, 0x07, 0x05, 0x33, 0x04, 0x05, +0x14, 0x14, 0x0b, 0x02, 0x0b, 0x1e, 0x0d, 0x05, 0x1d, 0x2f, +0x41, 0x29, 0xd8, 0x45, 0x82, 0x0e, 0x90, 0x45, 0xd8, 0x23, +0x2c, 0x1b, 0x0a, 0x0c, 0x0a, 0x46, 0x06, 0x12, 0x02, 0x00, +0xff, 0xff, 0x00, 0x27, 0x00, 0x00, 0x01, 0xcd, 0x03, 0x3d, +0x02, 0x26, 0x00, 0x37, 0x00, 0x00, 0x01, 0x07, 0x01, 0x5f, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, +0x08, 0x0c, 0x06, 0x00, 0x50, 0x01, 0x00, 0x0d, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x3f, 0xff, 0xf5, +0x01, 0xc2, 0x02, 0xb5, 0x02, 0x26, 0x00, 0x57, 0x00, 0x00, +0x01, 0x06, 0x01, 0xc5, 0x68, 0x00, 0x00, 0x0a, 0xb6, 0x01, +0x61, 0x1e, 0x1c, 0x17, 0x0d, 0x50, 0x2b, 0x34, 0x00, 0x00, +0x00, 0x01, 0x00, 0x27, 0x00, 0x00, 0x01, 0xcd, 0x02, 0x6b, +0x00, 0x0f, 0x00, 0x37, 0x40, 0x1b, 0x05, 0x03, 0x01, 0x06, +0x73, 0x0e, 0x0c, 0x0a, 0x09, 0x09, 0x10, 0x11, 0x02, 0x0d, +0x79, 0x0f, 0x06, 0x09, 0x79, 0x03, 0x0c, 0x0c, 0x08, 0x0f, +0x41, 0x08, 0x42, 0x00, 0x3f, 0x3f, 0x12, 0x39, 0x2f, 0x33, +0xed, 0x32, 0x10, 0xed, 0x32, 0x01, 0x11, 0x12, 0x39, 0x2f, +0xcd, 0x33, 0xcc, 0xfd, 0xcc, 0x33, 0xcd, 0x31, 0x30, 0x01, +0x15, 0x23, 0x15, 0x33, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, +0x35, 0x33, 0x35, 0x23, 0x35, 0x01, 0xcd, 0xaa, 0x76, 0x76, +0x52, 0x77, 0x77, 0xaa, 0x02, 0x6b, 0x46, 0xc8, 0x40, 0xfe, +0xe3, 0x01, 0x1d, 0x40, 0xc8, 0x46, 0x00, 0x00, 0x00, 0x01, +0x00, 0x3f, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0x60, 0x00, 0x23, +0x00, 0x61, 0x40, 0x35, 0x17, 0x20, 0x0b, 0x00, 0x4d, 0x16, +0x18, 0x0c, 0x00, 0x4d, 0x07, 0x00, 0x03, 0x7f, 0x21, 0x1a, +0x1e, 0x1e, 0x1f, 0x11, 0x11, 0x05, 0x05, 0x02, 0x25, 0x1c, +0x1c, 0x00, 0x1f, 0x01, 0x08, 0x1f, 0x24, 0x22, 0x23, 0x03, +0x1e, 0x85, 0x21, 0x07, 0x1a, 0x04, 0x1d, 0x1d, 0x00, 0x21, +0x49, 0x10, 0x10, 0x0d, 0x88, 0x14, 0x51, 0x00, 0x3f, 0xed, +0x32, 0x2f, 0x3f, 0x33, 0x39, 0x2f, 0x33, 0xcd, 0x32, 0x10, +0xed, 0x32, 0xcd, 0x32, 0x01, 0x10, 0xc6, 0x5e, 0x5d, 0x32, +0x2f, 0x10, 0xce, 0x32, 0x2f, 0x32, 0x2f, 0x11, 0x39, 0x2f, +0x33, 0x33, 0xed, 0x32, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x13, +0x33, 0x15, 0x23, 0x15, 0x33, 0x15, 0x23, 0x15, 0x14, 0x1e, +0x02, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x06, 0x23, 0x22, +0x2e, 0x02, 0x35, 0x35, 0x23, 0x35, 0x33, 0x35, 0x23, 0x35, +0x33, 0x35, 0x37, 0xf3, 0xc4, 0xc4, 0xc4, 0xc4, 0x0a, 0x17, +0x24, 0x1a, 0x24, 0x2c, 0x14, 0x0c, 0x0e, 0x3d, 0x2d, 0x34, +0x42, 0x25, 0x0e, 0x62, 0x62, 0x62, 0x62, 0x52, 0x01, 0xd0, +0x45, 0x7a, 0x3e, 0x20, 0x23, 0x2c, 0x1b, 0x0a, 0x0c, 0x0a, +0x46, 0x06, 0x14, 0x18, 0x30, 0x47, 0x2f, 0x20, 0x3e, 0x7a, +0x45, 0x82, 0x0e, 0x00, 0xff, 0xff, 0x00, 0x30, 0xff, 0xf3, +0x01, 0xc4, 0x03, 0x1c, 0x02, 0x26, 0x00, 0x38, 0x00, 0x00, +0x01, 0x07, 0x00, 0x75, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x00, 0x28, 0x1a, 0x04, 0x14, 0x50, 0x01, +0x06, 0x27, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x44, 0xff, 0xf6, 0x01, 0xad, 0x02, 0x91, 0x02, 0x26, +0x00, 0x58, 0x00, 0x00, 0x01, 0x06, 0x00, 0x75, 0x00, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x01, 0x24, 0x16, 0x07, 0x00, +0x50, 0x01, 0x09, 0x23, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x30, 0xff, 0xf3, 0x01, 0xc4, 0x03, 0x06, 0x02, 0x26, +0x00, 0x38, 0x00, 0x00, 0x01, 0x07, 0x00, 0x8a, 0x00, 0x00, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x1a, 0x1b, +0x04, 0x14, 0x50, 0x01, 0x06, 0x1c, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x44, 0xff, 0xf6, 0x01, 0xad, +0x02, 0x7b, 0x02, 0x26, 0x00, 0x58, 0x00, 0x00, 0x01, 0x06, +0x00, 0x8a, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x01, +0x16, 0x17, 0x07, 0x00, 0x50, 0x01, 0x09, 0x18, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x30, 0xff, 0xf3, 0x01, 0xc4, +0x03, 0x28, 0x02, 0x26, 0x00, 0x38, 0x00, 0x00, 0x01, 0x07, +0x01, 0x61, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x00, 0x1e, 0x2c, 0x04, 0x14, 0x50, 0x01, 0x06, 0x1a, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x44, +0xff, 0xf6, 0x01, 0xad, 0x02, 0x9d, 0x02, 0x26, 0x00, 0x58, +0x00, 0x00, 0x01, 0x06, 0x01, 0x61, 0x00, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x01, 0x1a, 0x28, 0x07, 0x00, 0x50, 0x01, +0x09, 0x16, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x30, +0xff, 0xf3, 0x01, 0xc4, 0x03, 0x3e, 0x02, 0x26, 0x00, 0x38, +0x00, 0x00, 0x01, 0x07, 0x01, 0x63, 0x00, 0x00, 0x00, 0x86, +0x00, 0x0c, 0xb7, 0x02, 0x01, 0x00, 0x1f, 0x1a, 0x04, 0x14, +0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x44, +0xff, 0xf6, 0x01, 0xad, 0x02, 0xb8, 0x02, 0x26, 0x00, 0x58, +0x00, 0x00, 0x01, 0x06, 0x01, 0x63, 0x00, 0x00, 0x00, 0x0c, +0xb7, 0x02, 0x01, 0x01, 0x1b, 0x16, 0x07, 0x00, 0x50, 0x2b, +0x34, 0x34, 0xff, 0xff, 0x00, 0x30, 0xff, 0xf3, 0x01, 0xc4, +0x03, 0x3e, 0x02, 0x26, 0x00, 0x38, 0x00, 0x00, 0x01, 0x07, +0x01, 0x65, 0x00, 0x1b, 0x00, 0x89, 0x00, 0x17, 0x40, 0x10, +0x02, 0x01, 0x1b, 0x1c, 0x1e, 0x04, 0x14, 0x50, 0x02, 0x06, +0x1f, 0x4f, 0x01, 0x06, 0x1b, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x44, 0xff, 0xf6, +0x01, 0xad, 0x02, 0xb5, 0x02, 0x26, 0x00, 0x58, 0x00, 0x00, +0x01, 0x06, 0x01, 0x65, 0x1b, 0x00, 0x00, 0x17, 0x40, 0x10, +0x02, 0x01, 0x1c, 0x18, 0x1a, 0x07, 0x00, 0x50, 0x02, 0x09, +0x1b, 0x4f, 0x01, 0x09, 0x17, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x01, 0x00, 0x30, 0xff, 0x59, 0x01, 0xc4, +0x02, 0x6b, 0x00, 0x2b, 0x00, 0x5e, 0xb6, 0x0f, 0x10, 0x0f, +0x10, 0x00, 0x4c, 0x0b, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, +0x4d, 0x0b, 0xb8, 0xff, 0xf0, 0x40, 0x2b, 0x0f, 0x00, 0x4d, +0x02, 0x20, 0x0c, 0x00, 0x4d, 0x02, 0x10, 0x0b, 0x00, 0x4d, +0x02, 0x18, 0x0a, 0x00, 0x4d, 0x00, 0x29, 0x24, 0x1e, 0x1e, +0x05, 0x12, 0x73, 0x15, 0x2d, 0x08, 0x73, 0x05, 0x2c, 0x20, +0x26, 0x2c, 0x13, 0x06, 0x41, 0x1b, 0x0d, 0x7c, 0x00, 0x46, +0x00, 0x3f, 0xed, 0x33, 0x3f, 0x33, 0x10, 0xdc, 0xcd, 0x01, +0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, 0x12, 0x39, 0x2f, 0xcc, +0xcd, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x17, 0x22, 0x2e, 0x02, 0x35, 0x11, 0x33, 0x11, 0x14, 0x1e, +0x02, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x11, 0x33, 0x11, 0x14, +0x06, 0x07, 0x06, 0x06, 0x07, 0x06, 0x06, 0x15, 0x14, 0x33, +0x32, 0x36, 0x37, 0x17, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, +0x36, 0xf0, 0x37, 0x49, 0x2d, 0x13, 0x52, 0x11, 0x1f, 0x2c, +0x1c, 0x1c, 0x2c, 0x1f, 0x11, 0x52, 0x25, 0x2b, 0x0b, 0x26, +0x0e, 0x0e, 0x0f, 0x24, 0x06, 0x14, 0x0b, 0x06, 0x16, 0x25, +0x33, 0x2f, 0x0e, 0x18, 0x23, 0x3f, 0x57, 0x34, 0x01, 0x96, +0xfe, 0x73, 0x2f, 0x3f, 0x26, 0x10, 0x10, 0x26, 0x3f, 0x2f, +0x01, 0x8d, 0xfe, 0x6a, 0x45, 0x64, 0x1b, 0x07, 0x1c, 0x0e, +0x0e, 0x18, 0x0d, 0x1a, 0x03, 0x03, 0x36, 0x0a, 0x24, 0x20, +0x15, 0x1e, 0x00, 0x01, 0x00, 0x44, 0xff, 0x59, 0x01, 0xad, +0x01, 0xd0, 0x00, 0x2a, 0x00, 0x60, 0xb9, 0x00, 0x22, 0xff, +0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x22, 0xb8, 0xff, 0xf0, 0x40, +0x33, 0x0f, 0x00, 0x4d, 0x1b, 0x10, 0x11, 0x00, 0x4d, 0x1a, +0x10, 0x13, 0x00, 0x4d, 0x1a, 0x18, 0x0a, 0x00, 0x4d, 0x1a, +0x28, 0x08, 0x09, 0x00, 0x4c, 0x15, 0x10, 0x0b, 0x05, 0x28, +0x7f, 0x00, 0x2c, 0x20, 0x7f, 0x00, 0x1d, 0x01, 0x08, 0x1d, +0x2b, 0x07, 0x0d, 0x2b, 0x29, 0x1e, 0x49, 0x23, 0x88, 0x00, +0x18, 0x51, 0x00, 0x3f, 0x33, 0xed, 0x3f, 0x33, 0x10, 0xdc, +0xcd, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x10, 0xde, 0xed, +0xde, 0xcc, 0xcd, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x25, 0x0e, 0x03, 0x15, 0x14, 0x33, 0x32, 0x36, +0x37, 0x17, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37, +0x36, 0x37, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x11, +0x33, 0x15, 0x14, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x37, 0x11, +0x33, 0x01, 0xad, 0x06, 0x1a, 0x1b, 0x14, 0x24, 0x06, 0x14, +0x0a, 0x07, 0x17, 0x24, 0x33, 0x30, 0x18, 0x10, 0x0c, 0x0c, +0x17, 0x2b, 0x10, 0x35, 0x46, 0x2c, 0x12, 0x52, 0x33, 0x3c, +0x0d, 0x1b, 0x18, 0x12, 0x03, 0x53, 0x0d, 0x06, 0x16, 0x1b, +0x1d, 0x0c, 0x1a, 0x03, 0x03, 0x36, 0x0a, 0x24, 0x20, 0x15, +0x25, 0x10, 0x0d, 0x08, 0x02, 0x04, 0x1f, 0x39, 0x4e, 0x2f, +0x01, 0x05, 0xf3, 0x56, 0x48, 0x02, 0x03, 0x03, 0x01, 0x01, +0x88, 0x00, 0xff, 0xff, 0x00, 0x20, 0x00, 0x00, 0x01, 0xd4, +0x03, 0x3a, 0x02, 0x26, 0x00, 0x3a, 0x00, 0x00, 0x01, 0x07, +0x00, 0x69, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x00, 0x1a, 0x16, 0x06, 0x0d, 0x50, 0x01, 0x06, 0x17, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x13, +0x00, 0x00, 0x01, 0xe1, 0x02, 0xaf, 0x02, 0x26, 0x00, 0x5a, +0x00, 0x00, 0x01, 0x06, 0x00, 0x69, 0xfe, 0x00, 0x00, 0x13, +0xb9, 0x00, 0x01, 0xff, 0xfe, 0x40, 0x09, 0x30, 0x2c, 0x0e, +0x25, 0x50, 0x01, 0x0e, 0x2d, 0x4f, 0x2b, 0x2b, 0x34, 0x00, +0xff, 0xff, 0x00, 0x0d, 0x00, 0x00, 0x01, 0xe8, 0x03, 0x3a, +0x02, 0x26, 0x00, 0x3c, 0x00, 0x00, 0x01, 0x07, 0x00, 0x69, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, +0x16, 0x12, 0x04, 0x0c, 0x50, 0x01, 0x04, 0x13, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0x58, +0x01, 0xcd, 0x02, 0xaf, 0x02, 0x26, 0x00, 0x5c, 0x00, 0x00, +0x01, 0x06, 0x00, 0x69, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x01, 0x26, 0x22, 0x20, 0x15, 0x50, 0x01, 0x09, 0x23, +0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x36, 0x00, 0x00, +0x01, 0xc7, 0x03, 0x3e, 0x02, 0x26, 0x00, 0x3d, 0x00, 0x00, +0x01, 0x07, 0x00, 0x8f, 0x00, 0x09, 0x00, 0x89, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x08, 0x14, 0x12, 0x08, 0x06, 0x50, 0x01, +0x10, 0x13, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x49, 0x00, 0x00, 0x01, 0xab, 0x02, 0xb5, 0x02, 0x26, +0x00, 0x5d, 0x00, 0x00, 0x01, 0x06, 0x00, 0x8f, 0x09, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x0d, 0x14, 0x12, 0x08, 0x06, +0x50, 0x01, 0x10, 0x13, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x36, 0x00, 0x00, 0x01, 0xc7, 0x03, 0x22, 0x02, 0x26, +0x00, 0x3d, 0x00, 0x00, 0x01, 0x07, 0x01, 0x62, 0x00, 0x00, +0x00, 0x8b, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xfc, 0x40, +0x09, 0x14, 0x1a, 0x08, 0x06, 0x50, 0x01, 0x10, 0x12, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x49, +0x00, 0x00, 0x01, 0xab, 0x02, 0x97, 0x02, 0x26, 0x00, 0x5d, +0x00, 0x00, 0x01, 0x06, 0x01, 0x62, 0x00, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x00, 0x14, 0x1a, 0x08, 0x06, 0x50, 0x01, +0x10, 0x12, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x36, +0x00, 0x00, 0x01, 0xc7, 0x03, 0x3d, 0x02, 0x26, 0x00, 0x3d, +0x00, 0x00, 0x01, 0x07, 0x01, 0x5f, 0x00, 0x00, 0x00, 0x8b, +0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xfc, 0x40, 0x09, 0x12, +0x16, 0x08, 0x06, 0x50, 0x01, 0x10, 0x17, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x49, 0x00, 0x00, +0x01, 0xab, 0x02, 0xb2, 0x02, 0x26, 0x00, 0x5d, 0x00, 0x00, +0x01, 0x06, 0x01, 0x5f, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x00, 0x12, 0x16, 0x08, 0x06, 0x50, 0x01, 0x10, 0x17, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x01, 0x00, 0xa1, 0x00, 0x00, +0x01, 0xe2, 0x02, 0xb5, 0x00, 0x13, 0x00, 0x2e, 0xb9, 0x00, +0x0f, 0xff, 0xe8, 0x40, 0x15, 0x11, 0x12, 0x00, 0x4c, 0x13, +0x7f, 0x00, 0x00, 0x15, 0x14, 0x09, 0x09, 0x15, 0x0a, 0x0a, +0x0d, 0x88, 0x06, 0x4d, 0x00, 0x4a, 0x00, 0x3f, 0x3f, 0xed, +0x32, 0x2f, 0x01, 0x11, 0x33, 0x2f, 0x11, 0x12, 0x39, 0x2f, +0xed, 0x31, 0x30, 0x2b, 0x33, 0x11, 0x34, 0x3e, 0x02, 0x33, +0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, +0x15, 0x11, 0xa1, 0x1e, 0x31, 0x41, 0x24, 0x24, 0x49, 0x20, +0x0f, 0x16, 0x42, 0x22, 0x15, 0x25, 0x1c, 0x10, 0x01, 0xfa, +0x36, 0x47, 0x2c, 0x12, 0x10, 0x0b, 0x47, 0x0b, 0x10, 0x0b, +0x1b, 0x2d, 0x22, 0xfe, 0x07, 0x00, 0xff, 0xff, 0x00, 0x37, +0xff, 0x56, 0x01, 0xbd, 0x02, 0x79, 0x02, 0x26, 0x00, 0x36, +0x00, 0x00, 0x01, 0x06, 0x01, 0xc3, 0xdd, 0x00, 0x00, 0x0d, +0xb9, 0x00, 0x01, 0xff, 0xd9, 0xb4, 0x3b, 0x35, 0x2e, 0x25, +0x50, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x42, +0xff, 0x56, 0x01, 0xb2, 0x01, 0xdb, 0x02, 0x26, 0x00, 0x56, +0x00, 0x00, 0x01, 0x06, 0x01, 0xc3, 0xdd, 0x00, 0x00, 0x0d, +0xb9, 0x00, 0x01, 0xff, 0xd9, 0xb4, 0x31, 0x2b, 0x22, 0x1b, +0x50, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x27, +0xff, 0x56, 0x01, 0xcd, 0x02, 0x6b, 0x02, 0x26, 0x00, 0x37, +0x00, 0x00, 0x01, 0x06, 0x01, 0xc3, 0xe4, 0x00, 0x00, 0x0d, +0xb9, 0x00, 0x01, 0xff, 0xe0, 0xb4, 0x11, 0x0b, 0x06, 0x00, +0x50, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x3f, +0xff, 0x56, 0x01, 0xc2, 0x02, 0x60, 0x02, 0x26, 0x00, 0x57, +0x00, 0x00, 0x01, 0x06, 0x01, 0xc3, 0x24, 0x00, 0x00, 0x0a, +0xb6, 0x01, 0x19, 0x25, 0x1f, 0x17, 0x0d, 0x50, 0x2b, 0x34, +0x00, 0x00, 0x00, 0x01, 0x00, 0x47, 0xff, 0x56, 0x01, 0x80, +0x01, 0xd0, 0x00, 0x13, 0x00, 0x2f, 0xb9, 0x00, 0x05, 0xff, +0xe8, 0x40, 0x16, 0x09, 0x0a, 0x00, 0x4c, 0x12, 0x7f, 0x03, +0x15, 0x0b, 0x0b, 0x00, 0x14, 0x0c, 0x0c, 0x0f, 0x88, 0x08, +0x52, 0x13, 0x85, 0x02, 0x49, 0x00, 0x3f, 0xed, 0x3f, 0xed, +0x32, 0x2f, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xde, 0xed, +0x31, 0x30, 0x2b, 0x13, 0x35, 0x21, 0x11, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, +0x35, 0x11, 0x72, 0x01, 0x0e, 0x1b, 0x2d, 0x3b, 0x21, 0x26, +0x4d, 0x22, 0x19, 0x19, 0x3d, 0x1c, 0x28, 0x34, 0x01, 0x8b, +0x45, 0xfe, 0x35, 0x30, 0x43, 0x2a, 0x12, 0x10, 0x11, 0x46, +0x0c, 0x11, 0x29, 0x3b, 0x01, 0x87, 0x00, 0x00, 0x00, 0x01, +0x00, 0xc4, 0x01, 0xf9, 0x01, 0x34, 0x02, 0xb5, 0x00, 0x0d, +0x00, 0x1a, 0x40, 0x0a, 0x0c, 0x0f, 0x0e, 0x06, 0x07, 0x07, +0x00, 0x0d, 0x0d, 0x06, 0x00, 0x2f, 0xcc, 0x01, 0x2f, 0xcd, +0x33, 0x2f, 0xcd, 0x11, 0x12, 0x39, 0x31, 0x30, 0x01, 0x14, +0x14, 0x07, 0x06, 0x06, 0x07, 0x27, 0x36, 0x36, 0x35, 0x34, +0x26, 0x27, 0x01, 0x34, 0x01, 0x03, 0x1f, 0x15, 0x38, 0x11, +0x0f, 0x01, 0x01, 0x02, 0xb5, 0x0a, 0x0e, 0x08, 0x2e, 0x4b, +0x23, 0x15, 0x23, 0x3f, 0x23, 0x09, 0x14, 0x05, 0x00, 0x01, +0x00, 0x81, 0x02, 0x0b, 0x01, 0x73, 0x02, 0xb2, 0x00, 0x05, +0x00, 0x25, 0x40, 0x0f, 0x03, 0x04, 0x01, 0x00, 0x40, 0x02, +0x02, 0x07, 0x06, 0x03, 0x03, 0x01, 0x80, 0x02, 0x05, 0x00, +0x2f, 0x33, 0x1a, 0xcd, 0x32, 0x2f, 0x01, 0x11, 0x12, 0x39, +0x19, 0x2f, 0x1a, 0xcd, 0x32, 0xcd, 0x32, 0x31, 0x30, 0x13, +0x37, 0x17, 0x37, 0x17, 0x07, 0x81, 0x22, 0x57, 0x57, 0x22, +0x79, 0x02, 0x8b, 0x27, 0x4e, 0x4e, 0x27, 0x80, 0x00, 0x00, +0xff, 0xff, 0x00, 0x7b, 0x02, 0x3b, 0x01, 0x79, 0x02, 0x7b, +0x02, 0x06, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x82, +0x02, 0x21, 0x01, 0x72, 0x02, 0x9d, 0x00, 0x15, 0x00, 0x15, +0xb7, 0x11, 0x10, 0x05, 0x06, 0x10, 0x06, 0x0b, 0x00, 0x00, +0x2f, 0xdd, 0xce, 0x32, 0x01, 0x2f, 0xcd, 0xde, 0xcd, 0x31, +0x30, 0x13, 0x22, 0x2e, 0x02, 0x37, 0x33, 0x1e, 0x03, 0x33, +0x32, 0x3e, 0x02, 0x37, 0x33, 0x16, 0x0e, 0x02, 0xfa, 0x19, +0x2c, 0x21, 0x12, 0x01, 0x36, 0x01, 0x06, 0x0f, 0x18, 0x13, +0x13, 0x19, 0x0e, 0x06, 0x01, 0x36, 0x01, 0x12, 0x21, 0x2c, +0x02, 0x21, 0x11, 0x1f, 0x2e, 0x1e, 0x0a, 0x17, 0x13, 0x0c, +0x0c, 0x13, 0x17, 0x0a, 0x1e, 0x2e, 0x1f, 0x11, 0x00, 0x01, +0x00, 0xbe, 0x02, 0x1e, 0x01, 0x36, 0x02, 0x97, 0x00, 0x0b, +0x00, 0x0d, 0xb3, 0x09, 0x03, 0x06, 0x00, 0x00, 0x2f, 0xcd, +0x01, 0x2f, 0xcd, 0x31, 0x30, 0x13, 0x22, 0x26, 0x35, 0x34, +0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0xfa, 0x19, 0x23, +0x23, 0x19, 0x19, 0x23, 0x23, 0x02, 0x1e, 0x21, 0x1c, 0x1b, +0x21, 0x21, 0x1b, 0x1c, 0x21, 0x00, 0x00, 0x00, 0x00, 0x02, +0x00, 0x9e, 0x02, 0x01, 0x01, 0x56, 0x02, 0xb8, 0x00, 0x0b, +0x00, 0x17, 0x00, 0x39, 0xb9, 0x00, 0x0b, 0xff, 0xe0, 0x40, +0x11, 0x08, 0x0f, 0x00, 0x4c, 0x07, 0x20, 0x08, 0x0f, 0x00, +0x4c, 0x05, 0x20, 0x08, 0x0f, 0x00, 0x4c, 0x01, 0xb8, 0xff, +0xe0, 0x40, 0x0c, 0x08, 0x0f, 0x00, 0x4c, 0x00, 0x0c, 0x06, +0x12, 0x09, 0x0f, 0x15, 0x03, 0x00, 0x2f, 0xdd, 0xde, 0xcd, +0x01, 0x2f, 0xcd, 0xde, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x01, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, +0x33, 0x32, 0x16, 0x07, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, +0x14, 0x16, 0x33, 0x32, 0x36, 0x01, 0x56, 0x37, 0x25, 0x25, +0x37, 0x37, 0x25, 0x25, 0x37, 0x2d, 0x1b, 0x14, 0x14, 0x1b, +0x1b, 0x14, 0x14, 0x1b, 0x02, 0x5d, 0x2b, 0x31, 0x31, 0x2b, +0x2a, 0x31, 0x31, 0x2a, 0x17, 0x1a, 0x1a, 0x17, 0x18, 0x1a, +0x1a, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xab, 0xff, 0x59, +0x01, 0x49, 0x00, 0x07, 0x00, 0x16, 0x00, 0x20, 0x40, 0x0d, +0x08, 0x03, 0x15, 0x09, 0x0f, 0x11, 0x40, 0x00, 0x17, 0x80, +0x08, 0x08, 0x17, 0x00, 0x11, 0x33, 0x2f, 0x1a, 0x10, 0xdc, +0x1a, 0xcd, 0x01, 0x2f, 0x33, 0xcc, 0xcd, 0x32, 0x31, 0x30, +0x05, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, 0x33, +0x06, 0x06, 0x07, 0x06, 0x06, 0x15, 0x14, 0x33, 0x32, 0x36, +0x37, 0x17, 0x06, 0x01, 0x0e, 0x33, 0x30, 0x17, 0x10, 0x15, +0x0e, 0x53, 0x0b, 0x19, 0x0d, 0x0d, 0x10, 0x24, 0x06, 0x14, +0x0a, 0x07, 0x17, 0xa7, 0x24, 0x20, 0x15, 0x25, 0x11, 0x17, +0x08, 0x08, 0x14, 0x0e, 0x0e, 0x15, 0x0d, 0x1a, 0x03, 0x03, +0x36, 0x0a, 0x00, 0x02, 0x00, 0x64, 0x02, 0x06, 0x01, 0x90, +0x02, 0xb5, 0x00, 0x03, 0x00, 0x07, 0x00, 0x20, 0x40, 0x0d, +0x07, 0x04, 0x05, 0x06, 0x03, 0x00, 0x01, 0x02, 0x07, 0x03, +0x80, 0x05, 0x01, 0x00, 0x2f, 0x33, 0x1a, 0xcd, 0x32, 0x01, +0x2f, 0x33, 0xcd, 0x32, 0xdc, 0x32, 0xcd, 0x32, 0x31, 0x30, +0x13, 0x07, 0x27, 0x37, 0x17, 0x07, 0x27, 0x37, 0xfd, 0x6e, +0x2b, 0x67, 0xc5, 0x6e, 0x2b, 0x67, 0x02, 0x83, 0x7d, 0x20, +0x8f, 0x32, 0x7d, 0x20, 0x8f, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x20, 0x00, 0x00, 0x01, 0xd4, 0x03, 0x3e, 0x02, 0x26, +0x00, 0x3a, 0x00, 0x00, 0x01, 0x07, 0x00, 0x43, 0x00, 0x00, +0x00, 0x89, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xfd, 0x40, +0x09, 0x18, 0x16, 0x06, 0x0d, 0x50, 0x01, 0x06, 0x17, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x13, +0x00, 0x00, 0x01, 0xe1, 0x02, 0xb5, 0x02, 0x26, 0x00, 0x5a, +0x00, 0x00, 0x01, 0x06, 0x00, 0x43, 0x00, 0x00, 0x00, 0x13, +0xb9, 0x00, 0x01, 0xff, 0xfd, 0x40, 0x09, 0x2e, 0x2c, 0x0e, +0x25, 0x50, 0x01, 0x0e, 0x2d, 0x4f, 0x2b, 0x2b, 0x34, 0x00, +0xff, 0xff, 0x00, 0x20, 0x00, 0x00, 0x01, 0xd4, 0x03, 0x3e, +0x02, 0x26, 0x00, 0x3a, 0x00, 0x00, 0x01, 0x07, 0x00, 0x8f, +0x00, 0x00, 0x00, 0x89, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x04, +0x17, 0x15, 0x06, 0x0d, 0x50, 0x01, 0x06, 0x16, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x13, 0x00, 0x00, +0x01, 0xe1, 0x02, 0xb5, 0x02, 0x26, 0x00, 0x5a, 0x00, 0x00, +0x01, 0x06, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x04, 0x2d, 0x2b, 0x0e, 0x25, 0x50, 0x01, 0x0e, 0x2c, +0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x20, 0x00, 0x00, +0x01, 0xd4, 0x03, 0x1a, 0x02, 0x26, 0x00, 0x3a, 0x00, 0x00, +0x01, 0x07, 0x00, 0x83, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x17, +0x40, 0x10, 0x02, 0x01, 0x00, 0x17, 0x29, 0x06, 0x0d, 0x50, +0x02, 0x06, 0x21, 0x4f, 0x01, 0x06, 0x15, 0x4f, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x13, +0x00, 0x00, 0x01, 0xe1, 0x02, 0x8f, 0x02, 0x26, 0x00, 0x5a, +0x00, 0x00, 0x01, 0x06, 0x00, 0x83, 0x00, 0x00, 0x00, 0x17, +0x40, 0x10, 0x02, 0x01, 0x00, 0x2d, 0x3f, 0x0e, 0x25, 0x50, +0x02, 0x0e, 0x37, 0x4f, 0x01, 0x0e, 0x2b, 0x4f, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x00, +0x01, 0xe8, 0x03, 0x3e, 0x02, 0x26, 0x00, 0x3c, 0x00, 0x00, +0x01, 0x07, 0x00, 0x43, 0x00, 0x00, 0x00, 0x89, 0x00, 0x13, +0xb9, 0x00, 0x01, 0xff, 0xfc, 0x40, 0x09, 0x14, 0x12, 0x04, +0x0c, 0x50, 0x01, 0x04, 0x13, 0x4f, 0x2b, 0x2b, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0x58, 0x01, 0xcd, +0x02, 0xb5, 0x02, 0x26, 0x00, 0x5c, 0x00, 0x00, 0x01, 0x06, +0x00, 0x43, 0x00, 0x00, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, +0xfe, 0x40, 0x09, 0x24, 0x22, 0x20, 0x15, 0x50, 0x01, 0x09, +0x23, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0x01, 0x00, 0x19, +0x00, 0x00, 0x01, 0xda, 0x02, 0x6b, 0x00, 0x03, 0x00, 0x23, +0x40, 0x12, 0x00, 0x02, 0x01, 0x02, 0x8d, 0x03, 0x00, 0x14, +0x03, 0x00, 0x03, 0x01, 0x02, 0x03, 0x56, 0x00, 0x01, 0x55, +0x00, 0x3f, 0x33, 0x3f, 0x33, 0x01, 0x2f, 0x2f, 0x87, 0x2b, +0x87, 0x7d, 0xc4, 0x31, 0x30, 0x33, 0x23, 0x01, 0x33, 0x5f, +0x46, 0x01, 0x7b, 0x46, 0x02, 0x6b, 0x00, 0x03, 0x00, 0x74, +0x01, 0x12, 0x01, 0x80, 0x02, 0x79, 0x00, 0x0b, 0x00, 0x1f, +0x00, 0x2b, 0x00, 0x82, 0xb5, 0x1d, 0x10, 0x15, 0x00, 0x4d, +0x19, 0xb8, 0xff, 0xe0, 0xb3, 0x15, 0x00, 0x4d, 0x13, 0xb8, +0xff, 0xe8, 0x40, 0x0f, 0x15, 0x00, 0x4d, 0x0f, 0x10, 0x15, +0x00, 0x4d, 0x0b, 0x18, 0x0b, 0x0d, 0x00, 0x4c, 0x07, 0xb8, +0xff, 0xe8, 0xb4, 0x0b, 0x0d, 0x00, 0x4c, 0x05, 0xb8, 0xff, +0xe8, 0x40, 0x28, 0x0b, 0x0d, 0x00, 0x4c, 0x01, 0x10, 0x0b, +0x0d, 0x00, 0x4c, 0x26, 0x20, 0x26, 0x20, 0x0c, 0x16, 0x96, +0x00, 0x0c, 0x96, 0x06, 0x00, 0xcf, 0x23, 0x01, 0x23, 0x40, +0x19, 0x1c, 0x48, 0x23, 0x30, 0x29, 0x01, 0x29, 0x29, 0x03, +0x1b, 0x98, 0x09, 0xb8, 0x01, 0x01, 0xb3, 0x11, 0x98, 0x03, +0x63, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x11, 0x39, 0x2f, 0x71, +0xcd, 0x2b, 0x5d, 0x01, 0x2f, 0xdc, 0xed, 0x10, 0xed, 0x11, +0x39, 0x39, 0x2f, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x34, 0x36, 0x33, 0x32, 0x16, +0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x37, 0x34, 0x2e, 0x02, +0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, +0x3e, 0x02, 0x27, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, +0x36, 0x33, 0x32, 0x16, 0x74, 0x47, 0x3f, 0x3f, 0x47, 0x47, +0x3f, 0x3f, 0x47, 0xca, 0x06, 0x10, 0x1a, 0x14, 0x14, 0x1a, +0x10, 0x07, 0x07, 0x10, 0x1a, 0x14, 0x14, 0x1a, 0x10, 0x06, +0x1e, 0x15, 0x11, 0x11, 0x14, 0x14, 0x11, 0x11, 0x15, 0x01, +0xc6, 0x57, 0x5c, 0x5c, 0x57, 0x58, 0x5c, 0x5c, 0x58, 0x19, +0x2e, 0x21, 0x14, 0x14, 0x21, 0x2e, 0x19, 0x1a, 0x2d, 0x21, +0x14, 0x14, 0x21, 0x2d, 0x1c, 0x0f, 0x17, 0x17, 0x0f, 0x10, +0x17, 0x17, 0x00, 0x02, 0x00, 0x69, 0x01, 0x19, 0x01, 0x80, +0x02, 0x72, 0x00, 0x0e, 0x00, 0x13, 0x00, 0x79, 0xb9, 0x00, +0x10, 0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x10, 0xb8, 0xff, +0xe8, 0x40, 0x45, 0x0f, 0x00, 0x4d, 0x0e, 0x20, 0x15, 0x00, +0x4d, 0x0c, 0x20, 0x18, 0x00, 0x4d, 0x0c, 0x10, 0x15, 0x00, +0x4d, 0x0c, 0x08, 0x14, 0x00, 0x4d, 0x0b, 0x18, 0x17, 0x00, +0x4d, 0x0b, 0x10, 0x16, 0x00, 0x4d, 0x0b, 0x18, 0x15, 0x00, +0x4d, 0x0b, 0x10, 0x14, 0x00, 0x4d, 0x09, 0x12, 0x0e, 0x10, +0x14, 0x00, 0x4d, 0x0e, 0x0f, 0x0f, 0x07, 0x96, 0x01, 0x04, +0x15, 0x04, 0x08, 0x09, 0x01, 0x12, 0x12, 0x06, 0x0f, 0x0e, +0x60, 0x06, 0xb8, 0x01, 0x00, 0x00, 0x3f, 0x3f, 0x33, 0x12, +0x39, 0x2f, 0x33, 0x33, 0xcd, 0x32, 0x01, 0x10, 0xde, 0x32, +0xfd, 0x32, 0x11, 0x33, 0x2b, 0xcd, 0x32, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, +0x15, 0x33, 0x15, 0x23, 0x15, 0x23, 0x35, 0x23, 0x35, 0x3e, +0x03, 0x37, 0x07, 0x06, 0x06, 0x07, 0x33, 0x01, 0x53, 0x2d, +0x2d, 0x3c, 0xae, 0x0c, 0x27, 0x30, 0x34, 0x1a, 0x03, 0x1c, +0x3a, 0x15, 0x6b, 0x02, 0x72, 0xd0, 0x35, 0x54, 0x54, 0x29, +0x16, 0x3a, 0x3c, 0x3a, 0x16, 0x4a, 0x1d, 0x47, 0x22, 0x00, +0x00, 0x01, 0x00, 0x7f, 0x01, 0x12, 0x01, 0x77, 0x02, 0x72, +0x00, 0x1d, 0x00, 0x84, 0xb9, 0x00, 0x1d, 0xff, 0xd8, 0xb3, +0x0f, 0x00, 0x4d, 0x1d, 0xb8, 0xff, 0xe0, 0xb3, 0x0e, 0x00, +0x4d, 0x1d, 0xb8, 0xff, 0xd8, 0xb3, 0x0d, 0x00, 0x4d, 0x1d, +0xb8, 0xff, 0xe0, 0xb3, 0x0c, 0x00, 0x4d, 0x1d, 0xb8, 0xff, +0xd8, 0xb3, 0x0b, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xf0, 0xb3, +0x10, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xe0, 0x40, 0x26, 0x0b, +0x0f, 0x00, 0x4c, 0x0f, 0x18, 0x18, 0x00, 0x4d, 0x18, 0x96, +0x15, 0x12, 0x17, 0x17, 0x0d, 0x96, 0x00, 0x1b, 0x96, 0x12, +0x06, 0x06, 0x12, 0x12, 0x98, 0x1b, 0x1b, 0x0a, 0x18, 0x98, +0x15, 0x60, 0x07, 0x07, 0x0a, 0x98, 0x03, 0xb8, 0x01, 0x01, +0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x12, 0x39, 0x2f, +0xed, 0x01, 0x2f, 0x32, 0x2f, 0x10, 0xed, 0xdc, 0xed, 0x33, +0x2f, 0x10, 0xd6, 0xed, 0x31, 0x30, 0x00, 0x2b, 0x01, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x14, 0x06, 0x23, +0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, +0x34, 0x2e, 0x02, 0x23, 0x36, 0x36, 0x37, 0x33, 0x15, 0x23, +0x06, 0x06, 0x07, 0x16, 0x16, 0x01, 0x77, 0x47, 0x4b, 0x1d, +0x3a, 0x0f, 0x0d, 0x0e, 0x2d, 0x1c, 0x30, 0x24, 0x0f, 0x25, +0x3d, 0x2e, 0x06, 0x08, 0x02, 0xc1, 0x8c, 0x02, 0x01, 0x04, +0x55, 0x4c, 0x01, 0x7f, 0x30, 0x3d, 0x0d, 0x08, 0x35, 0x05, +0x0d, 0x1f, 0x14, 0x0f, 0x19, 0x11, 0x0a, 0x2d, 0x5b, 0x2a, +0x38, 0x12, 0x24, 0x13, 0x05, 0x39, 0x00, 0x00, 0x00, 0x02, +0x00, 0x7d, 0x01, 0x12, 0x01, 0x82, 0x02, 0x74, 0x00, 0x18, +0x00, 0x25, 0x01, 0x54, 0xb9, 0x00, 0x1d, 0xff, 0xc8, 0xb3, +0x18, 0x00, 0x4d, 0x1d, 0xb8, 0xff, 0xd8, 0x40, 0x10, 0x16, +0x17, 0x00, 0x4c, 0x18, 0x18, 0x0d, 0x00, 0x4d, 0x18, 0x20, +0x0b, 0x0c, 0x00, 0x4c, 0x13, 0xb8, 0xff, 0xe8, 0xb3, 0x10, +0x00, 0x4d, 0x13, 0xb8, 0xff, 0xe0, 0xb4, 0x0e, 0x0f, 0x00, +0x4c, 0x13, 0xb8, 0xff, 0xe8, 0xb4, 0x0c, 0x0d, 0x00, 0x4c, +0x13, 0xb8, 0xff, 0xe0, 0xb3, 0x0b, 0x00, 0x4d, 0x0f, 0xb8, +0xff, 0xd0, 0xb3, 0x11, 0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xe8, +0xb3, 0x10, 0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xd8, 0xb3, 0x0f, +0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, +0x0f, 0xb8, 0xff, 0xe0, 0xb3, 0x0d, 0x00, 0x4d, 0x0f, 0xb8, +0xff, 0xd8, 0xb3, 0x0c, 0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xe8, +0xb3, 0x0b, 0x00, 0x4d, 0x0e, 0xb8, 0xff, 0xd0, 0xb3, 0x0b, +0x00, 0x4d, 0x08, 0xb8, 0xff, 0xd8, 0xb3, 0x18, 0x00, 0x4d, +0x08, 0xb8, 0xff, 0xe8, 0xb3, 0x16, 0x00, 0x4d, 0x08, 0xb8, +0xff, 0xe8, 0xb3, 0x14, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xf0, +0xb3, 0x13, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xd8, 0xb3, 0x17, +0x00, 0x4d, 0x07, 0xb8, 0xff, 0xd8, 0xb3, 0x15, 0x00, 0x4d, +0x07, 0xb8, 0xff, 0xd0, 0xb3, 0x10, 0x00, 0x4d, 0x07, 0xb8, +0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xe8, +0xb3, 0x0e, 0x00, 0x4d, 0x06, 0xb8, 0xff, 0xd0, 0xb3, 0x18, +0x00, 0x4d, 0x06, 0xb8, 0xff, 0xd8, 0xb3, 0x17, 0x00, 0x4d, +0x06, 0xb8, 0xff, 0xc8, 0xb3, 0x16, 0x00, 0x4d, 0x06, 0xb8, +0xff, 0xd0, 0xb3, 0x15, 0x00, 0x4d, 0x06, 0xb8, 0xff, 0xd8, +0x40, 0x26, 0x13, 0x14, 0x00, 0x4c, 0x01, 0x20, 0x1b, 0x00, +0x4d, 0x14, 0x10, 0x1c, 0x00, 0x4d, 0x13, 0x10, 0x1c, 0x00, +0x4d, 0x09, 0x1b, 0x96, 0x00, 0x23, 0x96, 0x11, 0x04, 0x04, +0x11, 0x00, 0x19, 0x98, 0x0c, 0x0c, 0x03, 0x1e, 0x98, 0x16, +0xb8, 0x01, 0x01, 0xb3, 0x04, 0x98, 0x03, 0x60, 0x00, 0x3f, +0xed, 0x3f, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x01, 0x2f, 0xcc, +0x32, 0x2f, 0x10, 0xed, 0x10, 0xed, 0x32, 0x31, 0x30, 0x00, +0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x34, 0x36, 0x37, 0x17, 0x0e, +0x03, 0x07, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, +0x0e, 0x02, 0x23, 0x22, 0x26, 0x37, 0x22, 0x07, 0x06, 0x16, +0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x26, 0x7d, 0x7c, 0x6b, +0x06, 0x1e, 0x36, 0x2c, 0x20, 0x06, 0x12, 0x21, 0x0e, 0x22, +0x30, 0x1e, 0x0d, 0x0f, 0x1f, 0x2f, 0x20, 0x44, 0x44, 0x82, +0x23, 0x21, 0x02, 0x20, 0x2b, 0x11, 0x17, 0x0f, 0x06, 0x1f, +0x01, 0xa5, 0x64, 0x69, 0x02, 0x37, 0x01, 0x0b, 0x16, 0x1f, +0x15, 0x08, 0x04, 0x12, 0x1e, 0x28, 0x16, 0x14, 0x28, 0x22, +0x15, 0x4e, 0x5f, 0x0b, 0x31, 0x3c, 0x0c, 0x12, 0x16, 0x09, +0x1d, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x86, 0x01, 0x19, +0x01, 0x85, 0x02, 0x72, 0x00, 0x0e, 0x00, 0x4f, 0xb9, 0x00, +0x0b, 0xff, 0xf0, 0xb3, 0x16, 0x00, 0x4d, 0x0b, 0xb8, 0xff, +0xf8, 0x40, 0x29, 0x12, 0x00, 0x4d, 0x04, 0x28, 0x13, 0x00, +0x4d, 0x04, 0x18, 0x11, 0x00, 0x4d, 0x03, 0x10, 0x15, 0x00, +0x4d, 0x03, 0x18, 0x14, 0x00, 0x4d, 0x03, 0x10, 0x13, 0x00, +0x4d, 0x06, 0x00, 0x96, 0x0e, 0x05, 0x96, 0x09, 0x10, 0x05, +0x98, 0x08, 0x60, 0x00, 0xb8, 0x01, 0x00, 0x00, 0x3f, 0x3f, +0xed, 0x01, 0x10, 0xde, 0xed, 0xde, 0xed, 0xcc, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x3e, 0x03, +0x37, 0x23, 0x35, 0x33, 0x15, 0x0e, 0x03, 0x07, 0xba, 0x04, +0x18, 0x22, 0x2a, 0x15, 0xb1, 0xff, 0x12, 0x2d, 0x28, 0x1e, +0x04, 0x01, 0x19, 0x26, 0x51, 0x4d, 0x43, 0x18, 0x3a, 0x31, +0x12, 0x40, 0x50, 0x59, 0x2d, 0x00, 0x00, 0x03, 0x00, 0x77, +0x01, 0x12, 0x01, 0x7d, 0x02, 0x79, 0x00, 0x1b, 0x00, 0x29, +0x00, 0x35, 0x02, 0xa6, 0x40, 0x0b, 0x26, 0x28, 0x18, 0x00, +0x4d, 0x26, 0x20, 0x11, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe8, +0xb3, 0x10, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xf0, 0xb3, 0x0f, +0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, +0x18, 0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, 0x18, 0xb8, +0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xd8, +0xb4, 0x0c, 0x11, 0x00, 0x4c, 0x14, 0xb8, 0xff, 0xe0, 0x40, +0x1f, 0x0b, 0x00, 0x4d, 0x0f, 0x20, 0x0b, 0x11, 0x00, 0x4c, +0x0c, 0x20, 0x12, 0x00, 0x4d, 0x0c, 0x28, 0x11, 0x00, 0x4d, +0x06, 0x20, 0x0c, 0x11, 0x00, 0x4c, 0x06, 0x28, 0x0b, 0x00, +0x4d, 0x01, 0xb8, 0xff, 0xe0, 0x40, 0x0a, 0x0b, 0x11, 0x00, +0x4c, 0x33, 0x08, 0x16, 0x00, 0x4d, 0x32, 0xb8, 0xff, 0xe8, +0xb3, 0x2e, 0x00, 0x4d, 0x32, 0xb8, 0xff, 0xf0, 0xb3, 0x2b, +0x00, 0x4d, 0x32, 0xb8, 0xff, 0xe8, 0xb3, 0x29, 0x00, 0x4d, +0x31, 0xb8, 0xff, 0xd0, 0xb3, 0x2e, 0x00, 0x4d, 0x31, 0xb8, +0xff, 0xe0, 0xb3, 0x2b, 0x00, 0x4d, 0x31, 0xb8, 0xff, 0xd0, +0xb3, 0x29, 0x00, 0x4d, 0x31, 0xb8, 0xff, 0xe0, 0xb3, 0x20, +0x00, 0x4d, 0x31, 0xb8, 0xff, 0xf0, 0xb3, 0x1f, 0x00, 0x4d, +0x31, 0xb8, 0xff, 0xe8, 0xb3, 0x1d, 0x00, 0x4d, 0x31, 0xb8, +0xff, 0xd0, 0xb4, 0x19, 0x1b, 0x00, 0x4c, 0x31, 0xb8, 0xff, +0xe0, 0xb3, 0x18, 0x00, 0x4d, 0x31, 0xb8, 0xff, 0xe8, 0x40, +0x93, 0x15, 0x16, 0x00, 0x4c, 0x29, 0x30, 0x2e, 0x00, 0x4d, +0x28, 0x18, 0x2e, 0x00, 0x4d, 0x28, 0x18, 0x1c, 0x00, 0x4d, +0x28, 0x10, 0x1b, 0x00, 0x4d, 0x28, 0x18, 0x1a, 0x00, 0x4d, +0x28, 0x10, 0x19, 0x00, 0x4d, 0x28, 0x18, 0x18, 0x00, 0x4d, +0x28, 0x18, 0x12, 0x00, 0x4d, 0x27, 0x10, 0x1b, 0x00, 0x4d, +0x26, 0x30, 0x2e, 0x00, 0x4d, 0x26, 0x18, 0x29, 0x00, 0x4d, +0x26, 0x10, 0x1f, 0x00, 0x4d, 0x26, 0x28, 0x1e, 0x00, 0x4d, +0x26, 0x18, 0x1a, 0x1c, 0x00, 0x4c, 0x26, 0x10, 0x19, 0x00, +0x4d, 0x26, 0x20, 0x18, 0x00, 0x4d, 0x26, 0x18, 0x17, 0x00, +0x4d, 0x26, 0x10, 0x16, 0x00, 0x4d, 0x26, 0x18, 0x11, 0x00, +0x4d, 0x25, 0x40, 0x2e, 0x00, 0x4d, 0x25, 0x28, 0x29, 0x00, +0x4d, 0x25, 0x28, 0x1f, 0x00, 0x4d, 0x25, 0x18, 0x1d, 0x00, +0x4d, 0x25, 0x28, 0x1c, 0x00, 0x4d, 0x25, 0x38, 0x19, 0x1b, +0x00, 0x4c, 0x25, 0x18, 0x15, 0x00, 0x4d, 0x25, 0x30, 0x14, +0x00, 0x4d, 0x25, 0x28, 0x12, 0x00, 0x4d, 0x1a, 0xb8, 0xff, +0xf0, 0xb3, 0x1e, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe8, 0xb3, +0x17, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xc8, 0x40, 0x09, 0x16, +0x00, 0x4d, 0x18, 0x20, 0x1e, 0x00, 0x4d, 0x14, 0xb8, 0xff, +0xd8, 0xb3, 0x20, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xe8, 0xb4, +0x1d, 0x1e, 0x00, 0x4c, 0x14, 0xb8, 0xff, 0xf0, 0xb3, 0x14, +0x00, 0x4d, 0x14, 0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, +0x0f, 0xb8, 0xff, 0xe8, 0x40, 0x09, 0x20, 0x00, 0x4d, 0x0f, +0x18, 0x1f, 0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xe8, 0x40, 0x0e, +0x1d, 0x00, 0x4d, 0x0c, 0x18, 0x29, 0x00, 0x4d, 0x0c, 0x28, +0x1e, 0x00, 0x4d, 0x0a, 0xb8, 0xff, 0xf0, 0xb3, 0x17, 0x00, +0x4d, 0x0a, 0xb8, 0xff, 0xd8, 0x40, 0x0e, 0x16, 0x00, 0x4d, +0x06, 0x18, 0x1e, 0x00, 0x4d, 0x06, 0x10, 0x1d, 0x00, 0x4d, +0x05, 0xb8, 0xff, 0xf0, 0xb3, 0x1f, 0x00, 0x4d, 0x01, 0xb8, +0xff, 0xd8, 0x40, 0x49, 0x1f, 0x00, 0x4d, 0x01, 0x10, 0x1e, +0x00, 0x4d, 0x01, 0x18, 0x1d, 0x00, 0x4d, 0x19, 0x33, 0x27, +0x0b, 0x04, 0x16, 0x30, 0x96, 0x0e, 0x0e, 0x08, 0x2a, 0x96, +0x16, 0x16, 0xff, 0x24, 0x01, 0x24, 0x96, 0x00, 0x1c, 0x96, +0x08, 0x27, 0x10, 0x18, 0x00, 0x4d, 0x5b, 0x27, 0x01, 0x3f, +0x27, 0x01, 0x27, 0x98, 0x19, 0x0b, 0x5f, 0x33, 0x8f, 0x33, +0x02, 0x7f, 0x33, 0xdf, 0x33, 0x02, 0x8f, 0x33, 0x01, 0x33, +0x2d, 0x98, 0x11, 0x63, 0x21, 0x98, 0x03, 0xb8, 0x01, 0x01, +0x00, 0x3f, 0xed, 0x3f, 0xed, 0x2f, 0x5d, 0x71, 0x72, 0x33, +0x33, 0xed, 0x71, 0x71, 0x2b, 0x01, 0x2f, 0xed, 0xdc, 0xed, +0x5d, 0x33, 0x2f, 0xed, 0x11, 0x33, 0x2f, 0xed, 0x12, 0x17, +0x39, 0x31, 0x30, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x01, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x34, 0x36, 0x37, 0x26, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, +0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, 0x16, 0x16, 0x07, 0x14, +0x1e, 0x02, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x27, 0x06, +0x06, 0x37, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, +0x17, 0x36, 0x36, 0x01, 0x7d, 0x43, 0x41, 0x26, 0x32, 0x1e, +0x0c, 0x20, 0x15, 0x14, 0x18, 0x41, 0x38, 0x21, 0x2e, 0x1d, +0x0e, 0x1a, 0x15, 0x20, 0x17, 0xc6, 0x07, 0x10, 0x1a, 0x13, +0x25, 0x1f, 0x33, 0x2d, 0x13, 0x15, 0x80, 0x1b, 0x21, 0x21, +0x1b, 0x26, 0x2a, 0x12, 0x16, 0x01, 0x77, 0x2d, 0x38, 0x13, +0x1d, 0x22, 0x10, 0x19, 0x2c, 0x0e, 0x0f, 0x2a, 0x17, 0x28, +0x3a, 0x12, 0x1b, 0x21, 0x10, 0x19, 0x28, 0x0e, 0x10, 0x28, +0x20, 0x07, 0x10, 0x0d, 0x09, 0x1b, 0x12, 0x19, 0x1c, 0x0b, +0x0e, 0x1e, 0x94, 0x0b, 0x1d, 0x1c, 0x0e, 0x12, 0x21, 0x08, +0x0d, 0x1c, 0x00, 0x02, 0x00, 0x84, 0x01, 0x18, 0x01, 0x89, +0x02, 0x79, 0x00, 0x16, 0x00, 0x23, 0x00, 0x8c, 0x40, 0x0c, +0x1c, 0x18, 0x18, 0x00, 0x4d, 0x1c, 0x20, 0x16, 0x17, 0x00, +0x4c, 0x16, 0xb8, 0xff, 0xd8, 0x40, 0x57, 0x0b, 0x0d, 0x00, +0x4c, 0x12, 0x10, 0x19, 0x00, 0x4d, 0x11, 0x08, 0x19, 0x00, +0x4d, 0x11, 0x18, 0x10, 0x00, 0x4d, 0x11, 0x20, 0x0b, 0x0f, +0x00, 0x4c, 0x0d, 0x18, 0x0e, 0x10, 0x00, 0x4c, 0x0d, 0x28, +0x0b, 0x0d, 0x00, 0x4c, 0x06, 0x18, 0x17, 0x18, 0x00, 0x4c, +0x06, 0x20, 0x16, 0x00, 0x4d, 0x06, 0x18, 0x15, 0x00, 0x4d, +0x06, 0x20, 0x0e, 0x10, 0x00, 0x4c, 0x05, 0x38, 0x15, 0x00, +0x4d, 0x07, 0x1a, 0x96, 0x00, 0x22, 0x96, 0x0f, 0x04, 0x04, +0x0f, 0x17, 0x98, 0x0a, 0x0a, 0x03, 0x1d, 0x98, 0x14, 0x63, +0x04, 0x98, 0x03, 0x5f, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x11, +0x39, 0x2f, 0xed, 0x01, 0x2f, 0x33, 0x2f, 0x10, 0xed, 0xdc, +0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x14, +0x06, 0x23, 0x27, 0x36, 0x36, 0x37, 0x06, 0x06, 0x23, 0x22, +0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x07, +0x32, 0x36, 0x37, 0x36, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, +0x14, 0x01, 0x89, 0x7b, 0x74, 0x02, 0x41, 0x5c, 0x0d, 0x12, +0x21, 0x0e, 0x22, 0x30, 0x1e, 0x0d, 0x0f, 0x1f, 0x2f, 0x20, +0x43, 0x45, 0x82, 0x12, 0x22, 0x10, 0x02, 0x20, 0x2b, 0x11, +0x17, 0x0f, 0x07, 0x01, 0xe7, 0x64, 0x6b, 0x36, 0x02, 0x2a, +0x2b, 0x08, 0x05, 0x12, 0x1f, 0x28, 0x15, 0x13, 0x29, 0x22, +0x15, 0x4d, 0x5f, 0x04, 0x06, 0x31, 0x3c, 0x0c, 0x12, 0x15, +0x0a, 0x3a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x74, 0xff, 0xfa, +0x01, 0x80, 0x01, 0x61, 0x02, 0x07, 0x01, 0x6f, 0x00, 0x00, +0xfe, 0xe8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7e, 0x00, 0x01, +0x01, 0x7f, 0x01, 0x5a, 0x02, 0x07, 0x00, 0x94, 0x00, 0x00, +0xfe, 0xe8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7c, 0x00, 0x01, +0x01, 0x78, 0x01, 0x61, 0x02, 0x07, 0x00, 0x8d, 0x00, 0x00, +0xfe, 0xe8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7e, 0xff, 0xfa, +0x01, 0x76, 0x01, 0x61, 0x02, 0x07, 0x00, 0x8e, 0x00, 0x00, +0xfe, 0xe8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x69, 0x00, 0x01, +0x01, 0x80, 0x01, 0x5a, 0x02, 0x07, 0x01, 0x70, 0x00, 0x00, +0xfe, 0xe8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7f, 0xff, 0xfa, +0x01, 0x77, 0x01, 0x5a, 0x02, 0x07, 0x01, 0x71, 0x00, 0x00, +0xfe, 0xe8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7d, 0xff, 0xfa, +0x01, 0x82, 0x01, 0x5c, 0x02, 0x07, 0x01, 0x72, 0x00, 0x00, +0xfe, 0xe8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x86, 0x00, 0x01, +0x01, 0x85, 0x01, 0x5a, 0x02, 0x07, 0x01, 0x73, 0x00, 0x00, +0xfe, 0xe8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x77, 0xff, 0xfa, +0x01, 0x7d, 0x01, 0x61, 0x02, 0x07, 0x01, 0x74, 0x00, 0x00, +0xfe, 0xe8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x84, 0x00, 0x00, +0x01, 0x89, 0x01, 0x61, 0x02, 0x07, 0x01, 0x75, 0x00, 0x00, +0xfe, 0xe8, 0x00, 0x00, 0x00, 0x02, 0x00, 0x35, 0xff, 0xf3, +0x01, 0xad, 0x02, 0xb5, 0x00, 0x21, 0x00, 0x2f, 0x00, 0xc0, +0x40, 0x20, 0x23, 0x18, 0x11, 0x00, 0x4d, 0x23, 0x28, 0x0f, +0x00, 0x4d, 0x23, 0x10, 0x09, 0x00, 0x4d, 0x1c, 0x20, 0x0c, +0x00, 0x4d, 0x1c, 0x18, 0x0b, 0x00, 0x4d, 0x1c, 0x20, 0x09, +0x0a, 0x00, 0x4c, 0x17, 0xb8, 0xff, 0xf0, 0xb3, 0x10, 0x00, +0x4d, 0x0d, 0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, 0x0d, +0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x09, 0xb8, 0xff, +0xd8, 0xb3, 0x09, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xf0, 0xb4, +0x0d, 0x0e, 0x00, 0x4c, 0x08, 0xb8, 0xff, 0xe8, 0xb3, 0x0c, +0x00, 0x4d, 0x08, 0xb8, 0xff, 0xe0, 0x40, 0x36, 0x0a, 0x0b, +0x00, 0x4c, 0x03, 0x10, 0x0c, 0x00, 0x4d, 0x03, 0x18, 0x0b, +0x00, 0x4d, 0x03, 0x10, 0x0a, 0x00, 0x4d, 0x03, 0x18, 0x09, +0x00, 0x4d, 0x25, 0x0b, 0x16, 0x16, 0x0b, 0x31, 0x22, 0x0e, +0x00, 0x21, 0x21, 0x1f, 0x00, 0x30, 0x22, 0x00, 0x21, 0x1f, +0x0e, 0x20, 0x20, 0x19, 0x06, 0x15, 0x15, 0x12, 0x19, 0x5c, +0x2a, 0x06, 0x00, 0x2f, 0xcd, 0x3f, 0xcd, 0x32, 0x2f, 0x11, +0x12, 0x39, 0x2f, 0x33, 0x33, 0xcd, 0x32, 0x32, 0x01, 0x10, +0xc4, 0x32, 0x32, 0x2f, 0x10, 0xcd, 0x32, 0x10, 0xce, 0x32, +0x2f, 0x10, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x37, 0x11, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, +0x02, 0x15, 0x14, 0x06, 0x07, 0x15, 0x14, 0x16, 0x33, 0x32, +0x36, 0x37, 0x17, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x35, 0x07, 0x27, 0x37, 0x36, 0x36, 0x35, 0x34, 0x2e, 0x02, +0x23, 0x22, 0x0e, 0x02, 0x15, 0x90, 0x18, 0x28, 0x36, 0x1d, +0x26, 0x2f, 0x1b, 0x09, 0x66, 0x54, 0x2a, 0x2d, 0x1d, 0x26, +0x10, 0x21, 0x17, 0x40, 0x2b, 0x2c, 0x3c, 0x24, 0x0f, 0x3b, +0x20, 0xad, 0x39, 0x40, 0x04, 0x0c, 0x15, 0x11, 0x0e, 0x18, +0x12, 0x0b, 0xe4, 0x01, 0x02, 0x3d, 0x51, 0x2e, 0x13, 0x1c, +0x2d, 0x36, 0x1a, 0x5f, 0x9d, 0x46, 0x27, 0x3f, 0x39, 0x16, +0x0b, 0x3e, 0x14, 0x17, 0x1a, 0x2d, 0x3b, 0x20, 0x07, 0x2a, +0x30, 0x82, 0x34, 0x79, 0x4c, 0x0f, 0x1e, 0x18, 0x0f, 0x0a, +0x1e, 0x35, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1b, +0xff, 0xf4, 0x01, 0xd9, 0x01, 0x86, 0x00, 0x20, 0x00, 0x31, +0x00, 0x42, 0x40, 0x19, 0x46, 0x0e, 0x56, 0x0e, 0x02, 0x05, +0x0e, 0x01, 0x0c, 0x0d, 0x0d, 0x21, 0x20, 0x33, 0x2b, 0x03, +0x15, 0x32, 0x00, 0x2e, 0x2e, 0x09, 0x26, 0x1a, 0x0c, 0xb8, +0xff, 0xc0, 0xb6, 0x09, 0x0e, 0x48, 0x0c, 0x0c, 0x09, 0x10, +0x00, 0x2f, 0xcd, 0x32, 0x2f, 0x2b, 0x2f, 0xcd, 0x12, 0x39, +0x2f, 0xcd, 0x01, 0x10, 0xd6, 0xcd, 0x32, 0x10, 0xde, 0xcd, +0x33, 0x2f, 0x33, 0x31, 0x30, 0x00, 0x5d, 0x5d, 0x37, 0x22, +0x15, 0x15, 0x14, 0x16, 0x17, 0x16, 0x16, 0x33, 0x32, 0x36, +0x37, 0x33, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, +0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x15, 0x27, 0x34, +0x27, 0x26, 0x26, 0x23, 0x22, 0x06, 0x07, 0x06, 0x15, 0x15, +0x14, 0x33, 0x21, 0x32, 0x35, 0x70, 0x04, 0x03, 0x02, 0x1c, +0x44, 0x2a, 0x2c, 0x49, 0x1b, 0x20, 0x1d, 0x5e, 0x36, 0x2f, +0x51, 0x3c, 0x23, 0x23, 0x3c, 0x51, 0x2f, 0x2e, 0x51, 0x3d, +0x23, 0x52, 0x05, 0x1a, 0x45, 0x28, 0x29, 0x45, 0x1b, 0x06, +0x04, 0x01, 0x14, 0x03, 0xb7, 0x02, 0x6e, 0x04, 0x05, 0x03, +0x1d, 0x1f, 0x25, 0x1e, 0x23, 0x2b, 0x20, 0x36, 0x49, 0x29, +0x2a, 0x4a, 0x36, 0x20, 0x20, 0x36, 0x4a, 0x2a, 0x05, 0x7d, +0x06, 0x07, 0x1a, 0x1f, 0x20, 0x1b, 0x06, 0x08, 0x6b, 0x04, +0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0c, 0xff, 0xf9, +0x01, 0xe0, 0x02, 0x72, 0x00, 0x03, 0x00, 0x2e, 0x00, 0x39, +0x01, 0x1d, 0xb9, 0x00, 0x2a, 0xff, 0xe8, 0xb3, 0x11, 0x00, +0x4d, 0x29, 0xb8, 0xff, 0xe8, 0xb3, 0x15, 0x00, 0x4d, 0x29, +0xb8, 0xff, 0xf0, 0xb3, 0x14, 0x00, 0x4d, 0x29, 0xb8, 0xff, +0xe8, 0xb3, 0x13, 0x00, 0x4d, 0x29, 0xb8, 0xff, 0xe0, 0xb3, +0x12, 0x00, 0x4d, 0x29, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, +0x4d, 0x29, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x29, +0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x25, 0xb8, 0xff, +0xe0, 0xb3, 0x13, 0x00, 0x4d, 0x25, 0xb8, 0xff, 0xe8, 0xb4, +0x10, 0x12, 0x00, 0x4c, 0x25, 0xb8, 0xff, 0xf0, 0xb4, 0x0e, +0x0f, 0x00, 0x4c, 0x20, 0xb8, 0xff, 0xe0, 0xb3, 0x18, 0x00, +0x4d, 0x20, 0xb8, 0xff, 0xe8, 0xb3, 0x17, 0x00, 0x4d, 0x20, +0xb8, 0xff, 0xe0, 0xb4, 0x13, 0x16, 0x00, 0x4c, 0x20, 0xb8, +0xff, 0xd8, 0xb3, 0x12, 0x00, 0x4d, 0x20, 0xb8, 0xff, 0xe8, +0x40, 0x51, 0x11, 0x00, 0x4d, 0x02, 0x00, 0x03, 0x00, 0x9c, +0x3a, 0x02, 0x14, 0x3a, 0x3a, 0x02, 0x34, 0x96, 0x32, 0x35, +0x2f, 0x01, 0x01, 0x2f, 0x1a, 0x1a, 0x0e, 0x0e, 0x2e, 0x27, +0x25, 0x13, 0x96, 0x22, 0x22, 0x27, 0x03, 0x03, 0x0a, 0x96, +0x27, 0x35, 0x61, 0x39, 0x2f, 0x2f, 0x36, 0x32, 0x60, 0x25, +0x3f, 0x0e, 0x4f, 0x0e, 0x02, 0x0e, 0x98, 0x30, 0x0f, 0x40, +0x0f, 0x02, 0x0f, 0x0f, 0x1d, 0x04, 0x04, 0x07, 0x98, 0x2c, +0x68, 0x19, 0x19, 0x16, 0x98, 0x1d, 0x66, 0x02, 0x03, 0x59, +0x00, 0x01, 0x5b, 0x00, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0xed, +0x32, 0x2f, 0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x2f, 0x71, +0xed, 0x71, 0x39, 0x3f, 0x33, 0x33, 0x2f, 0xcd, 0x3f, 0x01, +0x2f, 0xed, 0x33, 0x2f, 0x11, 0x33, 0x2f, 0xed, 0x32, 0x10, +0xcd, 0x32, 0x2f, 0x32, 0x2f, 0x2f, 0x33, 0x2f, 0x10, 0xdc, +0x32, 0xed, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, +0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x33, 0x23, 0x01, +0x33, 0x03, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, +0x23, 0x23, 0x35, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, +0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, +0x15, 0x14, 0x06, 0x07, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x27, 0x01, 0x36, 0x36, 0x37, 0x33, 0x15, 0x23, 0x35, +0x06, 0x06, 0x07, 0x52, 0x46, 0x01, 0x7b, 0x46, 0x9f, 0x0b, +0x21, 0x14, 0x17, 0x20, 0x26, 0x26, 0x0c, 0x16, 0x1a, 0x1c, +0x19, 0x0e, 0x0e, 0x24, 0x0c, 0x13, 0x0f, 0x31, 0x1a, 0x11, +0x20, 0x19, 0x0f, 0x0f, 0x0f, 0x2a, 0x0c, 0x1a, 0x29, 0x1e, +0x2f, 0x25, 0xfe, 0xf1, 0x23, 0x2f, 0x18, 0x29, 0x3b, 0x14, +0x21, 0x12, 0x02, 0x6b, 0xfd, 0xcc, 0x04, 0x08, 0x0d, 0x10, +0x16, 0x0c, 0x32, 0x0b, 0x12, 0x0e, 0x0a, 0x0a, 0x05, 0x2b, +0x09, 0x0d, 0x07, 0x0f, 0x19, 0x12, 0x0f, 0x1e, 0x0b, 0x14, +0x2d, 0x0e, 0x1d, 0x17, 0x0e, 0x0e, 0x02, 0x2a, 0x0e, 0x1c, +0x17, 0xfa, 0xa8, 0x0b, 0x0e, 0x06, 0x00, 0x03, 0x00, 0x15, +0xff, 0xf9, 0x01, 0xe3, 0x02, 0x78, 0x00, 0x03, 0x00, 0x22, +0x00, 0x4c, 0x01, 0x3d, 0xb9, 0x00, 0x47, 0xff, 0xe0, 0xb4, +0x14, 0x15, 0x00, 0x4c, 0x47, 0xb8, 0xff, 0xe8, 0xb4, 0x11, +0x13, 0x00, 0x4c, 0x47, 0xb8, 0xff, 0xe0, 0xb4, 0x0e, 0x10, +0x00, 0x4c, 0x40, 0xb8, 0xff, 0xc8, 0xb3, 0x10, 0x00, 0x4d, +0x40, 0xb8, 0xff, 0xd0, 0xb4, 0x0e, 0x0f, 0x00, 0x4c, 0x3f, +0xb8, 0xff, 0xe0, 0xb3, 0x18, 0x00, 0x4d, 0x3f, 0xb8, 0xff, +0xe8, 0xb3, 0x17, 0x00, 0x4d, 0x3f, 0xb8, 0xff, 0xe0, 0xb3, +0x16, 0x00, 0x4d, 0x3f, 0xb8, 0xff, 0xe8, 0xb4, 0x13, 0x15, +0x00, 0x4c, 0x3f, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, +0x3f, 0xb8, 0xff, 0xd8, 0xb3, 0x11, 0x00, 0x4d, 0x1f, 0xb8, +0xff, 0xe0, 0xb3, 0x15, 0x00, 0x4d, 0x1f, 0xb8, 0xff, 0xe8, +0xb3, 0x14, 0x00, 0x4d, 0x1f, 0xb8, 0xff, 0xe0, 0xb4, 0x12, +0x13, 0x00, 0x4c, 0x1c, 0xb8, 0xff, 0xf0, 0xb3, 0x15, 0x00, +0x4d, 0x1c, 0xb8, 0xff, 0xe8, 0xb4, 0x11, 0x14, 0x00, 0x4c, +0x1c, 0xb8, 0xff, 0xd8, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x1c, +0xb8, 0xff, 0xe0, 0xb3, 0x0e, 0x00, 0x4d, 0x1c, 0xb8, 0xff, +0xd0, 0x40, 0x4f, 0x0d, 0x00, 0x4d, 0x18, 0x18, 0x15, 0x16, +0x00, 0x4c, 0x43, 0x32, 0x96, 0x41, 0x45, 0x39, 0x4c, 0x2d, +0x2d, 0x4c, 0x29, 0x96, 0x45, 0x00, 0x02, 0x01, 0x02, 0x9c, +0x03, 0x00, 0x14, 0x03, 0x00, 0x03, 0x03, 0x45, 0x4e, 0x10, +0x96, 0x04, 0x1d, 0x16, 0x17, 0x09, 0x01, 0x01, 0x22, 0x96, +0x09, 0x43, 0x2d, 0x2e, 0x2e, 0x3c, 0x23, 0x23, 0x26, 0x4a, +0x68, 0x38, 0x38, 0x35, 0x3c, 0x66, 0x16, 0x16, 0x13, 0x98, +0x1a, 0x63, 0x22, 0x98, 0x06, 0x61, 0x02, 0x03, 0x59, 0x00, +0x01, 0x5b, 0x00, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0xed, 0x3f, +0xed, 0x32, 0x2f, 0x3f, 0xcd, 0x32, 0x2f, 0x3f, 0xcd, 0x32, +0x2f, 0x11, 0x39, 0x2f, 0xcd, 0x39, 0x01, 0x2f, 0xed, 0x33, +0x2f, 0x10, 0xc0, 0x32, 0x2f, 0xc6, 0xed, 0x10, 0xce, 0x32, +0x2f, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, 0x10, 0xfd, +0xc4, 0x32, 0x2f, 0x10, 0xc6, 0x10, 0xd4, 0xed, 0x32, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x33, 0x23, 0x01, 0x33, 0x05, 0x15, 0x23, 0x26, 0x34, +0x35, 0x34, 0x36, 0x37, 0x37, 0x36, 0x36, 0x35, 0x34, 0x26, +0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, 0x16, +0x15, 0x14, 0x0e, 0x02, 0x07, 0x13, 0x16, 0x16, 0x33, 0x32, +0x36, 0x35, 0x34, 0x26, 0x23, 0x23, 0x35, 0x33, 0x32, 0x36, +0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, +0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x07, 0x16, 0x15, 0x14, +0x0e, 0x02, 0x23, 0x22, 0x27, 0x68, 0x46, 0x01, 0x7b, 0x46, +0xfe, 0xf9, 0xc6, 0x01, 0x29, 0x1a, 0x16, 0x17, 0x13, 0x17, +0x10, 0x0f, 0x20, 0x0c, 0x21, 0x12, 0x33, 0x1a, 0x30, 0x2f, +0x1b, 0x25, 0x28, 0x0d, 0xd0, 0x0b, 0x21, 0x14, 0x17, 0x20, +0x26, 0x26, 0x0c, 0x16, 0x1a, 0x1c, 0x19, 0x0e, 0x0e, 0x24, +0x0c, 0x13, 0x0f, 0x31, 0x1a, 0x11, 0x20, 0x19, 0x0f, 0x1e, +0x2a, 0x0c, 0x1a, 0x29, 0x1e, 0x2f, 0x25, 0x02, 0x6b, 0xc1, +0x32, 0x03, 0x11, 0x03, 0x20, 0x23, 0x10, 0x0f, 0x0e, 0x16, +0x0e, 0x11, 0x10, 0x0c, 0x0d, 0x27, 0x13, 0x13, 0x32, 0x20, +0x1a, 0x24, 0x1c, 0x16, 0x0c, 0xfe, 0x8d, 0x04, 0x08, 0x0d, +0x10, 0x16, 0x0c, 0x32, 0x0b, 0x12, 0x0e, 0x0a, 0x0a, 0x05, +0x2b, 0x09, 0x0d, 0x07, 0x0f, 0x19, 0x12, 0x20, 0x18, 0x13, +0x2e, 0x0e, 0x1d, 0x17, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x05, +0xff, 0xff, 0xff, 0xf9, 0x01, 0xd7, 0x02, 0x72, 0x00, 0x1f, +0x00, 0x23, 0x00, 0x2e, 0x00, 0x39, 0x00, 0x44, 0x00, 0xfd, +0x40, 0x0c, 0x31, 0x30, 0x16, 0x00, 0x4d, 0x1e, 0x28, 0x0e, +0x15, 0x00, 0x4c, 0x18, 0xb8, 0xff, 0xe0, 0xb4, 0x0e, 0x15, +0x00, 0x4c, 0x12, 0xb8, 0xff, 0xc8, 0xb3, 0x17, 0x00, 0x4d, +0x12, 0xb8, 0xff, 0xd0, 0xb3, 0x16, 0x00, 0x4d, 0x0e, 0xb8, +0xff, 0xd0, 0x40, 0x11, 0x0e, 0x15, 0x00, 0x4c, 0x08, 0x20, +0x0e, 0x15, 0x00, 0x4c, 0x04, 0x28, 0x16, 0x17, 0x00, 0x4c, +0x3b, 0xb8, 0xff, 0xf0, 0x40, 0x70, 0x17, 0x00, 0x4d, 0x33, +0x20, 0x18, 0x00, 0x4d, 0x33, 0x18, 0x17, 0x00, 0x4d, 0x33, +0x20, 0x16, 0x00, 0x4d, 0x31, 0x18, 0x17, 0x00, 0x4d, 0x31, +0x10, 0x16, 0x00, 0x4d, 0x30, 0x20, 0x17, 0x18, 0x00, 0x4c, +0x12, 0x18, 0x18, 0x00, 0x4d, 0x04, 0x20, 0x18, 0x00, 0x4d, +0x29, 0x96, 0x27, 0x2a, 0x24, 0x20, 0x22, 0x21, 0x22, 0x9c, +0x23, 0x20, 0x14, 0x23, 0x23, 0x20, 0x21, 0x24, 0x23, 0x23, +0x16, 0x03, 0x32, 0x3d, 0x13, 0x04, 0x06, 0x3f, 0x96, 0x10, +0x10, 0x16, 0x3a, 0x96, 0x06, 0x06, 0x34, 0x96, 0x00, 0x2f, +0x96, 0x16, 0x2a, 0x61, 0x2e, 0x24, 0x24, 0x2b, 0x27, 0x60, +0x22, 0x23, 0x59, 0x20, 0x21, 0x13, 0x3d, 0x3d, 0x0b, 0x37, +0x03, 0x32, 0x32, 0x1b, 0x68, 0x42, 0x0b, 0x66, 0x00, 0x3f, +0xcd, 0x3f, 0x39, 0x11, 0x33, 0xcd, 0x11, 0x39, 0x11, 0x33, +0x2f, 0x33, 0x3f, 0x33, 0x3f, 0x33, 0x33, 0x2f, 0xcd, 0x3f, +0x01, 0x2f, 0xed, 0xdc, 0xed, 0x33, 0x2f, 0xed, 0x11, 0x33, +0x2f, 0xed, 0x12, 0x17, 0x39, 0x11, 0x33, 0x2f, 0x2f, 0x33, +0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, 0x10, 0xdc, +0x32, 0xed, 0x31, 0x30, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x37, 0x34, 0x36, 0x37, 0x26, 0x26, 0x35, +0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, +0x07, 0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, +0x02, 0x07, 0x23, 0x01, 0x33, 0x05, 0x36, 0x36, 0x37, 0x33, +0x15, 0x23, 0x35, 0x06, 0x06, 0x07, 0x01, 0x34, 0x26, 0x27, +0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x27, 0x14, 0x16, +0x17, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0xff, 0x12, +0x19, 0x0f, 0x13, 0x11, 0x1c, 0x24, 0x13, 0x12, 0x24, 0x1c, +0x11, 0x0f, 0x17, 0x14, 0x1a, 0x13, 0x1e, 0x27, 0x14, 0x15, +0x27, 0x1e, 0x12, 0xba, 0x46, 0x01, 0x7b, 0x46, 0xfe, 0x50, +0x23, 0x2f, 0x18, 0x29, 0x3b, 0x14, 0x21, 0x12, 0x01, 0x7b, +0x29, 0x1a, 0x1f, 0x20, 0x11, 0x13, 0x1e, 0x59, 0x1e, 0x16, +0x1d, 0x16, 0x15, 0x0e, 0x18, 0x45, 0x0c, 0x24, 0x0b, 0x09, +0x1c, 0x17, 0x12, 0x1b, 0x12, 0x08, 0x09, 0x12, 0x1b, 0x11, +0x0e, 0x1c, 0x0d, 0x09, 0x1d, 0x19, 0x13, 0x1d, 0x13, 0x0a, +0x08, 0x12, 0x1d, 0x30, 0x02, 0x6b, 0x3a, 0x0e, 0x1c, 0x17, +0xfa, 0xa8, 0x0b, 0x0e, 0x06, 0xfe, 0x44, 0x12, 0x0f, 0x08, +0x10, 0x19, 0x0e, 0x0c, 0x0d, 0x82, 0x0e, 0x0f, 0x06, 0x11, +0x12, 0x0a, 0x0d, 0x0d, 0x00, 0x05, 0x00, 0x0b, 0xff, 0xf9, +0x01, 0xd7, 0x02, 0x79, 0x00, 0x1f, 0x00, 0x23, 0x00, 0x4f, +0x00, 0x5a, 0x00, 0x65, 0x01, 0xa2, 0xb9, 0x00, 0x54, 0xff, +0xe8, 0xb3, 0x18, 0x00, 0x4d, 0x54, 0xb8, 0xff, 0xe0, 0xb3, +0x16, 0x00, 0x4d, 0x53, 0xb8, 0xff, 0xd8, 0x40, 0x13, 0x17, +0x00, 0x4d, 0x52, 0x50, 0x18, 0x00, 0x4d, 0x52, 0x28, 0x17, +0x00, 0x4d, 0x52, 0x40, 0x16, 0x00, 0x4d, 0x4a, 0xb8, 0xff, +0xe0, 0xb4, 0x0e, 0x15, 0x00, 0x4c, 0x4a, 0xb8, 0xff, 0xd0, +0xb4, 0x0b, 0x0c, 0x00, 0x4c, 0x46, 0xb8, 0xff, 0xe0, 0xb3, +0x18, 0x00, 0x4d, 0x46, 0xb8, 0xff, 0xe0, 0xb4, 0x0e, 0x15, +0x00, 0x4c, 0x45, 0xb8, 0xff, 0xe0, 0xb3, 0x16, 0x00, 0x4d, +0x45, 0xb8, 0xff, 0xe8, 0xb4, 0x0e, 0x15, 0x00, 0x4c, 0x40, +0xb8, 0xff, 0xe0, 0x40, 0x0b, 0x11, 0x18, 0x00, 0x4c, 0x1e, +0x28, 0x0e, 0x15, 0x00, 0x4c, 0x18, 0xb8, 0xff, 0xe0, 0xb4, +0x0e, 0x15, 0x00, 0x4c, 0x13, 0xb8, 0xff, 0xe0, 0xb3, 0x16, +0x00, 0x4d, 0x12, 0xb8, 0xff, 0xd8, 0xb3, 0x18, 0x00, 0x4d, +0x12, 0xb8, 0xff, 0xd0, 0xb3, 0x16, 0x00, 0x4d, 0x0e, 0xb8, +0xff, 0xd8, 0x40, 0x88, 0x0e, 0x15, 0x00, 0x4c, 0x08, 0x28, +0x0e, 0x15, 0x00, 0x4c, 0x04, 0x18, 0x18, 0x00, 0x4d, 0x04, +0x30, 0x16, 0x00, 0x4d, 0x03, 0x28, 0x16, 0x00, 0x4d, 0x52, +0x20, 0x17, 0x00, 0x4d, 0x52, 0x08, 0x16, 0x00, 0x4d, 0x12, +0x28, 0x17, 0x00, 0x4d, 0x04, 0x20, 0x17, 0x00, 0x4d, 0x33, +0x96, 0x42, 0x42, 0x2a, 0x96, 0x48, 0x4f, 0x20, 0x22, 0x21, +0x22, 0x9c, 0x23, 0x20, 0x14, 0x23, 0x23, 0x20, 0x21, 0x21, +0x4f, 0x3a, 0x3a, 0x4f, 0x2e, 0x2e, 0x4f, 0x23, 0x23, 0x16, +0x03, 0x53, 0x5e, 0x13, 0x04, 0x06, 0x60, 0x96, 0x10, 0x10, +0x16, 0x5b, 0x96, 0x06, 0x06, 0x55, 0x96, 0x00, 0x50, 0x96, +0x1f, 0x16, 0x01, 0x16, 0x45, 0x6f, 0x2e, 0x01, 0x2e, 0x30, +0x2f, 0x40, 0x2f, 0x60, 0x2f, 0x03, 0x2f, 0x2f, 0x3d, 0x24, +0x24, 0x27, 0x98, 0x4d, 0x64, 0x39, 0x39, 0x36, 0x98, 0x3d, +0x63, 0x22, 0x23, 0x59, 0x20, 0x21, 0x5b, 0x13, 0x5e, 0x5e, +0xb8, 0xff, 0xe0, 0x40, 0x16, 0x1d, 0x00, 0x4d, 0x34, 0x5e, +0x01, 0x5e, 0x0b, 0x58, 0x98, 0x03, 0x53, 0x4b, 0x53, 0x01, +0x53, 0x1b, 0x68, 0x63, 0x98, 0x0b, 0x66, 0x00, 0x3f, 0xed, +0x3f, 0x39, 0x71, 0x11, 0x33, 0xed, 0x11, 0x39, 0x71, 0x2b, +0x11, 0x33, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0xed, 0x32, 0x2f, +0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x2f, 0x71, 0xcd, 0x71, +0x39, 0x01, 0x2f, 0x71, 0xed, 0xdc, 0xed, 0x33, 0x2f, 0xed, +0x11, 0x33, 0x2f, 0xed, 0x12, 0x17, 0x39, 0x11, 0x33, 0x2f, +0x2f, 0x33, 0x2f, 0x11, 0x33, 0x2f, 0x11, 0x33, 0x2f, 0x87, +0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, 0x10, 0xdd, 0xed, +0x33, 0x2f, 0xed, 0x31, 0x30, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, +0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x37, 0x34, 0x36, 0x37, 0x26, 0x26, +0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, +0x06, 0x07, 0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, +0x2e, 0x02, 0x07, 0x23, 0x01, 0x33, 0x05, 0x16, 0x16, 0x33, +0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x23, 0x35, 0x33, 0x32, +0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, +0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, 0x16, +0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x27, 0x01, 0x34, +0x26, 0x27, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x27, +0x14, 0x16, 0x17, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, +0xff, 0x11, 0x1a, 0x0e, 0x14, 0x11, 0x1c, 0x24, 0x13, 0x12, +0x24, 0x1c, 0x11, 0x0e, 0x17, 0x13, 0x1a, 0x13, 0x1e, 0x27, +0x14, 0x15, 0x27, 0x1e, 0x12, 0xaf, 0x45, 0x01, 0x7a, 0x47, +0xfe, 0x56, 0x0b, 0x21, 0x14, 0x17, 0x21, 0x27, 0x26, 0x0c, +0x17, 0x19, 0x1c, 0x19, 0x0e, 0x0e, 0x24, 0x0c, 0x13, 0x0f, +0x31, 0x1a, 0x11, 0x20, 0x19, 0x0f, 0x0f, 0x0f, 0x14, 0x17, +0x0c, 0x1b, 0x29, 0x1e, 0x2f, 0x25, 0x01, 0x89, 0x29, 0x1a, +0x1f, 0x20, 0x11, 0x13, 0x1e, 0x59, 0x1e, 0x16, 0x1d, 0x16, +0x15, 0x0e, 0x18, 0x45, 0x0c, 0x24, 0x0c, 0x08, 0x1c, 0x17, +0x12, 0x1b, 0x12, 0x08, 0x09, 0x12, 0x1b, 0x11, 0x0e, 0x1d, +0x0c, 0x09, 0x1d, 0x19, 0x13, 0x1d, 0x13, 0x0a, 0x08, 0x12, +0x1d, 0x30, 0x02, 0x6b, 0xbd, 0x05, 0x08, 0x0d, 0x11, 0x15, +0x0c, 0x32, 0x0b, 0x12, 0x0f, 0x09, 0x0a, 0x05, 0x2b, 0x09, +0x0d, 0x07, 0x0f, 0x19, 0x12, 0x0f, 0x1d, 0x0b, 0x0a, 0x21, +0x17, 0x0e, 0x1d, 0x17, 0x0e, 0x0e, 0xfe, 0xc8, 0x12, 0x0f, +0x08, 0x10, 0x19, 0x0e, 0x0c, 0x0d, 0x82, 0x0e, 0x0f, 0x06, +0x11, 0x12, 0x0a, 0x0d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x05, +0x00, 0x0b, 0xff, 0xf9, 0x01, 0xd7, 0x02, 0x72, 0x00, 0x1f, +0x00, 0x23, 0x00, 0x2e, 0x00, 0x39, 0x00, 0x55, 0x01, 0xfb, +0xb9, 0x00, 0x3e, 0xff, 0xe8, 0xb4, 0x11, 0x14, 0x00, 0x4c, +0x3e, 0xb8, 0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x3e, 0xb8, +0xff, 0xd8, 0xb4, 0x0e, 0x0f, 0x00, 0x4c, 0x3c, 0xb8, 0xff, +0xe8, 0xb4, 0x10, 0x14, 0x00, 0x4c, 0x3c, 0xb8, 0xff, 0xe0, +0xb3, 0x0f, 0x00, 0x4d, 0x3c, 0xb8, 0xff, 0xd8, 0x40, 0x19, +0x0e, 0x00, 0x4d, 0x1e, 0x10, 0x15, 0x00, 0x4d, 0x1e, 0x18, +0x13, 0x14, 0x00, 0x4c, 0x1e, 0x20, 0x12, 0x00, 0x4d, 0x1e, +0x18, 0x11, 0x00, 0x4d, 0x18, 0xb8, 0xff, 0xe8, 0xb3, 0x14, +0x00, 0x4d, 0x18, 0xb8, 0xff, 0xf0, 0xb4, 0x11, 0x13, 0x00, +0x4c, 0x12, 0xb8, 0xff, 0xd0, 0xb3, 0x16, 0x00, 0x4d, 0x0e, +0xb8, 0xff, 0xd8, 0xb3, 0x14, 0x00, 0x4d, 0x0e, 0xb8, 0xff, +0xe0, 0xb3, 0x13, 0x00, 0x4d, 0x0e, 0xb8, 0xff, 0xf0, 0xb3, +0x12, 0x00, 0x4d, 0x0e, 0xb8, 0xff, 0xe0, 0x40, 0x3f, 0x11, +0x00, 0x4d, 0x08, 0x18, 0x14, 0x15, 0x00, 0x4c, 0x08, 0x10, +0x13, 0x00, 0x4d, 0x08, 0x18, 0x11, 0x12, 0x00, 0x4c, 0x05, +0x10, 0x16, 0x00, 0x4d, 0x04, 0x28, 0x16, 0x00, 0x4d, 0x27, +0x10, 0x16, 0x00, 0x4d, 0x26, 0x28, 0x16, 0x00, 0x4d, 0x25, +0x18, 0x1f, 0x21, 0x00, 0x4c, 0x25, 0x20, 0x1e, 0x00, 0x4d, +0x25, 0x20, 0x17, 0x18, 0x00, 0x4c, 0x1e, 0x18, 0x16, 0x00, +0x4d, 0x19, 0xb8, 0xff, 0xf8, 0xb3, 0x23, 0x00, 0x4d, 0x18, +0xb8, 0xff, 0xf0, 0xb3, 0x23, 0x00, 0x4d, 0x08, 0xb8, 0xff, +0xf0, 0x40, 0x4a, 0x16, 0x00, 0x4d, 0x04, 0x18, 0x23, 0x00, +0x4d, 0x34, 0x27, 0x01, 0x22, 0x20, 0x23, 0x20, 0x9c, 0x56, +0x22, 0x14, 0x56, 0x56, 0x22, 0x21, 0x21, 0x43, 0x43, 0x4d, +0x53, 0x53, 0x4a, 0x96, 0x3d, 0x55, 0x10, 0x3a, 0x01, 0x3a, +0x96, 0x52, 0x20, 0x2f, 0x00, 0x4d, 0x52, 0x4d, 0x03, 0x27, +0x32, 0x13, 0x04, 0x10, 0x2f, 0x96, 0x06, 0x29, 0x96, 0x00, +0x24, 0x96, 0x16, 0x23, 0x23, 0x16, 0x34, 0x96, 0x10, 0x16, +0x9f, 0x4d, 0xbf, 0x4d, 0x02, 0x4d, 0x3a, 0xb8, 0xff, 0xc0, +0xb3, 0x2f, 0x00, 0x4d, 0x3a, 0xb8, 0xff, 0xc0, 0x40, 0x18, +0x1f, 0x00, 0x4d, 0x30, 0x3a, 0x40, 0x3a, 0x50, 0x3a, 0x70, +0x3a, 0x90, 0x3a, 0xb0, 0x3a, 0x06, 0x3a, 0x3a, 0x47, 0x55, +0x98, 0x52, 0x60, 0x44, 0xb8, 0xff, 0xd0, 0xb3, 0x20, 0x00, +0x4d, 0x44, 0xb8, 0xff, 0xc0, 0xb3, 0x1f, 0x00, 0x4d, 0x44, +0xb8, 0xff, 0xe0, 0x40, 0x32, 0x1c, 0x00, 0x4d, 0x40, 0x44, +0x01, 0x44, 0x44, 0x47, 0x98, 0x40, 0x64, 0x22, 0x23, 0x59, +0x20, 0x21, 0x5b, 0x13, 0x30, 0x32, 0x01, 0x32, 0x27, 0x03, +0x27, 0x27, 0x20, 0x1d, 0x00, 0x4d, 0x27, 0x18, 0x17, 0x18, +0x00, 0x4c, 0x40, 0x27, 0x01, 0x27, 0x0b, 0x2c, 0x98, 0x1b, +0x68, 0x37, 0x98, 0x0b, 0x66, 0x00, 0x3f, 0xed, 0x3f, 0xed, +0x11, 0x39, 0x71, 0x2b, 0x2b, 0x11, 0x33, 0x10, 0xc9, 0x71, +0x32, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0xed, 0x32, 0x2f, 0x71, +0x2b, 0x2b, 0x2b, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0x71, 0x2b, +0x2b, 0xcd, 0x71, 0x01, 0x2f, 0xd4, 0xed, 0x11, 0x33, 0x2f, +0x10, 0xfd, 0xd4, 0xed, 0xd4, 0xed, 0x12, 0x17, 0x39, 0x2f, +0x33, 0x2b, 0xed, 0x72, 0x32, 0xdc, 0xed, 0x33, 0x2f, 0x11, +0x33, 0x2f, 0x33, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x00, 0x71, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x37, 0x34, 0x36, +0x37, 0x26, 0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, +0x02, 0x15, 0x14, 0x06, 0x07, 0x16, 0x16, 0x15, 0x14, 0x0e, +0x02, 0x23, 0x22, 0x2e, 0x02, 0x07, 0x23, 0x01, 0x33, 0x03, +0x34, 0x26, 0x27, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, +0x27, 0x14, 0x16, 0x17, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, +0x06, 0x03, 0x16, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, +0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, +0x23, 0x3e, 0x03, 0x37, 0x33, 0x15, 0x23, 0xff, 0x11, 0x1a, +0x0e, 0x14, 0x11, 0x1c, 0x24, 0x13, 0x12, 0x24, 0x1c, 0x11, +0x0e, 0x17, 0x13, 0x1a, 0x13, 0x1e, 0x27, 0x14, 0x15, 0x27, +0x1e, 0x12, 0xaf, 0x45, 0x01, 0x7a, 0x47, 0x30, 0x29, 0x1a, +0x1f, 0x20, 0x11, 0x13, 0x1e, 0x59, 0x1e, 0x16, 0x1d, 0x16, +0x15, 0x0e, 0x18, 0xdd, 0x38, 0x36, 0x3a, 0x3b, 0x18, 0x2e, +0x0c, 0x0e, 0x0a, 0x23, 0x15, 0x1a, 0x22, 0x2f, 0x40, 0x03, +0x03, 0x03, 0x02, 0x01, 0x93, 0x60, 0x45, 0x0c, 0x24, 0x0c, +0x08, 0x1c, 0x17, 0x12, 0x1b, 0x12, 0x08, 0x09, 0x12, 0x1b, +0x11, 0x0e, 0x1d, 0x0c, 0x09, 0x1d, 0x19, 0x13, 0x1d, 0x13, +0x0a, 0x08, 0x12, 0x1d, 0x30, 0x02, 0x6b, 0xfd, 0xda, 0x12, +0x0f, 0x08, 0x10, 0x19, 0x0e, 0x0c, 0x0d, 0x82, 0x0e, 0x0f, +0x06, 0x11, 0x12, 0x0a, 0x0d, 0x0d, 0x01, 0x57, 0x02, 0x2b, +0x27, 0x28, 0x30, 0x0d, 0x08, 0x30, 0x05, 0x0e, 0x10, 0x13, +0x17, 0x13, 0x17, 0x1f, 0x1c, 0x1d, 0x15, 0x32, 0x00, 0x00, +0x00, 0x05, 0x00, 0x0b, 0xff, 0xf9, 0x01, 0xd7, 0x02, 0x72, +0x00, 0x1f, 0x00, 0x23, 0x00, 0x2e, 0x00, 0x39, 0x00, 0x48, +0x00, 0xd2, 0x40, 0x0c, 0x1e, 0x20, 0x11, 0x15, 0x00, 0x4c, +0x1e, 0x18, 0x10, 0x00, 0x4d, 0x18, 0xb8, 0xff, 0xe0, 0xb4, +0x11, 0x15, 0x00, 0x4c, 0x18, 0xb8, 0xff, 0xe8, 0xb3, 0x10, +0x00, 0x4d, 0x14, 0xb8, 0xff, 0xd8, 0xb3, 0x10, 0x00, 0x4d, +0x0e, 0xb8, 0xff, 0xe0, 0xb4, 0x11, 0x15, 0x00, 0x4c, 0x0e, +0xb8, 0xff, 0xe8, 0x40, 0x5d, 0x10, 0x00, 0x4d, 0x08, 0x18, +0x11, 0x15, 0x00, 0x4c, 0x08, 0x20, 0x10, 0x00, 0x4d, 0x20, +0x22, 0x21, 0x22, 0x9c, 0x23, 0x20, 0x14, 0x23, 0x23, 0x20, +0x21, 0x21, 0x70, 0x40, 0x01, 0x40, 0x3a, 0x96, 0x48, 0x3f, +0x96, 0x43, 0x03, 0x27, 0x32, 0x13, 0x04, 0x10, 0x2f, 0x96, +0x06, 0x29, 0x96, 0x00, 0x24, 0x96, 0x16, 0x23, 0x23, 0x16, +0x34, 0x96, 0x10, 0x16, 0x43, 0x3f, 0x98, 0x41, 0x60, 0x3a, +0x61, 0x22, 0x23, 0x59, 0x20, 0x21, 0x5b, 0x13, 0x32, 0x42, +0x32, 0x01, 0x34, 0x32, 0x01, 0x32, 0x0b, 0x2c, 0x98, 0x03, +0x27, 0x27, 0x1b, 0x68, 0x37, 0x98, 0x0b, 0x66, 0x00, 0x3f, +0xed, 0x3f, 0x39, 0x11, 0x33, 0xed, 0x11, 0x39, 0x71, 0x71, +0x11, 0x33, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0x3f, 0xed, 0x32, +0x01, 0x2f, 0xd4, 0xed, 0x11, 0x33, 0x2f, 0x10, 0xfd, 0xdc, +0xed, 0xd4, 0xed, 0x12, 0x17, 0x39, 0x2f, 0xed, 0xde, 0xed, +0xcc, 0x5d, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x37, 0x34, 0x36, 0x37, 0x26, 0x26, 0x35, 0x34, +0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, +0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, +0x07, 0x23, 0x01, 0x33, 0x03, 0x34, 0x26, 0x27, 0x06, 0x15, +0x14, 0x16, 0x33, 0x32, 0x36, 0x27, 0x14, 0x16, 0x17, 0x36, +0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x27, 0x3e, 0x03, 0x37, +0x23, 0x35, 0x33, 0x15, 0x0e, 0x03, 0x07, 0xff, 0x11, 0x1a, +0x0e, 0x14, 0x11, 0x1c, 0x24, 0x13, 0x12, 0x24, 0x1c, 0x11, +0x0e, 0x17, 0x13, 0x1a, 0x13, 0x1e, 0x27, 0x14, 0x15, 0x27, +0x1e, 0x12, 0xaf, 0x45, 0x01, 0x7a, 0x47, 0x30, 0x29, 0x1a, +0x1f, 0x20, 0x11, 0x13, 0x1e, 0x59, 0x1e, 0x16, 0x1d, 0x16, +0x15, 0x0e, 0x18, 0xfd, 0x06, 0x0e, 0x12, 0x19, 0x12, 0x68, +0xaf, 0x18, 0x1e, 0x14, 0x0d, 0x06, 0x45, 0x0c, 0x24, 0x0c, +0x08, 0x1c, 0x17, 0x12, 0x1b, 0x12, 0x08, 0x09, 0x12, 0x1b, +0x11, 0x0e, 0x1d, 0x0c, 0x09, 0x1d, 0x19, 0x13, 0x1d, 0x13, +0x0a, 0x08, 0x12, 0x1d, 0x30, 0x02, 0x6b, 0xfd, 0xda, 0x12, +0x0f, 0x08, 0x10, 0x19, 0x0e, 0x0c, 0x0d, 0x82, 0x0e, 0x0f, +0x06, 0x11, 0x12, 0x0a, 0x0d, 0x0d, 0xb4, 0x22, 0x34, 0x2d, +0x2b, 0x1a, 0x32, 0x29, 0x1b, 0x2c, 0x2f, 0x36, 0x25, 0x00, +0x00, 0x03, 0x00, 0x0b, 0xff, 0xf7, 0x01, 0xd7, 0x02, 0x72, +0x00, 0x0a, 0x00, 0x26, 0x00, 0x2a, 0x00, 0x98, 0xb9, 0x00, +0x0f, 0xff, 0xd8, 0xb4, 0x0e, 0x14, 0x00, 0x4c, 0x0d, 0xb8, +0xff, 0xd8, 0xb4, 0x0e, 0x14, 0x00, 0x4c, 0x15, 0xb8, 0xff, +0xe8, 0x40, 0x2d, 0x1c, 0x00, 0x4d, 0x27, 0x29, 0x28, 0x29, +0x9c, 0x2a, 0x27, 0x14, 0x2a, 0x27, 0x2a, 0x2a, 0x0e, 0x26, +0x0b, 0x1e, 0x23, 0x14, 0x14, 0x1e, 0x0e, 0x25, 0x25, 0x1b, +0x96, 0x0e, 0x28, 0x28, 0x00, 0x05, 0x96, 0x03, 0x06, 0x00, +0x29, 0x2a, 0x59, 0x27, 0x28, 0x5b, 0x1e, 0x0b, 0xb8, 0xff, +0xc0, 0x40, 0x16, 0x1c, 0x20, 0x48, 0x0b, 0x0b, 0x18, 0x26, +0x98, 0x23, 0x65, 0x18, 0x98, 0x11, 0x68, 0x06, 0x61, 0x0a, +0x00, 0x00, 0x07, 0x03, 0x60, 0x00, 0x3f, 0x33, 0x33, 0x2f, +0xcd, 0x3f, 0x3f, 0xed, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0x2b, +0xcd, 0x3f, 0x33, 0x3f, 0x33, 0x01, 0x2f, 0xdc, 0x32, 0xed, +0x11, 0x33, 0x2f, 0x2f, 0xed, 0x33, 0x2f, 0x10, 0xcc, 0x32, +0x2f, 0x32, 0x10, 0xcd, 0x32, 0x11, 0x33, 0x2f, 0x87, 0x2b, +0x87, 0x7d, 0xc4, 0x31, 0x30, 0x00, 0x2b, 0x01, 0x2b, 0x2b, +0x13, 0x36, 0x36, 0x37, 0x33, 0x15, 0x23, 0x35, 0x06, 0x06, +0x07, 0x01, 0x16, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, +0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, +0x23, 0x3e, 0x03, 0x37, 0x33, 0x15, 0x23, 0x05, 0x23, 0x01, +0x33, 0x10, 0x23, 0x2f, 0x18, 0x29, 0x3b, 0x14, 0x21, 0x12, +0x01, 0x48, 0x38, 0x36, 0x3a, 0x3b, 0x18, 0x2e, 0x0c, 0x0e, +0x0a, 0x23, 0x15, 0x1a, 0x22, 0x2f, 0x40, 0x03, 0x03, 0x03, +0x02, 0x01, 0x93, 0x60, 0xfe, 0xe4, 0x45, 0x01, 0x7a, 0x47, +0x02, 0x31, 0x0e, 0x1c, 0x17, 0xfa, 0xa8, 0x0b, 0x0e, 0x06, +0xfe, 0xa2, 0x02, 0x2b, 0x27, 0x28, 0x30, 0x0d, 0x08, 0x30, +0x05, 0x0e, 0x10, 0x13, 0x17, 0x13, 0x17, 0x1f, 0x1c, 0x1d, +0x15, 0x32, 0xc8, 0x02, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x03, +0x00, 0x15, 0xff, 0xf7, 0x01, 0xe4, 0x02, 0x79, 0x00, 0x1b, +0x00, 0x1f, 0x00, 0x3c, 0x01, 0x10, 0xb9, 0x00, 0x39, 0xff, +0xe0, 0xb3, 0x15, 0x00, 0x4d, 0x39, 0xb8, 0xff, 0xe8, 0xb3, +0x14, 0x00, 0x4d, 0x39, 0xb8, 0xff, 0xf0, 0xb3, 0x13, 0x00, +0x4d, 0x39, 0xb8, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x36, +0xb8, 0xff, 0xe0, 0x40, 0x14, 0x0e, 0x15, 0x00, 0x4c, 0x32, +0x20, 0x16, 0x00, 0x4d, 0x32, 0x18, 0x15, 0x00, 0x4d, 0x32, +0x20, 0x14, 0x00, 0x4d, 0x04, 0xb8, 0xff, 0xd8, 0xb4, 0x0e, +0x15, 0x00, 0x4c, 0x02, 0xb8, 0xff, 0xd0, 0x40, 0x44, 0x0e, +0x15, 0x00, 0x4c, 0x2a, 0x96, 0x37, 0x37, 0x20, 0x23, 0x1c, +0x1e, 0x1d, 0x1e, 0x9c, 0x1f, 0x1c, 0x14, 0x1f, 0x1f, 0x1c, +0x1d, 0x1d, 0x3c, 0x23, 0x31, 0x31, 0x23, 0x1f, 0x1f, 0x03, +0x1b, 0x00, 0x13, 0x18, 0x09, 0x09, 0x13, 0x03, 0x1a, 0x1a, +0x10, 0x96, 0x03, 0x30, 0x30, 0x2d, 0x98, 0x34, 0x63, 0x3c, +0x98, 0x22, 0x61, 0x1e, 0x1f, 0x59, 0x1c, 0x1d, 0x5b, 0x3f, +0x13, 0x4f, 0x13, 0x02, 0x13, 0x98, 0x00, 0xb8, 0xff, 0xc0, +0x40, 0x0b, 0x1c, 0x21, 0x48, 0x00, 0x00, 0x0d, 0x1b, 0x98, +0x18, 0x65, 0x0a, 0xb8, 0xff, 0xd0, 0xb3, 0x21, 0x00, 0x4d, +0x0a, 0xb8, 0xff, 0xd8, 0xb4, 0x1f, 0x20, 0x00, 0x4c, 0x0a, +0xb8, 0xff, 0xd0, 0xb3, 0x1e, 0x00, 0x4d, 0x0a, 0xb8, 0xff, +0xc0, 0x40, 0x0a, 0x1c, 0x1d, 0x00, 0x4c, 0x0a, 0x0a, 0x0d, +0x98, 0x06, 0x68, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x2b, 0x2b, +0x2b, 0x2b, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0x2b, 0xed, 0x71, +0x3f, 0x33, 0x3f, 0x33, 0x3f, 0xed, 0x3f, 0xed, 0x32, 0x2f, +0x01, 0x2f, 0xed, 0x33, 0x2f, 0x10, 0xcc, 0x32, 0x2f, 0x32, +0x10, 0xcd, 0x32, 0x11, 0x33, 0x2f, 0x2f, 0x33, 0x2f, 0x11, +0x33, 0x33, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, +0x18, 0x10, 0xcd, 0x32, 0x2f, 0xed, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x16, +0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, +0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x3e, 0x03, +0x37, 0x33, 0x15, 0x23, 0x05, 0x23, 0x01, 0x33, 0x05, 0x15, +0x23, 0x35, 0x34, 0x36, 0x37, 0x37, 0x36, 0x36, 0x35, 0x34, +0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, +0x16, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x01, 0x69, 0x38, 0x36, +0x3a, 0x3b, 0x18, 0x2e, 0x0c, 0x0e, 0x0a, 0x23, 0x15, 0x1a, +0x22, 0x2f, 0x40, 0x03, 0x03, 0x03, 0x02, 0x01, 0x93, 0x60, +0xfe, 0xfd, 0x46, 0x01, 0x7b, 0x46, 0xfe, 0xf7, 0xc6, 0x28, +0x1a, 0x16, 0x17, 0x13, 0x17, 0x10, 0x0f, 0x20, 0x0c, 0x20, +0x11, 0x33, 0x1a, 0x30, 0x2f, 0x1b, 0x25, 0x29, 0x0d, 0xa3, +0x02, 0x2b, 0x27, 0x28, 0x30, 0x0d, 0x08, 0x30, 0x05, 0x0e, +0x10, 0x13, 0x17, 0x13, 0x17, 0x1f, 0x1c, 0x1d, 0x15, 0x32, +0xc8, 0x02, 0x6b, 0xc3, 0x32, 0x17, 0x20, 0x23, 0x10, 0x0f, +0x0e, 0x19, 0x0e, 0x11, 0x10, 0x0d, 0x0d, 0x28, 0x13, 0x13, +0x32, 0x20, 0x1a, 0x25, 0x1c, 0x18, 0x0c, 0x00, 0x00, 0x00, +0x00, 0x03, 0x00, 0x13, 0xff, 0xf7, 0x01, 0xdc, 0x02, 0x79, +0x00, 0x2a, 0x00, 0x46, 0x00, 0x4a, 0x00, 0xf3, 0xb9, 0x00, +0x2f, 0xff, 0xd0, 0xb4, 0x0e, 0x15, 0x00, 0x4c, 0x2d, 0xb8, +0xff, 0xd0, 0xb4, 0x0e, 0x15, 0x00, 0x4c, 0x25, 0xb8, 0xff, +0xe8, 0xb4, 0x0e, 0x15, 0x00, 0x4c, 0x22, 0xb8, 0xff, 0xd0, +0xb4, 0x0e, 0x15, 0x00, 0x4c, 0x1c, 0xb8, 0xff, 0xe0, 0x40, +0x39, 0x11, 0x18, 0x00, 0x4c, 0x47, 0x49, 0x48, 0x49, 0x9c, +0x4a, 0x47, 0x14, 0x4a, 0x47, 0x4a, 0x4a, 0x2e, 0x46, 0x2b, +0x96, 0x3e, 0x43, 0x34, 0x34, 0x3e, 0x2e, 0x45, 0x45, 0x3b, +0x96, 0x2e, 0x48, 0x48, 0x2a, 0x21, 0x0f, 0x96, 0x1e, 0x1e, +0x06, 0x96, 0x23, 0x2a, 0x16, 0x16, 0x2a, 0x0a, 0x0a, 0x2a, +0x49, 0x4a, 0x59, 0x47, 0x48, 0x5b, 0x3e, 0x2b, 0xb8, 0xff, +0xc0, 0x40, 0x0b, 0x1c, 0x21, 0x48, 0x2b, 0x2b, 0x38, 0x46, +0x98, 0x43, 0x65, 0x35, 0xb8, 0xff, 0xc0, 0xb3, 0x1d, 0x00, +0x4d, 0x35, 0xb8, 0xff, 0xd8, 0x40, 0x24, 0x1c, 0x00, 0x4d, +0x35, 0x35, 0x38, 0x98, 0x31, 0x68, 0x21, 0x6f, 0x0a, 0x01, +0x0a, 0x30, 0x0b, 0x40, 0x0b, 0x60, 0x0b, 0x03, 0x0b, 0x0b, +0x19, 0x00, 0x00, 0x03, 0x98, 0x28, 0x64, 0x15, 0x15, 0x12, +0x98, 0x19, 0x63, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, +0x32, 0x2f, 0x11, 0x39, 0x2f, 0x71, 0xcd, 0x71, 0x39, 0x3f, +0xed, 0x32, 0x2f, 0x2b, 0x2b, 0x3f, 0xed, 0x12, 0x39, 0x2f, +0x2b, 0xcd, 0x3f, 0x33, 0x3f, 0x33, 0x01, 0x2f, 0x33, 0x2f, +0x11, 0x33, 0x2f, 0x10, 0xdd, 0xed, 0x33, 0x2f, 0xed, 0x32, +0x11, 0x33, 0x2f, 0x2f, 0xed, 0x33, 0x2f, 0x10, 0xcc, 0x32, +0x2f, 0x32, 0x10, 0xed, 0x32, 0x11, 0x33, 0x2f, 0x87, 0x2b, +0x87, 0x7d, 0xc4, 0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x13, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, +0x23, 0x23, 0x35, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, +0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, +0x15, 0x14, 0x06, 0x07, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x27, 0x05, 0x16, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, +0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, +0x26, 0x23, 0x3e, 0x03, 0x37, 0x33, 0x15, 0x23, 0x05, 0x23, +0x01, 0x33, 0x22, 0x0b, 0x21, 0x14, 0x17, 0x21, 0x27, 0x26, +0x0c, 0x17, 0x19, 0x1c, 0x19, 0x0e, 0x0e, 0x24, 0x0c, 0x13, +0x0f, 0x31, 0x1a, 0x11, 0x20, 0x19, 0x0f, 0x0f, 0x0f, 0x2b, +0x0c, 0x1b, 0x29, 0x1e, 0x2f, 0x25, 0x01, 0x56, 0x38, 0x36, +0x3a, 0x3b, 0x18, 0x2e, 0x0c, 0x0e, 0x0a, 0x23, 0x15, 0x1a, +0x22, 0x2f, 0x40, 0x03, 0x03, 0x03, 0x02, 0x01, 0x93, 0x60, +0xfe, 0xf5, 0x46, 0x01, 0x7b, 0x46, 0x01, 0xae, 0x05, 0x08, +0x0d, 0x11, 0x15, 0x0c, 0x32, 0x0b, 0x12, 0x0f, 0x09, 0x0a, +0x05, 0x2b, 0x09, 0x0d, 0x07, 0x0f, 0x19, 0x12, 0x0f, 0x1e, +0x0b, 0x14, 0x2d, 0x0e, 0x1d, 0x17, 0x0e, 0x0e, 0xda, 0x02, +0x2b, 0x27, 0x28, 0x30, 0x0d, 0x08, 0x30, 0x05, 0x0e, 0x10, +0x13, 0x17, 0x13, 0x17, 0x1f, 0x1c, 0x1d, 0x15, 0x32, 0xc8, +0x02, 0x6b, 0x00, 0x04, 0x00, 0x0f, 0xff, 0xf7, 0x01, 0xe5, +0x02, 0x72, 0x00, 0x1b, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x31, +0x00, 0xc8, 0x40, 0x10, 0x28, 0x18, 0x16, 0x00, 0x4d, 0x27, +0x20, 0x16, 0x00, 0x4d, 0x26, 0x20, 0x16, 0x00, 0x4d, 0x04, +0xb8, 0xff, 0xd8, 0xb4, 0x0e, 0x15, 0x00, 0x4c, 0x02, 0xb8, +0xff, 0xd0, 0x40, 0x3e, 0x0e, 0x15, 0x00, 0x4c, 0x1e, 0x1d, +0x20, 0x96, 0x23, 0x29, 0x23, 0x30, 0x2e, 0x31, 0x2e, 0x9c, +0x2f, 0x30, 0x14, 0x2f, 0x30, 0x28, 0x23, 0x2f, 0x2f, 0x2c, +0x25, 0x31, 0x31, 0x03, 0x1b, 0x00, 0x96, 0x13, 0x18, 0x09, +0x09, 0x13, 0x03, 0x1a, 0x1a, 0x10, 0x96, 0x03, 0x30, 0x31, +0x59, 0x2e, 0x2f, 0x5b, 0x29, 0x28, 0x60, 0x25, 0x1d, 0x2c, +0x20, 0x23, 0x22, 0x61, 0x13, 0x00, 0xb8, 0xff, 0xc0, 0x40, +0x0b, 0x1c, 0x21, 0x48, 0x00, 0x00, 0x0d, 0x1b, 0x98, 0x18, +0x65, 0x0a, 0xb8, 0xff, 0xd8, 0xb3, 0x1d, 0x00, 0x4d, 0x0a, +0xb8, 0xff, 0xd0, 0x40, 0x09, 0x1c, 0x00, 0x4d, 0x0a, 0x0a, +0x0d, 0x98, 0x06, 0x68, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x2b, +0x2b, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0x2b, 0xcd, 0x3f, 0xdd, +0x32, 0xcd, 0x32, 0x32, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0x33, +0x01, 0x2f, 0xed, 0x33, 0x2f, 0x10, 0xcc, 0x32, 0x2f, 0x32, +0x10, 0xed, 0x32, 0x11, 0x33, 0x2f, 0x2f, 0x33, 0x33, 0x2f, +0xce, 0x32, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x11, 0x33, +0x18, 0x10, 0xfd, 0x32, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x25, 0x16, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, +0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, +0x26, 0x23, 0x3e, 0x03, 0x37, 0x33, 0x15, 0x23, 0x03, 0x15, +0x33, 0x15, 0x23, 0x15, 0x23, 0x35, 0x23, 0x35, 0x36, 0x36, +0x37, 0x17, 0x06, 0x06, 0x07, 0x33, 0x03, 0x23, 0x01, 0x33, +0x01, 0x69, 0x38, 0x36, 0x3a, 0x3b, 0x18, 0x2e, 0x0c, 0x0e, +0x0a, 0x23, 0x15, 0x1a, 0x22, 0x2f, 0x40, 0x03, 0x03, 0x03, +0x02, 0x01, 0x93, 0x60, 0xa0, 0x23, 0x23, 0x3b, 0x82, 0x1b, +0x2f, 0x20, 0x18, 0x16, 0x21, 0x10, 0x47, 0x27, 0x46, 0x01, +0x7b, 0x46, 0xa3, 0x02, 0x2b, 0x27, 0x28, 0x30, 0x0d, 0x08, +0x30, 0x05, 0x0e, 0x10, 0x13, 0x17, 0x13, 0x17, 0x1f, 0x1c, +0x1d, 0x15, 0x32, 0x01, 0xaa, 0x98, 0x32, 0x30, 0x30, 0x29, +0x2e, 0x4b, 0x28, 0x2b, 0x1b, 0x38, 0x1a, 0xfe, 0x26, 0x02, +0x6b, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0xf7, +0x01, 0xc0, 0x02, 0x72, 0x00, 0x15, 0x00, 0x20, 0x00, 0x2b, +0x00, 0x2f, 0x00, 0xb8, 0xb6, 0x0f, 0x20, 0x0e, 0x15, 0x00, +0x4c, 0x0a, 0xb8, 0xff, 0xe0, 0xb4, 0x0f, 0x15, 0x00, 0x4c, +0x0a, 0xb8, 0xff, 0xd8, 0xb3, 0x0e, 0x00, 0x4d, 0x07, 0xb8, +0xff, 0xe0, 0xb4, 0x0f, 0x15, 0x00, 0x4c, 0x06, 0xb8, 0xff, +0xd8, 0x40, 0x55, 0x0e, 0x00, 0x4d, 0x13, 0x10, 0x1d, 0x00, +0x4d, 0x2c, 0x2e, 0x2d, 0x2e, 0x9c, 0x2f, 0x2c, 0x14, 0x2f, +0x2f, 0x2c, 0x2d, 0x2d, 0x16, 0x0f, 0x1a, 0x01, 0x1a, 0x96, +0x19, 0x1d, 0x16, 0x2f, 0x2f, 0x08, 0x03, 0x23, 0x96, 0x10, +0x29, 0x96, 0x08, 0x00, 0x00, 0x08, 0x2c, 0x30, 0x2e, 0x2f, +0x59, 0x2d, 0x1c, 0x61, 0x20, 0x2f, 0x16, 0x3f, 0x16, 0x4f, +0x16, 0x03, 0x16, 0x16, 0x1d, 0x1a, 0x60, 0x21, 0x98, 0x03, +0x05, 0x05, 0x26, 0x4d, 0x00, 0x01, 0x00, 0x7f, 0x15, 0x8f, +0x15, 0x02, 0x15, 0x66, 0x26, 0x98, 0x0d, 0x68, 0x00, 0x3f, +0xed, 0x3f, 0x71, 0xcd, 0x71, 0x12, 0x39, 0x2f, 0x33, 0xed, +0x3f, 0x33, 0x33, 0x2f, 0x5d, 0xcd, 0x3f, 0x2f, 0x3f, 0x33, +0x11, 0x33, 0x01, 0x2f, 0x33, 0x2f, 0x10, 0xfd, 0xd4, 0xed, +0x32, 0x11, 0x33, 0x2f, 0x2f, 0xdd, 0x32, 0xed, 0x71, 0x11, +0x33, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, +0x00, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x06, +0x06, 0x07, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x01, 0x36, +0x36, 0x37, 0x33, 0x15, 0x23, 0x35, 0x06, 0x06, 0x07, 0x01, +0x22, 0x07, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, +0x05, 0x23, 0x01, 0x33, 0x01, 0xa8, 0x2f, 0x3b, 0x0d, 0x17, +0x12, 0x30, 0x2d, 0x0c, 0x18, 0x23, 0x17, 0x37, 0x31, 0x15, +0x2c, 0x43, 0x2e, 0xfe, 0x6d, 0x23, 0x2f, 0x18, 0x29, 0x3b, +0x14, 0x21, 0x12, 0x01, 0x34, 0x17, 0x16, 0x19, 0x16, 0x14, +0x15, 0x15, 0xfe, 0xda, 0x46, 0x01, 0x7b, 0x46, 0xd1, 0x02, +0x18, 0x1b, 0x0d, 0x34, 0x23, 0x11, 0x21, 0x1a, 0x0f, 0x3d, +0x30, 0x1f, 0x3a, 0x2c, 0x1a, 0x01, 0x2e, 0x0e, 0x1c, 0x17, +0xfa, 0xa8, 0x0b, 0x0e, 0x06, 0xfe, 0x76, 0x0e, 0x22, 0x1e, +0x19, 0x0e, 0x10, 0x17, 0x77, 0x02, 0x6b, 0x00, 0x00, 0x00, +0x00, 0x04, 0x00, 0x1c, 0xff, 0xf7, 0x01, 0xdd, 0x02, 0x72, +0x00, 0x15, 0x00, 0x31, 0x00, 0x3c, 0x00, 0x40, 0x01, 0x04, +0xb9, 0x00, 0x1a, 0xff, 0xd8, 0xb4, 0x0e, 0x15, 0x00, 0x4c, +0x18, 0xb8, 0xff, 0xd0, 0x40, 0x0b, 0x0e, 0x15, 0x00, 0x4c, +0x0f, 0x20, 0x0e, 0x15, 0x00, 0x4c, 0x0a, 0xb8, 0xff, 0xe0, +0xb4, 0x0e, 0x15, 0x00, 0x4c, 0x07, 0xb8, 0xff, 0xd8, 0x40, +0x4e, 0x0e, 0x15, 0x00, 0x4c, 0x3d, 0x3f, 0x3e, 0x3f, 0x9c, +0x40, 0x3d, 0x14, 0x40, 0x3d, 0x54, 0x40, 0x01, 0x40, 0x40, +0x08, 0x03, 0x34, 0x96, 0x10, 0x40, 0x19, 0x1c, 0x48, 0x10, +0x3a, 0x96, 0x08, 0x00, 0x00, 0x1b, 0x08, 0x01, 0x5b, 0x08, +0x01, 0x08, 0x42, 0x3e, 0x3e, 0x29, 0x30, 0x30, 0x04, 0x26, +0x01, 0x26, 0x19, 0x31, 0x16, 0x29, 0x2e, 0x1f, 0x1f, 0x29, +0x3f, 0x40, 0x59, 0x3d, 0x3e, 0x5b, 0x29, 0x40, 0x1c, 0x1f, +0x48, 0x29, 0x98, 0x94, 0x16, 0xb4, 0x16, 0x02, 0x16, 0xb8, +0xff, 0xc0, 0x40, 0x0b, 0x1c, 0x20, 0x48, 0x16, 0x16, 0x23, +0x31, 0x98, 0x2e, 0x60, 0x20, 0xb8, 0xff, 0xc0, 0x40, 0x29, +0x22, 0x00, 0x4d, 0xb4, 0x20, 0x01, 0x73, 0x20, 0x01, 0x02, +0x61, 0x20, 0x01, 0x30, 0x20, 0x01, 0x20, 0x20, 0x23, 0x98, +0x1c, 0x64, 0x32, 0x98, 0x03, 0x05, 0x05, 0x37, 0x00, 0x98, +0x7f, 0x15, 0x8f, 0x15, 0x02, 0x15, 0x66, 0x37, 0x98, 0x0d, +0x68, 0x00, 0x3f, 0xed, 0x3f, 0x71, 0xed, 0x12, 0x39, 0x2f, +0x33, 0xed, 0x3f, 0xed, 0x32, 0x2f, 0x71, 0x71, 0x5f, 0x71, +0x71, 0x2b, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0x2b, 0x71, 0xed, +0x2b, 0x3f, 0x33, 0x3f, 0x33, 0x01, 0x2f, 0x32, 0x2f, 0x32, +0x10, 0xcd, 0x32, 0xdc, 0xcd, 0x71, 0x33, 0x2f, 0x11, 0x33, +0x2f, 0x10, 0xc6, 0x5d, 0x71, 0x32, 0x2f, 0x10, 0xfd, 0xdc, +0x2b, 0xed, 0x32, 0x11, 0x33, 0x2f, 0x5d, 0x87, 0x2b, 0x87, +0x7d, 0xc4, 0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x25, 0x06, 0x06, 0x07, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, +0x0e, 0x02, 0x23, 0x22, 0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, +0x01, 0x16, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, +0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, +0x3e, 0x03, 0x37, 0x33, 0x15, 0x23, 0x13, 0x22, 0x07, 0x14, +0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x05, 0x23, 0x01, +0x33, 0x01, 0xa8, 0x2f, 0x3b, 0x0d, 0x17, 0x12, 0x30, 0x2d, +0x0c, 0x18, 0x23, 0x17, 0x37, 0x31, 0x15, 0x2c, 0x43, 0x2e, +0xfe, 0xd4, 0x38, 0x36, 0x3a, 0x3b, 0x18, 0x2e, 0x0c, 0x0e, +0x0a, 0x23, 0x15, 0x1a, 0x22, 0x2f, 0x40, 0x03, 0x03, 0x03, +0x02, 0x01, 0x93, 0x60, 0xdb, 0x17, 0x16, 0x19, 0x16, 0x14, +0x15, 0x15, 0xfe, 0xf7, 0x46, 0x01, 0x7b, 0x46, 0xd1, 0x02, +0x18, 0x1b, 0x0d, 0x34, 0x23, 0x11, 0x21, 0x1a, 0x0f, 0x3d, +0x30, 0x1f, 0x3a, 0x2c, 0x1a, 0x01, 0x18, 0x02, 0x2b, 0x27, +0x28, 0x30, 0x0d, 0x08, 0x30, 0x05, 0x0e, 0x10, 0x13, 0x17, +0x13, 0x17, 0x1f, 0x1c, 0x1d, 0x15, 0x32, 0xfe, 0x37, 0x0e, +0x22, 0x1e, 0x19, 0x0e, 0x10, 0x17, 0x77, 0x02, 0x6b, 0x00, +0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x01, 0xd3, +0x02, 0x72, 0x00, 0x0a, 0x00, 0x19, 0x00, 0x1d, 0x00, 0x62, +0x40, 0x37, 0x1a, 0x1c, 0x1b, 0x1c, 0x9c, 0x1d, 0x1a, 0x14, +0x1d, 0x1a, 0x1d, 0x1d, 0x14, 0x19, 0x96, 0x0b, 0x0b, 0x11, +0x10, 0x96, 0x14, 0x1b, 0x1b, 0x00, 0x05, 0x96, 0x03, 0x07, +0x00, 0x1b, 0x1a, 0x1e, 0x1c, 0x1d, 0x59, 0x14, 0x10, 0x98, +0x13, 0x65, 0x0b, 0x5b, 0x06, 0x61, 0x0a, 0x00, 0x40, 0x08, +0x0d, 0x48, 0x00, 0x00, 0x07, 0x03, 0x60, 0x00, 0x3f, 0x33, +0x33, 0x2f, 0x2b, 0xcd, 0x3f, 0x3f, 0x3f, 0xed, 0x32, 0x3f, +0x33, 0x11, 0x33, 0x33, 0x01, 0x2f, 0xdd, 0x32, 0xed, 0x11, +0x33, 0x2f, 0x2f, 0xed, 0xcd, 0x39, 0x2f, 0xed, 0x11, 0x33, +0x2f, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x13, 0x36, +0x36, 0x37, 0x33, 0x15, 0x23, 0x35, 0x06, 0x06, 0x07, 0x01, +0x3e, 0x03, 0x37, 0x23, 0x35, 0x33, 0x15, 0x0e, 0x03, 0x07, +0x21, 0x23, 0x01, 0x33, 0x10, 0x23, 0x2f, 0x18, 0x29, 0x3b, +0x14, 0x21, 0x12, 0x01, 0x19, 0x06, 0x0e, 0x12, 0x1a, 0x12, +0x68, 0xaf, 0x18, 0x1e, 0x15, 0x0d, 0x06, 0xfe, 0xd0, 0x46, +0x01, 0x7b, 0x46, 0x02, 0x31, 0x0e, 0x1c, 0x17, 0xfa, 0xa8, +0x0b, 0x0e, 0x06, 0xfd, 0xff, 0x22, 0x34, 0x2d, 0x2b, 0x1a, +0x32, 0x29, 0x1b, 0x2c, 0x2e, 0x37, 0x25, 0x02, 0x6b, 0x00, +0x00, 0x00, 0x00, 0x03, 0x00, 0x15, 0x00, 0x00, 0x01, 0xe3, +0x02, 0x79, 0x00, 0x03, 0x00, 0x20, 0x00, 0x2f, 0x00, 0x7d, +0xb9, 0x00, 0x1f, 0xff, 0xe8, 0xb3, 0x19, 0x00, 0x4d, 0x1a, +0xb8, 0xff, 0xd8, 0x40, 0x3e, 0x0e, 0x15, 0x00, 0x4c, 0x27, +0x21, 0x96, 0x2f, 0x2a, 0x00, 0x02, 0x01, 0x02, 0x9c, 0x03, +0x00, 0x14, 0x03, 0x00, 0x03, 0x03, 0x26, 0x96, 0x2a, 0x0e, +0x96, 0x1b, 0x04, 0x04, 0x1b, 0x06, 0x01, 0x01, 0x20, 0x96, +0x06, 0x15, 0x15, 0x06, 0x2a, 0x26, 0x98, 0x28, 0x65, 0x21, +0x5b, 0x14, 0x14, 0x11, 0x98, 0x18, 0x63, 0x20, 0x98, 0x06, +0x61, 0x02, 0x03, 0x59, 0x00, 0x01, 0x5b, 0x00, 0x3f, 0x33, +0x3f, 0x33, 0x3f, 0xed, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0x3f, +0xed, 0x32, 0x01, 0x2f, 0x33, 0x2f, 0x10, 0xed, 0x33, 0x2f, +0x10, 0xcd, 0x32, 0x2f, 0x10, 0xed, 0x2f, 0xed, 0x33, 0x2f, +0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, 0x10, 0xde, 0xed, +0xcc, 0x31, 0x30, 0x2b, 0x2b, 0x33, 0x23, 0x01, 0x33, 0x05, +0x15, 0x23, 0x35, 0x34, 0x36, 0x37, 0x37, 0x36, 0x36, 0x35, +0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x33, +0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x13, 0x3e, 0x03, +0x37, 0x23, 0x35, 0x33, 0x15, 0x0e, 0x03, 0x07, 0x68, 0x46, +0x01, 0x7b, 0x46, 0xfe, 0xf8, 0xc6, 0x28, 0x1a, 0x16, 0x17, +0x13, 0x17, 0x10, 0x0f, 0x20, 0x0c, 0x20, 0x11, 0x33, 0x1a, +0x30, 0x2f, 0x1b, 0x25, 0x29, 0x0d, 0xde, 0x06, 0x0e, 0x12, +0x1a, 0x12, 0x68, 0xaf, 0x18, 0x1e, 0x15, 0x0d, 0x06, 0x02, +0x6b, 0xc3, 0x32, 0x17, 0x20, 0x23, 0x10, 0x0f, 0x0e, 0x19, +0x0e, 0x11, 0x10, 0x0d, 0x0d, 0x28, 0x13, 0x13, 0x32, 0x20, +0x1a, 0x25, 0x1d, 0x17, 0x0c, 0xfe, 0x58, 0x22, 0x34, 0x2d, +0x2b, 0x1a, 0x32, 0x29, 0x1b, 0x2c, 0x2e, 0x37, 0x25, 0x00, +0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x01, 0xd6, 0x02, 0x79, +0x00, 0x2a, 0x00, 0x39, 0x00, 0x3d, 0x00, 0xa4, 0xb9, 0x00, +0x25, 0xff, 0xe0, 0xb4, 0x0e, 0x15, 0x00, 0x4c, 0x1c, 0xb8, +0xff, 0xe0, 0x40, 0x58, 0x11, 0x15, 0x00, 0x4c, 0x3a, 0x3c, +0x3b, 0x3c, 0x9c, 0x3d, 0x3a, 0x14, 0x3d, 0x3a, 0x3d, 0x3d, +0x34, 0x39, 0x96, 0x2b, 0x2b, 0x31, 0x30, 0x96, 0x34, 0x3b, +0x3b, 0x2a, 0x21, 0x0f, 0x96, 0x1e, 0x1e, 0x06, 0x96, 0x23, +0x2a, 0x16, 0x16, 0x2a, 0x0a, 0x0a, 0x2a, 0x3c, 0x3d, 0x59, +0x3a, 0x3b, 0x5b, 0x34, 0x30, 0x98, 0x32, 0x65, 0x2b, 0x5b, +0x21, 0x3f, 0x0a, 0x4f, 0x0a, 0x6f, 0x0a, 0x03, 0x0a, 0x98, +0x30, 0x0b, 0x40, 0x0b, 0x60, 0x0b, 0x03, 0x0b, 0x0b, 0x19, +0x00, 0x00, 0x03, 0x98, 0x28, 0x64, 0x15, 0x15, 0x12, 0x98, +0x19, 0x63, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x32, +0x2f, 0x11, 0x39, 0x2f, 0x71, 0xed, 0x71, 0x39, 0x3f, 0x3f, +0xed, 0x32, 0x3f, 0x33, 0x3f, 0x33, 0x01, 0x2f, 0x33, 0x2f, +0x11, 0x33, 0x2f, 0x10, 0xdd, 0xed, 0x33, 0x2f, 0xed, 0x32, +0x11, 0x33, 0x2f, 0x2f, 0xed, 0xcd, 0x39, 0x2f, 0xed, 0x11, +0x33, 0x2f, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x01, +0x2b, 0x2b, 0x13, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, +0x26, 0x23, 0x23, 0x35, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, +0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, 0x1e, +0x02, 0x15, 0x14, 0x06, 0x07, 0x16, 0x15, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x27, 0x01, 0x3e, 0x03, 0x37, 0x23, 0x35, 0x33, +0x15, 0x0e, 0x03, 0x07, 0x21, 0x23, 0x01, 0x33, 0x22, 0x0b, +0x21, 0x14, 0x17, 0x21, 0x27, 0x26, 0x0c, 0x17, 0x19, 0x1c, +0x19, 0x0e, 0x0e, 0x24, 0x0c, 0x13, 0x0f, 0x31, 0x1a, 0x11, +0x20, 0x19, 0x0f, 0x0f, 0x0f, 0x2b, 0x0c, 0x1b, 0x29, 0x1e, +0x2f, 0x25, 0x01, 0x27, 0x06, 0x0e, 0x12, 0x1a, 0x12, 0x68, +0xaf, 0x18, 0x1e, 0x15, 0x0d, 0x06, 0xfe, 0xe6, 0x46, 0x01, +0x7b, 0x46, 0x01, 0xae, 0x05, 0x08, 0x0d, 0x11, 0x15, 0x0c, +0x32, 0x0b, 0x12, 0x0f, 0x09, 0x0a, 0x05, 0x2b, 0x09, 0x0d, +0x07, 0x0f, 0x19, 0x12, 0x0f, 0x1e, 0x0b, 0x14, 0x2d, 0x0e, +0x1d, 0x17, 0x0e, 0x0e, 0xfe, 0x83, 0x22, 0x34, 0x2d, 0x2b, +0x1a, 0x32, 0x29, 0x1b, 0x2c, 0x2e, 0x37, 0x25, 0x02, 0x6b, +0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x01, 0xe0, 0x02, 0x72, +0x00, 0x0e, 0x00, 0x1b, 0x00, 0x20, 0x00, 0x24, 0x00, 0x6e, +0x40, 0x3c, 0x21, 0x23, 0x22, 0x23, 0x9c, 0x24, 0x21, 0x14, +0x24, 0x24, 0x21, 0x22, 0x22, 0x18, 0x1b, 0x1c, 0x1c, 0x10, +0x13, 0x96, 0x16, 0x16, 0x11, 0x1f, 0x18, 0x24, 0x24, 0x09, +0x0e, 0x96, 0x00, 0x00, 0x07, 0x05, 0x96, 0x09, 0x23, 0x24, +0x59, 0x21, 0x22, 0x5b, 0x1c, 0x1b, 0x60, 0x18, 0x10, 0x1f, +0x98, 0x13, 0x16, 0x15, 0x61, 0x09, 0x05, 0x98, 0x07, 0x65, +0x00, 0x5b, 0x00, 0x3f, 0x3f, 0xed, 0x32, 0x3f, 0xdd, 0x32, +0xed, 0x32, 0x32, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0x33, 0x01, +0x2f, 0xed, 0xcd, 0x39, 0x2f, 0xed, 0x11, 0x33, 0x2f, 0x2f, +0x33, 0xcd, 0x39, 0x2f, 0xed, 0x32, 0x33, 0x11, 0x33, 0x11, +0x33, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, +0x21, 0x3e, 0x03, 0x37, 0x23, 0x35, 0x33, 0x15, 0x0e, 0x03, +0x07, 0x03, 0x15, 0x33, 0x15, 0x23, 0x15, 0x23, 0x35, 0x23, +0x35, 0x36, 0x36, 0x37, 0x17, 0x06, 0x06, 0x07, 0x33, 0x03, +0x23, 0x01, 0x33, 0x01, 0x43, 0x06, 0x0e, 0x12, 0x1a, 0x12, +0x68, 0xaf, 0x18, 0x1e, 0x15, 0x0d, 0x06, 0xb2, 0x23, 0x23, +0x3b, 0x82, 0x1b, 0x2f, 0x20, 0x18, 0x16, 0x21, 0x10, 0x47, +0x2c, 0x46, 0x01, 0x7b, 0x46, 0x22, 0x34, 0x2d, 0x2b, 0x1a, +0x32, 0x29, 0x1b, 0x2c, 0x2e, 0x37, 0x25, 0x02, 0x72, 0x98, +0x32, 0x30, 0x30, 0x29, 0x2e, 0x4b, 0x28, 0x2b, 0x1b, 0x38, +0x1a, 0xfe, 0x26, 0x02, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0d, 0x00, 0x00, 0x01, 0xdc, 0x02, 0x72, 0x00, 0x1b, +0x00, 0x2a, 0x00, 0x2e, 0x00, 0xea, 0xb9, 0x00, 0x04, 0xff, +0xd0, 0xb4, 0x0e, 0x15, 0x00, 0x4c, 0x02, 0xb8, 0xff, 0xd8, +0xb4, 0x0e, 0x15, 0x00, 0x4c, 0x11, 0xb8, 0xff, 0xf0, 0xb3, +0x22, 0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xe0, 0xb3, 0x1f, 0x00, +0x4d, 0x0a, 0xb8, 0xff, 0xc0, 0x40, 0x53, 0x1f, 0x00, 0x4d, +0x2b, 0x2d, 0x2c, 0x2d, 0x9c, 0x2e, 0x2b, 0x14, 0x2e, 0x2b, +0x2e, 0x2e, 0x25, 0x1c, 0x96, 0x2a, 0x25, 0x22, 0x21, 0x96, +0x25, 0x2c, 0x2c, 0x13, 0x1a, 0x1a, 0x10, 0x96, 0x03, 0x1b, +0x00, 0x96, 0x13, 0x18, 0x18, 0x2a, 0x2b, 0x00, 0x4c, 0x18, +0x13, 0x09, 0x09, 0x13, 0x2d, 0x2e, 0x59, 0x2b, 0x2c, 0x5b, +0x25, 0x21, 0x98, 0x23, 0x65, 0x1c, 0x5b, 0x6f, 0x13, 0x01, +0x3f, 0x13, 0x4f, 0x13, 0x6f, 0x13, 0x7f, 0x13, 0x9f, 0x13, +0x05, 0x13, 0x98, 0x60, 0x00, 0x01, 0x90, 0x00, 0x01, 0x00, +0xb8, 0xff, 0xc0, 0x40, 0x0b, 0x1c, 0x20, 0x48, 0x00, 0x00, +0x0d, 0x1b, 0x98, 0x18, 0x60, 0x0a, 0xb8, 0xff, 0xc0, 0xb3, +0x2f, 0x00, 0x4d, 0x0a, 0xb8, 0xff, 0xc0, 0x40, 0x0e, 0x1d, +0x00, 0x4d, 0x30, 0x0a, 0x50, 0x0a, 0x02, 0x0a, 0x0a, 0x0d, +0x98, 0x06, 0x64, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x71, 0x2b, +0x2b, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0x2b, 0x71, 0x72, 0xed, +0x71, 0x72, 0x3f, 0x3f, 0xed, 0x32, 0x3f, 0x33, 0x3f, 0x33, +0x01, 0x2f, 0x33, 0x2f, 0x11, 0x33, 0x2b, 0x10, 0xed, 0x32, +0xdc, 0xed, 0x33, 0x2f, 0x11, 0x33, 0x2f, 0x2f, 0xfd, 0xcd, +0x10, 0xde, 0xed, 0x11, 0x33, 0x2f, 0x87, 0x2b, 0x87, 0x7d, +0xc4, 0x31, 0x30, 0x00, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, +0x13, 0x16, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, +0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, +0x3e, 0x03, 0x37, 0x33, 0x15, 0x23, 0x13, 0x3e, 0x03, 0x37, +0x23, 0x35, 0x33, 0x15, 0x0e, 0x03, 0x07, 0x21, 0x23, 0x01, +0x33, 0x66, 0x38, 0x36, 0x3a, 0x3b, 0x18, 0x2e, 0x0c, 0x0e, +0x0a, 0x23, 0x15, 0x1a, 0x22, 0x2f, 0x40, 0x03, 0x03, 0x03, +0x02, 0x01, 0x93, 0x60, 0xda, 0x06, 0x0e, 0x12, 0x1a, 0x12, +0x68, 0xaf, 0x18, 0x1e, 0x15, 0x0d, 0x06, 0xfe, 0xd7, 0x46, +0x01, 0x7b, 0x46, 0x02, 0x1b, 0x02, 0x2b, 0x27, 0x28, 0x30, +0x0d, 0x08, 0x30, 0x05, 0x0e, 0x10, 0x13, 0x17, 0x13, 0x17, +0x1f, 0x1c, 0x1d, 0x15, 0x32, 0xfd, 0xc0, 0x22, 0x34, 0x2d, +0x2b, 0x1a, 0x32, 0x29, 0x1b, 0x2c, 0x2e, 0x37, 0x25, 0x02, +0x6b, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, +0x01, 0xda, 0x02, 0x7b, 0x00, 0x03, 0x00, 0x19, 0x00, 0x28, +0x00, 0x34, 0x00, 0xc3, 0x40, 0x0c, 0x16, 0x18, 0x12, 0x00, +0x4d, 0x13, 0x20, 0x0e, 0x15, 0x00, 0x4c, 0x0e, 0xb8, 0xff, +0xd8, 0xb4, 0x0e, 0x15, 0x00, 0x4c, 0x0b, 0xb8, 0xff, 0xd8, +0x40, 0x68, 0x0e, 0x15, 0x00, 0x4c, 0x17, 0x20, 0x20, 0x00, +0x4d, 0x16, 0x20, 0x20, 0x00, 0x4d, 0x05, 0x10, 0x20, 0x00, +0x4d, 0x57, 0x05, 0x01, 0x28, 0x96, 0x1a, 0x1a, 0x23, 0x20, +0x1f, 0x96, 0x23, 0x00, 0x02, 0x01, 0x02, 0x9c, 0x03, 0x00, +0x14, 0x03, 0x00, 0x03, 0x03, 0x23, 0x32, 0x96, 0x0c, 0x04, +0x04, 0x80, 0x0c, 0xa0, 0x0c, 0xb0, 0x0c, 0x03, 0x0c, 0x07, +0x2c, 0x96, 0x14, 0x01, 0x01, 0x14, 0x23, 0x1f, 0x21, 0x65, +0x1a, 0x5b, 0x29, 0x98, 0x07, 0x80, 0x09, 0x90, 0x09, 0xb0, +0x09, 0x03, 0x09, 0x09, 0x2f, 0x6c, 0x04, 0x7c, 0x04, 0x02, +0x5e, 0x04, 0x01, 0x04, 0x19, 0x5a, 0x2f, 0x98, 0x11, 0x64, +0x02, 0x03, 0x59, 0x00, 0x01, 0x5b, 0x00, 0x3f, 0x33, 0x3f, +0x33, 0x3f, 0xed, 0x3f, 0xcd, 0x71, 0x71, 0x12, 0x39, 0x2f, +0x71, 0x33, 0xed, 0x3f, 0x3f, 0xcd, 0x32, 0x01, 0x2f, 0x33, +0x2f, 0x10, 0xfd, 0x32, 0xcc, 0x71, 0x32, 0x2f, 0x10, 0xed, +0x2f, 0x33, 0x2f, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, +0x10, 0xfd, 0xcd, 0x11, 0x39, 0x2f, 0xed, 0x31, 0x30, 0x00, +0x71, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x33, +0x23, 0x01, 0x33, 0x05, 0x06, 0x06, 0x07, 0x36, 0x33, 0x32, +0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x35, 0x34, +0x3e, 0x02, 0x33, 0x13, 0x3e, 0x03, 0x37, 0x23, 0x35, 0x33, +0x15, 0x0e, 0x03, 0x07, 0x03, 0x22, 0x06, 0x07, 0x14, 0x16, +0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x5f, 0x46, 0x01, 0x7b, +0x46, 0xfe, 0xf2, 0x2f, 0x3a, 0x0d, 0x13, 0x15, 0x2f, 0x2e, +0x0c, 0x18, 0x23, 0x18, 0x36, 0x31, 0x15, 0x2b, 0x43, 0x2e, +0x74, 0x06, 0x0e, 0x12, 0x1a, 0x12, 0x68, 0xaf, 0x18, 0x1e, +0x15, 0x0d, 0x06, 0xfc, 0x0c, 0x16, 0x0b, 0x19, 0x15, 0x14, +0x15, 0x15, 0x02, 0x6b, 0x22, 0x02, 0x18, 0x1a, 0x0c, 0x34, +0x23, 0x11, 0x21, 0x1a, 0x0f, 0x3d, 0x30, 0x1f, 0x3a, 0x2c, +0x1a, 0xfd, 0x85, 0x22, 0x34, 0x2d, 0x2b, 0x1a, 0x32, 0x29, +0x1b, 0x2c, 0x2e, 0x37, 0x25, 0x01, 0xef, 0x08, 0x06, 0x22, +0x1e, 0x19, 0x0e, 0x10, 0x17, 0x00, 0x00, 0x04, 0xff, 0xff, +0xff, 0xf7, 0x01, 0xd5, 0x02, 0x72, 0x00, 0x15, 0x00, 0x20, +0x00, 0x2a, 0x00, 0x2e, 0x00, 0xba, 0xb9, 0x00, 0x12, 0xff, +0xf0, 0xb3, 0x12, 0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xd8, 0x40, +0x11, 0x0e, 0x15, 0x00, 0x4c, 0x0a, 0x28, 0x0e, 0x15, 0x00, +0x4c, 0x07, 0x28, 0x0e, 0x15, 0x00, 0x4c, 0x13, 0xb8, 0xff, +0xe8, 0x40, 0x48, 0x1d, 0x00, 0x4d, 0x2b, 0x2d, 0x2c, 0x2d, +0x9c, 0x2e, 0x2b, 0x14, 0x2e, 0x2e, 0x2b, 0x2c, 0x2c, 0x16, +0x1a, 0x96, 0x19, 0x1d, 0x16, 0x2e, 0x2e, 0x03, 0x23, 0x96, +0x10, 0x28, 0x96, 0x08, 0x00, 0x00, 0x8f, 0x08, 0x01, 0x08, +0x80, 0x10, 0x01, 0x10, 0x2c, 0x2b, 0x2f, 0x2d, 0x2e, 0x59, +0x1c, 0x61, 0x20, 0x16, 0x40, 0x0a, 0x0d, 0x48, 0x16, 0x16, +0x1d, 0x19, 0x60, 0x21, 0x98, 0x03, 0x05, 0x40, 0x1e, 0x21, +0x48, 0x05, 0x05, 0x25, 0x00, 0xb8, 0xff, 0xc0, 0x40, 0x0c, +0x1c, 0x1d, 0x00, 0x4c, 0x00, 0x98, 0x15, 0x68, 0x25, 0x98, +0x0d, 0x66, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x2b, 0x12, 0x39, +0x2f, 0x2b, 0x33, 0xed, 0x3f, 0x33, 0x33, 0x2f, 0x2b, 0xcd, +0x3f, 0x3f, 0x33, 0x11, 0x33, 0x33, 0x01, 0x2f, 0x71, 0xcc, +0x71, 0x32, 0x2f, 0x10, 0xed, 0x10, 0xed, 0x32, 0x33, 0x2f, +0x2f, 0xdd, 0x32, 0xed, 0x11, 0x33, 0x2f, 0x87, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x31, 0x30, 0x00, 0x2b, 0x01, 0x2b, 0x2b, +0x2b, 0x2b, 0x25, 0x36, 0x36, 0x37, 0x06, 0x23, 0x22, 0x26, +0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, +0x02, 0x23, 0x01, 0x36, 0x36, 0x37, 0x33, 0x15, 0x23, 0x35, +0x06, 0x06, 0x07, 0x01, 0x32, 0x37, 0x26, 0x23, 0x22, 0x06, +0x15, 0x14, 0x16, 0x05, 0x23, 0x01, 0x33, 0x01, 0x1e, 0x2e, +0x3a, 0x0d, 0x16, 0x12, 0x2f, 0x2d, 0x0c, 0x18, 0x23, 0x17, +0x37, 0x31, 0x15, 0x2c, 0x43, 0x2e, 0xfe, 0xed, 0x23, 0x2f, +0x18, 0x29, 0x3b, 0x14, 0x21, 0x12, 0x01, 0x50, 0x14, 0x18, +0x01, 0x2d, 0x14, 0x15, 0x15, 0xfe, 0xea, 0x46, 0x01, 0x7b, +0x46, 0x29, 0x02, 0x17, 0x1a, 0x0b, 0x34, 0x23, 0x11, 0x21, +0x19, 0x10, 0x3d, 0x30, 0x1f, 0x3a, 0x2c, 0x1a, 0x02, 0x3a, +0x0e, 0x1c, 0x17, 0xfa, 0xa8, 0x0b, 0x0e, 0x06, 0xfe, 0x82, +0x0d, 0x41, 0x19, 0x0e, 0x10, 0x17, 0x83, 0x02, 0x6b, 0x00, +0x00, 0x00, 0x00, 0x04, 0x00, 0x15, 0xff, 0xf7, 0x01, 0xde, +0x02, 0x79, 0x00, 0x15, 0x00, 0x32, 0x00, 0x3c, 0x00, 0x40, +0x00, 0xd0, 0xb9, 0x00, 0x2c, 0xff, 0xd8, 0xb4, 0x0e, 0x15, +0x00, 0x4c, 0x12, 0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, +0x0f, 0xb8, 0xff, 0xd8, 0x40, 0x11, 0x0e, 0x15, 0x00, 0x4c, +0x0a, 0x20, 0x0e, 0x15, 0x00, 0x4c, 0x07, 0x28, 0x0e, 0x15, +0x00, 0x4c, 0x12, 0xb8, 0xff, 0xe8, 0xb3, 0x1e, 0x00, 0x4d, +0x11, 0xb8, 0xff, 0xe8, 0x40, 0x59, 0x1e, 0x00, 0x4d, 0x3d, +0x3f, 0x3e, 0x3f, 0x9c, 0x40, 0x3d, 0x14, 0x40, 0x40, 0x3d, +0x3e, 0x3e, 0x19, 0x20, 0x96, 0x2d, 0x16, 0x16, 0x2d, 0x32, +0x19, 0x27, 0x27, 0x19, 0x40, 0x40, 0x10, 0x3a, 0x96, 0x08, +0x00, 0x00, 0x0f, 0x08, 0x1f, 0x08, 0x7f, 0x08, 0x8f, 0x08, +0x04, 0x08, 0x03, 0x35, 0x96, 0x10, 0x3f, 0x40, 0x59, 0x3d, +0x3e, 0x5b, 0x26, 0x26, 0x23, 0x98, 0x2a, 0x63, 0x32, 0x98, +0x18, 0x61, 0x33, 0x98, 0x03, 0x0f, 0x05, 0x1f, 0x05, 0x02, +0x05, 0x40, 0x1e, 0x21, 0x48, 0x05, 0x05, 0x37, 0x00, 0x15, +0x68, 0x37, 0x98, 0x0d, 0x66, 0x00, 0x3f, 0xed, 0x3f, 0xcd, +0x12, 0x39, 0x2f, 0x2b, 0x71, 0x33, 0xed, 0x3f, 0xed, 0x3f, +0xed, 0x32, 0x2f, 0x3f, 0x33, 0x3f, 0x33, 0x01, 0x2f, 0xfd, +0x32, 0xcc, 0x71, 0x32, 0x2f, 0x10, 0xed, 0x11, 0x33, 0x2f, +0x2f, 0x33, 0x2f, 0x10, 0xcd, 0xcd, 0x32, 0x2f, 0x10, 0xed, +0x11, 0x33, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, +0x30, 0x00, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x25, 0x36, 0x36, 0x37, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, +0x3e, 0x02, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x03, 0x15, 0x23, 0x35, 0x34, 0x36, 0x37, 0x37, 0x36, 0x36, +0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, +0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x01, 0x32, +0x37, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x07, 0x23, +0x01, 0x33, 0x01, 0x1e, 0x2e, 0x3a, 0x0d, 0x16, 0x12, 0x2f, +0x2d, 0x0c, 0x18, 0x23, 0x17, 0x37, 0x31, 0x15, 0x2c, 0x43, +0x2e, 0x48, 0xc6, 0x28, 0x1a, 0x16, 0x17, 0x13, 0x17, 0x10, +0x0f, 0x20, 0x0c, 0x20, 0x11, 0x33, 0x1a, 0x30, 0x2f, 0x1b, +0x25, 0x29, 0x0d, 0x01, 0x15, 0x14, 0x18, 0x01, 0x2d, 0x14, +0x15, 0x15, 0xf8, 0x46, 0x01, 0x7b, 0x46, 0x29, 0x02, 0x17, +0x1a, 0x0b, 0x34, 0x23, 0x11, 0x21, 0x19, 0x10, 0x3d, 0x30, +0x1f, 0x3a, 0x2c, 0x1a, 0x01, 0xb1, 0x32, 0x17, 0x20, 0x23, +0x10, 0x0f, 0x0e, 0x19, 0x0e, 0x11, 0x10, 0x0d, 0x0d, 0x28, +0x13, 0x13, 0x32, 0x20, 0x1a, 0x25, 0x1c, 0x18, 0x0c, 0xfe, +0xdb, 0x0d, 0x41, 0x19, 0x0e, 0x10, 0x17, 0x83, 0x02, 0x6b, +0x00, 0x00, 0x00, 0x05, 0x00, 0x0f, 0xff, 0xf7, 0x01, 0xe2, +0x02, 0x72, 0x00, 0x15, 0x00, 0x22, 0x00, 0x2c, 0x00, 0x31, +0x00, 0x35, 0x00, 0xb0, 0xb9, 0x00, 0x30, 0xff, 0xe8, 0xb3, +0x17, 0x00, 0x4d, 0x2e, 0xb8, 0xff, 0xe0, 0xb3, 0x17, 0x00, +0x4d, 0x12, 0xb8, 0xff, 0xf8, 0xb3, 0x12, 0x00, 0x4d, 0x0f, +0xb8, 0xff, 0xe0, 0x40, 0x54, 0x0e, 0x15, 0x00, 0x4c, 0x0a, +0x20, 0x0e, 0x15, 0x00, 0x4c, 0x07, 0x28, 0x0e, 0x15, 0x00, +0x4c, 0x32, 0x34, 0x33, 0x34, 0x9c, 0x35, 0x32, 0x14, 0x35, +0x35, 0x32, 0x33, 0x33, 0x30, 0x1f, 0x22, 0x2d, 0x2d, 0x1d, +0x18, 0x1a, 0x96, 0x17, 0x96, 0x1d, 0x35, 0x35, 0x03, 0x25, +0x96, 0x10, 0x2a, 0x96, 0x08, 0x00, 0x00, 0x08, 0x10, 0x34, +0x35, 0x59, 0x32, 0x33, 0x5b, 0x2d, 0x22, 0x60, 0x1f, 0x17, +0x30, 0x1a, 0x1d, 0x1c, 0x61, 0x23, 0x98, 0x03, 0x05, 0x05, +0x27, 0x00, 0x98, 0x15, 0x68, 0x27, 0x98, 0x0d, 0x66, 0x00, +0x3f, 0xed, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0x33, 0xed, 0x3f, +0xdd, 0x32, 0xcd, 0x32, 0x32, 0x3f, 0x33, 0x3f, 0x33, 0x3f, +0x33, 0x01, 0x2f, 0xcc, 0x32, 0x2f, 0x10, 0xed, 0x10, 0xed, +0x32, 0x33, 0x2f, 0x2f, 0xed, 0xfd, 0xcd, 0x11, 0x33, 0x11, +0x33, 0x2f, 0x33, 0x33, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, +0xc4, 0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x25, 0x36, 0x36, 0x37, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, +0x3e, 0x02, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x03, 0x15, 0x33, 0x15, 0x23, 0x15, 0x23, 0x35, 0x23, 0x35, +0x36, 0x36, 0x37, 0x13, 0x32, 0x37, 0x26, 0x23, 0x22, 0x06, +0x15, 0x14, 0x16, 0x03, 0x06, 0x06, 0x07, 0x33, 0x03, 0x23, +0x01, 0x33, 0x01, 0x1e, 0x2e, 0x3a, 0x0d, 0x16, 0x12, 0x2f, +0x2d, 0x0c, 0x18, 0x23, 0x17, 0x37, 0x31, 0x15, 0x2c, 0x43, +0x2e, 0x57, 0x23, 0x23, 0x3b, 0x82, 0x1b, 0x2f, 0x20, 0xf8, +0x14, 0x18, 0x01, 0x2d, 0x14, 0x15, 0x15, 0xca, 0x16, 0x21, +0x10, 0x47, 0x2a, 0x46, 0x01, 0x7b, 0x46, 0x29, 0x02, 0x17, +0x1a, 0x0b, 0x34, 0x23, 0x11, 0x21, 0x19, 0x10, 0x3d, 0x30, +0x1f, 0x3a, 0x2c, 0x1a, 0x02, 0x7b, 0x98, 0x32, 0x30, 0x30, +0x29, 0x2e, 0x4b, 0x28, 0xfe, 0x11, 0x0d, 0x41, 0x19, 0x0e, +0x10, 0x17, 0x01, 0xc4, 0x1b, 0x38, 0x1a, 0xfe, 0x26, 0x02, +0x6b, 0x00, 0x00, 0x04, 0x00, 0x0d, 0xff, 0xf7, 0x01, 0xd5, +0x02, 0x72, 0x00, 0x15, 0x00, 0x31, 0x00, 0x3b, 0x00, 0x3f, +0x00, 0xf5, 0xb9, 0x00, 0x1a, 0xff, 0xd8, 0xb4, 0x0e, 0x15, +0x00, 0x4c, 0x18, 0xb8, 0xff, 0xd0, 0xb4, 0x0e, 0x15, 0x00, +0x4c, 0x12, 0xb8, 0xff, 0xf8, 0xb3, 0x12, 0x00, 0x4d, 0x0f, +0xb8, 0xff, 0xd8, 0x40, 0x16, 0x0e, 0x15, 0x00, 0x4c, 0x0a, +0x20, 0x0e, 0x15, 0x00, 0x4c, 0x07, 0x28, 0x0e, 0x15, 0x00, +0x4c, 0x1b, 0x20, 0x0d, 0x00, 0x4d, 0x17, 0xb8, 0xff, 0xd8, +0xb3, 0x0d, 0x00, 0x4d, 0x0e, 0xb8, 0xff, 0xd8, 0xb3, 0x0d, +0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xd8, 0x40, 0x5e, 0x0d, 0x00, +0x4d, 0x06, 0x30, 0x0d, 0x00, 0x4d, 0x3c, 0x3e, 0x3d, 0x3e, +0x9c, 0x3f, 0x3c, 0x14, 0x3f, 0x3f, 0x3c, 0x3d, 0x3d, 0x29, +0x30, 0x30, 0x26, 0x96, 0x4f, 0x19, 0x01, 0x19, 0x31, 0x16, +0x29, 0x2e, 0x29, 0x1f, 0x1f, 0x41, 0x29, 0x01, 0x29, 0x3f, +0x3f, 0x03, 0x34, 0x96, 0x10, 0x39, 0x96, 0x08, 0x00, 0x00, +0x08, 0x10, 0x3e, 0x3f, 0x59, 0x3c, 0x3d, 0x5b, 0x29, 0x98, +0x16, 0x16, 0x23, 0x31, 0x98, 0x2e, 0x60, 0x20, 0x20, 0x23, +0x98, 0x40, 0x1c, 0x01, 0x1c, 0x64, 0x32, 0x98, 0x05, 0x05, +0x36, 0x00, 0x98, 0x15, 0x68, 0x36, 0x98, 0x4f, 0x0d, 0x01, +0x0d, 0x66, 0x00, 0x3f, 0x5d, 0xed, 0x3f, 0xed, 0x12, 0x39, +0x2f, 0xed, 0x3f, 0x5d, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x12, +0x39, 0x2f, 0xed, 0x3f, 0x33, 0x3f, 0x33, 0x01, 0x2f, 0xcc, +0x32, 0x2f, 0x10, 0xed, 0x10, 0xed, 0x32, 0x33, 0x2f, 0x2f, +0x5d, 0x33, 0x2f, 0x11, 0x33, 0x10, 0xcd, 0x32, 0xdc, 0x5d, +0xed, 0x33, 0x2f, 0x11, 0x33, 0x2f, 0x87, 0x10, 0x2b, 0x87, +0x7d, 0xc4, 0x31, 0x30, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x36, 0x36, +0x37, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, +0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x03, 0x16, 0x16, +0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, +0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x3e, 0x03, 0x37, +0x33, 0x15, 0x23, 0x01, 0x32, 0x37, 0x26, 0x23, 0x22, 0x06, +0x15, 0x14, 0x16, 0x05, 0x23, 0x01, 0x33, 0x01, 0x1e, 0x2e, +0x3a, 0x0d, 0x16, 0x12, 0x2f, 0x2d, 0x0c, 0x18, 0x23, 0x17, +0x37, 0x31, 0x15, 0x2c, 0x43, 0x2e, 0xbd, 0x38, 0x36, 0x3a, +0x3b, 0x18, 0x2e, 0x0c, 0x0e, 0x0a, 0x23, 0x15, 0x1a, 0x22, +0x2f, 0x40, 0x03, 0x03, 0x03, 0x02, 0x01, 0x93, 0x60, 0x01, +0x08, 0x14, 0x18, 0x01, 0x2d, 0x14, 0x15, 0x15, 0xfe, 0xfa, +0x46, 0x01, 0x7b, 0x46, 0x29, 0x02, 0x17, 0x1a, 0x0b, 0x34, +0x23, 0x11, 0x21, 0x19, 0x10, 0x3d, 0x30, 0x1f, 0x3a, 0x2c, +0x1a, 0x02, 0x24, 0x02, 0x2b, 0x27, 0x28, 0x30, 0x0d, 0x08, +0x30, 0x05, 0x0e, 0x10, 0x13, 0x17, 0x13, 0x17, 0x1f, 0x1c, +0x1d, 0x15, 0x32, 0xfe, 0x43, 0x0d, 0x41, 0x19, 0x0e, 0x10, +0x17, 0x83, 0x02, 0x6b, 0x00, 0x04, 0x00, 0x0b, 0xff, 0xf7, +0x01, 0xd5, 0x02, 0x72, 0x00, 0x03, 0x00, 0x19, 0x00, 0x28, +0x00, 0x32, 0x00, 0x9b, 0xb9, 0x00, 0x16, 0xff, 0xf8, 0xb3, +0x12, 0x00, 0x4d, 0x13, 0xb8, 0xff, 0xd8, 0x40, 0x54, 0x0e, +0x15, 0x00, 0x4c, 0x0e, 0x20, 0x0e, 0x15, 0x00, 0x4c, 0x0b, +0x28, 0x0e, 0x15, 0x00, 0x4c, 0x28, 0x96, 0x1a, 0x1a, 0x1f, +0x5f, 0x23, 0x01, 0x23, 0x20, 0x00, 0x02, 0x01, 0x02, 0x9c, +0x03, 0x00, 0x14, 0x03, 0x03, 0x00, 0x01, 0x01, 0x50, 0x20, +0x01, 0x20, 0x07, 0x2b, 0x96, 0x14, 0x30, 0x96, 0x0c, 0x04, +0x04, 0x0c, 0x14, 0x03, 0x03, 0x14, 0x23, 0x1f, 0x98, 0x21, +0x60, 0x1a, 0x61, 0x29, 0x98, 0x07, 0x09, 0x09, 0x2d, 0x04, +0x98, 0x19, 0x68, 0x2d, 0x98, 0x11, 0x66, 0x02, 0x03, 0x59, +0x00, 0x01, 0x5b, 0x00, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0xed, +0x3f, 0xed, 0x12, 0x39, 0x2f, 0x33, 0xed, 0x3f, 0x3f, 0xed, +0x32, 0x01, 0x2f, 0x33, 0x2f, 0x10, 0xcc, 0x32, 0x2f, 0x10, +0xed, 0x10, 0xed, 0x32, 0x2f, 0x5d, 0x33, 0x2f, 0x87, 0x10, +0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, 0x10, 0xcd, 0x5d, 0x32, +0x39, 0x2f, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x33, +0x23, 0x01, 0x33, 0x03, 0x36, 0x36, 0x37, 0x06, 0x23, 0x22, +0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x15, 0x14, +0x0e, 0x02, 0x23, 0x03, 0x3e, 0x03, 0x37, 0x23, 0x35, 0x33, +0x15, 0x0e, 0x03, 0x07, 0x17, 0x32, 0x37, 0x34, 0x23, 0x22, +0x06, 0x15, 0x14, 0x16, 0x50, 0x45, 0x01, 0x7a, 0x47, 0xae, +0x2e, 0x3b, 0x0d, 0x15, 0x14, 0x2f, 0x2d, 0x0c, 0x18, 0x23, +0x17, 0x37, 0x31, 0x15, 0x2c, 0x43, 0x2e, 0xdd, 0x06, 0x0e, +0x12, 0x19, 0x12, 0x68, 0xaf, 0x18, 0x1e, 0x14, 0x0d, 0x06, +0xf0, 0x15, 0x17, 0x2e, 0x14, 0x15, 0x15, 0x02, 0x6b, 0xfd, +0xbe, 0x02, 0x17, 0x1b, 0x0c, 0x34, 0x23, 0x11, 0x21, 0x19, +0x10, 0x3d, 0x30, 0x1f, 0x3a, 0x2c, 0x1a, 0x01, 0x81, 0x22, +0x34, 0x2d, 0x2b, 0x1a, 0x32, 0x29, 0x1b, 0x2c, 0x2f, 0x36, +0x25, 0xf5, 0x0d, 0x41, 0x19, 0x0e, 0x10, 0x17, 0x00, 0x06, +0x00, 0x13, 0xff, 0xf7, 0x01, 0xe1, 0x02, 0x79, 0x00, 0x1f, +0x00, 0x35, 0x00, 0x3f, 0x00, 0x4c, 0x00, 0x57, 0x00, 0x5b, +0x01, 0x54, 0xb9, 0x00, 0x2f, 0xff, 0xd8, 0x40, 0x17, 0x0e, +0x15, 0x00, 0x4c, 0x2a, 0x18, 0x0e, 0x15, 0x00, 0x4c, 0x27, +0x20, 0x0e, 0x15, 0x00, 0x4c, 0x1e, 0x30, 0x0e, 0x15, 0x00, +0x4c, 0x18, 0xb8, 0xff, 0xe0, 0xb4, 0x0e, 0x15, 0x00, 0x4c, +0x13, 0xb8, 0xff, 0xf0, 0xb3, 0x10, 0x00, 0x4d, 0x0e, 0xb8, +0xff, 0xd8, 0x40, 0x36, 0x0e, 0x15, 0x00, 0x4c, 0x08, 0x28, +0x0e, 0x15, 0x00, 0x4c, 0x46, 0x20, 0x18, 0x00, 0x4d, 0x46, +0x28, 0x17, 0x00, 0x4d, 0x46, 0x20, 0x16, 0x00, 0x4d, 0x43, +0x20, 0x18, 0x00, 0x4d, 0x43, 0x18, 0x16, 0x17, 0x00, 0x4c, +0x42, 0x18, 0x18, 0x00, 0x4d, 0x42, 0x20, 0x16, 0x17, 0x00, +0x4c, 0x32, 0x18, 0x12, 0x15, 0x00, 0x4c, 0x22, 0xb8, 0xff, +0xe0, 0xb3, 0x11, 0x00, 0x4d, 0x22, 0xb8, 0xff, 0xe8, 0xb3, +0x10, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xe0, 0xb4, 0x13, 0x15, +0x00, 0x4c, 0x14, 0xb8, 0xff, 0xd8, 0xb3, 0x12, 0x00, 0x4d, +0x14, 0xb8, 0xff, 0xd0, 0xb3, 0x11, 0x00, 0x4d, 0x14, 0xb8, +0xff, 0xe0, 0x40, 0x64, 0x10, 0x00, 0x4d, 0x04, 0x18, 0x16, +0x18, 0x00, 0x4c, 0x04, 0x18, 0x10, 0x00, 0x4d, 0x58, 0x5a, +0x59, 0x5a, 0x9c, 0x5b, 0x58, 0x14, 0x5b, 0x58, 0x5b, 0x5b, +0x23, 0x38, 0x96, 0x30, 0x3d, 0x96, 0x28, 0x20, 0x20, 0x28, +0x30, 0x59, 0x59, 0x00, 0x13, 0x50, 0x45, 0x03, 0x04, 0x06, +0x52, 0x96, 0x10, 0x10, 0x40, 0x96, 0x16, 0x00, 0x4d, 0x96, +0x06, 0x06, 0x47, 0x96, 0x00, 0x5a, 0x5b, 0x59, 0x58, 0x59, +0x5b, 0x36, 0x98, 0x23, 0x25, 0x25, 0x3a, 0x20, 0x98, 0x35, +0x68, 0x3a, 0x98, 0x2d, 0x66, 0x13, 0x50, 0x98, 0x45, 0x03, +0x45, 0x45, 0x55, 0x4a, 0x98, 0x70, 0x1b, 0x01, 0x1b, 0x64, +0x55, 0x98, 0x0b, 0x63, 0x00, 0x3f, 0xed, 0x3f, 0x5d, 0xed, +0x12, 0x39, 0x11, 0x33, 0x10, 0xe9, 0x32, 0x3f, 0xed, 0x3f, +0xed, 0x12, 0x39, 0x2f, 0x33, 0xed, 0x3f, 0x33, 0x3f, 0x33, +0x01, 0x2f, 0xed, 0x33, 0x2f, 0xed, 0x10, 0xdc, 0xed, 0x33, +0x2f, 0xed, 0x12, 0x17, 0x39, 0x11, 0x33, 0x2f, 0x2f, 0xcc, +0x32, 0x2f, 0x10, 0xed, 0x10, 0xed, 0x32, 0x33, 0x2f, 0x87, +0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x00, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x13, 0x34, 0x36, 0x37, 0x26, 0x26, 0x35, 0x34, +0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, +0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, +0x01, 0x36, 0x36, 0x37, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, +0x3e, 0x02, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x37, 0x32, 0x37, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, +0x03, 0x34, 0x2e, 0x02, 0x27, 0x06, 0x15, 0x14, 0x16, 0x33, +0x32, 0x36, 0x27, 0x14, 0x16, 0x17, 0x36, 0x35, 0x34, 0x26, +0x23, 0x22, 0x06, 0x13, 0x23, 0x01, 0x33, 0x13, 0x11, 0x1a, +0x0f, 0x13, 0x11, 0x1c, 0x24, 0x13, 0x12, 0x24, 0x1b, 0x11, +0x0e, 0x17, 0x13, 0x1a, 0x13, 0x1e, 0x27, 0x14, 0x15, 0x26, +0x1e, 0x12, 0x01, 0x0b, 0x2e, 0x3a, 0x0d, 0x16, 0x12, 0x2f, +0x2d, 0x0c, 0x18, 0x23, 0x17, 0x37, 0x31, 0x15, 0x2c, 0x43, +0x2e, 0x4e, 0x14, 0x18, 0x01, 0x2d, 0x14, 0x15, 0x15, 0xac, +0x0b, 0x13, 0x18, 0x0d, 0x1e, 0x1f, 0x11, 0x14, 0x1d, 0x58, +0x1f, 0x15, 0x1c, 0x15, 0x16, 0x0e, 0x17, 0x0f, 0x46, 0x01, +0x7b, 0x46, 0x01, 0xbb, 0x0c, 0x25, 0x0b, 0x09, 0x1c, 0x17, +0x12, 0x1a, 0x12, 0x08, 0x09, 0x12, 0x1a, 0x11, 0x0f, 0x1c, +0x0d, 0x09, 0x1d, 0x19, 0x13, 0x1d, 0x13, 0x0a, 0x08, 0x12, +0x1d, 0xfe, 0x83, 0x02, 0x17, 0x1a, 0x0b, 0x34, 0x23, 0x11, +0x21, 0x19, 0x10, 0x3d, 0x30, 0x1f, 0x3a, 0x2c, 0x1a, 0x8c, +0x0d, 0x41, 0x19, 0x0e, 0x10, 0x17, 0x01, 0x38, 0x09, 0x0c, +0x09, 0x07, 0x04, 0x0e, 0x1b, 0x0e, 0x0c, 0x0d, 0x82, 0x0e, +0x0f, 0x06, 0x11, 0x12, 0x0a, 0x0d, 0x0d, 0xfd, 0xc6, 0x02, +0x6b, 0x00, 0x00, 0x02, 0x00, 0x26, 0xff, 0xf5, 0x01, 0xbf, +0x02, 0xb5, 0x00, 0x20, 0x00, 0x32, 0x00, 0x92, 0x40, 0x11, +0x31, 0x18, 0x11, 0x00, 0x4d, 0x2d, 0x18, 0x0d, 0x00, 0x4d, +0x2d, 0x10, 0x0b, 0x0c, 0x00, 0x4c, 0x29, 0xb8, 0xff, 0xf8, +0xb3, 0x10, 0x00, 0x4d, 0x23, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, +0x00, 0x4d, 0x23, 0xb8, 0xff, 0xf0, 0x40, 0x15, 0x0d, 0x0e, +0x00, 0x4c, 0x20, 0x10, 0x0d, 0x00, 0x4d, 0x20, 0x20, 0x0b, +0x0c, 0x00, 0x4c, 0x13, 0x18, 0x11, 0x00, 0x4d, 0x10, 0xb8, +0xff, 0xf0, 0x40, 0x0e, 0x0e, 0x00, 0x4d, 0x0f, 0x18, 0x0d, +0x00, 0x4d, 0x0e, 0x08, 0x0c, 0x00, 0x4d, 0x09, 0xb8, 0xff, +0xd8, 0x40, 0x1a, 0x0e, 0x00, 0x4d, 0x1e, 0x30, 0x82, 0x0c, +0x34, 0x26, 0x82, 0x16, 0x04, 0x04, 0x16, 0x33, 0x21, 0x88, +0x1b, 0x1b, 0x07, 0x2b, 0x88, 0x11, 0x68, 0x00, 0x07, 0x00, +0x2f, 0xcd, 0x3f, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x01, 0x10, +0xc6, 0x32, 0x2f, 0x10, 0xed, 0x10, 0xde, 0xed, 0x32, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x22, 0x06, 0x07, 0x27, 0x36, +0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, +0x17, 0x26, 0x26, 0x07, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, +0x02, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x26, 0x26, 0xbe, 0x1a, +0x2e, 0x14, 0x0c, 0x1a, 0x3d, 0x1f, 0x48, 0x5e, 0x37, 0x16, +0x16, 0x35, 0x59, 0x43, 0x2c, 0x43, 0x2d, 0x16, 0x1a, 0x35, +0x4f, 0x36, 0x26, 0x3a, 0x11, 0x06, 0x4e, 0x18, 0x23, 0x34, +0x21, 0x10, 0x0d, 0x19, 0x27, 0x1a, 0x2a, 0x36, 0x20, 0x0e, +0x1a, 0x3a, 0x02, 0x6e, 0x0b, 0x09, 0x45, 0x0b, 0x0b, 0x3a, +0x60, 0x7c, 0x42, 0x3c, 0x80, 0x69, 0x43, 0x24, 0x3c, 0x4e, +0x2a, 0x2c, 0x56, 0x43, 0x2a, 0x17, 0x0d, 0x67, 0x6f, 0xf8, +0x1f, 0x32, 0x3f, 0x1f, 0x1b, 0x33, 0x27, 0x17, 0x34, 0x50, +0x5f, 0x2a, 0x19, 0x15, 0x00, 0x02, 0x00, 0x09, 0x00, 0x00, +0x01, 0xeb, 0x02, 0x6b, 0x00, 0x0b, 0x00, 0x16, 0x00, 0x47, +0x40, 0x27, 0x06, 0x12, 0x0c, 0x12, 0x78, 0x0b, 0x06, 0x14, +0x0b, 0x0b, 0x06, 0x05, 0x11, 0x0c, 0x11, 0x78, 0x00, 0x05, +0x14, 0x00, 0x00, 0x05, 0x0c, 0x00, 0x0b, 0x18, 0x00, 0x17, +0x0b, 0x44, 0x0c, 0x06, 0x05, 0x41, 0x12, 0x11, 0x79, 0x00, +0x44, 0x00, 0x3f, 0xed, 0x32, 0x3f, 0x33, 0x33, 0x3f, 0x01, +0x10, 0xc6, 0x10, 0xce, 0x11, 0x39, 0x87, 0x10, 0x2b, 0x87, +0x7d, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, +0x30, 0x33, 0x3e, 0x03, 0x37, 0x33, 0x1e, 0x03, 0x17, 0x03, +0x0e, 0x03, 0x07, 0x21, 0x2e, 0x03, 0x09, 0x17, 0x2c, 0x2d, +0x32, 0x1e, 0x66, 0x1b, 0x35, 0x31, 0x2a, 0x11, 0xf2, 0x0a, +0x21, 0x26, 0x28, 0x12, 0x01, 0x15, 0x12, 0x28, 0x26, 0x20, +0x59, 0x9d, 0x95, 0x92, 0x4e, 0x44, 0xa2, 0xa5, 0x9e, 0x42, +0x02, 0x23, 0x1b, 0x60, 0x7d, 0x95, 0x50, 0x50, 0x95, 0x7d, +0x60, 0x00, 0x00, 0x01, 0x00, 0x3a, 0xff, 0x9f, 0x01, 0xba, +0x02, 0x6b, 0x00, 0x07, 0x00, 0x1b, 0x40, 0x0b, 0x02, 0x01, +0x09, 0x05, 0x06, 0x08, 0x04, 0x07, 0x59, 0x02, 0x06, 0x00, +0x2f, 0x33, 0x3f, 0xcd, 0x01, 0x10, 0xd6, 0xcd, 0x10, 0xde, +0xcd, 0x31, 0x30, 0x01, 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, +0x11, 0x01, 0xba, 0x52, 0xdc, 0x52, 0x02, 0x6b, 0xfd, 0x34, +0x02, 0x86, 0xfd, 0x7a, 0x02, 0xcc, 0x00, 0x01, 0x00, 0x31, +0xff, 0x9f, 0x01, 0xbf, 0x02, 0x6b, 0x00, 0x17, 0x00, 0x54, +0x40, 0x2a, 0x00, 0x13, 0x00, 0x03, 0x13, 0x78, 0x0f, 0x0a, +0x14, 0x0f, 0x0f, 0x0a, 0x12, 0x12, 0x04, 0x19, 0x00, 0x03, +0x03, 0x78, 0x07, 0x0a, 0x14, 0x07, 0x07, 0x0a, 0x0f, 0x0f, +0x07, 0x18, 0x0a, 0x0a, 0x00, 0x00, 0x03, 0x0f, 0x13, 0x10, +0x41, 0x07, 0x03, 0x06, 0x00, 0x2f, 0xcd, 0x32, 0x3f, 0xcd, +0x32, 0x11, 0x39, 0x19, 0x2f, 0x33, 0x01, 0x18, 0x2f, 0x10, +0xc6, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x7d, 0x10, 0xc4, 0x01, +0x18, 0x10, 0xce, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x08, 0x7d, +0x10, 0xc4, 0x31, 0x30, 0x01, 0x06, 0x06, 0x07, 0x21, 0x15, +0x21, 0x35, 0x36, 0x36, 0x37, 0x2e, 0x03, 0x27, 0x35, 0x21, +0x15, 0x21, 0x1e, 0x03, 0x01, 0x4c, 0x38, 0x62, 0x21, 0x01, +0x2e, 0xfe, 0x72, 0x1e, 0x63, 0x41, 0x30, 0x41, 0x2c, 0x1a, +0x07, 0x01, 0x8a, 0xfe, 0xd8, 0x0e, 0x2b, 0x32, 0x34, 0x01, +0x0f, 0x53, 0x96, 0x42, 0x45, 0x3b, 0x3f, 0x96, 0x62, 0x49, +0x62, 0x42, 0x27, 0x0e, 0x38, 0x46, 0x17, 0x44, 0x4c, 0x4e, +0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x01, 0xe2, 0x02, 0x79, +0x00, 0x2d, 0x00, 0x60, 0xb9, 0x00, 0x07, 0xff, 0xd8, 0xb3, +0x0e, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xe0, 0x40, 0x2e, 0x0d, +0x00, 0x4d, 0x03, 0x18, 0x0e, 0x00, 0x4d, 0x03, 0x20, 0x0d, +0x00, 0x4d, 0x0f, 0x13, 0x13, 0x18, 0x76, 0x0a, 0x10, 0x10, +0x0a, 0x2f, 0x29, 0x25, 0x25, 0x22, 0x76, 0x00, 0x28, 0x28, +0x00, 0x2e, 0x13, 0x25, 0x25, 0x0f, 0x29, 0x79, 0x12, 0x27, +0x44, 0x1d, 0x7c, 0x05, 0x45, 0x00, 0x3f, 0xed, 0x3f, 0x33, +0xed, 0x32, 0x32, 0x11, 0x33, 0x01, 0x10, 0xc6, 0x32, 0x2f, +0x10, 0xed, 0x32, 0x2f, 0x33, 0x10, 0xce, 0x32, 0x2f, 0x10, +0xed, 0x32, 0x2f, 0x33, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x13, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, +0x0e, 0x02, 0x07, 0x33, 0x15, 0x23, 0x35, 0x3e, 0x03, 0x35, +0x34, 0x2e, 0x02, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x16, +0x17, 0x15, 0x23, 0x35, 0x33, 0x2e, 0x03, 0x20, 0x23, 0x3c, +0x4f, 0x2d, 0x2d, 0x4f, 0x3c, 0x23, 0x12, 0x1a, 0x20, 0x0d, +0x65, 0xc5, 0x18, 0x24, 0x18, 0x0c, 0x10, 0x20, 0x31, 0x21, +0x21, 0x31, 0x20, 0x10, 0x2a, 0x36, 0xc7, 0x67, 0x11, 0x1f, +0x1a, 0x0f, 0x01, 0x4c, 0x4b, 0x71, 0x4b, 0x26, 0x26, 0x4b, +0x71, 0x4b, 0x28, 0x4c, 0x43, 0x39, 0x16, 0x46, 0x33, 0x18, +0x41, 0x4b, 0x50, 0x27, 0x2d, 0x50, 0x3e, 0x24, 0x25, 0x3d, +0x51, 0x2d, 0x4e, 0x90, 0x3c, 0x33, 0x46, 0x19, 0x3e, 0x43, +0x48, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2e, 0x00, 0xe4, +0x01, 0xc7, 0x01, 0x2a, 0x00, 0x03, 0x00, 0x0d, 0xb3, 0x03, +0x02, 0x00, 0x03, 0x00, 0x2f, 0xcd, 0x01, 0x2f, 0x2f, 0x31, +0x30, 0x13, 0x21, 0x15, 0x21, 0x2e, 0x01, 0x99, 0xfe, 0x67, +0x01, 0x2a, 0x46, 0x00, 0xff, 0xff, 0x00, 0x19, 0x00, 0x00, +0x01, 0xda, 0x02, 0x6b, 0x02, 0x06, 0x01, 0x6e, 0x00, 0x00, +0xff, 0xff, 0x00, 0xb1, 0x00, 0xca, 0x01, 0x44, 0x01, 0x63, +0x02, 0x07, 0x00, 0x11, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, +0x00, 0x01, 0x00, 0x1d, 0xff, 0xf3, 0x01, 0xe2, 0x02, 0xbb, +0x00, 0x0e, 0x00, 0x2e, 0x40, 0x14, 0x08, 0x07, 0x04, 0x04, +0x01, 0x05, 0x06, 0x10, 0x0d, 0x01, 0x00, 0x04, 0x08, 0x5c, +0x05, 0x06, 0x0e, 0x0e, 0x0d, 0x01, 0x00, 0x2f, 0xcd, 0x32, +0x2f, 0x2f, 0x33, 0x3f, 0x33, 0x01, 0x2f, 0xdd, 0xcd, 0x10, +0xde, 0xcd, 0x11, 0x39, 0x19, 0x2f, 0x33, 0x33, 0x31, 0x30, +0x13, 0x37, 0x16, 0x16, 0x17, 0x13, 0x33, 0x03, 0x23, 0x2e, +0x03, 0x27, 0x07, 0x1d, 0x83, 0x1d, 0x2b, 0x14, 0x9d, 0x49, +0xc1, 0x4a, 0x0b, 0x16, 0x17, 0x1b, 0x10, 0x41, 0x01, 0x39, +0x2b, 0x50, 0x7b, 0x3e, 0x02, 0x60, 0xfd, 0x38, 0x24, 0x43, +0x45, 0x49, 0x2a, 0x15, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x88, +0x01, 0xd6, 0x01, 0x85, 0x00, 0x0b, 0x00, 0x2b, 0x00, 0x37, +0x00, 0x39, 0x40, 0x1b, 0x1f, 0x0f, 0x35, 0x03, 0x03, 0x17, +0x2f, 0x27, 0x09, 0x17, 0x32, 0x22, 0x22, 0x0f, 0x03, 0x35, +0x1f, 0x04, 0x12, 0x06, 0x1c, 0x12, 0x2c, 0x0c, 0x0c, 0x00, +0x12, 0x00, 0x2f, 0xcd, 0x33, 0x2f, 0xcd, 0x10, 0xdc, 0xcd, +0x12, 0x17, 0x39, 0x33, 0x2f, 0xcd, 0x01, 0x2f, 0xcd, 0x2f, +0xcd, 0x11, 0x39, 0x2f, 0xcd, 0x39, 0x39, 0x31, 0x30, 0x37, +0x32, 0x36, 0x37, 0x26, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, +0x16, 0x17, 0x22, 0x26, 0x27, 0x06, 0x06, 0x23, 0x22, 0x2e, +0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x36, +0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x27, +0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x16, +0x16, 0x98, 0x14, 0x23, 0x10, 0x0f, 0x25, 0x13, 0x17, 0x21, +0x21, 0xe0, 0x24, 0x35, 0x0e, 0x0f, 0x33, 0x24, 0x10, 0x29, +0x24, 0x19, 0x19, 0x24, 0x29, 0x10, 0x24, 0x33, 0x0f, 0x0f, +0x34, 0x24, 0x10, 0x29, 0x24, 0x18, 0x18, 0x24, 0x29, 0x13, +0x16, 0x21, 0x21, 0x16, 0x14, 0x24, 0x10, 0x0f, 0x25, 0xc2, +0x25, 0x20, 0x1f, 0x25, 0x22, 0x22, 0x23, 0x22, 0x3a, 0x28, +0x17, 0x17, 0x28, 0x0c, 0x1d, 0x31, 0x25, 0x25, 0x30, 0x1d, +0x0c, 0x29, 0x17, 0x17, 0x29, 0x0c, 0x1d, 0x30, 0x25, 0x25, +0x31, 0x1d, 0x0c, 0x3a, 0x22, 0x23, 0x22, 0x22, 0x24, 0x20, +0x20, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x4b, 0xff, 0x5b, +0x01, 0xa8, 0x02, 0xb5, 0x00, 0x17, 0x00, 0x1d, 0x40, 0x0c, +0x07, 0x0c, 0x13, 0x17, 0x17, 0x19, 0x18, 0x14, 0x10, 0x08, +0x04, 0x5a, 0x00, 0x3f, 0xcd, 0x2f, 0xcd, 0x01, 0x11, 0x12, +0x39, 0x2f, 0xce, 0xdd, 0xce, 0x31, 0x30, 0x13, 0x34, 0x36, +0x33, 0x32, 0x32, 0x17, 0x15, 0x23, 0x22, 0x06, 0x15, 0x11, +0x14, 0x06, 0x23, 0x22, 0x22, 0x27, 0x35, 0x33, 0x32, 0x36, +0x35, 0xd0, 0x53, 0x58, 0x03, 0x13, 0x17, 0x27, 0x33, 0x2c, +0x51, 0x58, 0x05, 0x12, 0x17, 0x27, 0x33, 0x2b, 0x01, 0xfa, +0x5a, 0x61, 0x01, 0x47, 0x3e, 0x33, 0xfe, 0x19, 0x59, 0x61, +0x01, 0x47, 0x3e, 0x33, 0xff, 0xff, 0x00, 0x25, 0x00, 0x5f, +0x01, 0xcf, 0x01, 0xb1, 0x02, 0x36, 0x00, 0x61, 0x00, 0x60, +0x00, 0x06, 0x00, 0x61, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x01, +0x00, 0x2e, 0x00, 0x0e, 0x01, 0xc7, 0x01, 0xfd, 0x00, 0x13, +0x00, 0x42, 0x40, 0x21, 0x0f, 0x0c, 0x0b, 0x08, 0x04, 0x07, +0x10, 0x12, 0x01, 0x02, 0x05, 0x04, 0x11, 0x06, 0x07, 0x07, +0x0a, 0x0d, 0x10, 0x11, 0x11, 0x03, 0x00, 0x08, 0x06, 0x05, +0x0b, 0x02, 0x0c, 0x01, 0x10, 0x0f, 0x12, 0x00, 0x2f, 0x33, +0xcd, 0xdd, 0x32, 0xde, 0x32, 0xdd, 0xcd, 0x33, 0x01, 0x2f, +0x33, 0x33, 0x2f, 0xcd, 0x2f, 0x33, 0x33, 0x2f, 0xcd, 0x11, +0x17, 0x39, 0x11, 0x12, 0x17, 0x39, 0x31, 0x30, 0x37, 0x33, +0x37, 0x23, 0x35, 0x33, 0x37, 0x17, 0x07, 0x33, 0x15, 0x23, +0x07, 0x33, 0x15, 0x23, 0x07, 0x27, 0x37, 0x23, 0x2e, 0x88, +0x3d, 0xc5, 0xe9, 0x3b, 0x3a, 0x2a, 0x65, 0x89, 0x3d, 0xc6, +0xea, 0x3a, 0x3b, 0x2a, 0x64, 0xca, 0x77, 0x47, 0x75, 0x20, +0x55, 0x47, 0x77, 0x47, 0x75, 0x20, 0x55, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x2e, 0x00, 0x01, 0x01, 0xc7, 0x02, 0x03, +0x02, 0x27, 0x01, 0x9f, 0x00, 0x00, 0xff, 0x1d, 0x00, 0x06, +0x00, 0x1f, 0xfd, 0x3d, 0xff, 0xff, 0x00, 0x2e, 0x00, 0x01, +0x01, 0xc7, 0x02, 0x03, 0x02, 0x27, 0x01, 0x9f, 0x00, 0x00, +0xff, 0x1d, 0x00, 0x06, 0x00, 0x21, 0xfd, 0x3d, 0x00, 0x02, +0x00, 0x27, 0xff, 0xf1, 0x01, 0xcd, 0x02, 0x7b, 0x00, 0x11, +0x00, 0x21, 0x00, 0x8c, 0x40, 0x1a, 0x19, 0x20, 0x0f, 0x00, +0x4d, 0x17, 0x28, 0x0f, 0x00, 0x4d, 0x15, 0x28, 0x0f, 0x00, +0x4d, 0x0f, 0x18, 0x0f, 0x00, 0x4d, 0x0c, 0x20, 0x0f, 0x00, +0x4d, 0x07, 0xb8, 0xff, 0xe0, 0xb3, 0x0d, 0x00, 0x4d, 0x03, +0xb8, 0xff, 0xe0, 0x40, 0x1d, 0x0d, 0x00, 0x4d, 0x05, 0x17, +0x17, 0x1f, 0x12, 0x0a, 0x1f, 0x1c, 0x00, 0x0d, 0x1f, 0x1f, +0x23, 0x22, 0x1c, 0x12, 0x0a, 0x00, 0x00, 0x05, 0x1f, 0x20, +0x16, 0x00, 0x4d, 0x1f, 0xb8, 0xff, 0xd0, 0xb3, 0x11, 0x00, +0x4d, 0x1f, 0xb8, 0xff, 0xc0, 0x40, 0x0d, 0x10, 0x00, 0x4d, +0x1f, 0x0d, 0x17, 0x30, 0x10, 0x11, 0x00, 0x4c, 0x17, 0x05, +0x00, 0x2f, 0x33, 0x2b, 0x2f, 0x33, 0x2b, 0x2b, 0x2b, 0x12, +0x39, 0x19, 0x2f, 0x33, 0x33, 0x33, 0x01, 0x11, 0x12, 0x39, +0x2f, 0x33, 0xdd, 0x18, 0xcd, 0x19, 0x10, 0xdd, 0x18, 0xcd, +0x11, 0x33, 0x11, 0x33, 0x31, 0x30, 0x00, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x3e, 0x03, 0x37, 0x1e, 0x03, +0x17, 0x06, 0x06, 0x07, 0x2e, 0x03, 0x25, 0x2e, 0x03, 0x27, +0x0e, 0x03, 0x07, 0x16, 0x16, 0x17, 0x36, 0x36, 0x27, 0x1e, +0x36, 0x33, 0x32, 0x1a, 0x1a, 0x32, 0x33, 0x36, 0x1e, 0x3b, +0x64, 0x34, 0x1a, 0x32, 0x33, 0x36, 0x01, 0x32, 0x12, 0x1e, +0x1e, 0x1e, 0x11, 0x11, 0x1f, 0x1d, 0x1f, 0x11, 0x22, 0x38, +0x23, 0x22, 0x38, 0x01, 0x36, 0x31, 0x57, 0x4f, 0x49, 0x25, +0x25, 0x49, 0x4f, 0x57, 0x31, 0x62, 0x9a, 0x49, 0x25, 0x49, +0x4f, 0x56, 0x32, 0x1f, 0x36, 0x31, 0x2d, 0x18, 0x18, 0x2e, +0x31, 0x35, 0x1f, 0x3d, 0x60, 0x2e, 0x2e, 0x5e, 0x00, 0x00, +0x00, 0x03, 0x00, 0x1c, 0x00, 0x00, 0x01, 0xcc, 0x02, 0xb5, +0x00, 0x03, 0x00, 0x0f, 0x00, 0x26, 0x00, 0x4d, 0x40, 0x2a, +0x12, 0x20, 0x0c, 0x00, 0x4d, 0x07, 0x83, 0x0d, 0x01, 0x7f, +0x00, 0x28, 0x20, 0x1e, 0x16, 0x22, 0x7f, 0x25, 0x10, 0x23, +0x27, 0x01, 0x23, 0x4c, 0x17, 0x17, 0x1a, 0x88, 0x14, 0x4d, +0x21, 0x24, 0x85, 0x10, 0x0a, 0x8a, 0x04, 0x02, 0x02, 0x1e, +0x10, 0x49, 0x00, 0x3f, 0x33, 0x33, 0x10, 0xde, 0xed, 0x10, +0xed, 0x32, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0x33, 0x01, 0x10, +0xd6, 0x32, 0xce, 0xfd, 0xcc, 0x33, 0xce, 0x10, 0xde, 0xed, +0xd4, 0xed, 0x31, 0x30, 0x2b, 0x21, 0x23, 0x11, 0x33, 0x27, +0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, +0x06, 0x05, 0x35, 0x34, 0x36, 0x33, 0x32, 0x17, 0x07, 0x26, +0x26, 0x23, 0x22, 0x06, 0x15, 0x15, 0x33, 0x15, 0x23, 0x11, +0x23, 0x11, 0x23, 0x35, 0x01, 0xc0, 0x53, 0x53, 0x2a, 0x16, +0x1f, 0x1f, 0x16, 0x17, 0x1f, 0x1f, 0xfe, 0xa4, 0x56, 0x5a, +0x2f, 0x18, 0x0c, 0x0a, 0x17, 0x13, 0x38, 0x2c, 0x7b, 0x7b, +0x53, 0x35, 0x01, 0xd0, 0x54, 0x1e, 0x19, 0x19, 0x1d, 0x1d, +0x19, 0x19, 0x1e, 0x54, 0x2a, 0x5a, 0x61, 0x06, 0x48, 0x04, +0x03, 0x3f, 0x36, 0x29, 0x45, 0xfe, 0x75, 0x01, 0x8b, 0x45, +0x00, 0x00, 0x00, 0x03, 0x00, 0x1c, 0x00, 0x00, 0x01, 0xcc, +0x02, 0xb5, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x26, 0x00, 0x44, +0x40, 0x24, 0x07, 0x83, 0x0d, 0x01, 0x7f, 0x00, 0x28, 0x20, +0x1e, 0x16, 0x21, 0x7f, 0x25, 0x10, 0x24, 0x27, 0x01, 0x23, +0x4c, 0x17, 0x17, 0x1a, 0x88, 0x14, 0x4d, 0x21, 0x24, 0x85, +0x1e, 0x10, 0x49, 0x0a, 0x8a, 0x04, 0x02, 0x49, 0x00, 0x3f, +0xde, 0xed, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0xed, 0x32, 0x2f, +0x3f, 0x33, 0x01, 0x10, 0xd6, 0x32, 0xcd, 0xfd, 0xcc, 0x33, +0xcd, 0x10, 0xde, 0xed, 0xd4, 0xed, 0x31, 0x30, 0x21, 0x23, +0x11, 0x33, 0x27, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, +0x16, 0x15, 0x14, 0x06, 0x05, 0x35, 0x34, 0x36, 0x33, 0x32, +0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x06, 0x15, 0x15, 0x33, +0x15, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, 0x01, 0xc0, 0x53, +0x53, 0x2a, 0x16, 0x1f, 0x1f, 0x16, 0x17, 0x1f, 0x1f, 0xfe, +0xa4, 0x56, 0x5a, 0x2f, 0x18, 0x0c, 0x0a, 0x17, 0x13, 0x38, +0x2c, 0x7b, 0x7b, 0x53, 0x35, 0x01, 0xd0, 0x54, 0x1e, 0x19, +0x19, 0x1d, 0x1d, 0x19, 0x19, 0x1e, 0x54, 0x2a, 0x5a, 0x61, +0x06, 0x48, 0x04, 0x03, 0x3f, 0x36, 0x29, 0x45, 0xfe, 0x75, +0x01, 0x8b, 0x45, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1c, +0xff, 0xf7, 0x01, 0xeb, 0x02, 0xb5, 0x00, 0x0b, 0x00, 0x22, +0x00, 0x44, 0x40, 0x24, 0x0b, 0x0b, 0x03, 0x7f, 0x06, 0x24, +0x1c, 0x1a, 0x12, 0x1d, 0x7f, 0x21, 0x0c, 0x20, 0x23, 0x1f, +0x4c, 0x13, 0x13, 0x16, 0x88, 0x10, 0x4d, 0x1d, 0x20, 0x85, +0x1a, 0x0c, 0x49, 0x04, 0x05, 0x4d, 0x0b, 0x88, 0x00, 0x51, +0x00, 0x3f, 0xed, 0x3f, 0x33, 0x3f, 0x33, 0xed, 0x32, 0x3f, +0xed, 0x32, 0x2f, 0x3f, 0x01, 0x10, 0xd6, 0x32, 0xcd, 0xfd, +0xcc, 0x33, 0xcd, 0x10, 0xdc, 0xed, 0x33, 0x2f, 0x31, 0x30, +0x05, 0x26, 0x26, 0x35, 0x11, 0x37, 0x11, 0x14, 0x1e, 0x02, +0x17, 0x01, 0x35, 0x34, 0x36, 0x33, 0x32, 0x17, 0x07, 0x26, +0x26, 0x23, 0x22, 0x06, 0x15, 0x15, 0x33, 0x15, 0x23, 0x11, +0x23, 0x11, 0x23, 0x35, 0x01, 0xe0, 0x44, 0x38, 0x53, 0x05, +0x0c, 0x14, 0x0f, 0xfe, 0x66, 0x56, 0x5a, 0x2f, 0x18, 0x0c, +0x0a, 0x17, 0x13, 0x38, 0x2c, 0x7b, 0x7b, 0x53, 0x35, 0x09, +0x02, 0x3e, 0x42, 0x02, 0x2e, 0x0e, 0xfd, 0xd2, 0x15, 0x1a, +0x10, 0x08, 0x03, 0x01, 0x93, 0x2a, 0x5a, 0x61, 0x06, 0x48, +0x04, 0x03, 0x3f, 0x36, 0x29, 0x45, 0xfe, 0x75, 0x01, 0x8b, +0x45, 0x00, 0x00, 0x02, 0x00, 0x1c, 0xff, 0xf7, 0x01, 0xeb, +0x02, 0xb5, 0x00, 0x0b, 0x00, 0x22, 0x00, 0x44, 0x40, 0x24, +0x0b, 0x0b, 0x03, 0x7f, 0x06, 0x24, 0x1c, 0x1a, 0x12, 0x1d, +0x7f, 0x21, 0x0c, 0x20, 0x23, 0x1f, 0x4c, 0x13, 0x13, 0x16, +0x88, 0x10, 0x4d, 0x1d, 0x20, 0x85, 0x1a, 0x0c, 0x49, 0x04, +0x05, 0x4d, 0x0b, 0x88, 0x00, 0x51, 0x00, 0x3f, 0xed, 0x3f, +0x33, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0xed, 0x32, 0x2f, 0x3f, +0x01, 0x10, 0xd6, 0x32, 0xcd, 0xfd, 0xcc, 0x33, 0xcd, 0x10, +0xdc, 0xed, 0x33, 0x2f, 0x31, 0x30, 0x05, 0x26, 0x26, 0x35, +0x11, 0x37, 0x11, 0x14, 0x1e, 0x02, 0x17, 0x01, 0x35, 0x34, +0x36, 0x33, 0x32, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x06, +0x15, 0x15, 0x33, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, +0x01, 0xe0, 0x44, 0x38, 0x53, 0x05, 0x0c, 0x14, 0x0f, 0xfe, +0x66, 0x56, 0x5a, 0x2f, 0x18, 0x0c, 0x0a, 0x17, 0x13, 0x38, +0x2c, 0x7b, 0x7b, 0x53, 0x35, 0x09, 0x02, 0x3e, 0x42, 0x02, +0x2e, 0x0e, 0xfd, 0xd2, 0x15, 0x1a, 0x10, 0x08, 0x03, 0x01, +0x93, 0x2a, 0x5a, 0x61, 0x06, 0x48, 0x04, 0x03, 0x3f, 0x36, +0x29, 0x45, 0xfe, 0x75, 0x01, 0x8b, 0x45, 0x00, 0xff, 0xff, +0x00, 0x74, 0x01, 0x7d, 0x01, 0x80, 0x02, 0xe4, 0x02, 0x06, +0x01, 0x6f, 0x00, 0x6b, 0xff, 0xff, 0x00, 0x87, 0x01, 0x84, +0x01, 0x88, 0x02, 0xdd, 0x02, 0x06, 0x00, 0x94, 0x09, 0x6b, +0xff, 0xff, 0x00, 0x7c, 0x01, 0x84, 0x01, 0x78, 0x02, 0xe4, +0x02, 0x06, 0x00, 0x8d, 0x00, 0x6b, 0xff, 0xff, 0x00, 0x80, +0x01, 0x7d, 0x01, 0x78, 0x02, 0xe4, 0x02, 0x06, 0x00, 0x8e, +0x02, 0x6b, 0xff, 0xff, 0x00, 0x69, 0x01, 0x84, 0x01, 0x80, +0x02, 0xdd, 0x02, 0x06, 0x01, 0x70, 0x00, 0x6b, 0xff, 0xff, +0x00, 0x77, 0x01, 0x7d, 0x01, 0x6f, 0x02, 0xdd, 0x02, 0x06, +0x01, 0x71, 0xf8, 0x6b, 0xff, 0xff, 0x00, 0x75, 0x01, 0x7d, +0x01, 0x7a, 0x02, 0xdf, 0x02, 0x06, 0x01, 0x72, 0xf8, 0x6b, +0xff, 0xff, 0x00, 0x7e, 0x01, 0x84, 0x01, 0x7d, 0x02, 0xdd, +0x02, 0x06, 0x01, 0x73, 0xf8, 0x6b, 0xff, 0xff, 0x00, 0x77, +0x01, 0x7d, 0x01, 0x7d, 0x02, 0xe4, 0x02, 0x06, 0x01, 0x74, +0x00, 0x6b, 0xff, 0xff, 0x00, 0x7c, 0x01, 0x83, 0x01, 0x81, +0x02, 0xe4, 0x02, 0x06, 0x01, 0x75, 0xf8, 0x6b, 0xff, 0xff, +0x00, 0x74, 0xff, 0x60, 0x01, 0x80, 0x00, 0xc7, 0x02, 0x07, +0x01, 0x6f, 0x00, 0x00, 0xfe, 0x4e, 0x00, 0x00, 0xff, 0xff, +0x00, 0x87, 0xff, 0x67, 0x01, 0x88, 0x00, 0xc0, 0x02, 0x07, +0x00, 0x94, 0x00, 0x09, 0xfe, 0x4e, 0x00, 0x00, 0xff, 0xff, +0x00, 0x7c, 0xff, 0x67, 0x01, 0x78, 0x00, 0xc7, 0x02, 0x07, +0x00, 0x8d, 0x00, 0x00, 0xfe, 0x4e, 0x00, 0x00, 0xff, 0xff, +0x00, 0x80, 0xff, 0x60, 0x01, 0x78, 0x00, 0xc7, 0x02, 0x07, +0x00, 0x8e, 0x00, 0x02, 0xfe, 0x4e, 0x00, 0x00, 0xff, 0xff, +0x00, 0x69, 0xff, 0x67, 0x01, 0x80, 0x00, 0xc0, 0x02, 0x07, +0x01, 0x70, 0x00, 0x00, 0xfe, 0x4e, 0x00, 0x00, 0xff, 0xff, +0x00, 0x77, 0xff, 0x60, 0x01, 0x6f, 0x00, 0xc0, 0x02, 0x07, +0x01, 0x71, 0xff, 0xf8, 0xfe, 0x4e, 0x00, 0x00, 0xff, 0xff, +0x00, 0x75, 0xff, 0x60, 0x01, 0x7a, 0x00, 0xc2, 0x02, 0x07, +0x01, 0x72, 0xff, 0xf8, 0xfe, 0x4e, 0x00, 0x00, 0xff, 0xff, +0x00, 0x7e, 0xff, 0x67, 0x01, 0x7d, 0x00, 0xc0, 0x02, 0x07, +0x01, 0x73, 0xff, 0xf8, 0xfe, 0x4e, 0x00, 0x00, 0xff, 0xff, +0x00, 0x77, 0xff, 0x60, 0x01, 0x7d, 0x00, 0xc7, 0x02, 0x07, +0x01, 0x74, 0x00, 0x00, 0xfe, 0x4e, 0x00, 0x00, 0xff, 0xff, +0x00, 0x7c, 0xff, 0x66, 0x01, 0x81, 0x00, 0xc7, 0x02, 0x07, +0x01, 0x75, 0xff, 0xf8, 0xfe, 0x4e, 0x00, 0x00, 0x00, 0x01, +0x00, 0xd2, 0x01, 0xee, 0x01, 0x21, 0x02, 0xb5, 0x00, 0x03, +0x00, 0x11, 0xb5, 0x00, 0x40, 0x03, 0x03, 0x80, 0x02, 0x00, +0x2f, 0x1a, 0xcd, 0x01, 0x2f, 0x1a, 0xcd, 0x31, 0x30, 0x01, +0x07, 0x23, 0x35, 0x01, 0x21, 0x18, 0x37, 0x02, 0xb5, 0xc7, +0xc7, 0x00, 0x00, 0x01, 0x00, 0xab, 0xff, 0x56, 0x01, 0x40, +0xff, 0xd3, 0x00, 0x0e, 0x00, 0x13, 0xb6, 0x0a, 0x01, 0x00, +0x07, 0x0a, 0x00, 0x0f, 0x00, 0x10, 0xde, 0xde, 0xcd, 0x01, +0x2f, 0xcd, 0xce, 0x31, 0x30, 0x17, 0x33, 0x16, 0x16, 0x15, +0x14, 0x06, 0x23, 0x22, 0x27, 0x35, 0x33, 0x32, 0x36, 0x35, +0xee, 0x50, 0x01, 0x01, 0x3d, 0x2e, 0x14, 0x16, 0x0f, 0x21, +0x13, 0x2d, 0x05, 0x0b, 0x04, 0x39, 0x30, 0x06, 0x30, 0x1d, +0x1d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb9, 0x02, 0x20, +0x01, 0x3b, 0x02, 0xb9, 0x00, 0x0f, 0x00, 0x11, 0xb5, 0x0a, +0x0f, 0x04, 0x09, 0x0a, 0x00, 0x00, 0x2f, 0xde, 0xcd, 0x01, +0x2f, 0xdd, 0xce, 0x31, 0x30, 0x01, 0x23, 0x26, 0x34, 0x35, +0x34, 0x3e, 0x02, 0x37, 0x17, 0x0e, 0x03, 0x15, 0x01, 0x09, +0x4f, 0x01, 0x12, 0x1d, 0x24, 0x12, 0x1d, 0x0b, 0x12, 0x0e, +0x07, 0x02, 0x20, 0x05, 0x0b, 0x03, 0x20, 0x2f, 0x20, 0x13, +0x04, 0x28, 0x08, 0x10, 0x16, 0x20, 0x18, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0xd2, 0x02, 0x08, 0x01, 0x21, 0x02, 0xb5, +0x00, 0x03, 0x00, 0x11, 0xb5, 0x00, 0x40, 0x03, 0x03, 0x80, +0x02, 0x00, 0x2f, 0x1a, 0xcd, 0x01, 0x2f, 0x1a, 0xcd, 0x31, +0x30, 0x01, 0x07, 0x23, 0x35, 0x01, 0x21, 0x18, 0x37, 0x02, +0xb5, 0xad, 0xad, 0x00, 0xff, 0xff, 0x00, 0x71, 0xff, 0x83, +0x01, 0x82, 0x02, 0xe7, 0x02, 0x06, 0x00, 0x0b, 0x00, 0x2a, +0xff, 0xff, 0x00, 0x71, 0xff, 0x83, 0x01, 0x82, 0x02, 0xe7, +0x02, 0x06, 0x00, 0x0c, 0x00, 0x2a, 0xff, 0xff, 0x00, 0x8c, +0x01, 0x0d, 0x01, 0x68, 0x01, 0x5b, 0x02, 0x06, 0x00, 0x10, +0x00, 0x36, 0xff, 0xff, 0x00, 0x45, 0xff, 0x85, 0x01, 0xaf, +0x02, 0xe5, 0x02, 0x06, 0x00, 0x12, 0x00, 0x2a, 0xff, 0xff, +0x00, 0x28, 0xff, 0xb5, 0x01, 0xd4, 0x02, 0xb5, 0x02, 0x06, +0x00, 0x23, 0x00, 0x3c, 0xff, 0xff, 0x00, 0x8f, 0xff, 0x85, +0x01, 0x7e, 0x02, 0xe5, 0x02, 0x06, 0x00, 0x3e, 0x00, 0x2a, +0xff, 0xff, 0x00, 0x46, 0xff, 0x85, 0x01, 0xae, 0x02, 0xe5, +0x02, 0x06, 0x00, 0x3f, 0x00, 0x2a, 0xff, 0xff, 0x00, 0x76, +0xff, 0x85, 0x01, 0x65, 0x02, 0xe5, 0x02, 0x06, 0x00, 0x40, +0x00, 0x2a, 0xff, 0xff, 0x00, 0x4f, 0xff, 0x85, 0x01, 0xab, +0x02, 0xe5, 0x02, 0x06, 0x00, 0x5e, 0x00, 0x2a, 0xff, 0xff, +0x00, 0x49, 0xff, 0x85, 0x01, 0xa5, 0x02, 0xe5, 0x02, 0x06, +0x00, 0x60, 0x00, 0x2a, 0xff, 0xff, 0x00, 0x90, 0x00, 0x6f, +0x01, 0x55, 0x01, 0xfa, 0x02, 0x06, 0x00, 0x6c, 0x00, 0x37, +0xff, 0xff, 0x00, 0x72, 0x00, 0xc4, 0x01, 0x82, 0x01, 0xe2, +0x02, 0x06, 0x00, 0x72, 0x00, 0x17, 0xff, 0xff, 0x00, 0x45, +0x01, 0x12, 0x01, 0xaf, 0x01, 0x58, 0x02, 0x06, 0x00, 0x73, +0x00, 0x26, 0xff, 0xff, 0x00, 0x00, 0x01, 0x12, 0x01, 0xf4, +0x01, 0x58, 0x02, 0x06, 0x00, 0x74, 0x00, 0x26, 0xff, 0xff, +0x00, 0x9f, 0x00, 0x6f, 0x01, 0x64, 0x01, 0xfa, 0x02, 0x06, +0x00, 0x78, 0x00, 0x37, 0xff, 0xff, 0x00, 0xb6, 0xff, 0xfa, +0x01, 0x3c, 0x02, 0x70, 0x02, 0x07, 0x00, 0x7c, 0x00, 0x00, +0x00, 0x9f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x3f, 0x00, 0x85, +0x01, 0x9d, 0x01, 0xe4, 0x02, 0x06, 0x00, 0x86, 0x00, 0x36, +0xff, 0xff, 0x00, 0x55, 0x00, 0x85, 0x01, 0xb5, 0x01, 0xe4, +0x02, 0x06, 0x00, 0x96, 0x00, 0x36, 0xff, 0xff, 0x00, 0x5c, +0xff, 0xf8, 0x01, 0x9a, 0x02, 0x73, 0x02, 0x07, 0x00, 0x9a, +0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x02, 0x00, 0x14, +0xff, 0xf5, 0x01, 0xcc, 0x02, 0xb5, 0x00, 0x1a, 0x00, 0x29, +0x00, 0x99, 0x40, 0x1c, 0x24, 0x18, 0x10, 0x00, 0x4d, 0x24, +0x20, 0x0f, 0x00, 0x4d, 0x24, 0x18, 0x0e, 0x00, 0x4d, 0x1f, +0x28, 0x0f, 0x10, 0x00, 0x4c, 0x1f, 0x18, 0x0d, 0x0e, 0x00, +0x4c, 0x0e, 0xb8, 0xff, 0xe0, 0xb4, 0x08, 0x0a, 0x00, 0x4c, +0x0a, 0xb8, 0xff, 0xe0, 0xb3, 0x0a, 0x00, 0x4d, 0x0a, 0xb8, +0xff, 0xe0, 0xb3, 0x08, 0x00, 0x4d, 0x09, 0xb8, 0xff, 0xd0, +0x40, 0x32, 0x09, 0x00, 0x4d, 0x21, 0x82, 0x0c, 0x2b, 0x29, +0x02, 0x00, 0x03, 0x7f, 0x18, 0x16, 0x00, 0x15, 0x01, 0x15, +0x2a, 0x03, 0x15, 0x00, 0x18, 0x18, 0x07, 0x19, 0x1a, 0x4d, +0x1b, 0x1e, 0x88, 0x14, 0x11, 0x51, 0x29, 0x26, 0x88, 0x04, +0x00, 0x07, 0x10, 0x07, 0x20, 0x07, 0x40, 0x07, 0x04, 0x08, +0x07, 0x50, 0x00, 0x3f, 0x5e, 0x5d, 0x33, 0xed, 0x32, 0x3f, +0x33, 0xed, 0x32, 0x3f, 0x33, 0x12, 0x39, 0x2f, 0x33, 0xcd, +0x32, 0x01, 0x10, 0xd6, 0x5d, 0xcd, 0x33, 0xfd, 0x32, 0xcd, +0x33, 0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x33, 0x15, 0x23, 0x15, +0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x26, 0x27, 0x11, 0x23, 0x35, 0x33, 0x35, 0x37, +0x11, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x2e, 0x02, +0x23, 0x22, 0x06, 0x07, 0xa8, 0xa2, 0xa2, 0x0f, 0x36, 0x22, +0x2d, 0x46, 0x30, 0x1a, 0x1e, 0x38, 0x4e, 0x30, 0x36, 0x52, +0x1a, 0x42, 0x42, 0x52, 0x12, 0x24, 0x10, 0x40, 0x49, 0x0d, +0x1b, 0x2c, 0x1e, 0x1c, 0x33, 0x0e, 0x02, 0x62, 0x3e, 0x65, +0x09, 0x13, 0x24, 0x40, 0x59, 0x36, 0x38, 0x5a, 0x3f, 0x22, +0x10, 0x08, 0x02, 0x17, 0x3e, 0x45, 0x0e, 0xfd, 0x93, 0x05, +0x05, 0x55, 0x55, 0x24, 0x3f, 0x2d, 0x1a, 0x17, 0x0d, 0x00, +0x00, 0x00, 0x00, 0x03, 0x00, 0x12, 0xff, 0xfb, 0x01, 0xe2, +0x02, 0x71, 0x00, 0x22, 0x00, 0x31, 0x00, 0x3e, 0x00, 0xc7, +0x40, 0x2f, 0x3a, 0x38, 0x12, 0x00, 0x4d, 0x3a, 0x28, 0x11, +0x00, 0x4d, 0x36, 0x28, 0x12, 0x00, 0x4d, 0x36, 0x30, 0x11, +0x00, 0x4d, 0x2f, 0x40, 0x12, 0x00, 0x4d, 0x2e, 0x30, 0x11, +0x00, 0x4d, 0x2e, 0x18, 0x10, 0x00, 0x4d, 0x29, 0x30, 0x11, +0x12, 0x00, 0x4c, 0x29, 0x10, 0x10, 0x00, 0x4d, 0x22, 0xb8, +0xff, 0xe8, 0xb3, 0x09, 0x00, 0x4d, 0x21, 0xb8, 0xff, 0xe8, +0xb4, 0x0a, 0x0c, 0x00, 0x4c, 0x18, 0xb8, 0xff, 0xe8, 0xb3, +0x0c, 0x00, 0x4d, 0x18, 0xb8, 0xff, 0xf0, 0xb3, 0x0b, 0x00, +0x4d, 0x18, 0xb8, 0xff, 0xe0, 0xb3, 0x0a, 0x00, 0x4d, 0x18, +0xb8, 0xff, 0xe8, 0x40, 0x37, 0x09, 0x00, 0x4d, 0x11, 0x10, +0x0c, 0x00, 0x4d, 0x11, 0x18, 0x0b, 0x00, 0x4d, 0x1d, 0x38, +0x76, 0x1a, 0x1a, 0x2c, 0x76, 0x20, 0x40, 0x23, 0x3e, 0x73, +0x00, 0x06, 0x20, 0x06, 0x02, 0x08, 0x06, 0x09, 0x00, 0x0f, +0x01, 0x0f, 0x3f, 0x0c, 0x0c, 0x06, 0x3b, 0x79, 0x14, 0x1d, +0x23, 0x79, 0x32, 0x32, 0x14, 0x41, 0x27, 0x7c, 0x00, 0x43, +0x00, 0x3f, 0xed, 0x3f, 0x39, 0x2f, 0xed, 0x39, 0x10, 0xed, +0x32, 0x32, 0x2f, 0x01, 0x10, 0xd6, 0x5d, 0xdd, 0xde, 0x5e, +0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, 0x33, 0x2f, 0xed, 0x32, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x05, +0x22, 0x2e, 0x02, 0x27, 0x11, 0x06, 0x06, 0x15, 0x14, 0x17, +0x07, 0x26, 0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x33, 0x32, +0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, 0x16, 0x16, 0x15, 0x14, +0x06, 0x03, 0x15, 0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x35, +0x34, 0x2e, 0x02, 0x23, 0x27, 0x33, 0x32, 0x3e, 0x02, 0x35, +0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x01, 0x1f, 0x0e, 0x21, +0x23, 0x21, 0x0d, 0x26, 0x21, 0x04, 0x43, 0x02, 0x05, 0x2c, +0x48, 0x5a, 0x2f, 0x0f, 0x24, 0x3d, 0x2d, 0x1a, 0x2d, 0x26, +0x33, 0x3c, 0x5b, 0x96, 0x0b, 0x19, 0x0b, 0x16, 0x29, 0x1f, +0x12, 0x15, 0x23, 0x2d, 0x18, 0x22, 0x18, 0x12, 0x26, 0x1e, +0x14, 0x2e, 0x2c, 0x09, 0x14, 0x0b, 0x05, 0x02, 0x03, 0x06, +0x04, 0x02, 0x18, 0x05, 0x20, 0x1d, 0x10, 0x11, 0x08, 0x06, +0x19, 0x0d, 0x32, 0x39, 0x1c, 0x07, 0x10, 0x26, 0x3e, 0x2e, +0x2c, 0x4a, 0x0e, 0x0e, 0x4c, 0x3c, 0x5d, 0x5d, 0x01, 0x26, +0xdd, 0x02, 0x02, 0x0a, 0x1a, 0x2d, 0x23, 0x20, 0x2a, 0x19, +0x0a, 0x44, 0x08, 0x17, 0x26, 0x1e, 0x36, 0x2d, 0x01, 0x02, +0x00, 0x00, 0x00, 0x02, 0x00, 0x36, 0xff, 0xfb, 0x01, 0xc3, +0x02, 0x6b, 0x00, 0x10, 0x00, 0x1f, 0x00, 0x79, 0x40, 0x16, +0x18, 0x20, 0x10, 0x00, 0x4d, 0x18, 0x18, 0x0f, 0x00, 0x4d, +0x14, 0x20, 0x0f, 0x10, 0x00, 0x4c, 0x13, 0x18, 0x0e, 0x00, +0x4d, 0x08, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x08, +0xb8, 0xff, 0xe0, 0xb3, 0x08, 0x00, 0x4d, 0x05, 0xb8, 0xff, +0xe8, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x05, 0xb8, 0xff, 0xe0, +0xb3, 0x0a, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe8, 0x40, 0x1c, +0x08, 0x00, 0x4d, 0x16, 0x76, 0x07, 0x10, 0x10, 0x07, 0x21, +0x01, 0x1d, 0x73, 0x0d, 0x20, 0x1c, 0x79, 0x01, 0x01, 0x11, +0x00, 0x79, 0x0e, 0x41, 0x11, 0x7c, 0x0a, 0x43, 0x00, 0x3f, +0xed, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xd6, +0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, +0x15, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x23, 0x22, +0x26, 0x27, 0x11, 0x21, 0x15, 0x03, 0x32, 0x3e, 0x02, 0x35, +0x34, 0x2e, 0x02, 0x23, 0x23, 0x15, 0x16, 0x16, 0x88, 0x42, +0x3b, 0x5d, 0x40, 0x21, 0x7f, 0x77, 0x23, 0x53, 0x21, 0x01, +0x56, 0xbb, 0x22, 0x3a, 0x2b, 0x19, 0x18, 0x2d, 0x3f, 0x27, +0x3e, 0x1a, 0x1d, 0x02, 0x25, 0xa6, 0x14, 0x2d, 0x4a, 0x35, +0x63, 0x61, 0x06, 0x09, 0x02, 0x61, 0x46, 0xfe, 0x1b, 0x0d, +0x1d, 0x30, 0x24, 0x25, 0x31, 0x1c, 0x0c, 0xf8, 0x03, 0x01, +0x00, 0x00, 0x00, 0x02, 0x00, 0x47, 0xff, 0xf5, 0x01, 0xcc, +0x02, 0xb1, 0x00, 0x14, 0x00, 0x23, 0x00, 0x89, 0x40, 0x2a, +0x1e, 0x18, 0x10, 0x00, 0x4d, 0x1e, 0x28, 0x0f, 0x00, 0x4d, +0x1e, 0x18, 0x0e, 0x00, 0x4d, 0x19, 0x30, 0x0f, 0x10, 0x00, +0x4c, 0x19, 0x28, 0x0e, 0x00, 0x4d, 0x19, 0x10, 0x0d, 0x00, +0x4d, 0x0b, 0x18, 0x10, 0x00, 0x4d, 0x0b, 0x10, 0x0f, 0x00, +0x4d, 0x06, 0xb8, 0xff, 0xf0, 0xb3, 0x0a, 0x00, 0x4d, 0x06, +0xb8, 0xff, 0xe0, 0xb3, 0x09, 0x00, 0x4d, 0x06, 0xb8, 0xff, +0xe8, 0x40, 0x23, 0x08, 0x00, 0x4d, 0x1b, 0x82, 0x09, 0x14, +0x14, 0x09, 0x25, 0x01, 0x15, 0x7f, 0x00, 0x11, 0x01, 0x08, +0x11, 0x24, 0x00, 0x85, 0x12, 0x4d, 0x15, 0x18, 0x88, 0x11, +0x0e, 0x51, 0x23, 0x20, 0x88, 0x01, 0x04, 0x50, 0x00, 0x3f, +0x33, 0xed, 0x32, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0xed, 0x01, +0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, +0x10, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x15, 0x36, 0x36, 0x33, +0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, +0x27, 0x11, 0x21, 0x15, 0x01, 0x16, 0x16, 0x33, 0x32, 0x36, +0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0x9a, 0x0f, +0x39, 0x23, 0x2f, 0x4a, 0x33, 0x1b, 0x20, 0x3a, 0x52, 0x32, +0x37, 0x56, 0x1a, 0x01, 0x53, 0xff, 0x00, 0x13, 0x26, 0x11, +0x45, 0x4e, 0x0e, 0x1e, 0x2f, 0x21, 0x1d, 0x36, 0x0e, 0x02, +0x6b, 0xac, 0x09, 0x13, 0x24, 0x40, 0x59, 0x36, 0x38, 0x5a, +0x3f, 0x22, 0x10, 0x08, 0x02, 0xa4, 0x46, 0xfd, 0xdd, 0x05, +0x05, 0x55, 0x55, 0x24, 0x3f, 0x2d, 0x1a, 0x17, 0x0d, 0x00, +0x00, 0x02, 0x00, 0x0b, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0xb5, +0x00, 0x15, 0x00, 0x23, 0x00, 0x83, 0x40, 0x15, 0x1e, 0x20, +0x0e, 0x00, 0x4d, 0x1e, 0x10, 0x0d, 0x00, 0x4d, 0x19, 0x20, +0x0e, 0x00, 0x4d, 0x19, 0x18, 0x0d, 0x00, 0x4d, 0x0a, 0xb8, +0xff, 0xe0, 0xb3, 0x08, 0x00, 0x4d, 0x09, 0xb8, 0xff, 0xe0, +0xb3, 0x10, 0x00, 0x4d, 0x09, 0xb8, 0xff, 0xe8, 0xb3, 0x0f, +0x00, 0x4d, 0x09, 0xb8, 0xff, 0xf0, 0xb3, 0x0a, 0x00, 0x4d, +0x09, 0xb8, 0xff, 0xe8, 0x40, 0x22, 0x09, 0x00, 0x4d, 0x1b, +0x82, 0x0c, 0x25, 0x03, 0x16, 0x7f, 0x00, 0x00, 0x14, 0x01, +0x08, 0x14, 0x24, 0x16, 0x18, 0x88, 0x14, 0x11, 0x51, 0x23, +0x20, 0x88, 0x04, 0x07, 0x50, 0x00, 0x00, 0x15, 0x03, 0x4d, +0x00, 0x3f, 0xcd, 0x39, 0x19, 0x2f, 0x18, 0x3f, 0x33, 0xed, +0x32, 0x3f, 0x33, 0xed, 0x32, 0x01, 0x10, 0xd6, 0x5e, 0x5d, +0xce, 0xed, 0x32, 0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x36, 0x36, +0x37, 0x15, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, +0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x11, 0x13, 0x16, 0x33, +0x32, 0x36, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, +0x0b, 0x20, 0x4a, 0x27, 0x10, 0x36, 0x23, 0x2f, 0x4a, 0x33, +0x1b, 0x20, 0x3a, 0x52, 0x32, 0x37, 0x53, 0x1a, 0x52, 0x25, +0x23, 0x45, 0x4e, 0x0e, 0x1e, 0x2f, 0x21, 0x1d, 0x34, 0x0e, +0x02, 0x78, 0x13, 0x20, 0x0a, 0xf6, 0x09, 0x13, 0x24, 0x40, +0x59, 0x36, 0x38, 0x5a, 0x3f, 0x22, 0x10, 0x08, 0x02, 0x26, +0xfe, 0x15, 0x0a, 0x55, 0x55, 0x24, 0x3f, 0x2d, 0x1a, 0x17, +0x0d, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0xff, 0xfb, +0x01, 0xc3, 0x02, 0x71, 0x00, 0x10, 0x00, 0x21, 0x00, 0x96, +0xb9, 0x00, 0x18, 0xff, 0xf0, 0xb3, 0x10, 0x00, 0x4d, 0x17, +0xb8, 0xff, 0xd8, 0xb3, 0x10, 0x00, 0x4d, 0x17, 0xb8, 0xff, +0xd0, 0xb3, 0x0f, 0x00, 0x4d, 0x17, 0xb8, 0xff, 0xe0, 0xb4, +0x08, 0x0a, 0x00, 0x4c, 0x15, 0xb8, 0xff, 0xd8, 0xb3, 0x10, +0x00, 0x4d, 0x15, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, +0x15, 0xb8, 0xff, 0xd8, 0xb3, 0x0a, 0x00, 0x4d, 0x15, 0xb8, +0xff, 0xe8, 0xb3, 0x09, 0x00, 0x4d, 0x15, 0xb8, 0xff, 0xd8, +0x40, 0x29, 0x08, 0x00, 0x4d, 0x0e, 0x18, 0x0e, 0x00, 0x4d, +0x03, 0x18, 0x0e, 0x00, 0x4d, 0x00, 0x76, 0x16, 0x23, 0x11, +0x09, 0x73, 0x1e, 0x00, 0x1c, 0x01, 0x08, 0x1c, 0x22, 0x1e, +0x1e, 0x1d, 0x21, 0x08, 0x7c, 0x11, 0x11, 0x21, 0x41, 0x0c, +0x7c, 0x19, 0x43, 0x00, 0x3f, 0xed, 0x3f, 0x39, 0x2f, 0xed, +0x10, 0xcd, 0x39, 0x19, 0x2f, 0x01, 0x18, 0x10, 0xd6, 0x5e, +0x5d, 0xce, 0xed, 0x32, 0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x25, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x22, 0x07, 0x11, 0x16, +0x16, 0x33, 0x32, 0x3e, 0x02, 0x27, 0x36, 0x32, 0x33, 0x32, +0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x11, 0x27, 0x36, +0x36, 0x37, 0x01, 0x71, 0x19, 0x2a, 0x39, 0x20, 0x0d, 0x21, +0x0d, 0x13, 0x27, 0x10, 0x1a, 0x32, 0x28, 0x19, 0xd7, 0x0b, +0x24, 0x0e, 0xec, 0x79, 0x6d, 0x22, 0x53, 0x21, 0x3e, 0x20, +0x47, 0x2a, 0xc2, 0x28, 0x34, 0x1f, 0x0d, 0x02, 0xfe, 0xfc, +0x03, 0x01, 0x0d, 0x1e, 0x32, 0xed, 0x02, 0xca, 0x64, 0x63, +0x06, 0x09, 0x01, 0xe6, 0x43, 0x13, 0x20, 0x0b, 0x00, 0x00, +0x00, 0x01, 0x00, 0x2a, 0xff, 0xf3, 0x01, 0xc6, 0x02, 0x79, +0x00, 0x1f, 0x00, 0x81, 0x40, 0x11, 0x1e, 0x28, 0x12, 0x00, +0x4d, 0x1e, 0x20, 0x11, 0x00, 0x4d, 0x1e, 0x18, 0x0f, 0x10, +0x00, 0x4c, 0x1a, 0xb8, 0xff, 0xe8, 0xb3, 0x0d, 0x00, 0x4d, +0x14, 0xb8, 0xff, 0xe8, 0x40, 0x41, 0x0d, 0x0e, 0x00, 0x4c, +0x0f, 0x28, 0x10, 0x00, 0x4d, 0x0e, 0x28, 0x12, 0x00, 0x4d, +0x0e, 0x18, 0x11, 0x00, 0x4d, 0x08, 0x08, 0x0c, 0x00, 0x4d, +0x08, 0x28, 0x0b, 0x00, 0x4d, 0x04, 0x10, 0x11, 0x12, 0x00, +0x4c, 0x04, 0x18, 0x0c, 0x00, 0x4d, 0x04, 0x28, 0x0b, 0x00, +0x4d, 0x06, 0x76, 0x17, 0x21, 0x0d, 0x0d, 0x1f, 0x20, 0x00, +0x00, 0x03, 0x7c, 0x1c, 0x46, 0x0c, 0x0c, 0x09, 0x7c, 0x12, +0x45, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x32, 0x2f, +0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xde, 0xed, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, +0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x3e, 0x03, 0x33, +0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, +0x27, 0x3f, 0x23, 0x3e, 0x1d, 0x53, 0x62, 0x59, 0x58, 0x1d, +0x40, 0x23, 0x15, 0x0f, 0x29, 0x2c, 0x2c, 0x12, 0x35, 0x5b, +0x42, 0x26, 0x28, 0x45, 0x5d, 0x35, 0x2d, 0x4d, 0x23, 0x5e, +0x13, 0x0f, 0x7a, 0x80, 0x78, 0x82, 0x0d, 0x14, 0x41, 0x0a, +0x10, 0x0a, 0x05, 0x26, 0x4f, 0x7a, 0x54, 0x53, 0x7a, 0x4f, +0x27, 0x13, 0x14, 0x00, 0x00, 0x01, 0x00, 0x2e, 0xff, 0xf3, +0x01, 0xeb, 0x02, 0xbe, 0x00, 0x2e, 0x00, 0x96, 0x40, 0x0b, +0x16, 0x18, 0x0e, 0x00, 0x4d, 0x16, 0x20, 0x0d, 0x00, 0x4d, +0x12, 0xb8, 0xff, 0xe0, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x12, +0xb8, 0xff, 0xd0, 0xb3, 0x10, 0x00, 0x4d, 0x12, 0xb8, 0xff, +0xc0, 0xb3, 0x0f, 0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xe8, 0xb4, +0x11, 0x12, 0x00, 0x4c, 0x0b, 0xb8, 0xff, 0xe8, 0xb4, 0x0b, +0x0c, 0x00, 0x4c, 0x05, 0xb8, 0xff, 0xe8, 0xb3, 0x12, 0x00, +0x4d, 0x05, 0xb8, 0xff, 0xf0, 0xb3, 0x11, 0x00, 0x4d, 0x05, +0xb8, 0xff, 0xe8, 0xb4, 0x0b, 0x0c, 0x00, 0x4c, 0x05, 0xb8, +0xff, 0xf0, 0x40, 0x1d, 0x09, 0x0a, 0x00, 0x4c, 0x20, 0x00, +0x00, 0x26, 0x11, 0x30, 0x08, 0x76, 0x19, 0x2f, 0x2a, 0x23, +0x1e, 0x00, 0x00, 0x03, 0x7c, 0x1e, 0x45, 0x10, 0x10, 0x0d, +0x7c, 0x14, 0x46, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, +0x32, 0x2f, 0x10, 0xdc, 0xcd, 0x01, 0x10, 0xd6, 0xed, 0x10, +0xde, 0xce, 0x33, 0x2f, 0x33, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x26, +0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x33, +0x32, 0x36, 0x37, 0x17, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, +0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x17, 0x36, 0x36, 0x33, +0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, +0x01, 0x84, 0x1c, 0x2f, 0x17, 0x24, 0x3b, 0x2a, 0x17, 0x18, +0x2a, 0x3a, 0x23, 0x1a, 0x3a, 0x1e, 0x15, 0x20, 0x47, 0x29, +0x32, 0x56, 0x3f, 0x23, 0x27, 0x41, 0x55, 0x2d, 0x24, 0x1d, +0x0d, 0x2e, 0x2a, 0x0a, 0x1b, 0x08, 0x0d, 0x05, 0x12, 0x05, +0x0f, 0x13, 0x0e, 0x0a, 0x02, 0x12, 0x10, 0x0e, 0x25, 0x42, +0x5c, 0x37, 0x40, 0x5e, 0x3e, 0x1e, 0x0f, 0x13, 0x44, 0x14, +0x13, 0x27, 0x4f, 0x7a, 0x53, 0x4c, 0x78, 0x53, 0x2c, 0x0b, +0x31, 0x1f, 0x06, 0x05, 0x3d, 0x03, 0x04, 0x13, 0x1f, 0x26, +0x00, 0x00, 0x00, 0x01, 0x00, 0x31, 0xff, 0xf5, 0x01, 0xe6, +0x02, 0x32, 0x00, 0x31, 0x00, 0x4a, 0xb5, 0x18, 0x30, 0x0e, +0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xe8, 0xb3, 0x0d, 0x00, 0x4d, +0x06, 0xb8, 0xff, 0xe0, 0x40, 0x1c, 0x0d, 0x00, 0x4d, 0x23, +0x00, 0x00, 0x29, 0x11, 0x33, 0x08, 0x82, 0x1b, 0x32, 0x2d, +0x26, 0x00, 0x05, 0x88, 0x20, 0x50, 0x10, 0x10, 0x0d, 0x88, +0x16, 0x51, 0x01, 0x49, 0x00, 0x3f, 0x3f, 0xed, 0x32, 0x2f, +0x3f, 0xed, 0x32, 0xdc, 0xcd, 0x01, 0x10, 0xd6, 0xed, 0x10, +0xde, 0xce, 0x33, 0x2f, 0x33, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x01, 0x2e, 0x03, 0x23, 0x22, 0x06, 0x15, 0x14, 0x1e, 0x02, +0x33, 0x32, 0x36, 0x37, 0x17, 0x0e, 0x03, 0x23, 0x22, 0x2e, +0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x36, +0x36, 0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, +0x0e, 0x02, 0x01, 0x82, 0x05, 0x16, 0x1b, 0x1f, 0x0f, 0x49, +0x4f, 0x12, 0x27, 0x3c, 0x2b, 0x21, 0x37, 0x10, 0x0c, 0x07, +0x1b, 0x23, 0x28, 0x12, 0x3a, 0x57, 0x3b, 0x1e, 0x20, 0x3c, +0x54, 0x35, 0x0e, 0x1c, 0x0e, 0x0a, 0x32, 0x2d, 0x0b, 0x1b, +0x09, 0x0e, 0x07, 0x10, 0x06, 0x12, 0x14, 0x0b, 0x05, 0x01, +0x80, 0x01, 0x07, 0x06, 0x05, 0x57, 0x55, 0x26, 0x3e, 0x2c, +0x18, 0x0b, 0x08, 0x45, 0x05, 0x08, 0x07, 0x04, 0x24, 0x40, +0x59, 0x35, 0x35, 0x5a, 0x41, 0x25, 0x03, 0x02, 0x34, 0x27, +0x06, 0x05, 0x3c, 0x03, 0x03, 0x14, 0x1f, 0x29, 0xff, 0xff, +0x00, 0x12, 0xff, 0xfb, 0x01, 0xcc, 0x02, 0x71, 0x02, 0x06, +0x00, 0xab, 0x00, 0x00, 0x00, 0x02, 0x00, 0x12, 0xff, 0xfb, +0x01, 0xe4, 0x02, 0x71, 0x00, 0x1b, 0x00, 0x2a, 0x00, 0x6d, +0x40, 0x4d, 0x26, 0x48, 0x0e, 0x00, 0x4d, 0x26, 0x20, 0x0d, +0x00, 0x4d, 0x25, 0x18, 0x12, 0x00, 0x4d, 0x25, 0x10, 0x11, +0x00, 0x4d, 0x22, 0x10, 0x11, 0x12, 0x00, 0x4c, 0x21, 0x18, +0x0e, 0x00, 0x4d, 0x21, 0x10, 0x0d, 0x00, 0x4d, 0x07, 0x18, +0x0e, 0x00, 0x4d, 0x03, 0x18, 0x0e, 0x00, 0x4d, 0x24, 0x76, +0x05, 0x2c, 0x29, 0x73, 0x00, 0x0e, 0x10, 0x0e, 0x20, 0x0e, +0x03, 0x0e, 0x11, 0x00, 0x17, 0x01, 0x08, 0x17, 0x2b, 0x1f, +0x7c, 0x0a, 0x43, 0x14, 0x0e, 0x29, 0x79, 0x00, 0x41, 0x00, +0x3f, 0xfd, 0x32, 0xcc, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0x5e, +0x5d, 0xd5, 0xd6, 0x5d, 0xed, 0x10, 0xde, 0xed, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, +0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, +0x27, 0x11, 0x06, 0x06, 0x15, 0x14, 0x17, 0x07, 0x26, 0x26, +0x35, 0x34, 0x3e, 0x02, 0x13, 0x16, 0x16, 0x33, 0x32, 0x3e, +0x02, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x01, 0x08, +0x2f, 0x50, 0x3b, 0x22, 0x22, 0x3b, 0x50, 0x2f, 0x1a, 0x39, +0x16, 0x26, 0x21, 0x04, 0x43, 0x02, 0x05, 0x33, 0x4b, 0x55, +0x0c, 0x08, 0x10, 0x06, 0x1f, 0x30, 0x21, 0x11, 0x42, 0x41, +0x08, 0x10, 0x04, 0x02, 0x71, 0x22, 0x4c, 0x78, 0x55, 0x56, +0x78, 0x4b, 0x22, 0x09, 0x06, 0x02, 0x18, 0x05, 0x20, 0x1d, +0x10, 0x11, 0x08, 0x06, 0x19, 0x0d, 0x35, 0x39, 0x1b, 0x05, +0xfd, 0xd4, 0x02, 0x01, 0x1b, 0x3b, 0x5d, 0x41, 0x7e, 0x76, +0x02, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x31, 0xff, 0xfb, +0x01, 0xbf, 0x02, 0x6b, 0x00, 0x10, 0x00, 0x1f, 0x00, 0x7f, +0xb9, 0x00, 0x1e, 0xff, 0xd8, 0xb3, 0x10, 0x00, 0x4d, 0x1d, +0xb8, 0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x1d, 0xb8, 0xff, +0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x19, 0xb8, 0xff, 0xe8, 0xb3, +0x10, 0x00, 0x4d, 0x19, 0xb8, 0xff, 0xd8, 0xb3, 0x0f, 0x00, +0x4d, 0x19, 0xb8, 0xff, 0xf8, 0x40, 0x30, 0x0e, 0x00, 0x4d, +0x0b, 0x10, 0x12, 0x00, 0x4d, 0x0b, 0x18, 0x11, 0x00, 0x4d, +0x0b, 0x20, 0x08, 0x00, 0x4d, 0x07, 0x20, 0x08, 0x00, 0x4d, +0x0f, 0x14, 0x73, 0x03, 0x21, 0x1b, 0x76, 0x09, 0x00, 0x00, +0x09, 0x20, 0x15, 0x79, 0x0f, 0x0f, 0x01, 0x11, 0x7c, 0x06, +0x43, 0x00, 0x79, 0x01, 0x41, 0x00, 0x3f, 0xed, 0x3f, 0xed, +0x11, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, +0xed, 0x10, 0xde, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x35, 0x21, +0x11, 0x06, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x3e, 0x02, +0x33, 0x33, 0x35, 0x03, 0x32, 0x36, 0x37, 0x35, 0x23, 0x22, +0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x68, 0x01, 0x57, 0x22, +0x53, 0x23, 0x77, 0x7f, 0x21, 0x40, 0x5d, 0x3b, 0x42, 0x49, +0x12, 0x1d, 0x1a, 0x3e, 0x27, 0x3f, 0x2d, 0x18, 0x19, 0x2b, +0x3a, 0x02, 0x25, 0x46, 0xfd, 0x9f, 0x09, 0x06, 0x61, 0x63, +0x35, 0x4a, 0x2d, 0x14, 0xa6, 0xfe, 0x1b, 0x02, 0x02, 0xf8, +0x0c, 0x1c, 0x31, 0x25, 0x24, 0x30, 0x1d, 0x0d, 0x00, 0x02, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xad, 0x02, 0xb1, 0x00, 0x14, +0x00, 0x23, 0x00, 0x5f, 0xb9, 0x00, 0x1f, 0xff, 0xe8, 0xb4, +0x0d, 0x0e, 0x00, 0x4c, 0x1f, 0xb8, 0xff, 0xf0, 0xb3, 0x0c, +0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xf0, 0x40, 0x2a, 0x0e, 0x00, +0x4d, 0x0f, 0x18, 0x0f, 0x10, 0x00, 0x4c, 0x0e, 0x20, 0x08, +0x00, 0x4d, 0x14, 0x23, 0x7f, 0x04, 0x25, 0x1d, 0x82, 0x0c, +0x01, 0x01, 0x0c, 0x24, 0x15, 0x18, 0x88, 0x14, 0x11, 0x50, +0x23, 0x20, 0x88, 0x04, 0x07, 0x51, 0x01, 0x85, 0x02, 0x4d, +0x00, 0x3f, 0xed, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0x33, 0xed, +0x32, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xed, 0x10, 0xde, +0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, +0x23, 0x35, 0x21, 0x11, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, +0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x15, 0x26, +0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x16, 0x33, 0x32, +0x36, 0x37, 0x01, 0x5a, 0xfe, 0x01, 0x51, 0x1b, 0x54, 0x38, +0x32, 0x52, 0x3a, 0x20, 0x1b, 0x34, 0x49, 0x2f, 0x25, 0x38, +0x0e, 0x0e, 0x36, 0x1d, 0x21, 0x2f, 0x1e, 0x0e, 0x4c, 0x3d, +0x1f, 0x2b, 0x0a, 0x02, 0x6b, 0x46, 0xfd, 0x5c, 0x08, 0x10, +0x22, 0x3f, 0x5a, 0x38, 0x36, 0x59, 0x40, 0x24, 0x12, 0x0a, +0x51, 0x0d, 0x17, 0x1a, 0x2d, 0x3f, 0x24, 0x51, 0x58, 0x06, +0x03, 0x00, 0x00, 0x02, 0x00, 0x27, 0xff, 0x5b, 0x01, 0xcc, +0x01, 0xdb, 0x00, 0x28, 0x00, 0x3c, 0x00, 0xe1, 0xb9, 0x00, +0x3a, 0xff, 0xe8, 0x40, 0x1e, 0x0f, 0x10, 0x00, 0x4c, 0x36, +0x18, 0x10, 0x00, 0x4d, 0x36, 0x10, 0x0f, 0x00, 0x4d, 0x30, +0x28, 0x12, 0x00, 0x4d, 0x30, 0x20, 0x11, 0x00, 0x4d, 0x30, +0x10, 0x0f, 0x00, 0x4d, 0x2c, 0xb8, 0xff, 0xe0, 0xb4, 0x11, +0x12, 0x00, 0x4c, 0x2c, 0xb8, 0xff, 0xe8, 0xb3, 0x0f, 0x00, +0x4d, 0x27, 0xb8, 0xff, 0xe0, 0x40, 0x19, 0x09, 0x00, 0x4d, +0x21, 0x20, 0x09, 0x00, 0x4d, 0x1d, 0x10, 0x0b, 0x00, 0x4d, +0x1c, 0x18, 0x09, 0x00, 0x4d, 0x19, 0x18, 0x11, 0x12, 0x00, +0x4c, 0x09, 0xb8, 0xff, 0xe8, 0xb4, 0x0f, 0x10, 0x00, 0x4c, +0x09, 0xb8, 0xff, 0xe0, 0xb4, 0x0d, 0x0e, 0x00, 0x4c, 0x09, +0xb8, 0xff, 0xe8, 0xb3, 0x0c, 0x00, 0x4d, 0x09, 0xb8, 0xff, +0xe0, 0xb4, 0x0a, 0x0b, 0x00, 0x4c, 0x07, 0xb8, 0xff, 0xe0, +0xb3, 0x10, 0x00, 0x4d, 0x06, 0xb8, 0xff, 0xe0, 0xb4, 0x0e, +0x0f, 0x00, 0x4c, 0x03, 0xb8, 0xff, 0xf0, 0x40, 0x23, 0x0b, +0x00, 0x4d, 0x2e, 0x05, 0x29, 0x17, 0x82, 0x08, 0x08, 0x33, +0x82, 0x00, 0x3e, 0x29, 0x82, 0x1f, 0x0e, 0x0e, 0x1f, 0x3d, +0x2e, 0x05, 0x05, 0x12, 0x38, 0x88, 0x24, 0x50, 0x0f, 0x0f, +0x12, 0x89, 0x0b, 0x4b, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, +0xed, 0x12, 0x39, 0x11, 0x33, 0x01, 0x10, 0xc6, 0x32, 0x2f, +0x10, 0xed, 0x10, 0xde, 0xed, 0x33, 0x2f, 0xed, 0x12, 0x39, +0x39, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x01, 0x14, 0x0e, 0x02, 0x07, 0x16, 0x16, +0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, +0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x26, 0x27, 0x2e, 0x03, +0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x05, 0x14, +0x1e, 0x02, 0x17, 0x3e, 0x03, 0x35, 0x34, 0x2e, 0x02, 0x23, +0x22, 0x0e, 0x02, 0x01, 0xcc, 0x10, 0x23, 0x38, 0x28, 0x1f, +0x29, 0x5a, 0x4e, 0x2c, 0x4f, 0x11, 0x0f, 0x09, 0x44, 0x2c, +0x0c, 0x20, 0x1b, 0x13, 0x2d, 0x29, 0x23, 0x40, 0x32, 0x1d, +0x17, 0x32, 0x50, 0x3a, 0x37, 0x4f, 0x33, 0x19, 0xfe, 0xb1, +0x14, 0x21, 0x2b, 0x17, 0x26, 0x32, 0x1e, 0x0c, 0x0d, 0x1d, +0x30, 0x23, 0x20, 0x2f, 0x1e, 0x0f, 0x01, 0x07, 0x20, 0x3f, +0x39, 0x31, 0x10, 0x13, 0x32, 0x26, 0x35, 0x33, 0x10, 0x06, +0x44, 0x05, 0x13, 0x02, 0x07, 0x0d, 0x0b, 0x18, 0x27, 0x1a, +0x17, 0x2d, 0x38, 0x49, 0x32, 0x25, 0x49, 0x3b, 0x24, 0x22, +0x39, 0x4e, 0x29, 0x24, 0x37, 0x2a, 0x20, 0x0d, 0x0c, 0x26, +0x2e, 0x34, 0x1a, 0x1c, 0x33, 0x27, 0x17, 0x15, 0x26, 0x32, +0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x00, 0x00, 0x01, 0x99, +0x02, 0x6b, 0x00, 0x0b, 0x00, 0x32, 0x40, 0x19, 0x06, 0x06, +0x02, 0x73, 0x0b, 0x0d, 0x08, 0x08, 0x04, 0x04, 0x01, 0x0c, +0x03, 0x79, 0x06, 0x06, 0x0a, 0x02, 0x79, 0x0b, 0x44, 0x07, +0x79, 0x0a, 0x41, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x11, 0x39, +0x2f, 0xed, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x32, 0x2f, 0x10, +0xde, 0xed, 0x32, 0x2f, 0x31, 0x30, 0x33, 0x35, 0x21, 0x35, +0x23, 0x35, 0x33, 0x35, 0x21, 0x35, 0x21, 0x11, 0x28, 0x01, +0x1f, 0xe8, 0xe8, 0xfe, 0xf8, 0x01, 0x5a, 0x46, 0xdb, 0x46, +0xbe, 0x46, 0xfd, 0x95, 0x00, 0x02, 0x00, 0x19, 0xff, 0xf3, +0x01, 0xd8, 0x02, 0x79, 0x00, 0x1d, 0x00, 0x26, 0x00, 0xa2, +0x40, 0x16, 0x23, 0x18, 0x11, 0x12, 0x00, 0x4c, 0x23, 0x28, +0x0d, 0x00, 0x4d, 0x23, 0x10, 0x0c, 0x00, 0x4d, 0x23, 0x08, +0x0b, 0x00, 0x4d, 0x20, 0xb8, 0xff, 0xe8, 0x40, 0x5c, 0x0d, +0x00, 0x4d, 0x18, 0x18, 0x0e, 0x00, 0x4d, 0x18, 0x10, 0x08, +0x00, 0x4d, 0x15, 0x18, 0x0d, 0x00, 0x4d, 0x14, 0x10, 0x0d, +0x00, 0x4d, 0x10, 0x20, 0x0d, 0x00, 0x4d, 0x0a, 0x18, 0x12, +0x00, 0x4d, 0x0a, 0x20, 0x11, 0x00, 0x4d, 0x0a, 0x18, 0x0f, +0x10, 0x00, 0x4c, 0x01, 0x18, 0x11, 0x12, 0x00, 0x4c, 0x01, +0x28, 0x10, 0x00, 0x4d, 0x01, 0x40, 0x0d, 0x00, 0x4d, 0x01, +0x20, 0x0b, 0x00, 0x4d, 0x26, 0x00, 0x76, 0x12, 0x28, 0x1e, +0x76, 0x1a, 0x08, 0x08, 0x1a, 0x27, 0x00, 0x79, 0x26, 0x26, +0x02, 0x21, 0x7c, 0x17, 0x46, 0x07, 0x07, 0x02, 0x7c, 0x0d, +0x45, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x12, 0x39, +0x2f, 0xed, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xed, 0x10, +0xde, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x01, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x07, 0x27, +0x3e, 0x03, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37, 0x17, 0x06, 0x16, +0x33, 0x32, 0x3e, 0x02, 0x37, 0x01, 0x84, 0x0c, 0xac, 0x13, +0x23, 0x1f, 0x18, 0x07, 0x15, 0x05, 0x1c, 0x28, 0x30, 0x19, +0x42, 0x61, 0x41, 0x1f, 0x24, 0x3f, 0x55, 0x31, 0x66, 0x70, +0x02, 0x01, 0x50, 0x01, 0x49, 0x3d, 0x22, 0x35, 0x24, 0x14, +0x02, 0x01, 0x4a, 0xe9, 0x08, 0x0c, 0x0c, 0x04, 0x41, 0x05, +0x0e, 0x0d, 0x09, 0x30, 0x56, 0x75, 0x45, 0x52, 0x7a, 0x51, +0x29, 0x9a, 0x9b, 0x08, 0x15, 0x05, 0x45, 0x64, 0x69, 0x25, +0x3b, 0x49, 0x24, 0x00, 0x00, 0x01, 0x00, 0x28, 0xff, 0xf4, +0x01, 0xd4, 0x02, 0x76, 0x00, 0x36, 0x00, 0xba, 0xb9, 0x00, +0x32, 0xff, 0xf0, 0xb4, 0x0e, 0x10, 0x00, 0x4c, 0x28, 0xb8, +0xff, 0xd0, 0xb3, 0x12, 0x00, 0x4d, 0x28, 0xb8, 0xff, 0xe8, +0x40, 0x38, 0x11, 0x00, 0x4d, 0x22, 0x18, 0x12, 0x00, 0x4d, +0x22, 0x10, 0x11, 0x00, 0x4d, 0x21, 0x20, 0x12, 0x00, 0x4d, +0x21, 0x18, 0x11, 0x00, 0x4d, 0x21, 0x20, 0x08, 0x0a, 0x00, +0x4c, 0x1d, 0x18, 0x11, 0x12, 0x00, 0x4c, 0x19, 0x20, 0x11, +0x00, 0x4d, 0x15, 0x40, 0x12, 0x00, 0x4d, 0x15, 0x28, 0x11, +0x00, 0x4d, 0x15, 0x18, 0x08, 0x00, 0x4d, 0x0f, 0xb8, 0xff, +0xe8, 0xb4, 0x0d, 0x0e, 0x00, 0x4c, 0x08, 0xb8, 0xff, 0xe8, +0xb3, 0x10, 0x00, 0x4d, 0x04, 0xb8, 0xff, 0xf0, 0x40, 0x25, +0x10, 0x00, 0x4d, 0x29, 0x29, 0x00, 0x00, 0x0d, 0x38, 0x1c, +0x30, 0x76, 0x1f, 0x1f, 0x06, 0x76, 0x17, 0x37, 0x1c, 0x00, +0x79, 0x36, 0x36, 0x09, 0x24, 0x2a, 0x2a, 0x2d, 0x7c, 0x24, +0x45, 0x0c, 0x0c, 0x09, 0x7c, 0x12, 0x46, 0x00, 0x3f, 0xed, +0x32, 0x2f, 0x3f, 0xed, 0x32, 0x2f, 0x11, 0x12, 0x39, 0x2f, +0xed, 0x39, 0x01, 0x10, 0xd6, 0xed, 0x33, 0x2f, 0xed, 0x32, +0x10, 0xce, 0x32, 0x2f, 0x32, 0x2f, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x23, 0x22, 0x0e, 0x02, 0x15, +0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x0e, 0x03, 0x23, +0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x37, 0x26, 0x26, +0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x17, 0x07, +0x26, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x1e, 0x02, 0x33, +0x33, 0x01, 0x6c, 0x2a, 0x29, 0x49, 0x36, 0x20, 0x57, 0x47, +0x39, 0x54, 0x16, 0x19, 0x0b, 0x24, 0x30, 0x3b, 0x22, 0x36, +0x59, 0x3f, 0x22, 0x16, 0x26, 0x32, 0x1b, 0x36, 0x37, 0x1e, +0x36, 0x4b, 0x2c, 0x1c, 0x35, 0x2e, 0x24, 0x0c, 0x1b, 0x14, +0x50, 0x30, 0x36, 0x43, 0x22, 0x35, 0x40, 0x1e, 0x21, 0x01, +0x24, 0x0a, 0x1a, 0x2f, 0x24, 0x3e, 0x35, 0x1d, 0x0b, 0x42, +0x05, 0x0f, 0x0e, 0x0a, 0x14, 0x2c, 0x45, 0x32, 0x24, 0x36, +0x28, 0x1a, 0x07, 0x11, 0x4c, 0x2b, 0x29, 0x3d, 0x27, 0x13, +0x06, 0x0a, 0x0e, 0x07, 0x41, 0x0b, 0x15, 0x33, 0x29, 0x20, +0x29, 0x18, 0x09, 0x00, 0x00, 0x01, 0x00, 0x03, 0xff, 0x59, +0x01, 0xc3, 0x02, 0x6b, 0x00, 0x17, 0x00, 0x2d, 0x40, 0x16, +0x15, 0x15, 0x12, 0x19, 0x14, 0x00, 0x73, 0x08, 0x0f, 0x18, +0x17, 0x79, 0x14, 0x14, 0x18, 0x13, 0x79, 0x10, 0x41, 0x0c, +0x7c, 0x05, 0x00, 0x2f, 0xed, 0x3f, 0xed, 0x12, 0x39, 0x2f, +0xed, 0x01, 0x10, 0xd6, 0xcc, 0xed, 0x32, 0x10, 0xce, 0x32, +0x2f, 0x31, 0x30, 0x33, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, +0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, 0x21, +0x15, 0x21, 0x15, 0x33, 0x15, 0x23, 0xb6, 0x0b, 0x1d, 0x31, +0x27, 0x0d, 0x1c, 0x0a, 0x08, 0x09, 0x11, 0x08, 0x20, 0x17, +0x01, 0x5f, 0xfe, 0xf3, 0xed, 0xed, 0x27, 0x3e, 0x2b, 0x17, +0x03, 0x02, 0x42, 0x02, 0x01, 0x2b, 0x29, 0x02, 0x7a, 0x46, +0xc1, 0x45, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2e, 0xff, 0xf3, +0x01, 0xeb, 0x02, 0xbe, 0x00, 0x2f, 0x00, 0xa6, 0xb5, 0x1c, +0x10, 0x08, 0x00, 0x4d, 0x1b, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, +0x00, 0x4d, 0x1b, 0xb8, 0xff, 0xf8, 0xb3, 0x0d, 0x00, 0x4d, +0x18, 0xb8, 0xff, 0xe8, 0xb3, 0x0d, 0x00, 0x4d, 0x17, 0xb8, +0xff, 0xd0, 0xb3, 0x0e, 0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xe8, +0xb4, 0x11, 0x12, 0x00, 0x4c, 0x0b, 0xb8, 0xff, 0xd8, 0xb3, +0x0e, 0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xe0, 0xb3, 0x0d, 0x00, +0x4d, 0x05, 0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, 0x05, +0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x05, 0xb8, 0xff, +0xd8, 0xb3, 0x0e, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe0, 0x40, +0x21, 0x0d, 0x00, 0x4d, 0x27, 0x21, 0x00, 0x00, 0x11, 0x73, +0x12, 0x31, 0x08, 0x76, 0x19, 0x30, 0x2b, 0x24, 0x1e, 0x11, +0x11, 0x0d, 0x00, 0x03, 0x7c, 0x21, 0x1e, 0x45, 0x10, 0x0d, +0x7c, 0x13, 0x16, 0x46, 0x00, 0x3f, 0x33, 0xed, 0x32, 0x3f, +0x33, 0xed, 0x32, 0x12, 0x39, 0x2f, 0x10, 0xdc, 0xcd, 0x01, +0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, 0x33, 0x2f, 0x33, 0xcc, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x26, 0x26, 0x23, 0x22, 0x0e, +0x02, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x36, 0x37, 0x35, +0x33, 0x11, 0x06, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x3e, +0x02, 0x33, 0x32, 0x16, 0x17, 0x36, 0x36, 0x33, 0x32, 0x16, +0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x01, 0x84, +0x1a, 0x30, 0x16, 0x29, 0x3c, 0x29, 0x14, 0x14, 0x2a, 0x42, +0x2e, 0x1d, 0x20, 0x08, 0x52, 0x13, 0x54, 0x39, 0x78, 0x81, +0x29, 0x43, 0x56, 0x2c, 0x10, 0x1f, 0x0e, 0x0d, 0x2e, 0x2a, +0x0a, 0x1b, 0x08, 0x0d, 0x05, 0x12, 0x05, 0x0f, 0x13, 0x0e, +0x0a, 0x02, 0x12, 0x10, 0x0e, 0x29, 0x45, 0x5b, 0x31, 0x38, +0x5c, 0x42, 0x25, 0x08, 0x04, 0xea, 0xfe, 0xde, 0x07, 0x15, +0xa8, 0x9b, 0x51, 0x79, 0x51, 0x28, 0x05, 0x06, 0x31, 0x1f, +0x06, 0x05, 0x3d, 0x03, 0x04, 0x13, 0x1f, 0x26, 0x00, 0x02, +0x00, 0x0d, 0xff, 0x5c, 0x01, 0xe8, 0x02, 0x6b, 0x00, 0x25, +0x00, 0x33, 0x01, 0x35, 0x40, 0x10, 0x33, 0x10, 0x11, 0x00, +0x4d, 0x22, 0x18, 0x12, 0x00, 0x4d, 0x22, 0x18, 0x0e, 0x00, +0x4d, 0x1e, 0xb8, 0xff, 0xe8, 0x40, 0x2d, 0x0e, 0x00, 0x4d, +0x16, 0x20, 0x12, 0x00, 0x4d, 0x16, 0x30, 0x11, 0x00, 0x4d, +0x11, 0x20, 0x0b, 0x00, 0x4d, 0x11, 0x28, 0x0a, 0x00, 0x4d, +0x10, 0x18, 0x10, 0x00, 0x4d, 0x10, 0x10, 0x0f, 0x00, 0x4d, +0x10, 0x18, 0x0d, 0x0e, 0x00, 0x4c, 0x10, 0x20, 0x0c, 0x00, +0x4d, 0x0c, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x0c, +0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x0c, 0xb8, 0xff, +0xe8, 0xb4, 0x0d, 0x0e, 0x00, 0x4c, 0x0c, 0xb8, 0xff, 0xe0, +0xb3, 0x0c, 0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xe0, 0xb3, 0x0b, +0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xd8, 0xb3, 0x0a, 0x00, 0x4d, +0x06, 0xb8, 0xff, 0xd8, 0x40, 0x0a, 0x11, 0x12, 0x00, 0x4c, +0x03, 0x08, 0x0e, 0x00, 0x4d, 0x20, 0xb8, 0xff, 0xe8, 0x40, +0x22, 0x0f, 0x00, 0x4d, 0x30, 0x40, 0x1f, 0x00, 0x4d, 0x30, +0x76, 0x09, 0x17, 0x1b, 0x20, 0x1b, 0x78, 0x1a, 0x17, 0x14, +0x1a, 0x1a, 0x17, 0x05, 0x25, 0x20, 0x25, 0x78, 0x00, 0x05, +0x14, 0x00, 0x00, 0x05, 0x2a, 0xb8, 0xff, 0xc0, 0x40, 0x37, +0x1f, 0x00, 0x4d, 0x2a, 0x76, 0x13, 0x26, 0x20, 0x13, 0x0f, +0x09, 0x01, 0x09, 0x13, 0x20, 0x13, 0x20, 0x09, 0x03, 0x1a, +0x20, 0x00, 0x30, 0x00, 0x02, 0x00, 0x35, 0x3f, 0x1a, 0x6f, +0x1a, 0x7f, 0x1a, 0x03, 0x6f, 0x1a, 0x7f, 0x1a, 0x02, 0x1a, +0x34, 0x00, 0x25, 0x41, 0x26, 0x20, 0x05, 0x17, 0x17, 0x1b, +0x1a, 0x41, 0x2d, 0x79, 0x0e, 0x00, 0x2f, 0xed, 0x3f, 0x33, +0x39, 0x11, 0x33, 0x33, 0x33, 0x3f, 0x33, 0x01, 0x10, 0xc6, +0x5d, 0x71, 0x10, 0xc6, 0x5d, 0x11, 0x17, 0x39, 0x19, 0x2f, +0x18, 0x2f, 0x2f, 0x5d, 0x11, 0x12, 0x39, 0x10, 0xed, 0x2b, +0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x87, 0x18, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x01, 0x18, 0x10, 0xed, 0x2b, 0x31, 0x30, +0x00, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x01, 0x0e, 0x03, 0x07, 0x17, 0x16, 0x16, +0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, +0x36, 0x37, 0x37, 0x26, 0x26, 0x27, 0x33, 0x1e, 0x03, 0x17, +0x3e, 0x03, 0x37, 0x03, 0x07, 0x06, 0x06, 0x15, 0x14, 0x16, +0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x27, 0x01, 0xe8, 0x0c, +0x2a, 0x33, 0x3b, 0x1e, 0x37, 0x0b, 0x10, 0x0c, 0x1d, 0x30, +0x25, 0x25, 0x30, 0x1d, 0x0c, 0x0d, 0x0e, 0x38, 0x37, 0x61, +0x2a, 0x56, 0x10, 0x20, 0x24, 0x2a, 0x1b, 0x15, 0x2e, 0x2a, +0x21, 0x09, 0x9a, 0x22, 0x08, 0x0a, 0x1b, 0x1a, 0x1a, 0x1b, +0x0a, 0x08, 0x02, 0x6b, 0x1f, 0x68, 0x7e, 0x8a, 0x42, 0x6c, +0x16, 0x30, 0x11, 0x14, 0x2b, 0x24, 0x18, 0x18, 0x24, 0x2b, +0x14, 0x11, 0x2a, 0x1c, 0x6d, 0x72, 0xed, 0x71, 0x2d, 0x55, +0x5d, 0x6b, 0x42, 0x36, 0x78, 0x6d, 0x59, 0x18, 0xfd, 0xea, +0x40, 0x10, 0x1c, 0x0e, 0x18, 0x23, 0x23, 0x18, 0x0e, 0x1d, +0x0f, 0x00, 0x00, 0x01, 0x00, 0x24, 0xff, 0xf6, 0x01, 0xce, +0x02, 0xb5, 0x00, 0x2d, 0x00, 0x94, 0xb9, 0x00, 0x2b, 0xff, +0xe8, 0xb4, 0x0c, 0x10, 0x00, 0x4c, 0x2b, 0xb8, 0xff, 0xe0, +0x40, 0x19, 0x0b, 0x00, 0x4d, 0x15, 0x30, 0x0b, 0x00, 0x4d, +0x15, 0x20, 0x09, 0x0a, 0x00, 0x4c, 0x14, 0x20, 0x0e, 0x00, +0x4d, 0x14, 0x18, 0x0c, 0x00, 0x4d, 0x10, 0xb8, 0xff, 0xe0, +0xb3, 0x0e, 0x00, 0x4d, 0x10, 0xb8, 0xff, 0xe8, 0xb3, 0x0c, +0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xd0, 0xb3, 0x0b, 0x00, 0x4d, +0x0f, 0xb8, 0xff, 0xe0, 0xb3, 0x0a, 0x00, 0x4d, 0x0f, 0xb8, +0xff, 0xd8, 0x40, 0x22, 0x09, 0x00, 0x4d, 0x00, 0x7f, 0x17, +0x17, 0x22, 0x0a, 0x7f, 0x0d, 0x2f, 0x24, 0x21, 0x7f, 0x22, +0x2e, 0x20, 0x1d, 0x88, 0x25, 0x28, 0x50, 0x23, 0x24, 0x4d, +0x22, 0x4a, 0x05, 0x88, 0x12, 0x51, 0x0b, 0x49, 0x00, 0x3f, +0x3f, 0xed, 0x3f, 0x3f, 0x33, 0x3f, 0x33, 0xed, 0x32, 0x01, +0x10, 0xd6, 0xed, 0x32, 0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x14, 0x1e, 0x02, 0x33, 0x32, +0x3e, 0x02, 0x35, 0x11, 0x33, 0x11, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x2e, 0x02, 0x35, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, +0x06, 0x07, 0x11, 0x23, 0x11, 0x37, 0x15, 0x36, 0x36, 0x33, +0x32, 0x1e, 0x02, 0x15, 0x01, 0x1b, 0x07, 0x0d, 0x13, 0x0c, +0x0c, 0x12, 0x0d, 0x06, 0x4f, 0x0b, 0x1d, 0x32, 0x28, 0x28, +0x32, 0x1c, 0x0a, 0x09, 0x0d, 0x11, 0x08, 0x0b, 0x18, 0x08, +0x4e, 0x4e, 0x0b, 0x21, 0x0f, 0x14, 0x27, 0x20, 0x13, 0xbb, +0x27, 0x30, 0x1a, 0x09, 0x08, 0x1a, 0x30, 0x27, 0x01, 0x16, +0xfe, 0xde, 0x27, 0x44, 0x31, 0x1c, 0x1c, 0x32, 0x44, 0x27, +0x8a, 0x1c, 0x23, 0x13, 0x06, 0x0a, 0x05, 0xfe, 0x7e, 0x02, +0xa7, 0x0e, 0xee, 0x09, 0x0a, 0x0e, 0x22, 0x39, 0x2b, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0xff, 0xf3, 0x01, 0xc8, +0x02, 0x6b, 0x00, 0x15, 0x00, 0x45, 0x40, 0x29, 0x13, 0x18, +0x0c, 0x00, 0x4d, 0x13, 0x10, 0x0b, 0x00, 0x4d, 0x13, 0x20, +0x0a, 0x00, 0x4d, 0x05, 0x73, 0x00, 0x00, 0x01, 0x0d, 0x0d, +0x04, 0x17, 0x00, 0x01, 0x01, 0x08, 0x01, 0x16, 0x0c, 0x0c, +0x09, 0x7c, 0x10, 0x46, 0x05, 0x00, 0x79, 0x02, 0x41, 0x00, +0x3f, 0xed, 0x32, 0x3f, 0xed, 0x32, 0x2f, 0x01, 0x10, 0xc6, +0x5e, 0x5d, 0x10, 0xce, 0x32, 0x2f, 0x11, 0x39, 0x2f, 0xed, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x13, 0x23, 0x35, 0x21, 0x15, +0x23, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, +0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0xbc, 0x78, 0x01, 0x53, +0x89, 0x2b, 0x31, 0x1a, 0x29, 0x0b, 0x10, 0x0c, 0x3f, 0x20, +0x2e, 0x3e, 0x25, 0x10, 0x02, 0x25, 0x46, 0x46, 0xfe, 0x80, +0x3d, 0x2c, 0x0e, 0x06, 0x45, 0x09, 0x0f, 0x15, 0x2c, 0x45, +0x30, 0x00, 0x00, 0x01, 0x00, 0x59, 0x00, 0x00, 0x01, 0x9b, +0x02, 0x6b, 0x00, 0x13, 0x00, 0x4a, 0x40, 0x26, 0x10, 0x10, +0x09, 0x0a, 0x13, 0x13, 0x06, 0x03, 0x01, 0x05, 0x73, 0x0e, +0x0c, 0x00, 0x0a, 0x01, 0x08, 0x0a, 0x0a, 0x15, 0x14, 0x00, +0x0f, 0x79, 0x11, 0x04, 0x0b, 0x79, 0x01, 0x0e, 0x0e, 0x11, +0x41, 0x05, 0x0a, 0x79, 0x08, 0x44, 0x00, 0x3f, 0xed, 0x32, +0x3f, 0x39, 0x2f, 0x33, 0xed, 0x32, 0x10, 0xed, 0x32, 0x01, +0x11, 0x12, 0x39, 0x2f, 0x5e, 0x5d, 0xce, 0x33, 0xfd, 0x32, +0xce, 0xcd, 0x32, 0x2f, 0x10, 0xcd, 0x32, 0x2f, 0x31, 0x30, +0x01, 0x15, 0x33, 0x15, 0x23, 0x15, 0x33, 0x15, 0x21, 0x35, +0x33, 0x35, 0x23, 0x35, 0x33, 0x35, 0x23, 0x35, 0x21, 0x15, +0x01, 0x23, 0x5b, 0x5b, 0x78, 0xfe, 0xbe, 0x78, 0x5c, 0x5c, +0x78, 0x01, 0x42, 0x02, 0x25, 0xc2, 0x41, 0xdc, 0x46, 0x46, +0xdc, 0x41, 0xc2, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x40, 0x00, 0x00, 0x01, 0xfb, 0x02, 0x77, 0x00, 0x1d, +0x00, 0x6e, 0x40, 0x3e, 0x0d, 0x0d, 0x12, 0x00, 0x1d, 0x00, +0x78, 0x0b, 0x0d, 0x14, 0x0b, 0x0b, 0x0d, 0x13, 0x0d, 0x12, +0x0d, 0x78, 0x18, 0x13, 0x14, 0x18, 0x18, 0x13, 0x2f, 0x0b, +0x01, 0x0b, 0x05, 0x05, 0x12, 0x1f, 0x18, 0x1d, 0x19, 0x73, +0x00, 0x1a, 0x10, 0x1a, 0x02, 0x08, 0x1a, 0x1e, 0x1d, 0x18, +0x0d, 0x0d, 0x1a, 0x1b, 0x41, 0x1a, 0x44, 0x12, 0x13, 0x44, +0x0b, 0x00, 0x09, 0x7c, 0x02, 0x45, 0x00, 0x3f, 0xed, 0x32, +0x32, 0x3f, 0x33, 0x3f, 0x3f, 0x12, 0x39, 0x19, 0x2f, 0x33, +0x33, 0x01, 0x18, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x32, +0x10, 0xce, 0x32, 0x2f, 0x33, 0x5d, 0x87, 0x10, 0x2b, 0x87, +0x7d, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x08, 0x7d, 0xc4, +0x31, 0x30, 0x01, 0x36, 0x33, 0x32, 0x16, 0x17, 0x07, 0x26, +0x26, 0x23, 0x22, 0x06, 0x07, 0x07, 0x1e, 0x03, 0x17, 0x23, +0x2e, 0x03, 0x27, 0x11, 0x23, 0x11, 0x33, 0x11, 0x01, 0x30, +0x35, 0x3a, 0x17, 0x31, 0x14, 0x24, 0x0e, 0x1a, 0x0a, 0x13, +0x23, 0x1d, 0x69, 0x20, 0x49, 0x46, 0x3e, 0x15, 0x5d, 0x19, +0x3a, 0x41, 0x45, 0x23, 0x52, 0x52, 0x02, 0x2d, 0x4a, 0x15, +0x16, 0x39, 0x0e, 0x0d, 0x2b, 0x28, 0x8e, 0x1a, 0x49, 0x57, +0x61, 0x32, 0x2e, 0x58, 0x4c, 0x3f, 0x17, 0xfe, 0xd8, 0x02, +0x6b, 0xfe, 0xec, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x47, +0x00, 0x00, 0x01, 0xde, 0x02, 0xb5, 0x00, 0x24, 0x00, 0x5e, +0x40, 0x34, 0x00, 0x00, 0x05, 0x21, 0x1e, 0x21, 0x81, 0x22, +0x00, 0x14, 0x22, 0x22, 0x00, 0x06, 0x00, 0x05, 0x00, 0x81, +0x0b, 0x06, 0x14, 0x0b, 0x06, 0x00, 0x0b, 0x22, 0x22, 0x05, +0x26, 0x1e, 0x16, 0x16, 0x0b, 0x7f, 0x00, 0x0d, 0x01, 0x08, +0x0d, 0x25, 0x21, 0x22, 0x49, 0x1a, 0x89, 0x13, 0x4d, 0x0d, +0x4a, 0x06, 0x05, 0x4a, 0x00, 0x3f, 0x33, 0x3f, 0x3f, 0xed, +0x3f, 0x33, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x2f, +0x32, 0x10, 0xce, 0x32, 0x2f, 0x10, 0x00, 0xc1, 0x87, 0x05, +0x2b, 0x87, 0x7d, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x08, +0x7d, 0xc4, 0x31, 0x30, 0x37, 0x1e, 0x03, 0x17, 0x23, 0x2e, +0x03, 0x27, 0x15, 0x23, 0x11, 0x34, 0x3e, 0x02, 0x33, 0x32, +0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, +0x36, 0x36, 0x37, 0x33, 0x06, 0x06, 0xee, 0x1b, 0x44, 0x43, +0x3c, 0x12, 0x62, 0x13, 0x38, 0x3f, 0x3f, 0x19, 0x53, 0x0b, +0x1e, 0x33, 0x29, 0x0d, 0x20, 0x0a, 0x08, 0x08, 0x17, 0x07, +0x21, 0x1a, 0x37, 0x6e, 0x2c, 0x61, 0x2b, 0x79, 0xff, 0x14, +0x3d, 0x46, 0x49, 0x1f, 0x1f, 0x41, 0x3c, 0x32, 0x11, 0xdf, +0x02, 0x0e, 0x29, 0x3f, 0x2a, 0x15, 0x05, 0x02, 0x41, 0x02, +0x02, 0x2b, 0x29, 0xfe, 0xf1, 0x30, 0x5f, 0x33, 0x33, 0x6c, +0x00, 0x01, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0xb0, +0x00, 0x1f, 0x00, 0x42, 0x40, 0x22, 0x1b, 0x1b, 0x10, 0x0e, +0x11, 0x7f, 0x0b, 0x09, 0x07, 0x00, 0x06, 0x01, 0x08, 0x06, +0x06, 0x21, 0x20, 0x11, 0x06, 0x86, 0x0e, 0x09, 0x09, 0x17, +0x0a, 0x85, 0x0d, 0x4d, 0x1a, 0x1a, 0x17, 0x88, 0x00, 0x51, +0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x12, 0x39, 0x2f, +0x33, 0xed, 0x32, 0x01, 0x11, 0x12, 0x39, 0x2f, 0x5e, 0x5d, +0xcd, 0x33, 0xcc, 0xfd, 0x32, 0xcd, 0x32, 0x2f, 0x31, 0x30, +0x05, 0x22, 0x2e, 0x02, 0x35, 0x35, 0x23, 0x35, 0x33, 0x35, +0x23, 0x35, 0x33, 0x11, 0x33, 0x15, 0x23, 0x15, 0x14, 0x1e, +0x02, 0x33, 0x32, 0x36, 0x37, 0x17, 0x0e, 0x03, 0x01, 0x52, +0x2c, 0x3a, 0x22, 0x0e, 0x86, 0x86, 0x86, 0xd8, 0x84, 0x84, +0x09, 0x13, 0x1c, 0x13, 0x1d, 0x32, 0x0e, 0x0c, 0x06, 0x16, +0x1e, 0x23, 0x0b, 0x18, 0x30, 0x47, 0x2f, 0x95, 0x3e, 0xe4, +0x46, 0xfe, 0xd6, 0x3e, 0x95, 0x23, 0x2c, 0x1b, 0x0a, 0x0e, +0x08, 0x46, 0x03, 0x09, 0x08, 0x06, 0x00, 0x01, 0x00, 0x1d, +0x00, 0x00, 0x01, 0xd4, 0x02, 0xb5, 0x00, 0x27, 0x00, 0xa3, +0x40, 0x61, 0x1e, 0x28, 0x13, 0x00, 0x4d, 0x95, 0x1d, 0x01, +0x86, 0x1d, 0x01, 0x13, 0x28, 0x13, 0x00, 0x4d, 0x13, 0x30, +0x12, 0x00, 0x4d, 0x7c, 0x13, 0x01, 0x6c, 0x12, 0x01, 0x21, +0x21, 0x03, 0x0e, 0x08, 0x03, 0x08, 0x81, 0x09, 0x0e, 0x14, +0x09, 0x09, 0x0e, 0x23, 0x00, 0x03, 0x00, 0x81, 0x27, 0x23, +0x14, 0x27, 0x27, 0x23, 0x11, 0x11, 0x03, 0x03, 0x09, 0x27, +0x29, 0x19, 0x19, 0x09, 0x28, 0x22, 0x0f, 0x10, 0x21, 0x1f, +0x12, 0x20, 0x20, 0x0e, 0x11, 0x10, 0x10, 0x20, 0x10, 0x30, +0x10, 0x03, 0x10, 0x10, 0x23, 0x03, 0x0e, 0x0e, 0x09, 0x15, +0x89, 0x1c, 0x4d, 0x08, 0x09, 0x4a, 0x27, 0x00, 0x4a, 0x00, +0x3f, 0x32, 0x3f, 0x33, 0x3f, 0xed, 0x12, 0x39, 0x11, 0x33, +0x33, 0x33, 0x2f, 0x5d, 0xcd, 0x11, 0x33, 0x2f, 0x39, 0x39, +0xcd, 0x11, 0x39, 0x39, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, +0xce, 0x11, 0x39, 0x11, 0x33, 0x2f, 0x87, 0x10, 0x2b, 0x87, +0x7d, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, +0x11, 0x33, 0x18, 0x2f, 0x31, 0x30, 0x5d, 0x5d, 0x2b, 0x2b, +0x5d, 0x5d, 0x2b, 0x21, 0x26, 0x26, 0x27, 0x0e, 0x03, 0x07, +0x23, 0x3e, 0x03, 0x37, 0x27, 0x07, 0x27, 0x37, 0x26, 0x26, +0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, 0x16, +0x17, 0x37, 0x17, 0x07, 0x1e, 0x03, 0x17, 0x01, 0x77, 0x16, +0x3c, 0x23, 0x1a, 0x2d, 0x26, 0x1d, 0x09, 0x52, 0x0d, 0x29, +0x33, 0x39, 0x1e, 0x13, 0x5e, 0x14, 0x59, 0x0e, 0x21, 0x19, +0x0d, 0x11, 0x05, 0x0c, 0x05, 0x20, 0x16, 0x34, 0x3e, 0x15, +0x6f, 0x15, 0x6c, 0x1f, 0x38, 0x31, 0x29, 0x0f, 0x5b, 0xc6, +0x5b, 0x2f, 0x67, 0x65, 0x5d, 0x24, 0x32, 0x76, 0x7c, 0x7c, +0x37, 0x2e, 0x20, 0x38, 0x1f, 0x1a, 0x1b, 0x03, 0x02, 0x42, +0x02, 0x05, 0x34, 0x2b, 0x26, 0x38, 0x25, 0x49, 0x92, 0x8b, +0x81, 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2d, 0xff, 0xf3, +0x01, 0xc7, 0x02, 0x6b, 0x00, 0x25, 0x00, 0x48, 0x40, 0x29, +0x0b, 0x18, 0x0c, 0x00, 0x4d, 0x0b, 0x10, 0x0b, 0x00, 0x4d, +0x1b, 0x73, 0x16, 0x05, 0x18, 0x18, 0x0d, 0x23, 0x73, 0x00, +0x27, 0x10, 0x73, 0x0d, 0x26, 0x24, 0x0e, 0x19, 0x19, 0x0e, +0x41, 0x16, 0x13, 0x7c, 0x05, 0x08, 0x46, 0x20, 0x7c, 0x02, +0x46, 0x00, 0x3f, 0xed, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0x33, +0x2f, 0x11, 0x33, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, +0x11, 0x39, 0x2f, 0x33, 0x33, 0xed, 0x31, 0x30, 0x2b, 0x2b, +0x25, 0x06, 0x23, 0x22, 0x26, 0x27, 0x06, 0x06, 0x23, 0x22, +0x2e, 0x02, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, +0x36, 0x37, 0x26, 0x35, 0x35, 0x33, 0x15, 0x14, 0x1e, 0x02, +0x33, 0x32, 0x36, 0x37, 0x11, 0x33, 0x01, 0xc7, 0x36, 0x2d, +0x19, 0x29, 0x11, 0x14, 0x25, 0x1d, 0x1b, 0x34, 0x27, 0x18, +0x4b, 0x1e, 0x24, 0x0e, 0x14, 0x0a, 0x11, 0x4b, 0x04, 0x0d, +0x19, 0x15, 0x05, 0x11, 0x07, 0x4b, 0x0b, 0x18, 0x0e, 0x0c, +0x0e, 0x0c, 0x11, 0x2a, 0x48, 0x38, 0x01, 0xbd, 0xfe, 0x49, +0x3b, 0x41, 0x07, 0x08, 0x2b, 0x3c, 0xd2, 0xcc, 0x15, 0x2c, +0x24, 0x17, 0x02, 0x02, 0x02, 0x2f, 0x00, 0x00, 0x00, 0x01, +0xff, 0xcf, 0xff, 0x59, 0x01, 0xbd, 0x02, 0x6b, 0x00, 0x1f, +0x00, 0x4c, 0x40, 0x2e, 0x09, 0x0a, 0x19, 0x0a, 0x02, 0x15, +0x01, 0x01, 0x06, 0x01, 0x01, 0x01, 0x0a, 0x0f, 0x0a, 0x7e, +0x06, 0x01, 0x14, 0x06, 0x01, 0x06, 0x73, 0x09, 0x21, 0x0f, +0x73, 0x18, 0x00, 0x1f, 0x10, 0x1f, 0x02, 0x1f, 0x20, 0x1c, +0x7c, 0x15, 0x06, 0x0a, 0x44, 0x07, 0x41, 0x0f, 0x01, 0x41, +0x00, 0x3f, 0x33, 0x3f, 0x3f, 0x33, 0x2f, 0xed, 0x01, 0x10, +0xd6, 0x5d, 0xcc, 0xed, 0x10, 0xde, 0xfd, 0x87, 0x2b, 0x87, +0x7d, 0xc4, 0x01, 0x5d, 0x5d, 0x5d, 0x31, 0x30, 0x13, 0x33, +0x1e, 0x03, 0x17, 0x11, 0x33, 0x11, 0x23, 0x2e, 0x03, 0x27, +0x11, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, +0x16, 0x33, 0x32, 0x36, 0x35, 0x37, 0x54, 0x1f, 0x41, 0x3c, +0x36, 0x15, 0x4b, 0x4b, 0x0f, 0x35, 0x42, 0x48, 0x22, 0x0b, +0x1d, 0x31, 0x27, 0x0d, 0x1c, 0x0a, 0x0f, 0x0a, 0x10, 0x08, +0x21, 0x16, 0x02, 0x6b, 0x39, 0x75, 0x73, 0x6f, 0x31, 0x01, +0xc1, 0xfd, 0x95, 0x2e, 0x78, 0x82, 0x87, 0x3f, 0xfe, 0x12, +0x27, 0x3e, 0x2b, 0x17, 0x03, 0x02, 0x42, 0x02, 0x01, 0x2b, +0x29, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x47, 0xff, 0x5b, +0x01, 0xb0, 0x01, 0xda, 0x00, 0x13, 0x00, 0x52, 0xb6, 0x0c, +0x10, 0x0f, 0x10, 0x00, 0x4c, 0x05, 0xb8, 0xff, 0xe0, 0xb3, +0x12, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, +0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb4, 0x08, 0x0a, 0x00, 0x4c, +0x04, 0xb8, 0xff, 0xe0, 0x40, 0x17, 0x11, 0x00, 0x4d, 0x08, +0x7f, 0x07, 0x15, 0x12, 0x7f, 0x00, 0x13, 0x01, 0x08, 0x13, +0x14, 0x13, 0x4a, 0x08, 0x4b, 0x0e, 0x88, 0x03, 0x50, 0x00, +0x3f, 0xed, 0x3f, 0x3f, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, +0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x13, 0x36, 0x36, 0x33, 0x32, 0x16, 0x15, 0x11, 0x23, 0x11, +0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0x11, 0x23, 0x47, +0x2d, 0x59, 0x27, 0x5d, 0x5f, 0x52, 0x10, 0x1d, 0x29, 0x18, +0x14, 0x2d, 0x15, 0x53, 0x01, 0xc3, 0x0b, 0x0c, 0x60, 0x6a, +0xfe, 0x4b, 0x01, 0xaa, 0x2d, 0x38, 0x1f, 0x0c, 0x05, 0x04, +0xfe, 0x74, 0x00, 0x03, 0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, +0x02, 0x79, 0x00, 0x13, 0x00, 0x1a, 0x00, 0x21, 0x00, 0xcd, +0xb6, 0x21, 0x18, 0x0d, 0x0e, 0x00, 0x4c, 0x1c, 0xb8, 0xff, +0xf0, 0xb3, 0x0e, 0x00, 0x4d, 0x1c, 0xb8, 0xff, 0xe0, 0xb3, +0x0d, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, +0x4d, 0x1a, 0xb8, 0xff, 0xe0, 0x40, 0x19, 0x0d, 0x00, 0x4d, +0x15, 0x18, 0x0e, 0x00, 0x4d, 0x15, 0x20, 0x0d, 0x00, 0x4d, +0x11, 0x18, 0x0f, 0x10, 0x00, 0x4c, 0x11, 0x10, 0x08, 0x00, +0x4d, 0x0d, 0xb8, 0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x0d, +0xb8, 0xff, 0xe8, 0xb3, 0x0f, 0x00, 0x4d, 0x0d, 0xb8, 0xff, +0xe8, 0x40, 0x0e, 0x08, 0x00, 0x4d, 0x0c, 0x10, 0x0d, 0x00, +0x4d, 0x08, 0x10, 0x0d, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xe8, +0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x07, 0xb8, 0xff, 0xf0, 0x40, +0x35, 0x08, 0x00, 0x4d, 0x03, 0x20, 0x10, 0x00, 0x4d, 0x03, +0x18, 0x0f, 0x00, 0x4d, 0x03, 0x10, 0x08, 0x00, 0x4d, 0x1f, +0x17, 0x76, 0x0a, 0x23, 0x1e, 0x18, 0x76, 0x00, 0x40, 0x0b, +0x10, 0x48, 0x00, 0x22, 0x18, 0x79, 0x0f, 0x1e, 0x1f, 0x1e, +0x4f, 0x1e, 0x03, 0x1e, 0x1e, 0x05, 0x14, 0x7c, 0x0f, 0x46, +0x1b, 0x7c, 0x05, 0x45, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x11, +0x39, 0x2f, 0x5d, 0xed, 0x01, 0x10, 0xd6, 0x2b, 0xed, 0x32, +0x10, 0xde, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x34, 0x3e, 0x02, 0x33, +0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, +0x02, 0x17, 0x32, 0x36, 0x37, 0x21, 0x16, 0x16, 0x13, 0x22, +0x06, 0x07, 0x21, 0x26, 0x26, 0x1d, 0x20, 0x3a, 0x51, 0x32, +0x31, 0x52, 0x3a, 0x21, 0x21, 0x3a, 0x52, 0x31, 0x32, 0x51, +0x3a, 0x20, 0xdb, 0x42, 0x44, 0x05, 0xfe, 0xee, 0x05, 0x41, +0x41, 0x40, 0x42, 0x05, 0x01, 0x12, 0x05, 0x45, 0x01, 0x36, +0x53, 0x7a, 0x4f, 0x27, 0x27, 0x4f, 0x7a, 0x53, 0x53, 0x7a, +0x50, 0x26, 0x26, 0x50, 0x7a, 0xa9, 0x72, 0x6c, 0x6c, 0x72, +0x01, 0xf8, 0x70, 0x6a, 0x6a, 0x70, 0x00, 0x00, 0x00, 0x02, +0x00, 0x1d, 0xff, 0xf3, 0x01, 0xee, 0x02, 0xcb, 0x00, 0x20, +0x00, 0x2c, 0x00, 0xc8, 0xb9, 0x00, 0x2b, 0xff, 0xf0, 0x40, +0x15, 0x0d, 0x0e, 0x00, 0x4c, 0x29, 0x10, 0x0e, 0x00, 0x4d, +0x29, 0x18, 0x0d, 0x00, 0x4d, 0x25, 0x10, 0x0d, 0x0e, 0x00, +0x4c, 0x23, 0xb8, 0xff, 0xf0, 0xb3, 0x0e, 0x00, 0x4d, 0x23, +0xb8, 0xff, 0xe8, 0x40, 0x13, 0x0d, 0x00, 0x4d, 0x1e, 0x28, +0x10, 0x00, 0x4d, 0x1e, 0x18, 0x0f, 0x00, 0x4d, 0x1e, 0x10, +0x08, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, +0x4d, 0x1a, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x1a, +0xb8, 0xff, 0xe8, 0xb3, 0x08, 0x00, 0x4d, 0x13, 0xb8, 0xff, +0xf0, 0xb3, 0x10, 0x00, 0x4d, 0x13, 0xb8, 0xff, 0xe8, 0xb3, +0x0f, 0x00, 0x4d, 0x12, 0xb8, 0xff, 0xf0, 0x40, 0x35, 0x10, +0x00, 0x4d, 0x08, 0x18, 0x12, 0x00, 0x4d, 0x08, 0x10, 0x11, +0x00, 0x4d, 0x03, 0x10, 0x0f, 0x10, 0x00, 0x4c, 0x03, 0x10, +0x08, 0x00, 0x4d, 0x0a, 0x11, 0x27, 0x76, 0x14, 0x07, 0x17, +0x2e, 0x21, 0x76, 0x00, 0x40, 0x0b, 0x10, 0x48, 0x00, 0x2d, +0x24, 0x7c, 0x1c, 0x46, 0x14, 0x07, 0x07, 0x2a, 0x7c, 0x0d, +0x05, 0x45, 0x00, 0x3f, 0xce, 0xed, 0x33, 0x11, 0x33, 0x3f, +0xed, 0x01, 0x10, 0xd6, 0x2b, 0xed, 0x10, 0xde, 0x32, 0x32, +0xed, 0xdc, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x34, 0x3e, 0x02, 0x33, 0x32, +0x17, 0x36, 0x36, 0x35, 0x34, 0x26, 0x27, 0x33, 0x16, 0x14, +0x15, 0x14, 0x06, 0x07, 0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x2e, 0x02, 0x37, 0x14, 0x16, 0x33, 0x32, 0x36, +0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x1d, 0x20, 0x3a, 0x51, +0x32, 0x50, 0x35, 0x14, 0x0a, 0x01, 0x01, 0x52, 0x01, 0x24, +0x22, 0x17, 0x19, 0x21, 0x3a, 0x52, 0x31, 0x32, 0x51, 0x3a, +0x20, 0x54, 0x42, 0x45, 0x46, 0x46, 0x46, 0x46, 0x45, 0x42, +0x01, 0x36, 0x53, 0x7a, 0x4f, 0x27, 0x31, 0x17, 0x2d, 0x1d, +0x09, 0x14, 0x05, 0x0a, 0x11, 0x05, 0x2b, 0x4c, 0x20, 0x27, +0x6f, 0x48, 0x53, 0x7a, 0x50, 0x26, 0x26, 0x50, 0x7a, 0x53, +0x7a, 0x82, 0x82, 0x7a, 0x7a, 0x82, 0x82, 0x00, 0x00, 0x00, +0x00, 0x02, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xdc, 0x02, 0x31, +0x00, 0x1f, 0x00, 0x2b, 0x00, 0x98, 0x40, 0x0c, 0x2a, 0x20, +0x0f, 0x10, 0x00, 0x4c, 0x2a, 0x10, 0x0e, 0x00, 0x4d, 0x28, +0xb8, 0xff, 0xe0, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x28, 0xb8, +0xff, 0xf0, 0xb3, 0x0e, 0x00, 0x4d, 0x24, 0xb8, 0xff, 0xe0, +0xb3, 0x10, 0x00, 0x4d, 0x24, 0xb8, 0xff, 0xe8, 0xb3, 0x0f, +0x00, 0x4d, 0x24, 0xb8, 0xff, 0xf0, 0x40, 0x1d, 0x0e, 0x00, +0x4d, 0x22, 0x28, 0x10, 0x00, 0x4d, 0x22, 0x20, 0x0f, 0x00, +0x4d, 0x22, 0x10, 0x0e, 0x00, 0x4d, 0x0c, 0x18, 0x08, 0x00, +0x4d, 0x08, 0x18, 0x08, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xf0, +0x40, 0x1f, 0x08, 0x00, 0x4d, 0x14, 0x1b, 0x20, 0x82, 0x1e, +0x11, 0x00, 0x2d, 0x26, 0x82, 0x0a, 0x40, 0x09, 0x0c, 0x48, +0x0a, 0x2c, 0x23, 0x88, 0x1e, 0x17, 0x11, 0x0f, 0x50, 0x29, +0x88, 0x05, 0x51, 0x00, 0x3f, 0xed, 0x3f, 0x33, 0xce, 0x33, +0xed, 0x01, 0x10, 0xd6, 0x2b, 0xed, 0x10, 0xde, 0x32, 0x32, +0xed, 0xdc, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x14, +0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, +0x33, 0x32, 0x17, 0x36, 0x36, 0x35, 0x34, 0x26, 0x27, 0x33, +0x16, 0x14, 0x15, 0x14, 0x06, 0x07, 0x16, 0x07, 0x34, 0x26, +0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x01, +0xcc, 0x1f, 0x38, 0x4e, 0x2e, 0x2d, 0x4d, 0x38, 0x1f, 0x1f, +0x38, 0x4d, 0x2d, 0x48, 0x36, 0x10, 0x07, 0x01, 0x01, 0x4f, +0x01, 0x1c, 0x1e, 0x2a, 0x55, 0x44, 0x3a, 0x39, 0x43, 0x43, +0x39, 0x3a, 0x44, 0xe8, 0x37, 0x59, 0x40, 0x23, 0x23, 0x40, +0x59, 0x37, 0x37, 0x5a, 0x3f, 0x23, 0x2a, 0x16, 0x2b, 0x1d, +0x08, 0x15, 0x05, 0x0b, 0x10, 0x05, 0x2a, 0x46, 0x1f, 0x3e, +0x5c, 0x4f, 0x5b, 0x5b, 0x4f, 0x4e, 0x5b, 0x5b, 0x00, 0x00, +0x00, 0x02, 0x00, 0x2d, 0xff, 0xf3, 0x01, 0xd8, 0x02, 0x79, +0x00, 0x20, 0x00, 0x34, 0x00, 0xae, 0xb9, 0x00, 0x32, 0xff, +0xe8, 0x40, 0x0e, 0x11, 0x00, 0x4d, 0x2e, 0x18, 0x11, 0x00, +0x4d, 0x28, 0x18, 0x11, 0x00, 0x4d, 0x24, 0xb8, 0xff, 0xe8, +0x40, 0x0e, 0x11, 0x00, 0x4d, 0x1e, 0x20, 0x13, 0x00, 0x4d, +0x1e, 0x30, 0x12, 0x00, 0x4d, 0x1e, 0xb8, 0xff, 0xe8, 0xb3, +0x11, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe0, 0xb3, 0x13, 0x00, +0x4d, 0x1a, 0xb8, 0xff, 0xd8, 0x40, 0x09, 0x12, 0x00, 0x4d, +0x1a, 0x18, 0x11, 0x00, 0x4d, 0x19, 0xb8, 0xff, 0xf0, 0xb4, +0x09, 0x0a, 0x00, 0x4c, 0x0b, 0xb8, 0xff, 0xf0, 0x40, 0x0a, +0x0d, 0x00, 0x4d, 0x03, 0x28, 0x12, 0x13, 0x00, 0x4c, 0x03, +0xb8, 0xff, 0xe0, 0x40, 0x25, 0x11, 0x00, 0x4d, 0x2b, 0x76, +0x14, 0x07, 0x17, 0x40, 0x09, 0x0c, 0x48, 0x17, 0x0f, 0x73, +0x0c, 0x36, 0x21, 0x76, 0x00, 0x35, 0x26, 0x7c, 0x1c, 0x46, +0x0e, 0x44, 0x14, 0x12, 0x7c, 0x09, 0x45, 0x30, 0x7c, 0x07, +0x05, 0x45, 0x00, 0x3f, 0x33, 0xed, 0x3f, 0xed, 0x32, 0x3f, +0x3f, 0xed, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xfd, 0xde, +0x2b, 0x32, 0x32, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x13, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x17, 0x36, 0x33, 0x32, +0x16, 0x15, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x07, +0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, +0x37, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, +0x2e, 0x02, 0x23, 0x22, 0x0e, 0x02, 0x2d, 0x13, 0x25, 0x35, +0x22, 0x30, 0x21, 0x26, 0x30, 0x37, 0x3e, 0x4e, 0x14, 0x1f, +0x14, 0x13, 0x0f, 0x10, 0x14, 0x26, 0x37, 0x22, 0x23, 0x35, +0x24, 0x13, 0x4e, 0x08, 0x10, 0x19, 0x11, 0x11, 0x19, 0x11, +0x08, 0x08, 0x11, 0x19, 0x11, 0x11, 0x19, 0x10, 0x08, 0x01, +0x36, 0x56, 0x7b, 0x4e, 0x24, 0x22, 0x21, 0x52, 0x5f, 0xfe, +0x39, 0x01, 0xb7, 0x38, 0x44, 0x16, 0x27, 0x72, 0x4e, 0x57, +0x7a, 0x4e, 0x24, 0x24, 0x4e, 0x7a, 0x57, 0x37, 0x5d, 0x44, +0x26, 0x26, 0x44, 0x5d, 0x37, 0x39, 0x5e, 0x42, 0x24, 0x24, +0x42, 0x5e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1b, 0xff, 0x5b, +0x01, 0xbf, 0x01, 0xdb, 0x00, 0x26, 0x00, 0x32, 0x00, 0xa8, +0x40, 0x0c, 0x25, 0x18, 0x09, 0x00, 0x4d, 0x24, 0x18, 0x11, +0x12, 0x00, 0x4c, 0x20, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, +0x4d, 0x20, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x1f, +0xb8, 0xff, 0xf0, 0xb3, 0x0b, 0x00, 0x4d, 0x1f, 0xb8, 0xff, +0xe8, 0xb4, 0x09, 0x0a, 0x00, 0x4c, 0x0e, 0xb8, 0xff, 0xd0, +0xb3, 0x09, 0x00, 0x4d, 0x0d, 0xb8, 0xff, 0xe0, 0xb4, 0x0b, +0x10, 0x00, 0x4c, 0x0d, 0xb8, 0xff, 0xd8, 0xb3, 0x0a, 0x00, +0x4d, 0x0d, 0xb8, 0xff, 0xc0, 0x40, 0x36, 0x08, 0x00, 0x4d, +0x03, 0x10, 0x11, 0x12, 0x00, 0x4c, 0x03, 0x18, 0x0a, 0x0b, +0x00, 0x4c, 0x02, 0x18, 0x09, 0x00, 0x4d, 0x2d, 0x82, 0x1a, +0x08, 0x0f, 0x1d, 0x1f, 0x1d, 0x02, 0x1d, 0x13, 0x7f, 0x10, +0x34, 0x27, 0x82, 0x00, 0x33, 0x2a, 0x88, 0x22, 0x51, 0x12, +0x4b, 0x1a, 0x18, 0x88, 0x08, 0x0b, 0x50, 0x30, 0x88, 0x05, +0x50, 0x00, 0x3f, 0xed, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0x3f, +0xed, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xfd, 0xde, 0x5d, +0x32, 0x32, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x37, 0x34, +0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x36, 0x36, 0x33, 0x32, +0x1e, 0x02, 0x15, 0x11, 0x23, 0x11, 0x34, 0x2e, 0x02, 0x23, +0x22, 0x07, 0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, +0x2e, 0x02, 0x37, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, +0x26, 0x23, 0x22, 0x06, 0x1b, 0x18, 0x26, 0x31, 0x1a, 0x15, +0x2a, 0x11, 0x0e, 0x2c, 0x1a, 0x27, 0x2f, 0x19, 0x08, 0x4f, +0x04, 0x0a, 0x14, 0x0f, 0x14, 0x11, 0x0b, 0x0b, 0x18, 0x27, +0x31, 0x1a, 0x1a, 0x32, 0x27, 0x18, 0x4e, 0x1b, 0x21, 0x22, +0x1a, 0x1a, 0x22, 0x21, 0x1b, 0xe8, 0x47, 0x5e, 0x37, 0x17, +0x0f, 0x11, 0x0b, 0x14, 0x1b, 0x34, 0x4a, 0x2f, 0xfe, 0x49, +0x01, 0xa5, 0x29, 0x37, 0x22, 0x0f, 0x14, 0x1b, 0x4a, 0x30, +0x47, 0x5e, 0x37, 0x17, 0x17, 0x38, 0x5d, 0x47, 0x54, 0x59, +0x59, 0x54, 0x55, 0x58, 0x58, 0x00, 0x00, 0x02, 0x00, 0x12, +0x00, 0x00, 0x01, 0xd5, 0x02, 0x71, 0x00, 0x19, 0x00, 0x23, +0x00, 0x7c, 0xb9, 0x00, 0x06, 0xff, 0xd8, 0xb3, 0x0a, 0x00, +0x4d, 0x06, 0xb8, 0xff, 0xe0, 0xb3, 0x09, 0x00, 0x4d, 0x03, +0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, 0x03, 0xb8, 0xff, +0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xd8, 0xb4, +0x11, 0x12, 0x00, 0x4c, 0x02, 0xb8, 0xff, 0xe0, 0xb3, 0x0a, +0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe8, 0x40, 0x24, 0x09, 0x00, +0x4d, 0x22, 0x76, 0x05, 0x25, 0x09, 0x1d, 0x73, 0x00, 0x0c, +0x10, 0x0c, 0x20, 0x0c, 0x03, 0x08, 0x0c, 0x0f, 0x15, 0x24, +0x09, 0x79, 0x1e, 0x1e, 0x00, 0x0b, 0x44, 0x12, 0x12, 0x0c, +0x1a, 0x7c, 0x00, 0x41, 0x00, 0x3f, 0xed, 0x32, 0x32, 0x2f, +0x3f, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xd6, 0xdd, 0xde, +0x5e, 0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x32, 0x1e, 0x02, +0x15, 0x14, 0x06, 0x23, 0x23, 0x15, 0x23, 0x11, 0x06, 0x06, +0x15, 0x14, 0x17, 0x07, 0x26, 0x26, 0x35, 0x34, 0x3e, 0x02, +0x17, 0x22, 0x06, 0x07, 0x15, 0x33, 0x32, 0x36, 0x35, 0x34, +0x01, 0x1e, 0x30, 0x45, 0x2d, 0x15, 0x5b, 0x5b, 0x2e, 0x52, +0x26, 0x21, 0x04, 0x43, 0x02, 0x05, 0x30, 0x4c, 0x60, 0x3f, +0x12, 0x22, 0x08, 0x2a, 0x34, 0x32, 0x02, 0x71, 0x1c, 0x33, +0x46, 0x2b, 0x61, 0x69, 0xe7, 0x02, 0x22, 0x05, 0x20, 0x1d, +0x10, 0x11, 0x08, 0x06, 0x19, 0x0d, 0x34, 0x3a, 0x1b, 0x05, +0x47, 0x01, 0x02, 0xfa, 0x3c, 0x45, 0x7c, 0x00, 0x00, 0x02, +0x00, 0x47, 0xff, 0x5b, 0x01, 0xcc, 0x02, 0xb5, 0x00, 0x21, +0x00, 0x30, 0x00, 0x97, 0x40, 0x10, 0x2e, 0x10, 0x0e, 0x00, +0x4d, 0x24, 0x20, 0x0e, 0x00, 0x4d, 0x24, 0x18, 0x0d, 0x00, +0x4d, 0x1f, 0xb8, 0xff, 0xe8, 0xb3, 0x09, 0x00, 0x4d, 0x1f, +0xb8, 0xff, 0xf0, 0x40, 0x09, 0x08, 0x00, 0x4d, 0x0e, 0x10, +0x0f, 0x00, 0x4d, 0x03, 0xb8, 0xff, 0xf0, 0xb3, 0x10, 0x00, +0x4d, 0x03, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x03, +0xb8, 0xff, 0xf0, 0xb3, 0x0a, 0x00, 0x4d, 0x02, 0xb8, 0xff, +0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe8, 0xb3, +0x09, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe0, 0x40, 0x20, 0x08, +0x00, 0x4d, 0x22, 0x82, 0x00, 0x32, 0x29, 0x1b, 0x13, 0x08, +0x7f, 0x00, 0x0a, 0x01, 0x08, 0x0a, 0x31, 0x25, 0x88, 0x1d, +0x50, 0x17, 0x89, 0x10, 0x4d, 0x0a, 0x4b, 0x2c, 0x88, 0x05, +0x51, 0x00, 0x3f, 0xed, 0x3f, 0x3f, 0xed, 0x3f, 0xed, 0x01, +0x10, 0xd6, 0x5e, 0x5d, 0xfd, 0xcc, 0x33, 0x33, 0x10, 0xde, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x26, 0x27, 0x15, 0x23, 0x11, 0x34, 0x3e, 0x02, 0x33, +0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x06, 0x15, +0x15, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x07, 0x34, 0x26, 0x23, +0x22, 0x06, 0x07, 0x11, 0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, +0x01, 0xcc, 0x1b, 0x33, 0x4a, 0x2f, 0x25, 0x38, 0x0e, 0x53, +0x0b, 0x1e, 0x33, 0x29, 0x0d, 0x20, 0x0a, 0x08, 0x08, 0x17, +0x07, 0x21, 0x1a, 0x2e, 0x2e, 0x2e, 0x4f, 0x39, 0x20, 0x55, +0x4c, 0x3d, 0x1d, 0x2c, 0x0b, 0x0e, 0x36, 0x1d, 0x21, 0x2f, +0x1e, 0x0e, 0xe7, 0x35, 0x59, 0x40, 0x24, 0x12, 0x0b, 0xb7, +0x02, 0xb3, 0x29, 0x3f, 0x2a, 0x15, 0x05, 0x02, 0x41, 0x02, +0x02, 0x2b, 0x29, 0x55, 0x12, 0x22, 0x3f, 0x5a, 0x38, 0x51, +0x59, 0x0c, 0x03, 0xfe, 0xe0, 0x0d, 0x16, 0x1a, 0x2d, 0x3d, +0x00, 0x02, 0x00, 0x37, 0xff, 0x9f, 0x01, 0xeb, 0x02, 0xb5, +0x00, 0x1b, 0x00, 0x2a, 0x00, 0x76, 0xb9, 0x00, 0x1b, 0xff, +0xd8, 0xb3, 0x10, 0x00, 0x4d, 0x1b, 0xb8, 0xff, 0xe0, 0xb3, +0x08, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xf0, 0xb3, 0x10, 0x00, +0x4d, 0x02, 0xb8, 0xff, 0xc0, 0x40, 0x30, 0x08, 0x00, 0x4d, +0x03, 0x09, 0x0e, 0x09, 0x78, 0x08, 0x03, 0x14, 0x08, 0x03, +0x08, 0x08, 0x26, 0x76, 0x00, 0x2c, 0x0e, 0x0e, 0x20, 0x17, +0x13, 0x73, 0x00, 0x14, 0x10, 0x14, 0x02, 0x14, 0x2b, 0x0e, +0x03, 0x12, 0x79, 0x20, 0x20, 0x14, 0x1c, 0x7c, 0x16, 0x19, +0x41, 0x14, 0x44, 0x08, 0x09, 0x00, 0x2f, 0x33, 0x3f, 0x3f, +0xce, 0xed, 0x12, 0x39, 0x2f, 0xed, 0x32, 0x32, 0x01, 0x10, +0xd6, 0x5d, 0xed, 0x32, 0x32, 0x32, 0x2f, 0x10, 0xde, 0xed, +0x33, 0x2f, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x01, +0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x14, 0x06, 0x07, 0x1e, 0x03, +0x17, 0x23, 0x2e, 0x03, 0x27, 0x06, 0x22, 0x23, 0x23, 0x15, +0x23, 0x11, 0x33, 0x15, 0x36, 0x33, 0x32, 0x16, 0x27, 0x22, +0x06, 0x07, 0x15, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, +0x02, 0x01, 0xaf, 0x3c, 0x33, 0x15, 0x2e, 0x2d, 0x2a, 0x11, +0x5d, 0x0f, 0x26, 0x2a, 0x2b, 0x15, 0x06, 0x15, 0x04, 0x46, +0x53, 0x53, 0x25, 0x1f, 0x70, 0x71, 0xda, 0x17, 0x2b, 0x09, +0x35, 0x24, 0x39, 0x29, 0x16, 0x16, 0x24, 0x31, 0x01, 0xae, +0x39, 0x58, 0x17, 0x25, 0x58, 0x5e, 0x60, 0x2c, 0x2b, 0x5c, +0x59, 0x53, 0x23, 0x01, 0xf4, 0x02, 0xb5, 0x47, 0x03, 0x62, +0x1b, 0x01, 0x02, 0xef, 0x0a, 0x1b, 0x2f, 0x26, 0x24, 0x2e, +0x1b, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0xff, 0xf3, +0x01, 0xbe, 0x02, 0x79, 0x00, 0x31, 0x01, 0x0f, 0xb9, 0x00, +0x31, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x31, 0xb8, 0xff, +0xe0, 0xb3, 0x11, 0x00, 0x4d, 0x2d, 0xb8, 0xff, 0xe0, 0xb3, +0x0f, 0x00, 0x4d, 0x2c, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, +0x4d, 0x2b, 0xb8, 0xff, 0xe0, 0xb3, 0x0a, 0x00, 0x4d, 0x2b, +0xb8, 0xff, 0xd8, 0xb3, 0x09, 0x00, 0x4d, 0x28, 0xb8, 0xff, +0xf0, 0xb3, 0x08, 0x00, 0x4d, 0x27, 0xb8, 0xff, 0xe0, 0xb3, +0x0f, 0x00, 0x4d, 0x27, 0xb8, 0xff, 0xd8, 0xb3, 0x0a, 0x00, +0x4d, 0x24, 0xb8, 0xff, 0xc8, 0xb3, 0x0a, 0x00, 0x4d, 0x24, +0xb8, 0xff, 0xe0, 0xb3, 0x09, 0x00, 0x4d, 0x24, 0xb8, 0xff, +0xd8, 0x40, 0x3d, 0x08, 0x00, 0x4d, 0x1e, 0x18, 0x11, 0x12, +0x00, 0x4c, 0x1e, 0x28, 0x10, 0x00, 0x4d, 0x1e, 0x20, 0x0f, +0x00, 0x4d, 0x1e, 0x18, 0x0e, 0x00, 0x4d, 0x18, 0x28, 0x12, +0x00, 0x4d, 0x18, 0x20, 0x11, 0x00, 0x4d, 0x13, 0x18, 0x0e, +0x00, 0x4d, 0x0f, 0x20, 0x08, 0x00, 0x4d, 0x0e, 0x10, 0x0d, +0x00, 0x4d, 0x0b, 0x18, 0x0a, 0x00, 0x4d, 0x0b, 0x28, 0x08, +0x09, 0x00, 0x4c, 0x06, 0xb8, 0xff, 0xd8, 0xb3, 0x0e, 0x00, +0x4d, 0x06, 0xb8, 0xff, 0xe8, 0xb3, 0x0d, 0x00, 0x4d, 0x05, +0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x05, 0xb8, 0xff, +0xe0, 0x40, 0x20, 0x0f, 0x00, 0x4d, 0x16, 0x76, 0x25, 0x04, +0x04, 0x25, 0x33, 0x2f, 0x76, 0x0c, 0x1d, 0x1d, 0x0c, 0x32, +0x2a, 0x09, 0x1c, 0x1c, 0x19, 0x7c, 0x11, 0x22, 0x45, 0x03, +0x03, 0x00, 0x7c, 0x09, 0x46, 0x00, 0x3f, 0xed, 0x32, 0x2f, +0x3f, 0x39, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x01, 0x10, 0xc6, +0x32, 0x2f, 0x10, 0xed, 0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, +0x32, 0x36, 0x37, 0x17, 0x0e, 0x03, 0x23, 0x22, 0x26, 0x35, +0x34, 0x3e, 0x02, 0x37, 0x3e, 0x03, 0x35, 0x34, 0x26, 0x23, +0x22, 0x06, 0x07, 0x27, 0x3e, 0x03, 0x33, 0x32, 0x16, 0x15, +0x14, 0x0e, 0x02, 0x07, 0x0e, 0x03, 0x15, 0x14, 0x16, 0x01, +0x0b, 0x38, 0x4e, 0x14, 0x19, 0x09, 0x22, 0x2d, 0x3a, 0x21, +0x66, 0x6e, 0x19, 0x2e, 0x3f, 0x26, 0x1a, 0x2c, 0x21, 0x13, +0x42, 0x2d, 0x2b, 0x46, 0x14, 0x1a, 0x0a, 0x21, 0x2a, 0x30, +0x1a, 0x5b, 0x66, 0x19, 0x2b, 0x37, 0x1e, 0x1a, 0x32, 0x28, +0x18, 0x42, 0x3a, 0x1d, 0x0b, 0x44, 0x06, 0x0e, 0x0e, 0x09, +0x57, 0x51, 0x2b, 0x3c, 0x2c, 0x20, 0x10, 0x0b, 0x16, 0x1b, +0x24, 0x1a, 0x2d, 0x2d, 0x18, 0x0c, 0x45, 0x07, 0x0e, 0x0a, +0x07, 0x5b, 0x51, 0x25, 0x36, 0x28, 0x1e, 0x0c, 0x0a, 0x17, +0x1f, 0x29, 0x1d, 0x30, 0x30, 0x00, 0x00, 0x01, 0x00, 0x41, +0xff, 0xf5, 0x01, 0xb1, 0x01, 0xdb, 0x00, 0x27, 0x00, 0xf6, +0xb9, 0x00, 0x26, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x26, +0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x25, 0xb8, 0xff, +0xe0, 0xb3, 0x09, 0x00, 0x4d, 0x25, 0xb8, 0xff, 0xd8, 0xb3, +0x08, 0x00, 0x4d, 0x23, 0xb8, 0xff, 0xd8, 0xb3, 0x0c, 0x00, +0x4d, 0x23, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x22, +0xb8, 0xff, 0xe0, 0xb3, 0x0d, 0x00, 0x4d, 0x20, 0xb8, 0xff, +0xe8, 0xb3, 0x0c, 0x00, 0x4d, 0x20, 0xb8, 0xff, 0xe0, 0xb3, +0x0b, 0x00, 0x4d, 0x20, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, +0x4d, 0x20, 0xb8, 0xff, 0xd8, 0x40, 0x2b, 0x08, 0x09, 0x00, +0x4c, 0x11, 0x18, 0x0f, 0x10, 0x00, 0x4c, 0x11, 0x10, 0x0e, +0x00, 0x4d, 0x0e, 0x20, 0x0d, 0x00, 0x4d, 0x0e, 0x28, 0x0c, +0x00, 0x4d, 0x0e, 0x18, 0x0a, 0x00, 0x4d, 0x0b, 0x18, 0x0b, +0x0c, 0x00, 0x4c, 0x0b, 0x20, 0x08, 0x0a, 0x00, 0x4c, 0x07, +0xb8, 0xff, 0xc8, 0xb3, 0x0e, 0x00, 0x4d, 0x06, 0xb8, 0xff, +0xe0, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x06, 0xb8, 0xff, 0xd8, +0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x06, 0xb8, 0xff, 0xe0, 0x40, +0x23, 0x0e, 0x00, 0x4d, 0x13, 0x82, 0x21, 0x06, 0x06, 0x21, +0x29, 0x1b, 0x1b, 0x00, 0x82, 0x00, 0x0c, 0x01, 0x08, 0x0c, +0x28, 0x25, 0x09, 0x1a, 0x1a, 0x15, 0x88, 0x10, 0x1e, 0x50, +0x05, 0x05, 0x02, 0x88, 0x09, 0x51, 0x00, 0x3f, 0xed, 0x32, +0x2f, 0x3f, 0x39, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x01, 0x10, +0xd6, 0x5e, 0x5d, 0xed, 0x33, 0x2f, 0x10, 0xce, 0x32, 0x2f, +0x10, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x37, 0x14, 0x33, 0x32, +0x36, 0x37, 0x17, 0x06, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, +0x3e, 0x04, 0x35, 0x34, 0x23, 0x22, 0x0e, 0x02, 0x07, 0x27, +0x36, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x04, 0x94, +0x72, 0x2b, 0x4d, 0x23, 0x10, 0x24, 0x50, 0x30, 0x6a, 0x62, +0x29, 0x3e, 0x48, 0x3e, 0x29, 0x6c, 0x14, 0x28, 0x24, 0x1c, +0x08, 0x0f, 0x1d, 0x51, 0x27, 0x60, 0x5b, 0x29, 0x3d, 0x48, +0x3d, 0x29, 0x74, 0x39, 0x15, 0x10, 0x4b, 0x10, 0x10, 0x45, +0x3f, 0x27, 0x33, 0x24, 0x19, 0x18, 0x1d, 0x15, 0x3b, 0x04, +0x07, 0x09, 0x04, 0x4a, 0x09, 0x0b, 0x4b, 0x38, 0x28, 0x32, +0x22, 0x17, 0x18, 0x20, 0x00, 0x00, 0xff, 0xff, 0x00, 0x28, +0x00, 0x00, 0x01, 0xbf, 0x02, 0x6b, 0x02, 0x06, 0x03, 0xa2, +0x00, 0x00, 0x00, 0x02, 0x00, 0x2b, 0xff, 0x5b, 0x01, 0xb9, +0x02, 0xb5, 0x00, 0x1f, 0x00, 0x2c, 0x00, 0x8c, 0xb9, 0x00, +0x1e, 0xff, 0xe0, 0xb3, 0x0a, 0x00, 0x4d, 0x1e, 0xb8, 0xff, +0xd8, 0xb4, 0x08, 0x09, 0x00, 0x4c, 0x1d, 0xb8, 0xff, 0xe8, +0xb3, 0x0d, 0x00, 0x4d, 0x1d, 0xb8, 0xff, 0xe0, 0x40, 0x48, +0x0b, 0x0c, 0x00, 0x4c, 0x1a, 0x10, 0x0d, 0x00, 0x4d, 0x1a, +0x20, 0x0c, 0x00, 0x4d, 0x1a, 0x18, 0x0b, 0x00, 0x4d, 0x19, +0x20, 0x08, 0x0a, 0x00, 0x4c, 0x15, 0x20, 0x0a, 0x0c, 0x00, +0x4c, 0x15, 0x28, 0x09, 0x00, 0x4d, 0x15, 0x20, 0x08, 0x00, +0x4d, 0x14, 0x18, 0x0d, 0x00, 0x4d, 0x26, 0x00, 0x17, 0x01, +0x08, 0x17, 0x0f, 0x06, 0x00, 0x7f, 0x20, 0x0f, 0x0f, 0x2e, +0x2d, 0x10, 0x12, 0x2c, 0x29, 0x23, 0x1c, 0x4d, 0x05, 0x88, +0x0a, 0x4b, 0x00, 0x3f, 0xed, 0x3f, 0xdd, 0xde, 0x32, 0xcd, +0x32, 0x01, 0x11, 0x12, 0x39, 0x2f, 0x33, 0xfd, 0xce, 0x10, +0xdc, 0x5e, 0x5d, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x14, +0x1e, 0x02, 0x33, 0x33, 0x15, 0x06, 0x22, 0x23, 0x22, 0x2e, +0x02, 0x35, 0x11, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, +0x3e, 0x02, 0x33, 0x32, 0x16, 0x15, 0x27, 0x34, 0x26, 0x23, +0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x01, +0x34, 0x0f, 0x19, 0x22, 0x14, 0x27, 0x08, 0x18, 0x05, 0x32, +0x44, 0x2a, 0x12, 0x1e, 0x26, 0x1e, 0x2c, 0x1c, 0x0d, 0x0c, +0x1d, 0x31, 0x26, 0x4b, 0x3e, 0x52, 0x1f, 0x1e, 0x1d, 0x1d, +0x1a, 0x20, 0x14, 0x1c, 0x0d, 0x16, 0x21, 0x2c, 0x1b, 0x0b, +0x47, 0x01, 0x1a, 0x32, 0x49, 0x30, 0x01, 0xb8, 0x12, 0x15, +0x21, 0x2b, 0x15, 0x10, 0x2a, 0x26, 0x19, 0x56, 0x4c, 0x18, +0x23, 0x27, 0x25, 0x14, 0x14, 0x27, 0x0f, 0x0e, 0x00, 0x00, +0x00, 0x01, 0x00, 0x3f, 0xff, 0x59, 0x01, 0xc7, 0x02, 0x60, +0x00, 0x32, 0x00, 0x94, 0xb9, 0x00, 0x21, 0xff, 0xe8, 0xb3, +0x12, 0x00, 0x4d, 0x21, 0xb8, 0xff, 0xe0, 0xb4, 0x0f, 0x10, +0x00, 0x4c, 0x21, 0xb8, 0xff, 0xd8, 0xb3, 0x0e, 0x00, 0x4d, +0x21, 0xb8, 0xff, 0xe0, 0xb4, 0x0c, 0x0d, 0x00, 0x4c, 0x21, +0xb8, 0xff, 0xd8, 0x40, 0x40, 0x0b, 0x00, 0x4d, 0x03, 0x10, +0x0d, 0x00, 0x4d, 0x03, 0x18, 0x0c, 0x00, 0x4d, 0x03, 0x20, +0x0b, 0x00, 0x4d, 0x2e, 0x82, 0x1f, 0x0e, 0x0e, 0x1f, 0x34, +0x0c, 0x0f, 0x7f, 0x09, 0x06, 0x00, 0x07, 0x01, 0x08, 0x07, +0x33, 0x30, 0x27, 0x01, 0x0f, 0x27, 0x01, 0x27, 0x27, 0x2f, +0x2b, 0x89, 0x24, 0x4b, 0x1b, 0x4a, 0x0a, 0x0b, 0x0f, 0x06, +0x85, 0x0c, 0x09, 0x49, 0x19, 0x15, 0x88, 0x00, 0x51, 0x00, +0x3f, 0xed, 0x32, 0x3f, 0x33, 0xed, 0x32, 0xcd, 0x32, 0x3f, +0x3f, 0xed, 0x01, 0x2f, 0x33, 0x2f, 0x5d, 0x5d, 0x10, 0xd6, +0x5e, 0x5d, 0xdd, 0x32, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, +0x10, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x05, 0x22, 0x2e, 0x02, 0x35, 0x35, 0x23, 0x35, +0x33, 0x35, 0x37, 0x15, 0x33, 0x15, 0x23, 0x15, 0x14, 0x1e, +0x02, 0x33, 0x32, 0x3e, 0x02, 0x37, 0x1e, 0x03, 0x15, 0x14, +0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, +0x32, 0x36, 0x35, 0x34, 0x34, 0x27, 0x06, 0x01, 0x42, 0x31, +0x3f, 0x24, 0x0d, 0x62, 0x62, 0x52, 0xbb, 0xbb, 0x0a, 0x17, +0x24, 0x1a, 0x13, 0x24, 0x1e, 0x16, 0x04, 0x01, 0x02, 0x02, +0x01, 0x09, 0x1a, 0x31, 0x27, 0x0d, 0x1f, 0x0a, 0x07, 0x05, +0x19, 0x07, 0x23, 0x17, 0x01, 0x18, 0x06, 0x17, 0x2e, 0x45, +0x2f, 0xd8, 0x45, 0x82, 0x0e, 0x90, 0x45, 0xd8, 0x23, 0x2c, +0x1b, 0x0a, 0x03, 0x03, 0x04, 0x01, 0x06, 0x13, 0x15, 0x15, +0x07, 0x27, 0x3d, 0x2c, 0x17, 0x05, 0x02, 0x3d, 0x02, 0x03, +0x2d, 0x28, 0x04, 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x01, +0x00, 0x12, 0x00, 0x00, 0x01, 0xcd, 0x02, 0x6b, 0x00, 0x14, +0x00, 0x28, 0x40, 0x13, 0x02, 0x73, 0x05, 0x05, 0x0f, 0x01, +0x16, 0x09, 0x0f, 0x15, 0x0c, 0x0c, 0x02, 0x05, 0x79, 0x14, +0x41, 0x04, 0x44, 0x00, 0x3f, 0x3f, 0xed, 0x32, 0x32, 0x2f, +0x01, 0x10, 0xd6, 0xcd, 0x10, 0xce, 0x11, 0x39, 0x2f, 0xed, +0x31, 0x30, 0x01, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, 0x22, +0x06, 0x15, 0x14, 0x17, 0x07, 0x26, 0x26, 0x35, 0x34, 0x3e, +0x02, 0x33, 0x01, 0xcd, 0x98, 0x52, 0x42, 0x22, 0x27, 0x04, +0x43, 0x02, 0x05, 0x1d, 0x30, 0x3e, 0x21, 0x02, 0x6b, 0x46, +0xfd, 0xdb, 0x02, 0x25, 0x25, 0x20, 0x10, 0x11, 0x08, 0x06, +0x19, 0x0d, 0x28, 0x35, 0x1f, 0x0c, 0x00, 0x01, 0x00, 0x3f, +0xff, 0xf5, 0x01, 0xcc, 0x02, 0xb5, 0x00, 0x27, 0x00, 0x5a, +0xb9, 0x00, 0x25, 0xff, 0xe8, 0x40, 0x32, 0x11, 0x12, 0x00, +0x4c, 0x1b, 0x20, 0x0c, 0x00, 0x4d, 0x13, 0x18, 0x0b, 0x0c, +0x00, 0x4c, 0x20, 0x20, 0x0d, 0x0d, 0x02, 0x29, 0x00, 0x03, +0x7f, 0x19, 0x16, 0x00, 0x17, 0x01, 0x08, 0x17, 0x28, 0x21, +0x21, 0x24, 0x88, 0x1d, 0x4d, 0x03, 0x16, 0x85, 0x00, 0x19, +0x49, 0x0c, 0x0c, 0x09, 0x88, 0x10, 0x51, 0x00, 0x3f, 0xed, +0x32, 0x2f, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0xed, 0x32, 0x2f, +0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xdd, 0x32, 0xed, 0x32, 0x10, +0xce, 0x32, 0x2f, 0x32, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x13, 0x33, 0x15, 0x23, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, +0x36, 0x37, 0x17, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x35, 0x23, 0x35, 0x33, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, +0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x06, 0x15, 0xf3, 0xbb, +0xbb, 0x0a, 0x17, 0x24, 0x1a, 0x24, 0x2c, 0x14, 0x0c, 0x0e, +0x3a, 0x30, 0x34, 0x42, 0x25, 0x0e, 0x62, 0x62, 0x55, 0x67, +0x2a, 0x39, 0x0c, 0x0f, 0x0c, 0x2d, 0x21, 0x41, 0x2f, 0x01, +0xd0, 0x45, 0xd8, 0x23, 0x2c, 0x1b, 0x0a, 0x0c, 0x0a, 0x46, +0x06, 0x14, 0x18, 0x30, 0x47, 0x2f, 0xd8, 0x45, 0x2a, 0x59, +0x62, 0x0a, 0x05, 0x48, 0x05, 0x0b, 0x3d, 0x33, 0x00, 0x00, +0x00, 0x01, 0x00, 0x27, 0xff, 0x59, 0x01, 0xcd, 0x02, 0x6b, +0x00, 0x14, 0x00, 0x2a, 0x40, 0x15, 0x13, 0x07, 0x00, 0x73, +0x10, 0x00, 0x0e, 0x01, 0x08, 0x0e, 0x0e, 0x16, 0x15, 0x14, +0x0f, 0x79, 0x11, 0x41, 0x03, 0x7c, 0x09, 0x00, 0x2f, 0xed, +0x3f, 0xed, 0x32, 0x01, 0x11, 0x12, 0x39, 0x2f, 0x5e, 0x5d, +0xce, 0xfd, 0xcc, 0xce, 0x31, 0x30, 0x05, 0x14, 0x16, 0x33, +0x32, 0x36, 0x37, 0x17, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x11, 0x23, 0x35, 0x21, 0x15, 0x23, 0x01, 0x23, 0x17, 0x20, +0x08, 0x11, 0x09, 0x08, 0x16, 0x1c, 0x27, 0x32, 0x1d, 0x0b, +0xaa, 0x01, 0xa6, 0xaa, 0x0f, 0x29, 0x2b, 0x01, 0x02, 0x42, +0x05, 0x17, 0x2b, 0x3e, 0x27, 0x02, 0x25, 0x46, 0x46, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x30, 0xff, 0xf3, 0x01, 0xee, +0x02, 0xcb, 0x00, 0x28, 0x00, 0x6d, 0xb9, 0x00, 0x27, 0xff, +0xc8, 0xb3, 0x08, 0x00, 0x4d, 0x26, 0xb8, 0xff, 0xe0, 0xb3, +0x0a, 0x00, 0x4d, 0x26, 0xb8, 0xff, 0xe8, 0x40, 0x0e, 0x09, +0x00, 0x4d, 0x0f, 0x10, 0x12, 0x00, 0x4d, 0x0f, 0x18, 0x11, +0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xf0, 0x40, 0x27, 0x11, 0x12, +0x00, 0x4c, 0x03, 0x20, 0x0a, 0x00, 0x4d, 0x03, 0x18, 0x09, +0x00, 0x4d, 0x02, 0x28, 0x08, 0x00, 0x4d, 0x17, 0x1e, 0x12, +0x73, 0x24, 0x2a, 0x08, 0x73, 0x05, 0x29, 0x23, 0x1a, 0x13, +0x13, 0x06, 0x41, 0x0d, 0x7c, 0x00, 0x46, 0x00, 0x3f, 0xed, +0x3f, 0x33, 0x10, 0xce, 0xcd, 0x01, 0x10, 0xd6, 0xed, 0x10, +0xde, 0xed, 0xdc, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x17, 0x22, 0x2e, 0x02, 0x35, +0x11, 0x33, 0x11, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, +0x35, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x27, 0x33, +0x16, 0x14, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x11, 0x14, 0x0e, +0x02, 0xdf, 0x32, 0x43, 0x29, 0x11, 0x52, 0x0b, 0x17, 0x23, +0x18, 0x18, 0x23, 0x17, 0x0b, 0x40, 0x0d, 0x14, 0x01, 0x01, +0x52, 0x01, 0x09, 0x17, 0x25, 0x1b, 0x11, 0x29, 0x43, 0x0d, +0x1f, 0x39, 0x50, 0x31, 0x01, 0x9f, 0xfe, 0x6a, 0x2c, 0x3b, +0x24, 0x10, 0x10, 0x24, 0x3b, 0x2c, 0x01, 0x96, 0x1f, 0x1f, +0x09, 0x14, 0x05, 0x0a, 0x11, 0x05, 0x14, 0x29, 0x22, 0x19, +0x04, 0xfe, 0x9d, 0x31, 0x50, 0x39, 0x1f, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x44, 0xff, 0xf6, 0x01, 0xdc, 0x02, 0x31, +0x00, 0x22, 0x00, 0x4e, 0xb9, 0x00, 0x0d, 0xff, 0xe8, 0xb3, +0x12, 0x00, 0x4d, 0x0d, 0xb8, 0xff, 0xe0, 0x40, 0x26, 0x11, +0x00, 0x4d, 0x06, 0x18, 0x0a, 0x00, 0x4d, 0x06, 0x20, 0x08, +0x09, 0x00, 0x4c, 0x16, 0x1d, 0x12, 0x7f, 0x22, 0x24, 0x0b, +0x7f, 0x00, 0x08, 0x01, 0x08, 0x08, 0x23, 0x22, 0x19, 0x12, +0x12, 0x09, 0x49, 0x0e, 0x88, 0x03, 0x51, 0x00, 0x3f, 0xed, +0x3f, 0x33, 0x10, 0xce, 0xcd, 0x01, 0x10, 0xd6, 0x5e, 0x5d, +0xed, 0x10, 0xde, 0xed, 0xdd, 0xcd, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x2b, 0x25, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x11, 0x33, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x11, +0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x27, 0x33, 0x16, 0x14, +0x15, 0x14, 0x0e, 0x02, 0x07, 0x01, 0x7e, 0x17, 0x4f, 0x33, +0x2e, 0x3e, 0x25, 0x10, 0x52, 0x27, 0x30, 0x14, 0x26, 0x05, +0x39, 0x17, 0x0f, 0x01, 0x01, 0x52, 0x01, 0x09, 0x15, 0x25, +0x1b, 0x0d, 0x07, 0x10, 0x1f, 0x39, 0x4e, 0x2f, 0x01, 0x05, +0xf3, 0x56, 0x48, 0x07, 0x02, 0x01, 0x88, 0x20, 0x1f, 0x08, +0x15, 0x05, 0x0b, 0x10, 0x05, 0x15, 0x29, 0x22, 0x18, 0x04, +0x00, 0x01, 0x00, 0x12, 0xff, 0xf2, 0x01, 0xe2, 0x02, 0x6b, +0x00, 0x2b, 0x00, 0x93, 0xb5, 0x21, 0x18, 0x0d, 0x00, 0x4d, +0x1d, 0xb8, 0xff, 0xe8, 0x40, 0x0e, 0x0d, 0x00, 0x4d, 0x0b, +0x18, 0x0e, 0x00, 0x4d, 0x0b, 0x10, 0x08, 0x00, 0x4d, 0x07, +0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x07, 0xb8, 0xff, +0xf0, 0xb3, 0x08, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xf0, 0x40, +0x3b, 0x10, 0x00, 0x4d, 0x01, 0x7f, 0x29, 0xaf, 0x29, 0xbf, +0x29, 0x03, 0x29, 0x29, 0x24, 0x76, 0x04, 0x00, 0x00, 0x04, +0x2d, 0x11, 0x18, 0x10, 0x00, 0x4d, 0x11, 0x00, 0x15, 0x10, +0x15, 0x70, 0x15, 0xa0, 0x15, 0xb0, 0x15, 0x05, 0x15, 0x15, +0x1a, 0x76, 0x0e, 0x12, 0x12, 0x0e, 0x2c, 0x29, 0x15, 0x15, +0x01, 0x11, 0x79, 0x2a, 0x14, 0x41, 0x1f, 0x7c, 0x09, 0x46, +0x00, 0x3f, 0xed, 0x3f, 0x33, 0xed, 0x32, 0x32, 0x11, 0x33, +0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xed, 0x32, 0x2f, 0x5d, +0x33, 0x2b, 0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, 0x32, 0x2f, +0x5d, 0x33, 0x2b, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x01, 0x23, 0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x2e, 0x02, 0x35, 0x34, 0x36, 0x37, 0x23, 0x35, 0x33, +0x15, 0x0e, 0x03, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, +0x02, 0x35, 0x34, 0x2e, 0x02, 0x27, 0x35, 0x33, 0x01, 0xe2, +0x6d, 0x30, 0x2e, 0x1b, 0x37, 0x52, 0x36, 0x36, 0x52, 0x37, +0x1b, 0x2f, 0x2f, 0x6b, 0xc5, 0x18, 0x26, 0x19, 0x0e, 0x10, +0x21, 0x33, 0x23, 0x23, 0x33, 0x21, 0x10, 0x0e, 0x19, 0x26, +0x18, 0xc7, 0x02, 0x25, 0x3d, 0x95, 0x4a, 0x38, 0x65, 0x4c, +0x2e, 0x2e, 0x4c, 0x65, 0x38, 0x4a, 0x95, 0x3d, 0x46, 0x3c, +0x1a, 0x44, 0x4d, 0x52, 0x28, 0x2a, 0x4c, 0x39, 0x22, 0x22, +0x39, 0x4c, 0x2a, 0x28, 0x52, 0x4d, 0x44, 0x1a, 0x3c, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x2d, 0xff, 0xf3, 0x01, 0xc9, +0x02, 0x6e, 0x00, 0x21, 0x00, 0x76, 0xb5, 0x20, 0x10, 0x0f, +0x00, 0x4d, 0x1f, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, +0x1f, 0xb8, 0xff, 0xe8, 0x40, 0x19, 0x08, 0x00, 0x4d, 0x15, +0x38, 0x0f, 0x00, 0x4d, 0x15, 0x10, 0x0e, 0x00, 0x4d, 0x11, +0x08, 0x11, 0x12, 0x00, 0x4c, 0x10, 0x10, 0x0d, 0x00, 0x4d, +0x0d, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, 0x0d, 0xb8, +0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x03, 0xb8, 0xff, 0xe8, +0x40, 0x18, 0x0e, 0x00, 0x4d, 0x1a, 0x1a, 0x0b, 0x13, 0x76, +0x00, 0x23, 0x0b, 0x73, 0x08, 0x22, 0x16, 0x7c, 0x1d, 0x41, +0x09, 0x41, 0x0e, 0x7c, 0x05, 0x46, 0x00, 0x3f, 0xed, 0x3f, +0x3f, 0xed, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, 0x11, +0x39, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x14, 0x0e, 0x02, 0x23, 0x22, +0x26, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x3e, +0x02, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, +0x36, 0x33, 0x32, 0x1e, 0x02, 0x01, 0xc9, 0x22, 0x3b, 0x51, +0x2f, 0x5b, 0x64, 0x52, 0x2e, 0x3f, 0x1d, 0x33, 0x25, 0x16, +0x39, 0x48, 0x0c, 0x0f, 0x06, 0x02, 0x05, 0x21, 0x0d, 0x37, +0x4b, 0x2d, 0x14, 0x01, 0x3e, 0x5a, 0x7e, 0x4f, 0x24, 0x69, +0x7b, 0x01, 0x94, 0xfe, 0x80, 0x5c, 0x55, 0x18, 0x3a, 0x62, +0x4a, 0x77, 0x79, 0x01, 0x01, 0x45, 0x02, 0x01, 0x2e, 0x51, +0x6f, 0x00, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x02, 0x16, +0x02, 0x74, 0x00, 0x1b, 0x00, 0x59, 0x40, 0x31, 0x0a, 0x05, +0x0a, 0x0b, 0x05, 0x78, 0x04, 0x01, 0x14, 0x04, 0x04, 0x01, +0x0b, 0x0a, 0x0a, 0x78, 0x1a, 0x19, 0x14, 0x1a, 0x19, 0x1a, +0x73, 0x00, 0x01, 0x01, 0x08, 0x01, 0x01, 0x13, 0x04, 0x1c, +0x19, 0x13, 0x19, 0x0b, 0x16, 0x7c, 0x10, 0x45, 0x1a, 0x0a, +0x01, 0x01, 0x05, 0x04, 0x41, 0x00, 0x44, 0x00, 0x3f, 0x3f, +0x33, 0x39, 0x11, 0x33, 0x33, 0x3f, 0xed, 0x32, 0x32, 0x01, +0x2f, 0x33, 0x10, 0xc6, 0x11, 0x39, 0x2f, 0x5e, 0x5d, 0xfd, +0x87, 0x2b, 0x7d, 0x10, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x08, +0x7d, 0x10, 0xc4, 0x31, 0x30, 0x33, 0x35, 0x26, 0x26, 0x27, +0x33, 0x1e, 0x03, 0x17, 0x37, 0x3e, 0x03, 0x33, 0x32, 0x16, +0x17, 0x07, 0x26, 0x23, 0x22, 0x06, 0x07, 0x03, 0x15, 0xd2, +0x3b, 0x66, 0x24, 0x5c, 0x0a, 0x21, 0x27, 0x29, 0x14, 0x5a, +0x0b, 0x17, 0x1a, 0x1d, 0x11, 0x1b, 0x2d, 0x12, 0x25, 0x1a, +0x18, 0x0d, 0x18, 0x0e, 0x68, 0xe6, 0x63, 0xbf, 0x63, 0x23, +0x4e, 0x52, 0x51, 0x24, 0xdf, 0x1d, 0x26, 0x16, 0x09, 0x18, +0x13, 0x39, 0x1b, 0x19, 0x23, 0xfe, 0xfb, 0xea, 0x00, 0x01, +0x00, 0x13, 0xff, 0x58, 0x01, 0xe8, 0x01, 0xdc, 0x00, 0x29, +0x00, 0x72, 0x40, 0x40, 0x4a, 0x15, 0x01, 0x39, 0x15, 0x01, +0x15, 0x19, 0x1e, 0x19, 0x81, 0x18, 0x15, 0x14, 0x18, 0x18, +0x15, 0x67, 0x06, 0x01, 0x06, 0x21, 0x1e, 0x21, 0x81, 0x03, +0x06, 0x14, 0x03, 0x03, 0x06, 0x1e, 0x18, 0x03, 0x0f, 0x03, +0x01, 0x08, 0x03, 0x27, 0x2b, 0x0e, 0x0e, 0x18, 0x2a, 0x21, +0x03, 0x03, 0x00, 0x88, 0x24, 0x50, 0x1e, 0x06, 0x15, 0x15, +0x0b, 0x19, 0x18, 0x49, 0x12, 0x88, 0x0b, 0x4b, 0x00, 0x3f, +0xed, 0x3f, 0x33, 0x12, 0x39, 0x11, 0x33, 0x33, 0x3f, 0xed, +0x32, 0x2f, 0x32, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xce, +0x32, 0x5e, 0x5d, 0x11, 0x12, 0x39, 0x87, 0x10, 0x2b, 0x87, +0x7d, 0xc4, 0x01, 0x5d, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, +0xc4, 0x01, 0x5d, 0x5d, 0x31, 0x30, 0x01, 0x22, 0x06, 0x07, +0x06, 0x06, 0x07, 0x0e, 0x03, 0x23, 0x22, 0x26, 0x27, 0x37, +0x16, 0x16, 0x33, 0x32, 0x36, 0x37, 0x26, 0x26, 0x27, 0x33, +0x1e, 0x03, 0x17, 0x36, 0x36, 0x37, 0x36, 0x36, 0x33, 0x32, +0x16, 0x17, 0x07, 0x26, 0x01, 0xb5, 0x16, 0x15, 0x06, 0x19, +0x35, 0x21, 0x11, 0x24, 0x2c, 0x36, 0x23, 0x13, 0x2d, 0x08, +0x0f, 0x0a, 0x1f, 0x0f, 0x2c, 0x33, 0x14, 0x35, 0x5b, 0x1e, +0x5a, 0x09, 0x18, 0x1f, 0x25, 0x14, 0x16, 0x20, 0x12, 0x0b, +0x2f, 0x33, 0x11, 0x1f, 0x11, 0x0e, 0x0c, 0x01, 0x96, 0x1b, +0x1b, 0x6a, 0xb4, 0x50, 0x28, 0x3a, 0x26, 0x12, 0x0a, 0x04, +0x43, 0x05, 0x06, 0x2b, 0x31, 0x6b, 0xf0, 0x7b, 0x28, 0x5d, +0x62, 0x63, 0x2e, 0x46, 0x86, 0x4f, 0x32, 0x37, 0x07, 0x06, +0x41, 0x08, 0x00, 0x01, 0x00, 0x36, 0x00, 0x00, 0x01, 0xc7, +0x02, 0x6b, 0x00, 0x19, 0x00, 0x6e, 0x40, 0x36, 0x0a, 0x0a, +0x00, 0x15, 0x13, 0x10, 0x0e, 0x0d, 0x16, 0x0d, 0x01, 0x03, +0x06, 0x08, 0x09, 0x00, 0x09, 0x16, 0x0d, 0x16, 0x78, 0x00, +0x09, 0x14, 0x00, 0x00, 0x09, 0x04, 0x04, 0x00, 0x1b, 0x17, +0x17, 0x11, 0x11, 0x0d, 0x1a, 0x00, 0x16, 0x79, 0x19, 0x06, +0x10, 0x79, 0x03, 0x13, 0x13, 0x19, 0x41, 0x0d, 0x09, 0x79, +0x0c, 0x44, 0x00, 0x3f, 0xed, 0x32, 0x3f, 0x39, 0x2f, 0x33, +0xed, 0x32, 0x10, 0xed, 0x32, 0x01, 0x10, 0xc6, 0x32, 0x2f, +0x32, 0x2f, 0x10, 0xce, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x87, +0x7d, 0xc4, 0x87, 0x0e, 0xc4, 0x05, 0xc4, 0xc4, 0x0e, 0xc4, +0x10, 0x87, 0x0e, 0xc4, 0x05, 0xc4, 0xc4, 0x0e, 0xc4, 0x01, +0x11, 0x33, 0x18, 0x2f, 0x31, 0x30, 0x01, 0x06, 0x06, 0x07, +0x33, 0x15, 0x23, 0x06, 0x06, 0x07, 0x21, 0x15, 0x21, 0x35, +0x36, 0x36, 0x37, 0x23, 0x35, 0x33, 0x36, 0x36, 0x37, 0x21, +0x35, 0x21, 0x01, 0xbf, 0x1b, 0x45, 0x24, 0x77, 0x9f, 0x24, +0x41, 0x1a, 0x01, 0x33, 0xfe, 0x6f, 0x1d, 0x43, 0x23, 0x61, +0x88, 0x21, 0x41, 0x1e, 0xfe, 0xe5, 0x01, 0x7a, 0x02, 0x2b, +0x27, 0x68, 0x39, 0x40, 0x3b, 0x71, 0x31, 0x46, 0x36, 0x39, +0x79, 0x3b, 0x40, 0x36, 0x61, 0x2b, 0x46, 0x00, 0x00, 0x01, +0x00, 0x49, 0x00, 0x00, 0x01, 0xab, 0x01, 0xd0, 0x00, 0x19, +0x00, 0x6c, 0x40, 0x37, 0x0a, 0x0a, 0x00, 0x15, 0x13, 0x10, +0x0d, 0x16, 0x0d, 0x01, 0x03, 0x06, 0x09, 0x00, 0x09, 0x16, +0x0d, 0x16, 0x81, 0x00, 0x09, 0x14, 0x00, 0x00, 0x09, 0x04, +0x04, 0x00, 0x1b, 0x17, 0x17, 0x11, 0x11, 0x00, 0x0d, 0x01, +0x08, 0x0d, 0x1a, 0x00, 0x16, 0x85, 0x19, 0x06, 0x10, 0x03, +0x13, 0x13, 0x19, 0x49, 0x0d, 0x09, 0x85, 0x0c, 0x4a, 0x00, +0x3f, 0xed, 0x32, 0x3f, 0x39, 0x2f, 0x33, 0xcd, 0x32, 0x10, +0xed, 0x32, 0x01, 0x10, 0xc6, 0x5e, 0x5d, 0x32, 0x2f, 0x32, +0x2f, 0x10, 0xce, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, +0xc4, 0x87, 0xc4, 0xc4, 0x0e, 0xc4, 0x10, 0x87, 0x05, 0xc4, +0xc4, 0x0e, 0xc4, 0x01, 0x11, 0x33, 0x18, 0x2f, 0x31, 0x30, +0x01, 0x06, 0x06, 0x07, 0x33, 0x15, 0x23, 0x06, 0x06, 0x07, +0x33, 0x15, 0x21, 0x35, 0x36, 0x36, 0x37, 0x23, 0x35, 0x33, +0x36, 0x36, 0x37, 0x23, 0x35, 0x21, 0x01, 0xa4, 0x12, 0x38, +0x20, 0x62, 0x8e, 0x1b, 0x33, 0x14, 0xff, 0xfe, 0x9e, 0x13, +0x36, 0x1e, 0x4d, 0x78, 0x1b, 0x31, 0x13, 0xe4, 0x01, 0x4e, +0x01, 0x92, 0x14, 0x42, 0x2a, 0x3b, 0x25, 0x4a, 0x22, 0x46, +0x37, 0x23, 0x53, 0x2a, 0x3b, 0x23, 0x3f, 0x17, 0x45, 0x00, +0x00, 0x01, 0x00, 0x18, 0xff, 0xf3, 0x01, 0xcf, 0x02, 0x6b, +0x00, 0x25, 0x00, 0xba, 0x40, 0x11, 0x23, 0x20, 0x10, 0x00, +0x4d, 0x20, 0x18, 0x10, 0x00, 0x4d, 0x19, 0x18, 0x0d, 0x0e, +0x00, 0x4c, 0x13, 0xb8, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, +0x13, 0xb8, 0xff, 0xd8, 0xb3, 0x11, 0x00, 0x4d, 0x13, 0xb8, +0xff, 0xd8, 0xb3, 0x08, 0x00, 0x4d, 0x10, 0xb8, 0xff, 0xc8, +0xb3, 0x12, 0x00, 0x4d, 0x10, 0xb8, 0xff, 0xe8, 0xb3, 0x11, +0x00, 0x4d, 0x10, 0xb8, 0xff, 0xc8, 0xb3, 0x08, 0x00, 0x4d, +0x0f, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x0f, 0xb8, +0xff, 0xd0, 0x40, 0x39, 0x09, 0x00, 0x4d, 0x20, 0x0e, 0x01, +0x0f, 0x05, 0x1f, 0x05, 0x2f, 0x05, 0x03, 0x08, 0x05, 0x0e, +0x09, 0x0e, 0x78, 0x00, 0x05, 0x14, 0x00, 0x00, 0x05, 0x09, +0x09, 0x22, 0x76, 0x11, 0x27, 0x00, 0x00, 0x1b, 0x1b, 0x10, +0x06, 0x01, 0x06, 0x26, 0x24, 0x7c, 0x00, 0x0e, 0x0e, 0x08, +0x1c, 0x1c, 0x1f, 0x7c, 0x16, 0x46, 0x09, 0x05, 0x79, 0x08, +0x41, 0x00, 0x3f, 0xed, 0x32, 0x3f, 0xed, 0x32, 0x2f, 0x11, +0x39, 0x2f, 0x33, 0xed, 0x01, 0x10, 0xc6, 0x5d, 0x32, 0x2f, +0x32, 0x2f, 0x10, 0xde, 0xed, 0x33, 0x2f, 0x87, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x01, 0x5e, 0x5d, 0x5d, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x13, 0x3e, 0x03, 0x37, 0x21, 0x35, 0x21, 0x15, 0x0e, 0x03, +0x07, 0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, +0x02, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, +0x23, 0x23, 0xa6, 0x16, 0x31, 0x2f, 0x29, 0x0e, 0xfe, 0xe2, +0x01, 0x8c, 0x0e, 0x2a, 0x31, 0x35, 0x19, 0x5d, 0x68, 0x1e, +0x3e, 0x5e, 0x40, 0x23, 0x3c, 0x30, 0x24, 0x0a, 0x1a, 0x14, +0x56, 0x38, 0x51, 0x58, 0xc6, 0x11, 0x01, 0x5d, 0x16, 0x37, +0x37, 0x32, 0x12, 0x46, 0x31, 0x14, 0x34, 0x39, 0x3b, 0x1b, +0x07, 0x5e, 0x50, 0x29, 0x45, 0x32, 0x1b, 0x0a, 0x0e, 0x0f, +0x05, 0x44, 0x0b, 0x1e, 0x40, 0x39, 0x76, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x43, 0xff, 0xf3, 0x01, 0xce, 0x02, 0x6b, +0x00, 0x2c, 0x00, 0xd1, 0xb9, 0x00, 0x29, 0xff, 0xf0, 0xb3, +0x0a, 0x00, 0x4d, 0x29, 0xb8, 0xff, 0xe0, 0x40, 0x31, 0x09, +0x00, 0x4d, 0x1c, 0x20, 0x0a, 0x00, 0x4d, 0x1c, 0x28, 0x09, +0x00, 0x4d, 0x1b, 0x08, 0x12, 0x00, 0x4d, 0x1b, 0x10, 0x11, +0x00, 0x4d, 0x1b, 0x28, 0x08, 0x00, 0x4d, 0x17, 0x10, 0x11, +0x00, 0x4d, 0x17, 0x10, 0x0a, 0x00, 0x4d, 0x17, 0x18, 0x09, +0x00, 0x4d, 0x17, 0x20, 0x08, 0x00, 0x4d, 0x10, 0xb8, 0xff, +0xd8, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x10, 0xb8, 0xff, 0xe0, +0xb3, 0x10, 0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xf8, 0xb3, 0x10, +0x00, 0x4d, 0x08, 0xb8, 0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, +0x04, 0xb8, 0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x04, 0xb8, +0xff, 0xf0, 0x40, 0x2f, 0x0d, 0x0f, 0x00, 0x4c, 0x27, 0x1e, +0x23, 0x1e, 0x78, 0x2c, 0x27, 0x14, 0x2c, 0x27, 0x2c, 0x2c, +0x0f, 0x0f, 0x26, 0x2e, 0x23, 0x23, 0x06, 0x76, 0x00, 0x19, +0x01, 0x08, 0x19, 0x2d, 0x23, 0x27, 0x79, 0x24, 0x2c, 0x01, +0x7c, 0x1e, 0x1e, 0x24, 0x41, 0x0e, 0x0e, 0x09, 0x7c, 0x14, +0x46, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0x39, 0x2f, 0xed, +0x33, 0x10, 0xed, 0x32, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, +0x33, 0x2f, 0x10, 0xce, 0x32, 0x2f, 0x32, 0x2f, 0x87, 0x2b, +0x87, 0x7d, 0xc4, 0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x01, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, +0x16, 0x33, 0x32, 0x3e, 0x02, 0x37, 0x17, 0x0e, 0x03, 0x23, +0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x37, 0x2e, 0x03, +0x27, 0x35, 0x21, 0x15, 0x21, 0x1e, 0x03, 0x17, 0x01, 0x52, +0x11, 0x22, 0x3e, 0x30, 0x1c, 0x51, 0x42, 0x15, 0x2b, 0x25, +0x1e, 0x09, 0x1a, 0x09, 0x22, 0x2c, 0x35, 0x1b, 0x33, 0x54, +0x3c, 0x21, 0x1d, 0x30, 0x3f, 0x22, 0x16, 0x2e, 0x2c, 0x24, +0x0c, 0x01, 0x69, 0xff, 0x00, 0x0c, 0x24, 0x2a, 0x2b, 0x13, +0x01, 0x29, 0x0b, 0x1d, 0x2f, 0x24, 0x3d, 0x37, 0x06, 0x0a, +0x0c, 0x05, 0x44, 0x05, 0x0d, 0x0b, 0x07, 0x16, 0x2d, 0x46, +0x30, 0x2d, 0x40, 0x2c, 0x19, 0x05, 0x1b, 0x3a, 0x38, 0x33, +0x14, 0x34, 0x46, 0x12, 0x32, 0x37, 0x37, 0x16, 0x00, 0x00, +0x00, 0x01, 0x00, 0x3f, 0xff, 0x5b, 0x01, 0xc2, 0x01, 0xd0, +0x00, 0x28, 0x00, 0xaf, 0xb9, 0x00, 0x25, 0xff, 0xe0, 0x40, +0x3c, 0x09, 0x00, 0x4d, 0x18, 0x20, 0x0a, 0x00, 0x4d, 0x17, +0x10, 0x12, 0x00, 0x4d, 0x17, 0x18, 0x11, 0x00, 0x4d, 0x17, +0x10, 0x10, 0x00, 0x4d, 0x17, 0x28, 0x09, 0x00, 0x4d, 0x17, +0x20, 0x08, 0x00, 0x4d, 0x13, 0x10, 0x11, 0x12, 0x00, 0x4c, +0x13, 0x18, 0x10, 0x00, 0x4d, 0x13, 0x18, 0x09, 0x00, 0x4d, +0x13, 0x20, 0x08, 0x00, 0x4d, 0x12, 0x18, 0x10, 0x00, 0x4d, +0x08, 0xb8, 0xff, 0xe8, 0xb3, 0x0f, 0x00, 0x4d, 0x04, 0xb8, +0xff, 0xf0, 0x40, 0x2e, 0x0f, 0x00, 0x4d, 0x23, 0x1a, 0x1f, +0x1a, 0x81, 0x28, 0x23, 0x14, 0x28, 0x23, 0x28, 0x28, 0x0d, +0x0d, 0x22, 0x2a, 0x1f, 0x1f, 0x06, 0x82, 0x00, 0x15, 0x01, +0x08, 0x15, 0x29, 0x1f, 0x23, 0x85, 0x20, 0x28, 0x01, 0x89, +0x1a, 0x1a, 0x20, 0x49, 0x0c, 0x0c, 0x09, 0x89, 0x10, 0x4b, +0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0x39, 0x2f, 0xed, 0x33, +0x10, 0xed, 0x32, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x33, +0x2f, 0x10, 0xce, 0x32, 0x2f, 0x32, 0x2f, 0x87, 0x2b, 0x87, +0x7d, 0xc4, 0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, +0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, +0x37, 0x17, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, +0x3e, 0x02, 0x37, 0x2e, 0x03, 0x27, 0x35, 0x21, 0x15, 0x23, +0x1e, 0x03, 0x17, 0x01, 0x54, 0x0f, 0x22, 0x42, 0x33, 0x1f, +0x51, 0x48, 0x2b, 0x49, 0x14, 0x12, 0x16, 0x53, 0x31, 0x35, +0x56, 0x3d, 0x21, 0x1d, 0x32, 0x42, 0x26, 0x16, 0x2f, 0x2c, +0x26, 0x0c, 0x01, 0x5b, 0xf4, 0x0b, 0x25, 0x2a, 0x2c, 0x14, +0x8e, 0x09, 0x19, 0x2c, 0x23, 0x3a, 0x43, 0x10, 0x0a, 0x44, +0x0b, 0x10, 0x18, 0x30, 0x49, 0x30, 0x2c, 0x3d, 0x29, 0x17, +0x05, 0x19, 0x3a, 0x3a, 0x35, 0x14, 0x30, 0x45, 0x12, 0x32, +0x36, 0x37, 0x16, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x31, +0xff, 0x57, 0x01, 0xa7, 0x01, 0xd0, 0x00, 0x2c, 0x00, 0x94, +0xb9, 0x00, 0x1e, 0xff, 0xe0, 0xb4, 0x11, 0x12, 0x00, 0x4c, +0x1e, 0xb8, 0xff, 0xd0, 0xb3, 0x0d, 0x00, 0x4d, 0x19, 0xb8, +0xff, 0xd8, 0x40, 0x4c, 0x0a, 0x0b, 0x00, 0x4c, 0x0c, 0x28, +0x12, 0x00, 0x4d, 0x0c, 0x38, 0x11, 0x00, 0x4d, 0x08, 0x20, +0x10, 0x00, 0x4d, 0x02, 0x20, 0x0c, 0x0d, 0x00, 0x4c, 0x04, +0x17, 0x01, 0x11, 0x17, 0x15, 0x17, 0x81, 0x0e, 0x11, 0x14, +0x0e, 0x0e, 0x11, 0x15, 0x15, 0x0a, 0x82, 0x1c, 0x2e, 0x0e, +0x0e, 0x12, 0x26, 0x82, 0x00, 0x00, 0x00, 0x12, 0x01, 0x08, +0x12, 0x2d, 0x21, 0x11, 0x2a, 0x0e, 0x0d, 0x86, 0x06, 0x2a, +0x17, 0x17, 0x14, 0x2a, 0x4b, 0x15, 0x11, 0x85, 0x14, 0x49, +0x00, 0x3f, 0xed, 0x32, 0x3f, 0x12, 0x39, 0x2f, 0x12, 0x39, +0xed, 0x33, 0x11, 0x12, 0x39, 0x01, 0x10, 0xc6, 0x5e, 0x5d, +0x32, 0x2f, 0xed, 0x11, 0x33, 0x2f, 0x10, 0xde, 0xed, 0x33, +0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x5d, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x17, 0x34, +0x3e, 0x02, 0x37, 0x3e, 0x03, 0x35, 0x34, 0x26, 0x27, 0x35, +0x36, 0x36, 0x37, 0x23, 0x35, 0x21, 0x15, 0x06, 0x07, 0x1e, +0x03, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x0e, 0x03, 0x15, 0x14, +0x16, 0x17, 0x07, 0x26, 0x26, 0x31, 0x14, 0x23, 0x2d, 0x19, +0x20, 0x3b, 0x2e, 0x1b, 0x4e, 0x60, 0x2e, 0x4a, 0x16, 0xf4, +0x01, 0x59, 0x39, 0x61, 0x2b, 0x40, 0x2a, 0x15, 0x21, 0x3a, +0x4d, 0x2d, 0x0c, 0x1f, 0x1b, 0x12, 0x06, 0x02, 0x41, 0x05, +0x0b, 0x66, 0x1d, 0x26, 0x18, 0x0e, 0x06, 0x08, 0x0d, 0x15, +0x22, 0x1d, 0x28, 0x2b, 0x02, 0x38, 0x28, 0x4a, 0x1a, 0x45, +0x33, 0x4a, 0x56, 0x06, 0x15, 0x22, 0x32, 0x23, 0x2b, 0x35, +0x23, 0x14, 0x0a, 0x03, 0x07, 0x0e, 0x15, 0x11, 0x0e, 0x14, +0x05, 0x0e, 0x0b, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x39, +0x00, 0x00, 0x01, 0xbd, 0x02, 0x79, 0x00, 0x28, 0x00, 0xc2, +0x40, 0x16, 0x26, 0x10, 0x0e, 0x00, 0x4d, 0x26, 0x10, 0x08, +0x00, 0x4d, 0x25, 0x18, 0x09, 0x00, 0x4d, 0x1d, 0x18, 0x08, +0x09, 0x00, 0x4c, 0x17, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, +0x4d, 0x17, 0xb8, 0xff, 0xf0, 0xb3, 0x0d, 0x00, 0x4d, 0x14, +0xb8, 0xff, 0xe8, 0xb3, 0x0c, 0x00, 0x4d, 0x14, 0xb8, 0xff, +0xe0, 0xb4, 0x0a, 0x0b, 0x00, 0x4c, 0x14, 0xb8, 0xff, 0xc8, +0xb3, 0x09, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xd8, 0x40, 0x0a, +0x08, 0x00, 0x4d, 0x0f, 0x18, 0x09, 0x0a, 0x00, 0x4c, 0x0a, +0xb8, 0xff, 0xe0, 0x40, 0x37, 0x11, 0x12, 0x00, 0x4c, 0x06, +0x20, 0x11, 0x12, 0x00, 0x4c, 0x18, 0x1b, 0x15, 0x1f, 0x01, +0x27, 0x22, 0x04, 0x76, 0x15, 0x20, 0x20, 0x19, 0x19, 0x15, +0x2a, 0x1f, 0x76, 0x22, 0x28, 0x28, 0x0d, 0x0d, 0x00, 0x22, +0x01, 0x08, 0x22, 0x29, 0x1b, 0x27, 0x18, 0x01, 0x01, 0x12, +0x1f, 0x79, 0x22, 0x44, 0x0c, 0x0c, 0x07, 0x7c, 0x12, 0x45, +0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x11, 0x39, 0x2f, +0x33, 0xcd, 0x32, 0x01, 0x10, 0xc6, 0x5e, 0x5d, 0x32, 0x2f, +0x32, 0x2f, 0x10, 0xed, 0x10, 0xce, 0x32, 0x2f, 0x32, 0x2f, +0x10, 0xed, 0x11, 0x39, 0x39, 0x11, 0x12, 0x39, 0x39, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x33, 0x36, 0x36, 0x35, 0x34, +0x26, 0x23, 0x22, 0x0e, 0x02, 0x07, 0x27, 0x3e, 0x03, 0x33, +0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x33, 0x15, 0x23, 0x07, +0x06, 0x06, 0x07, 0x21, 0x15, 0x21, 0x26, 0x3e, 0x02, 0x37, +0x23, 0x5d, 0xa9, 0x20, 0x2b, 0x3c, 0x2a, 0x1e, 0x2d, 0x21, +0x17, 0x06, 0x29, 0x0d, 0x21, 0x2b, 0x37, 0x22, 0x5c, 0x5e, +0x1d, 0x1d, 0x4d, 0x89, 0x32, 0x26, 0x35, 0x02, 0x01, 0x1d, +0xfe, 0x89, 0x04, 0x12, 0x24, 0x31, 0x1b, 0x67, 0x01, 0x42, +0x20, 0x40, 0x28, 0x36, 0x30, 0x0e, 0x14, 0x13, 0x06, 0x3b, +0x0d, 0x1a, 0x15, 0x0d, 0x56, 0x53, 0x26, 0x45, 0x23, 0x40, +0x34, 0x26, 0x45, 0x1d, 0x46, 0x29, 0x47, 0x3f, 0x38, 0x1b, +0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0xff, 0xf3, 0x01, 0xba, +0x02, 0x6b, 0x00, 0x25, 0x00, 0x9a, 0x40, 0x18, 0x17, 0x18, +0x11, 0x12, 0x00, 0x4c, 0x17, 0x28, 0x0d, 0x0e, 0x00, 0x4c, +0x0b, 0x20, 0x11, 0x12, 0x00, 0x4c, 0x0a, 0x40, 0x10, 0x00, +0x4d, 0x06, 0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x05, +0xb8, 0xff, 0xd8, 0xb3, 0x10, 0x00, 0x4d, 0x05, 0xb8, 0xff, +0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe0, 0xb3, +0x08, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, +0x4d, 0x02, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x02, +0xb8, 0xff, 0xd8, 0x40, 0x23, 0x08, 0x00, 0x4d, 0x20, 0x20, +0x14, 0x76, 0x03, 0x27, 0x21, 0x00, 0x76, 0x1c, 0x19, 0x19, +0x0b, 0x0b, 0x1d, 0x26, 0x21, 0x1c, 0x79, 0x1e, 0x19, 0x7c, +0x00, 0x00, 0x1e, 0x41, 0x0c, 0x0c, 0x0f, 0x7c, 0x08, 0x46, +0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0x39, 0x2f, 0xed, 0x10, +0xed, 0x32, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x32, 0x2f, 0x33, +0xed, 0x32, 0x10, 0xde, 0xed, 0x33, 0x2f, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x13, 0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, +0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, +0x2e, 0x02, 0x23, 0x36, 0x36, 0x37, 0x23, 0x35, 0x21, 0x15, +0x23, 0x0e, 0x03, 0xba, 0x80, 0x80, 0x25, 0x3d, 0x51, 0x2b, +0x27, 0x50, 0x23, 0x0f, 0x19, 0x46, 0x25, 0x1c, 0x35, 0x29, +0x19, 0x1c, 0x3c, 0x60, 0x45, 0x07, 0x09, 0x04, 0x57, 0x01, +0x79, 0xd9, 0x01, 0x04, 0x04, 0x04, 0x01, 0x7c, 0x03, 0x6d, +0x5c, 0x32, 0x47, 0x2e, 0x16, 0x10, 0x10, 0x46, 0x0e, 0x11, +0x0c, 0x1b, 0x2b, 0x1f, 0x22, 0x35, 0x24, 0x13, 0x44, 0x6f, +0x39, 0x46, 0x46, 0x0c, 0x2e, 0x32, 0x2f, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb4, 0x01, 0xd0, +0x00, 0x23, 0x00, 0x9f, 0xb9, 0x00, 0x22, 0xff, 0xe8, 0xb3, +0x13, 0x00, 0x4d, 0x22, 0xb8, 0xff, 0xe0, 0xb3, 0x0c, 0x00, +0x4d, 0x22, 0xb8, 0xff, 0xe8, 0xb3, 0x0b, 0x00, 0x4d, 0x22, +0xb8, 0xff, 0xe0, 0xb4, 0x09, 0x0a, 0x00, 0x4c, 0x22, 0xb8, +0xff, 0xe8, 0x40, 0x0e, 0x08, 0x00, 0x4d, 0x13, 0x50, 0x12, +0x00, 0x4d, 0x13, 0x28, 0x11, 0x00, 0x4d, 0x01, 0xb8, 0xff, +0xe0, 0xb3, 0x13, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xf0, 0xb3, +0x0b, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xe0, 0xb3, 0x0a, 0x00, +0x4d, 0x01, 0xb8, 0xff, 0xe8, 0x40, 0x24, 0x08, 0x09, 0x00, +0x4c, 0x1c, 0x1c, 0x11, 0x82, 0x00, 0x25, 0x1d, 0x1e, 0x82, +0x18, 0x15, 0x15, 0x08, 0x08, 0x19, 0x24, 0x14, 0x89, 0x1e, +0x1e, 0x0e, 0x1d, 0x18, 0x86, 0x1a, 0x49, 0x09, 0x09, 0x0e, +0x88, 0x03, 0x51, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, +0x32, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xc6, 0x32, 0x2f, +0x32, 0x2f, 0x33, 0xed, 0x32, 0x10, 0xde, 0xed, 0x33, 0x2f, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x25, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x02, +0x27, 0x37, 0x1e, 0x03, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, +0x23, 0x23, 0x36, 0x36, 0x37, 0x23, 0x35, 0x21, 0x15, 0x23, +0x07, 0x33, 0x32, 0x1e, 0x02, 0x01, 0xb4, 0x68, 0x64, 0x19, +0x33, 0x2c, 0x20, 0x06, 0x0f, 0x05, 0x1c, 0x27, 0x2e, 0x17, +0x39, 0x42, 0x5b, 0x67, 0x2d, 0x06, 0x09, 0x02, 0x49, 0x01, +0x67, 0xd6, 0x0a, 0x13, 0x30, 0x52, 0x3c, 0x22, 0x8c, 0x43, +0x54, 0x06, 0x09, 0x08, 0x03, 0x46, 0x03, 0x08, 0x09, 0x06, +0x26, 0x2b, 0x2f, 0x26, 0x33, 0x4f, 0x2b, 0x42, 0x42, 0x6d, +0x10, 0x24, 0x39, 0x00, 0x00, 0x01, 0x00, 0x3e, 0xff, 0xf5, +0x01, 0xce, 0x02, 0x60, 0x00, 0x24, 0x00, 0xd0, 0x40, 0x20, +0x1a, 0x28, 0x12, 0x00, 0x4d, 0x1a, 0x18, 0x0c, 0x00, 0x4d, +0x11, 0x20, 0x11, 0x12, 0x00, 0x4c, 0x11, 0x28, 0x10, 0x00, +0x4d, 0x11, 0x20, 0x0f, 0x00, 0x4d, 0x11, 0x28, 0x0e, 0x00, +0x4d, 0x0c, 0xb8, 0xff, 0xf0, 0xb3, 0x0c, 0x00, 0x4d, 0x0c, +0xb8, 0xff, 0xe8, 0xb3, 0x0b, 0x00, 0x4d, 0x0c, 0xb8, 0xff, +0xe0, 0xb3, 0x0a, 0x00, 0x4d, 0x0c, 0xb8, 0xff, 0xc8, 0xb3, +0x09, 0x00, 0x4d, 0x0c, 0xb8, 0xff, 0xd8, 0xb3, 0x08, 0x00, +0x4d, 0x09, 0xb8, 0xff, 0xd0, 0xb3, 0x12, 0x00, 0x4d, 0x09, +0xb8, 0xff, 0xe0, 0xb3, 0x11, 0x00, 0x4d, 0x09, 0xb8, 0xff, +0xd0, 0xb3, 0x0d, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xb0, 0xb3, +0x11, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, +0x4d, 0x07, 0xb8, 0xff, 0xf8, 0x40, 0x28, 0x11, 0x00, 0x4d, +0x00, 0x03, 0x7f, 0x22, 0x1f, 0x1f, 0x20, 0x17, 0x82, 0x0b, +0x02, 0x02, 0x0b, 0x26, 0x11, 0x11, 0x00, 0x20, 0x01, 0x08, +0x20, 0x25, 0x23, 0x24, 0x4d, 0x03, 0x1f, 0x85, 0x00, 0x22, +0x49, 0x12, 0x12, 0x15, 0x88, 0x0e, 0x51, 0x00, 0x3f, 0xed, +0x32, 0x2f, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0x33, 0x01, 0x10, +0xc6, 0x5e, 0x5d, 0x32, 0x2f, 0x10, 0xce, 0x32, 0x2f, 0x10, +0xed, 0x11, 0x39, 0x2f, 0x33, 0xed, 0x32, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x33, 0x15, 0x23, +0x15, 0x14, 0x1e, 0x04, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, +0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x35, 0x34, 0x2e, 0x04, +0x35, 0x35, 0x23, 0x35, 0x33, 0x35, 0x37, 0xf2, 0xbc, 0xbc, +0x21, 0x30, 0x3a, 0x30, 0x21, 0x62, 0x6a, 0x30, 0x50, 0x24, +0x10, 0x23, 0x4d, 0x2b, 0x73, 0x21, 0x30, 0x3a, 0x30, 0x21, +0x62, 0x62, 0x52, 0x01, 0xd0, 0x45, 0x1f, 0x25, 0x29, 0x19, +0x12, 0x1e, 0x31, 0x2b, 0x3f, 0x45, 0x10, 0x10, 0x4b, 0x10, +0x15, 0x39, 0x1b, 0x1e, 0x14, 0x14, 0x24, 0x3d, 0x34, 0x21, +0x45, 0x82, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x47, +0xff, 0x5b, 0x01, 0xce, 0x01, 0xda, 0x00, 0x0b, 0x00, 0x19, +0x00, 0x68, 0xb9, 0x00, 0x19, 0xff, 0xe8, 0x40, 0x45, 0x08, +0x09, 0x00, 0x4c, 0x0a, 0x20, 0x11, 0x12, 0x00, 0x4c, 0x0a, +0x28, 0x0f, 0x00, 0x4d, 0x0a, 0x10, 0x0e, 0x00, 0x4d, 0x0a, +0x08, 0x0d, 0x00, 0x4d, 0x09, 0x10, 0x0a, 0x00, 0x4d, 0x08, +0x20, 0x11, 0x12, 0x00, 0x4c, 0x02, 0x28, 0x10, 0x00, 0x4d, +0x02, 0x18, 0x0f, 0x00, 0x4d, 0x00, 0x82, 0x0c, 0x1b, 0x07, +0x11, 0x7f, 0x00, 0x13, 0x01, 0x08, 0x13, 0x1a, 0x03, 0x88, +0x17, 0x50, 0x07, 0x88, 0x11, 0x11, 0x13, 0x4b, 0x00, 0x3f, +0x33, 0x2f, 0xed, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0x5e, 0x5d, +0xed, 0x32, 0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x34, 0x26, 0x23, +0x22, 0x06, 0x07, 0x11, 0x3e, 0x03, 0x37, 0x14, 0x0e, 0x02, +0x07, 0x15, 0x23, 0x11, 0x36, 0x36, 0x33, 0x32, 0x16, 0x01, +0x79, 0x45, 0x3f, 0x26, 0x28, 0x0d, 0x27, 0x50, 0x40, 0x28, +0x55, 0x31, 0x54, 0x70, 0x3f, 0x53, 0x1d, 0x57, 0x3b, 0x65, +0x73, 0x01, 0x0c, 0x3e, 0x47, 0x0a, 0x05, 0xfe, 0x9c, 0x0f, +0x24, 0x36, 0x4d, 0x36, 0x47, 0x65, 0x49, 0x33, 0x14, 0x73, +0x02, 0x5b, 0x0b, 0x19, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0xd4, 0xff, 0x5b, 0x01, 0x21, 0x02, 0xbb, 0x02, 0x06, +0x00, 0x5f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x79, 0xff, 0x5b, +0x01, 0x7c, 0x02, 0xbb, 0x02, 0x36, 0x00, 0x5f, 0xa5, 0x00, +0x00, 0x06, 0x00, 0x5f, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x23, 0xff, 0x5b, 0x01, 0xd0, 0x02, 0xbb, 0x00, 0x13, +0x00, 0x53, 0x40, 0x2c, 0x11, 0x0d, 0x0c, 0x04, 0x08, 0x06, +0x02, 0x09, 0x7f, 0x13, 0x0f, 0x00, 0x0c, 0x01, 0x0c, 0x0c, +0x15, 0x14, 0x05, 0x10, 0x86, 0x13, 0x02, 0x13, 0x09, 0x0c, +0x86, 0x0f, 0x06, 0x0f, 0x0f, 0x13, 0x1f, 0x13, 0x02, 0x08, +0x13, 0x0f, 0x13, 0x0f, 0x0b, 0x4b, 0x00, 0x53, 0x00, 0x3f, +0x3f, 0x39, 0x39, 0x2f, 0x2f, 0x5e, 0x5d, 0x11, 0x33, 0x10, +0xed, 0x32, 0x11, 0x33, 0x10, 0xed, 0x32, 0x01, 0x11, 0x12, +0x39, 0x2f, 0x5d, 0x33, 0x33, 0xfd, 0x32, 0x32, 0xcd, 0x32, +0x10, 0xcd, 0x32, 0x31, 0x30, 0x13, 0x33, 0x11, 0x33, 0x15, +0x23, 0x15, 0x33, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, +0x33, 0x35, 0x23, 0x35, 0x33, 0xd3, 0x4d, 0xb0, 0xb0, 0xb0, +0xb0, 0x4d, 0xb0, 0xb0, 0xb0, 0xb0, 0x02, 0xbb, 0xfe, 0xca, +0x42, 0x69, 0x42, 0xfe, 0xc3, 0x01, 0x3d, 0x42, 0x69, 0x42, +0x00, 0x00, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf4, 0x01, 0x3b, +0x02, 0x6b, 0x02, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, +0x00, 0x1b, 0xff, 0xfb, 0x01, 0xf3, 0x03, 0x31, 0x00, 0x05, +0x00, 0x17, 0x00, 0x28, 0x00, 0x34, 0x00, 0x81, 0x40, 0x42, +0x2e, 0x76, 0x1d, 0x34, 0x73, 0x40, 0x26, 0x04, 0x04, 0x05, +0x02, 0x05, 0x00, 0x00, 0x60, 0x05, 0x05, 0x06, 0x15, 0x15, +0x0f, 0x0b, 0x14, 0x0f, 0x14, 0x7e, 0x06, 0x0b, 0x14, 0x06, +0x06, 0x0b, 0x0f, 0x0f, 0x0c, 0x06, 0x06, 0x0c, 0x2c, 0x7c, +0x22, 0x42, 0x31, 0x7c, 0x18, 0x41, 0x06, 0x14, 0x79, 0x16, +0x40, 0x04, 0x00, 0x00, 0x03, 0x01, 0x80, 0x02, 0x05, 0x16, +0x41, 0x0f, 0x0b, 0x79, 0x0e, 0x44, 0x00, 0x3f, 0xed, 0x32, +0x3f, 0xde, 0x32, 0x1a, 0xcd, 0x32, 0x32, 0x11, 0x33, 0x1a, +0x10, 0xed, 0x32, 0x3f, 0xed, 0x3f, 0xed, 0x01, 0x2f, 0x33, +0x2f, 0x11, 0x33, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x01, 0x11, 0x33, 0x18, 0x2f, 0x12, 0x39, 0x19, 0x2f, 0x1a, +0xcd, 0x18, 0x2f, 0x11, 0x33, 0x19, 0x10, 0xcd, 0x18, 0x2f, +0x2f, 0x1a, 0xed, 0xdc, 0xed, 0x31, 0x30, 0x01, 0x37, 0x17, +0x37, 0x17, 0x07, 0x17, 0x0e, 0x03, 0x07, 0x33, 0x15, 0x23, +0x35, 0x3e, 0x03, 0x37, 0x23, 0x35, 0x33, 0x25, 0x32, 0x1e, +0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x11, +0x36, 0x36, 0x13, 0x16, 0x32, 0x33, 0x32, 0x35, 0x34, 0x26, +0x23, 0x22, 0x22, 0x07, 0x01, 0x0d, 0x1d, 0x56, 0x56, 0x1d, +0x73, 0x5f, 0x0d, 0x20, 0x22, 0x1f, 0x0c, 0x7a, 0xc2, 0x11, +0x1c, 0x1b, 0x1e, 0x13, 0x63, 0xac, 0xfe, 0x8a, 0x2d, 0x3f, +0x28, 0x12, 0x0b, 0x24, 0x42, 0x37, 0x11, 0x29, 0x12, 0x17, +0x25, 0x0b, 0x05, 0x08, 0x05, 0x53, 0x2a, 0x2b, 0x04, 0x07, +0x05, 0x03, 0x10, 0x21, 0x4e, 0x4e, 0x21, 0x79, 0x6c, 0x2c, +0x79, 0x84, 0x85, 0x37, 0x46, 0x36, 0x49, 0x7a, 0x73, 0x75, +0x44, 0x46, 0x06, 0x2c, 0x52, 0x75, 0x49, 0x33, 0x6e, 0x5d, +0x3c, 0x04, 0x05, 0x02, 0x63, 0x06, 0x04, 0xfd, 0xd2, 0x01, +0xf3, 0x7d, 0x78, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x1b, +0xff, 0xfb, 0x01, 0xfd, 0x02, 0x89, 0x00, 0x05, 0x00, 0x17, +0x00, 0x28, 0x00, 0x34, 0x00, 0xb0, 0x40, 0x15, 0x30, 0x20, +0x10, 0x00, 0x4d, 0x30, 0x18, 0x0f, 0x00, 0x4d, 0x2d, 0x28, +0x10, 0x00, 0x4d, 0x2d, 0x20, 0x0f, 0x00, 0x4d, 0x21, 0xb8, +0xff, 0xd0, 0xb3, 0x12, 0x00, 0x4d, 0x21, 0xb8, 0xff, 0xd8, +0xb3, 0x11, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xd8, 0xb3, 0x12, +0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe8, 0x40, 0x3f, 0x11, 0x00, +0x4d, 0x2e, 0x76, 0x1d, 0x34, 0x73, 0x40, 0x26, 0x05, 0x03, +0x01, 0x60, 0x00, 0x00, 0x06, 0x15, 0x15, 0x0f, 0x0b, 0x14, +0x0f, 0x14, 0x84, 0x06, 0x0b, 0x14, 0x06, 0x06, 0x0b, 0x0f, +0x0c, 0x06, 0x06, 0x0c, 0x2c, 0x7c, 0x22, 0x42, 0x31, 0x7c, +0x18, 0x41, 0x06, 0x14, 0x85, 0x16, 0x05, 0x01, 0x40, 0x04, +0x02, 0x80, 0x03, 0x00, 0x16, 0x49, 0x0f, 0x0b, 0x85, 0x0e, +0x4c, 0x00, 0x3f, 0xed, 0x32, 0x3f, 0xde, 0xcd, 0x1a, 0xdd, +0x32, 0x1a, 0xcd, 0x32, 0x10, 0xed, 0x32, 0x3f, 0xed, 0x3f, +0xed, 0x01, 0x2f, 0x33, 0x2f, 0x10, 0xcd, 0x87, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x01, 0x11, 0x33, 0x18, 0x2f, 0x12, 0x39, +0x19, 0x2f, 0x1a, 0xcd, 0x33, 0xcd, 0x18, 0x2f, 0x1a, 0xed, +0xdc, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x01, 0x27, 0x37, 0x17, 0x37, 0x17, 0x07, 0x0e, +0x03, 0x07, 0x33, 0x15, 0x23, 0x35, 0x3e, 0x03, 0x37, 0x23, +0x35, 0x33, 0x25, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x26, 0x27, 0x11, 0x36, 0x36, 0x13, 0x16, 0x32, +0x33, 0x32, 0x35, 0x34, 0x26, 0x23, 0x22, 0x22, 0x07, 0x01, +0x9d, 0x61, 0x1e, 0x43, 0x42, 0x1e, 0x1b, 0x09, 0x1b, 0x1e, +0x1c, 0x0a, 0x68, 0xac, 0x0a, 0x1c, 0x1d, 0x1d, 0x0b, 0x62, +0xa3, 0xfe, 0x87, 0x2d, 0x3f, 0x28, 0x12, 0x0b, 0x24, 0x42, +0x37, 0x11, 0x29, 0x12, 0x17, 0x25, 0x0b, 0x05, 0x08, 0x05, +0x53, 0x2a, 0x2b, 0x04, 0x07, 0x05, 0x02, 0x0c, 0x59, 0x24, +0x36, 0x36, 0x24, 0xd3, 0x18, 0x4c, 0x5a, 0x61, 0x2d, 0x46, +0x37, 0x28, 0x5f, 0x5d, 0x54, 0x1c, 0x45, 0xa1, 0x2c, 0x52, +0x75, 0x49, 0x33, 0x6e, 0x5d, 0x3c, 0x04, 0x05, 0x02, 0x63, +0x06, 0x04, 0xfd, 0xd2, 0x01, 0xf3, 0x7d, 0x78, 0x01, 0x00, +0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0xff, 0xf5, 0x01, 0xfd, +0x02, 0xb5, 0x00, 0x05, 0x00, 0x13, 0x00, 0x26, 0x00, 0x38, +0x00, 0x99, 0xb6, 0x20, 0x18, 0x0a, 0x0b, 0x00, 0x4c, 0x10, +0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, 0x10, 0xb8, 0xff, +0xf0, 0xb3, 0x11, 0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xe8, 0x40, +0x43, 0x12, 0x00, 0x4d, 0x05, 0x03, 0x01, 0x60, 0x00, 0x00, +0x27, 0x36, 0x36, 0x30, 0x2c, 0x35, 0x30, 0x35, 0x84, 0x27, +0x2c, 0x14, 0x27, 0x27, 0x2c, 0x30, 0x2d, 0x27, 0x27, 0x2d, +0x26, 0x13, 0x7f, 0x16, 0x0e, 0x7f, 0x1e, 0x05, 0x01, 0x40, +0x04, 0x02, 0x80, 0x03, 0x00, 0x35, 0x85, 0x37, 0x49, 0x30, +0x4e, 0x2c, 0x85, 0x2f, 0x4c, 0x27, 0x49, 0x09, 0x89, 0x23, +0x50, 0x11, 0x89, 0x19, 0x51, 0x14, 0x15, 0x4d, 0x00, 0x3f, +0x33, 0x3f, 0xed, 0x3f, 0xed, 0x3f, 0x3f, 0xed, 0x3f, 0x3f, +0xed, 0xde, 0xcd, 0x1a, 0xdd, 0x32, 0x1a, 0xcd, 0x32, 0x01, +0x2f, 0xed, 0xdc, 0xed, 0x32, 0x2f, 0x33, 0x2f, 0x10, 0xcd, +0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x11, 0x33, 0x18, +0x2f, 0x12, 0x39, 0x19, 0x2f, 0x1a, 0xcd, 0x33, 0xcd, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x27, 0x37, 0x17, 0x37, +0x17, 0x05, 0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, +0x16, 0x33, 0x32, 0x37, 0x11, 0x37, 0x11, 0x06, 0x06, 0x23, +0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, +0x17, 0x05, 0x0e, 0x03, 0x07, 0x33, 0x15, 0x23, 0x35, 0x3e, +0x03, 0x37, 0x23, 0x35, 0x33, 0x01, 0x9d, 0x61, 0x1e, 0x43, +0x42, 0x1e, 0xfe, 0xbf, 0x07, 0x1c, 0x0f, 0x0d, 0x16, 0x11, +0x09, 0x29, 0x1c, 0x1c, 0x0e, 0x48, 0x11, 0x3a, 0x27, 0x24, +0x35, 0x23, 0x11, 0x15, 0x22, 0x2c, 0x17, 0x14, 0x21, 0x08, +0x01, 0x2f, 0x09, 0x1b, 0x1e, 0x1c, 0x0a, 0x68, 0xac, 0x0a, +0x1c, 0x1d, 0x1d, 0x0b, 0x62, 0xa3, 0x02, 0x0c, 0x59, 0x24, +0x36, 0x36, 0x24, 0xed, 0x0d, 0x11, 0x10, 0x28, 0x43, 0x33, +0x61, 0x56, 0x07, 0x02, 0x6f, 0x0e, 0xfd, 0x58, 0x08, 0x10, +0x23, 0x41, 0x59, 0x36, 0x46, 0x5d, 0x38, 0x18, 0x12, 0x0a, +0x2d, 0x18, 0x4c, 0x5a, 0x61, 0x2d, 0x46, 0x37, 0x28, 0x5f, +0x5d, 0x54, 0x1c, 0x45, 0x00, 0x00, 0x00, 0x02, 0x00, 0x24, +0x00, 0x00, 0x01, 0xd9, 0x02, 0x6b, 0x00, 0x0c, 0x00, 0x12, +0x00, 0x29, 0x40, 0x15, 0x00, 0x05, 0x73, 0x08, 0x14, 0x0d, +0x12, 0x73, 0x0f, 0x13, 0x06, 0x10, 0x41, 0x12, 0x79, 0x0f, +0x44, 0x00, 0x7c, 0x0c, 0x44, 0x00, 0x3f, 0xed, 0x3f, 0xed, +0x3f, 0x33, 0x01, 0x10, 0xd6, 0xfd, 0xcd, 0x10, 0xde, 0xfd, +0xce, 0x31, 0x30, 0x25, 0x16, 0x3e, 0x02, 0x35, 0x11, 0x33, +0x11, 0x14, 0x06, 0x23, 0x23, 0x27, 0x15, 0x23, 0x11, 0x33, +0x11, 0x01, 0x25, 0x24, 0x28, 0x13, 0x03, 0x52, 0x44, 0x5a, +0x16, 0x29, 0xd8, 0x52, 0x45, 0x01, 0x0f, 0x1f, 0x2e, 0x1f, +0x01, 0xac, 0xfe, 0x2f, 0x4b, 0x4f, 0x46, 0x46, 0x02, 0x6b, +0xfd, 0xdb, 0x00, 0x00, 0x00, 0x03, 0x00, 0x36, 0xff, 0x59, +0x01, 0xd8, 0x02, 0x97, 0x00, 0x05, 0x00, 0x11, 0x00, 0x21, +0x00, 0x34, 0x40, 0x1b, 0x0f, 0x09, 0x09, 0x15, 0x1c, 0x73, +0x1f, 0x23, 0x00, 0x05, 0x73, 0x02, 0x22, 0x0c, 0x06, 0x1d, +0x49, 0x19, 0x88, 0x12, 0x4b, 0x03, 0x41, 0x05, 0x79, 0x02, +0x44, 0x00, 0x3f, 0xed, 0x3f, 0x3f, 0xed, 0x3f, 0xde, 0xcd, +0x01, 0x10, 0xd6, 0xfd, 0xcd, 0x10, 0xde, 0xfd, 0xcc, 0x33, +0x2f, 0xcd, 0x31, 0x30, 0x25, 0x15, 0x23, 0x11, 0x33, 0x11, +0x01, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, +0x14, 0x06, 0x03, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, +0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x06, 0x01, 0x28, +0xf2, 0x52, 0x01, 0x16, 0x17, 0x22, 0x22, 0x17, 0x19, 0x21, +0x21, 0x8f, 0x0b, 0x22, 0x0b, 0x0b, 0x09, 0x17, 0x0a, 0x2b, +0x25, 0x52, 0x51, 0x46, 0x46, 0x02, 0x6b, 0xfd, 0xdb, 0x01, +0xd9, 0x20, 0x1c, 0x1b, 0x21, 0x21, 0x1b, 0x1c, 0x20, 0xfd, +0x3a, 0x05, 0x05, 0x44, 0x03, 0x04, 0x35, 0x33, 0x01, 0xc8, +0xfe, 0x39, 0x5a, 0x56, 0x00, 0x03, 0x00, 0x63, 0xff, 0x59, +0x01, 0xa2, 0x02, 0xb5, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x27, +0x00, 0x36, 0x40, 0x1c, 0x15, 0x0f, 0x0f, 0x1b, 0x22, 0x7f, +0x25, 0x29, 0x0b, 0x06, 0x7f, 0x03, 0x28, 0x12, 0x0c, 0x23, +0x49, 0x1f, 0x88, 0x18, 0x4b, 0x04, 0x05, 0x4d, 0x0b, 0x88, +0x00, 0x51, 0x00, 0x3f, 0xed, 0x3f, 0x33, 0x3f, 0xed, 0x3f, +0xde, 0xcd, 0x01, 0x10, 0xd6, 0xfd, 0xce, 0x10, 0xde, 0xfd, +0xcc, 0x33, 0x2f, 0xcd, 0x31, 0x30, 0x17, 0x26, 0x26, 0x35, +0x11, 0x37, 0x11, 0x14, 0x1e, 0x02, 0x17, 0x13, 0x22, 0x26, +0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x03, +0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, +0x11, 0x33, 0x11, 0x14, 0x06, 0xdd, 0x43, 0x37, 0x52, 0x05, +0x0c, 0x14, 0x0f, 0x80, 0x17, 0x22, 0x22, 0x17, 0x18, 0x21, +0x21, 0x8e, 0x0b, 0x22, 0x0b, 0x0a, 0x09, 0x17, 0x0a, 0x2b, +0x26, 0x52, 0x51, 0x09, 0x02, 0x3e, 0x42, 0x02, 0x2e, 0x0e, +0xfd, 0xd2, 0x15, 0x1a, 0x10, 0x08, 0x03, 0x01, 0xe2, 0x20, +0x1c, 0x1b, 0x21, 0x21, 0x1b, 0x1c, 0x20, 0xfd, 0x3a, 0x05, +0x05, 0x44, 0x03, 0x04, 0x35, 0x33, 0x01, 0xc8, 0xfe, 0x39, +0x5a, 0x56, 0x00, 0x00, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00, +0x01, 0xd9, 0x02, 0x6b, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x39, +0x40, 0x1d, 0x00, 0x05, 0x08, 0x19, 0x16, 0x11, 0x12, 0x14, +0x17, 0x10, 0x0c, 0x0f, 0x18, 0x11, 0x16, 0x44, 0x13, 0x41, +0x17, 0x10, 0x41, 0x0e, 0x44, 0x00, 0x7c, 0x0b, 0x44, 0x06, +0x41, 0x00, 0x3f, 0x3f, 0xed, 0x3f, 0x3f, 0x33, 0x3f, 0x3f, +0x33, 0x01, 0x10, 0xd6, 0xcd, 0x32, 0x32, 0xdc, 0xcd, 0x32, +0x32, 0x10, 0xde, 0xdd, 0xce, 0x31, 0x30, 0x25, 0x32, 0x3e, +0x02, 0x35, 0x11, 0x33, 0x11, 0x14, 0x06, 0x23, 0x27, 0x15, +0x23, 0x11, 0x33, 0x13, 0x27, 0x35, 0x33, 0x11, 0x23, 0x03, +0x01, 0x3d, 0x1f, 0x22, 0x11, 0x03, 0x47, 0x46, 0x56, 0xdb, +0x3e, 0x42, 0x77, 0x09, 0x3e, 0x42, 0x77, 0x45, 0x0f, 0x1e, +0x2e, 0x1f, 0x01, 0xac, 0xfe, 0x2f, 0x4b, 0x4f, 0xfb, 0xfb, +0x02, 0x6b, 0xfe, 0x4c, 0xb7, 0xfd, 0xfd, 0x95, 0x01, 0xb4, +0x00, 0x03, 0x00, 0x24, 0xff, 0x59, 0x01, 0xdc, 0x02, 0x97, +0x00, 0x0b, 0x00, 0x1a, 0x00, 0x26, 0x00, 0x73, 0xb5, 0x26, +0x60, 0x12, 0x00, 0x4d, 0x20, 0xb8, 0xff, 0xa0, 0x40, 0x3c, +0x12, 0x00, 0x4d, 0x25, 0x1f, 0x20, 0x1f, 0x84, 0x26, 0x25, +0x14, 0x26, 0x26, 0x25, 0x20, 0x21, 0x24, 0x0f, 0x0f, 0x24, +0x40, 0x0e, 0x13, 0x48, 0x24, 0x15, 0x09, 0x83, 0x03, 0x03, +0x15, 0x73, 0x18, 0x28, 0x26, 0x1c, 0x50, 0x1d, 0x01, 0x1d, +0x27, 0x20, 0x25, 0x44, 0x22, 0x41, 0x26, 0x1f, 0x41, 0x1d, +0x44, 0x06, 0x8a, 0x00, 0x16, 0x49, 0x12, 0x88, 0x0c, 0x4b, +0x00, 0x3f, 0xed, 0x3f, 0xde, 0xed, 0x3f, 0x3f, 0x33, 0x3f, +0x3f, 0x33, 0x01, 0x10, 0xd6, 0x5d, 0xcd, 0x32, 0x10, 0xde, +0xed, 0x32, 0x2f, 0xed, 0x10, 0xce, 0x2b, 0x32, 0x2f, 0x10, +0xcd, 0x32, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, +0x00, 0x2b, 0x2b, 0x01, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, +0x32, 0x16, 0x15, 0x14, 0x06, 0x03, 0x22, 0x26, 0x27, 0x37, +0x16, 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x06, +0x01, 0x15, 0x23, 0x11, 0x33, 0x13, 0x27, 0x35, 0x33, 0x11, +0x23, 0x03, 0x01, 0xa3, 0x17, 0x22, 0x22, 0x17, 0x18, 0x21, +0x21, 0x8a, 0x0b, 0x22, 0x0b, 0x0b, 0x13, 0x17, 0x2b, 0x27, +0x47, 0x48, 0xfe, 0xe3, 0x3e, 0x42, 0x77, 0x09, 0x3e, 0x42, +0x77, 0x02, 0x1f, 0x20, 0x1c, 0x1b, 0x21, 0x21, 0x1b, 0x1c, +0x20, 0xfd, 0x3a, 0x05, 0x05, 0x44, 0x07, 0x35, 0x33, 0x01, +0xc8, 0xfe, 0x39, 0x5a, 0x56, 0x01, 0xa2, 0xfb, 0x02, 0x6b, +0xfe, 0x4c, 0xb7, 0xfd, 0xfd, 0x95, 0x01, 0xb4, 0x00, 0x00, +0x00, 0x03, 0x00, 0x24, 0xff, 0x59, 0x01, 0xd8, 0x02, 0x97, +0x00, 0x15, 0x00, 0x21, 0x00, 0x31, 0x00, 0x4d, 0xb9, 0x00, +0x06, 0xff, 0xd8, 0x40, 0x29, 0x09, 0x10, 0x00, 0x4c, 0x1f, +0x19, 0x19, 0x2c, 0x25, 0x25, 0x0b, 0x7f, 0xaf, 0x08, 0xbf, +0x08, 0x02, 0x08, 0x2c, 0x7f, 0x2f, 0x33, 0x13, 0x7f, 0x00, +0x32, 0x1c, 0x16, 0x2d, 0x49, 0x29, 0x88, 0x22, 0x4b, 0x0a, +0x15, 0x4c, 0x10, 0x88, 0x03, 0x50, 0x00, 0x3f, 0xed, 0x3f, +0x33, 0x3f, 0xed, 0x3f, 0xde, 0xcd, 0x01, 0x10, 0xd6, 0xed, +0x10, 0xd6, 0xfd, 0xde, 0x5d, 0xed, 0x32, 0x2f, 0x11, 0x33, +0x2f, 0xcd, 0x31, 0x30, 0x2b, 0x13, 0x36, 0x36, 0x33, 0x32, +0x1e, 0x02, 0x15, 0x11, 0x23, 0x11, 0x34, 0x2e, 0x02, 0x23, +0x22, 0x06, 0x07, 0x11, 0x23, 0x01, 0x22, 0x26, 0x35, 0x34, +0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x03, 0x22, 0x26, +0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, +0x11, 0x14, 0x06, 0x24, 0x20, 0x3f, 0x1c, 0x20, 0x30, 0x21, +0x11, 0x4b, 0x0a, 0x10, 0x15, 0x0c, 0x08, 0x1b, 0x09, 0x4b, +0x01, 0x7a, 0x17, 0x22, 0x22, 0x17, 0x19, 0x21, 0x21, 0x8f, +0x0b, 0x22, 0x0b, 0x0b, 0x09, 0x1c, 0x0a, 0x2b, 0x27, 0x4b, +0x51, 0x01, 0xc3, 0x0b, 0x0c, 0x0d, 0x25, 0x45, 0x38, 0xfe, +0xd5, 0x01, 0x1e, 0x27, 0x2d, 0x18, 0x07, 0x05, 0x04, 0xfe, +0x78, 0x02, 0x1f, 0x20, 0x1c, 0x1b, 0x21, 0x21, 0x1b, 0x1c, +0x20, 0xfd, 0x3a, 0x05, 0x05, 0x44, 0x03, 0x04, 0x35, 0x33, +0x01, 0xc8, 0xfe, 0x39, 0x5a, 0x56, 0x00, 0x00, 0xff, 0xff, +0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x03, 0x3d, 0x02, 0x26, +0x00, 0x24, 0x00, 0x00, 0x01, 0x07, 0x01, 0x5f, 0x00, 0x00, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x17, 0x1b, +0x04, 0x0f, 0x50, 0x02, 0x09, 0x1c, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb0, +0x02, 0xb2, 0x02, 0x26, 0x00, 0x44, 0x00, 0x00, 0x01, 0x06, +0x01, 0x5f, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x05, +0x31, 0x35, 0x1c, 0x13, 0x50, 0x02, 0x0f, 0x36, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x59, 0x00, 0x00, 0x01, 0x9b, +0x03, 0x3d, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x07, +0x01, 0x5f, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x00, 0x0c, 0x10, 0x04, 0x02, 0x50, 0x01, 0x09, 0x11, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x36, +0xff, 0xf5, 0x01, 0xc2, 0x02, 0xb2, 0x02, 0x26, 0x01, 0x0c, +0x00, 0x00, 0x01, 0x06, 0x01, 0x5f, 0xdd, 0x00, 0x00, 0x13, +0xb9, 0x00, 0x01, 0xff, 0xdb, 0x40, 0x09, 0x16, 0x1a, 0x01, +0x0b, 0x50, 0x01, 0x02, 0x1b, 0x4f, 0x2b, 0x2b, 0x34, 0x00, +0xff, 0xff, 0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, 0x03, 0x3d, +0x02, 0x26, 0x00, 0x32, 0x00, 0x00, 0x01, 0x07, 0x01, 0x5f, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, +0x20, 0x24, 0x00, 0x09, 0x50, 0x02, 0x04, 0x25, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, +0x01, 0xcc, 0x02, 0xb2, 0x02, 0x26, 0x00, 0x52, 0x00, 0x00, +0x01, 0x06, 0x01, 0x5f, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, +0x02, 0x00, 0x20, 0x24, 0x09, 0x00, 0x50, 0x02, 0x0e, 0x25, +0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x30, 0xff, 0xf3, +0x01, 0xc4, 0x03, 0x3d, 0x02, 0x26, 0x00, 0x38, 0x00, 0x00, +0x01, 0x07, 0x01, 0x5f, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x00, 0x1a, 0x1e, 0x04, 0x14, 0x50, 0x01, +0x06, 0x1f, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x44, 0xff, 0xf6, 0x01, 0xad, 0x02, 0xb2, 0x02, 0x26, +0x00, 0x58, 0x00, 0x00, 0x01, 0x06, 0x01, 0x5f, 0x00, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x01, 0x16, 0x1a, 0x07, 0x00, +0x50, 0x01, 0x09, 0x1b, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x04, +0x00, 0x30, 0xff, 0xf3, 0x01, 0xc4, 0x03, 0x3d, 0x00, 0x0b, +0x00, 0x17, 0x00, 0x1b, 0x00, 0x35, 0x00, 0x57, 0x40, 0x31, +0x09, 0x80, 0x03, 0x90, 0x03, 0x02, 0x03, 0x03, 0x1b, 0x0f, +0x15, 0x40, 0x10, 0x13, 0x48, 0x15, 0x40, 0x09, 0x0c, 0x48, +0x15, 0x15, 0x1a, 0x1b, 0x1a, 0x1b, 0x1a, 0x21, 0x2e, 0x73, +0x31, 0x37, 0x24, 0x73, 0x21, 0x36, 0x18, 0x1b, 0x12, 0x06, +0x0c, 0x00, 0x2f, 0x22, 0x41, 0x29, 0x7c, 0x1c, 0x46, 0x00, +0x3f, 0xed, 0x3f, 0x33, 0xde, 0x32, 0xdd, 0x32, 0xde, 0xcd, +0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, 0x12, 0x39, 0x39, +0x2f, 0x2f, 0x11, 0x33, 0x2f, 0x2b, 0x2b, 0xcd, 0x11, 0x33, +0x2f, 0x5d, 0xcd, 0x31, 0x30, 0x13, 0x22, 0x26, 0x35, 0x34, +0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x33, 0x22, 0x26, +0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x27, +0x33, 0x15, 0x23, 0x13, 0x22, 0x2e, 0x02, 0x35, 0x11, 0x33, +0x11, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x11, +0x33, 0x11, 0x14, 0x0e, 0x02, 0xa0, 0x15, 0x1b, 0x1b, 0x15, +0x15, 0x1b, 0x1b, 0x9f, 0x14, 0x1c, 0x1c, 0x14, 0x14, 0x1c, +0x1c, 0xdf, 0xe2, 0xe2, 0x71, 0x37, 0x4d, 0x30, 0x16, 0x52, +0x11, 0x1f, 0x2c, 0x1c, 0x1c, 0x2c, 0x1f, 0x11, 0x52, 0x16, +0x30, 0x4d, 0x02, 0x87, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, +0x16, 0x1b, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, +0xb6, 0x39, 0xfc, 0xef, 0x20, 0x3a, 0x54, 0x34, 0x01, 0x82, +0xfe, 0x87, 0x2f, 0x3f, 0x26, 0x10, 0x10, 0x26, 0x3f, 0x2f, +0x01, 0x79, 0xfe, 0x7e, 0x34, 0x54, 0x3a, 0x20, 0xff, 0xff, +0x00, 0x44, 0xff, 0xf6, 0x01, 0xad, 0x02, 0xcc, 0x02, 0x26, +0x00, 0x58, 0x00, 0x00, 0x01, 0x06, 0x02, 0xa7, 0x00, 0x00, +0x00, 0x1e, 0x40, 0x15, 0x03, 0x02, 0x01, 0x01, 0x18, 0x2a, +0x07, 0x00, 0x50, 0x03, 0x09, 0x30, 0x4f, 0x02, 0x09, 0x22, +0x4f, 0x01, 0x09, 0x16, 0x4f, 0x2b, 0x2b, 0x2b, 0x2b, 0x34, +0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x30, 0xff, 0xf3, +0x01, 0xc4, 0x03, 0x3e, 0x02, 0x26, 0x00, 0x38, 0x00, 0x00, +0x01, 0x06, 0x02, 0xb1, 0x00, 0x00, 0x00, 0x1e, 0x40, 0x15, +0x03, 0x02, 0x01, 0x00, 0x2c, 0x26, 0x04, 0x14, 0x50, 0x03, +0x06, 0x2a, 0x4f, 0x02, 0x06, 0x1e, 0x4f, 0x01, 0x06, 0x1b, +0x4f, 0x2b, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x44, 0xff, 0xf6, 0x01, 0xad, 0x02, 0xfb, +0x02, 0x26, 0x00, 0x58, 0x00, 0x00, 0x01, 0x06, 0x02, 0xaa, +0x00, 0x00, 0x00, 0x1e, 0x40, 0x15, 0x03, 0x02, 0x01, 0x01, +0x18, 0x2a, 0x07, 0x00, 0x50, 0x03, 0x09, 0x30, 0x4f, 0x02, +0x09, 0x22, 0x4f, 0x01, 0x09, 0x16, 0x4f, 0x2b, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x30, +0xff, 0xf3, 0x01, 0xc4, 0x03, 0x3e, 0x02, 0x26, 0x00, 0x38, +0x00, 0x00, 0x01, 0x06, 0x02, 0xb2, 0x00, 0x00, 0x00, 0x1e, +0x40, 0x15, 0x03, 0x02, 0x01, 0x00, 0x1c, 0x2e, 0x04, 0x14, +0x50, 0x03, 0x06, 0x37, 0x4f, 0x02, 0x06, 0x26, 0x4f, 0x01, +0x06, 0x1a, 0x4f, 0x2b, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x44, 0xff, 0xf6, 0x01, 0xad, +0x02, 0xe6, 0x02, 0x26, 0x00, 0x58, 0x00, 0x00, 0x01, 0x06, +0x02, 0xab, 0x00, 0x00, 0x00, 0x1e, 0x40, 0x15, 0x03, 0x02, +0x01, 0x01, 0x18, 0x2a, 0x07, 0x00, 0x50, 0x03, 0x09, 0x33, +0x4f, 0x02, 0x09, 0x22, 0x4f, 0x01, 0x09, 0x16, 0x4f, 0x2b, +0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x30, 0xff, 0xf3, 0x01, 0xc4, 0x03, 0x3e, 0x02, 0x26, +0x00, 0x38, 0x00, 0x00, 0x01, 0x06, 0x02, 0xb0, 0x00, 0x00, +0x00, 0x1e, 0x40, 0x15, 0x03, 0x02, 0x01, 0x00, 0x20, 0x32, +0x04, 0x14, 0x50, 0x03, 0x06, 0x2a, 0x4f, 0x02, 0x06, 0x1e, +0x4f, 0x01, 0x06, 0x1c, 0x4f, 0x2b, 0x2b, 0x2b, 0x2b, 0x34, +0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x44, 0xff, 0xf6, +0x01, 0xad, 0x02, 0xfb, 0x02, 0x26, 0x00, 0x58, 0x00, 0x00, +0x01, 0x06, 0x02, 0xa9, 0x00, 0x00, 0x00, 0x1e, 0x40, 0x15, +0x03, 0x02, 0x01, 0x01, 0x18, 0x2a, 0x07, 0x00, 0x50, 0x03, +0x09, 0x30, 0x4f, 0x02, 0x09, 0x22, 0x4f, 0x01, 0x09, 0x16, +0x4f, 0x2b, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, +0x00, 0x02, 0x00, 0x2d, 0xff, 0xf5, 0x01, 0xcc, 0x01, 0xdb, +0x00, 0x1a, 0x00, 0x23, 0x00, 0x5f, 0xb9, 0x00, 0x1d, 0xff, +0xf0, 0x40, 0x3a, 0x0f, 0x10, 0x00, 0x4c, 0x09, 0x20, 0x10, +0x00, 0x4d, 0x09, 0x20, 0x0d, 0x0e, 0x00, 0x4c, 0x02, 0x10, +0x13, 0x14, 0x00, 0x4c, 0x01, 0x20, 0x12, 0x00, 0x4d, 0x01, +0x18, 0x11, 0x00, 0x4d, 0x23, 0x07, 0x82, 0x16, 0x25, 0x0e, +0x0e, 0x03, 0x24, 0x1b, 0x82, 0x04, 0x07, 0x86, 0x23, 0x23, +0x00, 0x0d, 0x0d, 0x0a, 0x88, 0x11, 0x50, 0x1e, 0x88, 0x00, +0x51, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, +0x2f, 0xed, 0x01, 0x2f, 0xed, 0x10, 0xc6, 0x32, 0x2f, 0x10, +0xde, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x17, 0x22, 0x26, 0x35, 0x34, 0x34, 0x37, 0x21, 0x26, +0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, +0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x27, 0x06, 0x16, 0x33, +0x32, 0x3e, 0x02, 0x37, 0xf1, 0x5e, 0x66, 0x01, 0x01, 0x47, +0x05, 0x50, 0x4e, 0x2c, 0x3e, 0x10, 0x0b, 0x0f, 0x4e, 0x31, +0x3c, 0x5b, 0x3c, 0x1e, 0x26, 0x3e, 0x4f, 0x96, 0x01, 0x3d, +0x33, 0x1d, 0x2d, 0x21, 0x13, 0x03, 0x0b, 0x75, 0x77, 0x05, +0x12, 0x07, 0x48, 0x4b, 0x0f, 0x07, 0x45, 0x08, 0x12, 0x25, +0x40, 0x59, 0x34, 0x3e, 0x5b, 0x3d, 0x1e, 0xc7, 0x39, 0x48, +0x16, 0x24, 0x2f, 0x18, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, +0x01, 0xeb, 0x03, 0x3d, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x1b, +0x00, 0x2b, 0x00, 0x32, 0x00, 0x89, 0x40, 0x46, 0x1a, 0x1a, +0x15, 0x0f, 0x09, 0x1e, 0x2f, 0x2d, 0x2c, 0x25, 0x1f, 0x2c, +0x1f, 0x78, 0x20, 0x25, 0x14, 0x20, 0x20, 0x25, 0x1d, 0x30, +0x2c, 0x26, 0x1c, 0x2c, 0x1c, 0x78, 0x2b, 0x26, 0x14, 0x2b, +0x2b, 0x26, 0x1b, 0x1b, 0x03, 0x09, 0x09, 0x2c, 0x2c, 0x20, +0x2b, 0x34, 0x20, 0x33, 0x1c, 0x2b, 0x44, 0x1d, 0x1e, 0x79, +0x30, 0x2f, 0x2f, 0x25, 0x20, 0x18, 0x1b, 0x12, 0x06, 0x0c, +0x00, 0x2c, 0x26, 0x25, 0x41, 0x1f, 0x20, 0x44, 0x00, 0x3f, +0x33, 0x3f, 0x33, 0x33, 0xde, 0x32, 0xdd, 0x32, 0xde, 0xcd, +0x11, 0x12, 0x39, 0x2f, 0x33, 0xed, 0x32, 0x3f, 0x33, 0x01, +0x10, 0xc6, 0x10, 0xce, 0x11, 0x39, 0x11, 0x33, 0x2f, 0xcd, +0x32, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x10, 0xc4, +0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x10, 0x0e, +0xc4, 0x05, 0xc4, 0xc4, 0x01, 0x18, 0x10, 0xde, 0xcd, 0x32, +0x2f, 0x31, 0x30, 0x13, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, +0x32, 0x16, 0x15, 0x14, 0x06, 0x33, 0x22, 0x26, 0x35, 0x34, +0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x27, 0x33, 0x15, +0x23, 0x01, 0x27, 0x23, 0x07, 0x23, 0x3e, 0x03, 0x37, 0x33, +0x1e, 0x03, 0x17, 0x03, 0x06, 0x06, 0x07, 0x33, 0x26, 0x26, +0xa0, 0x15, 0x1b, 0x1b, 0x15, 0x15, 0x1b, 0x1b, 0x9f, 0x14, +0x1c, 0x1c, 0x14, 0x14, 0x1c, 0x1c, 0xdf, 0xe2, 0xe2, 0x01, +0x0b, 0x2a, 0xe5, 0x28, 0x54, 0x11, 0x2a, 0x31, 0x36, 0x1e, +0x66, 0x1d, 0x35, 0x2f, 0x2a, 0x11, 0xf2, 0x17, 0x32, 0x18, +0xbf, 0x17, 0x30, 0x02, 0x87, 0x1b, 0x16, 0x17, 0x1a, 0x1a, +0x17, 0x16, 0x1b, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, +0x1b, 0xb6, 0x39, 0xfc, 0xfc, 0xa2, 0xa2, 0x42, 0x94, 0x9a, +0x9d, 0x4a, 0x4a, 0x9d, 0x9a, 0x94, 0x42, 0x02, 0x0f, 0x3f, +0x92, 0x58, 0x5a, 0x93, 0x00, 0x00, 0xff, 0xff, 0x00, 0x3a, +0xff, 0xf5, 0x01, 0xb0, 0x02, 0xcc, 0x02, 0x26, 0x00, 0x44, +0x00, 0x00, 0x01, 0x06, 0x02, 0xa7, 0x00, 0x00, 0x00, 0x1e, +0x40, 0x15, 0x04, 0x03, 0x02, 0x05, 0x33, 0x45, 0x1c, 0x13, +0x50, 0x04, 0x0f, 0x4b, 0x4f, 0x03, 0x0f, 0x3d, 0x4f, 0x02, +0x0f, 0x31, 0x4f, 0x2b, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x34, +0x00, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, +0x03, 0x3d, 0x00, 0x0f, 0x00, 0x16, 0x00, 0x22, 0x00, 0x26, +0x00, 0x7f, 0x40, 0x40, 0x25, 0x26, 0x26, 0x20, 0x1a, 0x1a, +0x02, 0x13, 0x11, 0x10, 0x09, 0x03, 0x10, 0x03, 0x78, 0x04, +0x09, 0x14, 0x04, 0x04, 0x09, 0x01, 0x14, 0x10, 0x0a, 0x00, +0x10, 0x00, 0x78, 0x0f, 0x0a, 0x14, 0x0f, 0x0f, 0x0a, 0x10, +0x10, 0x04, 0x0f, 0x28, 0x04, 0x27, 0x23, 0x26, 0x1d, 0x17, +0x09, 0x01, 0x02, 0x79, 0x14, 0x13, 0x13, 0x03, 0x10, 0x0a, +0x09, 0x41, 0x04, 0x03, 0x44, 0x0f, 0x00, 0x44, 0x00, 0x3f, +0x32, 0x3f, 0x33, 0x3f, 0x33, 0x33, 0x12, 0x39, 0x2f, 0x33, +0xed, 0x32, 0x10, 0xde, 0xdd, 0xde, 0xcd, 0x01, 0x10, 0xc6, +0x10, 0xce, 0x11, 0x39, 0x3d, 0x2f, 0x87, 0x18, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x10, 0xc4, 0xc4, 0x87, 0x18, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x10, 0x0e, 0xc4, 0x05, 0xc4, 0xc4, 0x01, +0x33, 0x18, 0x2f, 0xcd, 0x33, 0x2f, 0xcd, 0x31, 0x30, 0x21, +0x27, 0x23, 0x07, 0x23, 0x3e, 0x03, 0x37, 0x33, 0x1e, 0x03, +0x17, 0x03, 0x06, 0x06, 0x07, 0x33, 0x26, 0x26, 0x27, 0x22, +0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, +0x27, 0x33, 0x15, 0x23, 0x01, 0x94, 0x2a, 0xe5, 0x28, 0x54, +0x11, 0x2a, 0x31, 0x36, 0x1e, 0x66, 0x1d, 0x35, 0x2f, 0x2a, +0x11, 0xf2, 0x17, 0x32, 0x18, 0xbf, 0x17, 0x30, 0x16, 0x15, +0x1c, 0x1c, 0x15, 0x15, 0x1c, 0x1c, 0x86, 0xe2, 0xe2, 0xa2, +0xa2, 0x42, 0x94, 0x9a, 0x9d, 0x4a, 0x4a, 0x9d, 0x9a, 0x94, +0x42, 0x02, 0x0f, 0x3f, 0x92, 0x58, 0x5a, 0x93, 0xb4, 0x1b, +0x17, 0x17, 0x1b, 0x1b, 0x17, 0x17, 0x1b, 0xb6, 0x39, 0x00, +0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb0, 0x02, 0xcc, +0x02, 0x26, 0x00, 0x44, 0x00, 0x00, 0x01, 0x06, 0x02, 0xa8, +0x00, 0x00, 0x00, 0x17, 0x40, 0x10, 0x03, 0x02, 0x05, 0x3d, +0x3e, 0x1c, 0x13, 0x50, 0x03, 0x0f, 0x3f, 0x4f, 0x02, 0x0f, +0x31, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, +0x00, 0x1b, 0x00, 0x00, 0x01, 0xe2, 0x03, 0x06, 0x02, 0x26, +0x00, 0xa1, 0x00, 0x00, 0x01, 0x07, 0x00, 0x8a, 0x00, 0x59, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x54, 0x17, 0x18, +0x04, 0x10, 0x50, 0x02, 0x07, 0x19, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xf5, 0x01, 0xde, +0x02, 0x7b, 0x02, 0x26, 0x00, 0xc1, 0x00, 0x00, 0x01, 0x06, +0x00, 0x8a, 0x09, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x03, 0x04, +0x4c, 0x4d, 0x21, 0x07, 0x50, 0x03, 0x00, 0x4e, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x01, 0x00, 0x2e, 0xff, 0xf3, 0x01, 0xda, +0x02, 0x79, 0x00, 0x2d, 0x00, 0xc1, 0xb9, 0x00, 0x28, 0xff, +0xe0, 0xb3, 0x12, 0x00, 0x4d, 0x28, 0xb8, 0xff, 0xd8, 0xb3, +0x11, 0x00, 0x4d, 0x28, 0xb8, 0xff, 0xf0, 0xb4, 0x0b, 0x0c, +0x00, 0x4c, 0x27, 0xb8, 0xff, 0xf0, 0xb3, 0x10, 0x00, 0x4d, +0x23, 0xb8, 0xff, 0xf8, 0xb3, 0x10, 0x00, 0x4d, 0x22, 0xb8, +0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x22, 0xb8, 0xff, 0xf0, +0xb3, 0x11, 0x00, 0x4d, 0x22, 0xb8, 0xff, 0xe8, 0xb3, 0x0c, +0x00, 0x4d, 0x22, 0xb8, 0xff, 0xf0, 0xb3, 0x0b, 0x00, 0x4d, +0x1a, 0xb8, 0xff, 0xe8, 0xb4, 0x0f, 0x12, 0x00, 0x4c, 0x1a, +0xb8, 0xff, 0xe0, 0xb3, 0x0e, 0x00, 0x4d, 0x1a, 0xb8, 0xff, +0xe8, 0x40, 0x31, 0x0d, 0x00, 0x4d, 0x0f, 0x18, 0x0e, 0x00, +0x4d, 0x0f, 0x10, 0x0d, 0x00, 0x4d, 0x03, 0x01, 0x00, 0x73, +0x09, 0x1c, 0x1c, 0x07, 0x06, 0x09, 0x2f, 0x25, 0x76, 0x12, +0x2e, 0x1d, 0x1d, 0x20, 0x7c, 0x17, 0x09, 0x01, 0x79, 0x02, +0x06, 0x02, 0x04, 0x02, 0x04, 0x02, 0x17, 0x45, 0x2a, 0x7c, +0x0d, 0x46, 0x00, 0x3f, 0xed, 0x3f, 0x39, 0x39, 0x2f, 0x2f, +0x11, 0x33, 0x10, 0xed, 0x32, 0x10, 0xed, 0x32, 0x2f, 0x01, +0x10, 0xd6, 0xed, 0x10, 0xde, 0x32, 0xcd, 0x33, 0x2f, 0x10, +0xfd, 0xcd, 0x33, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, +0x23, 0x35, 0x33, 0x35, 0x33, 0x15, 0x33, 0x15, 0x23, 0x15, +0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, +0x33, 0x32, 0x1e, 0x02, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, +0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x36, 0x37, +0x01, 0x5b, 0x47, 0x47, 0x53, 0x2c, 0x2c, 0x13, 0x50, 0x34, +0x35, 0x55, 0x3e, 0x21, 0x26, 0x40, 0x57, 0x31, 0x20, 0x30, +0x22, 0x16, 0x06, 0x1b, 0x15, 0x3a, 0x20, 0x23, 0x3a, 0x2a, +0x17, 0x15, 0x28, 0x3b, 0x26, 0x19, 0x1b, 0x07, 0xae, 0x41, +0x56, 0x56, 0x41, 0x9f, 0x07, 0x15, 0x2b, 0x52, 0x79, 0x4d, +0x4e, 0x78, 0x52, 0x2b, 0x0a, 0x0e, 0x0f, 0x04, 0x45, 0x12, +0x17, 0x24, 0x42, 0x5d, 0x39, 0x38, 0x5c, 0x42, 0x25, 0x08, +0x04, 0x00, 0x00, 0x02, 0x00, 0x28, 0xff, 0x58, 0x01, 0xe2, +0x01, 0xdb, 0x00, 0x22, 0x00, 0x35, 0x00, 0x98, 0xb9, 0x00, +0x30, 0xff, 0xf0, 0xb3, 0x0e, 0x00, 0x4d, 0x2b, 0xb8, 0xff, +0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x2b, 0xb8, 0xff, 0xf0, 0xb3, +0x0d, 0x00, 0x4d, 0x2b, 0xb8, 0xff, 0xe8, 0x40, 0x4c, 0x0c, +0x00, 0x4d, 0x20, 0x18, 0x11, 0x12, 0x00, 0x4c, 0x20, 0x10, +0x10, 0x00, 0x4d, 0x0b, 0x18, 0x0f, 0x10, 0x00, 0x4c, 0x06, +0x18, 0x0f, 0x10, 0x00, 0x4c, 0x05, 0x10, 0x11, 0x12, 0x00, +0x4c, 0x05, 0x18, 0x0f, 0x10, 0x00, 0x4c, 0x26, 0x24, 0x23, +0x22, 0x7f, 0x13, 0x11, 0x15, 0x37, 0x2d, 0x82, 0x08, 0x1b, +0x1b, 0x08, 0x36, 0x14, 0x23, 0x26, 0x11, 0x26, 0x32, 0x88, +0x03, 0x26, 0x03, 0x26, 0x03, 0x0d, 0x36, 0x1f, 0x88, 0x18, +0x4b, 0x2a, 0x88, 0x0d, 0x50, 0x00, 0x3f, 0xed, 0x3f, 0xed, +0x11, 0x12, 0x39, 0x39, 0x2f, 0x2f, 0x10, 0xed, 0x11, 0x33, +0x10, 0xcd, 0x32, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xed, +0x10, 0xde, 0x32, 0xce, 0xfd, 0x32, 0xcc, 0x33, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x25, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, +0x02, 0x33, 0x32, 0x16, 0x17, 0x15, 0x33, 0x15, 0x23, 0x15, +0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, +0x32, 0x36, 0x35, 0x35, 0x23, 0x35, 0x33, 0x35, 0x26, 0x26, +0x23, 0x22, 0x06, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x36, +0x37, 0x01, 0x49, 0x0d, 0x36, 0x23, 0x27, 0x44, 0x33, 0x1d, +0x1b, 0x35, 0x4c, 0x32, 0x39, 0x50, 0x1c, 0x47, 0x47, 0x68, +0x6a, 0x2a, 0x45, 0x1a, 0x0f, 0x19, 0x3e, 0x25, 0x43, 0x3b, +0x5a, 0x5a, 0x0c, 0x26, 0x20, 0x3c, 0x3e, 0x12, 0x1e, 0x27, +0x16, 0x1c, 0x33, 0x10, 0x2b, 0x08, 0x12, 0x1b, 0x37, 0x55, +0x3a, 0x33, 0x55, 0x3e, 0x23, 0x11, 0x08, 0xaf, 0x3d, 0xb2, +0x6c, 0x60, 0x0e, 0x0a, 0x49, 0x0b, 0x0e, 0x3a, 0x41, 0xbb, +0x3d, 0x74, 0x04, 0x07, 0x58, 0x49, 0x28, 0x39, 0x25, 0x11, +0x12, 0x0c, 0xff, 0xff, 0x00, 0x2e, 0xff, 0xf3, 0x01, 0xc7, +0x03, 0x3d, 0x02, 0x26, 0x00, 0x2a, 0x00, 0x00, 0x01, 0x07, +0x01, 0x5f, 0x00, 0x36, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x35, 0x26, 0x2a, 0x09, 0x01, 0x50, 0x01, 0x0e, 0x2b, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x28, +0xff, 0x58, 0x01, 0xad, 0x02, 0xb2, 0x02, 0x26, 0x00, 0x4a, +0x00, 0x00, 0x01, 0x06, 0x01, 0x5f, 0x12, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x02, 0x21, 0x2e, 0x32, 0x07, 0x10, 0x50, 0x02, +0x0c, 0x33, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x40, +0x00, 0x00, 0x01, 0xeb, 0x03, 0x3d, 0x02, 0x26, 0x00, 0x2e, +0x00, 0x00, 0x01, 0x07, 0x01, 0x5f, 0x00, 0x00, 0x00, 0x8b, +0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xe5, 0x40, 0x09, 0x17, +0x1b, 0x10, 0x08, 0x50, 0x01, 0x00, 0x1c, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x2b, 0x00, 0x00, +0x01, 0xde, 0x03, 0x3e, 0x00, 0x16, 0x00, 0x1c, 0x00, 0x85, +0x40, 0x45, 0x06, 0x00, 0x05, 0x00, 0x81, 0x0b, 0x06, 0x14, +0x0b, 0x00, 0x14, 0x0b, 0x06, 0x13, 0x10, 0x00, 0x14, 0x13, +0x14, 0x00, 0x81, 0x10, 0x13, 0x14, 0x10, 0x13, 0x00, 0x10, +0x14, 0x14, 0x05, 0x1e, 0x40, 0x1c, 0x1b, 0x17, 0x60, 0x19, +0x19, 0x10, 0x0b, 0x7f, 0x00, 0x0d, 0x01, 0x08, 0x0d, 0x1d, +0x0b, 0x10, 0x05, 0x14, 0x49, 0x1b, 0x17, 0x40, 0x1a, 0x18, +0x80, 0x19, 0x1c, 0x0e, 0x0f, 0x4d, 0x0d, 0x4a, 0x05, 0x06, +0x4a, 0x00, 0x3f, 0x33, 0x3f, 0x3f, 0x33, 0xde, 0xcd, 0x1a, +0xdd, 0x32, 0x1a, 0xcd, 0x32, 0x3f, 0x12, 0x39, 0x39, 0x01, +0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x32, 0x19, 0x2f, 0x1a, +0xcd, 0xcd, 0x33, 0x1a, 0x18, 0x10, 0xce, 0x32, 0x2f, 0x10, +0xc1, 0x87, 0x04, 0x2b, 0x10, 0x00, 0xc1, 0x87, 0x05, 0x7d, +0x10, 0xc4, 0x87, 0x08, 0x18, 0x10, 0x2b, 0x87, 0x05, 0x7d, +0xc4, 0x31, 0x30, 0x37, 0x1e, 0x03, 0x17, 0x23, 0x2e, 0x03, +0x27, 0x15, 0x23, 0x11, 0x37, 0x11, 0x36, 0x36, 0x37, 0x33, +0x06, 0x06, 0x03, 0x37, 0x17, 0x37, 0x17, 0x07, 0xee, 0x1b, +0x44, 0x43, 0x3c, 0x12, 0x62, 0x13, 0x38, 0x3f, 0x3f, 0x19, +0x53, 0x53, 0x37, 0x6e, 0x2c, 0x61, 0x2b, 0x79, 0xfd, 0x1a, +0x54, 0x54, 0x1a, 0x6e, 0xff, 0x14, 0x3d, 0x46, 0x49, 0x1f, +0x1f, 0x41, 0x3c, 0x32, 0x11, 0xdf, 0x02, 0x89, 0x0e, 0xfe, +0x77, 0x30, 0x5f, 0x33, 0x33, 0x6c, 0x01, 0xe5, 0x28, 0x36, +0x36, 0x28, 0x55, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1d, +0xff, 0x59, 0x01, 0xd8, 0x02, 0x79, 0x00, 0x24, 0x00, 0x30, +0x00, 0xb3, 0xb9, 0x00, 0x2f, 0xff, 0xf0, 0xb3, 0x0e, 0x00, +0x4d, 0x2f, 0xb8, 0xff, 0xf8, 0x40, 0x14, 0x0d, 0x00, 0x4d, +0x2d, 0x18, 0x0e, 0x00, 0x4d, 0x2d, 0x10, 0x0d, 0x00, 0x4d, +0x29, 0x10, 0x0d, 0x0e, 0x00, 0x4c, 0x27, 0xb8, 0xff, 0xf0, +0xb4, 0x0d, 0x0e, 0x00, 0x4c, 0x17, 0xb8, 0xff, 0xd8, 0xb4, +0x08, 0x0c, 0x00, 0x4c, 0x13, 0xb8, 0xff, 0xe8, 0xb4, 0x08, +0x0c, 0x00, 0x4c, 0x12, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, +0x4d, 0x12, 0xb8, 0xff, 0xf0, 0x40, 0x3f, 0x0f, 0x00, 0x4d, +0x0e, 0x18, 0x0f, 0x10, 0x00, 0x4c, 0x0d, 0x18, 0x08, 0x0c, +0x00, 0x4c, 0x08, 0x10, 0x10, 0x00, 0x4d, 0x08, 0x20, 0x0f, +0x00, 0x4d, 0x08, 0x18, 0x08, 0x0c, 0x00, 0x4c, 0x06, 0x03, +0x23, 0x1a, 0x1d, 0x1d, 0x25, 0x2b, 0x76, 0x15, 0x32, 0x25, +0x76, 0x0b, 0x40, 0x0b, 0x10, 0x48, 0x0b, 0x31, 0x1f, 0x00, +0x31, 0x2e, 0x7c, 0x10, 0x45, 0x28, 0x7c, 0x1a, 0x06, 0x46, +0x00, 0x3f, 0x33, 0xed, 0x3f, 0xed, 0x10, 0xdc, 0xcd, 0x01, +0x10, 0xd6, 0x2b, 0xed, 0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, +0x33, 0xcc, 0xcd, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x05, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37, 0x2e, 0x03, +0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, +0x06, 0x07, 0x0e, 0x03, 0x15, 0x14, 0x33, 0x32, 0x36, 0x37, +0x17, 0x06, 0x03, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, +0x26, 0x23, 0x22, 0x06, 0x01, 0x24, 0x33, 0x2f, 0x21, 0x11, +0x30, 0x50, 0x38, 0x1f, 0x20, 0x3b, 0x51, 0x32, 0x31, 0x51, +0x3b, 0x20, 0x37, 0x2f, 0x09, 0x21, 0x20, 0x18, 0x24, 0x06, +0x14, 0x0b, 0x06, 0x16, 0xd8, 0x43, 0x45, 0x46, 0x45, 0x45, +0x46, 0x45, 0x43, 0xa7, 0x24, 0x20, 0x17, 0x2e, 0x11, 0x01, +0x28, 0x50, 0x78, 0x52, 0x53, 0x7a, 0x4f, 0x27, 0x27, 0x4f, +0x7a, 0x53, 0x6e, 0x8c, 0x24, 0x07, 0x18, 0x1e, 0x20, 0x0e, +0x1a, 0x03, 0x03, 0x36, 0x0a, 0x01, 0xdd, 0x7a, 0x82, 0x82, +0x7a, 0x7a, 0x82, 0x82, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, +0xff, 0x59, 0x01, 0xcc, 0x01, 0xdb, 0x00, 0x27, 0x00, 0x33, +0x00, 0xc6, 0x40, 0x0c, 0x32, 0x20, 0x0f, 0x10, 0x00, 0x4c, +0x32, 0x18, 0x0e, 0x00, 0x4d, 0x30, 0xb8, 0xff, 0xe0, 0xb4, +0x0f, 0x10, 0x00, 0x4c, 0x30, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, +0x00, 0x4d, 0x2c, 0xb8, 0xff, 0xe0, 0xb4, 0x0f, 0x10, 0x00, +0x4c, 0x2c, 0xb8, 0xff, 0xf0, 0x40, 0x13, 0x0e, 0x00, 0x4d, +0x2a, 0x28, 0x10, 0x00, 0x4d, 0x2a, 0x20, 0x0f, 0x00, 0x4d, +0x2a, 0x10, 0x0e, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xf0, 0xb4, +0x11, 0x12, 0x00, 0x4c, 0x1a, 0xb8, 0xff, 0xd8, 0xb3, 0x0a, +0x00, 0x4d, 0x19, 0xb8, 0xff, 0xe0, 0xb4, 0x08, 0x09, 0x00, +0x4c, 0x15, 0xb8, 0xff, 0xe8, 0x40, 0x0b, 0x08, 0x09, 0x00, +0x4c, 0x0f, 0x18, 0x08, 0x09, 0x00, 0x4c, 0x0b, 0xb8, 0xff, +0xf0, 0x40, 0x2b, 0x10, 0x00, 0x4d, 0x0a, 0x18, 0x08, 0x09, +0x00, 0x4c, 0x08, 0x03, 0x20, 0x26, 0x26, 0x1c, 0x20, 0x20, +0x2e, 0x28, 0x82, 0x17, 0x35, 0x2e, 0x82, 0x0d, 0x40, 0x09, +0x0c, 0x48, 0x0d, 0x34, 0x22, 0x00, 0x34, 0x2b, 0x88, 0x12, +0x50, 0x31, 0x88, 0x1c, 0x08, 0x51, 0x00, 0x3f, 0x33, 0xed, +0x3f, 0xed, 0x10, 0xdc, 0xcd, 0x01, 0x10, 0xd6, 0x2b, 0xed, +0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, 0x33, 0x33, 0x2f, 0x10, +0xcd, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x05, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, 0x2e, +0x03, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, +0x14, 0x06, 0x07, 0x06, 0x06, 0x07, 0x06, 0x06, 0x15, 0x14, +0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x13, 0x34, 0x26, 0x23, +0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x01, 0x16, +0x33, 0x30, 0x17, 0x10, 0x08, 0x08, 0x2a, 0x47, 0x34, 0x1d, +0x1f, 0x38, 0x4d, 0x2d, 0x2e, 0x4e, 0x38, 0x1f, 0x34, 0x2d, +0x17, 0x25, 0x12, 0x0d, 0x0e, 0x24, 0x06, 0x14, 0x0a, 0x07, +0x17, 0x3d, 0x44, 0x3a, 0x39, 0x43, 0x43, 0x39, 0x3a, 0x44, +0xa7, 0x24, 0x20, 0x15, 0x25, 0x11, 0x08, 0x06, 0x03, 0x26, +0x3f, 0x56, 0x34, 0x37, 0x5a, 0x3f, 0x23, 0x23, 0x3f, 0x5a, +0x37, 0x48, 0x6b, 0x1f, 0x0e, 0x18, 0x13, 0x0e, 0x15, 0x0d, +0x1a, 0x03, 0x03, 0x36, 0x0a, 0x01, 0x8f, 0x4f, 0x5b, 0x5b, +0x4f, 0x4e, 0x5b, 0x5b, 0xff, 0xff, 0x00, 0x1d, 0xff, 0x59, +0x01, 0xd8, 0x03, 0x06, 0x02, 0x26, 0x02, 0x42, 0x00, 0x00, +0x01, 0x07, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x02, 0x00, 0x31, 0x32, 0x0a, 0x14, 0x50, 0x02, +0x0f, 0x33, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x28, 0xff, 0x59, 0x01, 0xcc, 0x02, 0x7b, 0x02, 0x26, +0x02, 0x43, 0x00, 0x00, 0x01, 0x06, 0x00, 0x8a, 0x00, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x34, 0x35, 0x0c, 0x16, +0x50, 0x02, 0x11, 0x36, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x18, 0xff, 0xf3, 0x01, 0xcf, 0x03, 0x3d, 0x02, 0x26, +0x02, 0x0f, 0x00, 0x00, 0x01, 0x07, 0x01, 0x5f, 0x00, 0x00, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x06, 0x26, 0x2a, +0x1b, 0x10, 0x50, 0x01, 0x07, 0x2b, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x2c, 0xff, 0x5b, 0x01, 0xaf, +0x02, 0xb2, 0x02, 0x26, 0x02, 0xa3, 0x00, 0x00, 0x01, 0x06, +0x01, 0x5f, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x0c, +0x29, 0x2d, 0x1b, 0x12, 0x50, 0x01, 0x07, 0x2e, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x47, 0xff, 0x56, 0x01, 0x97, +0x02, 0xb2, 0x02, 0x26, 0x01, 0x5d, 0x00, 0x00, 0x01, 0x06, +0x01, 0x5f, 0x24, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x3a, +0x14, 0x18, 0x0b, 0x02, 0x50, 0x01, 0x01, 0x19, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x03, 0x00, 0x1b, 0xff, 0xfb, 0x01, 0xdf, +0x02, 0x71, 0x00, 0x11, 0x00, 0x22, 0x00, 0x2e, 0x00, 0x8c, +0x40, 0x0b, 0x2a, 0x18, 0x0f, 0x00, 0x4d, 0x27, 0x18, 0x0f, +0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, +0x1a, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x1a, 0xb8, +0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xe8, +0xb3, 0x12, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xe0, 0x40, 0x31, +0x10, 0x11, 0x00, 0x4c, 0x28, 0x76, 0x1f, 0x17, 0x01, 0x17, +0x2d, 0x73, 0x20, 0x05, 0x0e, 0x09, 0x0e, 0x7e, 0x00, 0x05, +0x14, 0x00, 0x00, 0x05, 0x0f, 0x0f, 0x09, 0x06, 0x00, 0x00, +0x06, 0x26, 0x7c, 0x1c, 0x42, 0x2b, 0x7c, 0x12, 0x41, 0x00, +0x0e, 0x79, 0x11, 0x41, 0x09, 0x05, 0x79, 0x08, 0x44, 0x00, +0x3f, 0xed, 0x32, 0x3f, 0xed, 0x32, 0x3f, 0xed, 0x3f, 0xed, +0x01, 0x2f, 0x33, 0x2f, 0x10, 0xcd, 0x32, 0x2f, 0x87, 0x10, +0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, 0x2f, 0xed, 0xdc, 0x5d, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x01, 0x0e, 0x03, 0x07, 0x33, 0x15, 0x23, 0x35, 0x3e, 0x03, +0x37, 0x23, 0x35, 0x33, 0x25, 0x32, 0x1e, 0x02, 0x15, 0x14, +0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x11, 0x36, 0x36, 0x13, +0x16, 0x32, 0x33, 0x32, 0x35, 0x34, 0x26, 0x23, 0x22, 0x22, +0x07, 0x01, 0xdf, 0x0d, 0x20, 0x22, 0x1f, 0x0c, 0x7a, 0xc2, +0x11, 0x1c, 0x1b, 0x1e, 0x13, 0x63, 0xac, 0xfe, 0x8a, 0x2d, +0x3f, 0x28, 0x12, 0x0b, 0x24, 0x42, 0x37, 0x11, 0x29, 0x12, +0x17, 0x25, 0x0b, 0x05, 0x08, 0x05, 0x53, 0x2a, 0x2b, 0x04, +0x07, 0x05, 0x02, 0x2b, 0x2c, 0x79, 0x84, 0x85, 0x37, 0x46, +0x36, 0x49, 0x7a, 0x73, 0x75, 0x44, 0x46, 0x06, 0x2c, 0x52, +0x75, 0x49, 0x33, 0x6e, 0x5d, 0x3c, 0x04, 0x05, 0x02, 0x63, +0x06, 0x04, 0xfd, 0xd2, 0x01, 0xf3, 0x7d, 0x78, 0x01, 0x00, +0x00, 0x00, 0x00, 0x03, 0x00, 0x1b, 0xff, 0xfb, 0x01, 0xe2, +0x02, 0x71, 0x00, 0x11, 0x00, 0x22, 0x00, 0x2e, 0x00, 0x7c, +0x40, 0x0d, 0x2a, 0x18, 0x0e, 0x0f, 0x00, 0x4c, 0x27, 0x18, +0x0e, 0x0f, 0x00, 0x4c, 0x1a, 0xb8, 0xff, 0xe0, 0xb4, 0x10, +0x12, 0x00, 0x4c, 0x14, 0xb8, 0xff, 0xe0, 0x40, 0x37, 0x10, +0x12, 0x00, 0x4c, 0x28, 0x76, 0x2f, 0x17, 0x6f, 0x17, 0x02, +0x17, 0x2e, 0x73, 0x20, 0x05, 0x0e, 0x09, 0x0e, 0x84, 0x00, +0x05, 0x14, 0x00, 0x00, 0x05, 0x0f, 0x0f, 0x00, 0x09, 0x01, +0x08, 0x09, 0x06, 0x00, 0x00, 0x06, 0x26, 0x7c, 0x1c, 0x42, +0x2b, 0x7c, 0x12, 0x41, 0x00, 0x0e, 0x85, 0x11, 0x49, 0x09, +0x05, 0x85, 0x08, 0x4c, 0x00, 0x3f, 0xed, 0x32, 0x3f, 0xed, +0x32, 0x3f, 0xed, 0x3f, 0xed, 0x01, 0x2f, 0x33, 0x2f, 0x10, +0xcd, 0x5e, 0x5d, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, +0xc4, 0x01, 0x18, 0x2f, 0xed, 0xdc, 0x5d, 0xed, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x0e, 0x03, 0x07, 0x33, 0x15, +0x23, 0x35, 0x3e, 0x03, 0x37, 0x23, 0x35, 0x33, 0x25, 0x32, +0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, +0x11, 0x36, 0x36, 0x13, 0x16, 0x32, 0x33, 0x32, 0x35, 0x34, +0x26, 0x23, 0x22, 0x22, 0x07, 0x01, 0xe2, 0x09, 0x1b, 0x1e, +0x1c, 0x0a, 0x68, 0xac, 0x0a, 0x1c, 0x1d, 0x1d, 0x0b, 0x62, +0xa3, 0xfe, 0x87, 0x2d, 0x3f, 0x28, 0x12, 0x0b, 0x24, 0x42, +0x37, 0x11, 0x29, 0x12, 0x17, 0x25, 0x0b, 0x05, 0x08, 0x05, +0x53, 0x2a, 0x2b, 0x04, 0x07, 0x05, 0x01, 0x92, 0x18, 0x4c, +0x5a, 0x61, 0x2d, 0x46, 0x37, 0x28, 0x5f, 0x5d, 0x54, 0x1c, +0x45, 0xa1, 0x2c, 0x52, 0x75, 0x49, 0x33, 0x6e, 0x5d, 0x3c, +0x04, 0x05, 0x02, 0x63, 0x06, 0x04, 0xfd, 0xd2, 0x01, 0xf3, +0x7d, 0x78, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, +0xff, 0xf5, 0x01, 0xeb, 0x02, 0xb5, 0x00, 0x0d, 0x00, 0x20, +0x00, 0x32, 0x00, 0x7b, 0xb6, 0x1b, 0x10, 0x0a, 0x0b, 0x00, +0x4c, 0x0a, 0xb8, 0xff, 0xd8, 0xb3, 0x12, 0x00, 0x4d, 0x0a, +0xb8, 0xff, 0xf0, 0xb3, 0x11, 0x00, 0x4d, 0x05, 0xb8, 0xff, +0xf0, 0x40, 0x35, 0x12, 0x00, 0x4d, 0x26, 0x2f, 0x2a, 0x2f, +0x84, 0x21, 0x26, 0x14, 0x21, 0x21, 0x26, 0x30, 0x30, 0x00, +0x2a, 0x01, 0x08, 0x2a, 0x27, 0x21, 0x21, 0x27, 0x20, 0x00, +0x7f, 0x0f, 0x08, 0x82, 0x18, 0x21, 0x2f, 0x85, 0x31, 0x49, +0x2a, 0x26, 0x85, 0x29, 0x4c, 0x03, 0x89, 0x1d, 0x50, 0x0b, +0x89, 0x13, 0x51, 0x0e, 0x0f, 0x4d, 0x00, 0x3f, 0x33, 0x3f, +0xed, 0x3f, 0xed, 0x3f, 0xed, 0x32, 0x3f, 0xed, 0x32, 0x01, +0x2f, 0xed, 0xdc, 0xfd, 0xc0, 0x2f, 0x33, 0x2f, 0x10, 0xcd, +0x5e, 0x5d, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x26, 0x26, +0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x16, 0x33, 0x32, 0x37, +0x11, 0x37, 0x11, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x05, 0x0e, 0x03, +0x07, 0x33, 0x15, 0x23, 0x35, 0x3e, 0x03, 0x37, 0x23, 0x35, +0x33, 0xbc, 0x07, 0x1c, 0x0f, 0x0d, 0x16, 0x11, 0x09, 0x29, +0x1c, 0x1c, 0x0e, 0x48, 0x11, 0x3a, 0x27, 0x24, 0x35, 0x23, +0x11, 0x15, 0x22, 0x2c, 0x17, 0x14, 0x21, 0x08, 0x01, 0x2f, +0x09, 0x1b, 0x1e, 0x1c, 0x0a, 0x68, 0xac, 0x0a, 0x1c, 0x1d, +0x1d, 0x0b, 0x62, 0xa3, 0x01, 0x78, 0x0d, 0x11, 0x10, 0x28, +0x43, 0x33, 0x61, 0x56, 0x07, 0x02, 0x6f, 0x0e, 0xfd, 0x58, +0x08, 0x10, 0x23, 0x41, 0x59, 0x36, 0x46, 0x5d, 0x38, 0x18, +0x12, 0x0a, 0x2d, 0x18, 0x4c, 0x5a, 0x61, 0x2d, 0x46, 0x37, +0x28, 0x5f, 0x5d, 0x54, 0x1c, 0x45, 0x00, 0x00, 0xff, 0xff, +0x00, 0x2e, 0xff, 0xf3, 0x01, 0xc7, 0x03, 0x3e, 0x02, 0x26, +0x00, 0x2a, 0x00, 0x00, 0x01, 0x07, 0x00, 0x8f, 0x00, 0x38, +0x00, 0x89, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x3b, 0x28, 0x26, +0x09, 0x01, 0x50, 0x01, 0x0e, 0x27, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x28, 0xff, 0x58, 0x01, 0xad, +0x02, 0xb5, 0x02, 0x26, 0x00, 0x4a, 0x00, 0x00, 0x01, 0x06, +0x00, 0x8f, 0x29, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x3c, +0x30, 0x2e, 0x07, 0x10, 0x50, 0x02, 0x0c, 0x2f, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x01, 0x00, 0x24, 0xff, 0xf3, 0x01, 0xd2, +0x02, 0x6b, 0x00, 0x21, 0x00, 0x48, 0xb6, 0x17, 0x20, 0x0a, +0x10, 0x00, 0x4c, 0x12, 0xb8, 0xff, 0xe8, 0x40, 0x21, 0x0a, +0x10, 0x00, 0x4c, 0x20, 0x1c, 0x73, 0x1d, 0x21, 0x02, 0x73, +0x1a, 0x1a, 0x1d, 0x0c, 0x73, 0x0f, 0x1b, 0x79, 0x20, 0x20, +0x1d, 0x00, 0x1e, 0x41, 0x1d, 0x44, 0x07, 0x7c, 0x14, 0x46, +0x0d, 0x49, 0x00, 0x3f, 0x3f, 0xed, 0x3f, 0x3f, 0x33, 0x12, +0x39, 0x2f, 0xed, 0x01, 0x2f, 0xed, 0x2f, 0x39, 0x2f, 0xed, +0x33, 0x10, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x13, 0x33, +0x11, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x11, +0x33, 0x11, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x35, 0x23, 0x11, 0x23, 0x11, 0x33, 0x11, 0x33, 0xd8, 0x4f, +0x05, 0x0b, 0x11, 0x0c, 0x0c, 0x12, 0x0c, 0x06, 0x4e, 0x0b, +0x1c, 0x31, 0x26, 0x26, 0x30, 0x1c, 0x0a, 0x66, 0x4e, 0x4e, +0x66, 0x02, 0x6b, 0xfe, 0x59, 0x2b, 0x37, 0x1f, 0x0b, 0x0b, +0x1f, 0x37, 0x2b, 0x01, 0x0c, 0xfe, 0xf4, 0x32, 0x4d, 0x36, +0x1c, 0x1c, 0x36, 0x4d, 0x32, 0x5c, 0xfe, 0xe0, 0x02, 0x6b, +0xfe, 0xfb, 0x00, 0x00, 0x00, 0x02, 0x00, 0x49, 0xff, 0x5b, +0x01, 0xcd, 0x02, 0x71, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x6c, +0x40, 0x15, 0x15, 0x30, 0x0f, 0x00, 0x4d, 0x15, 0x18, 0x0e, +0x00, 0x4d, 0x11, 0x10, 0x12, 0x00, 0x4d, 0x11, 0x08, 0x11, +0x00, 0x4d, 0x07, 0xb8, 0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, +0x07, 0xb8, 0xff, 0xf0, 0xb3, 0x0a, 0x00, 0x4d, 0x07, 0xb8, +0xff, 0xe8, 0xb4, 0x08, 0x09, 0x00, 0x4c, 0x06, 0xb8, 0xff, +0xe8, 0x40, 0x1b, 0x10, 0x00, 0x4d, 0x13, 0x76, 0x08, 0x1b, +0x0e, 0x0d, 0x73, 0x00, 0x01, 0x01, 0x08, 0x01, 0x1a, 0x0e, +0x7c, 0x0d, 0x44, 0x19, 0x16, 0x7c, 0x02, 0x05, 0x41, 0x01, +0x00, 0x2f, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0xed, 0x01, 0x10, +0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x17, 0x23, +0x11, 0x36, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, +0x07, 0x35, 0x3e, 0x03, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, +0x07, 0x9b, 0x52, 0x1d, 0x5a, 0x34, 0x6a, 0x6f, 0x2f, 0x53, +0x70, 0x40, 0x2d, 0x51, 0x3d, 0x23, 0x49, 0x3b, 0x21, 0x2d, +0x0c, 0xa5, 0x02, 0xed, 0x0d, 0x1c, 0x74, 0x71, 0x4e, 0x79, +0x5f, 0x48, 0x1d, 0x4e, 0x19, 0x37, 0x4a, 0x62, 0x44, 0x49, +0x52, 0x0d, 0x05, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x37, +0x00, 0x00, 0x01, 0xbd, 0x03, 0x3e, 0x02, 0x26, 0x00, 0x31, +0x00, 0x00, 0x01, 0x07, 0x00, 0x43, 0x00, 0x00, 0x00, 0x89, +0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xfd, 0x40, 0x09, 0x15, +0x13, 0x07, 0x10, 0x50, 0x01, 0x08, 0x14, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x47, 0x00, 0x00, +0x01, 0xb0, 0x02, 0xb5, 0x02, 0x26, 0x00, 0x51, 0x00, 0x00, +0x01, 0x06, 0x00, 0x43, 0xf3, 0x00, 0x00, 0x13, 0xb9, 0x00, +0x01, 0xff, 0xee, 0x40, 0x09, 0x17, 0x15, 0x00, 0x05, 0x50, +0x01, 0x02, 0x16, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0x04, +0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x03, 0x3e, 0x00, 0x19, +0x00, 0x20, 0x00, 0x2c, 0x00, 0x30, 0x00, 0x99, 0xb9, 0x00, +0x19, 0xff, 0xd8, 0x40, 0x4f, 0x08, 0x11, 0x00, 0x4c, 0x15, +0x28, 0x08, 0x11, 0x00, 0x4c, 0x00, 0x21, 0x27, 0x2d, 0x2f, +0x2f, 0x14, 0x27, 0x27, 0x0a, 0x1d, 0x1b, 0x1a, 0x11, 0x0b, +0x1a, 0x0b, 0x78, 0x0c, 0x11, 0x14, 0x0c, 0x0c, 0x11, 0x1e, +0x09, 0x08, 0x02, 0x08, 0x1a, 0x08, 0x78, 0x07, 0x02, 0x14, +0x07, 0x02, 0x1a, 0x0c, 0x07, 0x32, 0x0c, 0x31, 0x2d, 0x30, +0x2f, 0x2e, 0x2e, 0x17, 0x24, 0x2a, 0x09, 0x0a, 0x79, 0x1e, +0x1d, 0x1d, 0x0c, 0x2a, 0x2a, 0x1a, 0x02, 0x11, 0x0b, 0x0c, +0x44, 0x08, 0x07, 0x44, 0x00, 0x3f, 0x33, 0x3f, 0x33, 0x2f, +0x33, 0x33, 0x33, 0x2f, 0x12, 0x39, 0x2f, 0x33, 0xed, 0x32, +0x10, 0xde, 0xcd, 0x32, 0x2f, 0xcd, 0xdd, 0xcd, 0x01, 0x10, +0xc6, 0x10, 0xde, 0x11, 0x39, 0x87, 0x2b, 0x87, 0x7d, 0xc4, +0x10, 0xc4, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x10, 0x0e, 0xc4, 0x05, 0xc4, 0xc4, 0x01, 0x33, 0x18, 0x2f, +0xcd, 0x32, 0x2f, 0xcd, 0x10, 0xde, 0xcd, 0x31, 0x30, 0x2b, +0x2b, 0x01, 0x14, 0x07, 0x1e, 0x03, 0x17, 0x23, 0x27, 0x23, +0x07, 0x23, 0x3e, 0x03, 0x37, 0x26, 0x26, 0x35, 0x34, 0x36, +0x33, 0x32, 0x16, 0x07, 0x06, 0x06, 0x07, 0x33, 0x26, 0x26, +0x37, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, +0x32, 0x36, 0x37, 0x07, 0x27, 0x37, 0x01, 0x4e, 0x17, 0x18, +0x31, 0x30, 0x2a, 0x11, 0x57, 0x25, 0xee, 0x24, 0x54, 0x10, +0x2b, 0x31, 0x32, 0x18, 0x0b, 0x0c, 0x30, 0x23, 0x21, 0x32, +0x55, 0x17, 0x32, 0x1c, 0xc8, 0x1a, 0x32, 0x16, 0x19, 0x12, +0x12, 0x19, 0x19, 0x12, 0x12, 0x19, 0x29, 0x8c, 0x13, 0x86, +0x02, 0x6e, 0x23, 0x17, 0x39, 0x90, 0x98, 0x95, 0x3e, 0xa2, +0xa2, 0x3e, 0x96, 0x98, 0x8e, 0x38, 0x0b, 0x1e, 0x13, 0x26, +0x2c, 0x2c, 0x7b, 0x3f, 0x95, 0x5f, 0x5e, 0x99, 0x91, 0x15, +0x17, 0x17, 0x15, 0x15, 0x18, 0x18, 0xa4, 0x2c, 0x31, 0x3c, +0x00, 0x00, 0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb0, +0x03, 0x2d, 0x02, 0x26, 0x00, 0x44, 0x00, 0x00, 0x01, 0x06, +0x02, 0xa6, 0x00, 0x00, 0x00, 0x0f, 0x40, 0x09, 0x04, 0x03, +0x02, 0x05, 0x3a, 0x31, 0x1c, 0x13, 0x50, 0x2b, 0x34, 0x34, +0x34, 0x00, 0xff, 0xff, 0x00, 0x1b, 0x00, 0x00, 0x01, 0xe2, +0x03, 0x3e, 0x02, 0x26, 0x00, 0xa1, 0x00, 0x00, 0x01, 0x07, +0x00, 0x8f, 0x00, 0x65, 0x00, 0x89, 0x00, 0x10, 0x40, 0x0b, +0x02, 0x64, 0x19, 0x17, 0x04, 0x10, 0x50, 0x02, 0x07, 0x18, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1f, +0xff, 0xf5, 0x01, 0xde, 0x02, 0xb5, 0x02, 0x26, 0x00, 0xc1, +0x00, 0x00, 0x01, 0x06, 0x00, 0x8f, 0x22, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x03, 0x21, 0x4e, 0x4c, 0x21, 0x07, 0x50, 0x03, +0x00, 0x4d, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x1d, +0xff, 0xdf, 0x01, 0xd8, 0x03, 0x3e, 0x02, 0x26, 0x00, 0xb3, +0x00, 0x00, 0x01, 0x07, 0x00, 0x8f, 0x00, 0x15, 0x00, 0x89, +0x00, 0x10, 0x40, 0x0b, 0x03, 0x18, 0x30, 0x2e, 0x00, 0x0c, +0x50, 0x03, 0x08, 0x2f, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x28, 0xff, 0xe0, 0x01, 0xcc, 0x02, 0xb5, +0x02, 0x26, 0x00, 0xd3, 0x00, 0x00, 0x01, 0x06, 0x00, 0x8f, +0x17, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x03, 0x1b, 0x31, 0x2f, +0x03, 0x10, 0x50, 0x03, 0x0c, 0x30, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x03, 0x3e, +0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x01, 0x07, 0x02, 0xa5, +0x00, 0x00, 0x00, 0x89, 0x00, 0x17, 0x40, 0x10, 0x03, 0x02, +0x00, 0x1e, 0x18, 0x04, 0x0f, 0x50, 0x03, 0x09, 0x1d, 0x4f, +0x02, 0x09, 0x19, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb0, +0x02, 0xb5, 0x02, 0x26, 0x00, 0x44, 0x00, 0x00, 0x01, 0x06, +0x02, 0xa5, 0x00, 0x00, 0x00, 0x17, 0x40, 0x10, 0x03, 0x02, +0x05, 0x38, 0x32, 0x1c, 0x13, 0x50, 0x03, 0x0f, 0x37, 0x4f, +0x02, 0x0f, 0x33, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0xff, 0xff, 0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x03, 0x28, +0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x01, 0x07, 0x02, 0xa4, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, +0x29, 0x1b, 0x04, 0x0f, 0x50, 0x02, 0x09, 0x1c, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, +0x01, 0xb0, 0x02, 0x9d, 0x02, 0x26, 0x00, 0x44, 0x00, 0x00, +0x01, 0x06, 0x02, 0xa4, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, +0x02, 0x05, 0x43, 0x35, 0x1c, 0x13, 0x50, 0x02, 0x0f, 0x36, +0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x5b, 0x00, 0x00, +0x01, 0xcc, 0x03, 0x3e, 0x02, 0x26, 0x00, 0x28, 0x00, 0x00, +0x01, 0x07, 0x02, 0xa5, 0x00, 0x00, 0x00, 0x89, 0x00, 0x1a, +0xb1, 0x02, 0x01, 0xb8, 0xff, 0xe7, 0x40, 0x0d, 0x13, 0x0d, +0x00, 0x0a, 0x50, 0x02, 0x01, 0x12, 0x4f, 0x01, 0x01, 0x0e, +0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0xff, 0xff, 0x00, 0x28, +0xff, 0xf5, 0x01, 0xc7, 0x02, 0xb5, 0x02, 0x26, 0x00, 0x48, +0x00, 0x00, 0x01, 0x06, 0x02, 0xa5, 0x00, 0x00, 0x00, 0x17, +0x40, 0x10, 0x03, 0x02, 0x02, 0x29, 0x23, 0x13, 0x02, 0x50, +0x03, 0x00, 0x28, 0x4f, 0x02, 0x00, 0x24, 0x4f, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x5b, 0x00, 0x00, +0x01, 0xcc, 0x03, 0x28, 0x02, 0x26, 0x00, 0x28, 0x00, 0x00, +0x01, 0x07, 0x02, 0xa4, 0x00, 0x1b, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x01, 0x1e, 0x10, 0x00, 0x0a, 0x50, 0x01, +0x01, 0x11, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xc7, 0x02, 0x9d, 0x02, 0x26, +0x00, 0x48, 0x00, 0x00, 0x01, 0x06, 0x02, 0xa4, 0x12, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x02, 0x14, 0x34, 0x26, 0x13, 0x02, +0x50, 0x02, 0x00, 0x27, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x53, 0x00, 0x00, 0x01, 0x9b, 0x03, 0x3e, 0x02, 0x26, +0x00, 0x2c, 0x00, 0x00, 0x01, 0x07, 0x02, 0xa5, 0xff, 0xef, +0x00, 0x89, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, 0xff, 0xef, +0x40, 0x0d, 0x13, 0x0d, 0x04, 0x02, 0x50, 0x02, 0x09, 0x12, +0x4f, 0x01, 0x09, 0x0e, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, +0xff, 0xff, 0x00, 0x2f, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0xb5, +0x02, 0x26, 0x01, 0x0c, 0x00, 0x00, 0x01, 0x06, 0x02, 0xa5, +0xcb, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, 0xff, 0xc9, +0x40, 0x0d, 0x1d, 0x17, 0x01, 0x0b, 0x50, 0x02, 0x02, 0x1c, +0x4f, 0x01, 0x02, 0x18, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x59, 0x00, 0x00, 0x01, 0x9b, +0x03, 0x28, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x07, +0x02, 0xa4, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x00, 0x1e, 0x10, 0x04, 0x02, 0x50, 0x01, 0x09, 0x11, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x36, +0xff, 0xf5, 0x01, 0xc2, 0x02, 0x9d, 0x02, 0x26, 0x01, 0x0c, +0x00, 0x00, 0x01, 0x06, 0x02, 0xa4, 0xdd, 0x00, 0x00, 0x13, +0xb9, 0x00, 0x01, 0xff, 0xdb, 0x40, 0x09, 0x28, 0x1a, 0x01, +0x0b, 0x50, 0x01, 0x02, 0x1b, 0x4f, 0x2b, 0x2b, 0x34, 0x00, +0xff, 0xff, 0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, 0x03, 0x3e, +0x02, 0x26, 0x00, 0x32, 0x00, 0x00, 0x01, 0x07, 0x02, 0xa5, +0xff, 0xef, 0x00, 0x89, 0x00, 0x1a, 0xb1, 0x03, 0x02, 0xb8, +0xff, 0xef, 0x40, 0x0d, 0x27, 0x21, 0x00, 0x09, 0x50, 0x03, +0x04, 0x26, 0x4f, 0x02, 0x04, 0x22, 0x4f, 0x2b, 0x2b, 0x2b, +0x34, 0x34, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, +0x02, 0xb5, 0x02, 0x26, 0x00, 0x52, 0x00, 0x00, 0x01, 0x06, +0x02, 0xa5, 0xef, 0x00, 0x00, 0x1a, 0xb1, 0x03, 0x02, 0xb8, +0xff, 0xef, 0x40, 0x0d, 0x27, 0x21, 0x09, 0x00, 0x50, 0x03, +0x0e, 0x26, 0x4f, 0x02, 0x0e, 0x22, 0x4f, 0x2b, 0x2b, 0x2b, +0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1d, 0xff, 0xf3, +0x01, 0xd8, 0x03, 0x28, 0x02, 0x26, 0x00, 0x32, 0x00, 0x00, +0x01, 0x07, 0x02, 0xa4, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x02, 0x00, 0x32, 0x24, 0x00, 0x09, 0x50, 0x02, +0x04, 0x25, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0x9d, 0x02, 0x26, +0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x02, 0xa4, 0x00, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x32, 0x24, 0x09, 0x00, +0x50, 0x02, 0x0e, 0x25, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x37, 0x00, 0x00, 0x01, 0xcf, 0x03, 0x3e, 0x02, 0x26, +0x00, 0x35, 0x00, 0x00, 0x01, 0x07, 0x02, 0xa5, 0xff, 0xe6, +0x00, 0x89, 0x00, 0x1a, 0xb1, 0x03, 0x02, 0xb8, 0xff, 0xdd, +0x40, 0x0d, 0x31, 0x2b, 0x12, 0x08, 0x50, 0x03, 0x17, 0x30, +0x4f, 0x02, 0x17, 0x2c, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, +0xff, 0xff, 0x00, 0x53, 0x00, 0x00, 0x01, 0xb6, 0x02, 0xb5, +0x02, 0x26, 0x00, 0x55, 0x00, 0x00, 0x01, 0x06, 0x02, 0xa5, +0xef, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, 0xff, 0xd9, +0x40, 0x0d, 0x15, 0x0f, 0x00, 0x06, 0x50, 0x02, 0x02, 0x14, +0x4f, 0x01, 0x02, 0x10, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x37, 0x00, 0x00, 0x01, 0xcf, +0x03, 0x28, 0x02, 0x26, 0x00, 0x35, 0x00, 0x00, 0x01, 0x07, +0x02, 0xa4, 0xff, 0xe6, 0x00, 0x8b, 0x00, 0x13, 0xb9, 0x00, +0x02, 0xff, 0xdd, 0x40, 0x09, 0x3c, 0x2e, 0x12, 0x08, 0x50, +0x02, 0x17, 0x2f, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x6b, 0x00, 0x00, 0x01, 0xb6, 0x02, 0x9d, +0x02, 0x26, 0x00, 0x55, 0x00, 0x00, 0x01, 0x06, 0x02, 0xa4, +0x1b, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x04, 0x20, 0x12, +0x00, 0x06, 0x50, 0x01, 0x02, 0x13, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x30, 0xff, 0xf3, 0x01, 0xc4, 0x03, 0x3e, +0x02, 0x26, 0x00, 0x38, 0x00, 0x00, 0x01, 0x07, 0x02, 0xa5, +0xff, 0xf8, 0x00, 0x89, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, +0xff, 0xf8, 0x40, 0x0d, 0x21, 0x1b, 0x04, 0x14, 0x50, 0x02, +0x06, 0x20, 0x4f, 0x01, 0x06, 0x1c, 0x4f, 0x2b, 0x2b, 0x2b, +0x34, 0x34, 0xff, 0xff, 0x00, 0x44, 0xff, 0xf6, 0x01, 0xad, +0x02, 0xb5, 0x02, 0x26, 0x00, 0x58, 0x00, 0x00, 0x01, 0x06, +0x02, 0xa5, 0xef, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, +0xff, 0xf1, 0x40, 0x0d, 0x1d, 0x17, 0x07, 0x00, 0x50, 0x02, +0x09, 0x1c, 0x4f, 0x01, 0x09, 0x18, 0x4f, 0x2b, 0x2b, 0x2b, +0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x30, 0xff, 0xf3, +0x01, 0xc4, 0x03, 0x28, 0x02, 0x26, 0x00, 0x38, 0x00, 0x00, +0x01, 0x07, 0x02, 0xa4, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x00, 0x2c, 0x1e, 0x04, 0x14, 0x50, 0x01, +0x06, 0x1f, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x44, 0xff, 0xf6, 0x01, 0xad, 0x02, 0x9d, 0x02, 0x26, +0x00, 0x58, 0x00, 0x00, 0x01, 0x06, 0x02, 0xa4, 0x00, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x01, 0x28, 0x1a, 0x07, 0x00, +0x50, 0x01, 0x09, 0x1b, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x01, +0x00, 0x1e, 0xff, 0x5b, 0x01, 0xd5, 0x02, 0x78, 0x00, 0x32, +0x00, 0xbf, 0xb9, 0x00, 0x29, 0xff, 0xd0, 0xb3, 0x0b, 0x00, +0x4d, 0x28, 0xb8, 0xff, 0xd8, 0xb3, 0x0c, 0x00, 0x4d, 0x26, +0xb8, 0xff, 0xe0, 0xb4, 0x0e, 0x0f, 0x00, 0x4c, 0x25, 0xb8, +0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x25, 0xb8, 0xff, 0xe0, +0xb3, 0x10, 0x00, 0x4d, 0x23, 0xb8, 0xff, 0xf0, 0xb4, 0x0e, +0x0f, 0x00, 0x4c, 0x1f, 0xb8, 0xff, 0xe0, 0x40, 0x58, 0x08, +0x00, 0x4d, 0x1a, 0x20, 0x12, 0x00, 0x4d, 0x1a, 0x28, 0x11, +0x00, 0x4d, 0x1a, 0x18, 0x10, 0x00, 0x4d, 0x1a, 0x20, 0x0f, +0x00, 0x4d, 0x14, 0x28, 0x0f, 0x00, 0x4d, 0x14, 0x18, 0x0e, +0x00, 0x4d, 0x10, 0x20, 0x0d, 0x00, 0x4d, 0x10, 0x18, 0x0c, +0x00, 0x4d, 0x10, 0x10, 0x0b, 0x00, 0x4d, 0x0f, 0x18, 0x10, +0x00, 0x4d, 0x07, 0x30, 0x0d, 0x00, 0x4d, 0x24, 0x12, 0x76, +0x21, 0x21, 0x05, 0x76, 0x27, 0x34, 0x2f, 0x2f, 0x0c, 0x0c, +0x19, 0x33, 0x24, 0x0b, 0x79, 0x0c, 0x0c, 0x1c, 0x00, 0x7c, +0x2c, 0x18, 0x18, 0x15, 0x7c, 0x1c, 0x45, 0x00, 0x3f, 0xed, +0x32, 0x2f, 0x2f, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x39, 0x01, +0x10, 0xc6, 0x32, 0x2f, 0x32, 0x2f, 0x10, 0xde, 0xed, 0x33, +0x2f, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x17, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, +0x02, 0x23, 0x23, 0x35, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, +0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, +0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, 0x16, 0x16, 0x15, 0x14, +0x0e, 0x02, 0x23, 0x22, 0x22, 0x27, 0x37, 0x16, 0x16, 0x57, +0x3d, 0x6d, 0x51, 0x2f, 0x2a, 0x42, 0x51, 0x27, 0x22, 0x1b, +0x2e, 0x4e, 0x38, 0x1f, 0x49, 0x4d, 0x35, 0x51, 0x14, 0x1b, +0x17, 0x63, 0x3c, 0x32, 0x55, 0x3d, 0x23, 0x3d, 0x39, 0x44, +0x4c, 0x3f, 0x6a, 0x89, 0x4a, 0x0a, 0x21, 0x0a, 0x05, 0x08, +0x19, 0x5a, 0x0f, 0x27, 0x42, 0x33, 0x2d, 0x3a, 0x22, 0x0e, +0x44, 0x11, 0x21, 0x33, 0x22, 0x3b, 0x43, 0x17, 0x0b, 0x44, +0x0e, 0x17, 0x16, 0x30, 0x4a, 0x34, 0x31, 0x5a, 0x18, 0x14, +0x66, 0x40, 0x48, 0x60, 0x3b, 0x19, 0x02, 0x4b, 0x01, 0x01, +0x00, 0x01, 0x00, 0x39, 0xff, 0x5b, 0x01, 0xb1, 0x01, 0xdc, +0x00, 0x31, 0x00, 0xbc, 0x40, 0x24, 0x22, 0x20, 0x10, 0x00, +0x4d, 0x22, 0x28, 0x0f, 0x00, 0x4d, 0x22, 0x10, 0x0e, 0x00, +0x4d, 0x1a, 0x30, 0x10, 0x00, 0x4d, 0x1a, 0x20, 0x0f, 0x00, +0x4d, 0x15, 0x18, 0x10, 0x00, 0x4d, 0x15, 0x20, 0x0c, 0x00, +0x4d, 0x0d, 0xb8, 0xff, 0xe0, 0xb4, 0x0e, 0x0f, 0x00, 0x4c, +0x0d, 0xb8, 0xff, 0xe8, 0xb3, 0x0d, 0x00, 0x4d, 0x0a, 0xb8, +0xff, 0xd8, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x06, 0xb8, 0xff, +0xe0, 0xb3, 0x12, 0x00, 0x4d, 0x06, 0xb8, 0xff, 0xe8, 0xb3, +0x11, 0x00, 0x4d, 0x03, 0xb8, 0xff, 0xd8, 0xb3, 0x12, 0x00, +0x4d, 0x03, 0xb8, 0xff, 0xe0, 0xb3, 0x11, 0x00, 0x4d, 0x03, +0xb8, 0xff, 0xe8, 0xb4, 0x08, 0x0a, 0x00, 0x4c, 0x02, 0xb8, +0xff, 0xd8, 0x40, 0x22, 0x11, 0x00, 0x4d, 0x08, 0x24, 0x82, +0x05, 0x05, 0x18, 0x82, 0x0b, 0x33, 0x1f, 0x1f, 0x11, 0x11, +0x2d, 0x32, 0x08, 0x1e, 0x85, 0x1f, 0x1f, 0x00, 0x11, 0x89, +0x10, 0x4b, 0x2c, 0x2c, 0x27, 0x88, 0x00, 0x50, 0x00, 0x3f, +0xed, 0x32, 0x2f, 0x3f, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x39, +0x01, 0x10, 0xc6, 0x32, 0x2f, 0x32, 0x2f, 0x10, 0xde, 0xed, +0x33, 0x2f, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x13, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, +0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x27, 0x3e, 0x05, +0x35, 0x34, 0x2e, 0x02, 0x23, 0x23, 0x35, 0x32, 0x3e, 0x02, +0x35, 0x34, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x07, 0x27, 0x3e, +0x03, 0xd1, 0x2b, 0x4b, 0x37, 0x1f, 0x37, 0x2c, 0x3a, 0x3d, +0x43, 0x6b, 0x84, 0x40, 0x06, 0x19, 0x3f, 0x41, 0x3e, 0x30, +0x1d, 0x2a, 0x3d, 0x43, 0x19, 0x0b, 0x24, 0x43, 0x34, 0x1f, +0x3f, 0x39, 0x17, 0x2c, 0x25, 0x1b, 0x06, 0x0f, 0x08, 0x20, +0x2a, 0x2f, 0x01, 0xdc, 0x12, 0x26, 0x3c, 0x2b, 0x29, 0x47, +0x12, 0x0d, 0x4e, 0x30, 0x3e, 0x52, 0x31, 0x14, 0x45, 0x01, +0x05, 0x0b, 0x13, 0x1f, 0x2c, 0x1e, 0x21, 0x28, 0x15, 0x06, +0x45, 0x0a, 0x18, 0x27, 0x1d, 0x2b, 0x2f, 0x06, 0x08, 0x09, +0x03, 0x48, 0x03, 0x08, 0x07, 0x06, 0x00, 0x00, 0xff, 0xff, +0x00, 0x2d, 0x00, 0x00, 0x01, 0xc7, 0x03, 0x3d, 0x02, 0x26, +0x00, 0x2b, 0x00, 0x00, 0x01, 0x07, 0x01, 0x5f, 0x00, 0x00, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x0c, 0x10, +0x07, 0x01, 0x50, 0x01, 0x00, 0x11, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0x00, 0x02, 0x00, 0x2c, 0x00, 0x00, 0x01, 0xb0, +0x03, 0x3e, 0x00, 0x15, 0x00, 0x1b, 0x00, 0x80, 0x40, 0x15, +0x10, 0x20, 0x12, 0x00, 0x4d, 0x10, 0x28, 0x11, 0x00, 0x4d, +0x10, 0x18, 0x10, 0x00, 0x4d, 0x10, 0x10, 0x0f, 0x00, 0x4d, +0x09, 0xb8, 0xff, 0xd8, 0xb3, 0x08, 0x00, 0x4d, 0x08, 0xb8, +0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xd8, +0x40, 0x29, 0x09, 0x00, 0x4d, 0x0d, 0x7f, 0x0c, 0x1d, 0x40, +0x1a, 0x18, 0x16, 0x60, 0x1b, 0x1b, 0x03, 0x15, 0x7f, 0x00, +0x00, 0x01, 0x08, 0x00, 0x1c, 0x11, 0x88, 0x06, 0x50, 0x1a, +0x16, 0x40, 0x19, 0x17, 0x80, 0x18, 0x1b, 0x01, 0x02, 0x4d, +0x0d, 0x00, 0x4a, 0x00, 0x3f, 0x32, 0x3f, 0x33, 0xde, 0xcd, +0x1a, 0xdd, 0x32, 0x1a, 0xcd, 0x32, 0x3f, 0xed, 0x01, 0x10, +0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x32, 0x19, 0x2f, 0x1a, 0xcd, +0x33, 0xcd, 0x1a, 0x18, 0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x33, 0x11, 0x37, 0x15, +0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x11, 0x23, 0x35, +0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x11, 0x03, 0x37, 0x17, +0x37, 0x17, 0x07, 0x47, 0x53, 0x14, 0x32, 0x18, 0x35, 0x47, +0x2a, 0x12, 0x52, 0x30, 0x3e, 0x1a, 0x31, 0x0b, 0x6e, 0x1a, +0x54, 0x54, 0x1a, 0x6e, 0x02, 0x89, 0x0e, 0xce, 0x08, 0x09, +0x1f, 0x38, 0x4e, 0x2f, 0xfe, 0xfa, 0xf4, 0x56, 0x47, 0x0b, +0x05, 0xfe, 0x7f, 0x03, 0x16, 0x28, 0x36, 0x36, 0x28, 0x55, +0x00, 0x00, 0x00, 0x01, 0x00, 0x2d, 0xff, 0x5b, 0x01, 0xc7, +0x02, 0x78, 0x00, 0x13, 0x00, 0x3b, 0xb9, 0x00, 0x11, 0xff, +0xe0, 0x40, 0x22, 0x08, 0x0c, 0x00, 0x4c, 0x04, 0x28, 0x10, +0x00, 0x4d, 0x04, 0x18, 0x0f, 0x00, 0x4d, 0x04, 0x10, 0x0e, +0x00, 0x4d, 0x02, 0x73, 0x13, 0x15, 0x08, 0x73, 0x0b, 0x14, +0x05, 0x7c, 0x0e, 0x45, 0x0a, 0x44, 0x01, 0x00, 0x2f, 0x3f, +0x3f, 0xed, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x05, 0x23, 0x11, 0x34, 0x26, +0x23, 0x22, 0x06, 0x07, 0x11, 0x23, 0x11, 0x36, 0x36, 0x33, +0x32, 0x1e, 0x02, 0x15, 0x01, 0xc7, 0x52, 0x3f, 0x48, 0x1d, +0x40, 0x12, 0x52, 0x21, 0x6b, 0x3f, 0x3b, 0x50, 0x30, 0x14, +0xa5, 0x02, 0x10, 0x66, 0x60, 0x09, 0x05, 0xfd, 0xdd, 0x02, +0x5b, 0x0b, 0x12, 0x25, 0x41, 0x5b, 0x36, 0x00, 0x00, 0x00, +0x00, 0x03, 0x00, 0x19, 0xff, 0x58, 0x01, 0xf4, 0x02, 0xb5, +0x00, 0x0e, 0x00, 0x35, 0x00, 0x42, 0x00, 0xa7, 0xb6, 0x2f, +0x20, 0x0a, 0x0f, 0x00, 0x4c, 0x2a, 0xb8, 0xff, 0xe0, 0xb4, +0x0a, 0x0f, 0x00, 0x4c, 0x26, 0xb8, 0xff, 0xe0, 0x40, 0x21, +0x0a, 0x0f, 0x00, 0x4c, 0x18, 0x28, 0x11, 0x12, 0x00, 0x4c, +0x18, 0x20, 0x08, 0x0a, 0x00, 0x4c, 0x13, 0x28, 0x12, 0x00, +0x4d, 0x13, 0x18, 0x11, 0x00, 0x4d, 0x13, 0x20, 0x08, 0x0a, +0x00, 0x4c, 0x0a, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, +0x0a, 0xb8, 0xff, 0xe0, 0x40, 0x30, 0x0f, 0x00, 0x4d, 0x31, +0x32, 0x32, 0x39, 0x20, 0x7f, 0x30, 0x1d, 0x0f, 0x0e, 0x0e, +0x40, 0x08, 0x82, 0x15, 0x43, 0x40, 0x28, 0x20, 0x33, 0x23, +0x32, 0x32, 0x39, 0x30, 0x36, 0x31, 0x31, 0x3d, 0x2d, 0x4b, +0x1e, 0x1f, 0x4d, 0x03, 0x85, 0x1a, 0x50, 0x36, 0x23, 0x23, +0x0b, 0x85, 0x12, 0x51, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0xcd, +0x3f, 0xed, 0x3f, 0x33, 0x3f, 0xcd, 0x33, 0x2f, 0x12, 0x39, +0x39, 0x33, 0x11, 0x12, 0x39, 0x39, 0x01, 0x2f, 0xcd, 0x10, +0xd6, 0xed, 0x12, 0x39, 0x2f, 0x33, 0x33, 0x33, 0xed, 0x32, +0x33, 0x2f, 0x33, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x26, 0x26, 0x23, 0x22, +0x0e, 0x02, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, +0x06, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, +0x32, 0x16, 0x17, 0x35, 0x37, 0x11, 0x36, 0x36, 0x33, 0x32, +0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, +0x07, 0x27, 0x37, 0x26, 0x34, 0x37, 0x22, 0x06, 0x07, 0x15, +0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0xf0, 0x0a, +0x24, 0x16, 0x12, 0x18, 0x10, 0x07, 0x2b, 0x25, 0x14, 0x19, +0x08, 0x01, 0x0c, 0x1d, 0x0e, 0x4c, 0x55, 0x11, 0x23, 0x33, +0x22, 0x1a, 0x29, 0x0b, 0x52, 0x11, 0x22, 0x15, 0x18, 0x27, +0x1c, 0x0f, 0x0e, 0x1d, 0x2e, 0x1f, 0x2f, 0x3b, 0x10, 0x43, +0x2b, 0x5e, 0x01, 0x8c, 0x13, 0x1a, 0x0e, 0x20, 0x1a, 0x1a, +0x1a, 0x19, 0x01, 0x70, 0x0d, 0x17, 0x1a, 0x2f, 0x3f, 0x24, +0x51, 0x58, 0x0a, 0x04, 0x44, 0x08, 0x09, 0x7f, 0x71, 0x36, +0x59, 0x40, 0x24, 0x15, 0x0a, 0xeb, 0x0e, 0xfd, 0x8b, 0x0d, +0x0d, 0x15, 0x22, 0x2f, 0x19, 0x16, 0x2e, 0x25, 0x17, 0x29, +0x25, 0x51, 0x26, 0x70, 0x09, 0x0a, 0x1b, 0x14, 0x10, 0x16, +0x20, 0x28, 0x27, 0x1a, 0x1b, 0x26, 0x00, 0x02, 0x00, 0x24, +0xff, 0xfc, 0x01, 0xd0, 0x02, 0x6b, 0x00, 0x2f, 0x00, 0x41, +0x00, 0x83, 0xb5, 0x3a, 0x18, 0x10, 0x00, 0x4d, 0x37, 0xb8, +0xff, 0xe8, 0x40, 0x14, 0x10, 0x00, 0x4d, 0x16, 0x10, 0x10, +0x00, 0x4d, 0x12, 0x20, 0x08, 0x00, 0x4d, 0x11, 0x20, 0x11, +0x12, 0x00, 0x4c, 0x0d, 0xb8, 0xff, 0xd8, 0xb3, 0x12, 0x00, +0x4d, 0x0d, 0xb8, 0xff, 0xd0, 0xb3, 0x11, 0x00, 0x4d, 0x0c, +0xb8, 0xff, 0xe0, 0xb3, 0x08, 0x00, 0x4d, 0x08, 0xb8, 0xff, +0xf0, 0x40, 0x22, 0x10, 0x00, 0x4d, 0x05, 0x29, 0x76, 0x00, +0x00, 0x3d, 0x76, 0x0a, 0x43, 0x19, 0x23, 0x76, 0x1c, 0x1c, +0x35, 0x76, 0x14, 0x42, 0x19, 0x05, 0x30, 0x7c, 0x26, 0x26, +0x2c, 0x1f, 0x41, 0x38, 0x7c, 0x0f, 0x42, 0x00, 0x3f, 0xed, +0x3f, 0x33, 0x39, 0x2f, 0xed, 0x39, 0x39, 0x01, 0x10, 0xd6, +0xed, 0x33, 0x2f, 0xed, 0x32, 0x10, 0xde, 0xed, 0x33, 0x2f, +0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x01, 0x14, 0x0e, 0x02, 0x07, 0x1e, 0x03, +0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, +0x3e, 0x02, 0x37, 0x26, 0x26, 0x35, 0x34, 0x36, 0x37, 0x33, +0x06, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, +0x26, 0x27, 0x33, 0x16, 0x16, 0x07, 0x22, 0x0e, 0x02, 0x15, +0x14, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, +0x01, 0xa7, 0x09, 0x12, 0x1c, 0x13, 0x17, 0x2a, 0x1f, 0x13, +0x18, 0x34, 0x50, 0x39, 0x39, 0x52, 0x34, 0x18, 0x12, 0x1f, +0x2a, 0x17, 0x26, 0x23, 0x07, 0x08, 0x52, 0x05, 0x09, 0x2b, +0x2f, 0x2f, 0x2b, 0x09, 0x05, 0x52, 0x08, 0x07, 0xad, 0x1b, +0x30, 0x24, 0x15, 0x4b, 0x39, 0x1b, 0x30, 0x24, 0x15, 0x15, +0x24, 0x30, 0x01, 0xe1, 0x16, 0x2a, 0x26, 0x1d, 0x09, 0x09, +0x1b, 0x26, 0x33, 0x20, 0x29, 0x44, 0x33, 0x1c, 0x1c, 0x32, +0x45, 0x29, 0x20, 0x33, 0x26, 0x1b, 0x09, 0x12, 0x4f, 0x2b, +0x2b, 0x3c, 0x23, 0x20, 0x3d, 0x20, 0x3c, 0x3f, 0x3f, 0x3c, +0x20, 0x3d, 0x20, 0x23, 0x3c, 0xe1, 0x0d, 0x1c, 0x2b, 0x1f, +0x3f, 0x36, 0x0d, 0x1c, 0x2c, 0x20, 0x1f, 0x2b, 0x1c, 0x0d, +0x00, 0x00, 0x00, 0x02, 0x00, 0x21, 0xff, 0xf5, 0x01, 0xd4, +0x02, 0xb5, 0x00, 0x0b, 0x00, 0x35, 0x00, 0x9c, 0x40, 0x15, +0x2d, 0x18, 0x11, 0x00, 0x4d, 0x2d, 0x10, 0x10, 0x00, 0x4d, +0x2d, 0x18, 0x0f, 0x00, 0x4d, 0x2d, 0x20, 0x0e, 0x00, 0x4d, +0x2b, 0xb8, 0xff, 0xe8, 0xb4, 0x10, 0x11, 0x00, 0x4c, 0x2b, +0xb8, 0xff, 0xf0, 0x40, 0x0a, 0x0e, 0x0f, 0x00, 0x4c, 0x1a, +0x18, 0x08, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xe8, 0x40, 0x0a, +0x08, 0x00, 0x4d, 0x0a, 0x18, 0x0d, 0x10, 0x00, 0x4c, 0x08, +0xb8, 0xff, 0xe0, 0xb4, 0x0d, 0x10, 0x00, 0x4c, 0x04, 0xb8, +0xff, 0xe8, 0x40, 0x29, 0x0d, 0x10, 0x00, 0x4c, 0x02, 0x18, +0x0d, 0x10, 0x00, 0x4c, 0x0f, 0x2f, 0x82, 0x0c, 0x0c, 0x00, +0x82, 0x12, 0x37, 0x1f, 0x29, 0x82, 0x22, 0x22, 0x06, 0x82, +0x1c, 0x36, 0x1f, 0x0f, 0x03, 0x88, 0x2c, 0x2c, 0x32, 0x25, +0x4d, 0x09, 0x88, 0x17, 0x51, 0x00, 0x3f, 0xed, 0x3f, 0x33, +0x39, 0x2f, 0xed, 0x39, 0x39, 0x01, 0x10, 0xd6, 0xed, 0x33, +0x2f, 0xed, 0x32, 0x10, 0xde, 0xed, 0x33, 0x2f, 0xed, 0x32, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x34, 0x26, 0x23, 0x22, 0x06, +0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x13, 0x14, 0x06, 0x07, +0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, +0x35, 0x34, 0x36, 0x37, 0x26, 0x26, 0x35, 0x34, 0x36, 0x37, +0x33, 0x06, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, +0x34, 0x26, 0x27, 0x33, 0x16, 0x16, 0x01, 0x82, 0x4a, 0x3d, +0x3d, 0x4b, 0x4b, 0x3d, 0x3d, 0x4a, 0x34, 0x2b, 0x23, 0x2d, +0x3f, 0x20, 0x3a, 0x50, 0x2f, 0x30, 0x50, 0x3a, 0x20, 0x3f, +0x2d, 0x23, 0x2b, 0x09, 0x05, 0x50, 0x05, 0x06, 0x35, 0x34, +0x33, 0x35, 0x06, 0x05, 0x50, 0x05, 0x09, 0xd2, 0x45, 0x50, +0x50, 0x45, 0x45, 0x50, 0x50, 0x01, 0x95, 0x33, 0x4f, 0x0f, +0x16, 0x64, 0x45, 0x34, 0x52, 0x39, 0x1e, 0x1f, 0x39, 0x52, +0x33, 0x45, 0x64, 0x16, 0x0f, 0x4f, 0x33, 0x26, 0x47, 0x26, +0x20, 0x3e, 0x20, 0x48, 0x41, 0x41, 0x48, 0x20, 0x3e, 0x20, +0x26, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, 0xff, 0x59, +0x01, 0xc7, 0x02, 0x6b, 0x00, 0x21, 0x00, 0x40, 0x40, 0x21, +0x0f, 0x17, 0x73, 0x06, 0x06, 0x05, 0x1e, 0x19, 0x1e, 0x78, +0x00, 0x05, 0x14, 0x00, 0x05, 0x00, 0x23, 0x1f, 0x1f, 0x19, +0x22, 0x00, 0x1e, 0x79, 0x21, 0x41, 0x13, 0x0c, 0x19, 0x05, +0x79, 0x18, 0x44, 0x00, 0x3f, 0xed, 0x32, 0xdc, 0xcd, 0x3f, +0xed, 0x32, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xde, 0x87, +0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x33, 0x18, 0x2f, 0xfd, 0xcc, +0x31, 0x30, 0x01, 0x0e, 0x03, 0x07, 0x21, 0x15, 0x14, 0x0e, +0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, +0x36, 0x35, 0x35, 0x21, 0x35, 0x3e, 0x03, 0x37, 0x21, 0x35, +0x21, 0x01, 0xbf, 0x20, 0x4f, 0x52, 0x4d, 0x1d, 0x01, 0x33, +0x0b, 0x1c, 0x34, 0x28, 0x0d, 0x20, 0x0a, 0x08, 0x08, 0x16, +0x08, 0x21, 0x1b, 0xfe, 0xbf, 0x1f, 0x4b, 0x4e, 0x4e, 0x24, +0xfe, 0xe5, 0x01, 0x7a, 0x02, 0x2b, 0x2c, 0x79, 0x84, 0x85, +0x37, 0x46, 0x29, 0x3f, 0x2a, 0x15, 0x05, 0x02, 0x41, 0x02, +0x02, 0x2b, 0x29, 0x0f, 0x36, 0x3f, 0x85, 0x80, 0x78, 0x33, +0x46, 0x00, 0x00, 0x01, 0x00, 0x49, 0xff, 0x59, 0x01, 0xab, +0x01, 0xd0, 0x00, 0x21, 0x00, 0x40, 0x40, 0x21, 0x0f, 0x17, +0x7f, 0x06, 0x06, 0x05, 0x1e, 0x19, 0x1e, 0x81, 0x00, 0x05, +0x14, 0x00, 0x05, 0x00, 0x23, 0x1f, 0x1f, 0x19, 0x22, 0x00, +0x1e, 0x85, 0x21, 0x49, 0x13, 0x0c, 0x19, 0x05, 0x85, 0x18, +0x4c, 0x00, 0x3f, 0xed, 0x32, 0xdc, 0xcd, 0x3f, 0xed, 0x32, +0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xde, 0x87, 0x2b, 0x87, +0x7d, 0xc4, 0x01, 0x33, 0x18, 0x2f, 0xfd, 0xcc, 0x31, 0x30, +0x01, 0x0e, 0x03, 0x07, 0x33, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, +0x35, 0x21, 0x35, 0x3e, 0x03, 0x37, 0x23, 0x35, 0x21, 0x01, +0xa4, 0x12, 0x3e, 0x47, 0x46, 0x1b, 0xff, 0x09, 0x1a, 0x30, +0x27, 0x0d, 0x20, 0x0a, 0x07, 0x05, 0x19, 0x08, 0x22, 0x17, +0xfe, 0xe9, 0x15, 0x3f, 0x44, 0x41, 0x18, 0xe4, 0x01, 0x4e, +0x01, 0x92, 0x15, 0x4b, 0x5b, 0x64, 0x2d, 0x46, 0x27, 0x3d, +0x2c, 0x17, 0x05, 0x02, 0x3d, 0x02, 0x03, 0x2d, 0x28, 0x13, +0x37, 0x28, 0x5f, 0x5d, 0x54, 0x1c, 0x45, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x03, 0x31, +0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x01, 0x07, 0x01, 0x62, +0x00, 0x02, 0x00, 0x9a, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x02, +0x19, 0x1f, 0x04, 0x0f, 0x50, 0x02, 0x09, 0x17, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, +0x01, 0xb0, 0x02, 0x97, 0x02, 0x26, 0x00, 0x44, 0x00, 0x00, +0x01, 0x06, 0x01, 0x62, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, +0x02, 0x05, 0x33, 0x39, 0x1c, 0x13, 0x50, 0x02, 0x0f, 0x31, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x01, 0x00, 0x5b, 0xff, 0x57, +0x01, 0xcc, 0x02, 0x6b, 0x00, 0x26, 0x00, 0x5b, 0xb1, 0x11, +0x03, 0xb8, 0xff, 0xc0, 0x40, 0x2b, 0x0b, 0x0e, 0x48, 0x03, +0x24, 0x00, 0x17, 0x0b, 0x14, 0x14, 0x18, 0x1f, 0x1f, 0x1b, +0x1b, 0x22, 0x28, 0x1d, 0x21, 0x73, 0x18, 0x27, 0x20, 0x79, +0x1d, 0x1d, 0x21, 0x1c, 0x79, 0x19, 0x41, 0x21, 0x79, 0x18, +0x00, 0x14, 0x14, 0x18, 0x0f, 0x08, 0x23, 0x18, 0x44, 0x00, +0x3f, 0x33, 0xdc, 0xcd, 0x12, 0x39, 0x2f, 0xcd, 0x10, 0xed, +0x3f, 0xed, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xd6, 0xed, +0x32, 0x10, 0xce, 0x32, 0x2f, 0x32, 0x2f, 0x11, 0x39, 0x2f, +0xcc, 0x33, 0xdd, 0x32, 0xd5, 0x2b, 0xcd, 0x31, 0x30, 0x05, +0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, +0x37, 0x16, 0x16, 0x33, 0x32, 0x35, 0x34, 0x27, 0x27, 0x36, +0x36, 0x37, 0x23, 0x11, 0x21, 0x15, 0x21, 0x15, 0x33, 0x15, +0x23, 0x15, 0x21, 0x15, 0x23, 0x06, 0x06, 0x01, 0x27, 0x1a, +0x17, 0x09, 0x15, 0x23, 0x1a, 0x17, 0x28, 0x0b, 0x0a, 0x0b, +0x18, 0x0f, 0x20, 0x25, 0x07, 0x05, 0x0f, 0x07, 0xa3, 0x01, +0x5b, 0xfe, 0xf7, 0xe8, 0xe8, 0x01, 0x1f, 0x94, 0x05, 0x09, +0x21, 0x0c, 0x1e, 0x1d, 0x0a, 0x17, 0x13, 0x0d, 0x07, 0x05, +0x33, 0x04, 0x05, 0x14, 0x14, 0x0b, 0x02, 0x0d, 0x23, 0x0e, +0x02, 0x6b, 0x46, 0xbe, 0x46, 0xdb, 0x46, 0x08, 0x12, 0x00, +0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0xff, 0x57, 0x01, 0xc7, +0x01, 0xdb, 0x00, 0x30, 0x00, 0x39, 0x00, 0xda, 0xb9, 0x00, +0x36, 0xff, 0xf0, 0xb3, 0x0e, 0x00, 0x4d, 0x28, 0xb8, 0xff, +0xe0, 0xb4, 0x0d, 0x0e, 0x00, 0x4c, 0x28, 0xb8, 0xff, 0xe8, +0xb3, 0x0c, 0x00, 0x4d, 0x23, 0xb8, 0xff, 0xf0, 0xb3, 0x14, +0x00, 0x4d, 0x23, 0xb8, 0xff, 0xf8, 0xb3, 0x13, 0x00, 0x4d, +0x23, 0xb8, 0xff, 0xd8, 0xb3, 0x10, 0x00, 0x4d, 0x23, 0xb8, +0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x23, 0xb8, 0xff, 0xf0, +0xb3, 0x09, 0x00, 0x4d, 0x22, 0xb8, 0xff, 0xe0, 0xb3, 0x12, +0x00, 0x4d, 0x22, 0xb8, 0xff, 0xd8, 0xb3, 0x11, 0x00, 0x4d, +0x22, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x22, 0xb8, +0xff, 0xd8, 0x40, 0x0f, 0x0f, 0x00, 0x4d, 0x1f, 0x10, 0x10, +0x00, 0x4d, 0x1f, 0x18, 0x0f, 0x00, 0x4d, 0x11, 0x03, 0xb8, +0xff, 0xc0, 0x40, 0x2e, 0x0b, 0x0e, 0x48, 0x03, 0x30, 0x00, +0x17, 0x0b, 0x14, 0x14, 0x1c, 0x31, 0x82, 0x25, 0x2d, 0x2d, +0x25, 0x3b, 0x39, 0x26, 0x82, 0x1c, 0x3a, 0x00, 0x14, 0x14, +0x30, 0x0f, 0x08, 0x3a, 0x26, 0x86, 0x39, 0x39, 0x21, 0x2c, +0x2c, 0x29, 0x88, 0x17, 0x30, 0x51, 0x34, 0x88, 0x21, 0x50, +0x00, 0x3f, 0xed, 0x3f, 0x33, 0xed, 0x32, 0x2f, 0x11, 0x39, +0x2f, 0xed, 0x10, 0xdc, 0xcd, 0x12, 0x39, 0x2f, 0xcd, 0x01, +0x10, 0xd6, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, +0x12, 0x39, 0x2f, 0xcc, 0x33, 0xdd, 0x32, 0xd5, 0x2b, 0xcd, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x05, 0x16, 0x16, 0x15, +0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, +0x33, 0x32, 0x35, 0x34, 0x27, 0x27, 0x36, 0x36, 0x37, 0x2e, +0x03, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x15, 0x15, +0x21, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x06, +0x07, 0x13, 0x34, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x07, 0x01, +0x1b, 0x1a, 0x17, 0x09, 0x15, 0x23, 0x1a, 0x17, 0x28, 0x0b, +0x0a, 0x0b, 0x18, 0x0f, 0x20, 0x25, 0x07, 0x04, 0x0d, 0x06, +0x32, 0x4a, 0x31, 0x19, 0x26, 0x3e, 0x4e, 0x29, 0x5e, 0x66, +0xfe, 0xb4, 0x05, 0x55, 0x4d, 0x2c, 0x3e, 0x10, 0x0b, 0x0e, +0x46, 0x2d, 0x4d, 0x3e, 0x33, 0x1d, 0x2f, 0x22, 0x14, 0x03, +0x21, 0x0c, 0x1e, 0x1d, 0x0a, 0x17, 0x13, 0x0d, 0x07, 0x05, +0x33, 0x04, 0x05, 0x14, 0x14, 0x0b, 0x02, 0x0b, 0x1d, 0x0e, +0x06, 0x29, 0x3f, 0x52, 0x2f, 0x3e, 0x5c, 0x3c, 0x1e, 0x75, +0x77, 0x1d, 0x48, 0x4b, 0x0e, 0x08, 0x46, 0x08, 0x10, 0x02, +0x01, 0x20, 0x3b, 0x45, 0x16, 0x24, 0x2e, 0x18, 0x00, 0x00, +0x00, 0x05, 0x00, 0x1e, 0xff, 0xf3, 0x01, 0xd9, 0x03, 0x3d, +0x00, 0x0b, 0x00, 0x17, 0x00, 0x1b, 0x00, 0x2f, 0x00, 0x39, +0x00, 0xca, 0xb9, 0x00, 0x38, 0xff, 0xf0, 0x40, 0x14, 0x0e, +0x00, 0x4d, 0x36, 0x10, 0x0d, 0x0e, 0x00, 0x4c, 0x34, 0x18, +0x0e, 0x00, 0x4d, 0x34, 0x10, 0x0d, 0x00, 0x4d, 0x32, 0xb8, +0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x32, 0xb8, 0xff, 0xf0, +0x40, 0x13, 0x0d, 0x00, 0x4d, 0x2e, 0x18, 0x08, 0x00, 0x4d, +0x2d, 0x18, 0x10, 0x00, 0x4d, 0x2d, 0x10, 0x0f, 0x00, 0x4d, +0x29, 0xb8, 0xff, 0xe8, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x28, +0xb8, 0xff, 0xe8, 0xb3, 0x08, 0x00, 0x4d, 0x24, 0xb8, 0xff, +0xe8, 0xb3, 0x08, 0x00, 0x4d, 0x23, 0xb8, 0xff, 0xe8, 0xb3, +0x10, 0x00, 0x4d, 0x23, 0xb8, 0xff, 0xf0, 0x40, 0x38, 0x0f, +0x00, 0x4d, 0x1f, 0x18, 0x10, 0x00, 0x4d, 0x1f, 0x20, 0x0f, +0x00, 0x4d, 0x1e, 0x10, 0x08, 0x00, 0x4d, 0x1a, 0x1a, 0x15, +0x0f, 0x09, 0x1b, 0x1b, 0x03, 0x09, 0x09, 0x1c, 0x35, 0x76, +0x26, 0x3b, 0x30, 0x76, 0x1c, 0x40, 0x0b, 0x10, 0x48, 0x1c, +0x3a, 0x33, 0x7c, 0x2b, 0x46, 0x18, 0x1b, 0x12, 0x06, 0x0c, +0x00, 0x37, 0x7c, 0x21, 0x41, 0x00, 0x3f, 0xed, 0xde, 0x32, +0xdd, 0x32, 0xde, 0xcd, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0x2b, +0xed, 0x10, 0xde, 0xed, 0x12, 0x39, 0x2f, 0xcd, 0x32, 0x2f, +0x10, 0xde, 0xcd, 0x32, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x22, 0x26, 0x35, 0x34, 0x36, +0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x33, 0x22, 0x26, 0x35, +0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x27, 0x33, +0x15, 0x23, 0x03, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, +0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x37, 0x14, +0x16, 0x33, 0x32, 0x35, 0x34, 0x23, 0x22, 0x06, 0xa0, 0x15, +0x1b, 0x1b, 0x15, 0x15, 0x1b, 0x1b, 0x9f, 0x14, 0x1c, 0x1c, +0x14, 0x14, 0x1c, 0x1c, 0xdf, 0xe2, 0xe2, 0x6b, 0x20, 0x3a, +0x51, 0x32, 0x31, 0x52, 0x3a, 0x21, 0x21, 0x3a, 0x52, 0x31, +0x32, 0x51, 0x3a, 0x20, 0x54, 0x42, 0x45, 0x8c, 0x8c, 0x45, +0x42, 0x02, 0x87, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, +0x1b, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, 0xb6, +0x39, 0xfe, 0x28, 0x53, 0x76, 0x4c, 0x24, 0x24, 0x4c, 0x76, +0x53, 0x53, 0x77, 0x4c, 0x23, 0x23, 0x4c, 0x77, 0x53, 0x7a, +0x78, 0xf2, 0xf2, 0x78, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, +0x01, 0xcc, 0x02, 0xcc, 0x02, 0x26, 0x00, 0x52, 0x00, 0x00, +0x01, 0x06, 0x02, 0xa7, 0x00, 0x00, 0x00, 0x1e, 0x40, 0x15, +0x04, 0x03, 0x02, 0x00, 0x22, 0x34, 0x09, 0x00, 0x50, 0x04, +0x0e, 0x3a, 0x4f, 0x03, 0x0e, 0x2c, 0x4f, 0x02, 0x0e, 0x20, +0x4f, 0x2b, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, +0x00, 0x04, 0x00, 0x1e, 0xff, 0xf3, 0x01, 0xd9, 0x03, 0x3d, +0x00, 0x1d, 0x00, 0x21, 0x00, 0x35, 0x00, 0x3f, 0x00, 0xff, +0xb9, 0x00, 0x3e, 0xff, 0xf0, 0x40, 0x14, 0x0e, 0x00, 0x4d, +0x3c, 0x18, 0x0d, 0x0e, 0x00, 0x4c, 0x3a, 0x18, 0x0e, 0x00, +0x4d, 0x3a, 0x10, 0x0d, 0x00, 0x4d, 0x38, 0xb8, 0xff, 0xe8, +0xb3, 0x0e, 0x00, 0x4d, 0x38, 0xb8, 0xff, 0xf0, 0x40, 0x0f, +0x0d, 0x00, 0x4d, 0x34, 0x18, 0x08, 0x00, 0x4d, 0x33, 0x20, +0x0f, 0x10, 0x00, 0x4c, 0x2f, 0xb8, 0xff, 0xf0, 0xb3, 0x10, +0x00, 0x4d, 0x2f, 0xb8, 0xff, 0xe8, 0xb3, 0x0f, 0x00, 0x4d, +0x2e, 0xb8, 0xff, 0xe8, 0xb3, 0x08, 0x00, 0x4d, 0x2a, 0xb8, +0xff, 0xe8, 0xb3, 0x08, 0x00, 0x4d, 0x29, 0xb8, 0xff, 0xe8, +0x40, 0x1c, 0x0f, 0x10, 0x00, 0x4c, 0x25, 0x18, 0x0f, 0x10, +0x00, 0x4c, 0x24, 0x18, 0x08, 0x00, 0x4d, 0x12, 0x10, 0x0f, +0x10, 0x00, 0x4c, 0x12, 0x18, 0x0d, 0x0e, 0x00, 0x4c, 0x03, +0xb8, 0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x03, 0xb8, 0xff, +0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x03, 0xb8, 0xff, 0xe8, 0xb3, +0x0e, 0x00, 0x4d, 0x03, 0xb8, 0xff, 0xe0, 0x40, 0x2f, 0x0d, +0x00, 0x4d, 0x20, 0x20, 0x1d, 0x00, 0x0f, 0x21, 0x21, 0x0e, +0x0f, 0x0f, 0x22, 0x3b, 0x76, 0x2c, 0x41, 0x36, 0x76, 0x22, +0x40, 0x0b, 0x10, 0x48, 0x22, 0x40, 0x39, 0x7c, 0x31, 0x46, +0x1e, 0x21, 0x14, 0x1d, 0x1d, 0x14, 0x0b, 0x1a, 0x05, 0x0e, +0x0e, 0x05, 0x3d, 0x7c, 0x27, 0x41, 0x00, 0x3f, 0xed, 0xce, +0x32, 0x2f, 0x10, 0xcd, 0xdc, 0xcd, 0x32, 0x2f, 0x10, 0xde, +0xcd, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0x2b, 0xed, 0x10, 0xde, +0xed, 0x12, 0x39, 0x2f, 0xcd, 0x33, 0x2f, 0x10, 0xdc, 0xcd, +0x33, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x0e, 0x03, 0x23, 0x22, +0x26, 0x27, 0x26, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x3e, +0x03, 0x33, 0x32, 0x16, 0x17, 0x16, 0x16, 0x33, 0x32, 0x36, +0x37, 0x27, 0x33, 0x15, 0x23, 0x03, 0x34, 0x3e, 0x02, 0x33, +0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, +0x02, 0x37, 0x14, 0x16, 0x33, 0x32, 0x35, 0x34, 0x23, 0x22, +0x06, 0x01, 0x84, 0x03, 0x10, 0x16, 0x1e, 0x11, 0x10, 0x1e, +0x0d, 0x0f, 0x12, 0x0b, 0x0f, 0x17, 0x06, 0x28, 0x03, 0x0f, +0x16, 0x1c, 0x12, 0x11, 0x1d, 0x0d, 0x10, 0x11, 0x0b, 0x0f, +0x18, 0x06, 0xd3, 0xe3, 0xe3, 0x6a, 0x20, 0x3a, 0x51, 0x32, +0x31, 0x52, 0x3a, 0x21, 0x21, 0x3a, 0x52, 0x31, 0x32, 0x51, +0x3a, 0x20, 0x54, 0x42, 0x45, 0x8c, 0x8c, 0x45, 0x42, 0x02, +0xd7, 0x0b, 0x1a, 0x16, 0x10, 0x0a, 0x08, 0x07, 0x07, 0x19, +0x0d, 0x12, 0x0b, 0x1a, 0x17, 0x10, 0x0a, 0x08, 0x08, 0x06, +0x18, 0x0d, 0x54, 0x39, 0xfe, 0x28, 0x53, 0x76, 0x4c, 0x24, +0x24, 0x4c, 0x76, 0x53, 0x53, 0x77, 0x4c, 0x23, 0x23, 0x4c, +0x77, 0x53, 0x7a, 0x78, 0xf2, 0xf2, 0x78, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0xcc, +0x02, 0x26, 0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x02, 0xac, +0x00, 0x00, 0x00, 0x17, 0x40, 0x10, 0x03, 0x02, 0x00, 0x2f, +0x20, 0x09, 0x00, 0x50, 0x03, 0x0e, 0x40, 0x4f, 0x02, 0x0e, +0x2e, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, +0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, 0x03, 0x22, 0x02, 0x26, +0x00, 0x32, 0x00, 0x00, 0x01, 0x07, 0x01, 0x62, 0x00, 0x00, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x22, 0x28, +0x00, 0x09, 0x50, 0x02, 0x04, 0x20, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, +0x02, 0x97, 0x02, 0x26, 0x00, 0x52, 0x00, 0x00, 0x01, 0x06, +0x01, 0x62, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, +0x22, 0x28, 0x09, 0x00, 0x50, 0x02, 0x0e, 0x20, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x04, 0x00, 0x1e, 0xff, 0xf3, 0x01, 0xd9, +0x03, 0x3d, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x23, 0x00, 0x2d, +0x00, 0xc0, 0xb9, 0x00, 0x2c, 0xff, 0xe8, 0xb3, 0x0e, 0x00, +0x4d, 0x2c, 0xb8, 0xff, 0xf8, 0x40, 0x18, 0x0d, 0x00, 0x4d, +0x2a, 0x18, 0x0e, 0x00, 0x4d, 0x2a, 0x10, 0x0d, 0x00, 0x4d, +0x28, 0x20, 0x0e, 0x00, 0x4d, 0x28, 0x10, 0x0d, 0x00, 0x4d, +0x26, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x26, 0xb8, +0xff, 0xf8, 0x40, 0x0f, 0x0d, 0x00, 0x4d, 0x21, 0x18, 0x0f, +0x10, 0x00, 0x4c, 0x21, 0x18, 0x08, 0x00, 0x4d, 0x1d, 0xb8, +0xff, 0xf0, 0xb3, 0x10, 0x00, 0x4d, 0x1d, 0xb8, 0xff, 0xe8, +0xb3, 0x0f, 0x00, 0x4d, 0x1d, 0xb8, 0xff, 0xe8, 0xb3, 0x08, +0x00, 0x4d, 0x17, 0xb8, 0xff, 0xe8, 0xb4, 0x0f, 0x10, 0x00, +0x4c, 0x17, 0xb8, 0xff, 0xe0, 0x40, 0x2d, 0x08, 0x00, 0x4d, +0x13, 0x18, 0x0f, 0x10, 0x00, 0x4c, 0x13, 0x18, 0x08, 0x00, +0x4d, 0x0e, 0x0f, 0x09, 0x03, 0x03, 0x10, 0x29, 0x76, 0x1a, +0x2f, 0x24, 0x76, 0x10, 0x40, 0x0b, 0x10, 0x48, 0x10, 0x2e, +0x27, 0x7c, 0x1f, 0x46, 0x0c, 0x0f, 0x06, 0x00, 0x2b, 0x7c, +0x15, 0x41, 0x00, 0x3f, 0xed, 0xde, 0xdd, 0xde, 0xcd, 0x3f, +0xed, 0x01, 0x10, 0xd6, 0x2b, 0xed, 0x10, 0xde, 0xed, 0x12, +0x39, 0x2f, 0xcd, 0xd6, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x22, 0x26, 0x35, 0x34, 0x36, +0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x27, 0x33, 0x15, 0x23, +0x03, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, +0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x37, 0x14, 0x16, 0x33, +0x32, 0x35, 0x34, 0x23, 0x22, 0x06, 0xfa, 0x15, 0x1c, 0x1c, +0x15, 0x15, 0x1c, 0x1c, 0x86, 0xe2, 0xe2, 0x6b, 0x20, 0x3a, +0x51, 0x32, 0x31, 0x52, 0x3a, 0x21, 0x21, 0x3a, 0x52, 0x31, +0x32, 0x51, 0x3a, 0x20, 0x54, 0x42, 0x45, 0x8c, 0x8c, 0x45, +0x42, 0x02, 0x87, 0x1b, 0x17, 0x17, 0x1b, 0x1b, 0x17, 0x17, +0x1b, 0xb6, 0x39, 0xfe, 0x28, 0x53, 0x76, 0x4c, 0x24, 0x24, +0x4c, 0x76, 0x53, 0x53, 0x77, 0x4c, 0x23, 0x23, 0x4c, 0x77, +0x53, 0x7a, 0x78, 0xf2, 0xf2, 0x78, 0xff, 0xff, 0x00, 0x28, +0xff, 0xf5, 0x01, 0xcc, 0x02, 0xcc, 0x02, 0x26, 0x00, 0x52, +0x00, 0x00, 0x01, 0x06, 0x02, 0xa8, 0x00, 0x00, 0x00, 0x17, +0x40, 0x10, 0x03, 0x02, 0x00, 0x2c, 0x2d, 0x09, 0x00, 0x50, +0x03, 0x0e, 0x2e, 0x4f, 0x02, 0x0e, 0x20, 0x4f, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x00, +0x01, 0xe8, 0x03, 0x06, 0x02, 0x26, 0x00, 0x3c, 0x00, 0x00, +0x01, 0x07, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x00, 0x11, 0x12, 0x04, 0x0c, 0x50, 0x01, +0x04, 0x13, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x24, 0xff, 0x58, 0x01, 0xcd, 0x02, 0x7b, 0x02, 0x26, +0x00, 0x5c, 0x00, 0x00, 0x01, 0x06, 0x00, 0x8a, 0x00, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x01, 0x21, 0x22, 0x20, 0x15, +0x50, 0x01, 0x09, 0x23, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x02, +0x00, 0x36, 0xff, 0x58, 0x01, 0xb3, 0x02, 0xb0, 0x00, 0x19, +0x00, 0x26, 0x00, 0x5f, 0xb6, 0x0e, 0x18, 0x09, 0x0c, 0x00, +0x4c, 0x09, 0xb8, 0xff, 0xe0, 0xb4, 0x09, 0x0c, 0x00, 0x4c, +0x05, 0xb8, 0xff, 0xe0, 0x40, 0x25, 0x09, 0x0c, 0x00, 0x4c, +0x24, 0x07, 0x28, 0x1d, 0x19, 0x7f, 0x0f, 0x16, 0x17, 0x10, +0x11, 0x11, 0x17, 0x27, 0x16, 0x85, 0x19, 0x4d, 0x12, 0x0f, +0x1d, 0x1d, 0x21, 0x00, 0x02, 0x1a, 0x21, 0x0c, 0x11, 0x10, +0x10, 0x0c, 0x4b, 0x00, 0x3f, 0x33, 0x2f, 0x33, 0x10, 0xdd, +0xde, 0xcd, 0x32, 0x12, 0x39, 0x11, 0x33, 0x33, 0x3f, 0xed, +0x01, 0x10, 0xc6, 0x32, 0x2f, 0x33, 0x10, 0xdd, 0x32, 0xed, +0x32, 0x10, 0xde, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x37, +0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x26, 0x27, 0x07, 0x27, 0x37, 0x26, 0x34, 0x35, 0x11, +0x23, 0x35, 0x33, 0x13, 0x22, 0x06, 0x07, 0x15, 0x14, 0x16, +0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0xeb, 0x25, 0x2c, 0x1b, +0x2c, 0x1f, 0x11, 0x0f, 0x20, 0x32, 0x23, 0x33, 0x40, 0x11, +0x43, 0x2b, 0x5d, 0x01, 0x63, 0xb5, 0x45, 0x17, 0x1f, 0x0f, +0x24, 0x20, 0x20, 0x20, 0x1f, 0x40, 0x1a, 0x15, 0x22, 0x2f, +0x19, 0x16, 0x2e, 0x25, 0x17, 0x29, 0x25, 0x51, 0x26, 0x70, +0x08, 0x0d, 0x08, 0x02, 0x5f, 0x46, 0xfd, 0x6c, 0x14, 0x10, +0x16, 0x20, 0x28, 0x27, 0x1a, 0x1b, 0x26, 0x00, 0x00, 0x00, +0x00, 0x02, 0x00, 0x25, 0xff, 0x58, 0x01, 0xf4, 0x01, 0xda, +0x00, 0x2c, 0x00, 0x39, 0x00, 0x6d, 0xb6, 0x23, 0x20, 0x08, +0x0d, 0x00, 0x4c, 0x1e, 0xb8, 0xff, 0xd8, 0xb4, 0x08, 0x0d, +0x00, 0x4c, 0x1a, 0xb8, 0xff, 0xd8, 0xb4, 0x08, 0x0d, 0x00, +0x4c, 0x11, 0xb8, 0xff, 0xd8, 0x40, 0x28, 0x09, 0x0e, 0x00, +0x4c, 0x09, 0x7f, 0x0a, 0x3a, 0x25, 0x26, 0x26, 0x24, 0x2c, +0x7f, 0x14, 0x30, 0x37, 0x1c, 0x30, 0x24, 0x2d, 0x25, 0x14, +0x27, 0x26, 0x17, 0x2d, 0x34, 0x21, 0x26, 0x25, 0x25, 0x21, +0x4b, 0x05, 0x88, 0x0e, 0x50, 0x0a, 0x4c, 0x00, 0x3f, 0x3f, +0xed, 0x3f, 0x33, 0x2f, 0x33, 0x10, 0xdd, 0xde, 0xcd, 0x11, +0x39, 0x39, 0x11, 0x12, 0x39, 0x39, 0x01, 0x2f, 0xdd, 0xde, +0x32, 0xed, 0x32, 0x32, 0x2f, 0x33, 0x10, 0xd6, 0xed, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x34, 0x2e, 0x02, 0x23, +0x22, 0x06, 0x07, 0x11, 0x23, 0x11, 0x36, 0x36, 0x33, 0x32, +0x1e, 0x02, 0x15, 0x15, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, +0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x07, 0x27, +0x37, 0x34, 0x26, 0x26, 0x34, 0x35, 0x17, 0x22, 0x06, 0x07, +0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0xf0, +0x07, 0x11, 0x1b, 0x13, 0x0f, 0x1e, 0x05, 0x53, 0x16, 0x48, +0x30, 0x2a, 0x37, 0x21, 0x0d, 0x11, 0x22, 0x15, 0x18, 0x27, +0x1c, 0x0f, 0x0e, 0x1d, 0x2e, 0x1f, 0x2f, 0x3b, 0x10, 0x43, +0x2b, 0x5e, 0x01, 0x01, 0x8d, 0x13, 0x1a, 0x0e, 0x20, 0x1a, +0x1a, 0x1a, 0x19, 0x01, 0x03, 0x2b, 0x37, 0x20, 0x0c, 0x08, +0x02, 0xfe, 0x79, 0x01, 0xc3, 0x08, 0x0f, 0x18, 0x30, 0x47, +0x2f, 0xdc, 0x0d, 0x0d, 0x15, 0x22, 0x2f, 0x19, 0x16, 0x2e, +0x25, 0x17, 0x29, 0x25, 0x51, 0x26, 0x70, 0x04, 0x10, 0x13, +0x10, 0x04, 0x0d, 0x14, 0x10, 0x16, 0x20, 0x28, 0x27, 0x1a, +0x1b, 0x26, 0x00, 0x02, 0x00, 0x3f, 0xff, 0x58, 0x01, 0xb3, +0x02, 0x60, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x79, 0xb6, 0x0f, +0x20, 0x08, 0x0d, 0x00, 0x4c, 0x0a, 0xb8, 0xff, 0xe0, 0xb4, +0x08, 0x0d, 0x00, 0x4c, 0x06, 0xb8, 0xff, 0xd8, 0x40, 0x33, +0x08, 0x0d, 0x00, 0x4c, 0x08, 0x2b, 0x24, 0x24, 0x1d, 0x20, +0x7f, 0x1a, 0x10, 0x17, 0x17, 0x18, 0x1f, 0x2f, 0x11, 0x12, +0x12, 0x00, 0x18, 0x01, 0x08, 0x18, 0x2e, 0x1b, 0x1c, 0x20, +0x17, 0x85, 0x1d, 0x1a, 0x49, 0x24, 0x10, 0x21, 0x11, 0x00, +0x13, 0x12, 0x03, 0x21, 0x28, 0x0d, 0x12, 0x11, 0x11, 0x0d, +0x4b, 0x00, 0x3f, 0x33, 0x2f, 0x33, 0x10, 0xdd, 0xde, 0xcd, +0x11, 0x39, 0x39, 0x11, 0x12, 0x39, 0x39, 0x3f, 0x33, 0xed, +0x32, 0xcd, 0x32, 0x01, 0x10, 0xc6, 0x5e, 0x5d, 0x32, 0x2f, +0x33, 0x10, 0xce, 0x11, 0x39, 0x2f, 0x33, 0x33, 0xed, 0x32, +0x32, 0x10, 0xde, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x37, +0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x26, 0x27, 0x07, 0x27, 0x37, 0x26, 0x34, 0x35, +0x11, 0x23, 0x35, 0x33, 0x35, 0x37, 0x15, 0x33, 0x15, 0x23, +0x13, 0x22, 0x06, 0x07, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, +0x35, 0x34, 0x26, 0xf3, 0x12, 0x20, 0x17, 0x1b, 0x2c, 0x1f, +0x11, 0x0f, 0x20, 0x32, 0x23, 0x33, 0x38, 0x11, 0x43, 0x2b, +0x5d, 0x01, 0x62, 0x62, 0x52, 0xbb, 0xbb, 0x3d, 0x17, 0x17, +0x0f, 0x1c, 0x20, 0x20, 0x20, 0x1f, 0x40, 0x0d, 0x0d, 0x15, +0x22, 0x2f, 0x19, 0x16, 0x2e, 0x25, 0x17, 0x29, 0x25, 0x51, +0x26, 0x70, 0x08, 0x0d, 0x08, 0x01, 0x80, 0x45, 0x82, 0x0e, +0x90, 0x45, 0xfe, 0x91, 0x14, 0x10, 0x16, 0x20, 0x28, 0x27, +0x1a, 0x1b, 0x26, 0x00, 0x00, 0x03, 0x00, 0x1b, 0xff, 0xf5, +0x01, 0xd9, 0x02, 0xb5, 0x00, 0x1e, 0x00, 0x2f, 0x00, 0x40, +0x00, 0xa3, 0xb9, 0x00, 0x3b, 0xff, 0xe8, 0xb4, 0x11, 0x12, +0x00, 0x4c, 0x35, 0xb8, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, +0x35, 0xb8, 0xff, 0xf0, 0x40, 0x1d, 0x11, 0x00, 0x4d, 0x18, +0x10, 0x0c, 0x00, 0x4d, 0x18, 0x18, 0x0b, 0x00, 0x4d, 0x18, +0x20, 0x0a, 0x00, 0x4d, 0x18, 0x28, 0x09, 0x00, 0x4d, 0x14, +0x10, 0x09, 0x00, 0x4d, 0x0c, 0xb8, 0xff, 0xf0, 0xb3, 0x0b, +0x00, 0x4d, 0x08, 0xb8, 0xff, 0xf0, 0xb3, 0x0d, 0x00, 0x4d, +0x08, 0xb8, 0xff, 0xe8, 0xb3, 0x0c, 0x00, 0x4d, 0x08, 0xb8, +0xff, 0xe0, 0x40, 0x28, 0x0b, 0x00, 0x4d, 0x10, 0x1f, 0x02, +0x2f, 0x7f, 0x3f, 0x1e, 0x30, 0x30, 0x16, 0x27, 0x82, 0x0a, +0x42, 0x38, 0x82, 0x16, 0x41, 0x33, 0x89, 0x1b, 0x50, 0x3d, +0x89, 0x13, 0x51, 0x22, 0x89, 0x0d, 0x51, 0x2c, 0x89, 0x05, +0x50, 0x00, 0x01, 0x4d, 0x00, 0x3f, 0x33, 0x3f, 0xed, 0x3f, +0xed, 0x3f, 0xed, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0xed, 0x10, +0xde, 0xed, 0x11, 0x39, 0x2f, 0x33, 0x33, 0xed, 0x32, 0x32, +0x39, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x37, 0x15, 0x36, 0x36, +0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, +0x27, 0x06, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x3e, 0x02, +0x33, 0x32, 0x16, 0x17, 0x13, 0x16, 0x16, 0x33, 0x32, 0x3e, +0x02, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0x23, +0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, +0x33, 0x32, 0x36, 0x37, 0xd5, 0x4a, 0x0e, 0x20, 0x12, 0x16, +0x2c, 0x23, 0x15, 0x4b, 0x40, 0x18, 0x2a, 0x11, 0x10, 0x28, +0x17, 0x48, 0x49, 0x16, 0x24, 0x2e, 0x17, 0x14, 0x1f, 0x08, +0x4a, 0x08, 0x14, 0x08, 0x0f, 0x1b, 0x14, 0x0b, 0x08, 0x0f, +0x15, 0x0d, 0x0e, 0x1b, 0x0b, 0x4a, 0x07, 0x1a, 0x0f, 0x0d, +0x16, 0x11, 0x09, 0x0b, 0x13, 0x18, 0x0e, 0x0e, 0x17, 0x04, +0x02, 0xa7, 0x0e, 0xf6, 0x0d, 0x0f, 0x18, 0x38, 0x5d, 0x46, +0x7a, 0x79, 0x0d, 0x09, 0x09, 0x0d, 0x82, 0x71, 0x46, 0x5d, +0x38, 0x18, 0x12, 0x0a, 0xfe, 0x85, 0x05, 0x06, 0x12, 0x2a, +0x43, 0x30, 0x36, 0x44, 0x27, 0x0e, 0x15, 0x0f, 0x0d, 0x17, +0x0e, 0x27, 0x44, 0x36, 0x30, 0x43, 0x2a, 0x12, 0x07, 0x03, +0x00, 0x00, 0x00, 0x03, 0x00, 0x1b, 0xff, 0x5b, 0x01, 0xd9, +0x01, 0xdb, 0x00, 0x1e, 0x00, 0x2f, 0x00, 0x40, 0x00, 0x6e, +0xb9, 0x00, 0x2a, 0xff, 0xf0, 0xb4, 0x11, 0x12, 0x00, 0x4c, +0x24, 0xb8, 0xff, 0xe0, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x16, +0xb8, 0xff, 0xe8, 0x40, 0x35, 0x0b, 0x00, 0x4d, 0x09, 0x18, +0x09, 0x00, 0x4d, 0x06, 0x10, 0x0a, 0x0b, 0x00, 0x4c, 0x06, +0x20, 0x09, 0x00, 0x4d, 0x0e, 0x1c, 0x40, 0x7f, 0x00, 0x1f, +0x1f, 0x08, 0x38, 0x82, 0x14, 0x42, 0x27, 0x82, 0x08, 0x41, +0x1e, 0x4b, 0x33, 0x89, 0x19, 0x51, 0x3d, 0x89, 0x11, 0x50, +0x22, 0x89, 0x0b, 0x50, 0x2c, 0x89, 0x03, 0x51, 0x00, 0x3f, +0xed, 0x3f, 0xed, 0x3f, 0xed, 0x3f, 0xed, 0x3f, 0x01, 0x10, +0xd6, 0xed, 0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, 0x33, 0xed, +0x32, 0x39, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x37, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x36, +0x33, 0x32, 0x16, 0x17, 0x36, 0x36, 0x33, 0x32, 0x16, 0x15, +0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x15, 0x23, 0x11, +0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, +0x33, 0x32, 0x36, 0x37, 0x33, 0x16, 0x16, 0x33, 0x32, 0x3e, +0x02, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0xd5, +0x0e, 0x20, 0x12, 0x17, 0x2b, 0x23, 0x15, 0x4b, 0x40, 0x18, +0x2a, 0x11, 0x10, 0x27, 0x18, 0x48, 0x49, 0x16, 0x24, 0x2e, +0x17, 0x14, 0x1f, 0x08, 0x4a, 0x08, 0x14, 0x08, 0x0f, 0x1b, +0x14, 0x0b, 0x08, 0x0f, 0x15, 0x0d, 0x0e, 0x1b, 0x0b, 0x4a, +0x07, 0x1a, 0x0f, 0x0d, 0x16, 0x10, 0x0a, 0x0b, 0x13, 0x19, +0x0d, 0x0e, 0x17, 0x04, 0x12, 0x0e, 0x0f, 0x18, 0x38, 0x5d, +0x46, 0x7b, 0x78, 0x0d, 0x09, 0x09, 0x0d, 0x82, 0x71, 0x46, +0x5d, 0x38, 0x18, 0x12, 0x0b, 0xb7, 0x02, 0x31, 0x06, 0x05, +0x12, 0x29, 0x43, 0x31, 0x36, 0x44, 0x27, 0x0e, 0x15, 0x10, +0x0d, 0x18, 0x0e, 0x27, 0x44, 0x36, 0x31, 0x43, 0x29, 0x12, +0x07, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x09, 0xff, 0xa6, +0x01, 0xeb, 0x02, 0xb6, 0x00, 0x19, 0x00, 0x21, 0x00, 0x24, +0x00, 0x9d, 0x40, 0x53, 0x12, 0x03, 0x13, 0x03, 0x7e, 0x04, +0x12, 0x14, 0x04, 0x04, 0x12, 0x13, 0x13, 0x06, 0x1d, 0x1b, +0x1a, 0x0d, 0x07, 0x1a, 0x07, 0x78, 0x08, 0x0d, 0x14, 0x08, +0x08, 0x0d, 0x21, 0x24, 0x01, 0x00, 0x0e, 0x00, 0x1a, 0x00, +0x78, 0x19, 0x0e, 0x14, 0x19, 0x0e, 0x1a, 0x08, 0x19, 0x26, +0x04, 0x04, 0x08, 0x25, 0x00, 0x19, 0x44, 0x13, 0x12, 0x12, +0x0d, 0x05, 0x02, 0x01, 0x06, 0x79, 0x24, 0x23, 0x1e, 0x22, +0x1f, 0x14, 0x11, 0x04, 0x0d, 0x1d, 0x1d, 0x08, 0x1a, 0x0e, +0x0d, 0x41, 0x07, 0x08, 0x44, 0x04, 0x03, 0x00, 0x2f, 0x33, +0x3f, 0x33, 0x3f, 0x33, 0x33, 0x12, 0x39, 0x2f, 0x12, 0x17, +0x39, 0x33, 0x33, 0x33, 0xed, 0x32, 0x32, 0x32, 0x11, 0x33, +0x2f, 0x33, 0x3f, 0x33, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, +0xde, 0x11, 0x39, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x10, 0xc4, +0xc4, 0x0e, 0xc4, 0x87, 0x05, 0x18, 0x10, 0x2b, 0x87, 0x7d, +0xc4, 0x10, 0x0e, 0xc4, 0x05, 0xc4, 0xc4, 0x01, 0x33, 0x18, +0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x21, +0x27, 0x23, 0x07, 0x27, 0x37, 0x23, 0x07, 0x23, 0x3e, 0x03, +0x37, 0x33, 0x16, 0x16, 0x17, 0x37, 0x17, 0x07, 0x1e, 0x03, +0x17, 0x03, 0x06, 0x06, 0x07, 0x33, 0x37, 0x26, 0x26, 0x17, +0x07, 0x33, 0x01, 0x94, 0x25, 0x58, 0x47, 0x3f, 0x42, 0x52, +0x24, 0x54, 0x11, 0x2a, 0x31, 0x36, 0x1e, 0x66, 0x05, 0x09, +0x06, 0x27, 0x3d, 0x3f, 0x13, 0x24, 0x21, 0x1e, 0x0d, 0xf2, +0x17, 0x36, 0x18, 0x52, 0x3a, 0x0b, 0x12, 0x40, 0x1d, 0x39, +0xa2, 0xfc, 0x12, 0xea, 0xa2, 0x42, 0x9a, 0xa2, 0xa3, 0x4a, +0x10, 0x1c, 0x10, 0x87, 0x10, 0xde, 0x3b, 0x79, 0x75, 0x6f, +0x30, 0x02, 0x23, 0x3f, 0xa6, 0x58, 0xce, 0x21, 0x34, 0xc1, +0x64, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x2e, 0xff, 0xa6, +0x01, 0xd9, 0x02, 0xb6, 0x00, 0x23, 0x00, 0x2b, 0x00, 0xde, +0xb9, 0x00, 0x2a, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x2a, +0xb8, 0xff, 0xf0, 0xb3, 0x11, 0x00, 0x4d, 0x2a, 0xb8, 0xff, +0xf0, 0x40, 0x14, 0x0d, 0x00, 0x4d, 0x29, 0x10, 0x0b, 0x00, +0x4d, 0x28, 0x08, 0x0d, 0x00, 0x4d, 0x28, 0x18, 0x0b, 0x0c, +0x00, 0x4c, 0x26, 0xb8, 0xff, 0xe8, 0xb4, 0x0f, 0x10, 0x00, +0x4c, 0x19, 0xb8, 0xff, 0xe8, 0x40, 0x0a, 0x0f, 0x10, 0x00, +0x4c, 0x0f, 0x20, 0x0e, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xd8, +0xb3, 0x12, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xe8, 0xb3, 0x11, +0x00, 0x4d, 0x01, 0xb8, 0xff, 0xd0, 0xb3, 0x10, 0x00, 0x4d, +0x01, 0xb8, 0xff, 0xd8, 0x40, 0x39, 0x0f, 0x00, 0x4d, 0x09, +0x27, 0x28, 0x14, 0x15, 0x08, 0x15, 0x17, 0x1d, 0x1e, 0x06, +0x07, 0x16, 0x16, 0x16, 0x00, 0x00, 0x1a, 0x2d, 0x07, 0x08, +0x08, 0x24, 0x76, 0x0c, 0x2c, 0x28, 0x1d, 0x1b, 0x1b, 0x29, +0x7c, 0x11, 0x16, 0x15, 0x15, 0x17, 0x14, 0x11, 0x45, 0x27, +0x23, 0x23, 0x1e, 0x20, 0x7c, 0x03, 0x08, 0x07, 0x07, 0x09, +0x06, 0x03, 0x46, 0x00, 0x3f, 0x33, 0x33, 0x33, 0x2f, 0x33, +0x10, 0xed, 0x32, 0x32, 0x2f, 0x32, 0x3f, 0x33, 0x33, 0x33, +0x2f, 0x33, 0x10, 0xed, 0x32, 0x2f, 0x32, 0x32, 0x01, 0x10, +0xd6, 0xed, 0x33, 0x2f, 0xcd, 0x10, 0xce, 0x32, 0x2f, 0x32, +0x2f, 0x7d, 0x87, 0xc4, 0xc4, 0xc4, 0xc4, 0x01, 0x18, 0xdd, +0x7d, 0x87, 0xc4, 0xc4, 0xc4, 0xc4, 0x31, 0x30, 0x01, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x25, 0x06, 0x06, 0x23, 0x22, 0x26, 0x27, 0x07, +0x27, 0x37, 0x26, 0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, +0x16, 0x17, 0x37, 0x17, 0x07, 0x16, 0x16, 0x17, 0x07, 0x26, +0x27, 0x03, 0x16, 0x33, 0x32, 0x36, 0x37, 0x25, 0x14, 0x16, +0x17, 0x13, 0x23, 0x22, 0x06, 0x01, 0xcc, 0x23, 0x4f, 0x2d, +0x11, 0x21, 0x0f, 0x17, 0x40, 0x19, 0x3b, 0x45, 0x28, 0x47, +0x62, 0x3b, 0x08, 0x10, 0x08, 0x12, 0x3e, 0x11, 0x10, 0x20, +0x10, 0x18, 0x1c, 0x20, 0x85, 0x1b, 0x1c, 0x1d, 0x40, 0x22, +0xfe, 0xcc, 0x24, 0x20, 0x81, 0x09, 0x5e, 0x5e, 0x1a, 0x14, +0x13, 0x03, 0x05, 0x55, 0x12, 0x5b, 0x22, 0x90, 0x71, 0x4f, +0x78, 0x52, 0x2a, 0x01, 0x01, 0x3f, 0x10, 0x3c, 0x05, 0x0e, +0x09, 0x44, 0x0f, 0x0a, 0xfe, 0x21, 0x08, 0x0f, 0x13, 0xd8, +0x4b, 0x66, 0x1e, 0x01, 0xc9, 0x88, 0x00, 0x00, 0x00, 0x02, +0x00, 0x28, 0xff, 0xb5, 0x01, 0xc3, 0x02, 0x25, 0x00, 0x24, +0x00, 0x2d, 0x00, 0xc3, 0xb9, 0x00, 0x2b, 0xff, 0xe0, 0x40, +0x13, 0x0c, 0x00, 0x4d, 0x29, 0x10, 0x0e, 0x00, 0x4d, 0x29, +0x08, 0x0b, 0x00, 0x4d, 0x28, 0x08, 0x10, 0x00, 0x4d, 0x27, +0xb8, 0xff, 0xf0, 0x40, 0x62, 0x0c, 0x00, 0x4d, 0x23, 0x28, +0x0d, 0x00, 0x4d, 0x03, 0x20, 0x10, 0x00, 0x4d, 0x03, 0x28, +0x0e, 0x0f, 0x00, 0x4c, 0x03, 0x30, 0x0d, 0x00, 0x4d, 0x02, +0x10, 0x0f, 0x00, 0x4d, 0x02, 0x20, 0x0e, 0x00, 0x4d, 0x02, +0x18, 0x0d, 0x00, 0x4d, 0x02, 0x20, 0x08, 0x00, 0x4d, 0x0b, +0x12, 0x13, 0x1f, 0x20, 0x0a, 0x20, 0x22, 0x28, 0x29, 0x08, +0x09, 0x21, 0x09, 0x0a, 0x0a, 0x1a, 0x1a, 0x0e, 0x2f, 0x20, +0x21, 0x21, 0x25, 0x82, 0x00, 0x2e, 0x21, 0x20, 0x20, 0x1d, +0x28, 0x19, 0x19, 0x13, 0x16, 0x88, 0x22, 0x1f, 0x1d, 0x51, +0x12, 0x0f, 0x0f, 0x29, 0x88, 0x05, 0x0a, 0x09, 0x09, 0x0b, +0x08, 0x05, 0x50, 0x00, 0x3f, 0x33, 0x33, 0x33, 0x2f, 0x33, +0x10, 0xed, 0x32, 0x2f, 0x32, 0x3f, 0x33, 0x33, 0xed, 0x32, +0x32, 0x2f, 0x32, 0x11, 0x33, 0x2f, 0x33, 0x01, 0x10, 0xd6, +0xed, 0x33, 0x2f, 0xcd, 0x10, 0xce, 0x32, 0x2f, 0x32, 0x2f, +0xdd, 0x7d, 0x87, 0xc4, 0xc4, 0xc4, 0xc4, 0x10, 0x87, 0xc4, +0xc4, 0xc4, 0xc4, 0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x37, +0x34, 0x3e, 0x02, 0x33, 0x32, 0x32, 0x17, 0x37, 0x17, 0x07, +0x16, 0x16, 0x17, 0x07, 0x26, 0x26, 0x27, 0x03, 0x16, 0x16, +0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x06, 0x23, 0x22, 0x27, +0x07, 0x27, 0x37, 0x26, 0x26, 0x37, 0x14, 0x16, 0x17, 0x13, +0x22, 0x0e, 0x02, 0x28, 0x29, 0x48, 0x5f, 0x36, 0x06, 0x0c, +0x07, 0x18, 0x37, 0x14, 0x0e, 0x1c, 0x10, 0x13, 0x11, 0x1e, +0x0f, 0x69, 0x0c, 0x19, 0x0e, 0x21, 0x3e, 0x23, 0x0c, 0x23, +0x4a, 0x2c, 0x21, 0x1e, 0x16, 0x38, 0x15, 0x40, 0x4a, 0x54, +0x2a, 0x24, 0x66, 0x25, 0x42, 0x31, 0x1c, 0xe7, 0x3f, 0x5c, +0x3c, 0x1d, 0x01, 0x4b, 0x13, 0x3e, 0x03, 0x06, 0x05, 0x47, +0x05, 0x08, 0x02, 0xfe, 0xb5, 0x02, 0x02, 0x07, 0x0c, 0x45, +0x0d, 0x0b, 0x06, 0x46, 0x13, 0x42, 0x19, 0x6f, 0x55, 0x37, +0x47, 0x14, 0x01, 0x3d, 0x14, 0x29, 0x40, 0x00, 0x00, 0x01, +0x00, 0x24, 0x00, 0x00, 0x01, 0xcc, 0x02, 0x6b, 0x00, 0x0d, +0x00, 0x2d, 0x40, 0x16, 0x00, 0x0f, 0x0b, 0x09, 0x0c, 0x73, +0x06, 0x04, 0x03, 0x0e, 0x0c, 0x03, 0x79, 0x09, 0x06, 0x06, +0x07, 0x41, 0x0d, 0x79, 0x02, 0x44, 0x00, 0x3f, 0xed, 0x3f, +0x39, 0x2f, 0x33, 0xed, 0x32, 0x01, 0x10, 0xd6, 0xcd, 0x33, +0xfd, 0x32, 0xcd, 0x10, 0xce, 0x31, 0x30, 0x25, 0x15, 0x21, +0x11, 0x23, 0x35, 0x33, 0x11, 0x33, 0x11, 0x33, 0x15, 0x23, +0x15, 0x01, 0xcc, 0xfe, 0xa1, 0x49, 0x49, 0x52, 0x8d, 0x8d, +0x46, 0x46, 0x01, 0x21, 0x43, 0x01, 0x07, 0xfe, 0xf9, 0x43, +0xdb, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x12, 0xff, 0xdd, +0x01, 0xf6, 0x02, 0xa5, 0x00, 0x0c, 0x00, 0x0f, 0x00, 0x56, +0x40, 0x2b, 0x04, 0x05, 0x03, 0x0e, 0x0a, 0x0d, 0x0b, 0x0d, +0x0b, 0x0c, 0x00, 0x73, 0x08, 0x06, 0x00, 0x03, 0x01, 0x08, +0x03, 0x03, 0x11, 0x10, 0x0d, 0x06, 0x05, 0x07, 0x0e, 0x79, +0x0a, 0x00, 0x03, 0x0c, 0x04, 0x0c, 0x0b, 0x0b, 0x0a, 0x41, +0x05, 0x04, 0x04, 0x02, 0x44, 0x00, 0x3f, 0x33, 0x2f, 0x33, +0x3f, 0x33, 0x2f, 0x33, 0x11, 0x12, 0x39, 0x39, 0x10, 0xed, +0x32, 0x11, 0x39, 0x39, 0x01, 0x11, 0x12, 0x39, 0x2f, 0x5e, +0x5d, 0x33, 0xcc, 0xfd, 0xcd, 0x32, 0x33, 0x11, 0x12, 0x39, +0x39, 0x10, 0xcd, 0x32, 0x31, 0x30, 0x01, 0x11, 0x23, 0x35, +0x07, 0x27, 0x13, 0x11, 0x23, 0x35, 0x21, 0x37, 0x17, 0x07, +0x37, 0x23, 0x01, 0x11, 0x52, 0x78, 0x35, 0xad, 0xaa, 0x01, +0x86, 0x25, 0x36, 0xe5, 0x5d, 0x5d, 0x01, 0x1b, 0xfe, 0xe5, +0x9a, 0xbd, 0x22, 0x01, 0x11, 0x01, 0x15, 0x46, 0x3a, 0x22, +0xf2, 0x94, 0x00, 0x01, 0x00, 0x3f, 0xff, 0x5b, 0x01, 0xb1, +0x01, 0xdb, 0x00, 0x3f, 0x00, 0xbc, 0xb9, 0x00, 0x1d, 0xff, +0xe8, 0xb3, 0x0c, 0x00, 0x4d, 0x1d, 0xb8, 0xff, 0xe0, 0xb3, +0x0b, 0x00, 0x4d, 0x1d, 0xb8, 0xff, 0xd8, 0xb3, 0x0a, 0x00, +0x4d, 0x1d, 0xb8, 0xff, 0xd0, 0xb3, 0x09, 0x00, 0x4d, 0x1b, +0xb8, 0xff, 0xd8, 0xb3, 0x0f, 0x00, 0x4d, 0x1a, 0xb8, 0xff, +0xe0, 0xb3, 0x0d, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe8, 0xb3, +0x0c, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xf0, 0x40, 0x4c, 0x0a, +0x00, 0x4d, 0x08, 0x18, 0x0a, 0x0b, 0x00, 0x4c, 0x08, 0x28, +0x09, 0x00, 0x4d, 0x06, 0x28, 0x0d, 0x00, 0x4d, 0x05, 0x30, +0x0c, 0x00, 0x4d, 0x05, 0x18, 0x0a, 0x00, 0x4d, 0x02, 0x10, +0x0e, 0x00, 0x4d, 0x2a, 0x2a, 0x1c, 0x0d, 0x0d, 0x00, 0x82, +0x1c, 0x41, 0x22, 0x37, 0x37, 0x15, 0x82, 0x00, 0x07, 0x01, +0x08, 0x07, 0x40, 0x26, 0x89, 0x2d, 0x4b, 0x37, 0x88, 0x38, +0x38, 0x18, 0x0a, 0x3b, 0x89, 0x03, 0x22, 0x1f, 0x4e, 0x0e, +0x0e, 0x13, 0x88, 0x0a, 0x50, 0x00, 0x3f, 0xed, 0x32, 0x2f, +0x3f, 0x33, 0x39, 0xed, 0x11, 0x39, 0x32, 0x2f, 0xed, 0x3f, +0xed, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x33, 0x2f, 0x33, +0x10, 0xde, 0xed, 0x33, 0x2f, 0x11, 0x33, 0x2f, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x34, 0x2e, 0x04, 0x35, 0x34, +0x36, 0x33, 0x32, 0x16, 0x17, 0x07, 0x2e, 0x03, 0x23, 0x22, +0x15, 0x14, 0x1e, 0x04, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, +0x27, 0x17, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, +0x06, 0x23, 0x22, 0x2e, 0x02, 0x27, 0x2e, 0x03, 0x27, 0x37, +0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x01, 0x5e, 0x29, 0x3d, +0x48, 0x3d, 0x29, 0x5b, 0x61, 0x26, 0x51, 0x1d, 0x0e, 0x08, +0x1d, 0x24, 0x29, 0x13, 0x6d, 0x29, 0x3d, 0x48, 0x3d, 0x29, +0x5d, 0x6b, 0x10, 0x13, 0x0b, 0x37, 0x18, 0x43, 0x36, 0x08, +0x16, 0x0b, 0x08, 0x0b, 0x22, 0x0b, 0x24, 0x33, 0x27, 0x23, +0x15, 0x12, 0x20, 0x1f, 0x20, 0x13, 0x1c, 0x2a, 0x45, 0x20, +0x17, 0x2a, 0x20, 0x13, 0x74, 0x19, 0x20, 0x18, 0x17, 0x22, +0x32, 0x28, 0x38, 0x4b, 0x0b, 0x09, 0x4a, 0x04, 0x09, 0x07, +0x04, 0x3b, 0x15, 0x1d, 0x18, 0x19, 0x24, 0x33, 0x27, 0x36, +0x41, 0x01, 0x01, 0x31, 0x15, 0x1e, 0x02, 0x02, 0x43, 0x03, +0x03, 0x0a, 0x14, 0x1c, 0x12, 0x0f, 0x21, 0x1e, 0x1a, 0x08, +0x49, 0x11, 0x08, 0x04, 0x0a, 0x11, 0x00, 0x01, 0x00, 0x4a, +0xff, 0x5b, 0x01, 0xcd, 0x01, 0xd0, 0x00, 0x2a, 0x00, 0xa5, +0x40, 0x15, 0x1d, 0x20, 0x12, 0x00, 0x4d, 0x1d, 0x10, 0x0f, +0x00, 0x4d, 0x1d, 0x10, 0x0c, 0x00, 0x4d, 0x1d, 0x18, 0x0b, +0x00, 0x4d, 0x0d, 0xb8, 0xff, 0xd8, 0xb3, 0x10, 0x00, 0x4d, +0x0c, 0xb8, 0xff, 0xd8, 0xb3, 0x0e, 0x00, 0x4d, 0x0c, 0xb8, +0xff, 0xe0, 0xb3, 0x0d, 0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xe8, +0xb3, 0x10, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xe8, 0xb3, 0x11, +0x00, 0x4d, 0x05, 0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, +0x05, 0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x05, 0xb8, +0xff, 0xe8, 0x40, 0x28, 0x09, 0x00, 0x4d, 0x05, 0x27, 0x22, +0x27, 0x81, 0x00, 0x05, 0x14, 0x00, 0x00, 0x05, 0x13, 0x13, +0x00, 0x2c, 0x28, 0x28, 0x00, 0x22, 0x01, 0x08, 0x22, 0x2b, +0x00, 0x27, 0x85, 0x29, 0x49, 0x22, 0x05, 0x86, 0x21, 0x4c, +0x0f, 0x88, 0x16, 0x4b, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x32, +0x3f, 0xed, 0x32, 0x01, 0x10, 0xc6, 0x5e, 0x5d, 0x32, 0x2f, +0x10, 0xce, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x01, 0x2b, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x0e, 0x03, 0x07, 0x1e, +0x03, 0x17, 0x1e, 0x03, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, +0x06, 0x23, 0x22, 0x2e, 0x02, 0x27, 0x2e, 0x03, 0x23, 0x23, +0x35, 0x3e, 0x03, 0x37, 0x23, 0x35, 0x21, 0x01, 0xa4, 0x13, +0x3d, 0x47, 0x48, 0x1e, 0x15, 0x22, 0x1d, 0x16, 0x08, 0x0f, +0x1e, 0x20, 0x24, 0x15, 0x04, 0x16, 0x0b, 0x09, 0x0b, 0x22, +0x0b, 0x1e, 0x2b, 0x24, 0x20, 0x12, 0x0a, 0x1d, 0x26, 0x30, +0x1d, 0x12, 0x15, 0x3f, 0x43, 0x41, 0x18, 0xe5, 0x01, 0x4f, +0x01, 0x92, 0x15, 0x49, 0x5c, 0x67, 0x31, 0x04, 0x11, 0x14, +0x14, 0x08, 0x0f, 0x20, 0x1a, 0x10, 0x01, 0x02, 0x44, 0x03, +0x03, 0x0f, 0x18, 0x20, 0x12, 0x0a, 0x1a, 0x18, 0x10, 0x37, +0x28, 0x5f, 0x5d, 0x53, 0x1d, 0x45, 0x00, 0x00, 0x00, 0x01, +0x00, 0x44, 0x00, 0x00, 0x01, 0xc1, 0x02, 0x79, 0x00, 0x23, +0x00, 0x74, 0xb9, 0x00, 0x20, 0xff, 0xe0, 0xb3, 0x10, 0x00, +0x4d, 0x1e, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x1b, +0xb8, 0xff, 0xe8, 0xb4, 0x0e, 0x0f, 0x00, 0x4c, 0x18, 0xb8, +0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x18, 0xb8, 0xff, 0xf0, +0xb3, 0x09, 0x00, 0x4d, 0x18, 0xb8, 0xff, 0xe8, 0x40, 0x27, +0x08, 0x00, 0x4d, 0x12, 0x20, 0x10, 0x00, 0x4d, 0x12, 0x28, +0x0f, 0x00, 0x4d, 0x0a, 0x76, 0x19, 0x23, 0x73, 0x11, 0x00, +0x02, 0x10, 0x02, 0x02, 0x02, 0x02, 0x25, 0x24, 0x1e, 0x01, +0x10, 0x0d, 0x7c, 0x07, 0x01, 0x16, 0x45, 0x01, 0x44, 0x00, +0x3f, 0x3f, 0x12, 0x39, 0xed, 0x32, 0x11, 0x39, 0x01, 0x11, +0x12, 0x39, 0x2f, 0x5d, 0xce, 0xfd, 0xdc, 0xed, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x33, 0x23, +0x35, 0x34, 0x3e, 0x02, 0x37, 0x36, 0x36, 0x35, 0x34, 0x26, +0x23, 0x22, 0x06, 0x07, 0x27, 0x3e, 0x03, 0x33, 0x32, 0x16, +0x15, 0x14, 0x0e, 0x02, 0x07, 0x0e, 0x03, 0x15, 0xfa, 0x52, +0x0e, 0x1c, 0x2b, 0x1e, 0x22, 0x30, 0x47, 0x34, 0x31, 0x4e, +0x13, 0x1c, 0x0a, 0x26, 0x2f, 0x36, 0x1b, 0x66, 0x67, 0x10, +0x1d, 0x29, 0x18, 0x17, 0x21, 0x16, 0x0b, 0xbb, 0x24, 0x34, +0x28, 0x20, 0x11, 0x14, 0x30, 0x26, 0x2d, 0x2f, 0x1c, 0x0c, +0x43, 0x07, 0x10, 0x0d, 0x08, 0x5a, 0x45, 0x22, 0x30, 0x24, +0x1e, 0x0f, 0x0f, 0x1a, 0x1d, 0x26, 0x1b, 0x00, 0x00, 0x01, +0x00, 0x55, 0x00, 0x00, 0x01, 0xa9, 0x01, 0xdc, 0x00, 0x25, +0x00, 0x91, 0xb9, 0x00, 0x1d, 0xff, 0xe8, 0xb3, 0x12, 0x00, +0x4d, 0x1d, 0xb8, 0xff, 0xf0, 0xb3, 0x11, 0x00, 0x4d, 0x1a, +0xb8, 0xff, 0xe8, 0xb3, 0x0d, 0x00, 0x4d, 0x1a, 0xb8, 0xff, +0xe0, 0xb3, 0x0c, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe8, 0xb3, +0x0b, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe0, 0xb3, 0x0a, 0x00, +0x4d, 0x1a, 0xb8, 0xff, 0xd8, 0x40, 0x38, 0x08, 0x09, 0x00, +0x4c, 0x15, 0x10, 0x11, 0x00, 0x4d, 0x15, 0x20, 0x10, 0x00, +0x4d, 0x15, 0x18, 0x0f, 0x00, 0x4d, 0x15, 0x20, 0x0e, 0x00, +0x4d, 0x14, 0x20, 0x12, 0x00, 0x4d, 0x0a, 0x82, 0x1b, 0x25, +0x7f, 0x13, 0x00, 0x02, 0x10, 0x02, 0x02, 0x02, 0x02, 0x27, +0x26, 0x20, 0x01, 0x12, 0x12, 0x0d, 0x88, 0x07, 0x01, 0x18, +0x50, 0x01, 0x4c, 0x00, 0x3f, 0x3f, 0x12, 0x39, 0xed, 0x32, +0x2f, 0x11, 0x39, 0x01, 0x11, 0x12, 0x39, 0x2f, 0x5d, 0xce, +0xfd, 0xdc, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x33, 0x23, 0x35, +0x34, 0x3e, 0x02, 0x37, 0x36, 0x36, 0x35, 0x34, 0x26, 0x23, +0x22, 0x0e, 0x02, 0x07, 0x27, 0x3e, 0x03, 0x33, 0x32, 0x16, +0x15, 0x14, 0x0e, 0x02, 0x07, 0x0e, 0x03, 0x15, 0xfe, 0x50, +0x0f, 0x1b, 0x26, 0x16, 0x1a, 0x29, 0x39, 0x2a, 0x12, 0x27, +0x25, 0x1e, 0x09, 0x1a, 0x09, 0x23, 0x2c, 0x31, 0x18, 0x58, +0x5b, 0x10, 0x1a, 0x23, 0x12, 0x11, 0x1b, 0x15, 0x0b, 0x72, +0x1e, 0x2b, 0x22, 0x1b, 0x0e, 0x0f, 0x26, 0x1b, 0x23, 0x1c, +0x08, 0x0b, 0x0d, 0x05, 0x45, 0x05, 0x0e, 0x0c, 0x08, 0x44, +0x3e, 0x1b, 0x29, 0x20, 0x18, 0x0c, 0x0b, 0x14, 0x17, 0x1d, +0x13, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x12, 0xff, 0xfb, +0x01, 0xc3, 0x02, 0x71, 0x00, 0x1e, 0x00, 0x31, 0x00, 0x40, +0x00, 0xc5, 0x40, 0x12, 0x36, 0x10, 0x0f, 0x10, 0x00, 0x4c, +0x2e, 0x18, 0x10, 0x00, 0x4d, 0x2a, 0x18, 0x0f, 0x10, 0x00, +0x4c, 0x1d, 0xb8, 0xff, 0xe0, 0xb4, 0x11, 0x12, 0x00, 0x4c, +0x1d, 0xb8, 0xff, 0xe8, 0xb4, 0x09, 0x0a, 0x00, 0x4c, 0x1b, +0xb8, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x1b, 0xb8, 0xff, +0xd8, 0xb3, 0x11, 0x00, 0x4d, 0x17, 0xb8, 0xff, 0xe8, 0xb3, +0x12, 0x00, 0x4d, 0x17, 0xb8, 0xff, 0xe0, 0xb3, 0x11, 0x00, +0x4d, 0x12, 0xb8, 0xff, 0xd0, 0xb3, 0x12, 0x00, 0x4d, 0x12, +0xb8, 0xff, 0xd8, 0xb3, 0x11, 0x00, 0x4d, 0x12, 0xb8, 0xff, +0xe0, 0xb4, 0x09, 0x0a, 0x00, 0x4c, 0x11, 0xb8, 0xff, 0xf0, +0x40, 0x2f, 0x12, 0x00, 0x4d, 0x19, 0x38, 0x76, 0x14, 0x14, +0x2c, 0x76, 0x1c, 0x42, 0x32, 0x22, 0x20, 0x23, 0x73, 0x09, +0x07, 0x06, 0x41, 0x19, 0x1f, 0x79, 0x32, 0x23, 0x06, 0x79, +0x09, 0x20, 0x09, 0xbf, 0x32, 0x01, 0x32, 0x09, 0x32, 0x09, +0x27, 0x3d, 0x7c, 0x0f, 0x41, 0x27, 0x7c, 0x00, 0x42, 0x00, +0x3f, 0xed, 0x3f, 0xed, 0x12, 0x39, 0x39, 0x2f, 0x2f, 0x5d, +0x11, 0x33, 0x10, 0xed, 0x32, 0x10, 0xed, 0x39, 0x01, 0x10, +0xd6, 0xcd, 0x33, 0xfd, 0x32, 0xcd, 0x33, 0x10, 0xde, 0xed, +0x33, 0x2f, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x17, +0x22, 0x2e, 0x02, 0x27, 0x35, 0x23, 0x35, 0x33, 0x11, 0x3e, +0x03, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x07, +0x16, 0x16, 0x15, 0x14, 0x06, 0x03, 0x15, 0x33, 0x15, 0x23, +0x15, 0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, +0x02, 0x23, 0x27, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, +0x02, 0x23, 0x22, 0x06, 0x07, 0xd9, 0x0f, 0x26, 0x28, 0x26, +0x0f, 0x35, 0x35, 0x0f, 0x26, 0x27, 0x26, 0x0f, 0x2c, 0x4b, +0x38, 0x1f, 0x0e, 0x19, 0x21, 0x13, 0x33, 0x45, 0x6f, 0xba, +0x6d, 0x6d, 0x0a, 0x1d, 0x1d, 0x1c, 0x36, 0x28, 0x19, 0x16, +0x26, 0x32, 0x1b, 0x4e, 0x3b, 0x17, 0x2e, 0x24, 0x16, 0x13, +0x21, 0x2b, 0x18, 0x17, 0x24, 0x08, 0x05, 0x02, 0x03, 0x06, +0x04, 0x86, 0x3e, 0x01, 0x94, 0x04, 0x06, 0x03, 0x02, 0x10, +0x26, 0x3e, 0x2e, 0x16, 0x29, 0x24, 0x1b, 0x07, 0x0e, 0x4b, +0x3c, 0x5d, 0x5d, 0x01, 0x26, 0x53, 0x3e, 0x4c, 0x02, 0x02, +0x0a, 0x1b, 0x2c, 0x23, 0x1f, 0x2a, 0x19, 0x0b, 0x44, 0x0a, +0x16, 0x26, 0x1d, 0x1b, 0x26, 0x18, 0x0a, 0x01, 0x02, 0x00, +0x00, 0x02, 0x00, 0x12, 0xff, 0xf3, 0x01, 0xe2, 0x02, 0x6b, +0x00, 0x14, 0x00, 0x21, 0x00, 0x98, 0xb9, 0x00, 0x20, 0xff, +0xd8, 0xb3, 0x12, 0x00, 0x4d, 0x20, 0xb8, 0xff, 0xe0, 0xb3, +0x11, 0x00, 0x4d, 0x20, 0xb8, 0xff, 0xf0, 0x40, 0x11, 0x0f, +0x10, 0x00, 0x4c, 0x17, 0x20, 0x11, 0x12, 0x00, 0x4c, 0x17, +0x10, 0x0f, 0x10, 0x00, 0x4c, 0x14, 0xb8, 0xff, 0xf0, 0xb4, +0x0b, 0x0c, 0x00, 0x4c, 0x14, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, +0x00, 0x4d, 0x14, 0xb8, 0xff, 0xf0, 0x40, 0x33, 0x09, 0x00, +0x4d, 0x01, 0x18, 0x0a, 0x0c, 0x00, 0x4c, 0x01, 0x10, 0x09, +0x00, 0x4d, 0x0b, 0x1a, 0x73, 0x10, 0x0e, 0x12, 0x23, 0x0a, +0x1d, 0x73, 0x07, 0x05, 0x00, 0x03, 0x10, 0x03, 0x20, 0x03, +0x03, 0x08, 0x03, 0x22, 0x1c, 0x11, 0x04, 0x79, 0x0e, 0x0a, +0x07, 0x07, 0x0c, 0x08, 0x41, 0x15, 0x7c, 0x00, 0x46, 0x00, +0x3f, 0xed, 0x3f, 0x33, 0x39, 0x2f, 0x33, 0x33, 0xed, 0x32, +0x32, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xce, 0x33, 0xed, 0x32, +0x10, 0xde, 0x32, 0xce, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x17, 0x22, +0x26, 0x35, 0x35, 0x23, 0x35, 0x33, 0x35, 0x33, 0x15, 0x33, +0x35, 0x33, 0x15, 0x33, 0x15, 0x23, 0x15, 0x14, 0x06, 0x27, +0x32, 0x3e, 0x02, 0x35, 0x35, 0x23, 0x15, 0x14, 0x1e, 0x02, +0xfa, 0x61, 0x52, 0x35, 0x35, 0x53, 0xc0, 0x53, 0x35, 0x35, +0x52, 0x61, 0x16, 0x24, 0x19, 0x0d, 0xc0, 0x0d, 0x19, 0x23, +0x0d, 0x70, 0x69, 0x66, 0x3d, 0xfc, 0xfc, 0xfc, 0xfc, 0x3d, +0x66, 0x68, 0x71, 0x47, 0x0d, 0x23, 0x3c, 0x2f, 0x5d, 0x5d, +0x2f, 0x3c, 0x23, 0x0d, 0xff, 0xff, 0x00, 0x09, 0x00, 0x00, +0x01, 0xeb, 0x02, 0x6b, 0x02, 0x06, 0x03, 0x9b, 0x00, 0x00, +0x00, 0x03, 0x00, 0x5b, 0xff, 0x97, 0x01, 0xd3, 0x02, 0xa8, +0x00, 0x0f, 0x00, 0x13, 0x00, 0x17, 0x00, 0x70, 0x40, 0x3f, +0x03, 0x15, 0x16, 0x11, 0x12, 0x06, 0x06, 0x02, 0x07, 0x00, +0x0d, 0x0c, 0x09, 0x04, 0x01, 0x08, 0x08, 0x0a, 0x0a, 0x0e, +0x19, 0x10, 0x14, 0x73, 0x04, 0x01, 0x02, 0x02, 0x00, 0x04, +0x10, 0x04, 0x20, 0x04, 0x03, 0x08, 0x04, 0x18, 0x0c, 0x17, +0x79, 0x09, 0x10, 0x10, 0x05, 0x14, 0x08, 0x07, 0x07, 0x13, +0x79, 0x05, 0x41, 0x0d, 0x14, 0x79, 0x04, 0x02, 0x01, 0x01, +0x00, 0x04, 0x44, 0x00, 0x3f, 0x33, 0x33, 0x2f, 0x33, 0x10, +0xed, 0x32, 0x3f, 0xed, 0x33, 0x2f, 0x33, 0x11, 0x12, 0x39, +0x2f, 0x33, 0xed, 0x32, 0x01, 0x10, 0xc6, 0x5e, 0x5d, 0x32, +0x2f, 0xcd, 0x10, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, 0x32, +0x2f, 0x12, 0x17, 0x39, 0xcd, 0x11, 0x17, 0x39, 0x31, 0x30, +0x33, 0x07, 0x27, 0x37, 0x23, 0x11, 0x21, 0x37, 0x17, 0x03, +0x33, 0x15, 0x23, 0x07, 0x33, 0x15, 0x01, 0x33, 0x37, 0x23, +0x11, 0x33, 0x37, 0x23, 0xf6, 0x22, 0x40, 0x1d, 0x56, 0x01, +0x24, 0x15, 0x3f, 0x65, 0x39, 0x50, 0x49, 0xbe, 0xfe, 0xe1, +0x7b, 0x40, 0xbb, 0x1b, 0x49, 0x64, 0x69, 0x11, 0x58, 0x02, +0x6b, 0x3d, 0x11, 0xfe, 0xd0, 0x46, 0xdb, 0x46, 0x01, 0x67, +0xbe, 0xfe, 0x21, 0xdb, 0x00, 0x00, 0x00, 0x04, 0x00, 0x26, +0xff, 0xb5, 0x01, 0xc9, 0x02, 0x25, 0x00, 0x25, 0x00, 0x2f, +0x00, 0x34, 0x00, 0x38, 0x00, 0x6f, 0x40, 0x3d, 0x06, 0x33, +0x34, 0x0d, 0x0e, 0x1b, 0x06, 0x1c, 0x05, 0x1e, 0x37, 0x38, +0x26, 0x27, 0x03, 0x06, 0x1d, 0x04, 0x05, 0x05, 0x30, 0x82, +0x09, 0x15, 0x15, 0x09, 0x3a, 0x2f, 0x35, 0x82, 0x21, 0x1c, +0x1d, 0x1d, 0x21, 0x39, 0x0d, 0x38, 0x86, 0x34, 0x26, 0x26, +0x00, 0x37, 0x14, 0x14, 0x0e, 0x11, 0x88, 0x1e, 0x1b, 0x18, +0x51, 0x33, 0x27, 0x2a, 0x89, 0x06, 0x03, 0x00, 0x50, 0x00, +0x3f, 0x32, 0x32, 0xed, 0x32, 0x32, 0x3f, 0x33, 0x33, 0xed, +0x32, 0x32, 0x2f, 0x32, 0x11, 0x39, 0x2f, 0x33, 0xed, 0x32, +0x01, 0x10, 0xc6, 0x32, 0x2f, 0xcd, 0x10, 0xed, 0x32, 0x10, +0xce, 0x32, 0x2f, 0x10, 0xed, 0x33, 0x2f, 0xcd, 0x11, 0x17, +0x39, 0x11, 0x12, 0x17, 0x39, 0x31, 0x30, 0x01, 0x32, 0x16, +0x17, 0x37, 0x17, 0x07, 0x16, 0x16, 0x15, 0x14, 0x14, 0x07, +0x23, 0x07, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, +0x06, 0x23, 0x22, 0x26, 0x27, 0x07, 0x27, 0x37, 0x26, 0x26, +0x35, 0x34, 0x3e, 0x02, 0x17, 0x37, 0x22, 0x26, 0x23, 0x22, +0x0e, 0x02, 0x07, 0x33, 0x34, 0x26, 0x27, 0x07, 0x07, 0x16, +0x17, 0x37, 0x01, 0x03, 0x08, 0x0f, 0x08, 0x18, 0x38, 0x17, +0x35, 0x39, 0x01, 0xbc, 0x2e, 0x0f, 0x22, 0x13, 0x2c, 0x3e, +0x10, 0x0b, 0x0f, 0x4e, 0x31, 0x17, 0x28, 0x12, 0x18, 0x37, +0x18, 0x36, 0x35, 0x27, 0x3e, 0x4f, 0x08, 0x2a, 0x02, 0x06, +0x02, 0x20, 0x30, 0x21, 0x13, 0x02, 0xf9, 0x18, 0x19, 0x24, +0xa6, 0x03, 0x2c, 0x25, 0x01, 0xdb, 0x01, 0x01, 0x4c, 0x13, +0x48, 0x17, 0x6c, 0x58, 0x05, 0x0f, 0x07, 0x8f, 0x05, 0x03, +0x0e, 0x08, 0x44, 0x08, 0x12, 0x05, 0x05, 0x4a, 0x13, 0x4d, +0x1f, 0x6d, 0x46, 0x3e, 0x5c, 0x3c, 0x1e, 0xc8, 0x83, 0x01, +0x16, 0x25, 0x30, 0x19, 0x26, 0x3b, 0x11, 0x72, 0x3f, 0x4f, +0x24, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, 0xff, 0xf3, +0x01, 0xe2, 0x02, 0x6b, 0x00, 0x1b, 0x00, 0x41, 0x40, 0x23, +0x0e, 0x18, 0x0b, 0x0e, 0x00, 0x4c, 0x1a, 0x18, 0x17, 0x73, +0x05, 0x03, 0x06, 0x1d, 0x00, 0x00, 0x0f, 0x1c, 0x06, 0x17, +0x79, 0x03, 0x1a, 0x1a, 0x01, 0x10, 0x10, 0x13, 0x7c, 0x0c, +0x46, 0x1b, 0x79, 0x01, 0x41, 0x00, 0x3f, 0xed, 0x3f, 0xed, +0x32, 0x2f, 0x11, 0x39, 0x2f, 0x33, 0xed, 0x32, 0x01, 0x10, +0xc6, 0x32, 0x2f, 0x10, 0xde, 0x32, 0xcd, 0xfd, 0xcd, 0x33, +0x31, 0x30, 0x2b, 0x13, 0x35, 0x21, 0x11, 0x33, 0x15, 0x23, +0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, +0x16, 0x33, 0x32, 0x36, 0x35, 0x35, 0x23, 0x35, 0x33, 0x35, +0x7f, 0x01, 0x1c, 0x47, 0x47, 0x13, 0x2d, 0x4d, 0x3a, 0x3b, +0x51, 0x12, 0x21, 0x12, 0x3e, 0x28, 0x3e, 0x3c, 0x7d, 0x7d, +0x02, 0x25, 0x46, 0xfe, 0xf9, 0x43, 0x5a, 0x2c, 0x4e, 0x39, +0x21, 0x22, 0x10, 0x43, 0x0e, 0x20, 0x44, 0x51, 0x52, 0x43, +0xc1, 0x00, 0x00, 0x02, 0x00, 0x47, 0xff, 0x56, 0x01, 0xcd, +0x02, 0x9e, 0x00, 0x0b, 0x00, 0x27, 0x00, 0x4e, 0x40, 0x29, +0x09, 0x03, 0x03, 0x26, 0x23, 0x7f, 0x11, 0x0f, 0x12, 0x29, +0x24, 0x24, 0x0c, 0x0c, 0x1b, 0x28, 0x12, 0x23, 0x86, 0x0f, +0x00, 0x26, 0x10, 0x26, 0x02, 0x08, 0x26, 0x26, 0x0e, 0x1c, +0x1c, 0x1f, 0x88, 0x18, 0x52, 0x06, 0x00, 0x27, 0x85, 0x0e, +0x49, 0x00, 0x3f, 0xed, 0xde, 0xcd, 0x3f, 0xed, 0x32, 0x2f, +0x11, 0x39, 0x2f, 0x5e, 0x5d, 0x33, 0xed, 0x32, 0x01, 0x10, +0xc6, 0x32, 0x2f, 0x32, 0x2f, 0x10, 0xde, 0x32, 0xcd, 0xed, +0x32, 0x32, 0x2f, 0xcd, 0x31, 0x30, 0x01, 0x22, 0x26, 0x35, +0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x35, +0x21, 0x15, 0x33, 0x15, 0x23, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, +0x35, 0x23, 0x35, 0x33, 0x35, 0x01, 0x34, 0x1a, 0x26, 0x26, +0x1a, 0x1b, 0x25, 0x25, 0xdd, 0x01, 0x0e, 0x4d, 0x4d, 0x1b, +0x2d, 0x3b, 0x21, 0x26, 0x4d, 0x22, 0x19, 0x19, 0x3d, 0x1c, +0x28, 0x34, 0xbc, 0xbc, 0x02, 0x18, 0x24, 0x1f, 0x1f, 0x24, +0x24, 0x1f, 0x1f, 0x24, 0x8d, 0x45, 0xbb, 0x3f, 0xd1, 0x30, +0x43, 0x2a, 0x12, 0x10, 0x11, 0x46, 0x0c, 0x11, 0x29, 0x3b, +0xd2, 0x3f, 0x76, 0x00, 0x00, 0x02, 0x00, 0x1d, 0xff, 0x59, +0x02, 0x00, 0x02, 0x79, 0x00, 0x22, 0x00, 0x30, 0x00, 0xa8, +0xb9, 0x00, 0x2f, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x2f, +0xb8, 0xff, 0xf8, 0x40, 0x13, 0x0d, 0x00, 0x4d, 0x2d, 0x18, +0x0e, 0x00, 0x4d, 0x2d, 0x10, 0x0d, 0x00, 0x4d, 0x28, 0x10, +0x0e, 0x00, 0x4d, 0x25, 0xb8, 0xff, 0xf0, 0xb3, 0x0e, 0x00, +0x4d, 0x25, 0xb8, 0xff, 0xe8, 0x40, 0x0e, 0x0d, 0x00, 0x4d, +0x20, 0x18, 0x0f, 0x00, 0x4d, 0x20, 0x18, 0x08, 0x00, 0x4d, +0x1c, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, 0x1c, 0xb8, +0xff, 0xe8, 0xb4, 0x0f, 0x11, 0x00, 0x4c, 0x07, 0xb8, 0xff, +0xe8, 0xb3, 0x0f, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xf0, 0x40, +0x29, 0x08, 0x00, 0x4d, 0x03, 0x18, 0x0f, 0x00, 0x4d, 0x03, +0x18, 0x08, 0x00, 0x4d, 0x1a, 0x2b, 0x76, 0x12, 0x0a, 0x32, +0x23, 0x76, 0x00, 0x40, 0x0b, 0x10, 0x48, 0x00, 0x31, 0x0e, +0x7c, 0x15, 0x31, 0x1b, 0x26, 0x7c, 0x1e, 0x46, 0x2e, 0x7c, +0x05, 0x45, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x32, 0x10, 0xdc, +0xed, 0x01, 0x10, 0xd6, 0x2b, 0xed, 0x10, 0xde, 0xcc, 0xed, +0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x34, +0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x11, 0x14, 0x16, +0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x06, 0x23, 0x22, 0x2e, +0x02, 0x35, 0x35, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x37, +0x14, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x26, 0x23, +0x22, 0x06, 0x1d, 0x1e, 0x35, 0x4b, 0x2d, 0x2e, 0x4b, 0x36, +0x1e, 0x0f, 0x16, 0x05, 0x14, 0x05, 0x08, 0x08, 0x1c, 0x0b, +0x23, 0x2b, 0x18, 0x08, 0x0b, 0x43, 0x2d, 0x2d, 0x4b, 0x35, +0x1e, 0x54, 0x39, 0x3c, 0x1f, 0x2e, 0x1f, 0x0f, 0x3d, 0x3e, +0x3c, 0x39, 0x01, 0x36, 0x53, 0x7a, 0x4f, 0x27, 0x27, 0x4f, +0x7a, 0x53, 0xfe, 0xbb, 0x29, 0x2b, 0x02, 0x02, 0x41, 0x02, +0x05, 0x15, 0x2a, 0x3f, 0x29, 0x3d, 0x20, 0x2a, 0x26, 0x50, +0x7a, 0x53, 0x7a, 0x82, 0x1c, 0x3c, 0x60, 0x44, 0x7a, 0x82, +0x82, 0x00, 0x00, 0x02, 0x00, 0x28, 0xff, 0x59, 0x01, 0xf2, +0x01, 0xda, 0x00, 0x20, 0x00, 0x2f, 0x00, 0x76, 0xb9, 0x00, +0x2e, 0xff, 0xe0, 0xb3, 0x0e, 0x00, 0x4d, 0x2e, 0xb8, 0xff, +0xe8, 0xb3, 0x0d, 0x00, 0x4d, 0x24, 0xb8, 0xff, 0xf0, 0x40, +0x41, 0x0e, 0x00, 0x4d, 0x0b, 0x10, 0x0f, 0x10, 0x00, 0x4c, +0x0b, 0x10, 0x08, 0x09, 0x00, 0x4c, 0x05, 0x20, 0x0f, 0x10, +0x00, 0x4c, 0x05, 0x10, 0x0a, 0x00, 0x4d, 0x05, 0x18, 0x09, +0x00, 0x4d, 0x05, 0x20, 0x08, 0x00, 0x4d, 0x29, 0x20, 0x7f, +0x18, 0x11, 0x31, 0x21, 0x82, 0x08, 0x40, 0x09, 0x0c, 0x48, +0x08, 0x30, 0x14, 0x89, 0x1b, 0x4b, 0x2d, 0x88, 0x0d, 0x50, +0x29, 0x26, 0x88, 0x00, 0x03, 0x51, 0x00, 0x3f, 0x33, 0xed, +0x32, 0x3f, 0xed, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0x2b, 0xed, +0x10, 0xde, 0xcc, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x06, 0x06, 0x23, +0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, +0x17, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, +0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x27, 0x14, 0x1e, 0x02, +0x33, 0x32, 0x36, 0x37, 0x11, 0x26, 0x26, 0x23, 0x22, 0x06, +0x01, 0x49, 0x0e, 0x35, 0x20, 0x2c, 0x47, 0x31, 0x1a, 0x1f, +0x37, 0x4e, 0x30, 0x34, 0x51, 0x1b, 0x14, 0x1a, 0x06, 0x14, +0x06, 0x08, 0x08, 0x1e, 0x0b, 0x25, 0x2e, 0x1b, 0x0a, 0xcc, +0x0d, 0x1c, 0x2b, 0x1e, 0x1c, 0x32, 0x0d, 0x0b, 0x23, 0x20, +0x38, 0x47, 0x12, 0x0a, 0x13, 0x24, 0x40, 0x59, 0x35, 0x38, +0x5a, 0x3f, 0x22, 0x11, 0x08, 0xfe, 0x30, 0x29, 0x2b, 0x02, +0x02, 0x41, 0x02, 0x05, 0x15, 0x2a, 0x3f, 0x29, 0xe7, 0x24, +0x3d, 0x2d, 0x1a, 0x16, 0x0d, 0x01, 0x25, 0x04, 0x06, 0x59, +0x00, 0x00, 0x00, 0x02, 0x00, 0x12, 0x00, 0x00, 0x01, 0xd7, +0x02, 0x71, 0x00, 0x1e, 0x00, 0x2d, 0x00, 0x95, 0xb5, 0x27, +0x18, 0x0f, 0x00, 0x4d, 0x1e, 0xb8, 0xff, 0xd0, 0xb3, 0x10, +0x00, 0x4d, 0x1e, 0xb8, 0xff, 0xf8, 0xb3, 0x0a, 0x00, 0x4d, +0x1e, 0xb8, 0xff, 0xe8, 0xb3, 0x09, 0x00, 0x4d, 0x1e, 0xb8, +0xff, 0xe0, 0x40, 0x09, 0x08, 0x00, 0x4d, 0x02, 0x18, 0x0f, +0x00, 0x4d, 0x01, 0xb8, 0xff, 0xe8, 0x40, 0x34, 0x10, 0x00, +0x4d, 0x03, 0x09, 0x0e, 0x09, 0x78, 0x08, 0x03, 0x14, 0x08, +0x08, 0x03, 0x0e, 0x0e, 0x00, 0x13, 0x08, 0x08, 0x29, 0x76, +0x00, 0x2f, 0x23, 0x13, 0x73, 0x18, 0x16, 0x00, 0x14, 0x01, +0x08, 0x14, 0x2e, 0x0e, 0x03, 0x15, 0x79, 0x23, 0x18, 0x18, +0x14, 0x1f, 0x7c, 0x1c, 0x41, 0x14, 0x44, 0x09, 0x08, 0x44, +0x00, 0x3f, 0x33, 0x3f, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0x33, +0xed, 0x32, 0x32, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xce, 0x33, +0xed, 0x32, 0x10, 0xde, 0xed, 0x33, 0x2f, 0x11, 0x12, 0x39, +0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x01, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x14, 0x06, +0x07, 0x1e, 0x03, 0x17, 0x23, 0x2e, 0x03, 0x27, 0x06, 0x22, +0x23, 0x23, 0x15, 0x23, 0x35, 0x23, 0x35, 0x33, 0x11, 0x36, +0x36, 0x33, 0x32, 0x16, 0x27, 0x22, 0x06, 0x07, 0x15, 0x33, +0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, 0x01, 0xb8, 0x3c, +0x32, 0x0f, 0x25, 0x26, 0x24, 0x0f, 0x5d, 0x0e, 0x21, 0x21, +0x21, 0x0f, 0x06, 0x18, 0x03, 0x35, 0x52, 0x40, 0x40, 0x1f, +0x46, 0x20, 0x70, 0x71, 0xdb, 0x17, 0x18, 0x0a, 0x24, 0x24, +0x39, 0x29, 0x16, 0x16, 0x25, 0x31, 0x01, 0xae, 0x39, 0x57, +0x18, 0x18, 0x3e, 0x45, 0x49, 0x22, 0x22, 0x46, 0x41, 0x38, +0x14, 0x01, 0xf4, 0xf4, 0x44, 0x01, 0x2a, 0x08, 0x07, 0x62, +0x1b, 0x01, 0x02, 0xef, 0x0a, 0x1b, 0x2f, 0x26, 0x24, 0x2e, +0x1b, 0x0b, 0x00, 0x01, 0x00, 0x21, 0x00, 0x00, 0x01, 0xae, +0x01, 0xda, 0x00, 0x15, 0x00, 0x2f, 0x40, 0x17, 0x0a, 0x17, +0x13, 0x11, 0x14, 0x7f, 0x04, 0x02, 0x01, 0x16, 0x14, 0x01, +0x86, 0x11, 0x04, 0x04, 0x00, 0x0e, 0x88, 0x07, 0x50, 0x00, +0x4c, 0x00, 0x3f, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0x33, 0xed, +0x32, 0x01, 0x10, 0xd6, 0xcd, 0x33, 0xfd, 0x32, 0xcd, 0x10, +0xce, 0x31, 0x30, 0x33, 0x35, 0x23, 0x35, 0x33, 0x35, 0x36, +0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x07, +0x15, 0x33, 0x15, 0x23, 0x15, 0x63, 0x42, 0x42, 0x66, 0x68, +0x1f, 0x3b, 0x23, 0x0f, 0x20, 0x31, 0x1d, 0x3e, 0x3e, 0xa6, +0xa6, 0xb7, 0x3f, 0xc1, 0x23, 0x05, 0x08, 0x49, 0x09, 0x05, +0x11, 0x8b, 0x3f, 0xb7, 0x00, 0x02, 0x00, 0x15, 0x00, 0x00, +0x01, 0xdf, 0x02, 0x6b, 0x00, 0x1b, 0x00, 0x21, 0x00, 0x69, +0x40, 0x38, 0x1c, 0x11, 0x1c, 0x0a, 0x11, 0x78, 0x12, 0x1a, +0x14, 0x12, 0x12, 0x1a, 0x15, 0x15, 0x12, 0x1a, 0x73, 0x01, +0x1c, 0x0a, 0x0a, 0x78, 0x09, 0x01, 0x14, 0x09, 0x09, 0x01, +0x06, 0x06, 0x09, 0x01, 0x01, 0x23, 0x22, 0x11, 0x12, 0x41, +0x20, 0x1f, 0x17, 0x04, 0x14, 0x0e, 0x0d, 0x01, 0x1a, 0x1c, +0x03, 0x07, 0x07, 0x0a, 0x09, 0x41, 0x00, 0x44, 0x00, 0x3f, +0x3f, 0x33, 0x39, 0x2f, 0x17, 0x39, 0x33, 0x33, 0x33, 0xcd, +0x32, 0x32, 0x32, 0x3f, 0x33, 0x01, 0x11, 0x12, 0x39, 0x2f, +0xcd, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x7d, 0x10, 0xc4, 0x01, +0x18, 0x10, 0xfd, 0xcd, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x08, +0x7d, 0x10, 0xc4, 0x31, 0x30, 0x33, 0x35, 0x26, 0x26, 0x27, +0x23, 0x35, 0x33, 0x26, 0x27, 0x33, 0x16, 0x16, 0x17, 0x33, +0x36, 0x36, 0x37, 0x33, 0x06, 0x07, 0x33, 0x15, 0x23, 0x06, +0x06, 0x07, 0x15, 0x03, 0x36, 0x36, 0x37, 0x23, 0x16, 0xd2, +0x1e, 0x36, 0x18, 0x4b, 0x34, 0x21, 0x19, 0x5d, 0x0b, 0x1b, +0x10, 0xa7, 0x0f, 0x1a, 0x0d, 0x5a, 0x1b, 0x1f, 0x34, 0x4c, +0x17, 0x35, 0x1d, 0x28, 0x11, 0x1e, 0x0e, 0x7c, 0x1e, 0xe6, +0x31, 0x5e, 0x30, 0x40, 0x41, 0x45, 0x23, 0x42, 0x21, 0x22, +0x41, 0x23, 0x45, 0x41, 0x40, 0x2f, 0x5d, 0x31, 0xe8, 0x01, +0x2d, 0x1f, 0x3b, 0x1e, 0x3c, 0x00, 0x00, 0x02, 0x00, 0x2a, +0xff, 0x58, 0x01, 0xdd, 0x01, 0xd0, 0x00, 0x27, 0x00, 0x2e, +0x00, 0xa3, 0x40, 0x55, 0x19, 0x1b, 0x1e, 0x21, 0x18, 0x21, +0x16, 0x14, 0x2b, 0x29, 0x28, 0x21, 0x17, 0x28, 0x17, 0x81, +0x18, 0x21, 0x14, 0x18, 0x18, 0x21, 0x13, 0x2c, 0x28, 0x10, +0x28, 0x0c, 0x09, 0x06, 0x0f, 0x06, 0x10, 0x28, 0x10, 0x81, +0x0f, 0x06, 0x14, 0x0f, 0x0f, 0x06, 0x28, 0x28, 0x0f, 0x1c, +0x1c, 0x18, 0x30, 0x27, 0x27, 0x0b, 0x0b, 0x0f, 0x2f, 0x2c, +0x2b, 0x1e, 0x09, 0x1b, 0x14, 0x13, 0x0c, 0x21, 0x06, 0x28, +0x28, 0x1f, 0x0c, 0x2f, 0x0c, 0x02, 0x0c, 0x0c, 0x0f, 0x03, +0x88, 0x24, 0x4b, 0x17, 0x18, 0x49, 0x10, 0x0f, 0x49, 0x00, +0x3f, 0x33, 0x3f, 0x33, 0x3f, 0xed, 0x11, 0x39, 0x2f, 0x5d, +0x39, 0x11, 0x33, 0x33, 0x11, 0x33, 0x33, 0x33, 0xcd, 0x32, +0x32, 0x32, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x32, 0x2f, 0x10, +0xce, 0x32, 0x2f, 0x11, 0x39, 0x19, 0x2f, 0x87, 0x18, 0x10, +0x2b, 0x87, 0x7d, 0xc4, 0x87, 0xc4, 0xc4, 0x10, 0x87, 0xc4, +0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x10, 0x0e, +0xc4, 0x05, 0xc4, 0xc4, 0x0e, 0xc4, 0x10, 0x87, 0x05, 0xc4, +0xc4, 0x0e, 0xc4, 0x31, 0x30, 0x17, 0x16, 0x16, 0x33, 0x32, +0x36, 0x37, 0x26, 0x26, 0x27, 0x23, 0x35, 0x33, 0x26, 0x26, +0x27, 0x33, 0x16, 0x16, 0x17, 0x33, 0x36, 0x36, 0x37, 0x33, +0x06, 0x06, 0x07, 0x33, 0x15, 0x23, 0x06, 0x06, 0x07, 0x06, +0x06, 0x23, 0x22, 0x26, 0x27, 0x37, 0x36, 0x36, 0x37, 0x23, +0x16, 0x16, 0x39, 0x0a, 0x20, 0x0e, 0x32, 0x37, 0x16, 0x1c, +0x35, 0x17, 0x5a, 0x43, 0x11, 0x1d, 0x0d, 0x58, 0x0a, 0x1b, +0x11, 0x8d, 0x0b, 0x17, 0x0c, 0x54, 0x0c, 0x18, 0x0e, 0x3c, +0x4f, 0x14, 0x2b, 0x17, 0x23, 0x59, 0x4a, 0x13, 0x2d, 0x08, +0xea, 0x0c, 0x15, 0x0b, 0x65, 0x0d, 0x1c, 0x57, 0x05, 0x06, +0x2b, 0x31, 0x34, 0x73, 0x3c, 0x3c, 0x2e, 0x5c, 0x2d, 0x27, +0x5e, 0x32, 0x2b, 0x5a, 0x32, 0x2f, 0x5b, 0x2d, 0x3c, 0x3f, +0x76, 0x36, 0x50, 0x4a, 0x0a, 0x04, 0xf0, 0x22, 0x43, 0x22, +0x23, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2c, 0xff, 0x5b, +0x01, 0xaf, 0x01, 0xd0, 0x00, 0x28, 0x00, 0x82, 0x40, 0x10, +0x24, 0x10, 0x0f, 0x00, 0x4d, 0x20, 0x20, 0x10, 0x00, 0x4d, +0x20, 0x18, 0x0f, 0x00, 0x4d, 0x15, 0xb8, 0xff, 0xe8, 0xb4, +0x11, 0x12, 0x00, 0x4c, 0x11, 0xb8, 0xff, 0xe8, 0xb4, 0x11, +0x12, 0x00, 0x4c, 0x11, 0xb8, 0xff, 0xe0, 0x40, 0x2f, 0x10, +0x00, 0x4d, 0x05, 0x0e, 0x09, 0x0e, 0x81, 0x00, 0x05, 0x14, +0x00, 0x00, 0x05, 0x09, 0x09, 0x22, 0x82, 0x13, 0x2a, 0x00, +0x00, 0x01, 0x08, 0x00, 0x00, 0x1b, 0x1b, 0x06, 0x29, 0x28, +0x89, 0x00, 0x0e, 0x0e, 0x07, 0x1c, 0x1c, 0x1f, 0x88, 0x18, +0x4b, 0x09, 0x05, 0x85, 0x07, 0x49, 0x00, 0x3f, 0xed, 0x32, +0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x2f, 0x33, 0xed, 0x01, +0x10, 0xc6, 0x32, 0x2f, 0x32, 0x2f, 0x5e, 0x5d, 0x10, 0xde, +0xed, 0x33, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, +0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x37, 0x3e, +0x03, 0x37, 0x23, 0x35, 0x21, 0x15, 0x0e, 0x03, 0x07, 0x1e, +0x03, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, +0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x2e, 0x02, 0x23, +0x23, 0x9a, 0x13, 0x2c, 0x2a, 0x25, 0x0c, 0xf4, 0x01, 0x5b, +0x0c, 0x25, 0x2c, 0x2f, 0x16, 0x26, 0x42, 0x32, 0x1c, 0x21, +0x3e, 0x56, 0x34, 0x31, 0x53, 0x16, 0x12, 0x14, 0x49, 0x2a, +0x49, 0x4c, 0x1e, 0x32, 0x3f, 0x22, 0x0f, 0xc4, 0x16, 0x37, +0x36, 0x32, 0x12, 0x45, 0x30, 0x14, 0x35, 0x3a, 0x3a, 0x19, +0x05, 0x17, 0x29, 0x3d, 0x2c, 0x30, 0x49, 0x30, 0x18, 0x10, +0x0b, 0x46, 0x0a, 0x10, 0x41, 0x3a, 0x23, 0x2c, 0x19, 0x09, +0x00, 0x00, 0x00, 0x01, 0x00, 0x82, 0x02, 0x21, 0x01, 0x72, +0x02, 0x9d, 0x00, 0x15, 0x00, 0x15, 0xb7, 0x05, 0x06, 0x11, +0x10, 0x00, 0x0b, 0x05, 0x11, 0x00, 0x2f, 0x33, 0xdc, 0xcd, +0x01, 0x2f, 0xcd, 0xde, 0xcd, 0x31, 0x30, 0x13, 0x32, 0x1e, +0x02, 0x07, 0x23, 0x2e, 0x03, 0x23, 0x22, 0x0e, 0x02, 0x07, +0x23, 0x26, 0x3e, 0x02, 0xfa, 0x19, 0x2c, 0x21, 0x12, 0x01, +0x36, 0x01, 0x06, 0x0e, 0x19, 0x13, 0x13, 0x18, 0x0f, 0x06, +0x01, 0x36, 0x01, 0x12, 0x21, 0x2c, 0x02, 0x9d, 0x11, 0x20, +0x2e, 0x1d, 0x0a, 0x17, 0x13, 0x0c, 0x0c, 0x13, 0x17, 0x0a, +0x1d, 0x2e, 0x20, 0x11, 0x00, 0x02, 0x00, 0x64, 0x02, 0x06, +0x01, 0x90, 0x02, 0xb5, 0x00, 0x03, 0x00, 0x07, 0x00, 0x24, +0x40, 0x0f, 0x04, 0x07, 0x05, 0x00, 0x03, 0x40, 0x02, 0x01, +0x06, 0x05, 0x00, 0x04, 0x80, 0x02, 0x06, 0x00, 0x2f, 0x33, +0x1a, 0xcd, 0x32, 0x01, 0x2f, 0x33, 0xdc, 0x32, 0x1a, 0xcd, +0x32, 0x10, 0xcd, 0x32, 0x31, 0x30, 0x01, 0x17, 0x07, 0x27, +0x27, 0x17, 0x07, 0x27, 0x01, 0x29, 0x67, 0x2b, 0x6e, 0x61, +0x67, 0x2b, 0x6e, 0x02, 0xb5, 0x8f, 0x20, 0x7d, 0x32, 0x8f, +0x20, 0x7d, 0x00, 0x00, 0x00, 0x03, 0x00, 0xa7, 0x02, 0x01, +0x01, 0x4d, 0x03, 0x2d, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x1b, +0x00, 0x4f, 0xb9, 0x00, 0x0f, 0xff, 0xe0, 0x40, 0x11, 0x08, +0x11, 0x00, 0x4c, 0x0b, 0x20, 0x08, 0x11, 0x00, 0x4c, 0x09, +0x28, 0x08, 0x11, 0x00, 0x4c, 0x05, 0xb8, 0xff, 0xd8, 0x40, +0x17, 0x08, 0x11, 0x00, 0x4c, 0x04, 0x10, 0x16, 0x40, 0x00, +0x80, 0x02, 0x02, 0x0a, 0x16, 0x00, 0x03, 0x02, 0x01, 0x01, +0x0d, 0x13, 0x19, 0x07, 0x00, 0x2f, 0xdd, 0xde, 0xcd, 0x32, +0x2f, 0xcd, 0xdd, 0xcd, 0x01, 0x2f, 0xcd, 0x32, 0x2f, 0x1a, +0xcd, 0x1a, 0x10, 0xde, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x01, 0x07, 0x27, 0x37, 0x17, 0x14, 0x06, 0x23, 0x22, +0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x07, 0x34, 0x26, +0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x01, +0x4d, 0x8d, 0x13, 0x87, 0x19, 0x32, 0x21, 0x23, 0x30, 0x30, +0x23, 0x21, 0x32, 0x28, 0x19, 0x12, 0x12, 0x19, 0x19, 0x12, +0x12, 0x19, 0x02, 0xeb, 0x35, 0x31, 0x46, 0xd9, 0x26, 0x2d, +0x2d, 0x26, 0x26, 0x2c, 0x2c, 0x26, 0x14, 0x17, 0x17, 0x14, +0x15, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x70, +0x02, 0x0c, 0x01, 0x84, 0x02, 0xcc, 0x00, 0x0b, 0x00, 0x17, +0x00, 0x1b, 0x00, 0x27, 0x40, 0x12, 0x1a, 0x1a, 0x15, 0x92, +0x0f, 0x09, 0x1b, 0x1b, 0x03, 0x92, 0x09, 0x18, 0x1b, 0x12, +0x06, 0x92, 0x0c, 0x00, 0x00, 0x2f, 0x32, 0xfd, 0x32, 0xde, +0xcd, 0x01, 0x2f, 0xed, 0x32, 0x2f, 0x10, 0xde, 0xed, 0x32, +0x2f, 0x31, 0x30, 0x13, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, +0x32, 0x16, 0x15, 0x14, 0x06, 0x33, 0x22, 0x26, 0x35, 0x34, +0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x27, 0x33, 0x15, +0x23, 0xa0, 0x15, 0x1b, 0x1b, 0x15, 0x15, 0x1b, 0x1b, 0x9f, +0x14, 0x1c, 0x1c, 0x14, 0x14, 0x1c, 0x1c, 0xdf, 0xe2, 0xe2, +0x02, 0x0c, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, +0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, 0xc0, 0x39, +0x00, 0x02, 0x00, 0x89, 0x02, 0x0c, 0x01, 0x6b, 0x02, 0xcc, +0x00, 0x0b, 0x00, 0x0f, 0x00, 0x1a, 0x40, 0x0b, 0x0e, 0x0f, +0x0f, 0x09, 0x92, 0x03, 0x0c, 0x0f, 0x06, 0x92, 0x00, 0x00, +0x2f, 0xfd, 0xde, 0xcd, 0x01, 0x2f, 0xed, 0x33, 0x2f, 0xcd, +0x31, 0x30, 0x13, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, +0x16, 0x15, 0x14, 0x06, 0x27, 0x33, 0x15, 0x23, 0xfa, 0x15, +0x1c, 0x1c, 0x15, 0x15, 0x1c, 0x1c, 0x86, 0xe2, 0xe2, 0x02, +0x0c, 0x1b, 0x17, 0x17, 0x1b, 0x1b, 0x17, 0x17, 0x1b, 0xc0, +0x39, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x6b, 0x02, 0x0c, +0x01, 0x89, 0x02, 0xfb, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x1b, +0x00, 0x66, 0x40, 0x0b, 0x1b, 0x18, 0x11, 0x00, 0x4d, 0x1b, +0x10, 0x10, 0x00, 0x4d, 0x18, 0xb8, 0xff, 0xe8, 0xb3, 0x14, +0x00, 0x4d, 0x18, 0xb8, 0xff, 0xe8, 0x40, 0x2d, 0x11, 0x00, +0x4d, 0x18, 0x1b, 0x1a, 0x70, 0x19, 0xa0, 0x19, 0xb0, 0x19, +0x03, 0x19, 0x19, 0x15, 0x92, 0x7f, 0x0f, 0x01, 0x0f, 0x03, +0x92, 0x40, 0x70, 0x09, 0x01, 0x09, 0x1b, 0x18, 0x80, 0x19, +0x1f, 0x1a, 0x2f, 0x1a, 0x3f, 0x1a, 0x03, 0x1a, 0x12, 0x06, +0x92, 0x0c, 0x00, 0x00, 0x2f, 0x32, 0xed, 0x32, 0xdc, 0x71, +0x32, 0x1a, 0xcd, 0x32, 0x01, 0x2f, 0x5d, 0x1a, 0xed, 0xde, +0x5d, 0xed, 0x33, 0x2f, 0x5d, 0x33, 0xcd, 0x32, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x22, 0x26, 0x35, 0x34, 0x36, +0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x33, 0x22, 0x26, 0x35, +0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x27, 0x17, +0x07, 0x27, 0x9b, 0x14, 0x1c, 0x1c, 0x14, 0x15, 0x1c, 0x1c, +0xa9, 0x15, 0x1c, 0x1c, 0x15, 0x14, 0x1c, 0x1c, 0xa2, 0x55, +0x28, 0x63, 0x02, 0x0c, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, +0x16, 0x1b, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, +0xef, 0x7e, 0x22, 0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x6b, +0x02, 0x0c, 0x01, 0x89, 0x02, 0xfb, 0x00, 0x0b, 0x00, 0x17, +0x00, 0x1b, 0x00, 0x66, 0xb9, 0x00, 0x19, 0xff, 0xf0, 0x40, +0x3e, 0x10, 0x00, 0x4d, 0x18, 0x18, 0x15, 0x00, 0x4d, 0x18, +0x10, 0x14, 0x00, 0x4d, 0x18, 0x18, 0x11, 0x00, 0x4d, 0x18, +0x19, 0x1a, 0x6f, 0x1b, 0x01, 0x7f, 0x1b, 0x9f, 0x1b, 0xaf, +0x1b, 0xbf, 0x1b, 0x04, 0x1b, 0x1b, 0x09, 0x15, 0x92, 0x7f, +0x0f, 0x01, 0x0f, 0x03, 0x92, 0x40, 0x09, 0x19, 0x18, 0x80, +0x1b, 0x1a, 0x40, 0x1a, 0x1f, 0x48, 0x1a, 0x1a, 0x12, 0x06, +0x92, 0x0c, 0x00, 0x00, 0x2f, 0x32, 0xed, 0x32, 0x33, 0x2f, +0x2b, 0x33, 0x1a, 0xcd, 0x32, 0x01, 0x2f, 0x1a, 0xed, 0xde, +0x5d, 0xed, 0x11, 0x33, 0x2f, 0x5d, 0x71, 0x33, 0xcd, 0x32, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x22, 0x26, 0x35, +0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x33, 0x22, +0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, +0x27, 0x17, 0x07, 0x27, 0x9b, 0x14, 0x1c, 0x1c, 0x14, 0x15, +0x1c, 0x1c, 0xa9, 0x15, 0x1c, 0x1c, 0x15, 0x14, 0x1c, 0x1c, +0x44, 0x36, 0x63, 0x28, 0x02, 0x0c, 0x1b, 0x16, 0x17, 0x1a, +0x1a, 0x17, 0x16, 0x1b, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, +0x16, 0x1b, 0xef, 0x2f, 0x71, 0x22, 0x00, 0x00, 0x00, 0x03, +0x00, 0x6b, 0x02, 0x0c, 0x01, 0x89, 0x02, 0xe6, 0x00, 0x0b, +0x00, 0x17, 0x00, 0x1d, 0x00, 0x3a, 0x40, 0x1c, 0x1c, 0x1a, +0x18, 0x60, 0x1d, 0x1d, 0x09, 0x15, 0x92, 0x0f, 0x03, 0x92, +0x09, 0x1b, 0x19, 0x1c, 0x18, 0x1a, 0x1f, 0x1d, 0x01, 0x1d, +0x1d, 0x12, 0x06, 0x92, 0x0c, 0x00, 0x00, 0x2f, 0x32, 0xed, +0x32, 0x33, 0x2f, 0x71, 0xcd, 0xdd, 0x32, 0xcd, 0x32, 0x01, +0x2f, 0xed, 0xde, 0xed, 0x12, 0x39, 0x19, 0x2f, 0x1a, 0xcd, +0x33, 0xcd, 0x31, 0x30, 0x13, 0x22, 0x26, 0x35, 0x34, 0x36, +0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x33, 0x22, 0x26, 0x35, +0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x27, 0x37, +0x17, 0x37, 0x17, 0x07, 0x9b, 0x14, 0x1c, 0x1c, 0x14, 0x15, +0x1c, 0x1c, 0xa9, 0x15, 0x1c, 0x1c, 0x15, 0x14, 0x1c, 0x1c, +0xe2, 0x1a, 0x54, 0x54, 0x1a, 0x6e, 0x02, 0x0c, 0x1b, 0x16, +0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, 0x1b, 0x16, 0x17, 0x1a, +0x1a, 0x17, 0x16, 0x1b, 0xb2, 0x28, 0x36, 0x36, 0x28, 0x55, +0x00, 0x02, 0x00, 0x71, 0x02, 0x0b, 0x01, 0x84, 0x02, 0xcc, +0x00, 0x1d, 0x00, 0x21, 0x00, 0x49, 0x40, 0x0c, 0x12, 0x18, +0x0e, 0x00, 0x4d, 0x12, 0x20, 0x0c, 0x0d, 0x00, 0x4c, 0x03, +0xb8, 0xff, 0xe8, 0x40, 0x19, 0x0c, 0x00, 0x4d, 0x1d, 0x00, +0x10, 0x21, 0x21, 0x0e, 0x10, 0x1f, 0x1f, 0x01, 0x1e, 0x21, +0x14, 0x1d, 0x1d, 0x14, 0x0b, 0x1a, 0x05, 0x0e, 0x0e, 0x05, +0x00, 0x2f, 0x33, 0x2f, 0x10, 0xcd, 0xdc, 0xcd, 0x32, 0x2f, +0x10, 0xde, 0xcd, 0x01, 0x2f, 0x33, 0x2f, 0x2f, 0xcd, 0x33, +0x2f, 0x10, 0xdc, 0xcd, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x01, +0x0e, 0x03, 0x23, 0x22, 0x26, 0x27, 0x26, 0x26, 0x23, 0x22, +0x06, 0x07, 0x27, 0x3e, 0x03, 0x33, 0x32, 0x16, 0x17, 0x16, +0x16, 0x33, 0x32, 0x36, 0x37, 0x27, 0x33, 0x15, 0x23, 0x01, +0x84, 0x03, 0x10, 0x16, 0x1e, 0x11, 0x10, 0x1e, 0x0d, 0x0f, +0x12, 0x0b, 0x0f, 0x17, 0x06, 0x28, 0x03, 0x0f, 0x16, 0x1c, +0x12, 0x11, 0x1d, 0x0d, 0x10, 0x11, 0x0b, 0x0f, 0x18, 0x06, +0xd3, 0xe3, 0xe3, 0x02, 0x5c, 0x0b, 0x1a, 0x16, 0x10, 0x0a, +0x08, 0x07, 0x07, 0x19, 0x0d, 0x12, 0x0b, 0x1a, 0x17, 0x10, +0x0a, 0x08, 0x08, 0x06, 0x18, 0x0d, 0x5e, 0x39, 0x00, 0x00, +0x00, 0x01, 0x00, 0x9c, 0x02, 0xc7, 0x01, 0x45, 0x03, 0x3e, +0x00, 0x03, 0x00, 0x11, 0xb5, 0x00, 0x02, 0x00, 0x03, 0x02, +0x01, 0x00, 0x2f, 0xcd, 0xdd, 0xcd, 0x01, 0x2f, 0xcd, 0x31, +0x30, 0x01, 0x07, 0x27, 0x37, 0x01, 0x45, 0x96, 0x13, 0x90, +0x02, 0xfd, 0x36, 0x31, 0x46, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x8c, 0x02, 0xc1, 0x01, 0x68, 0x03, 0x3e, 0x00, 0x05, +0x00, 0x23, 0x40, 0x0e, 0x05, 0x01, 0x60, 0x00, 0x03, 0x01, +0x05, 0x04, 0x03, 0x40, 0x00, 0x80, 0x02, 0x04, 0x00, 0x2f, +0x33, 0x1a, 0xdd, 0x1a, 0xcd, 0x10, 0xcd, 0x32, 0x01, 0x19, +0x2f, 0x33, 0x1a, 0xcd, 0xcd, 0x31, 0x30, 0x13, 0x17, 0x07, +0x27, 0x07, 0x27, 0xfa, 0x6e, 0x1a, 0x54, 0x54, 0x1a, 0x03, +0x3e, 0x55, 0x28, 0x37, 0x37, 0x28, 0x00, 0x01, 0x00, 0x8c, +0x02, 0xc1, 0x01, 0x68, 0x03, 0x3e, 0x00, 0x05, 0x00, 0x21, +0x40, 0x0d, 0x05, 0x04, 0x00, 0x60, 0x02, 0x04, 0x00, 0x40, +0x03, 0x01, 0x80, 0x02, 0x05, 0x00, 0x2f, 0xcd, 0x1a, 0xdd, +0x32, 0x1a, 0xcd, 0x32, 0x01, 0x19, 0x2f, 0x1a, 0xcd, 0xcd, +0x33, 0x31, 0x30, 0x13, 0x37, 0x17, 0x37, 0x17, 0x07, 0x8c, +0x1a, 0x54, 0x54, 0x1a, 0x6e, 0x03, 0x16, 0x28, 0x36, 0x36, +0x28, 0x55, 0x00, 0x00, 0x00, 0x03, 0x00, 0x50, 0x02, 0x91, +0x01, 0xa4, 0x03, 0x3e, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x1b, +0x00, 0x2c, 0x40, 0x13, 0x00, 0x03, 0x02, 0x01, 0x01, 0x19, +0x13, 0x07, 0x0d, 0x16, 0x0a, 0x04, 0x40, 0x00, 0x80, 0x02, +0x02, 0x10, 0x04, 0x00, 0x2f, 0x33, 0x33, 0x2f, 0x1a, 0xcd, +0x1a, 0x10, 0xcd, 0x32, 0x01, 0x2f, 0xcd, 0xdc, 0xcd, 0x33, +0x2f, 0x33, 0xcd, 0x32, 0x31, 0x30, 0x13, 0x17, 0x07, 0x27, +0x07, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, +0x14, 0x06, 0x33, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, +0x16, 0x15, 0x14, 0x06, 0xe2, 0x46, 0x28, 0x54, 0x2b, 0x15, +0x1c, 0x1c, 0x15, 0x14, 0x1c, 0x1c, 0xde, 0x14, 0x1c, 0x1c, +0x14, 0x14, 0x1d, 0x1d, 0x03, 0x3e, 0x6b, 0x22, 0x5f, 0x7f, +0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, 0x1b, 0x16, +0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, 0x00, 0x03, 0x00, 0x50, +0x02, 0x91, 0x01, 0xa4, 0x03, 0x3e, 0x00, 0x03, 0x00, 0x0f, +0x00, 0x1b, 0x00, 0x34, 0x40, 0x17, 0x03, 0x00, 0x00, 0x0d, +0x07, 0x19, 0x01, 0x02, 0x02, 0x13, 0x19, 0x0a, 0x16, 0x10, +0x40, 0x00, 0x03, 0x80, 0x02, 0x01, 0x01, 0x04, 0x10, 0x00, +0x2f, 0x33, 0x33, 0x2f, 0x33, 0x1a, 0xcd, 0x32, 0x1a, 0x10, +0xcd, 0x32, 0x01, 0x2f, 0xcd, 0x33, 0x2f, 0x33, 0x10, 0xdc, +0xcd, 0x33, 0x2f, 0x33, 0x31, 0x30, 0x01, 0x07, 0x27, 0x37, +0x17, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, +0x14, 0x06, 0x21, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, +0x16, 0x15, 0x14, 0x06, 0x01, 0x4a, 0x56, 0x28, 0x48, 0x5f, +0x14, 0x1c, 0x1c, 0x14, 0x15, 0x1c, 0x1c, 0xfe, 0xf9, 0x14, +0x1d, 0x1d, 0x14, 0x14, 0x1c, 0x1c, 0x03, 0x10, 0x5f, 0x22, +0x6b, 0xad, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, +0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, 0x00, 0x00, +0x00, 0x03, 0x00, 0x50, 0x02, 0x91, 0x01, 0xa4, 0x03, 0x3e, +0x00, 0x0b, 0x00, 0x17, 0x00, 0x1d, 0x00, 0x3c, 0x40, 0x1a, +0x15, 0x0f, 0x0f, 0x1d, 0x03, 0x40, 0x09, 0x09, 0x1c, 0x1a, +0x18, 0x60, 0x1d, 0x1c, 0x18, 0x40, 0x1b, 0x19, 0x80, 0x1a, +0x1d, 0x1d, 0x12, 0x06, 0x0c, 0x00, 0x00, 0x2f, 0x32, 0xcd, +0x32, 0x33, 0x2f, 0xcd, 0x1a, 0xdd, 0x32, 0x1a, 0xcd, 0x32, +0x01, 0x19, 0x2f, 0x1a, 0xcd, 0x33, 0xcd, 0x33, 0x18, 0x2f, +0x1a, 0xcd, 0x11, 0x33, 0x2f, 0xcd, 0x31, 0x30, 0x13, 0x22, +0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, +0x33, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, +0x14, 0x06, 0x27, 0x37, 0x17, 0x37, 0x17, 0x07, 0x81, 0x14, +0x1d, 0x1d, 0x14, 0x14, 0x1c, 0x1c, 0xde, 0x14, 0x1c, 0x1c, +0x14, 0x15, 0x1c, 0x1c, 0xe2, 0x1a, 0x39, 0x39, 0x1a, 0x53, +0x02, 0x91, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, +0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, 0x85, 0x28, +0x23, 0x23, 0x28, 0x42, 0x00, 0x00, 0xff, 0xff, 0x00, 0x5b, +0x00, 0x00, 0x01, 0xcc, 0x03, 0x3e, 0x02, 0x26, 0x00, 0x28, +0x00, 0x00, 0x01, 0x07, 0x00, 0x43, 0x00, 0x0e, 0x00, 0x89, +0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xf1, 0x40, 0x09, 0x0f, +0x0d, 0x00, 0x0a, 0x50, 0x01, 0x01, 0x0e, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x5b, 0x00, 0x00, +0x01, 0xcc, 0x03, 0x1a, 0x02, 0x26, 0x00, 0x28, 0x00, 0x00, +0x01, 0x07, 0x00, 0x83, 0x00, 0x12, 0x00, 0x8b, 0x00, 0x1a, +0xb1, 0x02, 0x01, 0xb8, 0xff, 0xf9, 0x40, 0x0d, 0x0e, 0x20, +0x00, 0x0a, 0x50, 0x02, 0x01, 0x18, 0x4f, 0x01, 0x01, 0x0c, +0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x01, 0x00, 0x12, +0xff, 0xfe, 0x01, 0xcc, 0x02, 0x6b, 0x00, 0x24, 0x00, 0x79, +0x40, 0x1f, 0x17, 0x20, 0x12, 0x00, 0x4d, 0x17, 0x20, 0x10, +0x00, 0x4d, 0x17, 0x18, 0x0f, 0x00, 0x4d, 0x12, 0x28, 0x12, +0x00, 0x4d, 0x12, 0x18, 0x10, 0x00, 0x4d, 0x12, 0x20, 0x0f, +0x00, 0x4d, 0x04, 0xb8, 0xff, 0xe8, 0x40, 0x2d, 0x09, 0x0a, +0x00, 0x4c, 0x23, 0x23, 0x14, 0x76, 0x05, 0x26, 0x1c, 0x0f, +0x0d, 0x1f, 0x0d, 0x02, 0x0d, 0x0d, 0x24, 0x73, 0x00, 0x1f, +0x01, 0x08, 0x1f, 0x20, 0x25, 0x24, 0x1f, 0x79, 0x21, 0x1c, +0x19, 0x7c, 0x00, 0x02, 0x02, 0x21, 0x41, 0x1e, 0x44, 0x11, +0x7c, 0x0a, 0x43, 0x00, 0x3f, 0xed, 0x3f, 0x3f, 0x39, 0x2f, +0x33, 0xed, 0x32, 0x10, 0xed, 0x32, 0x01, 0x10, 0xd6, 0xdd, +0x5e, 0x5d, 0xed, 0x32, 0x2f, 0x5d, 0x32, 0x10, 0xde, 0xed, +0x33, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x13, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, +0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0x11, 0x23, +0x11, 0x23, 0x35, 0x21, 0x15, 0x23, 0xb9, 0x2d, 0x2b, 0x58, +0x63, 0x15, 0x2a, 0x3f, 0x2b, 0x0d, 0x1b, 0x0b, 0x03, 0x05, +0x0f, 0x0d, 0x31, 0x33, 0x11, 0x1e, 0x29, 0x18, 0x13, 0x27, +0x15, 0x52, 0x55, 0x01, 0x65, 0xbe, 0x01, 0x78, 0x0d, 0x6c, +0x5d, 0x27, 0x45, 0x34, 0x1e, 0x01, 0x02, 0x41, 0x01, 0x01, +0x46, 0x34, 0x26, 0x33, 0x20, 0x0d, 0x07, 0x06, 0xfe, 0xcd, +0x02, 0x25, 0x46, 0x46, 0xff, 0xff, 0x00, 0x36, 0x00, 0x00, +0x01, 0xcc, 0x03, 0x3e, 0x02, 0x26, 0x02, 0xc6, 0x00, 0x00, +0x01, 0x07, 0x00, 0x8f, 0x00, 0x47, 0x00, 0x89, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x44, 0x0c, 0x0a, 0x08, 0x02, 0x50, 0x01, +0x01, 0x0b, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x01, +0x00, 0x26, 0xff, 0xf3, 0x01, 0xcc, 0x02, 0x79, 0x00, 0x26, +0x00, 0xd9, 0x40, 0x0c, 0x25, 0x10, 0x0d, 0x0e, 0x00, 0x4c, +0x1f, 0x18, 0x0d, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xf0, 0xb4, +0x11, 0x12, 0x00, 0x4c, 0x1a, 0xb8, 0xff, 0xe8, 0xb4, 0x0f, +0x10, 0x00, 0x4c, 0x1a, 0xb8, 0xff, 0xe0, 0xb3, 0x0e, 0x00, +0x4d, 0x11, 0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, 0x11, +0xb8, 0xff, 0xe0, 0xb3, 0x11, 0x00, 0x4d, 0x11, 0xb8, 0xff, +0xd8, 0xb3, 0x0c, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xe0, 0xb3, +0x0b, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, +0x4d, 0x11, 0xb8, 0xff, 0xf0, 0xb3, 0x09, 0x00, 0x4d, 0x10, +0xb8, 0xff, 0xf0, 0xb3, 0x10, 0x00, 0x4d, 0x09, 0xb8, 0xff, +0xf0, 0xb3, 0x12, 0x00, 0x4d, 0x09, 0xb8, 0xff, 0xe8, 0xb3, +0x11, 0x00, 0x4d, 0x09, 0xb8, 0xff, 0xe0, 0xb4, 0x0b, 0x0c, +0x00, 0x4c, 0x02, 0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, +0x02, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x02, 0xb8, +0xff, 0xe0, 0x40, 0x1f, 0x10, 0x00, 0x4d, 0x0e, 0x0e, 0x03, +0x03, 0x18, 0x28, 0x0c, 0x0f, 0x76, 0x22, 0x27, 0x0e, 0x79, +0x0d, 0x0d, 0x00, 0x17, 0x17, 0x12, 0x7c, 0x1d, 0x46, 0x04, +0x04, 0x07, 0x7c, 0x00, 0x45, 0x00, 0x3f, 0xed, 0x32, 0x2f, +0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x2f, 0xed, 0x01, 0x10, +0xd6, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, 0x32, 0x2f, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, +0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, +0x07, 0x33, 0x15, 0x23, 0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, +0x37, 0x17, 0x0e, 0x03, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, +0x3e, 0x02, 0x01, 0x27, 0x3d, 0x55, 0x12, 0x15, 0x11, 0x46, +0x31, 0x2b, 0x41, 0x2d, 0x19, 0x04, 0xe4, 0xe5, 0x07, 0x60, +0x55, 0x13, 0x28, 0x24, 0x1d, 0x08, 0x15, 0x07, 0x1b, 0x29, +0x36, 0x21, 0x39, 0x60, 0x45, 0x26, 0x24, 0x44, 0x5e, 0x02, +0x79, 0x1d, 0x0b, 0x40, 0x09, 0x18, 0x1f, 0x37, 0x4e, 0x2f, +0x46, 0x67, 0x78, 0x07, 0x0b, 0x0c, 0x06, 0x42, 0x05, 0x0d, +0x0e, 0x09, 0x2b, 0x52, 0x78, 0x4e, 0x4e, 0x78, 0x52, 0x2b, +0x00, 0x01, 0x00, 0x37, 0xff, 0xf3, 0x01, 0xbe, 0x02, 0x79, +0x00, 0x31, 0x00, 0xd8, 0x40, 0x0b, 0x2c, 0x18, 0x0e, 0x00, +0x4d, 0x2c, 0x10, 0x0d, 0x00, 0x4d, 0x27, 0xb8, 0xff, 0xe8, +0xb3, 0x0a, 0x00, 0x4d, 0x27, 0xb8, 0xff, 0xf0, 0xb3, 0x09, +0x00, 0x4d, 0x24, 0xb8, 0xff, 0xf0, 0xb3, 0x0d, 0x00, 0x4d, +0x24, 0xb8, 0xff, 0xd0, 0xb3, 0x0a, 0x00, 0x4d, 0x23, 0xb8, +0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x1b, 0xb8, 0xff, 0xe8, +0xb3, 0x11, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe0, 0xb3, 0x12, +0x00, 0x4d, 0x14, 0xb8, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, +0x14, 0xb8, 0xff, 0xf0, 0xb3, 0x11, 0x00, 0x4d, 0x14, 0xb8, +0xff, 0xe0, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x14, 0xb8, 0xff, +0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x13, 0xb8, 0xff, 0xe0, 0x40, +0x3e, 0x0e, 0x00, 0x4d, 0x0b, 0x10, 0x0e, 0x0f, 0x00, 0x4c, +0x0b, 0x20, 0x09, 0x0a, 0x00, 0x4c, 0x02, 0x10, 0x11, 0x00, +0x4d, 0x01, 0x28, 0x12, 0x00, 0x4d, 0x15, 0x15, 0x03, 0x76, +0x26, 0x33, 0x2e, 0x2e, 0x1c, 0x76, 0x00, 0x0d, 0x10, 0x0d, +0x02, 0x0d, 0x32, 0x59, 0x08, 0x01, 0x08, 0x29, 0x19, 0x21, +0x10, 0x2f, 0x2f, 0x00, 0x7c, 0x29, 0x46, 0x16, 0x16, 0x19, +0x7c, 0x10, 0x45, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, +0x32, 0x2f, 0x11, 0x39, 0x11, 0x12, 0x39, 0x5d, 0x01, 0x10, +0xd6, 0x5d, 0xed, 0x33, 0x2f, 0x10, 0xde, 0xed, 0x33, 0x2f, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x37, 0x32, 0x36, 0x35, 0x34, 0x2e, 0x02, 0x27, 0x2e, 0x03, +0x35, 0x34, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x17, 0x07, 0x26, +0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x1e, 0x02, 0x17, 0x1e, +0x03, 0x15, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x27, 0x37, +0x16, 0x16, 0xea, 0x3f, 0x42, 0x18, 0x28, 0x32, 0x1a, 0x1e, +0x37, 0x2b, 0x19, 0x66, 0x5b, 0x19, 0x31, 0x2a, 0x21, 0x0a, +0x19, 0x14, 0x47, 0x2b, 0x2d, 0x42, 0x13, 0x21, 0x2c, 0x1a, +0x26, 0x3f, 0x2e, 0x19, 0x6e, 0x66, 0x21, 0x3a, 0x2d, 0x22, +0x09, 0x18, 0x14, 0x4f, 0x3a, 0x30, 0x30, 0x1d, 0x29, 0x1f, +0x17, 0x0a, 0x0c, 0x1e, 0x28, 0x36, 0x25, 0x51, 0x5b, 0x07, +0x0a, 0x0e, 0x07, 0x46, 0x0c, 0x19, 0x2d, 0x2d, 0x1a, 0x24, +0x1b, 0x16, 0x0b, 0x10, 0x20, 0x2c, 0x3c, 0x2b, 0x51, 0x57, +0x09, 0x0e, 0x0e, 0x06, 0x46, 0x0b, 0x1f, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x5a, 0x00, 0x00, 0x01, 0x9b, 0x02, 0x6b, +0x00, 0x0b, 0x00, 0x2b, 0x40, 0x15, 0x08, 0x05, 0x06, 0x0b, +0x02, 0x01, 0x73, 0x06, 0x06, 0x0c, 0x0d, 0x00, 0x07, 0x79, +0x09, 0x41, 0x01, 0x06, 0x79, 0x04, 0x44, 0x00, 0x3f, 0xed, +0x32, 0x3f, 0xed, 0x32, 0x01, 0x11, 0x12, 0x39, 0x2f, 0xfd, +0xcd, 0x32, 0x10, 0xcd, 0x32, 0x31, 0x30, 0x01, 0x11, 0x33, +0x15, 0x21, 0x35, 0x33, 0x11, 0x23, 0x35, 0x21, 0x15, 0x01, +0x23, 0x78, 0xfe, 0xbf, 0x77, 0x77, 0x01, 0x41, 0x02, 0x25, +0xfe, 0x21, 0x46, 0x46, 0x01, 0xdf, 0x46, 0x46, 0xff, 0xff, +0x00, 0x5a, 0x00, 0x00, 0x01, 0x9b, 0x03, 0x1a, 0x02, 0x26, +0x02, 0xb9, 0x00, 0x00, 0x01, 0x07, 0x00, 0x83, 0x00, 0x00, +0x00, 0x8b, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, 0x00, 0x0e, +0x20, 0x04, 0x02, 0x50, 0x02, 0x09, 0x18, 0x4f, 0x01, 0x09, +0x0c, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x36, 0xff, 0xf3, 0x01, 0xa4, 0x02, 0x6b, +0x00, 0x13, 0x00, 0x4a, 0x40, 0x17, 0x10, 0x18, 0x0f, 0x10, +0x00, 0x4c, 0x0a, 0x18, 0x0e, 0x00, 0x4d, 0x0a, 0x20, 0x0c, +0x0d, 0x00, 0x4c, 0x0a, 0x18, 0x0b, 0x00, 0x4d, 0x05, 0xb8, +0xff, 0xf0, 0x40, 0x16, 0x11, 0x12, 0x00, 0x4c, 0x12, 0x73, +0x03, 0x15, 0x00, 0x00, 0x0b, 0x14, 0x0c, 0x0c, 0x0f, 0x7c, +0x08, 0x46, 0x00, 0x79, 0x01, 0x41, 0x00, 0x3f, 0xed, 0x3f, +0xed, 0x32, 0x2f, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xde, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x35, +0x21, 0x11, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, +0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, 0x7f, 0x01, 0x25, +0x13, 0x2f, 0x4f, 0x3c, 0x3c, 0x52, 0x13, 0x21, 0x13, 0x3f, +0x2a, 0x40, 0x3f, 0x02, 0x25, 0x46, 0xfe, 0x5c, 0x2c, 0x4e, +0x39, 0x21, 0x22, 0x10, 0x43, 0x0e, 0x20, 0x44, 0x51, 0x01, +0x56, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0xff, 0xf7, +0x01, 0xde, 0x02, 0x6b, 0x00, 0x1c, 0x00, 0x28, 0x00, 0x56, +0xb9, 0x00, 0x01, 0xff, 0xf0, 0x40, 0x0c, 0x0b, 0x0d, 0x00, +0x4c, 0x25, 0x19, 0x73, 0x0a, 0x0b, 0x73, 0x18, 0x18, 0xb8, +0xff, 0xc0, 0x40, 0x1f, 0x09, 0x0c, 0x48, 0x0a, 0x18, 0x0a, +0x18, 0x11, 0x20, 0x76, 0x03, 0x2a, 0x11, 0x29, 0x23, 0x7c, +0x00, 0x00, 0x1d, 0x0b, 0x79, 0x18, 0x41, 0x11, 0x7c, 0x10, +0x46, 0x1d, 0x7c, 0x06, 0x46, 0x00, 0x3f, 0xed, 0x3f, 0xed, +0x3f, 0xed, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xc6, 0x10, +0xde, 0xed, 0x11, 0x39, 0x39, 0x2f, 0x2f, 0x2b, 0x10, 0xed, +0x10, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x01, 0x32, 0x16, 0x15, +0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x11, 0x23, 0x14, 0x0e, +0x02, 0x07, 0x27, 0x3e, 0x05, 0x35, 0x33, 0x15, 0x36, 0x36, +0x13, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x07, 0x15, +0x16, 0x16, 0x01, 0x51, 0x45, 0x48, 0x49, 0x4d, 0x17, 0x30, +0x1a, 0x44, 0x05, 0x1b, 0x3b, 0x36, 0x09, 0x14, 0x1b, 0x12, +0x0a, 0x04, 0x01, 0xd8, 0x08, 0x10, 0x06, 0x23, 0x1f, 0x25, +0x22, 0x0d, 0x0c, 0x08, 0x10, 0x01, 0x8c, 0x64, 0x61, 0x5f, +0x6f, 0x08, 0x08, 0x02, 0x1c, 0xa0, 0xcc, 0x7a, 0x3a, 0x0e, +0x49, 0x06, 0x18, 0x2f, 0x4c, 0x77, 0xa8, 0x73, 0xe1, 0x01, +0x01, 0xfe, 0xb3, 0x3c, 0x4c, 0x3f, 0x40, 0x03, 0xff, 0x03, +0x02, 0x00, 0x00, 0x02, 0x00, 0x2d, 0xff, 0xf9, 0x01, 0xde, +0x02, 0x6b, 0x00, 0x16, 0x00, 0x23, 0x00, 0x4f, 0xb9, 0x00, +0x02, 0xff, 0xe8, 0x40, 0x28, 0x0d, 0x00, 0x4d, 0x14, 0x21, +0x73, 0x11, 0x09, 0x09, 0x0d, 0x1a, 0x76, 0x03, 0x25, 0x10, +0x0c, 0x73, 0x0d, 0x24, 0x12, 0x41, 0x1d, 0x7c, 0x00, 0x0b, +0x79, 0x10, 0x00, 0x10, 0x00, 0x10, 0x0d, 0x0e, 0x41, 0x0d, +0x44, 0x17, 0x7c, 0x06, 0x46, 0x00, 0x3f, 0xed, 0x3f, 0x3f, +0x12, 0x39, 0x39, 0x2f, 0x2f, 0x10, 0xed, 0x10, 0xed, 0x3f, +0x01, 0x10, 0xd6, 0xed, 0x32, 0x10, 0xde, 0xed, 0x11, 0x39, +0x2f, 0x33, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x01, 0x32, 0x16, +0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x11, 0x23, 0x11, +0x23, 0x11, 0x33, 0x15, 0x33, 0x35, 0x33, 0x15, 0x36, 0x36, +0x13, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x22, 0x07, +0x15, 0x16, 0x16, 0x01, 0x51, 0x45, 0x48, 0x49, 0x4d, 0x17, +0x30, 0x1a, 0x71, 0x49, 0x49, 0x71, 0x4a, 0x08, 0x10, 0x06, +0x23, 0x1f, 0x25, 0x22, 0x06, 0x0d, 0x06, 0x08, 0x10, 0x01, +0x87, 0x5f, 0x61, 0x5f, 0x6f, 0x08, 0x08, 0x01, 0x2c, 0xfe, +0xcb, 0x02, 0x6b, 0xf0, 0xf0, 0xe6, 0x01, 0x01, 0xfe, 0xb8, +0x3c, 0x4c, 0x3f, 0x3b, 0x02, 0xfb, 0x03, 0x02, 0x00, 0x00, +0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x01, 0xbf, 0x02, 0x6b, +0x00, 0x19, 0x00, 0x6b, 0xb9, 0x00, 0x14, 0xff, 0xe8, 0xb3, +0x0c, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xf0, 0xb3, 0x0b, 0x00, +0x4d, 0x14, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x14, +0xb8, 0xff, 0xe0, 0x40, 0x2c, 0x09, 0x00, 0x4d, 0x02, 0x18, +0x12, 0x00, 0x4d, 0x02, 0x28, 0x11, 0x00, 0x4d, 0x19, 0x73, +0x18, 0x0f, 0x0d, 0x01, 0x08, 0x0d, 0x0d, 0x18, 0x1b, 0x06, +0x0e, 0x73, 0x09, 0x0a, 0x1a, 0x19, 0x44, 0x03, 0x7c, 0x12, +0x12, 0x08, 0x0e, 0x09, 0x79, 0x0b, 0x41, 0x08, 0x44, 0x00, +0x3f, 0x3f, 0xed, 0x32, 0x12, 0x39, 0x2f, 0xed, 0x3f, 0x01, +0x10, 0xd6, 0xdd, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, 0x5e, +0x5d, 0x10, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x25, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x11, 0x23, +0x11, 0x23, 0x35, 0x21, 0x15, 0x23, 0x15, 0x36, 0x36, 0x33, +0x32, 0x1e, 0x02, 0x15, 0x15, 0x23, 0x01, 0x6c, 0x28, 0x33, +0x1a, 0x33, 0x0b, 0x52, 0x55, 0x01, 0x65, 0xbe, 0x0e, 0x38, +0x1d, 0x30, 0x3f, 0x25, 0x0f, 0x53, 0xa7, 0x53, 0x46, 0x0a, +0x04, 0xfe, 0xce, 0x02, 0x25, 0x46, 0x46, 0xae, 0x05, 0x09, +0x1c, 0x38, 0x53, 0x37, 0xa7, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x40, 0x00, 0x00, 0x01, 0xeb, 0x03, 0x3e, 0x02, 0x26, +0x00, 0x2e, 0x00, 0x00, 0x01, 0x07, 0x00, 0x8f, 0xff, 0xff, +0x00, 0x89, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xe8, 0x40, +0x09, 0x19, 0x17, 0x10, 0x08, 0x50, 0x01, 0x00, 0x18, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x37, +0x00, 0x00, 0x01, 0xbd, 0x03, 0x3e, 0x02, 0x26, 0x02, 0xcb, +0x00, 0x00, 0x01, 0x07, 0x00, 0x43, 0x00, 0x04, 0x00, 0x89, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x15, 0x13, 0x00, 0x09, +0x50, 0x01, 0x01, 0x14, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x09, 0xff, 0xf8, 0x01, 0xee, 0x03, 0x23, +0x02, 0x26, 0x02, 0xd6, 0x00, 0x00, 0x01, 0x07, 0x03, 0x90, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, +0xfe, 0x40, 0x09, 0x29, 0x31, 0x0b, 0x15, 0x50, 0x01, 0x0b, +0x26, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x31, 0xff, 0x5b, 0x01, 0xc6, 0x02, 0x6b, 0x00, 0x0b, +0x00, 0x2c, 0x40, 0x16, 0x06, 0x73, 0x09, 0x09, 0x0a, 0x02, +0x73, 0x05, 0x0d, 0x01, 0x73, 0x0a, 0x0c, 0x03, 0x0b, 0x41, +0x08, 0x06, 0x01, 0x79, 0x0a, 0x44, 0x00, 0x3f, 0xed, 0x33, +0xce, 0x3f, 0x33, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, +0x11, 0x39, 0x2f, 0xed, 0x31, 0x30, 0x13, 0x11, 0x33, 0x11, +0x33, 0x11, 0x23, 0x15, 0x23, 0x35, 0x23, 0x11, 0x83, 0xf0, +0x53, 0xa4, 0x4e, 0xa3, 0x02, 0x6b, 0xfd, 0xdb, 0x02, 0x25, +0xfd, 0x95, 0xa5, 0xa5, 0x02, 0x6b, 0xff, 0xff, 0x00, 0x09, +0x00, 0x00, 0x01, 0xeb, 0x02, 0x6b, 0x02, 0x06, 0x00, 0x24, +0x00, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0xfb, 0x01, 0xc3, +0x02, 0x6b, 0x02, 0x06, 0x01, 0xdb, 0x00, 0x00, 0xff, 0xff, +0x00, 0x36, 0xff, 0xfb, 0x01, 0xc3, 0x02, 0x71, 0x02, 0x06, +0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, 0x00, 0x00, +0x01, 0xcc, 0x02, 0x6b, 0x00, 0x09, 0x00, 0x25, 0x40, 0x12, +0x03, 0x0b, 0x06, 0x06, 0x05, 0x73, 0x00, 0x09, 0x0a, 0x05, +0x00, 0x79, 0x08, 0x44, 0x04, 0x79, 0x01, 0x41, 0x00, 0x3f, +0xed, 0x3f, 0xed, 0x32, 0x01, 0x10, 0xd6, 0xd5, 0xed, 0x32, +0x2f, 0x10, 0xce, 0x31, 0x30, 0x37, 0x11, 0x21, 0x15, 0x23, +0x11, 0x33, 0x15, 0x21, 0x35, 0x8f, 0x01, 0x3d, 0xeb, 0x86, +0xfe, 0xcf, 0x46, 0x02, 0x25, 0x46, 0xfe, 0x21, 0x46, 0x46, +0x00, 0x02, 0x00, 0x12, 0xff, 0x5b, 0x01, 0xd9, 0x02, 0x6b, +0x00, 0x10, 0x00, 0x19, 0x00, 0x65, 0x40, 0x14, 0x11, 0x73, +0x0a, 0x0b, 0x73, 0x19, 0x00, 0x0a, 0x01, 0x08, 0x0a, 0x19, +0x0a, 0x19, 0x04, 0x10, 0x73, 0x0d, 0x1b, 0x17, 0xb8, 0xff, +0xd8, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x17, 0xb8, 0xff, 0xe8, +0xb3, 0x10, 0x00, 0x4d, 0x17, 0xb8, 0xff, 0xf0, 0x40, 0x16, +0x0f, 0x00, 0x4d, 0x17, 0x04, 0x04, 0x00, 0x73, 0x03, 0x1a, +0x11, 0x79, 0x0a, 0x41, 0x17, 0x0c, 0x04, 0x79, 0x0f, 0x01, +0x00, 0x44, 0x00, 0x3f, 0xcd, 0x32, 0xed, 0x32, 0x32, 0x3f, +0xed, 0x01, 0x10, 0xd6, 0xed, 0x33, 0x2f, 0x33, 0x2b, 0x2b, +0x2b, 0x10, 0xde, 0xed, 0x11, 0x39, 0x39, 0x2f, 0x2f, 0x5e, +0x5d, 0x10, 0xed, 0x10, 0xed, 0x31, 0x30, 0x33, 0x15, 0x23, +0x35, 0x33, 0x3e, 0x03, 0x37, 0x37, 0x21, 0x11, 0x33, 0x15, +0x23, 0x35, 0x03, 0x07, 0x0e, 0x03, 0x07, 0x33, 0x11, 0x60, +0x4e, 0x24, 0x23, 0x24, 0x11, 0x05, 0x03, 0x03, 0x01, 0x19, +0x27, 0x4e, 0xa4, 0x02, 0x02, 0x06, 0x0f, 0x1e, 0x1b, 0xcb, +0xa5, 0xeb, 0x30, 0x6d, 0x79, 0x84, 0x48, 0x43, 0xfd, 0xdb, +0xeb, 0xa5, 0x02, 0x25, 0x43, 0x32, 0x6c, 0x6b, 0x66, 0x2d, +0x01, 0xdf, 0x00, 0x00, 0xff, 0xff, 0x00, 0x5b, 0x00, 0x00, +0x01, 0xcc, 0x02, 0x6b, 0x02, 0x06, 0x00, 0x28, 0x00, 0x00, +0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x01, 0xf1, 0x02, 0x6b, +0x00, 0x2d, 0x00, 0x8a, 0x40, 0x4c, 0x1b, 0x27, 0x00, 0x21, +0x10, 0x21, 0x02, 0x21, 0x27, 0x2c, 0x27, 0x78, 0x26, 0x21, +0x14, 0x26, 0x26, 0x21, 0x18, 0x2c, 0x73, 0x01, 0x06, 0x12, +0x0c, 0x12, 0x15, 0x12, 0x78, 0x11, 0x0c, 0x14, 0x11, 0x11, +0x0c, 0x15, 0x01, 0x01, 0x07, 0x1c, 0x1c, 0x9f, 0x26, 0x01, +0x26, 0x2f, 0x11, 0x11, 0x07, 0x2e, 0x26, 0x27, 0x44, 0x1c, +0x1b, 0x41, 0x18, 0x15, 0x15, 0x0c, 0x2c, 0x01, 0x01, 0x21, +0x0c, 0x0c, 0x16, 0x41, 0x12, 0x11, 0x41, 0x07, 0x06, 0x44, +0x00, 0x44, 0x00, 0x3f, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0x39, +0x11, 0x33, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x3f, +0x33, 0x3f, 0x33, 0x01, 0x10, 0xc6, 0x33, 0x2f, 0x10, 0xce, +0x5d, 0x32, 0x2f, 0x11, 0x39, 0x2f, 0x33, 0x87, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x01, 0x11, 0x33, 0x18, 0x10, 0xed, 0x32, +0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x5d, 0x11, 0x33, +0x31, 0x30, 0x33, 0x11, 0x0e, 0x03, 0x07, 0x23, 0x3e, 0x03, +0x37, 0x2e, 0x03, 0x27, 0x33, 0x16, 0x16, 0x17, 0x11, 0x33, +0x11, 0x36, 0x36, 0x37, 0x33, 0x0e, 0x03, 0x07, 0x1e, 0x03, +0x17, 0x23, 0x2e, 0x03, 0x27, 0x11, 0xd5, 0x14, 0x23, 0x20, +0x1c, 0x0c, 0x52, 0x0c, 0x22, 0x28, 0x2b, 0x15, 0x12, 0x22, +0x23, 0x23, 0x12, 0x52, 0x1d, 0x39, 0x1f, 0x4a, 0x1e, 0x3a, +0x1d, 0x52, 0x12, 0x24, 0x22, 0x22, 0x12, 0x15, 0x2b, 0x29, +0x22, 0x0c, 0x53, 0x0c, 0x1c, 0x20, 0x24, 0x13, 0x01, 0x2d, +0x18, 0x46, 0x51, 0x56, 0x28, 0x2b, 0x5e, 0x58, 0x4e, 0x1b, +0x22, 0x42, 0x45, 0x4c, 0x2c, 0x4d, 0x85, 0x39, 0x01, 0x0b, +0xfe, 0xf7, 0x39, 0x84, 0x4c, 0x2c, 0x4c, 0x45, 0x42, 0x22, +0x1b, 0x4e, 0x58, 0x5e, 0x2b, 0x28, 0x55, 0x51, 0x46, 0x18, +0xfe, 0xd4, 0x00, 0x01, 0x00, 0x26, 0xff, 0xf4, 0x01, 0xd1, +0x02, 0x76, 0x00, 0x34, 0x00, 0xb9, 0x40, 0x15, 0x30, 0x18, +0x10, 0x00, 0x4d, 0x2c, 0x18, 0x10, 0x00, 0x4d, 0x25, 0x20, +0x0e, 0x00, 0x4d, 0x25, 0x10, 0x0d, 0x00, 0x4d, 0x1f, 0xb8, +0xff, 0xd0, 0xb3, 0x12, 0x00, 0x4d, 0x1f, 0xb8, 0xff, 0xd8, +0xb3, 0x11, 0x00, 0x4d, 0x1f, 0xb8, 0xff, 0xe0, 0xb3, 0x08, +0x00, 0x4d, 0x1b, 0xb8, 0xff, 0xe8, 0xb4, 0x11, 0x12, 0x00, +0x4c, 0x17, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, 0x17, +0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x13, 0xb8, 0xff, +0xd8, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x13, 0xb8, 0xff, 0xe0, +0x40, 0x36, 0x08, 0x0a, 0x00, 0x4c, 0x0e, 0x20, 0x11, 0x12, +0x00, 0x4c, 0x04, 0x10, 0x0f, 0x10, 0x00, 0x4c, 0x04, 0x18, +0x0e, 0x00, 0x4d, 0x18, 0x06, 0x76, 0x15, 0x15, 0x2e, 0x76, +0x1d, 0x36, 0x34, 0x34, 0x0d, 0x0d, 0x27, 0x35, 0x18, 0x34, +0x79, 0x00, 0x00, 0x10, 0x28, 0x28, 0x2b, 0x7c, 0x22, 0x46, +0x0c, 0x0c, 0x09, 0x7c, 0x10, 0x45, 0x00, 0x3f, 0xed, 0x32, +0x2f, 0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x2f, 0xed, 0x39, +0x01, 0x10, 0xc6, 0x32, 0x2f, 0x32, 0x2f, 0x10, 0xde, 0xed, +0x33, 0x2f, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x13, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x26, 0x23, +0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, +0x15, 0x14, 0x06, 0x07, 0x1e, 0x03, 0x15, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x2e, 0x02, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, +0x36, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x23, 0x8d, 0x21, 0x1e, +0x40, 0x35, 0x22, 0x43, 0x36, 0x30, 0x4f, 0x14, 0x1b, 0x17, +0x60, 0x38, 0x2c, 0x4b, 0x36, 0x1e, 0x37, 0x36, 0x1b, 0x31, +0x26, 0x16, 0x22, 0x3f, 0x58, 0x36, 0x22, 0x3b, 0x31, 0x24, +0x0a, 0x19, 0x15, 0x54, 0x39, 0x48, 0x56, 0x20, 0x36, 0x49, +0x29, 0x2a, 0x01, 0x6a, 0x09, 0x18, 0x29, 0x20, 0x29, 0x33, +0x15, 0x0b, 0x41, 0x0f, 0x16, 0x13, 0x27, 0x3d, 0x29, 0x2b, +0x4c, 0x11, 0x07, 0x1a, 0x28, 0x36, 0x24, 0x32, 0x45, 0x2c, +0x14, 0x0a, 0x0e, 0x0f, 0x05, 0x42, 0x0b, 0x1d, 0x35, 0x3e, +0x24, 0x2f, 0x1a, 0x0a, 0x00, 0x01, 0x00, 0x37, 0x00, 0x00, +0x01, 0xbd, 0x02, 0x6b, 0x00, 0x11, 0x00, 0x4c, 0x40, 0x2f, +0x29, 0x08, 0x49, 0x08, 0x02, 0x0a, 0x08, 0x01, 0x05, 0x11, +0x25, 0x11, 0x02, 0x08, 0x11, 0x0c, 0x11, 0x78, 0x03, 0x08, +0x14, 0x03, 0x03, 0x08, 0x0c, 0x73, 0x09, 0x13, 0x03, 0x73, +0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x12, 0x03, 0x11, 0x44, +0x0b, 0x44, 0x0c, 0x08, 0x41, 0x02, 0x41, 0x00, 0x3f, 0x3f, +0x33, 0x3f, 0x3f, 0x33, 0x01, 0x10, 0xd6, 0x5d, 0xed, 0x10, +0xde, 0xed, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x5d, +0x5d, 0x5d, 0x31, 0x30, 0x33, 0x11, 0x33, 0x11, 0x3e, 0x03, +0x37, 0x33, 0x11, 0x23, 0x11, 0x0e, 0x03, 0x07, 0x37, 0x4b, +0x1e, 0x30, 0x33, 0x3d, 0x29, 0x54, 0x4b, 0x1c, 0x35, 0x38, +0x3c, 0x22, 0x02, 0x6b, 0xfe, 0x24, 0x49, 0x6f, 0x69, 0x70, +0x4b, 0xfd, 0x95, 0x01, 0xee, 0x35, 0x69, 0x76, 0x87, 0x53, +0xff, 0xff, 0x00, 0x37, 0x00, 0x00, 0x01, 0xbd, 0x03, 0x23, +0x02, 0x26, 0x02, 0xcb, 0x00, 0x00, 0x01, 0x07, 0x03, 0x90, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, +0x15, 0x1d, 0x00, 0x09, 0x50, 0x01, 0x01, 0x12, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x40, 0x00, 0x00, +0x01, 0xeb, 0x02, 0x6b, 0x02, 0x06, 0x00, 0x2e, 0x00, 0x00, +0x00, 0x01, 0x00, 0x0d, 0xff, 0xf7, 0x01, 0xc7, 0x02, 0x6b, +0x00, 0x15, 0x00, 0x5a, 0xb5, 0x0c, 0x10, 0x0d, 0x00, 0x4d, +0x06, 0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, 0x06, 0xb8, +0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x06, 0xb8, 0xff, 0xf0, +0xb4, 0x0b, 0x0c, 0x00, 0x4c, 0x05, 0xb8, 0xff, 0xf0, 0x40, +0x1c, 0x12, 0x00, 0x4d, 0x00, 0x73, 0x00, 0x11, 0x01, 0x08, +0x11, 0x11, 0x09, 0x14, 0x73, 0x13, 0x17, 0x09, 0x16, 0x14, +0x44, 0x00, 0x79, 0x11, 0x41, 0x09, 0x7c, 0x08, 0x46, 0x00, +0x3f, 0xed, 0x3f, 0xed, 0x3f, 0x01, 0x10, 0xc6, 0x10, 0xde, +0xed, 0x11, 0x39, 0x2f, 0x5e, 0x5d, 0xed, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x06, 0x06, 0x07, 0x0e, 0x03, +0x07, 0x27, 0x36, 0x36, 0x37, 0x3e, 0x03, 0x35, 0x21, 0x11, +0x23, 0x11, 0xee, 0x03, 0x0c, 0x16, 0x0b, 0x1e, 0x2b, 0x39, +0x26, 0x09, 0x2c, 0x30, 0x14, 0x0a, 0x0d, 0x07, 0x03, 0x01, +0x29, 0x52, 0x02, 0x25, 0x66, 0xb4, 0x51, 0x28, 0x46, 0x34, +0x1f, 0x02, 0x48, 0x07, 0x41, 0x45, 0x24, 0x5e, 0x6c, 0x76, +0x3b, 0xfd, 0x95, 0x02, 0x25, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x20, 0x00, 0x00, 0x01, 0xd4, 0x02, 0x6b, 0x02, 0x06, +0x00, 0x30, 0x00, 0x00, 0xff, 0xff, 0x00, 0x2d, 0x00, 0x00, +0x01, 0xc7, 0x02, 0x6b, 0x02, 0x06, 0x00, 0x2b, 0x00, 0x00, +0xff, 0xff, 0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, 0x02, 0x79, +0x02, 0x06, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2d, +0x00, 0x00, 0x01, 0xc7, 0x02, 0x6b, 0x00, 0x07, 0x00, 0x20, +0x40, 0x10, 0x00, 0x73, 0x07, 0x09, 0x03, 0x73, 0x04, 0x08, +0x02, 0x79, 0x05, 0x41, 0x04, 0x44, 0x00, 0x44, 0x00, 0x3f, +0x3f, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, +0x31, 0x30, 0x21, 0x11, 0x23, 0x11, 0x23, 0x11, 0x21, 0x11, +0x01, 0x75, 0xf6, 0x52, 0x01, 0x9a, 0x02, 0x25, 0xfd, 0xdb, +0x02, 0x6b, 0xfd, 0x95, 0xff, 0xff, 0x00, 0x49, 0x00, 0x00, +0x01, 0xc7, 0x02, 0x71, 0x02, 0x06, 0x00, 0x33, 0x00, 0x00, +0xff, 0xff, 0x00, 0x2e, 0xff, 0xf3, 0x01, 0xcc, 0x02, 0x79, +0x02, 0x06, 0x00, 0x26, 0x00, 0x00, 0xff, 0xff, 0x00, 0x27, +0x00, 0x00, 0x01, 0xcd, 0x02, 0x6b, 0x02, 0x06, 0x00, 0x37, +0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0xff, 0xf8, 0x01, 0xee, +0x02, 0x6b, 0x00, 0x25, 0x00, 0x74, 0xb9, 0x00, 0x1d, 0xff, +0xf0, 0xb3, 0x0e, 0x00, 0x4d, 0x1b, 0xb8, 0xff, 0xf0, 0x40, +0x3b, 0x08, 0x00, 0x4d, 0x03, 0x18, 0x0d, 0x00, 0x4d, 0x1a, +0x14, 0x11, 0x14, 0x78, 0x15, 0x1a, 0x14, 0x15, 0x15, 0x1a, +0x06, 0x10, 0x09, 0x0a, 0x00, 0x4c, 0x06, 0x0c, 0x11, 0x0c, +0x78, 0x0b, 0x06, 0x14, 0x0b, 0x0b, 0x06, 0x11, 0x0b, 0x15, +0x27, 0x22, 0x22, 0x0b, 0x26, 0x1a, 0x11, 0x06, 0x06, 0x0b, +0x00, 0x7c, 0x1f, 0x46, 0x15, 0x14, 0x41, 0x0c, 0x0b, 0x41, +0x00, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0xed, 0x12, 0x39, 0x11, +0x33, 0x33, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xce, 0x11, +0x39, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x2b, 0x87, +0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x01, 0x2b, +0x2b, 0x2b, 0x37, 0x32, 0x3e, 0x02, 0x37, 0x37, 0x2e, 0x03, +0x27, 0x33, 0x1e, 0x03, 0x17, 0x36, 0x36, 0x37, 0x33, 0x0e, +0x03, 0x07, 0x0e, 0x03, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, +0x16, 0x71, 0x18, 0x24, 0x1d, 0x17, 0x0b, 0x08, 0x25, 0x46, +0x3d, 0x32, 0x11, 0x5a, 0x0f, 0x29, 0x2f, 0x33, 0x18, 0x25, +0x40, 0x1b, 0x59, 0x14, 0x27, 0x27, 0x27, 0x14, 0x12, 0x26, +0x33, 0x47, 0x31, 0x14, 0x2d, 0x08, 0x0f, 0x0b, 0x20, 0x3f, +0x0d, 0x16, 0x20, 0x13, 0x0e, 0x3a, 0x7f, 0x7a, 0x6d, 0x28, +0x26, 0x5c, 0x63, 0x63, 0x2e, 0x59, 0xb9, 0x64, 0x3f, 0x6c, +0x63, 0x5d, 0x30, 0x2a, 0x4e, 0x3c, 0x24, 0x09, 0x05, 0x46, +0x05, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x2a, 0x00, 0x00, +0x01, 0xd4, 0x02, 0x93, 0x00, 0x15, 0x00, 0x1c, 0x00, 0x21, +0x00, 0x97, 0x40, 0x11, 0x21, 0x10, 0x0d, 0x0e, 0x00, 0x4c, +0x1e, 0x18, 0x0e, 0x00, 0x4d, 0x1e, 0x10, 0x0d, 0x00, 0x4d, +0x1b, 0xb8, 0xff, 0xe8, 0xb4, 0x0d, 0x0e, 0x00, 0x4c, 0x18, +0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x18, 0xb8, 0xff, +0xf0, 0x40, 0x1b, 0x0d, 0x00, 0x4d, 0x1d, 0x18, 0x0d, 0x00, +0x4d, 0x20, 0x06, 0x0e, 0x73, 0x19, 0x03, 0x11, 0x11, 0x00, +0x1d, 0x18, 0x0e, 0x00, 0x4d, 0x1d, 0x76, 0x09, 0x23, 0x16, +0xb8, 0xff, 0xe8, 0x40, 0x26, 0x0d, 0x0e, 0x00, 0x4c, 0x16, +0x76, 0x1f, 0x00, 0x01, 0x40, 0x00, 0x50, 0x00, 0x70, 0x00, +0xc0, 0x00, 0xd0, 0x00, 0x05, 0x2f, 0x00, 0x01, 0x00, 0x22, +0x20, 0x19, 0x7c, 0x0e, 0x11, 0x10, 0x44, 0x1f, 0x1a, 0x7c, +0x06, 0x03, 0x04, 0x00, 0x2f, 0xdd, 0x32, 0xed, 0x32, 0x3f, +0xdd, 0x32, 0xed, 0x32, 0x01, 0x10, 0xd6, 0x5d, 0x5d, 0x71, +0xed, 0x2b, 0x10, 0xd6, 0xed, 0x2b, 0x11, 0x39, 0x2f, 0x33, +0x33, 0xed, 0x32, 0x32, 0x2b, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x13, 0x34, 0x36, 0x37, 0x35, 0x33, 0x15, +0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x15, 0x23, 0x35, +0x2e, 0x03, 0x37, 0x14, 0x16, 0x17, 0x11, 0x06, 0x06, 0x05, +0x34, 0x27, 0x11, 0x36, 0x2a, 0x61, 0x50, 0x49, 0x4f, 0x61, +0x19, 0x2f, 0x41, 0x27, 0x49, 0x28, 0x41, 0x2f, 0x19, 0x52, +0x2d, 0x32, 0x32, 0x2d, 0x01, 0x06, 0x5e, 0x5e, 0x01, 0x4c, +0x76, 0x7c, 0x0b, 0x4a, 0x4a, 0x0b, 0x7c, 0x76, 0x3b, 0x5a, +0x3f, 0x24, 0x06, 0x4e, 0x4e, 0x06, 0x24, 0x3f, 0x5a, 0x3b, +0x52, 0x5c, 0x0b, 0x01, 0x72, 0x0b, 0x5d, 0x51, 0xa0, 0x18, +0xfe, 0x90, 0x17, 0x00, 0xff, 0xff, 0x00, 0x19, 0x00, 0x00, +0x01, 0xdb, 0x02, 0x6b, 0x02, 0x06, 0x00, 0x3b, 0x00, 0x00, +0x00, 0x01, 0x00, 0x2d, 0xff, 0x5b, 0x01, 0xd9, 0x02, 0x6b, +0x00, 0x0b, 0x00, 0x28, 0x40, 0x14, 0x03, 0x73, 0x06, 0x0a, +0x73, 0x07, 0x0d, 0x02, 0x73, 0x0b, 0x0c, 0x06, 0x02, 0x79, +0x09, 0x0b, 0x44, 0x04, 0x00, 0x41, 0x00, 0x3f, 0x32, 0x3f, +0xce, 0xed, 0x32, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, +0xd5, 0xed, 0x31, 0x30, 0x13, 0x33, 0x11, 0x33, 0x11, 0x33, +0x11, 0x33, 0x15, 0x23, 0x35, 0x21, 0x2d, 0x52, 0xe1, 0x52, +0x27, 0x4e, 0xfe, 0xa2, 0x02, 0x6b, 0xfd, 0xdb, 0x02, 0x25, +0xfd, 0xdb, 0xeb, 0xa5, 0x00, 0x01, 0x00, 0x36, 0x00, 0x00, +0x01, 0xbf, 0x02, 0x6b, 0x00, 0x17, 0x00, 0x4d, 0x40, 0x10, +0x13, 0x30, 0x0a, 0x00, 0x4d, 0x13, 0x18, 0x09, 0x00, 0x4d, +0x13, 0x28, 0x08, 0x00, 0x4d, 0x03, 0xb8, 0xff, 0xe0, 0xb3, +0x12, 0x00, 0x4d, 0x03, 0xb8, 0xff, 0xe8, 0x40, 0x17, 0x11, +0x00, 0x4d, 0x08, 0x0c, 0x73, 0x0b, 0x19, 0x00, 0x73, 0x15, +0x18, 0x05, 0x7c, 0x10, 0x10, 0x0c, 0x16, 0x41, 0x0c, 0x44, +0x09, 0x41, 0x00, 0x3f, 0x3f, 0x3f, 0x12, 0x39, 0x2f, 0xed, +0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, 0x32, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x14, 0x1e, 0x02, 0x33, +0x32, 0x36, 0x37, 0x11, 0x33, 0x11, 0x23, 0x35, 0x06, 0x06, +0x23, 0x22, 0x2e, 0x02, 0x35, 0x35, 0x33, 0x89, 0x0b, 0x1c, +0x30, 0x24, 0x20, 0x3b, 0x0e, 0x52, 0x52, 0x0f, 0x42, 0x23, +0x3c, 0x4c, 0x2b, 0x10, 0x53, 0x01, 0xb8, 0x26, 0x39, 0x26, +0x12, 0x0a, 0x04, 0x01, 0x3c, 0xfd, 0x95, 0xe8, 0x05, 0x09, +0x1f, 0x3a, 0x52, 0x33, 0xb3, 0x00, 0x00, 0x01, 0x00, 0x2d, +0x00, 0x00, 0x01, 0xc7, 0x02, 0x6b, 0x00, 0x0b, 0x00, 0x2e, +0x40, 0x17, 0x06, 0x73, 0x03, 0x03, 0x0b, 0x07, 0x73, 0x0a, +0x0d, 0x02, 0x73, 0x0b, 0x0c, 0x06, 0x02, 0x79, 0x0b, 0x44, +0x08, 0x04, 0x04, 0x00, 0x41, 0x00, 0x3f, 0x32, 0x2f, 0x32, +0x3f, 0xed, 0x32, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, +0x11, 0x39, 0x2f, 0xed, 0x31, 0x30, 0x13, 0x33, 0x11, 0x33, +0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x21, 0x2d, 0x4b, +0x5d, 0x4b, 0x5c, 0x4b, 0xfe, 0x66, 0x02, 0x6b, 0xfd, 0xdb, +0x01, 0x3a, 0xfe, 0xc6, 0x02, 0x25, 0xfd, 0x95, 0x00, 0x01, +0x00, 0x2d, 0xff, 0x5b, 0x01, 0xd9, 0x02, 0x6b, 0x00, 0x0f, +0x00, 0x41, 0x40, 0x25, 0x06, 0x73, 0x03, 0x03, 0x0f, 0x07, +0x73, 0x4f, 0x0a, 0x5f, 0x0a, 0xaf, 0x0a, 0xbf, 0x0a, 0x04, +0x0a, 0x0e, 0x73, 0x0b, 0x11, 0x02, 0x73, 0x0f, 0x10, 0x0a, +0x06, 0x02, 0x79, 0x0d, 0x0f, 0x44, 0x08, 0x04, 0x04, 0x00, +0x41, 0x00, 0x3f, 0x32, 0x2f, 0x32, 0x3f, 0xce, 0xed, 0x32, +0x32, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, 0xd5, 0x5d, +0xed, 0x11, 0x39, 0x2f, 0xed, 0x31, 0x30, 0x13, 0x33, 0x11, +0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x15, +0x23, 0x35, 0x21, 0x2d, 0x4b, 0x52, 0x4b, 0x52, 0x4b, 0x27, +0x4e, 0xfe, 0xa2, 0x02, 0x6b, 0xfd, 0xdb, 0x01, 0x3a, 0xfe, +0xc6, 0x02, 0x25, 0xfd, 0xdb, 0xeb, 0xa5, 0x00, 0x00, 0x02, +0x00, 0x12, 0xff, 0xf9, 0x01, 0xcc, 0x02, 0x6b, 0x00, 0x13, +0x00, 0x24, 0x00, 0x80, 0x40, 0x1f, 0x23, 0x20, 0x0f, 0x00, +0x4d, 0x22, 0x18, 0x10, 0x00, 0x4d, 0x22, 0x10, 0x0e, 0x00, +0x4d, 0x17, 0x30, 0x10, 0x00, 0x4d, 0x17, 0x20, 0x0e, 0x00, +0x4d, 0x16, 0x28, 0x0f, 0x00, 0x4d, 0x12, 0xb8, 0xff, 0xe8, +0xb3, 0x0a, 0x00, 0x4d, 0x12, 0xb8, 0xff, 0xf0, 0xb3, 0x09, +0x00, 0x4d, 0x02, 0xb8, 0xff, 0xd8, 0xb3, 0x12, 0x00, 0x4d, +0x02, 0xb8, 0xff, 0xe0, 0xb3, 0x11, 0x00, 0x4d, 0x02, 0xb8, +0xff, 0xf0, 0x40, 0x1b, 0x09, 0x0a, 0x00, 0x4c, 0x14, 0x76, +0x00, 0x26, 0x1c, 0x0c, 0x73, 0x09, 0x0a, 0x25, 0x19, 0x7c, +0x0f, 0x0f, 0x20, 0x09, 0x79, 0x0c, 0x41, 0x20, 0x7c, 0x05, +0x46, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0xed, +0x01, 0x10, 0xd6, 0xdd, 0xed, 0x32, 0x10, 0xde, 0xed, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x25, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, +0x11, 0x23, 0x35, 0x33, 0x15, 0x36, 0x33, 0x32, 0x1e, 0x02, +0x07, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0x11, 0x16, +0x16, 0x33, 0x32, 0x3e, 0x02, 0x01, 0xcc, 0x22, 0x3a, 0x4f, +0x2e, 0x1f, 0x42, 0x22, 0x5e, 0xb0, 0x19, 0x19, 0x30, 0x4f, +0x39, 0x20, 0x54, 0x14, 0x26, 0x34, 0x21, 0x09, 0x14, 0x0a, +0x0d, 0x18, 0x0c, 0x1c, 0x31, 0x24, 0x14, 0xc2, 0x38, 0x4d, +0x2f, 0x15, 0x08, 0x08, 0x02, 0x1c, 0x46, 0xe2, 0x03, 0x17, +0x30, 0x4d, 0x36, 0x26, 0x33, 0x1e, 0x0d, 0x01, 0x01, 0xfe, +0xfe, 0x02, 0x01, 0x0d, 0x1e, 0x32, 0x00, 0x00, 0x00, 0x03, +0x00, 0x24, 0xff, 0xfa, 0x01, 0xd0, 0x02, 0x6b, 0x00, 0x0e, +0x00, 0x1d, 0x00, 0x21, 0x00, 0x45, 0x40, 0x2a, 0x1c, 0x10, +0x11, 0x12, 0x00, 0x4c, 0x12, 0x18, 0x11, 0x12, 0x00, 0x4c, +0x0f, 0x76, 0x0f, 0x00, 0x01, 0x08, 0x00, 0x21, 0x73, 0x20, +0x23, 0x09, 0x18, 0x73, 0x06, 0x22, 0x21, 0x44, 0x1e, 0x41, +0x14, 0x7c, 0x0c, 0x0c, 0x07, 0x41, 0x1b, 0x7c, 0x03, 0x43, +0x00, 0x3f, 0xed, 0x3f, 0x39, 0x2f, 0xed, 0x3f, 0x3f, 0x01, +0x10, 0xd6, 0xed, 0x32, 0x10, 0xde, 0xfd, 0xde, 0x5e, 0x5d, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x25, 0x14, 0x06, 0x23, 0x22, +0x26, 0x27, 0x11, 0x33, 0x15, 0x36, 0x36, 0x33, 0x32, 0x16, +0x07, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0x15, 0x16, +0x16, 0x33, 0x32, 0x36, 0x13, 0x33, 0x11, 0x23, 0x01, 0x47, +0x5b, 0x53, 0x1a, 0x41, 0x1a, 0x4e, 0x0b, 0x14, 0x0a, 0x52, +0x5a, 0x51, 0x0a, 0x16, 0x26, 0x1c, 0x08, 0x10, 0x0a, 0x0c, +0x15, 0x0a, 0x30, 0x29, 0x8c, 0x4e, 0x4e, 0xc2, 0x64, 0x64, +0x07, 0x08, 0x02, 0x62, 0xe3, 0x02, 0x02, 0x67, 0x63, 0x1e, +0x30, 0x23, 0x13, 0x02, 0x02, 0xfe, 0x03, 0x02, 0x41, 0x01, +0xeb, 0xfd, 0x95, 0x00, 0x00, 0x02, 0x00, 0x2d, 0xff, 0xfa, +0x01, 0xcc, 0x02, 0x6b, 0x00, 0x0e, 0x00, 0x1f, 0x00, 0x58, +0x40, 0x1b, 0x1d, 0x30, 0x0f, 0x10, 0x00, 0x4c, 0x1d, 0x18, +0x0e, 0x00, 0x4d, 0x12, 0x40, 0x10, 0x00, 0x4d, 0x12, 0x30, +0x0f, 0x00, 0x4d, 0x12, 0x18, 0x0e, 0x00, 0x4d, 0x0e, 0xb8, +0xff, 0xe0, 0xb3, 0x08, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xe8, +0x40, 0x16, 0x08, 0x00, 0x4d, 0x0f, 0x76, 0x00, 0x21, 0x09, +0x18, 0x73, 0x06, 0x20, 0x14, 0x7c, 0x0c, 0x0c, 0x07, 0x41, +0x1b, 0x7c, 0x03, 0x43, 0x00, 0x3f, 0xed, 0x3f, 0x39, 0x2f, +0xed, 0x01, 0x10, 0xd6, 0xed, 0x32, 0x10, 0xde, 0xed, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x14, +0x06, 0x23, 0x22, 0x26, 0x27, 0x11, 0x33, 0x15, 0x36, 0x32, +0x33, 0x32, 0x16, 0x07, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x22, +0x07, 0x11, 0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x01, 0xcc, +0x83, 0x80, 0x25, 0x52, 0x25, 0x52, 0x11, 0x22, 0x12, 0x88, +0x80, 0x54, 0x1b, 0x30, 0x44, 0x28, 0x11, 0x20, 0x11, 0x0f, +0x26, 0x1c, 0x21, 0x3d, 0x2e, 0x1c, 0xc2, 0x64, 0x64, 0x06, +0x09, 0x02, 0x62, 0xe1, 0x02, 0x64, 0x66, 0x26, 0x33, 0x1f, +0x0d, 0x02, 0xfe, 0xfd, 0x02, 0x01, 0x0d, 0x1f, 0x32, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x2e, 0xff, 0xf3, 0x01, 0xd5, +0x02, 0x79, 0x00, 0x26, 0x00, 0xa5, 0x40, 0x54, 0x25, 0x28, +0x12, 0x00, 0x4d, 0x25, 0x20, 0x10, 0x11, 0x00, 0x4c, 0x1e, +0x18, 0x12, 0x00, 0x4d, 0x1e, 0x10, 0x11, 0x00, 0x4d, 0x1e, +0x20, 0x0d, 0x00, 0x4d, 0x1e, 0x18, 0x0b, 0x0c, 0x00, 0x4c, +0x17, 0x08, 0x10, 0x00, 0x4d, 0x16, 0x10, 0x12, 0x00, 0x4d, +0x16, 0x18, 0x11, 0x00, 0x4d, 0x16, 0x38, 0x0d, 0x00, 0x4d, +0x0d, 0x18, 0x12, 0x00, 0x4d, 0x0d, 0x10, 0x11, 0x00, 0x4d, +0x0d, 0x20, 0x10, 0x00, 0x4d, 0x0d, 0x18, 0x0e, 0x0f, 0x00, +0x4c, 0x07, 0x18, 0x0d, 0x00, 0x4d, 0x03, 0x10, 0x0d, 0x00, +0x4d, 0x02, 0xb8, 0xff, 0xe8, 0x40, 0x1f, 0x0e, 0x00, 0x4d, +0x1b, 0x18, 0x76, 0x05, 0x28, 0x24, 0x24, 0x19, 0x19, 0x0f, +0x27, 0x19, 0x79, 0x1a, 0x1a, 0x00, 0x10, 0x10, 0x15, 0x7c, +0x0a, 0x46, 0x23, 0x23, 0x20, 0x7c, 0x00, 0x45, 0x00, 0x3f, +0xed, 0x32, 0x2f, 0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x2f, +0xed, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x32, 0x2f, 0x10, 0xde, +0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x13, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x2e, 0x02, 0x27, 0x37, 0x1e, 0x03, 0x33, 0x32, 0x36, +0x37, 0x23, 0x35, 0x33, 0x2e, 0x03, 0x23, 0x22, 0x06, 0x07, +0x27, 0x36, 0x36, 0xd4, 0x3a, 0x5f, 0x43, 0x25, 0x27, 0x45, +0x60, 0x39, 0x21, 0x35, 0x29, 0x1c, 0x07, 0x15, 0x08, 0x1d, +0x24, 0x28, 0x13, 0x55, 0x61, 0x07, 0xe6, 0xe5, 0x04, 0x1a, +0x2d, 0x41, 0x2b, 0x31, 0x46, 0x11, 0x15, 0x12, 0x55, 0x02, +0x79, 0x29, 0x52, 0x79, 0x4f, 0x50, 0x79, 0x51, 0x29, 0x09, +0x0e, 0x0d, 0x05, 0x42, 0x06, 0x0c, 0x0b, 0x07, 0x73, 0x6c, +0x46, 0x2f, 0x4e, 0x37, 0x1f, 0x18, 0x09, 0x40, 0x0b, 0x1d, +0x00, 0x00, 0x00, 0x02, 0x00, 0x2d, 0xff, 0xf3, 0x01, 0xd9, +0x02, 0x79, 0x00, 0x18, 0x00, 0x2c, 0x00, 0x86, 0xb6, 0x10, +0x28, 0x11, 0x12, 0x00, 0x4c, 0x0c, 0xb8, 0xff, 0xd8, 0xb3, +0x12, 0x00, 0x4d, 0x0c, 0xb8, 0xff, 0xe0, 0xb3, 0x11, 0x00, +0x4d, 0x06, 0xb8, 0xff, 0xd8, 0xb3, 0x12, 0x00, 0x4d, 0x06, +0xb8, 0xff, 0xe0, 0x40, 0x1b, 0x11, 0x00, 0x4d, 0x03, 0x20, +0x11, 0x12, 0x00, 0x4c, 0x02, 0x18, 0x0a, 0x00, 0x4d, 0x02, +0x10, 0x09, 0x00, 0x4d, 0x23, 0x76, 0x09, 0x2e, 0x19, 0x76, +0x01, 0x13, 0xb8, 0xff, 0xc0, 0x40, 0x1f, 0x09, 0x0c, 0x48, +0x13, 0x00, 0x15, 0x73, 0x16, 0x2d, 0x14, 0x79, 0x0f, 0x00, +0x1f, 0x00, 0x02, 0x00, 0x00, 0x16, 0x17, 0x41, 0x16, 0x44, +0x1e, 0x7c, 0x0e, 0x46, 0x28, 0x7c, 0x04, 0x45, 0x00, 0x3f, +0xed, 0x3f, 0xed, 0x3f, 0x3f, 0x12, 0x39, 0x2f, 0x5d, 0xed, +0x01, 0x10, 0xd6, 0xfd, 0x32, 0xde, 0x2b, 0x32, 0xed, 0x10, +0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x13, 0x33, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, +0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x27, 0x23, +0x11, 0x23, 0x11, 0x33, 0x13, 0x14, 0x1e, 0x02, 0x33, 0x32, +0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x0e, 0x02, +0x7b, 0x3d, 0x05, 0x4a, 0x3f, 0x24, 0x36, 0x26, 0x13, 0x14, +0x26, 0x37, 0x22, 0x22, 0x34, 0x24, 0x14, 0x01, 0x3c, 0x4e, +0x4e, 0x8b, 0x08, 0x10, 0x19, 0x11, 0x11, 0x19, 0x11, 0x08, +0x08, 0x11, 0x19, 0x11, 0x11, 0x19, 0x10, 0x08, 0x01, 0x66, +0x92, 0x81, 0x24, 0x4e, 0x7b, 0x56, 0x57, 0x7a, 0x4e, 0x24, +0x22, 0x48, 0x72, 0x51, 0xfe, 0xe0, 0x02, 0x6b, 0xfe, 0xcb, +0x37, 0x5d, 0x44, 0x26, 0x26, 0x44, 0x5d, 0x37, 0x39, 0x5e, +0x42, 0x24, 0x24, 0x42, 0x5e, 0x00, 0x00, 0x02, 0x00, 0x39, +0x00, 0x00, 0x01, 0xca, 0x02, 0x71, 0x00, 0x1c, 0x00, 0x2b, +0x00, 0x96, 0xb9, 0x00, 0x1f, 0xff, 0xf8, 0x40, 0x62, 0x0e, +0x00, 0x4d, 0x09, 0x30, 0x0f, 0x10, 0x00, 0x4c, 0x09, 0x10, +0x0a, 0x00, 0x4d, 0x09, 0x18, 0x08, 0x09, 0x00, 0x4c, 0x07, +0x10, 0x10, 0x00, 0x4d, 0x07, 0x18, 0x0f, 0x00, 0x4d, 0x06, +0x38, 0x0a, 0x00, 0x4d, 0x06, 0x30, 0x09, 0x00, 0x4d, 0x06, +0x38, 0x08, 0x00, 0x4d, 0x04, 0x10, 0x12, 0x00, 0x4d, 0x04, +0x08, 0x11, 0x00, 0x4d, 0x1c, 0x05, 0x00, 0x05, 0x78, 0x17, +0x1c, 0x14, 0x17, 0x1c, 0x17, 0x17, 0x28, 0x12, 0x73, 0x11, +0x2d, 0x00, 0x00, 0x22, 0x76, 0x00, 0x08, 0x01, 0x08, 0x08, +0x2c, 0x17, 0x05, 0x13, 0x79, 0x28, 0x28, 0x0b, 0x12, 0x44, +0x1d, 0x7c, 0x0b, 0x41, 0x1c, 0x00, 0x44, 0x00, 0x3f, 0x32, +0x3f, 0xed, 0x3f, 0x12, 0x39, 0x2f, 0xed, 0x32, 0x32, 0x01, +0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x33, 0x2f, 0x10, 0xde, 0xed, +0x32, 0x32, 0x2f, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, +0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x33, 0x3e, 0x03, 0x37, 0x26, 0x26, 0x35, 0x34, +0x36, 0x33, 0x32, 0x1e, 0x02, 0x17, 0x11, 0x23, 0x35, 0x23, +0x22, 0x22, 0x27, 0x0e, 0x03, 0x07, 0x13, 0x22, 0x0e, 0x02, +0x15, 0x14, 0x1e, 0x02, 0x33, 0x33, 0x35, 0x26, 0x26, 0x39, +0x0f, 0x24, 0x24, 0x23, 0x0f, 0x34, 0x3c, 0x72, 0x6f, 0x10, +0x28, 0x29, 0x27, 0x0f, 0x52, 0x47, 0x03, 0x14, 0x07, 0x0e, +0x21, 0x22, 0x22, 0x0f, 0x9c, 0x1b, 0x31, 0x25, 0x16, 0x16, +0x29, 0x3a, 0x23, 0x36, 0x0a, 0x2a, 0x24, 0x4a, 0x44, 0x3c, +0x17, 0x19, 0x56, 0x3a, 0x61, 0x62, 0x02, 0x03, 0x06, 0x04, +0xfd, 0x9e, 0xf3, 0x01, 0x15, 0x39, 0x41, 0x44, 0x21, 0x02, +0x2b, 0x0c, 0x1d, 0x30, 0x24, 0x26, 0x2e, 0x1a, 0x09, 0xef, +0x02, 0x03, 0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, 0x01, 0xb0, +0x01, 0xdb, 0x02, 0x06, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, +0x00, 0x2d, 0xff, 0xf4, 0x01, 0xcc, 0x02, 0xb5, 0x00, 0x22, +0x00, 0x35, 0x00, 0xa1, 0x40, 0x15, 0x30, 0x18, 0x0f, 0x00, +0x4d, 0x30, 0x10, 0x0e, 0x00, 0x4d, 0x2a, 0x20, 0x0f, 0x00, +0x4d, 0x2a, 0x10, 0x0e, 0x00, 0x4d, 0x26, 0xb8, 0xff, 0xe8, +0xb4, 0x0e, 0x0f, 0x00, 0x4c, 0x21, 0xb8, 0xff, 0xe8, 0x40, +0x13, 0x09, 0x00, 0x4d, 0x13, 0x08, 0x0a, 0x00, 0x4d, 0x0d, +0x18, 0x10, 0x00, 0x4d, 0x0d, 0x18, 0x08, 0x00, 0x4d, 0x09, +0xb8, 0xff, 0xc0, 0xb3, 0x10, 0x00, 0x4d, 0x08, 0xb8, 0xff, +0xe0, 0xb3, 0x08, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xd8, 0xb3, +0x08, 0x00, 0x4d, 0x04, 0xb8, 0xff, 0xd8, 0xb3, 0x10, 0x00, +0x4d, 0x04, 0xb8, 0xff, 0xd8, 0x40, 0x1e, 0x09, 0x00, 0x4d, +0x2d, 0x82, 0x06, 0x1b, 0x1b, 0x06, 0x37, 0x00, 0x35, 0x82, +0x10, 0x36, 0x35, 0x32, 0x89, 0x00, 0x03, 0x03, 0x28, 0x1b, +0x88, 0x1a, 0x4d, 0x28, 0x88, 0x0b, 0x51, 0x00, 0x3f, 0xed, +0x3f, 0xed, 0x12, 0x39, 0x2f, 0x33, 0xed, 0x32, 0x01, 0x10, +0xd6, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x36, 0x36, 0x33, 0x32, +0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x34, 0x3e, 0x02, 0x37, 0x3e, 0x03, 0x37, 0x17, 0x0e, 0x03, +0x07, 0x06, 0x06, 0x07, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, +0x02, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0x86, +0x1a, 0x44, 0x21, 0x63, 0x64, 0x19, 0x33, 0x50, 0x36, 0x3e, +0x4f, 0x2e, 0x12, 0x15, 0x3a, 0x65, 0x50, 0x19, 0x23, 0x1c, +0x16, 0x0c, 0x09, 0x06, 0x0e, 0x18, 0x27, 0x1f, 0x56, 0x5c, +0x0f, 0x0a, 0x1b, 0x2f, 0x25, 0x21, 0x30, 0x1e, 0x0f, 0x0c, +0x1e, 0x32, 0x26, 0x24, 0x3f, 0x12, 0x01, 0x9b, 0x16, 0x18, +0x7a, 0x6d, 0x2f, 0x56, 0x42, 0x27, 0x2f, 0x50, 0x6b, 0x3c, +0x4e, 0x85, 0x66, 0x43, 0x0c, 0x04, 0x05, 0x04, 0x03, 0x03, +0x48, 0x02, 0x03, 0x03, 0x05, 0x03, 0x0b, 0x59, 0xec, 0x2a, +0x4c, 0x3b, 0x22, 0x1b, 0x2e, 0x3d, 0x22, 0x1e, 0x3b, 0x2d, +0x1c, 0x23, 0x17, 0x00, 0x00, 0x03, 0x00, 0x47, 0xff, 0xf8, +0x01, 0xc3, 0x01, 0xdc, 0x00, 0x0e, 0x00, 0x1b, 0x00, 0x32, +0x00, 0x80, 0xb9, 0x00, 0x30, 0xff, 0xe8, 0xb4, 0x0a, 0x0b, +0x00, 0x4c, 0x30, 0xb8, 0xff, 0xe0, 0xb3, 0x09, 0x00, 0x4d, +0x30, 0xb8, 0xff, 0xe8, 0xb3, 0x08, 0x00, 0x4d, 0x26, 0xb8, +0xff, 0xe8, 0xb4, 0x0c, 0x0d, 0x00, 0x4c, 0x26, 0xb8, 0xff, +0xf0, 0xb3, 0x0b, 0x00, 0x4d, 0x26, 0xb8, 0xff, 0xe0, 0x40, +0x2d, 0x0a, 0x00, 0x4d, 0x06, 0x10, 0x12, 0x00, 0x4d, 0x06, +0x08, 0x11, 0x00, 0x4d, 0x2b, 0x12, 0x82, 0x28, 0x28, 0x08, +0x82, 0x2e, 0x34, 0x1b, 0x00, 0x7f, 0x00, 0x1f, 0x01, 0x08, +0x1f, 0x33, 0x2b, 0x0e, 0x86, 0x1b, 0x1b, 0x03, 0x17, 0x88, +0x23, 0x50, 0x03, 0x88, 0x1c, 0x51, 0x00, 0x3f, 0xed, 0x3f, +0xed, 0x12, 0x39, 0x2f, 0xed, 0x39, 0x01, 0x10, 0xd6, 0x5e, +0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, 0x33, 0x2f, 0xed, 0x32, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x37, 0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, +0x02, 0x23, 0x23, 0x37, 0x32, 0x36, 0x35, 0x34, 0x2e, 0x02, +0x23, 0x22, 0x06, 0x07, 0x15, 0x13, 0x22, 0x26, 0x27, 0x11, +0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, +0x16, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x98, 0x0a, 0x34, 0x1a, +0x1a, 0x2f, 0x23, 0x15, 0x13, 0x20, 0x2c, 0x19, 0x61, 0x56, +0x30, 0x3f, 0x15, 0x23, 0x2c, 0x16, 0x15, 0x28, 0x0e, 0x55, +0x36, 0x56, 0x1a, 0x1a, 0x56, 0x36, 0x24, 0x46, 0x36, 0x21, +0x22, 0x1d, 0x26, 0x2e, 0x21, 0x3a, 0x4e, 0x3f, 0x02, 0x03, +0x07, 0x12, 0x1e, 0x17, 0x16, 0x1e, 0x12, 0x07, 0x3d, 0x1d, +0x29, 0x15, 0x19, 0x0e, 0x04, 0x02, 0x01, 0x83, 0xfe, 0xe6, +0x0a, 0x06, 0x01, 0xc4, 0x06, 0x0a, 0x0c, 0x1e, 0x32, 0x26, +0x23, 0x2f, 0x0e, 0x0e, 0x33, 0x30, 0x2a, 0x38, 0x21, 0x0e, +0x00, 0x01, 0x00, 0x6b, 0x00, 0x00, 0x01, 0xb8, 0x01, 0xd0, +0x00, 0x05, 0x00, 0x1a, 0x40, 0x0c, 0x03, 0x07, 0x05, 0x7f, +0x00, 0x06, 0x04, 0x85, 0x01, 0x49, 0x00, 0x4a, 0x00, 0x3f, +0x3f, 0xed, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xce, 0x31, 0x30, +0x33, 0x11, 0x21, 0x15, 0x23, 0x11, 0x6b, 0x01, 0x4d, 0xfb, +0x01, 0xd0, 0x45, 0xfe, 0x75, 0x00, 0x00, 0x02, 0x00, 0x1b, +0xff, 0x7f, 0x01, 0xd0, 0x01, 0xd0, 0x00, 0x0f, 0x00, 0x17, +0x00, 0x4d, 0xb9, 0x00, 0x15, 0xff, 0xf8, 0xb3, 0x09, 0x00, +0x4d, 0x15, 0xb8, 0xff, 0xe8, 0x40, 0x22, 0x08, 0x00, 0x4d, +0x12, 0x82, 0x06, 0x06, 0x01, 0x10, 0x7f, 0x08, 0x0c, 0x7f, +0x09, 0x19, 0x17, 0x82, 0x01, 0x0d, 0x7f, 0x00, 0x18, 0x0b, +0x0e, 0x17, 0x08, 0x01, 0x85, 0x0d, 0x4a, 0x12, 0x85, 0x06, +0x49, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x32, 0x32, 0xcd, 0x32, +0x01, 0x10, 0xd6, 0xed, 0xd5, 0xed, 0x10, 0xde, 0xed, 0xd5, +0xed, 0x11, 0x39, 0x2f, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x37, +0x33, 0x3e, 0x03, 0x37, 0x21, 0x11, 0x33, 0x15, 0x23, 0x35, +0x21, 0x15, 0x23, 0x25, 0x11, 0x23, 0x14, 0x0e, 0x02, 0x07, +0x1b, 0x24, 0x1e, 0x22, 0x11, 0x06, 0x01, 0x01, 0x12, 0x27, +0x4e, 0xfe, 0xe7, 0x4e, 0x01, 0x3c, 0x71, 0x08, 0x13, 0x20, +0x17, 0x46, 0x2b, 0x5a, 0x61, 0x69, 0x3b, 0xfe, 0x76, 0xc7, +0x81, 0x81, 0xc7, 0x01, 0x45, 0x28, 0x59, 0x56, 0x4f, 0x1f, +0x00, 0x00, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xc7, +0x01, 0xdb, 0x02, 0x06, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, +0x00, 0x07, 0x00, 0x00, 0x01, 0xeb, 0x01, 0xd0, 0x00, 0x31, +0x00, 0xa8, 0x40, 0x5f, 0x00, 0x0b, 0x10, 0x0b, 0x02, 0x0b, +0x0b, 0x06, 0x11, 0x16, 0x11, 0x81, 0x10, 0x0b, 0x14, 0x10, +0x10, 0x0b, 0x0b, 0x05, 0x00, 0x05, 0x81, 0x06, 0x0b, 0x14, +0x06, 0x06, 0x0b, 0x24, 0x24, 0x29, 0x1e, 0x19, 0x1e, 0x81, +0x1f, 0x24, 0x14, 0x1f, 0x1f, 0x24, 0x24, 0x2a, 0x2f, 0x2a, +0x81, 0x29, 0x24, 0x14, 0x29, 0x29, 0x24, 0x2f, 0x00, 0x16, +0x7f, 0x19, 0x19, 0x1f, 0x06, 0x06, 0x10, 0x33, 0x29, 0x29, +0x1f, 0x32, 0x00, 0x2f, 0x2f, 0x24, 0x16, 0x19, 0x19, 0x0b, +0x24, 0x24, 0x18, 0x30, 0x49, 0x29, 0x2a, 0x49, 0x1f, 0x1e, +0x4a, 0x18, 0x4a, 0x10, 0x11, 0x4a, 0x06, 0x05, 0x49, 0x00, +0x3f, 0x33, 0x3f, 0x33, 0x3f, 0x3f, 0x33, 0x3f, 0x33, 0x3f, +0x12, 0x39, 0x11, 0x33, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, +0x33, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xce, 0x32, 0x2f, +0x11, 0x39, 0x2f, 0xed, 0x32, 0x33, 0x87, 0x10, 0x2b, 0x87, +0x7d, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x08, 0x7d, 0xc4, +0x87, 0x05, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x87, 0x18, +0x10, 0x2b, 0x87, 0x08, 0x7d, 0xc4, 0x01, 0x5d, 0x31, 0x30, +0x01, 0x3e, 0x03, 0x37, 0x33, 0x0e, 0x03, 0x07, 0x1e, 0x03, +0x17, 0x23, 0x2e, 0x03, 0x27, 0x15, 0x23, 0x35, 0x0e, 0x03, +0x07, 0x23, 0x3e, 0x03, 0x37, 0x2e, 0x03, 0x27, 0x33, 0x1e, +0x03, 0x17, 0x35, 0x33, 0x01, 0x1e, 0x0c, 0x1c, 0x1b, 0x1a, +0x0a, 0x53, 0x10, 0x23, 0x24, 0x24, 0x10, 0x15, 0x2c, 0x2a, +0x25, 0x0e, 0x52, 0x0a, 0x1e, 0x21, 0x23, 0x0f, 0x49, 0x10, +0x23, 0x21, 0x1e, 0x0a, 0x52, 0x0e, 0x26, 0x2a, 0x2b, 0x15, +0x10, 0x24, 0x24, 0x23, 0x0f, 0x52, 0x0a, 0x1a, 0x1c, 0x1c, +0x0c, 0x49, 0x01, 0x0d, 0x15, 0x33, 0x34, 0x32, 0x15, 0x1a, +0x39, 0x3a, 0x37, 0x16, 0x14, 0x3b, 0x42, 0x46, 0x1f, 0x1a, +0x3a, 0x39, 0x34, 0x14, 0xd5, 0xd6, 0x14, 0x34, 0x39, 0x3b, +0x1a, 0x1f, 0x46, 0x42, 0x3b, 0x14, 0x16, 0x37, 0x3a, 0x3a, +0x19, 0x15, 0x33, 0x35, 0x33, 0x15, 0xc5, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x48, 0xff, 0xf5, 0x01, 0xbf, 0x01, 0xdc, +0x00, 0x2c, 0x00, 0x8b, 0x40, 0x0b, 0x1f, 0x28, 0x12, 0x00, +0x4d, 0x1f, 0x20, 0x11, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xe0, +0xb3, 0x0b, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xe8, 0xb4, 0x09, +0x0a, 0x00, 0x4c, 0x11, 0xb8, 0xff, 0xe0, 0xb3, 0x08, 0x00, +0x4d, 0x06, 0xb8, 0xff, 0xe8, 0xb3, 0x0c, 0x00, 0x4d, 0x06, +0xb8, 0xff, 0xc8, 0xb3, 0x0b, 0x00, 0x4d, 0x06, 0xb8, 0xff, +0xe0, 0x40, 0x28, 0x0a, 0x00, 0x4d, 0x0d, 0x26, 0x82, 0x08, +0x08, 0x1d, 0x82, 0x10, 0x2e, 0x21, 0x21, 0x00, 0x00, 0x00, +0x16, 0x01, 0x08, 0x16, 0x2d, 0x0d, 0x21, 0x86, 0x22, 0x22, +0x03, 0x17, 0x17, 0x1a, 0x88, 0x13, 0x51, 0x2c, 0x2c, 0x29, +0x88, 0x03, 0x50, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, +0x32, 0x2f, 0x11, 0x39, 0x2f, 0xed, 0x39, 0x01, 0x10, 0xc6, +0x5e, 0x5d, 0x32, 0x2f, 0x32, 0x2f, 0x10, 0xde, 0xed, 0x33, +0x2f, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x13, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, +0x15, 0x14, 0x0e, 0x02, 0x07, 0x16, 0x16, 0x15, 0x14, 0x06, +0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, +0x35, 0x34, 0x26, 0x23, 0x23, 0x35, 0x33, 0x32, 0x36, 0x35, +0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x56, 0x21, 0x4f, 0x27, +0x26, 0x46, 0x36, 0x20, 0x0e, 0x16, 0x19, 0x0c, 0x26, 0x33, +0x71, 0x61, 0x3c, 0x57, 0x12, 0x11, 0x0f, 0x4e, 0x37, 0x42, +0x3c, 0x3c, 0x33, 0x62, 0x5c, 0x33, 0x32, 0x38, 0x3c, 0x1c, +0x49, 0x1a, 0x01, 0xc4, 0x0b, 0x0d, 0x0d, 0x20, 0x33, 0x26, +0x12, 0x20, 0x1a, 0x12, 0x04, 0x0e, 0x35, 0x30, 0x43, 0x49, +0x12, 0x08, 0x46, 0x05, 0x13, 0x26, 0x20, 0x24, 0x2a, 0x42, +0x22, 0x1d, 0x1f, 0x24, 0x0e, 0x0c, 0x00, 0x00, 0x00, 0x01, +0x00, 0x3f, 0x00, 0x00, 0x01, 0xb6, 0x01, 0xd0, 0x00, 0x11, +0x00, 0x50, 0x40, 0x31, 0x24, 0x08, 0x01, 0x49, 0x11, 0x59, +0x11, 0x79, 0x11, 0x03, 0x38, 0x11, 0x01, 0x2b, 0x11, 0x01, +0x11, 0x08, 0x03, 0x08, 0x84, 0x0c, 0x11, 0x14, 0x0c, 0x0c, +0x11, 0x03, 0x7f, 0x00, 0x13, 0x0c, 0x7f, 0x00, 0x09, 0x01, +0x08, 0x09, 0x12, 0x03, 0x11, 0x49, 0x0b, 0x49, 0x0c, 0x08, +0x4a, 0x02, 0x4a, 0x00, 0x3f, 0x3f, 0x33, 0x3f, 0x3f, 0x33, +0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x10, 0xde, 0xed, 0x87, +0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x5d, 0x5d, 0x5d, 0x5d, +0x31, 0x30, 0x01, 0x11, 0x23, 0x11, 0x0e, 0x03, 0x07, 0x23, +0x11, 0x33, 0x11, 0x3e, 0x03, 0x37, 0x01, 0xb6, 0x51, 0x1b, +0x3b, 0x3b, 0x36, 0x15, 0x4a, 0x50, 0x17, 0x36, 0x3a, 0x3a, +0x1c, 0x01, 0xd0, 0xfe, 0x30, 0x01, 0x62, 0x22, 0x5c, 0x61, +0x5e, 0x25, 0x01, 0xd0, 0xfe, 0xb2, 0x27, 0x5b, 0x5b, 0x53, +0x1e, 0x00, 0xff, 0xff, 0x00, 0x3f, 0x00, 0x00, 0x01, 0xb6, +0x02, 0x98, 0x02, 0x26, 0x02, 0xeb, 0x00, 0x00, 0x01, 0x06, +0x03, 0x90, 0x0c, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x0b, +0x15, 0x1d, 0x09, 0x00, 0x50, 0x01, 0x00, 0x12, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x47, 0x00, 0x00, 0x01, 0xde, +0x01, 0xd0, 0x02, 0x06, 0x01, 0x15, 0x00, 0x00, 0x00, 0x01, +0x00, 0x0d, 0xff, 0xf7, 0x01, 0xad, 0x01, 0xd0, 0x00, 0x15, +0x00, 0x52, 0x40, 0x12, 0x0c, 0x18, 0x0f, 0x10, 0x00, 0x4c, +0x0b, 0x18, 0x0f, 0x10, 0x00, 0x4c, 0x0b, 0x20, 0x0b, 0x00, +0x4d, 0x07, 0xb8, 0xff, 0xd8, 0xb4, 0x11, 0x12, 0x00, 0x4c, +0x07, 0xb8, 0xff, 0xe0, 0x40, 0x19, 0x0c, 0x0d, 0x00, 0x4c, +0x00, 0x7f, 0x11, 0x11, 0x09, 0x14, 0x7f, 0x13, 0x17, 0x09, +0x16, 0x14, 0x4a, 0x00, 0x85, 0x11, 0x49, 0x09, 0x85, 0x08, +0x51, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x3f, 0x01, 0x10, 0xc6, +0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x14, 0x0e, 0x02, 0x07, 0x06, +0x06, 0x07, 0x27, 0x36, 0x36, 0x37, 0x3e, 0x02, 0x34, 0x35, +0x21, 0x11, 0x23, 0x11, 0xeb, 0x03, 0x07, 0x0c, 0x0a, 0x14, +0x52, 0x4c, 0x0c, 0x2c, 0x33, 0x0f, 0x0d, 0x0d, 0x06, 0x01, +0x12, 0x53, 0x01, 0x8b, 0x1e, 0x43, 0x43, 0x41, 0x1c, 0x39, +0x52, 0x08, 0x46, 0x08, 0x31, 0x23, 0x1e, 0x4c, 0x54, 0x54, +0x25, 0xfe, 0x30, 0x01, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x1b, 0x00, 0x00, 0x01, 0xd9, 0x01, 0xd0, 0x00, 0x24, +0x00, 0x7c, 0x40, 0x4b, 0x5a, 0x10, 0x6a, 0x10, 0x02, 0x2b, +0x10, 0x3b, 0x10, 0x4b, 0x10, 0x03, 0x10, 0x1f, 0x1a, 0x1f, +0x84, 0x0d, 0x10, 0x14, 0x0d, 0x10, 0x1a, 0x17, 0x64, 0x0a, +0x01, 0x52, 0x0a, 0x01, 0x34, 0x0a, 0x44, 0x0a, 0x02, 0x23, +0x0a, 0x01, 0x0a, 0x20, 0x00, 0x20, 0x84, 0x0d, 0x0a, 0x14, +0x0d, 0x0d, 0x0a, 0x0d, 0x03, 0x17, 0x82, 0x11, 0x16, 0x26, +0x00, 0x03, 0x82, 0x09, 0x04, 0x25, 0x1a, 0x10, 0x49, 0x00, +0x0a, 0x49, 0x1f, 0x0d, 0x20, 0x20, 0x17, 0x04, 0x4a, 0x00, +0x3f, 0x33, 0x33, 0x2f, 0x33, 0x33, 0x3f, 0x33, 0x3f, 0x33, +0x01, 0x10, 0xd6, 0x32, 0xed, 0x32, 0x10, 0xde, 0x32, 0xed, +0x11, 0x39, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x5d, +0x5d, 0x5d, 0x5d, 0x11, 0x33, 0x87, 0x18, 0x2b, 0x87, 0x7d, +0xc4, 0x01, 0x5d, 0x5d, 0x31, 0x30, 0x13, 0x06, 0x06, 0x07, +0x23, 0x3e, 0x03, 0x37, 0x33, 0x16, 0x16, 0x17, 0x36, 0x36, +0x37, 0x33, 0x1e, 0x03, 0x17, 0x23, 0x26, 0x26, 0x27, 0x0e, +0x03, 0x07, 0x23, 0x2e, 0x03, 0x77, 0x08, 0x01, 0x03, 0x50, +0x01, 0x07, 0x09, 0x0b, 0x06, 0x4d, 0x13, 0x34, 0x28, 0x29, +0x35, 0x14, 0x4c, 0x06, 0x0b, 0x09, 0x06, 0x02, 0x50, 0x03, +0x03, 0x07, 0x0d, 0x15, 0x13, 0x16, 0x0f, 0x52, 0x0e, 0x16, +0x13, 0x15, 0x01, 0x56, 0x5b, 0xad, 0x4e, 0x37, 0x76, 0x78, +0x76, 0x35, 0x30, 0x90, 0x64, 0x64, 0x90, 0x30, 0x35, 0x76, +0x78, 0x76, 0x37, 0x4e, 0xb4, 0x54, 0x1f, 0x35, 0x38, 0x3f, +0x2a, 0x2a, 0x3f, 0x38, 0x35, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x47, 0x00, 0x00, 0x01, 0xad, 0x01, 0xd0, 0x00, 0x0b, +0x00, 0x39, 0x40, 0x20, 0x09, 0x01, 0x7f, 0x00, 0x0d, 0x08, +0x04, 0x7f, 0x00, 0x05, 0x01, 0x05, 0x0c, 0x0a, 0x49, 0x03, +0x85, 0x0f, 0x08, 0x1f, 0x08, 0x02, 0x08, 0x08, 0x08, 0x05, +0x06, 0x49, 0x05, 0x4a, 0x01, 0x4a, 0x00, 0x3f, 0x3f, 0x3f, +0x12, 0x39, 0x2f, 0x5e, 0x5d, 0xed, 0x3f, 0x01, 0x10, 0xd6, +0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, 0x32, 0x31, 0x30, 0x21, +0x23, 0x35, 0x23, 0x15, 0x23, 0x11, 0x33, 0x15, 0x33, 0x35, +0x33, 0x01, 0xad, 0x53, 0xc0, 0x53, 0x53, 0xc0, 0x53, 0xcd, +0xcd, 0x01, 0xd0, 0xbd, 0xbd, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x01, 0xdb, 0x02, 0x06, +0x00, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x47, 0x00, 0x00, +0x01, 0xad, 0x01, 0xd0, 0x00, 0x07, 0x00, 0x26, 0x40, 0x14, +0x01, 0x7f, 0x00, 0x09, 0x04, 0x7f, 0x00, 0x05, 0x01, 0x08, +0x05, 0x08, 0x03, 0x85, 0x06, 0x49, 0x05, 0x4a, 0x01, 0x4a, +0x00, 0x3f, 0x3f, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0x5e, 0x5d, +0xed, 0x10, 0xde, 0xed, 0x31, 0x30, 0x21, 0x23, 0x11, 0x23, +0x11, 0x23, 0x11, 0x21, 0x01, 0xad, 0x53, 0xc0, 0x53, 0x01, +0x66, 0x01, 0x8b, 0xfe, 0x75, 0x01, 0xd0, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x47, 0xff, 0x5b, 0x01, 0xcc, 0x01, 0xda, +0x02, 0x06, 0x00, 0x53, 0x00, 0x00, 0xff, 0xff, 0x00, 0x31, +0xff, 0xf5, 0x01, 0xc3, 0x01, 0xdb, 0x02, 0x06, 0x00, 0x46, +0x00, 0x00, 0x00, 0x01, 0x00, 0x3a, 0x00, 0x00, 0x01, 0xba, +0x01, 0xd0, 0x00, 0x07, 0x00, 0x26, 0x40, 0x13, 0x01, 0x03, +0x7f, 0x06, 0x00, 0x04, 0x01, 0x08, 0x04, 0x04, 0x09, 0x08, +0x02, 0x05, 0x85, 0x07, 0x49, 0x04, 0x4a, 0x00, 0x3f, 0x3f, +0xed, 0x32, 0x01, 0x11, 0x12, 0x39, 0x2f, 0x5e, 0x5d, 0xce, +0xfd, 0xce, 0x31, 0x30, 0x01, 0x15, 0x23, 0x11, 0x23, 0x11, +0x23, 0x35, 0x01, 0xba, 0x97, 0x52, 0x97, 0x01, 0xd0, 0x45, +0xfe, 0x75, 0x01, 0x8b, 0x45, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x24, 0xff, 0x58, 0x01, 0xcd, 0x01, 0xd0, 0x02, 0x06, +0x00, 0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x1a, 0xff, 0x5b, +0x01, 0xda, 0x02, 0xb5, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x27, +0x00, 0x9a, 0xb9, 0x00, 0x1f, 0xff, 0xf0, 0xb3, 0x12, 0x00, +0x4d, 0x1f, 0xb8, 0xff, 0xf8, 0x40, 0x1a, 0x11, 0x00, 0x4d, +0x0c, 0x20, 0x10, 0x00, 0x4d, 0x0c, 0x28, 0x0e, 0x0f, 0x00, +0x4c, 0x08, 0x28, 0x0f, 0x10, 0x00, 0x4c, 0x08, 0x20, 0x0e, +0x00, 0x4d, 0x05, 0xb8, 0xff, 0xd0, 0xb3, 0x10, 0x00, 0x4d, +0x05, 0xb8, 0xff, 0xe0, 0xb4, 0x0e, 0x0f, 0x00, 0x4c, 0x02, +0xb8, 0xff, 0xd8, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x02, 0xb8, +0xff, 0xd0, 0x40, 0x29, 0x0e, 0x00, 0x4d, 0x0a, 0x82, 0x00, +0x22, 0x01, 0x08, 0x22, 0x1d, 0x07, 0x27, 0x7f, 0x10, 0x00, +0x82, 0x15, 0x1a, 0x03, 0x10, 0x10, 0x29, 0x28, 0x1b, 0x1c, +0x4d, 0x0d, 0x04, 0x88, 0x1d, 0x1a, 0x49, 0x07, 0x03, 0x88, +0x27, 0x10, 0x4c, 0x0f, 0x4b, 0x00, 0x3f, 0x3f, 0x33, 0xed, +0x32, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0x33, 0x01, 0x11, 0x12, +0x39, 0x2f, 0x33, 0x33, 0xdd, 0xed, 0x10, 0xfd, 0x32, 0x32, +0xdd, 0x5e, 0x5d, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x37, 0x14, 0x16, 0x17, +0x11, 0x06, 0x06, 0x17, 0x36, 0x36, 0x35, 0x34, 0x26, 0x27, +0x11, 0x23, 0x35, 0x2e, 0x03, 0x35, 0x34, 0x3e, 0x02, 0x37, +0x35, 0x37, 0x15, 0x1e, 0x03, 0x15, 0x14, 0x0e, 0x02, 0x07, +0x6c, 0x3d, 0x2c, 0x2c, 0x3d, 0xb2, 0x2c, 0x3e, 0x3e, 0x2c, +0x49, 0x26, 0x43, 0x34, 0x1e, 0x1e, 0x34, 0x43, 0x26, 0x49, +0x26, 0x44, 0x34, 0x1e, 0x1e, 0x34, 0x44, 0x26, 0xe8, 0x4e, +0x55, 0x02, 0x01, 0x4a, 0x02, 0x55, 0xf3, 0x02, 0x55, 0x4e, +0x4e, 0x55, 0x02, 0xfd, 0xce, 0xa2, 0x01, 0x20, 0x3c, 0x57, +0x37, 0x37, 0x57, 0x3c, 0x20, 0x01, 0xd4, 0x0e, 0xe2, 0x01, +0x20, 0x3c, 0x57, 0x37, 0x37, 0x57, 0x3c, 0x20, 0x01, 0x00, +0xff, 0xff, 0x00, 0x1d, 0x00, 0x00, 0x01, 0xd8, 0x01, 0xd0, +0x02, 0x06, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x47, +0xff, 0x7f, 0x01, 0xd0, 0x01, 0xd0, 0x00, 0x0b, 0x00, 0x2e, +0x40, 0x18, 0x09, 0x7f, 0x00, 0x04, 0x7f, 0x01, 0x0d, 0x08, +0x7f, 0x00, 0x05, 0x01, 0x08, 0x05, 0x0c, 0x0a, 0x06, 0x49, +0x00, 0x08, 0x85, 0x03, 0x05, 0x4a, 0x00, 0x3f, 0xce, 0xed, +0x32, 0x3f, 0x33, 0x01, 0x10, 0xde, 0x5e, 0x5d, 0xed, 0x10, +0xde, 0xed, 0xd5, 0xed, 0x31, 0x30, 0x25, 0x33, 0x15, 0x23, +0x35, 0x21, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x01, 0xa9, +0x27, 0x4e, 0xfe, 0xc5, 0x53, 0xbd, 0x52, 0x46, 0xc7, 0x81, +0x01, 0xd0, 0xfe, 0x76, 0x01, 0x8a, 0x00, 0x00, 0x00, 0x01, +0x00, 0x36, 0x00, 0x00, 0x01, 0xad, 0x01, 0xd0, 0x00, 0x17, +0x00, 0x3b, 0x40, 0x24, 0x14, 0x20, 0x0a, 0x0b, 0x00, 0x4c, +0x14, 0x18, 0x09, 0x00, 0x4d, 0x14, 0x20, 0x08, 0x00, 0x4d, +0x07, 0x0b, 0x7f, 0x0a, 0x19, 0x01, 0x7f, 0x16, 0x18, 0x04, +0x88, 0x11, 0x11, 0x0b, 0x17, 0x49, 0x0b, 0x4a, 0x08, 0x49, +0x00, 0x3f, 0x3f, 0x3f, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, +0xd6, 0xed, 0x10, 0xde, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x13, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x35, +0x33, 0x11, 0x23, 0x35, 0x0e, 0x03, 0x23, 0x22, 0x2e, 0x02, +0x35, 0x35, 0x88, 0x39, 0x32, 0x24, 0x30, 0x13, 0x53, 0x53, +0x07, 0x19, 0x1f, 0x22, 0x10, 0x28, 0x42, 0x2f, 0x1a, 0x01, +0xd0, 0x88, 0x35, 0x2a, 0x07, 0x05, 0xdb, 0xfe, 0x30, 0xb3, +0x02, 0x05, 0x05, 0x04, 0x11, 0x26, 0x3f, 0x2e, 0x89, 0x00, +0x00, 0x01, 0x00, 0x2d, 0x00, 0x00, 0x01, 0xc7, 0x01, 0xd0, +0x00, 0x0b, 0x00, 0x30, 0x40, 0x18, 0x07, 0x7f, 0x04, 0x04, +0x00, 0x08, 0x7f, 0x0b, 0x0d, 0x03, 0x7f, 0x00, 0x0c, 0x09, +0x01, 0x05, 0x05, 0x01, 0x49, 0x07, 0x03, 0x85, 0x00, 0x4a, +0x00, 0x3f, 0xed, 0x32, 0x3f, 0x33, 0x2f, 0x11, 0x33, 0x01, +0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, 0xed, +0x31, 0x30, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, +0x33, 0x11, 0x33, 0x11, 0x2d, 0x4b, 0x5d, 0x4b, 0x5c, 0x4b, +0x01, 0xd0, 0xfe, 0x76, 0x01, 0x1f, 0xfe, 0xe1, 0x01, 0x8a, +0xfe, 0x30, 0x00, 0x01, 0x00, 0x2d, 0xff, 0x7f, 0x01, 0xd0, +0x01, 0xd0, 0x00, 0x0f, 0x00, 0x41, 0x40, 0x25, 0x0e, 0x7f, +0x0b, 0x0b, 0x07, 0x0f, 0x7f, 0x4f, 0x02, 0x5f, 0x02, 0xaf, +0x02, 0xbf, 0x02, 0x04, 0x02, 0x06, 0x7f, 0x03, 0x11, 0x0a, +0x7f, 0x07, 0x10, 0x0c, 0x0c, 0x00, 0x08, 0x49, 0x0e, 0x02, +0x0a, 0x85, 0x05, 0x07, 0x4a, 0x00, 0x3f, 0xce, 0xed, 0x32, +0x32, 0x3f, 0x33, 0x33, 0x2f, 0x01, 0x10, 0xd6, 0xed, 0x10, +0xde, 0xed, 0xd5, 0x5d, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x31, +0x30, 0x01, 0x33, 0x11, 0x33, 0x15, 0x23, 0x35, 0x21, 0x11, +0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x01, 0x5e, 0x4b, +0x27, 0x4e, 0xfe, 0xab, 0x4b, 0x4d, 0x4b, 0x4e, 0x01, 0xd0, +0xfe, 0x76, 0xc7, 0x81, 0x01, 0xd0, 0xfe, 0x76, 0x01, 0x1f, +0xfe, 0xe1, 0x00, 0x02, 0x00, 0x12, 0xff, 0xf6, 0x01, 0xd0, +0x01, 0xd0, 0x00, 0x14, 0x00, 0x25, 0x00, 0x5b, 0xb9, 0x00, +0x0e, 0xff, 0xe8, 0xb3, 0x0b, 0x00, 0x4d, 0x0e, 0xb8, 0xff, +0xd0, 0xb3, 0x0a, 0x00, 0x4d, 0x0e, 0xb8, 0xff, 0xe8, 0xb3, +0x09, 0x00, 0x4d, 0x0a, 0xb8, 0xff, 0xe8, 0xb4, 0x0a, 0x0b, +0x00, 0x4c, 0x0a, 0xb8, 0xff, 0xe0, 0x40, 0x1a, 0x09, 0x00, +0x4d, 0x18, 0x82, 0x0c, 0x27, 0x20, 0x03, 0x7f, 0x00, 0x01, +0x26, 0x1d, 0x89, 0x07, 0x07, 0x03, 0x15, 0x89, 0x11, 0x51, +0x00, 0x85, 0x03, 0x49, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x11, +0x39, 0x2f, 0xed, 0x01, 0x10, 0xd6, 0xdd, 0xed, 0x32, 0x10, +0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, +0x23, 0x35, 0x33, 0x15, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, +0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x32, +0x36, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0x15, +0x1e, 0x03, 0x6d, 0x5b, 0xad, 0x0e, 0x3a, 0x19, 0x24, 0x40, +0x30, 0x1c, 0x1b, 0x32, 0x47, 0x2b, 0x2b, 0x52, 0x27, 0xa9, +0x30, 0x36, 0x10, 0x1c, 0x25, 0x15, 0x17, 0x2f, 0x11, 0x05, +0x14, 0x18, 0x1a, 0x01, 0x8b, 0x45, 0xb1, 0x03, 0x07, 0x11, +0x24, 0x3a, 0x28, 0x2a, 0x3b, 0x26, 0x11, 0x09, 0x0b, 0x30, +0x29, 0x2e, 0x16, 0x20, 0x15, 0x0a, 0x03, 0x05, 0x9f, 0x01, +0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x2d, +0xff, 0xf6, 0x01, 0xc7, 0x01, 0xd0, 0x00, 0x0c, 0x00, 0x1d, +0x00, 0x21, 0x00, 0x53, 0xb9, 0x00, 0x18, 0xff, 0xe8, 0xb3, +0x0d, 0x00, 0x4d, 0x15, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, +0x4d, 0x15, 0xb8, 0xff, 0xf0, 0x40, 0x21, 0x0d, 0x00, 0x4d, +0x0a, 0x82, 0x0f, 0x17, 0x01, 0x08, 0x17, 0x1f, 0x7f, 0x1e, +0x23, 0x0f, 0x04, 0x7f, 0x1d, 0x22, 0x1f, 0x4a, 0x00, 0x89, +0x12, 0x12, 0x0d, 0x07, 0x89, 0x1a, 0x51, 0x20, 0x0d, 0x49, +0x00, 0x3f, 0x33, 0x3f, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x3f, +0x01, 0x10, 0xd6, 0xed, 0x32, 0x10, 0xde, 0xfd, 0xde, 0x5e, +0x5d, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x37, 0x22, 0x06, +0x07, 0x15, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, +0x27, 0x33, 0x15, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, +0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x05, 0x23, 0x11, 0x33, +0xb4, 0x10, 0x1d, 0x0c, 0x08, 0x22, 0x0d, 0x21, 0x29, 0x2e, +0xa1, 0x4e, 0x0b, 0x25, 0x14, 0x1c, 0x33, 0x27, 0x17, 0x57, +0x45, 0x23, 0x3f, 0x21, 0x01, 0x9a, 0x4e, 0x4e, 0xe6, 0x03, +0x05, 0x9f, 0x02, 0x03, 0x29, 0x2e, 0x2d, 0x28, 0xea, 0xb1, +0x03, 0x07, 0x11, 0x24, 0x3a, 0x28, 0x54, 0x48, 0x09, 0x0b, +0x0a, 0x01, 0xd0, 0x00, 0x00, 0x02, 0x00, 0x47, 0xff, 0xf6, +0x01, 0xcc, 0x01, 0xd0, 0x00, 0x0e, 0x00, 0x1f, 0x00, 0x62, +0xb9, 0x00, 0x1a, 0xff, 0xe0, 0xb3, 0x0b, 0x00, 0x4d, 0x1a, +0xb8, 0xff, 0xd8, 0xb4, 0x09, 0x0a, 0x00, 0x4c, 0x17, 0xb8, +0xff, 0xe0, 0xb3, 0x0b, 0x00, 0x4d, 0x17, 0xb8, 0xff, 0xd8, +0xb3, 0x0a, 0x00, 0x4d, 0x17, 0xb8, 0xff, 0xe8, 0x40, 0x21, +0x09, 0x00, 0x4d, 0x06, 0x20, 0x11, 0x00, 0x4d, 0x05, 0x18, +0x12, 0x00, 0x4d, 0x03, 0x82, 0x19, 0x21, 0x11, 0x0c, 0x7f, +0x1f, 0x20, 0x08, 0x89, 0x14, 0x14, 0x0f, 0x00, 0x89, 0x1c, +0x51, 0x0f, 0x49, 0x00, 0x3f, 0x3f, 0xed, 0x11, 0x39, 0x2f, +0xed, 0x01, 0x10, 0xd6, 0xed, 0x32, 0x10, 0xde, 0xed, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x37, 0x32, +0x36, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0x15, +0x16, 0x16, 0x03, 0x33, 0x15, 0x36, 0x36, 0x33, 0x32, 0x1e, +0x02, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0xfe, 0x3a, +0x40, 0x13, 0x21, 0x2d, 0x19, 0x1a, 0x37, 0x13, 0x0c, 0x3d, +0x9c, 0x53, 0x10, 0x40, 0x1d, 0x28, 0x48, 0x36, 0x1f, 0x73, +0x60, 0x2f, 0x57, 0x2c, 0x3a, 0x29, 0x2e, 0x16, 0x20, 0x15, +0x0a, 0x03, 0x05, 0x9f, 0x02, 0x03, 0x01, 0x96, 0xb1, 0x03, +0x07, 0x11, 0x24, 0x3a, 0x28, 0x54, 0x48, 0x09, 0x0b, 0x00, +0x00, 0x01, 0x00, 0x3b, 0xff, 0xf5, 0x01, 0xcc, 0x01, 0xdb, +0x00, 0x24, 0x00, 0x50, 0x40, 0x30, 0x17, 0x28, 0x0e, 0x00, +0x4d, 0x0e, 0x28, 0x0e, 0x00, 0x4d, 0x0e, 0x20, 0x0d, 0x00, +0x4d, 0x0e, 0x10, 0x0c, 0x00, 0x4d, 0x14, 0x11, 0x82, 0x00, +0x26, 0x1d, 0x1d, 0x12, 0x12, 0x08, 0x25, 0x1c, 0x1c, 0x19, +0x88, 0x20, 0x12, 0x86, 0x13, 0x13, 0x20, 0x50, 0x09, 0x09, +0x0c, 0x88, 0x05, 0x51, 0x00, 0x3f, 0xed, 0x32, 0x2f, 0x3f, +0x39, 0x2f, 0xed, 0x10, 0xed, 0x32, 0x2f, 0x01, 0x10, 0xc6, +0x32, 0x2f, 0x32, 0x2f, 0x10, 0xde, 0xed, 0x32, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x14, 0x0e, 0x02, 0x23, 0x22, +0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x37, +0x23, 0x35, 0x33, 0x2e, 0x03, 0x23, 0x22, 0x06, 0x07, 0x27, +0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x01, 0xcc, 0x23, 0x41, +0x5d, 0x39, 0x33, 0x51, 0x13, 0x0c, 0x14, 0x49, 0x26, 0x24, +0x3d, 0x2e, 0x1c, 0x03, 0xd5, 0xd3, 0x04, 0x1c, 0x2c, 0x3a, +0x22, 0x27, 0x35, 0x1d, 0x13, 0x18, 0x46, 0x32, 0x38, 0x5c, +0x42, 0x24, 0xea, 0x3a, 0x5b, 0x3f, 0x21, 0x0f, 0x09, 0x45, +0x09, 0x0c, 0x14, 0x25, 0x36, 0x21, 0x43, 0x1e, 0x31, 0x22, +0x13, 0x0a, 0x0b, 0x47, 0x08, 0x0d, 0x22, 0x3e, 0x5a, 0x00, +0x00, 0x00, 0x00, 0x02, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xd9, +0x01, 0xdb, 0x00, 0x1a, 0x00, 0x26, 0x00, 0x87, 0xb9, 0x00, +0x18, 0xff, 0xe8, 0xb3, 0x0b, 0x00, 0x4d, 0x18, 0xb8, 0xff, +0xf0, 0xb3, 0x0a, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xe8, 0x40, +0x4c, 0x0a, 0x0b, 0x00, 0x4c, 0x0e, 0x18, 0x0b, 0x00, 0x4d, +0x0e, 0x28, 0x0a, 0x00, 0x4d, 0x03, 0x10, 0x0c, 0x0d, 0x00, +0x4c, 0x03, 0x18, 0x0b, 0x00, 0x4d, 0x03, 0x10, 0x0a, 0x00, +0x4d, 0x21, 0x82, 0x16, 0x28, 0x1b, 0x82, 0x0c, 0x20, 0x05, +0x30, 0x05, 0x40, 0x05, 0x03, 0x05, 0x0b, 0x07, 0x7f, 0x20, +0x08, 0x01, 0x08, 0x27, 0x24, 0x88, 0x11, 0x50, 0x06, 0x85, +0x0f, 0x0b, 0x1f, 0x0b, 0x02, 0x08, 0x0b, 0x0b, 0x08, 0x09, +0x49, 0x08, 0x4a, 0x1e, 0x88, 0x00, 0x51, 0x00, 0x3f, 0xed, +0x3f, 0x3f, 0x12, 0x39, 0x2f, 0x5e, 0x5d, 0xed, 0x3f, 0xed, +0x01, 0x10, 0xd6, 0x5d, 0xfd, 0x32, 0xde, 0x5d, 0x32, 0xed, +0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x05, 0x22, 0x2e, 0x02, 0x27, 0x23, 0x15, +0x23, 0x11, 0x33, 0x15, 0x33, 0x3e, 0x03, 0x33, 0x32, 0x1e, +0x02, 0x15, 0x14, 0x0e, 0x02, 0x27, 0x14, 0x16, 0x33, 0x32, +0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x01, 0x50, 0x19, +0x2f, 0x26, 0x1a, 0x03, 0x41, 0x4e, 0x4e, 0x40, 0x03, 0x1a, +0x26, 0x2f, 0x18, 0x1a, 0x32, 0x27, 0x18, 0x17, 0x27, 0x31, +0x57, 0x1a, 0x22, 0x22, 0x1a, 0x1a, 0x22, 0x22, 0x1a, 0x0b, +0x14, 0x30, 0x4f, 0x3c, 0xc4, 0x01, 0xd0, 0xc7, 0x3d, 0x51, +0x30, 0x14, 0x17, 0x37, 0x5e, 0x47, 0x47, 0x5e, 0x37, 0x17, +0xf3, 0x54, 0x59, 0x59, 0x54, 0x55, 0x58, 0x58, 0x00, 0x00, +0x00, 0x02, 0x00, 0x28, 0x00, 0x00, 0x01, 0xad, 0x01, 0xdc, +0x00, 0x1a, 0x00, 0x25, 0x00, 0x7f, 0xb9, 0x00, 0x20, 0xff, +0xe8, 0x40, 0x4d, 0x11, 0x12, 0x00, 0x4c, 0x11, 0x10, 0x0b, +0x00, 0x4d, 0x11, 0x28, 0x09, 0x0a, 0x00, 0x4c, 0x11, 0x20, +0x08, 0x00, 0x4d, 0x0d, 0x10, 0x0b, 0x00, 0x4d, 0x0d, 0x38, +0x08, 0x0a, 0x00, 0x4c, 0x0c, 0x06, 0x03, 0x06, 0x81, 0x07, +0x0c, 0x14, 0x07, 0x07, 0x0c, 0x03, 0x03, 0x0f, 0x25, 0x19, +0x7f, 0x18, 0x27, 0x07, 0x07, 0x21, 0x82, 0x00, 0x0f, 0x01, +0x08, 0x0f, 0x26, 0x0c, 0x03, 0x03, 0x1a, 0x86, 0x25, 0x25, +0x14, 0x19, 0x4a, 0x1e, 0x85, 0x14, 0x50, 0x07, 0x06, 0x4a, +0x00, 0x3f, 0x33, 0x3f, 0xed, 0x3f, 0x12, 0x39, 0x2f, 0xed, +0x32, 0x2f, 0x32, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x33, +0x2f, 0x10, 0xde, 0xed, 0x32, 0x11, 0x39, 0x2f, 0x87, 0x10, +0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x25, 0x22, 0x26, 0x27, 0x06, 0x06, 0x07, +0x23, 0x3e, 0x03, 0x37, 0x26, 0x26, 0x35, 0x34, 0x3e, 0x02, +0x33, 0x32, 0x16, 0x17, 0x11, 0x23, 0x35, 0x35, 0x26, 0x26, +0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x33, 0x01, 0x14, +0x0e, 0x19, 0x0b, 0x1d, 0x34, 0x15, 0x54, 0x0b, 0x1c, 0x1e, +0x1e, 0x0e, 0x32, 0x23, 0x1d, 0x34, 0x47, 0x2a, 0x3b, 0x50, +0x1c, 0x53, 0x0a, 0x2b, 0x1e, 0x33, 0x3e, 0x40, 0x33, 0x51, +0xb4, 0x01, 0x01, 0x2b, 0x61, 0x2a, 0x1a, 0x37, 0x33, 0x2f, +0x12, 0x12, 0x43, 0x26, 0x27, 0x3a, 0x27, 0x14, 0x0a, 0x08, +0xfe, 0x36, 0xb4, 0xdf, 0x02, 0x03, 0x2a, 0x2d, 0x2d, 0x22, +0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xc7, 0x02, 0xb5, +0x02, 0x26, 0x00, 0x48, 0x00, 0x00, 0x01, 0x06, 0x00, 0x43, +0x01, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x25, 0x23, +0x13, 0x02, 0x50, 0x02, 0x00, 0x24, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xc7, 0x02, 0x8f, +0x02, 0x26, 0x00, 0x48, 0x00, 0x00, 0x01, 0x06, 0x00, 0x83, +0x0d, 0x00, 0x00, 0x17, 0x40, 0x10, 0x03, 0x02, 0x0f, 0x24, +0x36, 0x13, 0x02, 0x50, 0x03, 0x00, 0x2e, 0x4f, 0x02, 0x00, +0x22, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x01, +0x00, 0x14, 0xff, 0x59, 0x01, 0xb0, 0x02, 0xb5, 0x00, 0x2b, +0x00, 0x8b, 0x40, 0x0b, 0x23, 0x18, 0x12, 0x00, 0x4d, 0x23, +0x10, 0x10, 0x00, 0x4d, 0x13, 0xb8, 0xff, 0xe0, 0xb4, 0x0e, +0x0f, 0x00, 0x4c, 0x13, 0xb8, 0xff, 0xe8, 0xb3, 0x0d, 0x00, +0x4d, 0x0e, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x0e, +0xb8, 0xff, 0xe0, 0x40, 0x37, 0x08, 0x0a, 0x00, 0x4c, 0x0f, +0x19, 0x1f, 0x19, 0x02, 0x19, 0x19, 0x28, 0x20, 0x7f, 0x11, +0x2d, 0x07, 0x06, 0x04, 0x28, 0x7f, 0x2b, 0x01, 0x00, 0x29, +0x01, 0x29, 0x2c, 0x29, 0x4a, 0x1d, 0x89, 0x16, 0x4b, 0x07, +0x2a, 0x04, 0x01, 0x01, 0x03, 0x24, 0x88, 0x00, 0x0b, 0x10, +0x0b, 0x20, 0x0b, 0x03, 0x08, 0x0b, 0x50, 0x02, 0x03, 0x4d, +0x00, 0x3f, 0x33, 0x3f, 0x5e, 0x5d, 0xed, 0x12, 0x39, 0x2f, +0x33, 0xcd, 0x32, 0x3f, 0xed, 0x3f, 0x01, 0x10, 0xd6, 0x5d, +0x32, 0xce, 0xfd, 0x32, 0xcc, 0x33, 0x10, 0xde, 0xed, 0x11, +0x39, 0x2f, 0x5d, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x13, 0x33, 0x35, 0x37, 0x15, 0x33, 0x15, 0x23, 0x15, +0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x11, 0x14, 0x0e, +0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, +0x36, 0x35, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x11, +0x23, 0x11, 0x23, 0x14, 0x42, 0x52, 0xa2, 0xa2, 0x13, 0x31, +0x16, 0x31, 0x43, 0x28, 0x12, 0x0b, 0x1e, 0x34, 0x28, 0x0d, +0x20, 0x0a, 0x08, 0x08, 0x16, 0x08, 0x21, 0x1b, 0x2d, 0x37, +0x17, 0x31, 0x0a, 0x52, 0x42, 0x02, 0x62, 0x45, 0x0e, 0x53, +0x3e, 0x5b, 0x08, 0x09, 0x1f, 0x38, 0x4e, 0x2f, 0xfe, 0xfa, +0x29, 0x3f, 0x2a, 0x15, 0x05, 0x02, 0x41, 0x02, 0x02, 0x2b, +0x29, 0x01, 0x03, 0x56, 0x47, 0x0b, 0x05, 0xfe, 0x7f, 0x02, +0x24, 0x00, 0xff, 0xff, 0x00, 0x6b, 0x00, 0x00, 0x01, 0xb8, +0x02, 0xb5, 0x02, 0x26, 0x02, 0xe6, 0x00, 0x00, 0x01, 0x06, +0x00, 0x8f, 0x36, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x22, +0x08, 0x06, 0x00, 0x02, 0x50, 0x01, 0x01, 0x07, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x01, 0x00, 0x31, 0xff, 0xf5, 0x01, 0xc2, +0x01, 0xdb, 0x00, 0x24, 0x00, 0x58, 0xb9, 0x00, 0x17, 0xff, +0xc0, 0xb3, 0x0e, 0x00, 0x4d, 0x17, 0xb8, 0xff, 0xd8, 0xb3, +0x0d, 0x00, 0x4d, 0x17, 0xb8, 0xff, 0xe8, 0xb3, 0x0c, 0x00, +0x4d, 0x0e, 0xb8, 0xff, 0xd8, 0x40, 0x1d, 0x0e, 0x00, 0x4d, +0x08, 0x08, 0x1d, 0x26, 0x11, 0x14, 0x82, 0x00, 0x25, 0x13, +0x86, 0x12, 0x12, 0x05, 0x1c, 0x1c, 0x19, 0x88, 0x20, 0x51, +0x09, 0x09, 0x0c, 0x88, 0x05, 0x50, 0x00, 0x3f, 0xed, 0x32, +0x2f, 0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, 0x2f, 0xed, 0x01, +0x10, 0xd6, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x37, 0x34, 0x3e, 0x02, 0x33, 0x32, +0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x07, +0x33, 0x15, 0x23, 0x1e, 0x03, 0x33, 0x32, 0x36, 0x37, 0x17, +0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x31, 0x24, 0x42, 0x5c, +0x38, 0x32, 0x46, 0x18, 0x13, 0x1d, 0x35, 0x27, 0x22, 0x3a, +0x2c, 0x1c, 0x04, 0xd3, 0xd5, 0x03, 0x1c, 0x2e, 0x3d, 0x24, +0x26, 0x49, 0x14, 0x0c, 0x13, 0x51, 0x33, 0x39, 0x5d, 0x41, +0x23, 0xea, 0x37, 0x5a, 0x3e, 0x22, 0x0d, 0x08, 0x47, 0x0b, +0x0a, 0x13, 0x22, 0x31, 0x1e, 0x43, 0x21, 0x36, 0x25, 0x14, +0x0c, 0x09, 0x45, 0x09, 0x0f, 0x21, 0x3f, 0x5b, 0xff, 0xff, +0x00, 0x42, 0xff, 0xf5, 0x01, 0xb2, 0x01, 0xdb, 0x02, 0x06, +0x00, 0x56, 0x00, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, +0x01, 0xc2, 0x02, 0x9e, 0x02, 0x06, 0x00, 0x4c, 0x00, 0x00, +0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0x8f, +0x02, 0x26, 0x01, 0x0c, 0x00, 0x00, 0x01, 0x06, 0x00, 0x83, +0xdc, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, 0xff, 0xda, +0x40, 0x0d, 0x18, 0x2a, 0x01, 0x0b, 0x50, 0x02, 0x02, 0x22, +0x4f, 0x01, 0x02, 0x16, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x47, 0xff, 0x56, 0x01, 0x80, +0x02, 0x9e, 0x02, 0x06, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x02, +0x00, 0x0d, 0xff, 0xf6, 0x01, 0xde, 0x01, 0xd0, 0x00, 0x1d, +0x00, 0x29, 0x00, 0x77, 0xb9, 0x00, 0x17, 0xff, 0xe0, 0xb3, +0x0d, 0x00, 0x4d, 0x17, 0xb8, 0xff, 0xe8, 0xb3, 0x0c, 0x00, +0x4d, 0x17, 0xb8, 0xff, 0xe0, 0xb3, 0x0b, 0x00, 0x4d, 0x14, +0xb8, 0xff, 0xe8, 0x40, 0x11, 0x0b, 0x10, 0x00, 0x4c, 0x23, +0x0f, 0x7f, 0x00, 0x01, 0x7f, 0x0e, 0xa0, 0x0e, 0xb0, 0x0e, +0x02, 0x0e, 0xb8, 0xff, 0xc0, 0x40, 0x1f, 0x09, 0x0c, 0x48, +0x00, 0x0e, 0x00, 0x0e, 0x08, 0x1e, 0x82, 0x15, 0x2b, 0x08, +0x2a, 0x21, 0x89, 0x12, 0x12, 0x0e, 0x27, 0x88, 0x1a, 0x51, +0x01, 0x85, 0x0e, 0x49, 0x08, 0x88, 0x07, 0x51, 0x00, 0x3f, +0xed, 0x3f, 0xed, 0x3f, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x01, +0x10, 0xc6, 0x10, 0xde, 0xed, 0x11, 0x39, 0x39, 0x2f, 0x2f, +0x2b, 0x5d, 0x10, 0xed, 0x10, 0xed, 0x32, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x13, 0x23, 0x15, 0x14, 0x0e, 0x02, 0x07, +0x27, 0x3e, 0x03, 0x35, 0x35, 0x33, 0x15, 0x36, 0x33, 0x32, +0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, +0x34, 0x26, 0x23, 0x22, 0x07, 0x15, 0x16, 0x16, 0x33, 0x32, +0x36, 0xf0, 0x44, 0x07, 0x1d, 0x3b, 0x34, 0x0c, 0x1f, 0x23, +0x10, 0x04, 0xd6, 0x16, 0x1a, 0x37, 0x3e, 0x14, 0x25, 0x33, +0x1f, 0x17, 0x32, 0x1a, 0xa1, 0x19, 0x20, 0x0b, 0x14, 0x08, +0x0e, 0x07, 0x21, 0x1a, 0x01, 0x8b, 0x22, 0x53, 0x82, 0x5e, +0x38, 0x07, 0x46, 0x07, 0x2b, 0x50, 0x76, 0x52, 0x49, 0xae, +0x07, 0x52, 0x45, 0x2b, 0x3b, 0x25, 0x11, 0x08, 0x08, 0x8b, +0x26, 0x2d, 0x05, 0xa1, 0x01, 0x01, 0x27, 0x00, 0x00, 0x02, +0x00, 0x36, 0xff, 0xf6, 0x01, 0xde, 0x01, 0xd0, 0x00, 0x17, +0x00, 0x22, 0x00, 0x67, 0xb9, 0x00, 0x11, 0xff, 0xe8, 0xb3, +0x0d, 0x00, 0x4d, 0x0e, 0xb8, 0xff, 0xf0, 0xb4, 0x0f, 0x10, +0x00, 0x4c, 0x0e, 0xb8, 0xff, 0xe8, 0x40, 0x2c, 0x0d, 0x0e, +0x00, 0x4c, 0x0a, 0x1e, 0x7f, 0x07, 0x17, 0x17, 0x03, 0x18, +0x82, 0x0f, 0x24, 0x06, 0x02, 0x7f, 0x10, 0x03, 0x01, 0x03, +0x23, 0x1b, 0x89, 0x0c, 0x01, 0x86, 0x06, 0x0c, 0x06, 0x0c, +0x06, 0x04, 0x20, 0x88, 0x14, 0x51, 0x08, 0x49, 0x04, 0x49, +0x03, 0x4a, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0xed, 0x11, 0x39, +0x39, 0x2f, 0x2f, 0x10, 0xed, 0x10, 0xed, 0x01, 0x10, 0xd6, +0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, 0x33, +0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x37, 0x23, 0x15, +0x23, 0x11, 0x33, 0x15, 0x33, 0x35, 0x33, 0x15, 0x36, 0x33, +0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, +0x37, 0x34, 0x26, 0x23, 0x22, 0x07, 0x15, 0x16, 0x33, 0x32, +0x36, 0xf0, 0x71, 0x49, 0x49, 0x71, 0x49, 0x17, 0x19, 0x37, +0x3e, 0x14, 0x25, 0x33, 0x1f, 0x17, 0x32, 0x1a, 0xa1, 0x19, +0x20, 0x0b, 0x14, 0x10, 0x0d, 0x21, 0x1a, 0xd3, 0xd3, 0x01, +0xd0, 0xbb, 0xbb, 0xaf, 0x08, 0x52, 0x45, 0x2b, 0x3b, 0x25, +0x11, 0x08, 0x08, 0x8b, 0x26, 0x2d, 0x05, 0xa0, 0x03, 0x27, +0x00, 0x00, 0xff, 0xff, 0x00, 0x14, 0x00, 0x00, 0x01, 0xb0, +0x02, 0xb5, 0x02, 0x06, 0x01, 0x02, 0x00, 0x00, 0xff, 0xff, +0x00, 0x47, 0x00, 0x00, 0x01, 0xde, 0x02, 0xb5, 0x02, 0x26, +0x01, 0x15, 0x00, 0x00, 0x01, 0x06, 0x00, 0x8f, 0x22, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x0d, 0x19, 0x17, 0x0d, 0x05, +0x50, 0x01, 0x0e, 0x18, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x3f, 0x00, 0x00, 0x01, 0xb6, 0x02, 0xb5, 0x02, 0x26, +0x02, 0xeb, 0x00, 0x00, 0x01, 0x06, 0x00, 0x43, 0x04, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x15, 0x13, 0x09, 0x00, +0x50, 0x01, 0x00, 0x14, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x24, 0xff, 0x58, 0x01, 0xcd, 0x02, 0x98, 0x02, 0x26, +0x00, 0x5c, 0x00, 0x00, 0x01, 0x06, 0x03, 0x90, 0x12, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x13, 0x24, 0x2c, 0x20, 0x15, +0x50, 0x01, 0x09, 0x21, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x01, +0x00, 0x47, 0xff, 0x7f, 0x01, 0xad, 0x01, 0xd0, 0x00, 0x0b, +0x00, 0x32, 0x40, 0x1a, 0x07, 0x7f, 0x0a, 0x0a, 0x0b, 0x03, +0x7f, 0x06, 0x0d, 0x02, 0x7f, 0x00, 0x0b, 0x01, 0x08, 0x0b, +0x0c, 0x09, 0x07, 0x02, 0x85, 0x0b, 0x4a, 0x04, 0x00, 0x49, +0x00, 0x3f, 0x32, 0x3f, 0xed, 0x33, 0xce, 0x01, 0x10, 0xd6, +0x5e, 0x5d, 0xed, 0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, 0xed, +0x31, 0x30, 0x13, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x23, +0x15, 0x23, 0x35, 0x23, 0x47, 0x53, 0xc0, 0x53, 0x8c, 0x4e, +0x8c, 0x01, 0xd0, 0xfe, 0x76, 0x01, 0x8a, 0xfe, 0x30, 0x81, +0x81, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, 0xff, 0xf4, +0x01, 0xcc, 0x02, 0xb5, 0x00, 0x11, 0x00, 0x3c, 0x00, 0xb3, +0xb5, 0x37, 0x18, 0x08, 0x00, 0x4d, 0x33, 0xb8, 0xff, 0xe8, +0xb3, 0x08, 0x00, 0x4d, 0x2d, 0xb8, 0xff, 0xc8, 0xb3, 0x09, +0x00, 0x4d, 0x2b, 0xb8, 0xff, 0xd8, 0xb3, 0x10, 0x00, 0x4d, +0x29, 0xb8, 0xff, 0xe0, 0x40, 0x33, 0x0f, 0x00, 0x4d, 0x16, +0x18, 0x0f, 0x00, 0x4d, 0x16, 0x20, 0x0e, 0x00, 0x4d, 0x16, +0x18, 0x0d, 0x00, 0x4d, 0x16, 0x28, 0x0c, 0x00, 0x4d, 0x16, +0x20, 0x0b, 0x00, 0x4d, 0x16, 0x28, 0x09, 0x0a, 0x00, 0x4c, +0x13, 0x18, 0x0d, 0x00, 0x4d, 0x10, 0x20, 0x10, 0x00, 0x4d, +0x0a, 0x18, 0x0f, 0x10, 0x00, 0x4c, 0x06, 0xb8, 0xff, 0xe8, +0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x01, 0xb8, 0xff, 0xe0, 0x40, +0x22, 0x10, 0x00, 0x4d, 0x12, 0x00, 0x15, 0x0d, 0x82, 0x30, +0x1e, 0x1e, 0x30, 0x3e, 0x26, 0x82, 0x15, 0x15, 0x03, 0x82, +0x3a, 0x3d, 0x2b, 0x00, 0x12, 0x12, 0x18, 0x08, 0x88, 0x35, +0x51, 0x21, 0x88, 0x18, 0x4d, 0x00, 0x3f, 0xed, 0x3f, 0xed, +0x11, 0x39, 0x11, 0x33, 0x33, 0x01, 0x10, 0xd6, 0xed, 0x33, +0x2f, 0xed, 0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, 0x11, 0x39, +0x39, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, +0x06, 0x06, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, +0x35, 0x34, 0x2e, 0x02, 0x27, 0x26, 0x26, 0x35, 0x34, 0x36, +0x33, 0x32, 0x32, 0x36, 0x36, 0x37, 0x17, 0x06, 0x06, 0x23, +0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x17, 0x1e, 0x03, +0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, +0x36, 0xff, 0x40, 0x44, 0x0e, 0x1e, 0x30, 0x23, 0x20, 0x30, +0x1f, 0x0f, 0x16, 0x23, 0x2b, 0x56, 0x22, 0x2a, 0x5a, 0x4e, +0x18, 0x23, 0x1b, 0x18, 0x0e, 0x05, 0x0e, 0x43, 0x2c, 0x0c, +0x1f, 0x1d, 0x13, 0x0c, 0x17, 0x20, 0x14, 0x24, 0x40, 0x31, +0x1d, 0x17, 0x32, 0x50, 0x3a, 0x36, 0x50, 0x33, 0x19, 0x53, +0x01, 0x98, 0x12, 0x61, 0x43, 0x21, 0x3c, 0x2e, 0x1b, 0x19, +0x2c, 0x3b, 0x21, 0x29, 0x3b, 0x2c, 0x1f, 0x36, 0x18, 0x3c, +0x22, 0x3f, 0x3a, 0x01, 0x01, 0x02, 0x47, 0x02, 0x01, 0x01, +0x09, 0x12, 0x12, 0x0e, 0x14, 0x14, 0x15, 0x0e, 0x18, 0x31, +0x3d, 0x4f, 0x36, 0x2a, 0x52, 0x41, 0x28, 0x26, 0x40, 0x56, +0x30, 0x54, 0x73, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x12, +0xff, 0xfb, 0x01, 0xd5, 0x02, 0x93, 0x00, 0x15, 0x00, 0x26, +0x00, 0x98, 0x40, 0x2a, 0x1e, 0x30, 0x0f, 0x10, 0x00, 0x4c, +0x1d, 0x38, 0x12, 0x00, 0x4d, 0x1d, 0x20, 0x11, 0x00, 0x4d, +0x19, 0x28, 0x12, 0x00, 0x4d, 0x19, 0x20, 0x11, 0x00, 0x4d, +0x19, 0x18, 0x10, 0x00, 0x4d, 0x19, 0x20, 0x0f, 0x00, 0x4d, +0x18, 0x20, 0x12, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xe8, 0xb3, +0x0a, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xd8, 0xb3, 0x09, 0x00, +0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x05, +0xb8, 0xff, 0xe0, 0x40, 0x25, 0x09, 0x00, 0x4d, 0x1b, 0x76, +0x07, 0x28, 0x21, 0x15, 0x13, 0x00, 0x73, 0x10, 0x0d, 0x0e, +0x27, 0x00, 0x0d, 0x79, 0x10, 0x13, 0x10, 0x21, 0x79, 0x01, +0x00, 0x01, 0x01, 0x10, 0x01, 0x10, 0x01, 0x11, 0x16, 0x7c, +0x09, 0x43, 0x00, 0x3f, 0xed, 0x2f, 0x39, 0x39, 0x2f, 0x2f, +0x5d, 0x10, 0xed, 0x11, 0x33, 0x10, 0xed, 0x32, 0x01, 0x10, +0xd6, 0xdd, 0x32, 0xfd, 0x32, 0xcd, 0x33, 0x10, 0xde, 0xed, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x15, 0x33, 0x32, 0x1e, 0x02, +0x15, 0x14, 0x23, 0x22, 0x26, 0x27, 0x11, 0x23, 0x35, 0x33, +0x35, 0x33, 0x15, 0x33, 0x15, 0x03, 0x32, 0x3e, 0x02, 0x35, +0x34, 0x2e, 0x02, 0x23, 0x23, 0x15, 0x1e, 0x02, 0x32, 0xbd, +0x34, 0x38, 0x56, 0x39, 0x1d, 0xe0, 0x22, 0x48, 0x20, 0x59, +0x59, 0x52, 0xa7, 0x6c, 0x1f, 0x33, 0x25, 0x14, 0x14, 0x26, +0x37, 0x24, 0x31, 0x0c, 0x0f, 0x0c, 0x0c, 0x02, 0x04, 0x85, +0x14, 0x2d, 0x4a, 0x35, 0xc4, 0x06, 0x09, 0x01, 0xfa, 0x46, +0x49, 0x49, 0x46, 0xfe, 0x3c, 0x0d, 0x1d, 0x30, 0x24, 0x25, +0x31, 0x1c, 0x0c, 0xf8, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, +0x00, 0x02, 0x00, 0x12, 0xff, 0xf6, 0x01, 0xcc, 0x02, 0xb5, +0x00, 0x18, 0x00, 0x27, 0x00, 0x63, 0xb9, 0x00, 0x11, 0xff, +0xe0, 0xb4, 0x09, 0x0a, 0x00, 0x4c, 0x0e, 0xb8, 0xff, 0xe8, +0x40, 0x30, 0x09, 0x0a, 0x00, 0x4c, 0x1c, 0x82, 0x10, 0x29, +0x22, 0x06, 0x04, 0x07, 0x7f, 0x01, 0x17, 0x18, 0x28, 0x07, +0x17, 0x86, 0x01, 0x04, 0x01, 0x1f, 0x89, 0x0b, 0x0f, 0x01, +0x1f, 0x01, 0x3f, 0x01, 0x4f, 0x01, 0x04, 0x08, 0x01, 0x0b, +0x01, 0x0b, 0x03, 0x19, 0x89, 0x13, 0x51, 0x02, 0x03, 0x4d, +0x00, 0x3f, 0x33, 0x3f, 0xed, 0x11, 0x39, 0x39, 0x2f, 0x2f, +0x5e, 0x5d, 0x10, 0xed, 0x11, 0x33, 0x10, 0xed, 0x32, 0x01, +0x10, 0xd6, 0xdd, 0x32, 0xfd, 0x32, 0xcd, 0x33, 0x10, 0xde, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x13, 0x33, 0x35, 0x37, 0x15, +0x33, 0x15, 0x23, 0x15, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, +0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x11, 0x23, 0x01, +0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x15, +0x1e, 0x03, 0x12, 0x59, 0x52, 0x9f, 0x9f, 0x0e, 0x3a, 0x19, +0x24, 0x3f, 0x2f, 0x1c, 0x66, 0x57, 0x2b, 0x52, 0x27, 0x59, +0x01, 0x02, 0x30, 0x36, 0x3c, 0x2a, 0x17, 0x2f, 0x11, 0x06, +0x14, 0x18, 0x1a, 0x01, 0xd0, 0xd7, 0x0e, 0xe5, 0x44, 0x6d, +0x03, 0x07, 0x11, 0x24, 0x3a, 0x28, 0x54, 0x48, 0x09, 0x0b, +0x01, 0x82, 0xfe, 0xae, 0x29, 0x2e, 0x2d, 0x28, 0x03, 0x05, +0x9f, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0x03, 0x00, 0x1d, +0xff, 0xf3, 0x01, 0xd8, 0x02, 0x79, 0x00, 0x13, 0x00, 0x24, +0x00, 0x35, 0x00, 0xe7, 0x40, 0x0b, 0x2c, 0x10, 0x0e, 0x00, +0x4d, 0x2c, 0x08, 0x0d, 0x00, 0x4d, 0x2a, 0xb8, 0xff, 0xf0, +0xb4, 0x0d, 0x0e, 0x00, 0x4c, 0x1c, 0xb8, 0xff, 0xf0, 0xb3, +0x12, 0x00, 0x4d, 0x1c, 0xb8, 0xff, 0xf8, 0xb3, 0x11, 0x00, +0x4d, 0x1b, 0xb8, 0xff, 0xe8, 0x40, 0x2d, 0x0e, 0x00, 0x4d, +0x19, 0x18, 0x0e, 0x00, 0x4d, 0x19, 0x10, 0x0d, 0x00, 0x4d, +0x19, 0x18, 0x0c, 0x00, 0x4d, 0x19, 0x10, 0x0b, 0x00, 0x4d, +0x18, 0x10, 0x11, 0x12, 0x00, 0x4c, 0x12, 0x10, 0x08, 0x00, +0x4d, 0x11, 0x10, 0x10, 0x00, 0x4d, 0x11, 0x18, 0x0f, 0x00, +0x4d, 0x0d, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x0d, +0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x0c, 0xb8, 0xff, +0xe8, 0xb3, 0x08, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xe8, 0xb3, +0x08, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, +0x4d, 0x07, 0xb8, 0xff, 0xe0, 0x40, 0x30, 0x0f, 0x00, 0x4d, +0x03, 0x10, 0x0f, 0x10, 0x00, 0x4c, 0x03, 0x10, 0x08, 0x00, +0x4d, 0x2e, 0x17, 0x76, 0x0a, 0x37, 0x28, 0x1d, 0x76, 0x00, +0x40, 0x0b, 0x10, 0x48, 0x00, 0x36, 0x28, 0x25, 0x20, 0x2e, +0x31, 0x17, 0x14, 0x1d, 0x20, 0x20, 0x05, 0x2b, 0x7c, 0x0f, +0x46, 0x1a, 0x7c, 0x05, 0x45, 0x00, 0x3f, 0xed, 0x3f, 0xed, +0x11, 0x39, 0x2f, 0x33, 0xdc, 0x32, 0xcd, 0x32, 0x10, 0xcd, +0x32, 0x01, 0x10, 0xd6, 0x2b, 0xed, 0x32, 0x10, 0xde, 0xed, +0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x34, 0x3e, 0x02, 0x33, +0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, +0x02, 0x25, 0x32, 0x36, 0x37, 0x26, 0x26, 0x23, 0x22, 0x06, +0x07, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x07, 0x22, 0x06, +0x07, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, 0x06, 0x06, 0x23, +0x22, 0x2e, 0x02, 0x1d, 0x20, 0x3b, 0x51, 0x32, 0x31, 0x51, +0x3b, 0x20, 0x20, 0x3b, 0x51, 0x31, 0x32, 0x51, 0x3b, 0x20, +0x01, 0x35, 0x0e, 0x1a, 0x0a, 0x03, 0x45, 0x43, 0x42, 0x42, +0x04, 0x0e, 0x26, 0x1c, 0x15, 0x24, 0x22, 0x22, 0x84, 0x18, +0x24, 0x0b, 0x08, 0x41, 0x3d, 0x3e, 0x44, 0x08, 0x0c, 0x1a, +0x12, 0x15, 0x24, 0x22, 0x23, 0x01, 0x36, 0x53, 0x7a, 0x4f, +0x27, 0x27, 0x4f, 0x7a, 0x53, 0x53, 0x7a, 0x50, 0x26, 0x26, +0x50, 0x7a, 0x4e, 0x0e, 0x0b, 0x70, 0x78, 0x76, 0x6f, 0x10, +0x15, 0x14, 0x19, 0x14, 0x03, 0x1e, 0x12, 0x5f, 0x65, 0x67, +0x61, 0x0a, 0x0a, 0x14, 0x18, 0x14, 0x00, 0x00, 0x00, 0x03, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x01, 0xdb, 0x00, 0x13, +0x00, 0x23, 0x00, 0x34, 0x00, 0xa0, 0xb9, 0x00, 0x2b, 0xff, +0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x2b, 0xb8, 0xff, 0xd8, 0xb3, +0x0f, 0x00, 0x4d, 0x2b, 0xb8, 0xff, 0xf0, 0x40, 0x1b, 0x0e, +0x00, 0x4d, 0x29, 0x30, 0x0f, 0x10, 0x00, 0x4c, 0x29, 0x18, +0x0e, 0x00, 0x4d, 0x22, 0x18, 0x11, 0x12, 0x00, 0x4c, 0x22, +0x10, 0x0d, 0x0e, 0x00, 0x4c, 0x18, 0xb8, 0xff, 0xf0, 0xb4, +0x0f, 0x10, 0x00, 0x4c, 0x12, 0xb8, 0xff, 0xe8, 0x40, 0x0e, +0x08, 0x00, 0x4d, 0x0c, 0x10, 0x08, 0x00, 0x4d, 0x08, 0x10, +0x08, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xf0, 0x40, 0x26, 0x08, +0x00, 0x4d, 0x27, 0x1d, 0x82, 0x00, 0x36, 0x2d, 0x17, 0x82, +0x1f, 0x0a, 0x2f, 0x0a, 0x3f, 0x0a, 0x03, 0x0a, 0x35, 0x1d, +0x1f, 0x27, 0x24, 0x17, 0x14, 0x2d, 0x30, 0x30, 0x1a, 0x2a, +0x88, 0x0f, 0x50, 0x1a, 0x88, 0x05, 0x51, 0x00, 0x3f, 0xed, +0x3f, 0xed, 0x12, 0x39, 0x2f, 0x33, 0xcd, 0x32, 0xdc, 0x32, +0xcd, 0x32, 0x01, 0x10, 0xd6, 0x5d, 0xed, 0x32, 0x10, 0xde, +0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, +0x1e, 0x02, 0x05, 0x22, 0x06, 0x07, 0x16, 0x16, 0x33, 0x32, +0x36, 0x37, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x37, 0x32, 0x36, +0x37, 0x26, 0x26, 0x23, 0x22, 0x06, 0x07, 0x36, 0x36, 0x33, +0x32, 0x1e, 0x02, 0x01, 0xcc, 0x1f, 0x38, 0x4e, 0x2e, 0x2d, +0x4d, 0x38, 0x1f, 0x1f, 0x38, 0x4d, 0x2d, 0x2e, 0x4e, 0x38, +0x1f, 0xfe, 0xec, 0x13, 0x1e, 0x08, 0x08, 0x40, 0x32, 0x34, +0x42, 0x06, 0x14, 0x20, 0x15, 0x22, 0x20, 0x20, 0x7a, 0x10, +0x18, 0x09, 0x08, 0x41, 0x33, 0x33, 0x41, 0x07, 0x0b, 0x1d, +0x16, 0x14, 0x22, 0x20, 0x20, 0xe8, 0x37, 0x59, 0x40, 0x23, +0x23, 0x40, 0x59, 0x37, 0x37, 0x5a, 0x3f, 0x23, 0x23, 0x3f, +0x5a, 0x3a, 0x14, 0x0d, 0x3f, 0x46, 0x4a, 0x42, 0x12, 0x0e, +0x10, 0x0e, 0x0f, 0x0d, 0x0a, 0x3f, 0x48, 0x4a, 0x41, 0x0b, +0x0e, 0x0e, 0x10, 0x0e, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x00, +0x01, 0xfd, 0x02, 0x74, 0x00, 0x1b, 0x00, 0x48, 0x40, 0x27, +0x16, 0x17, 0x16, 0x13, 0x17, 0x78, 0x0b, 0x0c, 0x14, 0x0b, +0x0b, 0x0c, 0x16, 0x13, 0x13, 0x78, 0x12, 0x0d, 0x14, 0x12, +0x0d, 0x12, 0x1c, 0x0d, 0x0b, 0x03, 0x13, 0x12, 0x41, 0x16, +0x0c, 0x0d, 0x44, 0x17, 0x0b, 0x06, 0x7c, 0x00, 0x45, 0x00, +0x3f, 0xed, 0x32, 0x32, 0x3f, 0x33, 0x33, 0x3f, 0x33, 0x01, +0x2f, 0x33, 0x2f, 0x10, 0xd6, 0x87, 0x2b, 0x7d, 0x10, 0xc4, +0x87, 0x18, 0x10, 0x2b, 0x08, 0x7d, 0x10, 0xc4, 0x31, 0x30, +0x01, 0x32, 0x16, 0x17, 0x07, 0x26, 0x23, 0x22, 0x0e, 0x02, +0x07, 0x03, 0x23, 0x2e, 0x03, 0x27, 0x33, 0x16, 0x12, 0x17, +0x13, 0x3e, 0x03, 0x01, 0xb3, 0x18, 0x24, 0x0e, 0x25, 0x0f, +0x11, 0x07, 0x09, 0x08, 0x08, 0x06, 0x78, 0x62, 0x17, 0x29, +0x28, 0x2a, 0x19, 0x59, 0x1d, 0x3f, 0x24, 0x60, 0x07, 0x0e, +0x18, 0x24, 0x02, 0x74, 0x13, 0x0c, 0x39, 0x10, 0x06, 0x11, +0x1d, 0x18, 0xfe, 0x20, 0x4b, 0x8a, 0x92, 0xa2, 0x62, 0x8a, +0xfe, 0xee, 0x7e, 0x01, 0xa4, 0x1e, 0x2f, 0x21, 0x11, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xe9, +0x01, 0xdc, 0x00, 0x19, 0x00, 0x54, 0x40, 0x2f, 0x00, 0x0b, +0x0a, 0x0b, 0x81, 0x19, 0x00, 0x14, 0x19, 0x19, 0x00, 0x0f, +0x19, 0x01, 0x08, 0x19, 0x13, 0x1b, 0x01, 0x05, 0x0a, 0x05, +0x81, 0x04, 0x01, 0x14, 0x04, 0x01, 0x04, 0x1a, 0x34, 0x0a, +0x01, 0x0a, 0x19, 0x0b, 0x16, 0x88, 0x10, 0x50, 0x05, 0x04, +0x49, 0x0a, 0x00, 0x01, 0x4a, 0x00, 0x3f, 0x33, 0x33, 0x3f, +0x33, 0x3f, 0xed, 0x32, 0x32, 0x01, 0x2f, 0x5d, 0x10, 0xd6, +0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, 0x10, 0xce, 0x32, +0x5e, 0x5d, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, +0x21, 0x23, 0x26, 0x26, 0x27, 0x33, 0x1e, 0x03, 0x17, 0x13, +0x3e, 0x03, 0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x23, 0x22, +0x06, 0x07, 0x01, 0x03, 0x4b, 0x2a, 0x4f, 0x21, 0x5a, 0x0a, +0x18, 0x1b, 0x1c, 0x0e, 0x53, 0x08, 0x12, 0x1a, 0x24, 0x1a, +0x11, 0x22, 0x12, 0x0e, 0x0d, 0x1d, 0x17, 0x14, 0x0a, 0x5f, +0xee, 0x83, 0x2c, 0x63, 0x61, 0x5b, 0x24, 0x01, 0x12, 0x18, +0x27, 0x1b, 0x0f, 0x07, 0x06, 0x41, 0x08, 0x1c, 0x1a, 0x00, +0x00, 0x02, 0x00, 0x37, 0xff, 0x57, 0x01, 0xe2, 0x03, 0x23, +0x00, 0x1b, 0x00, 0x29, 0x00, 0x80, 0x40, 0x4a, 0x10, 0x11, +0x16, 0x73, 0x0b, 0x27, 0x26, 0x1f, 0x20, 0x20, 0x00, 0x0a, +0x38, 0x08, 0x01, 0x2a, 0x08, 0x01, 0x09, 0x08, 0x01, 0x06, +0x1b, 0x26, 0x1b, 0x02, 0x08, 0x1b, 0x18, 0x1b, 0x7e, 0x03, +0x08, 0x14, 0x03, 0x03, 0x08, 0x18, 0x73, 0x0a, 0x40, 0x08, +0x0c, 0x48, 0x0a, 0x0b, 0x2b, 0x03, 0x73, 0x00, 0x00, 0x10, +0x00, 0x02, 0x00, 0x2a, 0x03, 0x1b, 0x44, 0x11, 0x10, 0x0a, +0x79, 0x17, 0x44, 0x18, 0x08, 0x41, 0x26, 0x20, 0x23, 0x1c, +0x02, 0x41, 0x00, 0x3f, 0xde, 0xdd, 0xce, 0x32, 0x3f, 0x33, +0x3f, 0xed, 0xdc, 0x19, 0xc5, 0x18, 0x3f, 0x33, 0x01, 0x10, +0xd6, 0x5d, 0xed, 0x10, 0xde, 0xdd, 0x2b, 0xed, 0x87, 0x10, +0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x5d, 0x5d, 0x5d, 0x5d, 0x11, +0x12, 0x39, 0x18, 0x2f, 0xc5, 0xd6, 0xc5, 0x10, 0xfd, 0xde, +0x19, 0xc5, 0x31, 0x30, 0x33, 0x11, 0x33, 0x11, 0x3e, 0x03, +0x37, 0x33, 0x11, 0x33, 0x16, 0x0e, 0x02, 0x07, 0x27, 0x3e, +0x03, 0x37, 0x23, 0x11, 0x06, 0x02, 0x07, 0x13, 0x22, 0x26, +0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, +0x06, 0x37, 0x4f, 0x0f, 0x33, 0x3c, 0x42, 0x1e, 0x56, 0x27, +0x01, 0x10, 0x1d, 0x29, 0x17, 0x3c, 0x09, 0x17, 0x15, 0x12, +0x05, 0x1a, 0x4b, 0x70, 0x23, 0x6c, 0x38, 0x46, 0x08, 0x3f, +0x08, 0x22, 0x1d, 0x1d, 0x22, 0x08, 0x3e, 0x08, 0x45, 0x02, +0x6b, 0xfe, 0x22, 0x2b, 0x78, 0x83, 0x82, 0x36, 0xfd, 0xdf, +0x1f, 0x42, 0x40, 0x3b, 0x17, 0x26, 0x09, 0x1c, 0x23, 0x27, +0x14, 0x01, 0xea, 0x95, 0xff, 0x00, 0x55, 0x02, 0xa6, 0x39, +0x33, 0x11, 0x1d, 0x23, 0x23, 0x1d, 0x11, 0x33, 0x39, 0x00, +0x00, 0x02, 0x00, 0x3f, 0xff, 0x6c, 0x01, 0xe3, 0x02, 0x98, +0x00, 0x1b, 0x00, 0x29, 0x00, 0x76, 0x40, 0x41, 0x05, 0x06, +0x0b, 0x7f, 0x02, 0x27, 0x26, 0x1f, 0x20, 0x20, 0x01, 0x13, +0x39, 0x1b, 0x01, 0x2b, 0x1b, 0x01, 0x1b, 0x12, 0x0d, 0x12, +0x81, 0x16, 0x1b, 0x14, 0x16, 0x16, 0x1b, 0x0d, 0x7f, 0x01, +0x40, 0x08, 0x0c, 0x48, 0x01, 0x02, 0x2b, 0x16, 0x7f, 0x00, +0x13, 0x01, 0x08, 0x13, 0x2a, 0x0d, 0x1b, 0x49, 0x26, 0x20, +0x23, 0x1c, 0x15, 0x49, 0x16, 0x12, 0x4a, 0x06, 0x05, 0x01, +0x85, 0x0c, 0x4a, 0x00, 0x3f, 0xed, 0xdc, 0x19, 0xc5, 0x18, +0x3f, 0x33, 0x3f, 0xde, 0xdd, 0xce, 0x32, 0x3f, 0x33, 0x01, +0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x10, 0xde, 0xdd, 0x2b, 0xed, +0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x5d, 0x5d, 0x11, +0x12, 0x39, 0x18, 0x2f, 0xcd, 0xde, 0xcd, 0x10, 0xfd, 0xde, +0x19, 0xc5, 0x31, 0x30, 0x01, 0x11, 0x33, 0x16, 0x06, 0x07, +0x27, 0x3e, 0x03, 0x37, 0x23, 0x11, 0x0e, 0x03, 0x07, 0x23, +0x11, 0x33, 0x11, 0x3e, 0x03, 0x37, 0x27, 0x22, 0x26, 0x27, +0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x06, +0x01, 0xba, 0x27, 0x02, 0x36, 0x29, 0x3a, 0x06, 0x13, 0x13, +0x11, 0x05, 0x22, 0x1b, 0x3d, 0x3c, 0x38, 0x15, 0x4a, 0x50, +0x17, 0x38, 0x3b, 0x3c, 0x1c, 0x6a, 0x38, 0x46, 0x08, 0x3f, +0x08, 0x22, 0x1d, 0x1d, 0x22, 0x08, 0x3e, 0x08, 0x45, 0x01, +0xd0, 0xfe, 0x75, 0x3f, 0x74, 0x26, 0x23, 0x06, 0x18, 0x1f, +0x23, 0x11, 0x01, 0x62, 0x22, 0x5c, 0x61, 0x5e, 0x25, 0x01, +0xd0, 0xfe, 0xb2, 0x27, 0x5b, 0x5b, 0x53, 0x1e, 0x4b, 0x39, +0x33, 0x11, 0x1d, 0x23, 0x23, 0x1d, 0x11, 0x33, 0x39, 0x00, +0x00, 0x00, 0x00, 0x02, 0x00, 0x12, 0xff, 0xfb, 0x01, 0xd5, +0x02, 0x6b, 0x00, 0x16, 0x00, 0x25, 0x00, 0x78, 0x40, 0x1a, +0x1f, 0x28, 0x0f, 0x00, 0x4d, 0x1e, 0x20, 0x10, 0x00, 0x4d, +0x1a, 0x20, 0x10, 0x00, 0x4d, 0x1a, 0x10, 0x0e, 0x00, 0x4d, +0x19, 0x28, 0x0f, 0x00, 0x4d, 0x08, 0xb8, 0xff, 0xe0, 0xb4, +0x09, 0x0a, 0x00, 0x4c, 0x05, 0xb8, 0xff, 0xe8, 0x40, 0x29, +0x09, 0x0a, 0x00, 0x4c, 0x1c, 0x76, 0x07, 0x27, 0x22, 0x16, +0x14, 0x00, 0x73, 0x11, 0x0e, 0x0f, 0x26, 0x00, 0x0e, 0x79, +0x11, 0x14, 0x11, 0x22, 0x79, 0x01, 0x00, 0x01, 0x10, 0x01, +0x02, 0x11, 0x01, 0x11, 0x01, 0x12, 0x41, 0x17, 0x7c, 0x0a, +0x43, 0x00, 0x3f, 0xed, 0x3f, 0x39, 0x39, 0x2f, 0x2f, 0x5d, +0x10, 0xed, 0x11, 0x33, 0x10, 0xed, 0x32, 0x01, 0x10, 0xd6, +0xdd, 0x32, 0xfd, 0x32, 0xcd, 0x33, 0x10, 0xde, 0xed, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x15, +0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, +0x27, 0x11, 0x23, 0x35, 0x33, 0x35, 0x33, 0x15, 0x33, 0x15, +0x03, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x23, +0x15, 0x16, 0x16, 0xab, 0x3d, 0x38, 0x58, 0x3d, 0x20, 0x78, +0x71, 0x22, 0x51, 0x20, 0x47, 0x47, 0x52, 0x7a, 0x36, 0x1f, +0x36, 0x28, 0x17, 0x17, 0x29, 0x3a, 0x24, 0x3a, 0x18, 0x1b, +0x01, 0xe5, 0x66, 0x14, 0x2d, 0x4a, 0x35, 0x63, 0x61, 0x06, +0x09, 0x01, 0xdb, 0x40, 0x46, 0x46, 0x40, 0xfe, 0x5b, 0x0d, +0x1d, 0x30, 0x24, 0x25, 0x31, 0x1c, 0x0c, 0xf8, 0x03, 0x01, +0x00, 0x02, 0x00, 0x12, 0xff, 0xf6, 0x01, 0xcc, 0x01, 0xe8, +0x00, 0x1c, 0x00, 0x2d, 0x00, 0x91, 0x40, 0x15, 0x22, 0x20, +0x12, 0x00, 0x4d, 0x22, 0x18, 0x11, 0x00, 0x4d, 0x1f, 0x18, +0x12, 0x00, 0x4d, 0x1f, 0x10, 0x11, 0x00, 0x4d, 0x14, 0xb8, +0xff, 0xe0, 0xb3, 0x0c, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xe8, +0xb4, 0x0a, 0x0b, 0x00, 0x4c, 0x10, 0xb8, 0xff, 0xe8, 0xb4, +0x0b, 0x0c, 0x00, 0x4c, 0x10, 0xb8, 0xff, 0xe0, 0x40, 0x32, +0x0a, 0x00, 0x4d, 0x20, 0x82, 0x12, 0x2f, 0x28, 0x06, 0x04, +0x07, 0x7f, 0x01, 0x1b, 0x1c, 0x2e, 0x07, 0x1b, 0x86, 0x01, +0x04, 0x01, 0x25, 0x89, 0x0d, 0x2f, 0x01, 0x3f, 0x01, 0x02, +0x00, 0x0d, 0x10, 0x0d, 0x40, 0x0d, 0x50, 0x0d, 0x04, 0x08, +0x01, 0x0d, 0x01, 0x0d, 0x02, 0x1d, 0x89, 0x17, 0x51, 0x02, +0x00, 0x2f, 0x3f, 0xed, 0x11, 0x39, 0x39, 0x2f, 0x2f, 0x5e, +0x5d, 0x5d, 0x10, 0xed, 0x11, 0x33, 0x10, 0xed, 0x32, 0x01, +0x10, 0xd6, 0xdd, 0x32, 0xfd, 0x32, 0xcd, 0x33, 0x10, 0xde, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x13, 0x33, 0x35, 0x33, 0x15, 0x33, 0x15, 0x23, 0x15, +0x3e, 0x03, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x26, 0x27, 0x11, 0x23, 0x13, 0x32, 0x36, 0x35, +0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0x15, 0x1e, 0x03, +0x12, 0x48, 0x52, 0x9e, 0x9e, 0x07, 0x19, 0x1e, 0x1f, 0x0c, +0x24, 0x42, 0x33, 0x1e, 0x1d, 0x35, 0x48, 0x2b, 0x2c, 0x5a, +0x27, 0x48, 0xf9, 0x30, 0x3f, 0x13, 0x1f, 0x28, 0x15, 0x16, +0x38, 0x11, 0x06, 0x16, 0x1b, 0x1d, 0x01, 0xaa, 0x3e, 0x3e, +0x3a, 0x51, 0x01, 0x04, 0x03, 0x02, 0x11, 0x24, 0x3a, 0x28, +0x2a, 0x3b, 0x26, 0x11, 0x09, 0x0b, 0x01, 0x66, 0xfe, 0xca, +0x29, 0x2e, 0x16, 0x20, 0x15, 0x0a, 0x03, 0x05, 0x9f, 0x01, +0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x49, +0x00, 0x00, 0x01, 0xc7, 0x02, 0x71, 0x00, 0x15, 0x00, 0x24, +0x00, 0xd5, 0xb6, 0x21, 0x10, 0x11, 0x12, 0x00, 0x4c, 0x21, +0xb8, 0xff, 0xf0, 0x40, 0x09, 0x10, 0x00, 0x4d, 0x0a, 0x10, +0x0e, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, +0x4d, 0x07, 0xb8, 0xff, 0xf0, 0xb3, 0x0c, 0x00, 0x4d, 0x07, +0xb8, 0xff, 0xe8, 0xb3, 0x0b, 0x00, 0x4d, 0x06, 0xb8, 0xff, +0xf0, 0xb3, 0x10, 0x00, 0x4d, 0x06, 0xb8, 0xff, 0xe0, 0xb4, +0x09, 0x0a, 0x00, 0x4c, 0x03, 0xb8, 0xff, 0xe0, 0xb3, 0x10, +0x00, 0x4d, 0x03, 0xb8, 0xff, 0xe8, 0xb3, 0x0f, 0x00, 0x4d, +0x03, 0xb8, 0xff, 0xe0, 0xb3, 0x0a, 0x00, 0x4d, 0x03, 0xb8, +0xff, 0xe8, 0xb3, 0x09, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe8, +0xb3, 0x10, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe0, 0x40, 0x31, +0x0f, 0x00, 0x4d, 0x1e, 0x0a, 0x1f, 0x09, 0x09, 0x21, 0x07, +0x20, 0x08, 0x20, 0x1f, 0x08, 0x1f, 0x08, 0x1f, 0x1a, 0x23, +0x76, 0x05, 0x26, 0x1a, 0x0f, 0x73, 0x00, 0x10, 0x01, 0x08, +0x10, 0x25, 0x0a, 0x09, 0x07, 0x0e, 0x79, 0x21, 0x20, 0x1e, +0x1a, 0x1a, 0x00, 0x10, 0x44, 0x16, 0x7c, 0x00, 0x41, 0x00, +0x3f, 0xed, 0x3f, 0x12, 0x39, 0x2f, 0x33, 0xcc, 0x33, 0xfd, +0x32, 0xce, 0x33, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, +0x10, 0xde, 0xed, 0x12, 0x39, 0x39, 0x2f, 0x2f, 0x11, 0x33, +0x11, 0x12, 0x39, 0x39, 0x33, 0x11, 0x12, 0x39, 0x39, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x32, 0x1e, 0x02, 0x15, +0x14, 0x07, 0x17, 0x07, 0x27, 0x06, 0x06, 0x23, 0x23, 0x15, +0x23, 0x11, 0x3e, 0x03, 0x17, 0x22, 0x06, 0x07, 0x15, 0x33, +0x32, 0x32, 0x37, 0x27, 0x37, 0x17, 0x36, 0x35, 0x34, 0xeb, +0x37, 0x53, 0x37, 0x1b, 0x61, 0x3f, 0x3a, 0x44, 0x11, 0x20, +0x13, 0x48, 0x52, 0x12, 0x2b, 0x2b, 0x29, 0x17, 0x1a, 0x30, +0x0c, 0x44, 0x0a, 0x11, 0x08, 0x2b, 0x38, 0x33, 0x31, 0x02, +0x71, 0x1c, 0x33, 0x46, 0x2b, 0x7c, 0x31, 0x6b, 0x21, 0x77, +0x03, 0x05, 0xe7, 0x02, 0x62, 0x04, 0x06, 0x04, 0x01, 0x47, +0x01, 0x02, 0xfa, 0x02, 0x4a, 0x22, 0x5a, 0x1e, 0x4f, 0x7c, +0x00, 0x02, 0x00, 0x47, 0xff, 0x5b, 0x01, 0xcc, 0x01, 0xda, +0x00, 0x16, 0x00, 0x29, 0x00, 0xb4, 0x40, 0x20, 0x1d, 0x38, +0x0f, 0x00, 0x4d, 0x1d, 0x18, 0x0e, 0x00, 0x4d, 0x1d, 0x10, +0x0d, 0x00, 0x4d, 0x19, 0x10, 0x11, 0x12, 0x00, 0x4c, 0x19, +0x10, 0x0d, 0x00, 0x4d, 0x15, 0x20, 0x0f, 0x00, 0x4d, 0x15, +0xb8, 0xff, 0xe8, 0xb4, 0x08, 0x09, 0x00, 0x4c, 0x14, 0xb8, +0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x03, 0xb8, 0xff, 0xe8, +0xb3, 0x0c, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, +0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe8, 0xb3, 0x0c, 0x00, 0x4d, +0x02, 0xb8, 0xff, 0xe0, 0x40, 0x30, 0x0b, 0x00, 0x4d, 0x06, +0x28, 0x05, 0x29, 0x05, 0x18, 0x03, 0x17, 0x04, 0x17, 0x29, +0x04, 0x29, 0x04, 0x29, 0x22, 0x1b, 0x82, 0x00, 0x2b, 0x22, +0x0d, 0x7f, 0x00, 0x0e, 0x01, 0x08, 0x0e, 0x2a, 0x1e, 0x88, +0x12, 0x50, 0x0e, 0x4b, 0x28, 0x18, 0x17, 0x25, 0x88, 0x06, +0x05, 0x03, 0x09, 0x51, 0x00, 0x3f, 0x33, 0xce, 0x33, 0xfd, +0xcc, 0x33, 0x33, 0x3f, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0x5e, +0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, 0x12, 0x39, 0x39, 0x2f, +0x2f, 0x11, 0x33, 0x11, 0x12, 0x39, 0x39, 0x33, 0x11, 0x12, +0x39, 0x39, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x14, 0x06, 0x07, +0x17, 0x07, 0x27, 0x06, 0x06, 0x23, 0x22, 0x26, 0x27, 0x15, +0x23, 0x11, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x07, 0x17, +0x36, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x11, +0x16, 0x16, 0x33, 0x32, 0x32, 0x37, 0x27, 0x01, 0xcc, 0x2c, +0x27, 0x34, 0x38, 0x34, 0x0e, 0x1e, 0x10, 0x25, 0x38, 0x0e, +0x53, 0x1b, 0x55, 0x37, 0x32, 0x52, 0x3a, 0x20, 0xaf, 0x35, +0x14, 0x11, 0x4c, 0x3d, 0x22, 0x27, 0x0b, 0x0e, 0x36, 0x1d, +0x09, 0x0f, 0x09, 0x36, 0xe7, 0x42, 0x66, 0x20, 0x59, 0x20, +0x5a, 0x05, 0x06, 0x12, 0x0b, 0xb7, 0x02, 0x67, 0x08, 0x10, +0x22, 0x3f, 0x5a, 0x61, 0x5d, 0x17, 0x46, 0x29, 0x51, 0x59, +0x06, 0x04, 0xfe, 0xdb, 0x0d, 0x16, 0x01, 0x5d, 0x00, 0x01, +0x00, 0x36, 0x00, 0x00, 0x01, 0xcc, 0x02, 0xe1, 0x00, 0x0b, +0x00, 0x28, 0x40, 0x14, 0x02, 0x73, 0x05, 0x0d, 0x08, 0x07, +0x73, 0x00, 0x0b, 0x0c, 0x07, 0x00, 0x79, 0x0a, 0x44, 0x06, +0x79, 0x03, 0x01, 0x41, 0x00, 0x3f, 0xce, 0xed, 0x3f, 0xed, +0x32, 0x01, 0x10, 0xd6, 0xdd, 0xfd, 0xcd, 0x10, 0xde, 0xed, +0x31, 0x30, 0x37, 0x11, 0x33, 0x35, 0x33, 0x15, 0x23, 0x11, +0x33, 0x15, 0x21, 0x35, 0x8f, 0xee, 0x4f, 0xeb, 0x86, 0xfe, +0xcf, 0x46, 0x02, 0x25, 0x76, 0xbc, 0xfe, 0x21, 0x46, 0x46, +0x00, 0x00, 0x00, 0x01, 0x00, 0x6b, 0x00, 0x00, 0x01, 0xb8, +0x02, 0x44, 0x00, 0x07, 0x00, 0x1f, 0x40, 0x0f, 0x02, 0x7f, +0x05, 0x09, 0x07, 0x7f, 0x00, 0x08, 0x06, 0x85, 0x03, 0x01, +0x49, 0x00, 0x4a, 0x00, 0x3f, 0x3f, 0xce, 0xed, 0x01, 0x10, +0xd6, 0xed, 0x10, 0xde, 0xed, 0x31, 0x30, 0x33, 0x11, 0x21, +0x35, 0x33, 0x15, 0x23, 0x11, 0x6b, 0x01, 0x02, 0x4b, 0xfb, +0x01, 0xd0, 0x74, 0xb9, 0xfe, 0x75, 0x00, 0x01, 0x00, 0x36, +0x00, 0x00, 0x01, 0xcc, 0x02, 0x6b, 0x00, 0x11, 0x00, 0x3e, +0x40, 0x1f, 0x07, 0x13, 0x0b, 0x0b, 0x0e, 0x09, 0x0d, 0x73, +0x04, 0x00, 0x11, 0x02, 0x02, 0x11, 0x12, 0x0c, 0x01, 0x79, +0x09, 0x04, 0x04, 0x05, 0x0d, 0x00, 0x79, 0x10, 0x44, 0x08, +0x79, 0x05, 0x41, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x32, 0x11, +0x39, 0x2f, 0x33, 0xed, 0x32, 0x01, 0x10, 0xc6, 0x32, 0x2f, +0x10, 0xdd, 0x32, 0xfd, 0x32, 0xcd, 0x32, 0x2f, 0x10, 0xce, +0x31, 0x30, 0x37, 0x35, 0x23, 0x35, 0x33, 0x11, 0x21, 0x15, +0x23, 0x15, 0x33, 0x15, 0x23, 0x15, 0x33, 0x15, 0x21, 0x35, +0x8f, 0x59, 0x59, 0x01, 0x3d, 0xeb, 0x86, 0x86, 0x86, 0xfe, +0xcf, 0x46, 0xd6, 0x43, 0x01, 0x0c, 0x46, 0xc6, 0x43, 0xd6, +0x46, 0x46, 0x00, 0x01, 0x00, 0x21, 0x00, 0x00, 0x01, 0xb8, +0x01, 0xd0, 0x00, 0x0d, 0x00, 0x2f, 0x40, 0x17, 0x07, 0x0f, +0x0b, 0x09, 0x0c, 0x7f, 0x04, 0x01, 0x02, 0x0e, 0x0c, 0x01, +0x86, 0x09, 0x04, 0x04, 0x00, 0x08, 0x85, 0x05, 0x49, 0x00, +0x4a, 0x00, 0x3f, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0x33, 0xed, +0x32, 0x01, 0x10, 0xd6, 0xdd, 0x32, 0xfd, 0x32, 0xcd, 0x10, +0xce, 0x31, 0x30, 0x33, 0x35, 0x23, 0x35, 0x33, 0x35, 0x21, +0x15, 0x23, 0x15, 0x33, 0x15, 0x23, 0x15, 0x6b, 0x4a, 0x4a, +0x01, 0x4d, 0xfb, 0x9e, 0x9e, 0xb7, 0x3f, 0xda, 0x45, 0x95, +0x3f, 0xb7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2d, 0xff, 0x5b, +0x01, 0xd0, 0x02, 0x6b, 0x00, 0x2b, 0x00, 0x72, 0xb9, 0x00, +0x2a, 0xff, 0xe8, 0x40, 0x22, 0x08, 0x00, 0x4d, 0x14, 0x18, +0x0e, 0x00, 0x4d, 0x14, 0x10, 0x0d, 0x00, 0x4d, 0x0f, 0x18, +0x11, 0x00, 0x4d, 0x0e, 0x18, 0x11, 0x00, 0x4d, 0x0e, 0x18, +0x0e, 0x00, 0x4d, 0x0e, 0x10, 0x0d, 0x00, 0x4d, 0x02, 0xb8, +0xff, 0xe8, 0x40, 0x22, 0x08, 0x00, 0x4d, 0x20, 0x20, 0x11, +0x76, 0x00, 0x2d, 0x22, 0x1c, 0x73, 0x1d, 0x0f, 0x08, 0x01, +0x08, 0x08, 0x1d, 0x2c, 0x16, 0x7c, 0x27, 0x27, 0x1d, 0x21, +0x79, 0x1e, 0x41, 0x1d, 0x44, 0x0c, 0x7c, 0x05, 0x00, 0x2f, +0xed, 0x3f, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, +0xc6, 0x32, 0x2f, 0x5d, 0x10, 0xed, 0x32, 0x10, 0xde, 0xed, +0x33, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x25, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x22, 0x27, +0x37, 0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, +0x02, 0x23, 0x22, 0x0e, 0x02, 0x07, 0x11, 0x23, 0x11, 0x21, +0x15, 0x21, 0x15, 0x3e, 0x03, 0x33, 0x32, 0x1e, 0x02, 0x01, +0xd0, 0x1d, 0x39, 0x55, 0x37, 0x0d, 0x1a, 0x0b, 0x02, 0x05, +0x0f, 0x0d, 0x22, 0x39, 0x2a, 0x18, 0x17, 0x2a, 0x39, 0x22, +0x0e, 0x1e, 0x1a, 0x15, 0x06, 0x52, 0x01, 0x63, 0xfe, 0xef, +0x07, 0x18, 0x1e, 0x1f, 0x0e, 0x3a, 0x57, 0x3a, 0x1c, 0x71, +0x39, 0x66, 0x4b, 0x2c, 0x02, 0x43, 0x01, 0x01, 0x1b, 0x35, +0x4f, 0x34, 0x37, 0x4e, 0x32, 0x18, 0x03, 0x05, 0x05, 0x02, +0xfe, 0xcf, 0x02, 0x6b, 0x46, 0xb1, 0x03, 0x06, 0x05, 0x03, +0x27, 0x48, 0x66, 0x00, 0x00, 0x01, 0x00, 0x47, 0xff, 0x5a, +0x01, 0xcf, 0x01, 0xd0, 0x00, 0x23, 0x00, 0x7c, 0x40, 0x15, +0x14, 0x18, 0x10, 0x00, 0x4d, 0x14, 0x10, 0x0f, 0x00, 0x4d, +0x10, 0x10, 0x10, 0x00, 0x4d, 0x10, 0x18, 0x0f, 0x00, 0x4d, +0x02, 0xb8, 0xff, 0xe0, 0xb3, 0x09, 0x00, 0x4d, 0x02, 0xb8, +0xff, 0xd8, 0xb3, 0x08, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xe8, +0x40, 0x2c, 0x0a, 0x00, 0x4d, 0x1d, 0x1d, 0x12, 0x82, 0x03, +0x25, 0x1f, 0x19, 0x7f, 0x1a, 0x20, 0x0b, 0x01, 0x0f, 0x0b, +0x1f, 0x0b, 0x02, 0x0b, 0x0b, 0x00, 0x1a, 0x01, 0x08, 0x1a, +0x24, 0x15, 0x89, 0x00, 0x00, 0x1a, 0x1e, 0x86, 0x1b, 0x49, +0x1a, 0x4a, 0x0f, 0x89, 0x08, 0x4b, 0x00, 0x3f, 0xed, 0x3f, +0x3f, 0xed, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xc6, 0x5e, +0x5d, 0x32, 0x2f, 0x5d, 0x5d, 0x10, 0xed, 0x32, 0x10, 0xde, +0xed, 0x33, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x01, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, +0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x15, 0x23, 0x11, 0x21, +0x15, 0x23, 0x15, 0x3e, 0x03, 0x01, 0x05, 0x6a, 0x60, 0x18, +0x30, 0x47, 0x2f, 0x0a, 0x16, 0x08, 0x05, 0x05, 0x0b, 0x08, +0x39, 0x3e, 0x42, 0x46, 0x14, 0x34, 0x13, 0x53, 0x01, 0x46, +0xf3, 0x07, 0x19, 0x1e, 0x1f, 0x01, 0x1e, 0x75, 0x6b, 0x30, +0x54, 0x3d, 0x23, 0x01, 0x02, 0x42, 0x01, 0x01, 0x4d, 0x54, +0x55, 0x47, 0x06, 0x05, 0xcf, 0x01, 0xd0, 0x44, 0x7d, 0x03, +0x05, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, +0xff, 0x5b, 0x01, 0xeb, 0x02, 0x6b, 0x00, 0x31, 0x00, 0xc1, +0x40, 0x6e, 0x0f, 0x0c, 0x01, 0x00, 0x21, 0x10, 0x21, 0x20, +0x21, 0x03, 0x08, 0x21, 0x21, 0x1c, 0x2b, 0x30, 0x2b, 0x78, +0x26, 0x21, 0x14, 0x26, 0x26, 0x21, 0x21, 0x1b, 0x18, 0x1b, +0x78, 0x1c, 0x21, 0x14, 0x1c, 0x1c, 0x21, 0x0c, 0x0c, 0x07, +0x12, 0x15, 0x12, 0x78, 0x11, 0x0c, 0x14, 0x11, 0x11, 0x0c, +0x30, 0x18, 0x31, 0x73, 0x00, 0x0c, 0x06, 0x01, 0x06, 0x78, +0x07, 0x0c, 0x14, 0x07, 0x07, 0x0c, 0x01, 0x15, 0x00, 0x00, +0x26, 0x07, 0x1c, 0x1c, 0x26, 0x26, 0x2a, 0x73, 0x27, 0x33, +0x11, 0x11, 0x07, 0x32, 0x29, 0x26, 0x79, 0x2b, 0x44, 0x1c, +0x1b, 0x41, 0x18, 0x15, 0x15, 0x0c, 0x30, 0x01, 0x01, 0x21, +0x0c, 0x0c, 0x16, 0x41, 0x11, 0x12, 0x41, 0x07, 0x06, 0x44, +0x00, 0x44, 0x00, 0x3f, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0x39, +0x11, 0x33, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x3f, +0x33, 0x3f, 0xed, 0xce, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, +0xde, 0xed, 0x33, 0x2f, 0x33, 0x2f, 0x11, 0x12, 0x39, 0x2f, +0x33, 0x33, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, +0x10, 0xed, 0x32, 0x32, 0x87, 0x10, 0x2b, 0x87, 0x08, 0x7d, +0xc4, 0x87, 0x05, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x87, +0x18, 0x10, 0x2b, 0x87, 0x08, 0x7d, 0xc4, 0x01, 0x5e, 0x5d, +0x5d, 0x31, 0x30, 0x33, 0x11, 0x0e, 0x03, 0x07, 0x23, 0x3e, +0x03, 0x37, 0x2e, 0x03, 0x27, 0x33, 0x16, 0x16, 0x17, 0x11, +0x33, 0x11, 0x36, 0x36, 0x37, 0x33, 0x0e, 0x03, 0x07, 0x1e, +0x03, 0x17, 0x33, 0x15, 0x23, 0x35, 0x23, 0x2e, 0x03, 0x27, +0x11, 0xc3, 0x11, 0x1e, 0x1c, 0x18, 0x0a, 0x52, 0x0a, 0x1e, +0x23, 0x26, 0x13, 0x0e, 0x20, 0x20, 0x1f, 0x0d, 0x52, 0x18, +0x31, 0x1a, 0x49, 0x1d, 0x36, 0x1c, 0x52, 0x0e, 0x21, 0x23, +0x23, 0x0f, 0x11, 0x21, 0x20, 0x1c, 0x0c, 0x28, 0x4e, 0x18, +0x0b, 0x1b, 0x1f, 0x22, 0x12, 0x01, 0x2e, 0x18, 0x47, 0x51, +0x56, 0x28, 0x2d, 0x5d, 0x56, 0x4d, 0x1e, 0x1e, 0x46, 0x4b, +0x4d, 0x24, 0x4d, 0x86, 0x39, 0x01, 0x0c, 0xfe, 0xf4, 0x39, +0x85, 0x4e, 0x23, 0x4b, 0x4b, 0x48, 0x1f, 0x19, 0x3e, 0x44, +0x48, 0x22, 0xeb, 0xa5, 0x28, 0x57, 0x51, 0x47, 0x18, 0xfe, +0xd1, 0x00, 0x00, 0x01, 0x00, 0x07, 0xff, 0x7f, 0x01, 0xe0, +0x01, 0xd0, 0x00, 0x31, 0x00, 0xb6, 0x40, 0x68, 0x0f, 0x24, +0x01, 0x00, 0x09, 0x10, 0x09, 0x20, 0x09, 0x03, 0x08, 0x11, +0x0c, 0x09, 0x03, 0x00, 0x03, 0x81, 0x04, 0x09, 0x14, 0x04, +0x04, 0x09, 0x24, 0x24, 0x1f, 0x2a, 0x2f, 0x2a, 0x81, 0x29, +0x24, 0x14, 0x29, 0x29, 0x24, 0x00, 0x16, 0x7f, 0x19, 0x24, +0x1e, 0x19, 0x1e, 0x81, 0x1f, 0x24, 0x14, 0x1f, 0x1f, 0x24, +0x2f, 0xa0, 0x19, 0xb0, 0x19, 0x02, 0x19, 0x19, 0x0c, 0x1f, +0x04, 0x04, 0x0c, 0x0c, 0x10, 0x7f, 0x0d, 0x33, 0x29, 0x29, +0x1f, 0x32, 0x00, 0x2f, 0x2f, 0x24, 0x16, 0x19, 0x19, 0x09, +0x24, 0x24, 0x18, 0x30, 0x49, 0x29, 0x2a, 0x49, 0x1f, 0x1e, +0x4a, 0x18, 0x4a, 0x0f, 0x0f, 0x0c, 0x85, 0x11, 0x4a, 0x04, +0x03, 0x49, 0x00, 0x3f, 0x33, 0x3f, 0xed, 0x33, 0x2f, 0x3f, +0x3f, 0x33, 0x3f, 0x33, 0x3f, 0x12, 0x39, 0x11, 0x33, 0x33, +0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x01, 0x10, 0xc6, 0x32, +0x2f, 0x10, 0xde, 0xed, 0x33, 0x2f, 0x33, 0x2f, 0x11, 0x12, +0x39, 0x2f, 0x5d, 0x33, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x01, 0x18, 0x10, 0xed, 0x32, 0x87, 0x10, 0x2b, 0x87, 0x08, +0x7d, 0xc4, 0x87, 0x05, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x01, 0x11, 0x33, 0x5e, 0x5d, 0x5d, 0x31, 0x30, 0x01, 0x36, +0x36, 0x37, 0x33, 0x0e, 0x03, 0x07, 0x16, 0x16, 0x17, 0x33, +0x15, 0x23, 0x35, 0x23, 0x2e, 0x03, 0x27, 0x15, 0x23, 0x35, +0x0e, 0x03, 0x07, 0x23, 0x3e, 0x03, 0x37, 0x2e, 0x03, 0x27, +0x33, 0x1e, 0x03, 0x17, 0x35, 0x33, 0x01, 0x15, 0x17, 0x34, +0x13, 0x53, 0x0d, 0x20, 0x23, 0x25, 0x12, 0x22, 0x3e, 0x18, +0x29, 0x4f, 0x0a, 0x09, 0x1b, 0x1f, 0x20, 0x0f, 0x49, 0x0f, +0x20, 0x1f, 0x1b, 0x0a, 0x52, 0x0c, 0x22, 0x27, 0x28, 0x14, +0x0f, 0x23, 0x22, 0x1e, 0x0b, 0x52, 0x09, 0x18, 0x19, 0x1a, +0x0b, 0x49, 0x01, 0x15, 0x2b, 0x67, 0x29, 0x15, 0x37, 0x3a, +0x3c, 0x19, 0x24, 0x5c, 0x2f, 0xc7, 0x81, 0x19, 0x38, 0x37, +0x33, 0x14, 0xcf, 0xda, 0x14, 0x34, 0x3b, 0x3c, 0x1b, 0x20, +0x44, 0x42, 0x3a, 0x15, 0x18, 0x3a, 0x3c, 0x38, 0x15, 0x16, +0x34, 0x36, 0x34, 0x15, 0xc9, 0x00, 0x00, 0x01, 0x00, 0x26, +0xff, 0x57, 0x01, 0xd1, 0x02, 0x76, 0x00, 0x4c, 0x01, 0x48, +0xb9, 0x00, 0x49, 0xff, 0xf0, 0xb3, 0x13, 0x00, 0x4d, 0x49, +0xb8, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x49, 0xb8, 0xff, +0xd8, 0xb3, 0x11, 0x00, 0x4d, 0x49, 0xb8, 0xff, 0xe0, 0xb3, +0x08, 0x00, 0x4d, 0x45, 0xb8, 0xff, 0xe0, 0xb4, 0x11, 0x12, +0x00, 0x4c, 0x41, 0xb8, 0xff, 0xe0, 0xb4, 0x11, 0x12, 0x00, +0x4c, 0x3d, 0xb8, 0xff, 0xf0, 0xb3, 0x13, 0x00, 0x4d, 0x3d, +0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, 0x3d, 0xb8, 0xff, +0xe8, 0x40, 0x2f, 0x08, 0x0a, 0x00, 0x4c, 0x38, 0x10, 0x12, +0x00, 0x4d, 0x38, 0x18, 0x11, 0x00, 0x4d, 0x32, 0x28, 0x11, +0x00, 0x4d, 0x2e, 0x10, 0x0f, 0x10, 0x00, 0x4c, 0x2e, 0x18, +0x0e, 0x00, 0x4d, 0x25, 0x18, 0x10, 0x00, 0x4d, 0x21, 0x20, +0x10, 0x00, 0x4d, 0x1a, 0x18, 0x0d, 0x11, 0x00, 0x4c, 0x05, +0xb8, 0xff, 0xe8, 0xb3, 0x15, 0x00, 0x4d, 0x05, 0xb8, 0xff, +0xe0, 0xb3, 0x14, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb4, +0x12, 0x13, 0x00, 0x4c, 0x05, 0xb8, 0xff, 0xe0, 0xb3, 0x11, +0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb4, 0x0f, 0x10, 0x00, +0x4c, 0x02, 0xb8, 0xff, 0xd8, 0xb4, 0x13, 0x14, 0x00, 0x4c, +0x02, 0xb8, 0xff, 0xd0, 0xb4, 0x10, 0x12, 0x00, 0x4c, 0x02, +0xb8, 0xff, 0xd8, 0x40, 0x0b, 0x0f, 0x00, 0x4d, 0x42, 0x30, +0x76, 0x3f, 0x3f, 0x47, 0x11, 0x03, 0xb8, 0xff, 0xc0, 0x40, +0x33, 0x0b, 0x0e, 0x48, 0x03, 0x4c, 0x00, 0x17, 0x0f, 0x0b, +0x01, 0x08, 0x0b, 0x14, 0x14, 0x1c, 0x23, 0x76, 0x47, 0x4e, +0x37, 0x37, 0x29, 0x29, 0x1c, 0x4d, 0x00, 0x14, 0x14, 0x17, +0x0f, 0x08, 0x4d, 0x36, 0x36, 0x33, 0x7c, 0x3a, 0x42, 0x29, +0x79, 0x2a, 0x2a, 0x3a, 0x45, 0x1d, 0x1d, 0x20, 0x7c, 0x4c, +0x17, 0x46, 0x00, 0x3f, 0x33, 0xed, 0x32, 0x2f, 0x3f, 0x39, +0x2f, 0xed, 0x39, 0x10, 0xed, 0x32, 0x2f, 0x10, 0xdc, 0xcd, +0x12, 0x39, 0x2f, 0xcd, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x32, +0x2f, 0x10, 0xde, 0xed, 0x12, 0x39, 0x2f, 0xcc, 0x5e, 0x5d, +0x33, 0xdd, 0x32, 0xd5, 0x2b, 0xcd, 0x11, 0x33, 0x2f, 0xed, +0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x17, 0x16, +0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, +0x16, 0x16, 0x33, 0x32, 0x35, 0x34, 0x27, 0x27, 0x36, 0x36, +0x37, 0x2e, 0x03, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, +0x35, 0x34, 0x2e, 0x02, 0x23, 0x23, 0x35, 0x33, 0x32, 0x3e, +0x02, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, +0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, 0x1e, +0x03, 0x15, 0x14, 0x0e, 0x02, 0x07, 0xfe, 0x1a, 0x17, 0x09, +0x15, 0x23, 0x1a, 0x17, 0x28, 0x0b, 0x0a, 0x0b, 0x18, 0x0f, +0x20, 0x25, 0x07, 0x04, 0x0c, 0x06, 0x1f, 0x36, 0x2b, 0x21, +0x09, 0x19, 0x15, 0x54, 0x39, 0x48, 0x56, 0x20, 0x36, 0x49, +0x29, 0x2a, 0x21, 0x1e, 0x40, 0x35, 0x22, 0x43, 0x36, 0x30, +0x4f, 0x14, 0x1b, 0x17, 0x60, 0x38, 0x2c, 0x4b, 0x36, 0x1e, +0x37, 0x36, 0x1b, 0x31, 0x26, 0x16, 0x1c, 0x34, 0x4a, 0x2e, +0x21, 0x0c, 0x1e, 0x1d, 0x0a, 0x17, 0x13, 0x0d, 0x07, 0x05, +0x33, 0x04, 0x05, 0x14, 0x14, 0x0b, 0x02, 0x0b, 0x1b, 0x0d, +0x01, 0x0a, 0x0d, 0x0e, 0x05, 0x42, 0x0b, 0x1d, 0x35, 0x3e, +0x24, 0x2f, 0x1a, 0x0a, 0x46, 0x09, 0x18, 0x29, 0x20, 0x29, +0x33, 0x15, 0x0b, 0x41, 0x0f, 0x16, 0x13, 0x27, 0x3d, 0x29, +0x2b, 0x4c, 0x11, 0x07, 0x1a, 0x28, 0x36, 0x24, 0x2d, 0x41, +0x2c, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x48, +0xff, 0x57, 0x01, 0xbf, 0x01, 0xdc, 0x00, 0x45, 0x00, 0xd6, +0xb9, 0x00, 0x42, 0xff, 0xe0, 0xb3, 0x0b, 0x00, 0x4d, 0x42, +0xb8, 0xff, 0xd8, 0xb4, 0x09, 0x0a, 0x00, 0x4c, 0x37, 0xb8, +0xff, 0xe8, 0xb4, 0x0b, 0x0c, 0x00, 0x4c, 0x37, 0xb8, 0xff, +0xe0, 0xb3, 0x0a, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe0, 0xb4, +0x13, 0x14, 0x00, 0x4c, 0x05, 0xb8, 0xff, 0xd8, 0xb4, 0x11, +0x12, 0x00, 0x4c, 0x05, 0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, +0x4d, 0x05, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x02, +0xb8, 0xff, 0xd0, 0xb4, 0x10, 0x14, 0x00, 0x4c, 0x02, 0xb8, +0xff, 0xd8, 0x40, 0x0b, 0x0f, 0x00, 0x4d, 0x3e, 0x2a, 0x82, +0x39, 0x39, 0x41, 0x11, 0x03, 0xb8, 0xff, 0xc0, 0x40, 0x35, +0x0b, 0x0e, 0x48, 0x03, 0x44, 0x00, 0x17, 0x0f, 0x0b, 0x01, +0x0b, 0x14, 0x14, 0x1a, 0x21, 0x82, 0x41, 0x47, 0x31, 0x31, +0x25, 0x25, 0x00, 0x1a, 0x01, 0x08, 0x1a, 0x46, 0x00, 0x14, +0x14, 0x17, 0x0f, 0x08, 0x46, 0x30, 0x30, 0x2d, 0x88, 0x34, +0x3e, 0x25, 0x86, 0x26, 0x26, 0x34, 0x50, 0x1b, 0x1e, 0x88, +0x44, 0x17, 0x51, 0x00, 0x3f, 0x33, 0xed, 0x32, 0x3f, 0x39, +0x2f, 0xed, 0x39, 0x10, 0xed, 0x32, 0x2f, 0x10, 0xdc, 0xcd, +0x12, 0x39, 0x2f, 0xcd, 0x01, 0x10, 0xc6, 0x5e, 0x5d, 0x32, +0x2f, 0x32, 0x2f, 0x10, 0xde, 0xed, 0x12, 0x39, 0x2f, 0xcc, +0x5d, 0x33, 0xdd, 0x32, 0xd5, 0x2b, 0xcd, 0x11, 0x33, 0x2f, +0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x17, 0x16, 0x16, 0x15, 0x14, 0x0e, +0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, +0x35, 0x34, 0x27, 0x27, 0x36, 0x36, 0x37, 0x26, 0x26, 0x27, +0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, +0x23, 0x35, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, +0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, +0x14, 0x0e, 0x02, 0x07, 0x16, 0x16, 0x15, 0x14, 0x06, 0x07, +0x06, 0xfe, 0x1a, 0x17, 0x09, 0x15, 0x23, 0x1a, 0x17, 0x28, +0x0b, 0x0a, 0x0b, 0x18, 0x0f, 0x20, 0x25, 0x07, 0x04, 0x0c, +0x06, 0x31, 0x47, 0x10, 0x11, 0x0f, 0x4e, 0x37, 0x42, 0x3c, +0x3c, 0x33, 0x62, 0x5c, 0x33, 0x32, 0x38, 0x3c, 0x1c, 0x49, +0x1a, 0x12, 0x21, 0x4f, 0x27, 0x26, 0x46, 0x36, 0x20, 0x0e, +0x16, 0x19, 0x0c, 0x26, 0x33, 0x61, 0x54, 0x07, 0x21, 0x0c, +0x1e, 0x1d, 0x0a, 0x17, 0x13, 0x0d, 0x07, 0x05, 0x33, 0x04, +0x05, 0x14, 0x14, 0x0b, 0x02, 0x0b, 0x1c, 0x0d, 0x02, 0x0f, +0x08, 0x46, 0x05, 0x13, 0x26, 0x20, 0x24, 0x2a, 0x42, 0x22, +0x1d, 0x1f, 0x24, 0x0e, 0x0c, 0x49, 0x0b, 0x0d, 0x0d, 0x20, +0x33, 0x26, 0x12, 0x20, 0x1a, 0x12, 0x04, 0x0e, 0x35, 0x30, +0x3e, 0x48, 0x05, 0x0b, 0x00, 0x01, 0x00, 0x40, 0xff, 0x5b, +0x01, 0xd9, 0x02, 0x6b, 0x00, 0x18, 0x00, 0x65, 0x40, 0x39, +0x03, 0x03, 0x06, 0x18, 0x15, 0x18, 0x78, 0x00, 0x03, 0x14, +0x00, 0x00, 0x03, 0x0b, 0x03, 0x06, 0x03, 0x78, 0x10, 0x0b, +0x14, 0x10, 0x10, 0x0b, 0x00, 0x00, 0x06, 0x0a, 0x73, 0x07, +0x1a, 0x15, 0x10, 0x73, 0x00, 0x12, 0x01, 0x08, 0x12, 0x19, +0x00, 0x18, 0x41, 0x15, 0x10, 0x03, 0x03, 0x12, 0x13, 0x41, +0x12, 0x44, 0x09, 0x06, 0x79, 0x0b, 0x44, 0x00, 0x3f, 0xed, +0xce, 0x3f, 0x3f, 0x12, 0x39, 0x11, 0x33, 0x33, 0x3f, 0x33, +0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, +0xc5, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x87, +0x18, 0x10, 0x2b, 0x87, 0x08, 0x7d, 0xc4, 0x31, 0x30, 0x01, +0x06, 0x06, 0x07, 0x16, 0x16, 0x17, 0x33, 0x15, 0x23, 0x35, +0x23, 0x2e, 0x03, 0x27, 0x11, 0x23, 0x11, 0x33, 0x11, 0x36, +0x36, 0x37, 0x01, 0xd6, 0x31, 0x75, 0x44, 0x35, 0x66, 0x2a, +0x28, 0x4e, 0x16, 0x19, 0x32, 0x38, 0x3d, 0x23, 0x52, 0x52, +0x41, 0x77, 0x2d, 0x02, 0x6b, 0x49, 0x90, 0x48, 0x2d, 0x87, +0x50, 0xeb, 0xa5, 0x2e, 0x58, 0x4c, 0x3f, 0x17, 0xfe, 0xd8, +0x02, 0x6b, 0xfe, 0xec, 0x43, 0x92, 0x3f, 0x00, 0x00, 0x01, +0x00, 0x47, 0xff, 0x7f, 0x01, 0xd0, 0x01, 0xd0, 0x00, 0x1a, +0x00, 0x3c, 0x40, 0x1e, 0x18, 0x18, 0x05, 0x09, 0x7f, 0x06, +0x1c, 0x14, 0x0f, 0x7f, 0x11, 0x1b, 0x18, 0x17, 0x17, 0x12, +0x0f, 0x00, 0x14, 0x14, 0x11, 0x12, 0x49, 0x11, 0x4a, 0x08, +0x05, 0x85, 0x0a, 0x4a, 0x00, 0x3f, 0xed, 0xce, 0x3f, 0x3f, +0x12, 0x39, 0x11, 0x33, 0x33, 0x11, 0x33, 0x2f, 0x33, 0x01, +0x10, 0xd6, 0xed, 0x32, 0x10, 0xde, 0xed, 0xc5, 0x32, 0x2f, +0x31, 0x30, 0x37, 0x1e, 0x03, 0x17, 0x33, 0x15, 0x23, 0x35, +0x23, 0x2e, 0x03, 0x27, 0x15, 0x23, 0x11, 0x33, 0x15, 0x36, +0x36, 0x37, 0x33, 0x06, 0x06, 0xee, 0x13, 0x30, 0x31, 0x31, +0x15, 0x28, 0x4e, 0x09, 0x13, 0x38, 0x3d, 0x3e, 0x19, 0x53, +0x53, 0x37, 0x6e, 0x2c, 0x61, 0x2b, 0x79, 0xff, 0x0f, 0x29, +0x31, 0x36, 0x1a, 0xc7, 0x81, 0x1f, 0x41, 0x3c, 0x32, 0x11, +0xdf, 0x01, 0xd0, 0xc2, 0x30, 0x5f, 0x33, 0x33, 0x6c, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x30, 0x00, 0x00, 0x01, 0xeb, +0x02, 0x6b, 0x00, 0x1e, 0x00, 0x7e, 0x40, 0x46, 0x00, 0x03, +0x01, 0x08, 0x05, 0x05, 0x08, 0x1e, 0x19, 0x1e, 0x78, 0x00, +0x05, 0x14, 0x00, 0x00, 0x05, 0x09, 0x05, 0x08, 0x05, 0x78, +0x0c, 0x09, 0x14, 0x0c, 0x09, 0x19, 0x0c, 0x16, 0xaf, 0x0f, +0xbf, 0x0f, 0x02, 0x0f, 0x0f, 0x12, 0x00, 0x00, 0x08, 0x20, +0x15, 0x11, 0x73, 0x12, 0x1f, 0x00, 0x1e, 0x41, 0x0e, 0x0e, +0x0c, 0x10, 0x15, 0x19, 0x15, 0x17, 0x17, 0x05, 0x15, 0x15, +0x12, 0x13, 0x41, 0x12, 0x44, 0x08, 0x09, 0x44, 0x00, 0x3f, +0x33, 0x3f, 0x3f, 0x12, 0x39, 0x2f, 0x33, 0x33, 0x2f, 0x11, +0x33, 0x10, 0xcd, 0x32, 0x32, 0x2f, 0x3f, 0x33, 0x01, 0x10, +0xd6, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, 0x11, 0x39, 0x2f, +0x5d, 0x33, 0xdd, 0x32, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x87, +0x18, 0x10, 0x2b, 0x87, 0x08, 0x7d, 0xc4, 0x31, 0x30, 0x01, +0x5e, 0x5d, 0x01, 0x0e, 0x03, 0x07, 0x16, 0x16, 0x17, 0x23, +0x26, 0x26, 0x27, 0x15, 0x23, 0x35, 0x23, 0x11, 0x23, 0x11, +0x33, 0x11, 0x33, 0x35, 0x33, 0x15, 0x3e, 0x03, 0x37, 0x01, +0xd6, 0x0b, 0x1b, 0x25, 0x31, 0x21, 0x30, 0x55, 0x2d, 0x5d, +0x2c, 0x4e, 0x26, 0x41, 0x2b, 0x52, 0x52, 0x2b, 0x41, 0x1c, +0x2a, 0x1f, 0x19, 0x0b, 0x02, 0x6b, 0x21, 0x3f, 0x44, 0x4d, +0x30, 0x3c, 0x9e, 0x70, 0x6a, 0x91, 0x25, 0x89, 0x87, 0xfe, +0xe2, 0x02, 0x6b, 0xfe, 0xf6, 0x87, 0x86, 0x29, 0x45, 0x3e, +0x3c, 0x21, 0x00, 0x01, 0x00, 0x36, 0x00, 0x00, 0x01, 0xde, +0x01, 0xd0, 0x00, 0x22, 0x00, 0x84, 0x40, 0x4b, 0x00, 0x00, +0x10, 0x00, 0x20, 0x00, 0x03, 0x08, 0x00, 0x00, 0x1e, 0x06, +0x0b, 0x06, 0x81, 0x05, 0x00, 0x14, 0x05, 0x05, 0x00, 0x00, +0x1d, 0x18, 0x1d, 0x81, 0x1e, 0x00, 0x14, 0x1e, 0x00, 0x1e, +0x1e, 0x05, 0x18, 0x0b, 0x15, 0xaf, 0x0e, 0xbf, 0x0e, 0x02, +0x0e, 0x0e, 0x11, 0x05, 0x24, 0x14, 0x0f, 0x7f, 0x11, 0x23, +0x1e, 0x1d, 0x49, 0x0d, 0x0d, 0x0b, 0x0f, 0x14, 0x18, 0x14, +0x16, 0x16, 0x00, 0x14, 0x14, 0x11, 0x12, 0x49, 0x11, 0x4a, +0x05, 0x06, 0x4a, 0x00, 0x3f, 0x33, 0x3f, 0x3f, 0x12, 0x39, +0x2f, 0x33, 0x33, 0x2f, 0x11, 0x33, 0x10, 0xcd, 0x32, 0x32, +0x2f, 0x3f, 0x33, 0x01, 0x10, 0xd6, 0xed, 0x32, 0x10, 0xce, +0x11, 0x39, 0x2f, 0x5d, 0x33, 0xcd, 0x32, 0x11, 0x33, 0x2f, +0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, +0x08, 0x7d, 0xc4, 0x01, 0x5e, 0x5d, 0x31, 0x30, 0x25, 0x1e, +0x03, 0x17, 0x23, 0x2e, 0x03, 0x27, 0x15, 0x23, 0x35, 0x23, +0x15, 0x23, 0x11, 0x33, 0x15, 0x33, 0x35, 0x33, 0x15, 0x3e, +0x03, 0x37, 0x33, 0x0e, 0x03, 0x01, 0x2d, 0x18, 0x31, 0x2d, +0x29, 0x12, 0x62, 0x10, 0x21, 0x22, 0x24, 0x13, 0x3d, 0x2d, +0x52, 0x52, 0x2d, 0x3d, 0x15, 0x21, 0x1c, 0x19, 0x0e, 0x61, +0x14, 0x22, 0x25, 0x2a, 0xff, 0x17, 0x3c, 0x44, 0x47, 0x21, +0x1c, 0x3b, 0x37, 0x32, 0x13, 0x62, 0x65, 0xd6, 0x01, 0xd0, +0xc1, 0x67, 0x50, 0x1b, 0x2b, 0x27, 0x27, 0x16, 0x1c, 0x31, +0x30, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, +0x01, 0xeb, 0x02, 0x6b, 0x00, 0x1c, 0x00, 0x79, 0x40, 0x45, +0x03, 0x03, 0x06, 0x1c, 0x19, 0x1c, 0x78, 0x00, 0x03, 0x14, +0x00, 0x00, 0x03, 0x07, 0x03, 0x06, 0x03, 0x78, 0x0c, 0x07, +0x14, 0x0c, 0x0c, 0x07, 0x00, 0x00, 0x06, 0x1e, 0x0c, 0x19, +0x17, 0x15, 0x18, 0x73, 0x12, 0x10, 0x00, 0x0f, 0x01, 0x0f, +0x1d, 0x00, 0x1c, 0x41, 0x19, 0x0c, 0x03, 0x18, 0x0f, 0x15, +0x03, 0x0f, 0x12, 0x1f, 0x12, 0x2f, 0x12, 0x03, 0x08, 0x12, +0x12, 0x0e, 0x13, 0x41, 0x0e, 0x44, 0x06, 0x07, 0x44, 0x00, +0x3f, 0x33, 0x3f, 0x3f, 0x12, 0x39, 0x2f, 0x5e, 0x5d, 0x39, +0x33, 0xcd, 0x32, 0x11, 0x33, 0x33, 0x3f, 0x33, 0x01, 0x10, +0xd6, 0x5d, 0xcd, 0x33, 0xfd, 0x32, 0xcd, 0x33, 0x33, 0x10, +0xce, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x87, +0x18, 0x10, 0x2b, 0x87, 0x08, 0x7d, 0xc4, 0x31, 0x30, 0x01, +0x06, 0x06, 0x07, 0x16, 0x16, 0x17, 0x23, 0x2e, 0x03, 0x27, +0x11, 0x23, 0x11, 0x23, 0x35, 0x33, 0x35, 0x33, 0x15, 0x33, +0x15, 0x23, 0x15, 0x36, 0x36, 0x37, 0x01, 0xd6, 0x31, 0x60, +0x40, 0x40, 0x76, 0x30, 0x5d, 0x19, 0x32, 0x38, 0x3d, 0x23, +0x52, 0x47, 0x47, 0x52, 0x36, 0x36, 0x41, 0x63, 0x28, 0x02, +0x6b, 0x49, 0x8f, 0x49, 0x36, 0xad, 0x67, 0x2e, 0x58, 0x4c, +0x3f, 0x17, 0xfe, 0xd8, 0x01, 0xe5, 0x40, 0x46, 0x46, 0x40, +0x8e, 0x43, 0x91, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x12, +0x00, 0x00, 0x01, 0xde, 0x01, 0xe8, 0x00, 0x1f, 0x00, 0x80, +0x40, 0x48, 0x00, 0x00, 0x05, 0x1a, 0x18, 0x1a, 0x81, 0x1b, +0x00, 0x14, 0x1b, 0x1b, 0x00, 0x06, 0x00, 0x05, 0x00, 0x81, +0x0b, 0x06, 0x14, 0x0b, 0x06, 0x00, 0x0b, 0x1b, 0x1b, 0x05, +0x21, 0x0b, 0x18, 0x16, 0x14, 0x17, 0x7f, 0x11, 0x0f, 0x00, +0x0e, 0x01, 0x08, 0x0e, 0x20, 0x1b, 0x1a, 0x49, 0x17, 0x0e, +0x14, 0x11, 0x0b, 0x18, 0x14, 0x18, 0x24, 0x18, 0x02, 0x18, +0x11, 0x40, 0x08, 0x0d, 0x48, 0x11, 0x11, 0x0d, 0x12, 0x0d, +0x4a, 0x05, 0x06, 0x4a, 0x00, 0x3f, 0x33, 0x3f, 0x2f, 0x12, +0x39, 0x2f, 0x2b, 0x39, 0x5d, 0x11, 0x33, 0x11, 0x33, 0xcd, +0x32, 0x3f, 0x33, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xcd, 0x33, +0xfd, 0x32, 0xcd, 0x33, 0x33, 0x10, 0xce, 0x32, 0x2f, 0x10, +0x00, 0xc1, 0x87, 0x05, 0x2b, 0x87, 0x7d, 0xc4, 0x87, 0x18, +0x10, 0x2b, 0x87, 0x08, 0x7d, 0xc4, 0x31, 0x30, 0x25, 0x1e, +0x03, 0x17, 0x23, 0x2e, 0x03, 0x27, 0x15, 0x23, 0x11, 0x23, +0x35, 0x33, 0x35, 0x33, 0x15, 0x33, 0x15, 0x23, 0x15, 0x36, +0x37, 0x33, 0x0e, 0x03, 0x01, 0x00, 0x1b, 0x3e, 0x3d, 0x36, +0x12, 0x62, 0x13, 0x32, 0x38, 0x3a, 0x19, 0x52, 0x48, 0x48, +0x52, 0x37, 0x37, 0x67, 0x58, 0x61, 0x15, 0x33, 0x36, 0x36, +0xfd, 0x14, 0x3d, 0x45, 0x48, 0x1f, 0x1f, 0x41, 0x3c, 0x32, +0x11, 0xdf, 0x01, 0x70, 0x3a, 0x3e, 0x3e, 0x3a, 0x62, 0x5b, +0x67, 0x1a, 0x37, 0x37, 0x34, 0x00, 0x00, 0x01, 0x00, 0x12, +0x00, 0x00, 0x01, 0xeb, 0x02, 0x6b, 0x00, 0x18, 0x00, 0x64, +0x40, 0x37, 0x03, 0x03, 0x00, 0x09, 0x0e, 0x09, 0x78, 0x08, +0x03, 0x14, 0x08, 0x08, 0x03, 0x03, 0x00, 0x18, 0x15, 0x03, +0x15, 0x18, 0x78, 0x00, 0x03, 0x14, 0x00, 0x03, 0x00, 0x00, +0x08, 0x1a, 0x0e, 0x15, 0x73, 0x11, 0x00, 0x12, 0x01, 0x08, +0x12, 0x19, 0x00, 0x18, 0x41, 0x15, 0x0e, 0x10, 0x11, 0x79, +0x14, 0x41, 0x10, 0x44, 0x08, 0x09, 0x44, 0x00, 0x3f, 0x33, +0x3f, 0x3f, 0xed, 0x12, 0x39, 0x39, 0x3f, 0x33, 0x01, 0x10, +0xd6, 0x5e, 0x5d, 0xdd, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, +0x87, 0x2b, 0x10, 0x00, 0xc1, 0x87, 0x05, 0x7d, 0x10, 0xc4, +0x87, 0x18, 0x10, 0x2b, 0x87, 0x08, 0x7d, 0xc4, 0x31, 0x30, +0x01, 0x06, 0x06, 0x07, 0x1e, 0x03, 0x17, 0x23, 0x2e, 0x03, +0x27, 0x11, 0x23, 0x11, 0x23, 0x35, 0x33, 0x11, 0x36, 0x36, +0x37, 0x01, 0xd6, 0x24, 0x5c, 0x40, 0x19, 0x3a, 0x38, 0x35, +0x15, 0x5d, 0x14, 0x2f, 0x34, 0x38, 0x1d, 0x52, 0x5e, 0xb0, +0x3b, 0x57, 0x23, 0x02, 0x6b, 0x43, 0x8c, 0x52, 0x15, 0x47, +0x58, 0x64, 0x32, 0x32, 0x5c, 0x4e, 0x3b, 0x11, 0xfe, 0xd8, +0x02, 0x25, 0x46, 0xfe, 0xec, 0x48, 0x8a, 0x42, 0x00, 0x00, +0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x01, 0xde, 0x01, 0xd0, +0x00, 0x18, 0x00, 0x62, 0x40, 0x36, 0x00, 0x00, 0x05, 0x15, +0x12, 0x15, 0x81, 0x16, 0x00, 0x14, 0x16, 0x16, 0x00, 0x06, +0x00, 0x05, 0x00, 0x81, 0x0b, 0x06, 0x14, 0x0b, 0x06, 0x00, +0x0b, 0x16, 0x16, 0x05, 0x1a, 0x0b, 0x12, 0x7f, 0x0f, 0x00, +0x0e, 0x01, 0x08, 0x0e, 0x19, 0x16, 0x15, 0x49, 0x12, 0x0b, +0x0d, 0x0e, 0x85, 0x11, 0x49, 0x0d, 0x4a, 0x05, 0x06, 0x4a, +0x00, 0x3f, 0x33, 0x3f, 0x3f, 0xed, 0x12, 0x39, 0x39, 0x3f, +0x33, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xcd, 0xed, 0x32, 0x10, +0xce, 0x32, 0x2f, 0x10, 0x00, 0xc1, 0x87, 0x05, 0x2b, 0x87, +0x7d, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x08, 0x7d, 0xc4, +0x31, 0x30, 0x25, 0x1e, 0x03, 0x17, 0x23, 0x2e, 0x03, 0x27, +0x15, 0x23, 0x11, 0x23, 0x35, 0x33, 0x15, 0x36, 0x36, 0x37, +0x33, 0x06, 0x06, 0x01, 0x13, 0x18, 0x37, 0x38, 0x32, 0x12, +0x62, 0x13, 0x2e, 0x32, 0x33, 0x18, 0x52, 0x5b, 0xad, 0x34, +0x56, 0x23, 0x61, 0x2a, 0x57, 0xff, 0x13, 0x3d, 0x46, 0x4a, +0x1f, 0x1f, 0x42, 0x3c, 0x33, 0x0f, 0xdf, 0x01, 0x8b, 0x45, +0xc2, 0x33, 0x61, 0x2e, 0x35, 0x66, 0x00, 0x01, 0x00, 0x2d, +0xff, 0x5b, 0x01, 0xd9, 0x02, 0x6b, 0x00, 0x0f, 0x00, 0x3c, +0x40, 0x21, 0x0f, 0x07, 0x73, 0x02, 0x06, 0x73, 0x03, 0x11, +0x0e, 0x0a, 0x73, 0x0b, 0x10, 0x09, 0x79, 0x0f, 0x0e, 0x1f, +0x0e, 0x02, 0x0e, 0x0e, 0x0b, 0x00, 0x0c, 0x41, 0x0b, 0x44, +0x05, 0x02, 0x79, 0x07, 0x44, 0x00, 0x3f, 0xed, 0xce, 0x3f, +0x3f, 0x33, 0x12, 0x39, 0x2f, 0x5d, 0xed, 0x01, 0x10, 0xd6, +0xed, 0x32, 0x10, 0xde, 0xed, 0xd5, 0xed, 0x32, 0x31, 0x30, +0x01, 0x33, 0x11, 0x33, 0x15, 0x23, 0x35, 0x23, 0x11, 0x23, +0x11, 0x23, 0x11, 0x33, 0x11, 0x33, 0x01, 0x60, 0x52, 0x27, +0x4e, 0x2b, 0xe1, 0x52, 0x52, 0xe1, 0x02, 0x6b, 0xfd, 0xdb, +0xeb, 0xa5, 0x01, 0x20, 0xfe, 0xe0, 0x02, 0x6b, 0xfe, 0xfb, +0x00, 0x00, 0x00, 0x01, 0x00, 0x47, 0xff, 0x7f, 0x01, 0xd0, +0x01, 0xd0, 0x00, 0x0f, 0x00, 0x42, 0x40, 0x25, 0x0d, 0x05, +0x7f, 0x00, 0x04, 0x7f, 0x01, 0x11, 0x0c, 0x08, 0x7f, 0x00, +0x09, 0x01, 0x09, 0x10, 0x07, 0x85, 0x0f, 0x0c, 0x1f, 0x0c, +0x02, 0x08, 0x0c, 0x0c, 0x09, 0x0e, 0x0a, 0x49, 0x09, 0x4a, +0x03, 0x00, 0x85, 0x05, 0x4a, 0x00, 0x3f, 0xed, 0xce, 0x3f, +0x3f, 0x33, 0x12, 0x39, 0x2f, 0x5e, 0x5d, 0xed, 0x01, 0x10, +0xd6, 0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, 0xd5, 0xed, 0x32, +0x31, 0x30, 0x25, 0x33, 0x15, 0x23, 0x35, 0x23, 0x35, 0x23, +0x15, 0x23, 0x11, 0x33, 0x15, 0x33, 0x35, 0x33, 0x01, 0xa9, +0x27, 0x4e, 0x2b, 0xbd, 0x53, 0x53, 0xbd, 0x52, 0x46, 0xc7, +0x81, 0xcd, 0xcd, 0x01, 0xd0, 0xbd, 0xbd, 0x00, 0x00, 0x01, +0x00, 0x2d, 0x00, 0x00, 0x01, 0xe2, 0x02, 0x6b, 0x00, 0x0d, +0x00, 0x3a, 0x40, 0x1f, 0x05, 0x0d, 0x73, 0x02, 0x01, 0x0f, +0x0b, 0x07, 0x73, 0x08, 0x0e, 0x02, 0x79, 0x0d, 0x0d, 0x09, +0x06, 0x79, 0x0f, 0x0b, 0x1f, 0x0b, 0x02, 0x0b, 0x0b, 0x08, +0x09, 0x41, 0x04, 0x08, 0x44, 0x00, 0x3f, 0x33, 0x3f, 0x12, +0x39, 0x2f, 0x5d, 0xed, 0x11, 0x33, 0x10, 0xed, 0x01, 0x10, +0xd6, 0xed, 0x32, 0x10, 0xde, 0xdd, 0xed, 0x32, 0x31, 0x30, +0x01, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, +0x33, 0x11, 0x33, 0x11, 0x01, 0xe2, 0x5e, 0x52, 0xb3, 0x52, +0x52, 0xb3, 0x02, 0x6b, 0x46, 0xfd, 0xdb, 0x01, 0x20, 0xfe, +0xe0, 0x02, 0x6b, 0xfe, 0xfb, 0x01, 0x05, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x47, 0x00, 0x00, 0x01, 0xe2, 0x01, 0xd0, +0x00, 0x0d, 0x00, 0x3b, 0x40, 0x21, 0x05, 0x0d, 0x7f, 0x02, +0x01, 0x0f, 0x0b, 0x07, 0x7f, 0x00, 0x08, 0x10, 0x08, 0x02, +0x08, 0x0e, 0x02, 0x85, 0x0d, 0x49, 0x06, 0x85, 0x0f, 0x0b, +0x01, 0x0b, 0x0b, 0x08, 0x09, 0x49, 0x04, 0x08, 0x4a, 0x00, +0x3f, 0x33, 0x3f, 0x12, 0x39, 0x2f, 0x5d, 0xed, 0x3f, 0xed, +0x01, 0x10, 0xd6, 0x5d, 0xed, 0x32, 0x10, 0xde, 0xd5, 0xed, +0x32, 0x31, 0x30, 0x01, 0x15, 0x23, 0x11, 0x23, 0x35, 0x23, +0x15, 0x23, 0x11, 0x33, 0x15, 0x33, 0x35, 0x01, 0xe2, 0x5b, +0x52, 0x9b, 0x53, 0x53, 0x9b, 0x01, 0xd0, 0x45, 0xfe, 0x75, +0xcd, 0xcd, 0x01, 0xd0, 0xbd, 0xbd, 0x00, 0x00, 0x00, 0x01, +0x00, 0x36, 0xff, 0x5b, 0x01, 0xd0, 0x02, 0x6b, 0x00, 0x23, +0x00, 0x88, 0x40, 0x0d, 0x18, 0x10, 0x11, 0x12, 0x00, 0x4c, +0x14, 0x10, 0x13, 0x14, 0x00, 0x4c, 0x0a, 0xb8, 0xff, 0xd8, +0xb4, 0x11, 0x12, 0x00, 0x4c, 0x06, 0xb8, 0xff, 0xf0, 0xb3, +0x0c, 0x00, 0x4d, 0x06, 0xb8, 0xff, 0xe8, 0xb4, 0x09, 0x0b, +0x00, 0x4c, 0x05, 0xb8, 0xff, 0xf0, 0x40, 0x34, 0x09, 0x00, +0x4d, 0x00, 0x1d, 0x73, 0x1e, 0x0f, 0x0e, 0x01, 0x0e, 0x1e, +0x0e, 0x1e, 0x22, 0x17, 0x76, 0x1f, 0x07, 0x01, 0x07, 0x48, +0x09, 0x49, 0x07, 0x25, 0x21, 0x73, 0x10, 0x22, 0x20, 0x22, +0x30, 0x22, 0x03, 0x22, 0x24, 0x19, 0x7c, 0x04, 0x04, 0x22, +0x20, 0x79, 0x23, 0x41, 0x1e, 0x22, 0x44, 0x12, 0x7c, 0x0c, +0x00, 0x2f, 0xed, 0x3f, 0x33, 0x3f, 0xed, 0x12, 0x39, 0x2f, +0xed, 0x01, 0x10, 0xd6, 0x5d, 0xed, 0x10, 0xde, 0x2b, 0x5d, +0xed, 0x11, 0x39, 0x39, 0x2f, 0x2f, 0x5d, 0x10, 0xed, 0x32, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x15, +0x36, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x23, +0x22, 0x27, 0x35, 0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x35, +0x34, 0x23, 0x22, 0x06, 0x07, 0x11, 0x23, 0x11, 0x23, 0x11, +0x23, 0x11, 0x01, 0x1a, 0x0a, 0x11, 0x0e, 0x4a, 0x43, 0x15, +0x27, 0x3a, 0x25, 0x0a, 0x08, 0x03, 0x08, 0x07, 0x18, 0x1f, +0x12, 0x07, 0x49, 0x09, 0x10, 0x09, 0x49, 0x52, 0x49, 0x02, +0x6b, 0xe1, 0x01, 0x01, 0x82, 0x86, 0x51, 0x71, 0x47, 0x20, +0x02, 0x45, 0x01, 0x01, 0x1f, 0x3c, 0x56, 0x38, 0xbb, 0x01, +0x01, 0xfe, 0xbe, 0x02, 0x25, 0xfd, 0xdb, 0x02, 0x6b, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x36, 0xff, 0x5b, 0x01, 0xd0, +0x01, 0xd0, 0x00, 0x22, 0x00, 0x6c, 0xb9, 0x00, 0x19, 0xff, +0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x19, 0xb8, 0xff, 0xf0, 0xb3, +0x0d, 0x00, 0x4d, 0x19, 0xb8, 0xff, 0xe8, 0xb4, 0x0b, 0x0c, +0x00, 0x4c, 0x19, 0xb8, 0xff, 0xf0, 0x40, 0x2a, 0x0a, 0x00, +0x4d, 0x14, 0x0c, 0x7f, 0x0d, 0x0f, 0x22, 0x01, 0x22, 0x0d, +0x22, 0x0d, 0x11, 0x06, 0x82, 0x1a, 0x24, 0x10, 0x7f, 0x10, +0x11, 0x01, 0x11, 0x23, 0x03, 0x89, 0x1f, 0x4b, 0x08, 0x88, +0x17, 0x17, 0x11, 0x0f, 0x85, 0x12, 0x49, 0x0d, 0x11, 0x4a, +0x00, 0x3f, 0x33, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0xed, 0x3f, +0xed, 0x01, 0x10, 0xd6, 0x5d, 0xed, 0x10, 0xde, 0xed, 0x11, +0x39, 0x39, 0x2f, 0x2f, 0x5d, 0x10, 0xed, 0x32, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x05, 0x16, 0x16, 0x33, 0x32, 0x36, +0x35, 0x34, 0x23, 0x22, 0x06, 0x23, 0x15, 0x23, 0x11, 0x23, +0x11, 0x23, 0x11, 0x33, 0x15, 0x36, 0x36, 0x33, 0x32, 0x16, +0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x01, 0x23, +0x03, 0x08, 0x07, 0x31, 0x1f, 0x49, 0x05, 0x15, 0x08, 0x49, +0x52, 0x49, 0xe4, 0x0a, 0x19, 0x06, 0x4a, 0x43, 0x15, 0x27, +0x3a, 0x25, 0x05, 0x0d, 0x05, 0x5e, 0x01, 0x01, 0x5c, 0x53, +0x87, 0x01, 0xd5, 0x01, 0x8b, 0xfe, 0x75, 0x01, 0xd0, 0xb5, +0x02, 0x01, 0x67, 0x6d, 0x41, 0x5b, 0x39, 0x1a, 0x01, 0x01, +0x00, 0x02, 0x00, 0x1d, 0xff, 0x5c, 0x01, 0xd9, 0x02, 0x79, +0x00, 0x2c, 0x00, 0x3a, 0x00, 0xec, 0xb5, 0x32, 0x20, 0x0d, +0x00, 0x4d, 0x2a, 0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, +0x2a, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x2a, 0xb8, +0xff, 0xe0, 0xb3, 0x0c, 0x00, 0x4d, 0x2a, 0xb8, 0xff, 0xe8, +0xb3, 0x0b, 0x00, 0x4d, 0x2a, 0xb8, 0xff, 0xf0, 0x40, 0x0e, +0x09, 0x00, 0x4d, 0x19, 0x18, 0x0e, 0x00, 0x4d, 0x19, 0x10, +0x08, 0x00, 0x4d, 0x12, 0xb8, 0xff, 0xd8, 0xb4, 0x10, 0x12, +0x00, 0x4c, 0x0a, 0xb8, 0xff, 0xe8, 0xb3, 0x0c, 0x00, 0x4d, +0x0a, 0xb8, 0xff, 0xf0, 0xb3, 0x0b, 0x00, 0x4d, 0x0a, 0xb8, +0xff, 0xe0, 0xb3, 0x0a, 0x00, 0x4d, 0x0a, 0xb8, 0xff, 0xe8, +0x40, 0x10, 0x09, 0x00, 0x4d, 0x06, 0x10, 0x0b, 0x0c, 0x00, +0x4c, 0x06, 0x18, 0x09, 0x0a, 0x00, 0x4c, 0x02, 0xb8, 0xff, +0xf0, 0xb3, 0x12, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xf0, 0xb4, +0x0b, 0x0d, 0x00, 0x4c, 0x01, 0xb8, 0xff, 0xf0, 0x40, 0x2e, +0x11, 0x00, 0x4d, 0x10, 0x30, 0x13, 0x2d, 0x76, 0x17, 0x03, +0x13, 0x05, 0x05, 0x1c, 0x35, 0x76, 0x0b, 0x13, 0x13, 0x24, +0x24, 0x0b, 0x3c, 0x00, 0x76, 0x1c, 0x3b, 0x38, 0x7c, 0x08, +0x28, 0x25, 0x25, 0x28, 0x7c, 0x21, 0x45, 0x30, 0x03, 0x7c, +0x10, 0x17, 0x46, 0x13, 0x7c, 0x14, 0x00, 0x2f, 0xed, 0x3f, +0x33, 0xed, 0x32, 0x3f, 0xed, 0x32, 0x2f, 0x10, 0xde, 0xed, +0x01, 0x10, 0xd6, 0xed, 0x10, 0xce, 0x32, 0x2f, 0x32, 0x2f, +0x10, 0xed, 0x11, 0x39, 0x2f, 0x12, 0x39, 0x39, 0xed, 0x11, +0x39, 0x39, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x13, 0x14, 0x16, 0x17, 0x26, 0x35, 0x34, 0x36, +0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x16, 0x16, +0x17, 0x07, 0x26, 0x26, 0x27, 0x2e, 0x03, 0x35, 0x34, 0x3e, +0x02, 0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, +0x0e, 0x02, 0x17, 0x14, 0x16, 0x17, 0x3e, 0x03, 0x35, 0x34, +0x26, 0x23, 0x22, 0x06, 0x6f, 0x3a, 0x33, 0x12, 0x4d, 0x42, +0x38, 0x48, 0x12, 0x24, 0x39, 0x27, 0x14, 0x3f, 0x2d, 0x0b, +0x45, 0x61, 0x1d, 0x2f, 0x4f, 0x39, 0x21, 0x29, 0x48, 0x62, +0x38, 0x25, 0x44, 0x14, 0x15, 0x1a, 0x32, 0x17, 0x2b, 0x46, +0x32, 0x1b, 0xac, 0x08, 0x08, 0x19, 0x23, 0x16, 0x0a, 0x15, +0x1a, 0x1d, 0x20, 0x01, 0x36, 0x6b, 0x79, 0x12, 0x49, 0x56, +0x7f, 0x72, 0x67, 0x68, 0x29, 0x51, 0x47, 0x35, 0x0d, 0x29, +0x32, 0x02, 0x45, 0x05, 0x51, 0x43, 0x03, 0x28, 0x4f, 0x77, +0x50, 0x4e, 0x78, 0x52, 0x2b, 0x0e, 0x0b, 0x43, 0x0b, 0x0b, +0x24, 0x42, 0x5e, 0x95, 0x2a, 0x4d, 0x23, 0x09, 0x29, 0x36, +0x3f, 0x1e, 0x43, 0x41, 0x52, 0x00, 0x00, 0x00, 0x00, 0x02, +0x00, 0x28, 0xff, 0x7f, 0x01, 0xd6, 0x01, 0xdb, 0x00, 0x0b, +0x00, 0x3f, 0x00, 0xd5, 0x40, 0x0c, 0x3a, 0x10, 0x08, 0x00, +0x4d, 0x35, 0x10, 0x08, 0x09, 0x00, 0x4c, 0x2c, 0xb8, 0xff, +0xc0, 0xb4, 0x10, 0x12, 0x00, 0x4c, 0x22, 0xb8, 0xff, 0xe8, +0xb3, 0x0d, 0x00, 0x4d, 0x22, 0xb8, 0xff, 0xe0, 0xb3, 0x0c, +0x00, 0x4d, 0x22, 0xb8, 0xff, 0xe8, 0xb3, 0x0b, 0x00, 0x4d, +0x22, 0xb8, 0xff, 0xe0, 0xb3, 0x0a, 0x00, 0x4d, 0x21, 0xb8, +0xff, 0xe8, 0x40, 0x0f, 0x0e, 0x00, 0x4d, 0x1d, 0x10, 0x0e, +0x00, 0x4d, 0x1c, 0x20, 0x0a, 0x0d, 0x00, 0x4c, 0x16, 0xb8, +0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x16, 0xb8, 0xff, 0xf0, +0xb4, 0x0e, 0x0f, 0x00, 0x4c, 0x11, 0xb8, 0xff, 0xe8, 0x40, +0x3e, 0x0f, 0x10, 0x00, 0x4c, 0x04, 0x20, 0x10, 0x12, 0x00, +0x4c, 0x04, 0x10, 0x0f, 0x00, 0x4d, 0x17, 0x34, 0x1a, 0x03, +0x29, 0x2e, 0x2e, 0x24, 0x00, 0x82, 0x1a, 0x0f, 0x1a, 0x01, +0x3f, 0x1a, 0x3f, 0x1a, 0x37, 0x06, 0x82, 0x24, 0x41, 0x14, +0x82, 0x37, 0x40, 0x09, 0x89, 0x1f, 0x0f, 0x0c, 0x0c, 0x0f, +0x89, 0x3c, 0x50, 0x17, 0x03, 0x89, 0x29, 0x34, 0x51, 0x2e, +0x89, 0x2f, 0x4b, 0x00, 0x3f, 0xed, 0x3f, 0x33, 0xed, 0x32, +0x3f, 0xed, 0x32, 0x2f, 0x10, 0xde, 0xed, 0x01, 0x10, 0xd6, +0xed, 0x10, 0xde, 0xed, 0x11, 0x39, 0x39, 0x2f, 0x2f, 0x5d, +0x10, 0xed, 0x11, 0x33, 0x2f, 0x39, 0x39, 0x12, 0x39, 0x39, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x14, 0x16, +0x17, 0x36, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x37, +0x26, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x16, 0x17, +0x26, 0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, +0x15, 0x14, 0x0e, 0x02, 0x07, 0x1e, 0x03, 0x17, 0x07, 0x2e, +0x03, 0x27, 0x26, 0x26, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, +0x16, 0x17, 0x01, 0x1a, 0x09, 0x06, 0x2c, 0x35, 0x17, 0x1e, +0x1e, 0x1d, 0x2f, 0x08, 0x21, 0x12, 0x1f, 0x36, 0x29, 0x17, +0x2e, 0x36, 0x07, 0x08, 0x0f, 0x20, 0x33, 0x24, 0x22, 0x31, +0x20, 0x0f, 0x13, 0x24, 0x34, 0x21, 0x0a, 0x22, 0x23, 0x21, +0x0a, 0x0b, 0x18, 0x37, 0x34, 0x2e, 0x10, 0x5f, 0x71, 0x25, +0x3e, 0x51, 0x2c, 0x1a, 0x2e, 0x08, 0xa5, 0x22, 0x37, 0x16, +0x08, 0x4c, 0x36, 0x29, 0x37, 0x37, 0xa7, 0x03, 0x07, 0x15, +0x2c, 0x41, 0x2c, 0x48, 0x5a, 0x0e, 0x18, 0x37, 0x20, 0x27, +0x42, 0x30, 0x1c, 0x19, 0x2c, 0x3a, 0x21, 0x23, 0x3f, 0x34, +0x25, 0x09, 0x13, 0x18, 0x0e, 0x06, 0x01, 0x3d, 0x01, 0x0e, +0x1c, 0x2c, 0x20, 0x05, 0x7e, 0x73, 0x3a, 0x5a, 0x3c, 0x1f, +0x08, 0x03, 0x00, 0x00, 0xff, 0xff, 0x00, 0x2e, 0xff, 0x57, +0x01, 0xcc, 0x02, 0x79, 0x02, 0x06, 0x00, 0xa2, 0x00, 0x00, +0xff, 0xff, 0x00, 0x31, 0xff, 0x57, 0x01, 0xc3, 0x01, 0xdb, +0x02, 0x06, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, +0xff, 0x5b, 0x01, 0xcd, 0x02, 0x6b, 0x00, 0x0b, 0x00, 0x2a, +0x40, 0x15, 0x07, 0x73, 0x04, 0x01, 0x03, 0x73, 0x0a, 0x08, +0x08, 0x0d, 0x0c, 0x02, 0x09, 0x79, 0x0b, 0x41, 0x06, 0x03, +0x79, 0x08, 0x44, 0x00, 0x3f, 0xed, 0xce, 0x3f, 0xed, 0x32, +0x01, 0x11, 0x12, 0x39, 0x2f, 0xce, 0xfd, 0xce, 0xdd, 0xed, +0x31, 0x30, 0x01, 0x15, 0x23, 0x11, 0x33, 0x15, 0x23, 0x35, +0x23, 0x11, 0x23, 0x35, 0x01, 0xcd, 0xaa, 0x27, 0x4e, 0x2b, +0xaa, 0x02, 0x6b, 0x46, 0xfe, 0x21, 0xeb, 0xa5, 0x02, 0x25, +0x46, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3a, 0xff, 0x7f, +0x01, 0xba, 0x01, 0xd0, 0x00, 0x0b, 0x00, 0x30, 0x40, 0x19, +0x0a, 0x7f, 0x07, 0x04, 0x06, 0x7f, 0x01, 0x00, 0x0b, 0x01, +0x08, 0x0b, 0x0b, 0x0d, 0x0c, 0x09, 0x06, 0x85, 0x0b, 0x4a, +0x05, 0x00, 0x85, 0x02, 0x49, 0x00, 0x3f, 0xed, 0x32, 0x3f, +0xed, 0xce, 0x01, 0x11, 0x12, 0x39, 0x2f, 0x5e, 0x5d, 0xce, +0xfd, 0xce, 0xdd, 0xed, 0x31, 0x30, 0x13, 0x23, 0x35, 0x21, +0x15, 0x23, 0x11, 0x33, 0x15, 0x23, 0x35, 0x23, 0xd1, 0x97, +0x01, 0x80, 0x97, 0x27, 0x4e, 0x2b, 0x01, 0x8b, 0x45, 0x45, +0xfe, 0xbb, 0xc7, 0x81, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0d, +0x00, 0x00, 0x01, 0xe8, 0x02, 0x6b, 0x02, 0x06, 0x00, 0x3c, +0x00, 0x00, 0x00, 0x01, 0x00, 0x1e, 0xff, 0x5b, 0x01, 0xd6, +0x01, 0xd0, 0x00, 0x14, 0x00, 0x54, 0x40, 0x2e, 0x0f, 0x0a, +0x0f, 0x14, 0x0a, 0x81, 0x09, 0x06, 0x14, 0x09, 0x09, 0x06, +0x0f, 0x14, 0x14, 0x81, 0x00, 0x03, 0x14, 0x00, 0x03, 0x00, +0x03, 0x7f, 0x09, 0x00, 0x06, 0x01, 0x08, 0x06, 0x06, 0x15, +0x16, 0x00, 0x14, 0x49, 0x0f, 0x03, 0x06, 0x06, 0x05, 0x0a, +0x09, 0x49, 0x05, 0x4b, 0x00, 0x3f, 0x3f, 0x33, 0x12, 0x39, +0x11, 0x33, 0x33, 0x3f, 0x33, 0x01, 0x11, 0x12, 0x39, 0x2f, +0x5e, 0x5d, 0xcd, 0xfd, 0xdd, 0x87, 0x2b, 0x7d, 0x10, 0xc4, +0x87, 0x18, 0x10, 0x2b, 0x08, 0x7d, 0x10, 0xc4, 0x31, 0x30, +0x01, 0x06, 0x06, 0x07, 0x15, 0x23, 0x35, 0x26, 0x26, 0x27, +0x33, 0x1e, 0x03, 0x17, 0x3e, 0x03, 0x37, 0x01, 0xd6, 0x25, +0x61, 0x2e, 0x52, 0x2e, 0x5f, 0x25, 0x5a, 0x0c, 0x1f, 0x23, +0x25, 0x11, 0x10, 0x25, 0x24, 0x1f, 0x0c, 0x01, 0xd0, 0x80, +0xe7, 0x5e, 0xb0, 0xb2, 0x5e, 0xe6, 0x7f, 0x2c, 0x63, 0x61, +0x5b, 0x24, 0x24, 0x5b, 0x61, 0x63, 0x2c, 0x00, 0x00, 0x01, +0x00, 0x0d, 0x00, 0x00, 0x01, 0xe8, 0x02, 0x6b, 0x00, 0x18, +0x00, 0x56, 0x40, 0x2e, 0x14, 0x10, 0x0b, 0x10, 0x78, 0x11, +0x14, 0x14, 0x11, 0x14, 0x11, 0x16, 0x17, 0x73, 0x01, 0x0b, +0x08, 0x08, 0x78, 0x07, 0x04, 0x14, 0x07, 0x04, 0x07, 0x04, +0x02, 0x01, 0x01, 0x19, 0x1a, 0x10, 0x11, 0x41, 0x17, 0x01, +0x79, 0x14, 0x0b, 0x04, 0x04, 0x08, 0x07, 0x41, 0x00, 0x44, +0x00, 0x3f, 0x3f, 0x33, 0x39, 0x2f, 0x33, 0x33, 0xed, 0x32, +0x3f, 0x33, 0x01, 0x11, 0x12, 0x39, 0x2f, 0xcd, 0x33, 0xdc, +0x87, 0x2b, 0x7d, 0x10, 0xc4, 0x01, 0x18, 0x10, 0xfd, 0xcd, +0xdc, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x33, 0x35, +0x23, 0x35, 0x33, 0x26, 0x26, 0x27, 0x33, 0x16, 0x16, 0x17, +0x3e, 0x03, 0x37, 0x33, 0x06, 0x06, 0x07, 0x33, 0x15, 0x23, +0x15, 0xd2, 0x80, 0x7a, 0x3c, 0x5a, 0x29, 0x5c, 0x21, 0x47, +0x2b, 0x17, 0x26, 0x23, 0x21, 0x11, 0x5a, 0x29, 0x5c, 0x3b, +0x7d, 0x81, 0xbd, 0x42, 0x61, 0xb0, 0x5b, 0x50, 0x94, 0x51, +0x2a, 0x4c, 0x4b, 0x4b, 0x29, 0x5b, 0xad, 0x64, 0x42, 0xbd, +0x00, 0x00, 0x00, 0x01, 0x00, 0x1e, 0xff, 0x5b, 0x01, 0xd6, +0x01, 0xd0, 0x00, 0x1a, 0x00, 0x54, 0x40, 0x2e, 0x0c, 0x10, +0x15, 0x10, 0x81, 0x0f, 0x0c, 0x14, 0x0f, 0x0c, 0x0f, 0x09, +0x03, 0x1a, 0x15, 0x1a, 0x81, 0x00, 0x03, 0x14, 0x00, 0x03, +0x00, 0x04, 0x06, 0x7f, 0x0b, 0x09, 0x09, 0x1c, 0x1b, 0x15, +0x10, 0x0f, 0x49, 0x15, 0x03, 0x0c, 0x86, 0x09, 0x4a, 0x08, +0x4b, 0x1a, 0x00, 0x49, 0x00, 0x3f, 0x32, 0x3f, 0x3f, 0xed, +0x32, 0x32, 0x3f, 0x33, 0x01, 0x2f, 0x11, 0x12, 0x39, 0x2f, +0xcd, 0xfd, 0xcd, 0xdd, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x01, +0x18, 0x10, 0xdc, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, +0x01, 0x06, 0x06, 0x07, 0x33, 0x15, 0x23, 0x15, 0x23, 0x35, +0x23, 0x35, 0x33, 0x26, 0x26, 0x27, 0x33, 0x1e, 0x03, 0x17, +0x3e, 0x03, 0x37, 0x01, 0xd6, 0x20, 0x53, 0x29, 0x63, 0x7b, +0x52, 0x7a, 0x63, 0x2a, 0x51, 0x20, 0x5a, 0x0c, 0x1f, 0x23, +0x25, 0x11, 0x10, 0x25, 0x24, 0x1f, 0x0c, 0x01, 0xd0, 0x70, +0xcb, 0x58, 0x3d, 0xa5, 0xa5, 0x3d, 0x58, 0xcc, 0x6f, 0x2c, +0x63, 0x61, 0x5b, 0x24, 0x24, 0x5b, 0x61, 0x63, 0x2c, 0x00, +0x00, 0x01, 0x00, 0x19, 0xff, 0x5b, 0x01, 0xd9, 0x02, 0x6b, +0x00, 0x19, 0x00, 0x56, 0x40, 0x2f, 0x10, 0x02, 0x0f, 0x02, +0x78, 0x17, 0x10, 0x14, 0x17, 0x10, 0x17, 0x17, 0x18, 0x0a, +0x12, 0x0b, 0x12, 0x78, 0x13, 0x0a, 0x14, 0x13, 0x13, 0x0a, +0x13, 0x01, 0x73, 0x18, 0x1b, 0x0f, 0x0f, 0x0b, 0x1a, 0x12, +0x13, 0x41, 0x10, 0x0f, 0x41, 0x0a, 0x0b, 0x44, 0x17, 0x79, +0x00, 0x02, 0x44, 0x00, 0x3f, 0xce, 0xed, 0x3f, 0x33, 0x3f, +0x33, 0x3f, 0x33, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xde, +0xed, 0x33, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x11, +0x33, 0x18, 0x2f, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, +0x05, 0x35, 0x23, 0x2e, 0x03, 0x27, 0x06, 0x06, 0x07, 0x23, +0x36, 0x36, 0x37, 0x03, 0x33, 0x17, 0x37, 0x33, 0x03, 0x16, +0x16, 0x17, 0x33, 0x15, 0x01, 0x8b, 0x17, 0x0b, 0x1b, 0x20, +0x24, 0x14, 0x24, 0x42, 0x1e, 0x59, 0x21, 0x55, 0x32, 0x9e, +0x5b, 0x76, 0x83, 0x59, 0xa6, 0x26, 0x43, 0x1e, 0x28, 0xa5, +0xa5, 0x1b, 0x44, 0x48, 0x48, 0x1f, 0x38, 0x91, 0x45, 0x4a, +0xad, 0x50, 0x01, 0x24, 0xed, 0xed, 0xfe, 0xdf, 0x3e, 0x83, +0x43, 0xeb, 0x00, 0x01, 0x00, 0x1d, 0xff, 0x7f, 0x01, 0xd0, +0x01, 0xd0, 0x00, 0x1b, 0x00, 0x52, 0x40, 0x2d, 0x0c, 0x14, +0x0d, 0x14, 0x81, 0x15, 0x0c, 0x14, 0x15, 0x0c, 0x15, 0x15, +0x01, 0x7f, 0x1a, 0x1d, 0x12, 0x02, 0x11, 0x02, 0x81, 0x19, +0x12, 0x14, 0x19, 0x19, 0x12, 0x11, 0x11, 0x0d, 0x1c, 0x19, +0x14, 0x15, 0x49, 0x12, 0x11, 0x49, 0x0c, 0x0d, 0x4a, 0x19, +0x85, 0x02, 0x4a, 0x00, 0x3f, 0xed, 0x3f, 0x33, 0x3f, 0x33, +0x3f, 0x33, 0x01, 0x2f, 0x10, 0xc6, 0x32, 0x2f, 0x87, 0x10, +0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, 0x10, 0xde, 0xed, 0x33, +0x2f, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x05, 0x35, +0x23, 0x2e, 0x03, 0x27, 0x0e, 0x03, 0x07, 0x23, 0x36, 0x36, +0x37, 0x27, 0x33, 0x17, 0x37, 0x33, 0x07, 0x16, 0x16, 0x17, +0x33, 0x15, 0x01, 0x82, 0x0e, 0x0a, 0x1b, 0x20, 0x23, 0x12, +0x12, 0x27, 0x25, 0x1f, 0x0b, 0x55, 0x21, 0x5d, 0x2e, 0xa5, +0x5d, 0x7b, 0x73, 0x58, 0x99, 0x20, 0x3e, 0x1c, 0x28, 0x81, +0x81, 0x14, 0x30, 0x33, 0x32, 0x16, 0x17, 0x32, 0x33, 0x30, +0x13, 0x3c, 0x7f, 0x39, 0xdc, 0xa2, 0xa2, 0xd7, 0x2a, 0x5b, +0x2e, 0xc7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x12, 0xff, 0x5b, +0x01, 0xd9, 0x02, 0x6b, 0x00, 0x0f, 0x00, 0x39, 0x40, 0x1f, +0x04, 0x73, 0x07, 0x07, 0x0b, 0x73, 0x08, 0x11, 0xa0, 0x01, +0xb0, 0x01, 0x02, 0x01, 0x02, 0x73, 0x0d, 0x0e, 0x10, 0x02, +0x0d, 0x79, 0x05, 0x0f, 0x41, 0x07, 0x04, 0x79, 0x0a, 0x0b, +0x44, 0x00, 0x3f, 0xcd, 0xed, 0x32, 0x3f, 0x33, 0xed, 0x32, +0x01, 0x10, 0xd6, 0xdd, 0xfd, 0xcd, 0x5d, 0x10, 0xde, 0xed, +0x33, 0x2f, 0xed, 0x31, 0x30, 0x01, 0x15, 0x23, 0x11, 0x33, +0x11, 0x33, 0x11, 0x33, 0x15, 0x23, 0x35, 0x21, 0x11, 0x23, +0x35, 0x01, 0x0e, 0x55, 0xa7, 0x52, 0x27, 0x4e, 0xfe, 0xdc, +0x55, 0x02, 0x6b, 0x46, 0xfe, 0x21, 0x02, 0x25, 0xfd, 0xdb, +0xeb, 0xa5, 0x02, 0x25, 0x46, 0x00, 0x00, 0x01, 0x00, 0x12, +0xff, 0x7f, 0x01, 0xd0, 0x01, 0xd0, 0x00, 0x0f, 0x00, 0x39, +0x40, 0x1f, 0x04, 0x7f, 0x07, 0x07, 0x0b, 0x7f, 0x08, 0x11, +0xa0, 0x01, 0xb0, 0x01, 0x02, 0x01, 0x02, 0x7f, 0x0d, 0x0e, +0x10, 0x02, 0x0d, 0x85, 0x05, 0x0f, 0x49, 0x07, 0x04, 0x85, +0x0a, 0x0b, 0x4a, 0x00, 0x3f, 0xcd, 0xed, 0x32, 0x3f, 0x33, +0xed, 0x32, 0x01, 0x10, 0xd6, 0xdd, 0xfd, 0xcd, 0x5d, 0x10, +0xde, 0xed, 0x33, 0x2f, 0xed, 0x31, 0x30, 0x01, 0x15, 0x23, +0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x15, 0x23, 0x35, 0x21, +0x11, 0x23, 0x35, 0x01, 0x0e, 0x55, 0x9e, 0x52, 0x27, 0x4e, +0xfe, 0xe5, 0x55, 0x01, 0xcf, 0x45, 0xfe, 0xbc, 0x01, 0x8a, +0xfe, 0x76, 0xc7, 0x81, 0x01, 0x8a, 0x45, 0x00, 0x00, 0x01, +0x00, 0x36, 0xff, 0x5b, 0x01, 0xd9, 0x02, 0x6b, 0x00, 0x1b, +0x00, 0x56, 0x40, 0x10, 0x17, 0x28, 0x08, 0x00, 0x4d, 0x16, +0x20, 0x0a, 0x00, 0x4d, 0x16, 0x18, 0x09, 0x00, 0x4d, 0x03, +0xb8, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, 0x03, 0xb8, 0xff, +0xf0, 0x40, 0x1c, 0x11, 0x00, 0x4d, 0x09, 0x10, 0x73, 0x0b, +0x0f, 0x73, 0x0c, 0x1d, 0x00, 0x73, 0x19, 0x1c, 0x05, 0x7c, +0x14, 0x14, 0x10, 0x09, 0x1a, 0x41, 0x0e, 0x0b, 0x79, 0x10, +0x44, 0x00, 0x3f, 0xed, 0xce, 0x3f, 0x33, 0x12, 0x39, 0x2f, +0xed, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, 0xd5, 0xed, +0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x14, +0x1e, 0x02, 0x33, 0x32, 0x36, 0x37, 0x11, 0x33, 0x11, 0x33, +0x15, 0x23, 0x35, 0x23, 0x35, 0x06, 0x06, 0x23, 0x22, 0x2e, +0x02, 0x35, 0x35, 0x33, 0x89, 0x08, 0x19, 0x2d, 0x24, 0x20, +0x37, 0x0e, 0x52, 0x27, 0x4e, 0x2b, 0x10, 0x3d, 0x23, 0x3c, +0x49, 0x28, 0x0d, 0x53, 0x01, 0xb8, 0x26, 0x39, 0x26, 0x12, +0x0a, 0x04, 0x01, 0x3c, 0xfd, 0xdb, 0xeb, 0xa5, 0xe8, 0x05, +0x09, 0x1f, 0x3a, 0x52, 0x33, 0xb3, 0x00, 0x01, 0x00, 0x36, +0xff, 0x7f, 0x01, 0xd0, 0x01, 0xd0, 0x00, 0x1b, 0x00, 0x45, +0x40, 0x2a, 0x0e, 0x10, 0x0d, 0x00, 0x4d, 0x0e, 0x18, 0x0b, +0x0c, 0x00, 0x4c, 0x0e, 0x20, 0x08, 0x0a, 0x00, 0x4c, 0x1a, +0x05, 0x7f, 0x00, 0x04, 0x7f, 0x01, 0x1d, 0x13, 0x7f, 0x10, +0x1c, 0x16, 0x89, 0x0b, 0x0b, 0x05, 0x1a, 0x11, 0x49, 0x03, +0x00, 0x85, 0x05, 0x4a, 0x00, 0x3f, 0xed, 0xce, 0x3f, 0x33, +0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, +0xed, 0xd5, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x25, +0x33, 0x15, 0x23, 0x35, 0x23, 0x35, 0x0e, 0x03, 0x23, 0x22, +0x2e, 0x02, 0x35, 0x35, 0x33, 0x15, 0x14, 0x16, 0x33, 0x32, +0x36, 0x37, 0x35, 0x33, 0x01, 0xa9, 0x27, 0x4e, 0x2b, 0x08, +0x19, 0x1f, 0x21, 0x10, 0x28, 0x41, 0x2e, 0x19, 0x52, 0x35, +0x32, 0x25, 0x30, 0x13, 0x52, 0x46, 0xc7, 0x81, 0xb4, 0x02, +0x05, 0x04, 0x04, 0x10, 0x26, 0x3e, 0x2e, 0x89, 0x88, 0x36, +0x29, 0x07, 0x05, 0xdb, 0x00, 0x01, 0x00, 0x36, 0x00, 0x00, +0x01, 0xbf, 0x02, 0x6b, 0x00, 0x1a, 0x00, 0x5b, 0xb9, 0x00, +0x02, 0xff, 0xe0, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x02, 0xb8, +0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe0, +0x40, 0x23, 0x0f, 0x00, 0x4d, 0x10, 0x05, 0x13, 0x04, 0x04, +0x18, 0x09, 0x0d, 0x73, 0x0c, 0x1c, 0x00, 0x73, 0x10, 0x18, +0x01, 0x18, 0x1b, 0x06, 0x04, 0x03, 0x7c, 0x12, 0x10, 0x13, +0x13, 0x0d, 0x0a, 0x19, 0x41, 0x0d, 0x44, 0x00, 0x3f, 0x3f, +0x33, 0x12, 0x39, 0x2f, 0x33, 0xcd, 0xfd, 0xcd, 0x33, 0x01, +0x10, 0xd6, 0x5d, 0xed, 0x10, 0xde, 0xed, 0x32, 0x11, 0x39, +0x2f, 0x33, 0xcd, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x13, +0x14, 0x16, 0x17, 0x35, 0x33, 0x15, 0x36, 0x36, 0x37, 0x11, +0x33, 0x11, 0x23, 0x35, 0x06, 0x07, 0x15, 0x23, 0x35, 0x2e, +0x03, 0x35, 0x35, 0x33, 0x89, 0x23, 0x31, 0x43, 0x18, 0x2a, +0x0b, 0x52, 0x52, 0x19, 0x34, 0x43, 0x33, 0x41, 0x25, 0x0e, +0x53, 0x01, 0xb8, 0x42, 0x48, 0x0a, 0x71, 0x73, 0x02, 0x08, +0x03, 0x01, 0x3c, 0xfd, 0x95, 0xe8, 0x08, 0x05, 0x73, 0x73, +0x04, 0x22, 0x39, 0x4e, 0x30, 0xb3, 0x00, 0x01, 0x00, 0x36, +0x00, 0x00, 0x01, 0xad, 0x01, 0xd0, 0x00, 0x1b, 0x00, 0x41, +0x40, 0x22, 0x18, 0x10, 0x0b, 0x00, 0x4d, 0x07, 0x13, 0x04, +0x14, 0x14, 0x1a, 0x0b, 0x0e, 0x7f, 0x0d, 0x1d, 0x01, 0x7f, +0x1a, 0x1c, 0x07, 0x05, 0x04, 0x88, 0x14, 0x12, 0x15, 0x15, +0x0e, 0x0b, 0x1b, 0x49, 0x0e, 0x4a, 0x00, 0x3f, 0x3f, 0x33, +0x12, 0x39, 0x2f, 0x33, 0xcd, 0xfd, 0xcd, 0x33, 0x01, 0x10, +0xd6, 0xed, 0x10, 0xde, 0xed, 0x32, 0x11, 0x39, 0x2f, 0x33, +0xcd, 0x32, 0x31, 0x30, 0x2b, 0x13, 0x15, 0x14, 0x16, 0x17, +0x35, 0x33, 0x15, 0x36, 0x36, 0x37, 0x35, 0x33, 0x11, 0x23, +0x35, 0x06, 0x06, 0x07, 0x15, 0x23, 0x35, 0x2e, 0x03, 0x35, +0x35, 0x88, 0x2a, 0x26, 0x3e, 0x16, 0x20, 0x0e, 0x53, 0x53, +0x0a, 0x24, 0x16, 0x3e, 0x24, 0x3c, 0x2b, 0x17, 0x01, 0xd0, +0x88, 0x2e, 0x2b, 0x05, 0x52, 0x52, 0x02, 0x05, 0x04, 0xdb, +0xfe, 0x30, 0xb3, 0x03, 0x08, 0x02, 0x53, 0x50, 0x02, 0x13, +0x26, 0x3d, 0x2c, 0x89, 0x00, 0x01, 0x00, 0x2d, 0x00, 0x00, +0x01, 0xc4, 0x02, 0x6b, 0x00, 0x15, 0x00, 0x56, 0x40, 0x11, +0x0d, 0x28, 0x11, 0x12, 0x00, 0x4c, 0x0d, 0x18, 0x10, 0x00, +0x4d, 0x0d, 0x10, 0x0f, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe8, +0xb3, 0x0a, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe0, 0xb3, 0x09, +0x00, 0x4d, 0x05, 0xb8, 0xff, 0xd0, 0x40, 0x16, 0x08, 0x00, +0x4d, 0x0a, 0x73, 0x09, 0x17, 0x00, 0x12, 0x73, 0x13, 0x16, +0x0e, 0x7c, 0x03, 0x03, 0x13, 0x14, 0x41, 0x0a, 0x13, 0x44, +0x00, 0x3f, 0x33, 0x3f, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, +0xd6, 0xed, 0x32, 0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x36, 0x36, 0x33, 0x32, 0x1e, +0x02, 0x15, 0x15, 0x23, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, +0x07, 0x11, 0x23, 0x11, 0x33, 0x7f, 0x11, 0x41, 0x26, 0x3f, +0x50, 0x2d, 0x11, 0x52, 0x39, 0x4e, 0x20, 0x3e, 0x0e, 0x52, +0x52, 0x01, 0x8c, 0x05, 0x09, 0x20, 0x3c, 0x54, 0x34, 0xb6, +0xb6, 0x4e, 0x4e, 0x08, 0x05, 0xfe, 0xbb, 0x02, 0x6b, 0x00, +0xff, 0xff, 0x00, 0x47, 0x00, 0x00, 0x01, 0xb0, 0x02, 0xb5, +0x02, 0x06, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x12, +0xff, 0xf3, 0x01, 0xdb, 0x02, 0x79, 0x00, 0x26, 0x00, 0x2f, +0x00, 0xbf, 0xb9, 0x00, 0x21, 0xff, 0xf0, 0xb3, 0x12, 0x00, +0x4d, 0x21, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x21, +0xb8, 0xff, 0xd8, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x21, 0xb8, +0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x21, 0xb8, 0xff, 0xf8, +0x40, 0x1e, 0x09, 0x00, 0x4d, 0x1f, 0x20, 0x0f, 0x10, 0x00, +0x4c, 0x1f, 0x10, 0x0a, 0x00, 0x4d, 0x1f, 0x08, 0x09, 0x00, +0x4d, 0x0c, 0x20, 0x10, 0x00, 0x4d, 0x0c, 0x18, 0x0f, 0x00, +0x4d, 0x08, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, 0x4d, 0x08, +0xb8, 0xff, 0xd8, 0xb3, 0x11, 0x00, 0x4d, 0x08, 0xb8, 0xff, +0xd0, 0xb3, 0x10, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xf8, 0x40, +0x2e, 0x0d, 0x0e, 0x00, 0x4c, 0x27, 0x76, 0x23, 0x07, 0x07, +0x23, 0x31, 0x2f, 0x00, 0x76, 0x1d, 0x00, 0x0f, 0x10, 0x0f, +0x20, 0x0f, 0x03, 0x08, 0x0f, 0x1a, 0x76, 0x14, 0x30, 0x0f, +0x00, 0x79, 0x1d, 0x17, 0x2f, 0x2f, 0x03, 0x2a, 0x7c, 0x20, +0x45, 0x06, 0x06, 0x03, 0x7c, 0x0a, 0x46, 0x00, 0x3f, 0xed, +0x32, 0x2f, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0xcc, 0x33, 0xed, +0x32, 0x01, 0x10, 0xd6, 0xfd, 0xdc, 0x5e, 0x5d, 0x32, 0xed, +0x32, 0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x13, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, +0x17, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x27, 0x2e, 0x03, +0x35, 0x34, 0x36, 0x37, 0x17, 0x06, 0x15, 0x14, 0x16, 0x17, +0x36, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x27, +0x34, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x07, 0xed, 0x04, 0x33, +0x43, 0x22, 0x2f, 0x07, 0x16, 0x07, 0x43, 0x2e, 0x35, 0x49, +0x2e, 0x15, 0x01, 0x1c, 0x32, 0x25, 0x16, 0x05, 0x02, 0x43, +0x04, 0x24, 0x20, 0x08, 0x56, 0x45, 0x4c, 0x50, 0x02, 0x01, +0x4b, 0x29, 0x24, 0x15, 0x1e, 0x13, 0x0a, 0x01, 0x01, 0x21, +0x73, 0x76, 0x18, 0x08, 0x41, 0x0a, 0x1a, 0x2d, 0x51, 0x6f, +0x42, 0x03, 0x11, 0x1f, 0x31, 0x23, 0x0d, 0x19, 0x06, 0x08, +0x11, 0x10, 0x20, 0x24, 0x01, 0x89, 0x89, 0x9f, 0x97, 0x08, +0x15, 0x05, 0x46, 0x64, 0x68, 0x25, 0x3a, 0x49, 0x24, 0x00, +0x00, 0x00, 0x00, 0x02, 0x00, 0x12, 0xff, 0xf5, 0x01, 0xc7, +0x01, 0xdb, 0x00, 0x26, 0x00, 0x2f, 0x00, 0x79, 0xb9, 0x00, +0x2c, 0xff, 0xf0, 0x40, 0x15, 0x0f, 0x10, 0x00, 0x4c, 0x25, +0x08, 0x14, 0x00, 0x4d, 0x25, 0x18, 0x12, 0x13, 0x00, 0x4c, +0x25, 0x10, 0x11, 0x00, 0x4d, 0x07, 0xb8, 0xff, 0xe0, 0xb3, +0x0f, 0x00, 0x4d, 0x01, 0xb8, 0xff, 0xd8, 0x40, 0x2b, 0x11, +0x12, 0x00, 0x4c, 0x27, 0x82, 0x03, 0x0c, 0x0c, 0x03, 0x31, +0x2f, 0x05, 0x82, 0x22, 0x00, 0x14, 0x10, 0x14, 0x02, 0x14, +0x1f, 0x82, 0x19, 0x30, 0x14, 0x05, 0x86, 0x22, 0x1c, 0x2f, +0x2f, 0x00, 0x0b, 0x0b, 0x08, 0x88, 0x0f, 0x51, 0x2a, 0x88, +0x00, 0x50, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x32, 0x2f, 0x11, +0x39, 0x2f, 0xcc, 0x33, 0xed, 0x32, 0x01, 0x10, 0xd6, 0xfd, +0xdc, 0x5d, 0x32, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, 0x10, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, +0x32, 0x16, 0x15, 0x15, 0x23, 0x16, 0x16, 0x33, 0x32, 0x36, +0x37, 0x17, 0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x27, 0x2e, +0x03, 0x35, 0x34, 0x36, 0x37, 0x17, 0x06, 0x15, 0x14, 0x16, +0x17, 0x3e, 0x03, 0x17, 0x34, 0x26, 0x23, 0x22, 0x0e, 0x02, +0x07, 0x01, 0x32, 0x48, 0x4d, 0xe0, 0x04, 0x35, 0x32, 0x1a, +0x26, 0x0a, 0x0b, 0x0a, 0x34, 0x20, 0x2c, 0x42, 0x2e, 0x18, +0x02, 0x1a, 0x2f, 0x23, 0x15, 0x05, 0x02, 0x43, 0x04, 0x20, +0x1d, 0x05, 0x1f, 0x2b, 0x33, 0x5e, 0x26, 0x1e, 0x0f, 0x1a, +0x12, 0x0c, 0x01, 0x01, 0xdb, 0x7c, 0x70, 0x1d, 0x48, 0x4b, +0x0e, 0x08, 0x46, 0x08, 0x12, 0x21, 0x3c, 0x52, 0x30, 0x03, +0x11, 0x1e, 0x2f, 0x22, 0x0d, 0x19, 0x06, 0x08, 0x11, 0x10, +0x1d, 0x25, 0x03, 0x32, 0x4b, 0x31, 0x18, 0xc6, 0x3d, 0x43, +0x16, 0x24, 0x2e, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x12, +0xff, 0x5b, 0x01, 0xdb, 0x02, 0x79, 0x00, 0x29, 0x00, 0x32, +0x00, 0xe5, 0xb9, 0x00, 0x24, 0xff, 0xf0, 0xb3, 0x12, 0x00, +0x4d, 0x24, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x24, +0xb8, 0xff, 0xd8, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x24, 0xb8, +0xff, 0xf0, 0xb3, 0x0a, 0x00, 0x4d, 0x24, 0xb8, 0xff, 0xc8, +0x40, 0x33, 0x09, 0x00, 0x4d, 0x22, 0x20, 0x0f, 0x10, 0x00, +0x4c, 0x22, 0x08, 0x0a, 0x00, 0x4d, 0x22, 0x10, 0x09, 0x00, +0x4d, 0x0f, 0x28, 0x0f, 0x00, 0x4d, 0x0f, 0x08, 0x0c, 0x00, +0x4d, 0x0f, 0x18, 0x0b, 0x00, 0x4d, 0x0f, 0x10, 0x09, 0x0a, +0x00, 0x4c, 0x0e, 0x28, 0x10, 0x00, 0x4d, 0x0e, 0x18, 0x0f, +0x00, 0x4d, 0x08, 0xb8, 0xff, 0xd8, 0xb4, 0x11, 0x12, 0x00, +0x4c, 0x08, 0xb8, 0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x02, +0xb8, 0xff, 0xf0, 0xb3, 0x0e, 0x00, 0x4d, 0x02, 0xb8, 0xff, +0xf8, 0x40, 0x34, 0x0d, 0x00, 0x4d, 0x0a, 0x73, 0x0d, 0x0d, +0x12, 0x2a, 0x76, 0x26, 0x07, 0x07, 0x26, 0x34, 0x32, 0x00, +0x76, 0x20, 0x00, 0x12, 0x10, 0x12, 0x20, 0x12, 0x03, 0x08, +0x12, 0x1d, 0x76, 0x17, 0x33, 0x12, 0x00, 0x79, 0x20, 0x1a, +0x32, 0x32, 0x03, 0x2d, 0x7c, 0x23, 0x45, 0x06, 0x06, 0x03, +0x7c, 0x0d, 0x0b, 0x0a, 0x46, 0x00, 0x3f, 0xcd, 0x33, 0xed, +0x32, 0x2f, 0x3f, 0xed, 0x12, 0x39, 0x2f, 0xcc, 0x33, 0xed, +0x32, 0x01, 0x10, 0xd6, 0xfd, 0xdc, 0x5e, 0x5d, 0x32, 0xed, +0x32, 0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, 0x11, 0x39, 0x2f, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x13, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, +0x06, 0x07, 0x15, 0x23, 0x35, 0x2e, 0x03, 0x27, 0x2e, 0x03, +0x35, 0x34, 0x36, 0x37, 0x17, 0x06, 0x15, 0x14, 0x16, 0x17, +0x36, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x27, +0x34, 0x26, 0x23, 0x22, 0x0e, 0x02, 0x07, 0xed, 0x04, 0x33, +0x43, 0x22, 0x2f, 0x07, 0x16, 0x06, 0x30, 0x23, 0x4e, 0x27, +0x38, 0x23, 0x10, 0x01, 0x1c, 0x32, 0x25, 0x16, 0x05, 0x02, +0x43, 0x04, 0x24, 0x20, 0x08, 0x56, 0x45, 0x4c, 0x50, 0x02, +0x01, 0x4b, 0x29, 0x24, 0x15, 0x1e, 0x13, 0x0a, 0x01, 0x01, +0x21, 0x73, 0x76, 0x18, 0x08, 0x41, 0x08, 0x15, 0x05, 0x9a, +0x9e, 0x09, 0x34, 0x4e, 0x64, 0x3a, 0x03, 0x11, 0x1f, 0x31, +0x23, 0x0d, 0x19, 0x06, 0x08, 0x11, 0x10, 0x20, 0x24, 0x01, +0x89, 0x89, 0x9f, 0x97, 0x08, 0x15, 0x05, 0x46, 0x64, 0x68, +0x25, 0x3a, 0x49, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x12, +0xff, 0x7f, 0x01, 0xc7, 0x01, 0xdb, 0x00, 0x27, 0x00, 0x30, +0x00, 0x92, 0xb9, 0x00, 0x2d, 0xff, 0xe8, 0x40, 0x16, 0x0f, +0x10, 0x00, 0x4c, 0x26, 0x10, 0x11, 0x12, 0x00, 0x4c, 0x13, +0x18, 0x0c, 0x00, 0x4d, 0x13, 0x10, 0x0a, 0x0b, 0x00, 0x4c, +0x07, 0xb8, 0xff, 0xe8, 0xb4, 0x0f, 0x10, 0x00, 0x4c, 0x01, +0xb8, 0xff, 0xd8, 0xb3, 0x12, 0x00, 0x4d, 0x01, 0xb8, 0xff, +0xe0, 0x40, 0x33, 0x11, 0x00, 0x4d, 0x0f, 0x7f, 0x12, 0x12, +0x15, 0x28, 0x82, 0x0c, 0x03, 0x32, 0x30, 0x05, 0x82, 0x23, +0x00, 0x15, 0x10, 0x15, 0x20, 0x15, 0x03, 0x08, 0x15, 0x20, +0x82, 0x1a, 0x31, 0x0d, 0x15, 0x05, 0x86, 0x23, 0x1d, 0x30, +0x30, 0x00, 0x0b, 0x0b, 0x08, 0x88, 0x12, 0x10, 0x0f, 0x51, +0x2b, 0x88, 0x00, 0x50, 0x00, 0x3f, 0xed, 0x3f, 0xcd, 0x33, +0xed, 0x32, 0x2f, 0x11, 0x39, 0x2f, 0xcc, 0x33, 0xed, 0x32, +0x01, 0x2f, 0x10, 0xd6, 0xfd, 0xdc, 0x5e, 0x5d, 0x32, 0xed, +0x32, 0x10, 0xde, 0x32, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x32, +0x16, 0x15, 0x15, 0x23, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, +0x17, 0x06, 0x06, 0x07, 0x15, 0x23, 0x35, 0x26, 0x26, 0x27, +0x2e, 0x03, 0x35, 0x34, 0x36, 0x37, 0x17, 0x06, 0x15, 0x14, +0x16, 0x17, 0x3e, 0x03, 0x17, 0x34, 0x26, 0x23, 0x22, 0x0e, +0x02, 0x07, 0x01, 0x32, 0x48, 0x4d, 0xe0, 0x04, 0x35, 0x32, +0x1a, 0x26, 0x0a, 0x0b, 0x08, 0x1f, 0x15, 0x4f, 0x42, 0x44, +0x03, 0x1a, 0x2f, 0x23, 0x15, 0x05, 0x02, 0x43, 0x04, 0x20, +0x1d, 0x05, 0x1f, 0x2b, 0x33, 0x5e, 0x26, 0x1e, 0x0f, 0x1a, +0x12, 0x0c, 0x01, 0x01, 0xdb, 0x7c, 0x70, 0x1d, 0x48, 0x4b, +0x0e, 0x08, 0x46, 0x06, 0x0d, 0x04, 0x79, 0x7b, 0x10, 0x75, +0x55, 0x03, 0x11, 0x1e, 0x2f, 0x22, 0x0d, 0x19, 0x06, 0x08, +0x11, 0x10, 0x1d, 0x25, 0x03, 0x32, 0x4b, 0x31, 0x18, 0xc6, +0x3d, 0x43, 0x16, 0x24, 0x2e, 0x18, 0x00, 0x00, 0xff, 0xff, +0x00, 0x59, 0x00, 0x00, 0x01, 0x9b, 0x02, 0x6b, 0x02, 0x06, +0x00, 0x2c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x04, 0x00, 0x00, +0x01, 0xf1, 0x03, 0x23, 0x02, 0x26, 0x02, 0xc9, 0x00, 0x00, +0x01, 0x07, 0x03, 0x90, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x13, +0xb9, 0x00, 0x01, 0xff, 0xff, 0x40, 0x09, 0x31, 0x39, 0x07, +0x26, 0x50, 0x01, 0x11, 0x2e, 0x4f, 0x2b, 0x2b, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x00, 0x01, 0xeb, +0x02, 0x98, 0x02, 0x26, 0x02, 0xe9, 0x00, 0x00, 0x01, 0x06, +0x03, 0x90, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, +0x35, 0x3d, 0x1f, 0x10, 0x50, 0x01, 0x05, 0x32, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x01, 0x00, 0x2e, 0xff, 0x5b, 0x01, 0xd8, +0x02, 0x6b, 0x00, 0x2b, 0x00, 0x87, 0x40, 0x16, 0x23, 0x18, +0x11, 0x12, 0x00, 0x4c, 0x22, 0x20, 0x0e, 0x00, 0x4d, 0x22, +0x10, 0x0d, 0x00, 0x4d, 0x1e, 0x18, 0x0e, 0x00, 0x4d, 0x14, +0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x13, 0xb8, 0xff, +0xe8, 0xb3, 0x0f, 0x00, 0x4d, 0x13, 0xb8, 0xff, 0xe8, 0xb3, +0x09, 0x00, 0x4d, 0x0e, 0xb8, 0xff, 0xe0, 0x40, 0x2a, 0x08, +0x00, 0x4d, 0x0c, 0x06, 0x01, 0x06, 0x78, 0x07, 0x0c, 0x14, +0x07, 0x0c, 0x07, 0x07, 0x20, 0x76, 0x11, 0x2d, 0x01, 0x19, +0x19, 0x28, 0x73, 0x2a, 0x2c, 0x25, 0x7c, 0x01, 0x0c, 0x0c, +0x2a, 0x2b, 0x41, 0x2a, 0x44, 0x1d, 0x7c, 0x16, 0x06, 0x07, +0x41, 0x00, 0x3f, 0x33, 0x2f, 0xed, 0x3f, 0x3f, 0x12, 0x39, +0x2f, 0x33, 0xed, 0x01, 0x10, 0xd6, 0xed, 0x32, 0x2f, 0x32, +0x10, 0xde, 0xed, 0x33, 0x2f, 0x87, 0x2b, 0x87, 0x7d, 0xc4, +0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x13, 0x11, 0x3e, 0x03, 0x37, 0x33, 0x0e, 0x03, 0x07, +0x1e, 0x03, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x22, 0x27, +0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x2e, 0x02, +0x23, 0x22, 0x06, 0x07, 0x11, 0x23, 0x11, 0x80, 0x1e, 0x43, +0x41, 0x3b, 0x15, 0x66, 0x19, 0x38, 0x3c, 0x3f, 0x1f, 0x30, +0x52, 0x3e, 0x23, 0x1a, 0x34, 0x4d, 0x34, 0x0d, 0x1b, 0x0b, +0x03, 0x05, 0x0f, 0x0d, 0x3c, 0x4e, 0x29, 0x3e, 0x46, 0x1c, +0x0c, 0x1a, 0x0d, 0x52, 0x02, 0x6b, 0xfe, 0xe5, 0x1e, 0x4b, +0x4d, 0x48, 0x1d, 0x21, 0x45, 0x47, 0x45, 0x1f, 0x04, 0x1e, +0x3b, 0x5b, 0x42, 0x38, 0x5f, 0x46, 0x28, 0x02, 0x43, 0x01, +0x01, 0x60, 0x62, 0x40, 0x4b, 0x26, 0x0b, 0x01, 0x01, 0xfe, +0xe6, 0x02, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x47, +0xff, 0x5a, 0x01, 0xcc, 0x01, 0xd0, 0x00, 0x27, 0x00, 0x75, +0x40, 0x11, 0x1f, 0x30, 0x0f, 0x00, 0x4d, 0x1f, 0x10, 0x0d, +0x0e, 0x00, 0x4c, 0x1b, 0x20, 0x0f, 0x00, 0x4d, 0x0d, 0xb8, +0xff, 0xe8, 0xb3, 0x09, 0x00, 0x4d, 0x0c, 0xb8, 0xff, 0xf0, +0x40, 0x2b, 0x0a, 0x00, 0x4d, 0x1d, 0x82, 0x0e, 0x00, 0x05, +0x05, 0x81, 0x06, 0x0b, 0x14, 0x06, 0x0b, 0x05, 0x06, 0x06, +0x0e, 0x29, 0x16, 0x16, 0x00, 0x23, 0x7f, 0x25, 0x28, 0x0b, +0x22, 0x89, 0x0b, 0x0b, 0x25, 0x26, 0x49, 0x25, 0x4a, 0x1a, +0x89, 0x13, 0x4b, 0x06, 0x49, 0x00, 0x3f, 0x3f, 0xed, 0x3f, +0x3f, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x2f, 0x10, 0xd6, 0xed, +0x32, 0x32, 0x2f, 0x10, 0xce, 0x32, 0x2f, 0x00, 0xc1, 0x87, +0x05, 0x2b, 0x04, 0x7d, 0x10, 0xc4, 0x01, 0x18, 0x10, 0xed, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x3e, 0x03, +0x37, 0x33, 0x0e, 0x03, 0x07, 0x16, 0x16, 0x15, 0x14, 0x0e, +0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, +0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x15, 0x23, +0x11, 0x33, 0x9a, 0x16, 0x3a, 0x3b, 0x35, 0x11, 0x61, 0x14, +0x31, 0x36, 0x36, 0x18, 0x5c, 0x68, 0x19, 0x30, 0x48, 0x2f, +0x0b, 0x16, 0x08, 0x05, 0x05, 0x0b, 0x08, 0x39, 0x41, 0x57, +0x51, 0x0d, 0x20, 0x06, 0x53, 0x53, 0x01, 0x06, 0x15, 0x35, +0x37, 0x35, 0x14, 0x17, 0x31, 0x31, 0x30, 0x16, 0x05, 0x74, +0x67, 0x2b, 0x4e, 0x3b, 0x23, 0x01, 0x02, 0x42, 0x01, 0x01, +0x4c, 0x48, 0x56, 0x4e, 0x03, 0x02, 0xd0, 0x01, 0xd0, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x0d, 0xff, 0x57, 0x01, 0xe2, +0x02, 0x6b, 0x00, 0x21, 0x00, 0x63, 0xb9, 0x00, 0x06, 0xff, +0xe0, 0xb4, 0x11, 0x12, 0x00, 0x4c, 0x06, 0xb8, 0xff, 0xf0, +0xb3, 0x0c, 0x00, 0x4d, 0x06, 0xb8, 0xff, 0xf8, 0xb3, 0x0b, +0x00, 0x4d, 0x03, 0xb8, 0xff, 0xf8, 0x40, 0x22, 0x0d, 0x00, +0x4d, 0x19, 0x1a, 0x1f, 0x73, 0x14, 0x00, 0x73, 0x11, 0x11, +0x09, 0x20, 0x73, 0x13, 0x14, 0x23, 0x09, 0x22, 0x1a, 0x19, +0x13, 0x79, 0x20, 0x44, 0x00, 0x79, 0x11, 0x41, 0x09, 0x79, +0x08, 0x46, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x3f, 0xed, 0xdc, +0x19, 0xc5, 0x01, 0x18, 0x10, 0xc6, 0x10, 0xde, 0xd5, 0xed, +0x11, 0x39, 0x2f, 0xed, 0x10, 0xfd, 0xde, 0x19, 0xc5, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x06, 0x06, 0x07, 0x0e, +0x03, 0x07, 0x27, 0x36, 0x36, 0x37, 0x3e, 0x03, 0x35, 0x21, +0x11, 0x33, 0x16, 0x0e, 0x02, 0x07, 0x27, 0x3e, 0x03, 0x37, +0x23, 0x11, 0xee, 0x03, 0x0c, 0x16, 0x0b, 0x1e, 0x2b, 0x39, +0x26, 0x09, 0x2c, 0x30, 0x14, 0x0a, 0x0d, 0x07, 0x03, 0x01, +0x1c, 0x27, 0x01, 0x10, 0x1d, 0x29, 0x17, 0x3c, 0x09, 0x17, +0x15, 0x12, 0x05, 0x1d, 0x02, 0x25, 0x66, 0xb4, 0x51, 0x28, +0x46, 0x34, 0x1f, 0x02, 0x48, 0x07, 0x41, 0x45, 0x24, 0x5e, +0x6c, 0x76, 0x3b, 0xfd, 0xdf, 0x1f, 0x42, 0x40, 0x3b, 0x17, +0x26, 0x09, 0x1c, 0x23, 0x27, 0x14, 0x02, 0x25, 0x00, 0x00, +0x00, 0x01, 0x00, 0x0d, 0xff, 0x6c, 0x01, 0xe3, 0x01, 0xd0, +0x00, 0x1f, 0x00, 0x56, 0xb5, 0x0b, 0x20, 0x0b, 0x00, 0x4d, +0x07, 0xb8, 0xff, 0xf0, 0xb3, 0x0d, 0x00, 0x4d, 0x07, 0xb8, +0xff, 0xe8, 0x40, 0x22, 0x0c, 0x00, 0x4d, 0x17, 0x18, 0x1d, +0x7f, 0x14, 0x00, 0x7f, 0x11, 0x11, 0x09, 0x1e, 0x7f, 0x13, +0x14, 0x21, 0x09, 0x20, 0x18, 0x17, 0x13, 0x85, 0x1e, 0x4a, +0x00, 0x85, 0x11, 0x49, 0x09, 0x85, 0x08, 0x51, 0x00, 0x3f, +0xed, 0x3f, 0xed, 0x3f, 0xed, 0xdc, 0x19, 0xc5, 0x01, 0x18, +0x10, 0xc6, 0x10, 0xde, 0xd5, 0xed, 0x11, 0x39, 0x2f, 0xed, +0x10, 0xfd, 0xde, 0x19, 0xc5, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x13, 0x14, 0x0e, 0x02, 0x07, 0x06, 0x06, 0x07, 0x27, 0x36, +0x36, 0x37, 0x3e, 0x02, 0x34, 0x35, 0x21, 0x11, 0x33, 0x16, +0x06, 0x07, 0x27, 0x3e, 0x03, 0x37, 0x23, 0x11, 0xeb, 0x03, +0x07, 0x0c, 0x0a, 0x14, 0x52, 0x4c, 0x0c, 0x2c, 0x33, 0x0f, +0x0d, 0x0d, 0x06, 0x01, 0x1f, 0x27, 0x02, 0x36, 0x29, 0x3a, +0x06, 0x13, 0x13, 0x11, 0x05, 0x24, 0x01, 0x8b, 0x1e, 0x43, +0x43, 0x41, 0x1c, 0x39, 0x52, 0x08, 0x46, 0x08, 0x31, 0x23, +0x1e, 0x4c, 0x54, 0x54, 0x25, 0xfe, 0x75, 0x3f, 0x74, 0x26, +0x23, 0x06, 0x18, 0x1f, 0x23, 0x11, 0x01, 0x8b, 0x00, 0x01, +0x00, 0x2d, 0xff, 0x59, 0x01, 0xc7, 0x02, 0x6b, 0x00, 0x19, +0x00, 0x35, 0x40, 0x1c, 0x19, 0x0a, 0x11, 0x73, 0x02, 0x1b, +0x18, 0x14, 0x73, 0x15, 0x1a, 0x13, 0x79, 0x0f, 0x18, 0x1f, +0x18, 0x02, 0x18, 0x18, 0x15, 0x00, 0x16, 0x41, 0x15, 0x44, +0x0e, 0x07, 0x00, 0x2f, 0xcd, 0x3f, 0x3f, 0x33, 0x12, 0x39, +0x2f, 0x5d, 0xed, 0x01, 0x10, 0xd6, 0xed, 0x32, 0x10, 0xde, +0xfd, 0xcc, 0x33, 0x31, 0x30, 0x01, 0x33, 0x11, 0x14, 0x0e, +0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, 0x33, 0x32, +0x36, 0x35, 0x11, 0x23, 0x11, 0x23, 0x11, 0x33, 0x11, 0x33, +0x01, 0x75, 0x52, 0x0b, 0x1e, 0x34, 0x28, 0x0d, 0x20, 0x0a, +0x08, 0x08, 0x17, 0x07, 0x21, 0x1b, 0xf6, 0x52, 0x52, 0xf6, +0x02, 0x6b, 0xfd, 0x95, 0x29, 0x3f, 0x2a, 0x15, 0x05, 0x02, +0x41, 0x02, 0x02, 0x2b, 0x29, 0x01, 0x2f, 0xfe, 0xe0, 0x02, +0x6b, 0xfe, 0xfb, 0x00, 0x00, 0x01, 0x00, 0x47, 0xff, 0x59, +0x01, 0xad, 0x01, 0xd0, 0x00, 0x19, 0x00, 0x3d, 0x40, 0x22, +0x17, 0x08, 0x0f, 0x7f, 0x00, 0x1b, 0x16, 0x12, 0x7f, 0x00, +0x13, 0x01, 0x13, 0x1a, 0x11, 0x85, 0x0f, 0x16, 0x1f, 0x16, +0x02, 0x08, 0x16, 0x16, 0x13, 0x18, 0x14, 0x49, 0x13, 0x4a, +0x0c, 0x89, 0x05, 0x4b, 0x00, 0x3f, 0xed, 0x3f, 0x3f, 0x33, +0x12, 0x39, 0x2f, 0x5e, 0x5d, 0xed, 0x01, 0x10, 0xd6, 0x5d, +0xed, 0x32, 0x10, 0xde, 0xfd, 0xcc, 0x33, 0x31, 0x30, 0x21, +0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x16, +0x33, 0x32, 0x36, 0x35, 0x35, 0x23, 0x15, 0x23, 0x11, 0x33, +0x15, 0x33, 0x35, 0x33, 0x01, 0xad, 0x0b, 0x1e, 0x34, 0x28, +0x0d, 0x20, 0x0b, 0x08, 0x08, 0x17, 0x08, 0x20, 0x1b, 0xc0, +0x53, 0x53, 0xc0, 0x53, 0x29, 0x3f, 0x2a, 0x15, 0x05, 0x02, +0x41, 0x02, 0x02, 0x2b, 0x29, 0xdc, 0xcd, 0x01, 0xd0, 0xbd, +0xbd, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2d, 0xff, 0x57, +0x01, 0xe2, 0x02, 0x6b, 0x00, 0x17, 0x00, 0x47, 0x40, 0x25, +0x08, 0x09, 0x0e, 0x73, 0x03, 0x17, 0x0f, 0x73, 0x02, 0x03, +0x19, 0x16, 0x12, 0x73, 0x13, 0x18, 0x11, 0x79, 0x0f, 0x16, +0x1f, 0x16, 0x02, 0x16, 0x16, 0x13, 0x00, 0x14, 0x41, 0x13, +0x44, 0x09, 0x08, 0x02, 0x79, 0x0f, 0x44, 0x00, 0x3f, 0xed, +0xdc, 0x19, 0xc5, 0x18, 0x3f, 0x3f, 0x33, 0x12, 0x39, 0x2f, +0x5d, 0xed, 0x01, 0x10, 0xd6, 0xed, 0x32, 0x10, 0xde, 0xd5, +0xed, 0x32, 0x10, 0xfd, 0xde, 0x19, 0xc5, 0x31, 0x30, 0x01, +0x33, 0x11, 0x33, 0x16, 0x0e, 0x02, 0x07, 0x27, 0x3e, 0x03, +0x37, 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, 0x33, 0x11, 0x33, +0x01, 0x68, 0x52, 0x27, 0x01, 0x10, 0x1d, 0x29, 0x17, 0x3c, +0x09, 0x17, 0x15, 0x12, 0x05, 0x1d, 0xe9, 0x52, 0x52, 0xe9, +0x02, 0x6b, 0xfd, 0xdf, 0x1f, 0x42, 0x40, 0x3b, 0x17, 0x26, +0x09, 0x1c, 0x23, 0x27, 0x14, 0x01, 0x20, 0xfe, 0xe0, 0x02, +0x6b, 0xfe, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x47, +0xff, 0x6c, 0x01, 0xe3, 0x01, 0xd0, 0x00, 0x15, 0x00, 0x47, +0x40, 0x24, 0x04, 0x05, 0x0a, 0x7f, 0x01, 0x13, 0x0b, 0x7f, +0x00, 0x01, 0x17, 0x12, 0x0d, 0x7f, 0x00, 0x0f, 0x01, 0x08, +0x0f, 0x16, 0x0d, 0x85, 0x12, 0x12, 0x0f, 0x14, 0x10, 0x49, +0x0f, 0x4a, 0x05, 0x04, 0x00, 0x85, 0x0b, 0x4a, 0x00, 0x3f, +0xed, 0xdc, 0x19, 0xc5, 0x18, 0x3f, 0x3f, 0x33, 0x12, 0x39, +0x2f, 0xed, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x10, +0xde, 0xd5, 0xed, 0x32, 0x10, 0xfd, 0xde, 0x19, 0xc5, 0x31, +0x30, 0x25, 0x33, 0x16, 0x06, 0x07, 0x27, 0x3e, 0x03, 0x37, +0x23, 0x35, 0x23, 0x15, 0x23, 0x11, 0x33, 0x15, 0x33, 0x35, +0x33, 0x01, 0xba, 0x27, 0x02, 0x36, 0x29, 0x3a, 0x06, 0x13, +0x13, 0x11, 0x05, 0x24, 0xce, 0x53, 0x53, 0xce, 0x52, 0x45, +0x3f, 0x74, 0x26, 0x23, 0x06, 0x18, 0x1f, 0x23, 0x11, 0xcd, +0xcd, 0x01, 0xd0, 0xbd, 0xbd, 0x00, 0x00, 0x01, 0x00, 0x36, +0xff, 0x5b, 0x01, 0xbf, 0x02, 0x6b, 0x00, 0x1b, 0x00, 0x50, +0x40, 0x10, 0x17, 0x18, 0x0a, 0x00, 0x4d, 0x17, 0x10, 0x09, +0x00, 0x4d, 0x16, 0x10, 0x0a, 0x00, 0x4d, 0x03, 0xb8, 0xff, +0xe0, 0x40, 0x1e, 0x11, 0x12, 0x00, 0x4c, 0x09, 0x10, 0x73, +0x0b, 0x0f, 0x73, 0x0c, 0x0b, 0x1d, 0x00, 0x73, 0x19, 0x1c, +0x05, 0x7c, 0x14, 0x14, 0x0c, 0x09, 0x1a, 0x41, 0x0f, 0x79, +0x0d, 0x0c, 0x44, 0x00, 0x3f, 0xcd, 0xed, 0x3f, 0x33, 0x12, +0x39, 0x2f, 0xed, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xd5, +0xed, 0x10, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x13, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x36, 0x37, 0x11, 0x33, +0x11, 0x23, 0x15, 0x23, 0x35, 0x33, 0x35, 0x06, 0x06, 0x23, +0x22, 0x2e, 0x02, 0x35, 0x35, 0x33, 0x89, 0x0b, 0x1c, 0x30, +0x24, 0x20, 0x3b, 0x0e, 0x52, 0x2a, 0x4f, 0x27, 0x0f, 0x42, +0x23, 0x3c, 0x4c, 0x2b, 0x10, 0x53, 0x01, 0xb8, 0x26, 0x39, +0x26, 0x12, 0x0a, 0x04, 0x01, 0x3c, 0xfd, 0x95, 0xa5, 0xeb, +0xa2, 0x05, 0x09, 0x1f, 0x3a, 0x52, 0x33, 0xb3, 0x00, 0x00, +0x00, 0x01, 0x00, 0x36, 0xff, 0x7f, 0x01, 0xad, 0x01, 0xd0, +0x00, 0x1b, 0x00, 0x45, 0x40, 0x29, 0x18, 0x18, 0x0b, 0x00, +0x4d, 0x18, 0x20, 0x0a, 0x00, 0x4d, 0x18, 0x18, 0x09, 0x00, +0x4d, 0x08, 0x0f, 0x7f, 0x0a, 0x0e, 0x7f, 0x0b, 0x0a, 0x1d, +0x01, 0x7f, 0x1a, 0x1c, 0x04, 0x88, 0x15, 0x15, 0x0b, 0x08, +0x1b, 0x49, 0x0e, 0x85, 0x0c, 0x0b, 0x4a, 0x00, 0x3f, 0xcd, +0xed, 0x3f, 0x33, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xd6, +0xed, 0x10, 0xde, 0xd5, 0xed, 0x10, 0xed, 0x32, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x13, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, +0x37, 0x35, 0x33, 0x11, 0x23, 0x15, 0x23, 0x35, 0x33, 0x35, +0x0e, 0x03, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x35, 0x88, 0x39, +0x32, 0x24, 0x30, 0x13, 0x53, 0x2b, 0x4f, 0x27, 0x07, 0x19, +0x1f, 0x22, 0x10, 0x28, 0x42, 0x2f, 0x1a, 0x01, 0xd0, 0x88, +0x35, 0x2a, 0x07, 0x05, 0xdb, 0xfe, 0x30, 0x81, 0xc7, 0x6d, +0x02, 0x05, 0x05, 0x04, 0x11, 0x26, 0x3f, 0x2e, 0x89, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0xff, 0x57, 0x01, 0xe2, +0x02, 0x6b, 0x00, 0x26, 0x00, 0xc4, 0xb9, 0x00, 0x26, 0xff, +0xf0, 0xb3, 0x0c, 0x00, 0x4d, 0x26, 0xb8, 0xff, 0xe0, 0xb3, +0x0b, 0x00, 0x4d, 0x03, 0xb8, 0xff, 0xf8, 0xb4, 0x10, 0x13, +0x00, 0x4c, 0x03, 0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, +0x03, 0xb8, 0xff, 0xf0, 0xb3, 0x0d, 0x00, 0x4d, 0x02, 0xb8, +0xff, 0xf8, 0x40, 0x0a, 0x0d, 0x00, 0x4d, 0x01, 0x28, 0x0b, +0x0c, 0x00, 0x4c, 0x0b, 0xb8, 0xff, 0xe8, 0x40, 0x46, 0x12, +0x00, 0x4d, 0x0b, 0x0c, 0x11, 0x73, 0x06, 0x19, 0x26, 0x00, +0x26, 0x7b, 0x1a, 0x19, 0x14, 0x1a, 0x1a, 0x19, 0x18, 0x01, +0x00, 0x01, 0x7b, 0x17, 0x18, 0x14, 0x17, 0x17, 0x18, 0x00, +0x1a, 0x17, 0x17, 0x12, 0x73, 0x02, 0x20, 0x05, 0x30, 0x05, +0x02, 0x05, 0x06, 0x28, 0x1a, 0x1f, 0x73, 0x25, 0x20, 0x27, +0x1a, 0x26, 0x41, 0x18, 0x00, 0x19, 0x19, 0x1f, 0x20, 0x44, +0x0c, 0x0b, 0x05, 0x79, 0x12, 0x44, 0x17, 0x01, 0x41, 0x00, +0x3f, 0x33, 0x3f, 0xed, 0xdc, 0x19, 0xc5, 0x18, 0x3f, 0x33, +0x33, 0x2f, 0x33, 0x33, 0x3f, 0x33, 0x01, 0x10, 0xd6, 0x32, +0xed, 0x32, 0x10, 0xd6, 0xd5, 0x5d, 0x32, 0xed, 0x32, 0x11, +0x12, 0x39, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x87, 0x18, +0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, 0x10, 0xfd, 0xde, +0x19, 0xc5, 0x2b, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x13, 0x13, 0x33, 0x16, 0x12, 0x17, 0x33, 0x16, +0x0e, 0x02, 0x07, 0x27, 0x3e, 0x03, 0x37, 0x23, 0x2e, 0x03, +0x27, 0x03, 0x23, 0x03, 0x0e, 0x03, 0x07, 0x23, 0x3e, 0x03, +0x37, 0x33, 0xef, 0x55, 0x4d, 0x12, 0x11, 0x06, 0x27, 0x01, +0x10, 0x1d, 0x29, 0x17, 0x3c, 0x09, 0x17, 0x15, 0x12, 0x05, +0x18, 0x01, 0x02, 0x03, 0x03, 0x02, 0x4f, 0x47, 0x51, 0x01, +0x03, 0x03, 0x03, 0x01, 0x50, 0x03, 0x08, 0x0b, 0x0f, 0x09, +0x4c, 0x01, 0x37, 0x01, 0x34, 0x82, 0xfe, 0xf3, 0x92, 0x1f, +0x42, 0x40, 0x3b, 0x17, 0x26, 0x09, 0x1c, 0x23, 0x27, 0x14, +0x36, 0x7e, 0x86, 0x8a, 0x41, 0xfe, 0xe6, 0x01, 0x1a, 0x41, +0x89, 0x87, 0x7e, 0x36, 0x4c, 0xa0, 0x9e, 0x9a, 0x47, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x1b, 0xff, 0x6c, 0x01, 0xe3, +0x01, 0xd0, 0x00, 0x2c, 0x00, 0xad, 0x40, 0x23, 0x18, 0x19, +0x1e, 0x7f, 0x15, 0x10, 0x18, 0x0e, 0x0f, 0x00, 0x4c, 0x10, +0x28, 0x0d, 0x00, 0x4d, 0x10, 0x20, 0x0b, 0x0c, 0x00, 0x4c, +0x10, 0x27, 0x22, 0x27, 0x84, 0x0d, 0x10, 0x14, 0x0d, 0x10, +0x22, 0x1f, 0x0a, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, 0x00, 0x4d, +0x0a, 0xb8, 0xff, 0xd8, 0xb4, 0x0d, 0x0e, 0x00, 0x4c, 0x0a, +0xb8, 0xff, 0xe0, 0xb3, 0x0c, 0x00, 0x4d, 0x0a, 0xb8, 0xff, +0xd8, 0x40, 0x2e, 0x0b, 0x00, 0x4d, 0x0a, 0x28, 0x00, 0x28, +0x84, 0x0d, 0x0a, 0x14, 0x0d, 0x0d, 0x0a, 0x0d, 0x03, 0x1f, +0x7f, 0x11, 0x14, 0x15, 0x2e, 0x00, 0x03, 0x7f, 0x09, 0x04, +0x2d, 0x19, 0x18, 0x14, 0x85, 0x1f, 0x4a, 0x22, 0x10, 0x49, +0x00, 0x0a, 0x49, 0x27, 0x0d, 0x28, 0x28, 0x04, 0x4a, 0x00, +0x3f, 0x33, 0x2f, 0x33, 0x33, 0x3f, 0x33, 0x3f, 0x33, 0x3f, +0xed, 0xdc, 0x19, 0xc5, 0x01, 0x18, 0x10, 0xd6, 0x32, 0xed, +0x32, 0x10, 0xde, 0xd5, 0x32, 0xed, 0x11, 0x39, 0x87, 0x10, +0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x11, +0x33, 0x87, 0x18, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x2b, 0x2b, +0x2b, 0x18, 0x10, 0xfd, 0xde, 0x19, 0xc5, 0x31, 0x30, 0x13, +0x06, 0x06, 0x07, 0x23, 0x3e, 0x03, 0x37, 0x33, 0x16, 0x16, +0x17, 0x36, 0x36, 0x37, 0x33, 0x16, 0x16, 0x17, 0x33, 0x16, +0x06, 0x07, 0x27, 0x3e, 0x03, 0x37, 0x23, 0x26, 0x26, 0x27, +0x0e, 0x03, 0x07, 0x23, 0x2e, 0x03, 0x77, 0x08, 0x01, 0x03, +0x50, 0x01, 0x07, 0x09, 0x0b, 0x06, 0x4d, 0x14, 0x30, 0x1d, +0x20, 0x2e, 0x15, 0x4d, 0x0b, 0x0f, 0x05, 0x27, 0x02, 0x36, +0x29, 0x3a, 0x06, 0x13, 0x13, 0x11, 0x05, 0x20, 0x02, 0x03, +0x07, 0x09, 0x10, 0x10, 0x15, 0x0e, 0x52, 0x0e, 0x13, 0x10, +0x10, 0x01, 0x56, 0x5b, 0xad, 0x4e, 0x37, 0x76, 0x78, 0x76, +0x35, 0x36, 0x95, 0x59, 0x59, 0x95, 0x36, 0x5b, 0xce, 0x62, +0x3f, 0x74, 0x26, 0x23, 0x06, 0x18, 0x1f, 0x23, 0x11, 0x4e, +0xb3, 0x55, 0x25, 0x36, 0x35, 0x3b, 0x2a, 0x2a, 0x3b, 0x35, +0x36, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x59, 0x00, 0x00, +0x01, 0x9b, 0x02, 0x6b, 0x02, 0x06, 0x00, 0x2c, 0x00, 0x00, +0xff, 0xff, 0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x03, 0x23, +0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x01, 0x07, 0x03, 0x90, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, +0x1a, 0x22, 0x04, 0x0f, 0x50, 0x02, 0x09, 0x17, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x3a, 0xff, 0xf5, +0x01, 0xb0, 0x02, 0x98, 0x02, 0x26, 0x00, 0x44, 0x00, 0x00, +0x01, 0x06, 0x03, 0x90, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, +0x02, 0x04, 0x34, 0x3c, 0x1c, 0x13, 0x50, 0x02, 0x0f, 0x31, +0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x09, 0x00, 0x00, +0x01, 0xeb, 0x03, 0x1a, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, +0x01, 0x07, 0x00, 0x83, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x17, +0x40, 0x10, 0x03, 0x02, 0x00, 0x19, 0x2b, 0x04, 0x0f, 0x50, +0x03, 0x09, 0x23, 0x4f, 0x02, 0x09, 0x17, 0x4f, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x3a, +0xff, 0xf5, 0x01, 0xb0, 0x02, 0x8f, 0x02, 0x26, 0x00, 0x44, +0x00, 0x00, 0x01, 0x06, 0x00, 0x83, 0x00, 0x00, 0x00, 0x17, +0x40, 0x10, 0x03, 0x02, 0x05, 0x33, 0x45, 0x1c, 0x13, 0x50, +0x03, 0x0f, 0x3d, 0x4f, 0x02, 0x0f, 0x31, 0x4f, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x1b, 0x00, 0x00, +0x01, 0xe2, 0x02, 0x6b, 0x02, 0x06, 0x00, 0xa1, 0x00, 0x00, +0xff, 0xff, 0x00, 0x1f, 0xff, 0xf5, 0x01, 0xde, 0x01, 0xdb, +0x02, 0x06, 0x00, 0xc1, 0x00, 0x00, 0xff, 0xff, 0x00, 0x5b, +0x00, 0x00, 0x01, 0xcc, 0x03, 0x23, 0x02, 0x26, 0x00, 0x28, +0x00, 0x00, 0x01, 0x07, 0x03, 0x90, 0x00, 0x12, 0x00, 0x8b, +0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xf8, 0x40, 0x09, 0x0f, +0x17, 0x00, 0x0a, 0x50, 0x01, 0x01, 0x0c, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, +0x01, 0xc7, 0x02, 0x98, 0x02, 0x26, 0x00, 0x48, 0x00, 0x00, +0x01, 0x06, 0x03, 0x90, 0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, +0x02, 0x02, 0x25, 0x2d, 0x13, 0x02, 0x50, 0x02, 0x00, 0x22, +0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x19, 0xff, 0xf3, +0x01, 0xd8, 0x02, 0x79, 0x02, 0x06, 0x01, 0xe8, 0x00, 0x00, +0xff, 0xff, 0x00, 0x2d, 0xff, 0xf5, 0x01, 0xcc, 0x01, 0xdb, +0x02, 0x06, 0x02, 0x35, 0x00, 0x00, 0xff, 0xff, 0x00, 0x19, +0xff, 0xf3, 0x01, 0xd8, 0x03, 0x1a, 0x02, 0x26, 0x01, 0xe8, +0x00, 0x00, 0x01, 0x07, 0x00, 0x83, 0xff, 0xef, 0x00, 0x8b, +0x00, 0x1a, 0xb1, 0x03, 0x02, 0xb8, 0xff, 0xf1, 0x40, 0x0d, +0x29, 0x3b, 0x19, 0x11, 0x50, 0x03, 0x0c, 0x33, 0x4f, 0x02, +0x0c, 0x27, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0xff, 0xff, +0x00, 0x2d, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0x8f, 0x02, 0x26, +0x02, 0x35, 0x00, 0x00, 0x01, 0x06, 0x00, 0x83, 0xf8, 0x00, +0x00, 0x1a, 0xb1, 0x03, 0x02, 0xb8, 0xff, 0xf6, 0x40, 0x0d, +0x26, 0x38, 0x02, 0x15, 0x50, 0x03, 0x10, 0x30, 0x4f, 0x02, +0x10, 0x24, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x04, 0x00, 0x00, 0x01, 0xf1, 0x03, 0x1a, +0x02, 0x26, 0x02, 0xc9, 0x00, 0x00, 0x01, 0x07, 0x00, 0x83, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, +0x00, 0x30, 0x42, 0x07, 0x26, 0x50, 0x02, 0x11, 0x3a, 0x4f, +0x01, 0x11, 0x2e, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x00, 0x01, 0xeb, +0x02, 0x8f, 0x02, 0x26, 0x02, 0xe9, 0x00, 0x00, 0x01, 0x06, +0x00, 0x83, 0x00, 0x00, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, +0x01, 0x34, 0x46, 0x1f, 0x10, 0x50, 0x02, 0x05, 0x3e, 0x4f, +0x01, 0x05, 0x32, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0xff, 0xff, 0x00, 0x26, 0xff, 0xf4, 0x01, 0xd1, 0x03, 0x1a, +0x02, 0x26, 0x02, 0xca, 0x00, 0x00, 0x01, 0x07, 0x00, 0x83, +0xff, 0xf8, 0x00, 0x8b, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, +0xff, 0xf7, 0x40, 0x0d, 0x37, 0x49, 0x27, 0x1c, 0x50, 0x02, +0x0f, 0x41, 0x4f, 0x01, 0x0f, 0x35, 0x4f, 0x2b, 0x2b, 0x2b, +0x34, 0x34, 0xff, 0xff, 0x00, 0x48, 0xff, 0xf5, 0x01, 0xbf, +0x02, 0x8f, 0x02, 0x26, 0x02, 0xea, 0x00, 0x00, 0x01, 0x06, +0x00, 0x83, 0xf8, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, +0xff, 0xef, 0x40, 0x0d, 0x2f, 0x41, 0x16, 0x0f, 0x50, 0x02, +0x02, 0x39, 0x4f, 0x01, 0x02, 0x2d, 0x4f, 0x2b, 0x2b, 0x2b, +0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x18, 0xff, 0xf3, +0x01, 0xcf, 0x02, 0x6b, 0x02, 0x06, 0x02, 0x0f, 0x00, 0x00, +0xff, 0xff, 0x00, 0x2c, 0xff, 0x5b, 0x01, 0xaf, 0x01, 0xd0, +0x02, 0x06, 0x02, 0xa3, 0x00, 0x00, 0xff, 0xff, 0x00, 0x37, +0x00, 0x00, 0x01, 0xbd, 0x03, 0x06, 0x02, 0x26, 0x02, 0xcb, +0x00, 0x00, 0x01, 0x07, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x8b, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x12, 0x13, 0x00, 0x09, +0x50, 0x01, 0x01, 0x14, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x3f, 0x00, 0x00, 0x01, 0xb6, 0x02, 0x7b, +0x02, 0x26, 0x02, 0xeb, 0x00, 0x00, 0x01, 0x06, 0x00, 0x8a, +0x00, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x12, 0x13, +0x09, 0x00, 0x50, 0x01, 0x00, 0x14, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x37, 0x00, 0x00, 0x01, 0xbd, 0x03, 0x1a, +0x02, 0x26, 0x02, 0xcb, 0x00, 0x00, 0x01, 0x07, 0x00, 0x83, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, +0x00, 0x14, 0x26, 0x00, 0x09, 0x50, 0x02, 0x01, 0x1e, 0x4f, +0x01, 0x01, 0x12, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x3f, 0x00, 0x00, 0x01, 0xb6, +0x02, 0x8f, 0x02, 0x26, 0x02, 0xeb, 0x00, 0x00, 0x01, 0x06, +0x00, 0x83, 0x00, 0x00, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, +0x00, 0x14, 0x26, 0x09, 0x00, 0x50, 0x02, 0x00, 0x1e, 0x4f, +0x01, 0x00, 0x12, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0xff, 0xff, 0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, 0x03, 0x1a, +0x02, 0x26, 0x00, 0x32, 0x00, 0x00, 0x01, 0x07, 0x00, 0x83, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x17, 0x40, 0x10, 0x03, 0x02, +0x00, 0x22, 0x34, 0x00, 0x09, 0x50, 0x03, 0x04, 0x2c, 0x4f, +0x02, 0x04, 0x20, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, +0x02, 0x8f, 0x02, 0x26, 0x00, 0x52, 0x00, 0x00, 0x01, 0x06, +0x00, 0x83, 0x00, 0x00, 0x00, 0x17, 0x40, 0x10, 0x03, 0x02, +0x00, 0x22, 0x34, 0x09, 0x00, 0x50, 0x03, 0x0e, 0x2c, 0x4f, +0x02, 0x0e, 0x20, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x03, 0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, 0x02, 0x79, +0x00, 0x13, 0x00, 0x1a, 0x00, 0x21, 0x00, 0x88, 0xb5, 0x21, +0x10, 0x0e, 0x00, 0x4d, 0x1c, 0xb8, 0xff, 0xf0, 0xb3, 0x0e, +0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xf0, 0xb3, 0x0e, 0x00, 0x4d, +0x1a, 0xb8, 0xff, 0xe8, 0x40, 0x14, 0x0d, 0x00, 0x4d, 0x15, +0x10, 0x0e, 0x00, 0x4d, 0x15, 0x18, 0x0d, 0x00, 0x4d, 0x11, +0x10, 0x0f, 0x10, 0x00, 0x4c, 0x0d, 0xb8, 0xff, 0xf0, 0xb4, +0x0f, 0x10, 0x00, 0x4c, 0x07, 0xb8, 0xff, 0xe8, 0x40, 0x2a, +0x0f, 0x10, 0x00, 0x4c, 0x03, 0x10, 0x10, 0x00, 0x4d, 0x03, +0x18, 0x0f, 0x00, 0x4d, 0x1f, 0x17, 0x76, 0x0a, 0x23, 0x1e, +0x18, 0x76, 0x00, 0x40, 0x0b, 0x10, 0x48, 0x00, 0x22, 0x18, +0x79, 0x1e, 0x1e, 0x05, 0x14, 0x7c, 0x0f, 0x46, 0x1b, 0x7c, +0x05, 0x45, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x11, 0x39, 0x2f, +0xed, 0x01, 0x10, 0xd6, 0x2b, 0xed, 0x32, 0x10, 0xde, 0xed, +0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x34, 0x3e, 0x02, 0x33, 0x32, +0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, +0x17, 0x32, 0x36, 0x37, 0x21, 0x16, 0x16, 0x13, 0x22, 0x06, +0x07, 0x21, 0x26, 0x26, 0x1d, 0x20, 0x3b, 0x51, 0x32, 0x31, +0x51, 0x3b, 0x20, 0x20, 0x3b, 0x51, 0x31, 0x32, 0x51, 0x3b, +0x20, 0xdc, 0x42, 0x44, 0x05, 0xfe, 0xed, 0x05, 0x42, 0x41, +0x40, 0x43, 0x05, 0x01, 0x13, 0x06, 0x44, 0x01, 0x36, 0x53, +0x7a, 0x4f, 0x27, 0x27, 0x4f, 0x7a, 0x53, 0x53, 0x7a, 0x50, +0x26, 0x26, 0x50, 0x7a, 0xa9, 0x72, 0x6b, 0x6b, 0x72, 0x01, +0xf8, 0x6f, 0x69, 0x69, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x03, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x01, 0xdb, 0x00, 0x13, +0x00, 0x1a, 0x00, 0x21, 0x00, 0x73, 0x40, 0x0c, 0x21, 0x20, +0x0f, 0x10, 0x00, 0x4c, 0x21, 0x10, 0x0e, 0x00, 0x4d, 0x1c, +0xb8, 0xff, 0xd8, 0xb3, 0x10, 0x00, 0x4d, 0x1c, 0xb8, 0xff, +0xe0, 0xb3, 0x0f, 0x00, 0x4d, 0x1c, 0xb8, 0xff, 0xf0, 0xb3, +0x0e, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe8, 0x40, 0x2b, 0x0f, +0x10, 0x00, 0x4c, 0x15, 0x18, 0x0f, 0x10, 0x00, 0x4c, 0x1f, +0x17, 0x82, 0x00, 0x23, 0x1e, 0x18, 0x82, 0x0a, 0x40, 0x09, +0x0c, 0x48, 0x0a, 0x22, 0x18, 0x86, 0x3f, 0x1e, 0x4f, 0x1e, +0x02, 0x1e, 0x1e, 0x14, 0x1b, 0x88, 0x0f, 0x50, 0x14, 0x88, +0x05, 0x51, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x12, 0x39, 0x2f, +0x5d, 0xed, 0x01, 0x10, 0xd6, 0x2b, 0xed, 0x32, 0x10, 0xde, +0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x25, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x07, 0x32, 0x36, +0x37, 0x23, 0x16, 0x16, 0x13, 0x22, 0x06, 0x07, 0x33, 0x26, +0x26, 0x01, 0xcc, 0x1f, 0x38, 0x4e, 0x2e, 0x2d, 0x4d, 0x38, +0x1f, 0x1f, 0x38, 0x4d, 0x2d, 0x2e, 0x4e, 0x38, 0x1f, 0xd3, +0x36, 0x44, 0x06, 0xfe, 0x08, 0x41, 0x35, 0x32, 0x43, 0x08, +0xfc, 0x08, 0x44, 0xe8, 0x37, 0x59, 0x40, 0x23, 0x23, 0x40, +0x59, 0x37, 0x37, 0x5a, 0x3f, 0x23, 0x23, 0x3f, 0x5a, 0xe0, +0x4a, 0x47, 0x48, 0x49, 0x01, 0x53, 0x44, 0x42, 0x42, 0x44, +0x00, 0x00, 0xff, 0xff, 0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, +0x03, 0x1a, 0x02, 0x26, 0x03, 0x78, 0x00, 0x00, 0x01, 0x07, +0x00, 0x83, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x17, 0x40, 0x10, +0x04, 0x03, 0x00, 0x24, 0x36, 0x00, 0x09, 0x50, 0x04, 0x04, +0x2e, 0x4f, 0x03, 0x04, 0x22, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, +0x01, 0xcc, 0x02, 0x8f, 0x02, 0x26, 0x03, 0x79, 0x00, 0x00, +0x01, 0x06, 0x00, 0x83, 0x00, 0x00, 0x00, 0x17, 0x40, 0x10, +0x04, 0x03, 0x00, 0x24, 0x36, 0x09, 0x00, 0x50, 0x04, 0x0e, +0x2e, 0x4f, 0x03, 0x0e, 0x22, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, +0x34, 0x00, 0xff, 0xff, 0x00, 0x2e, 0xff, 0xf3, 0x01, 0xd5, +0x03, 0x1a, 0x02, 0x26, 0x02, 0xe0, 0x00, 0x00, 0x01, 0x07, +0x00, 0x83, 0xff, 0xef, 0x00, 0x8b, 0x00, 0x1a, 0xb1, 0x02, +0x01, 0xb8, 0xff, 0xe8, 0x40, 0x0d, 0x29, 0x3b, 0x0f, 0x04, +0x50, 0x02, 0x00, 0x33, 0x4f, 0x01, 0x00, 0x27, 0x4f, 0x2b, +0x2b, 0x2b, 0x34, 0x34, 0xff, 0xff, 0x00, 0x3b, 0xff, 0xf5, +0x01, 0xcc, 0x02, 0x8f, 0x02, 0x26, 0x03, 0x00, 0x00, 0x00, +0x01, 0x06, 0x00, 0x83, 0xef, 0x00, 0x00, 0x1a, 0xb1, 0x02, +0x01, 0xb8, 0xff, 0xe6, 0x40, 0x0d, 0x27, 0x39, 0x08, 0x00, +0x50, 0x02, 0x1f, 0x31, 0x4f, 0x01, 0x1f, 0x25, 0x4f, 0x2b, +0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x09, +0xff, 0xf8, 0x01, 0xee, 0x03, 0x06, 0x02, 0x26, 0x02, 0xd6, +0x00, 0x00, 0x01, 0x07, 0x00, 0x8a, 0x00, 0x09, 0x00, 0x8b, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x07, 0x26, 0x27, 0x0b, 0x15, +0x50, 0x01, 0x0b, 0x28, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x24, 0xff, 0x58, 0x01, 0xcd, 0x02, 0x7b, +0x02, 0x26, 0x00, 0x5c, 0x00, 0x00, 0x01, 0x06, 0x00, 0x8a, +0x12, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x13, 0x21, 0x22, +0x20, 0x15, 0x50, 0x01, 0x09, 0x23, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x09, 0xff, 0xf8, 0x01, 0xee, 0x03, 0x1a, +0x02, 0x26, 0x02, 0xd6, 0x00, 0x00, 0x01, 0x07, 0x00, 0x83, +0x00, 0x09, 0x00, 0x8b, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, +0x07, 0x28, 0x3a, 0x0b, 0x15, 0x50, 0x02, 0x0b, 0x32, 0x4f, +0x01, 0x0b, 0x26, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0x58, 0x01, 0xcd, +0x02, 0x8f, 0x02, 0x26, 0x00, 0x5c, 0x00, 0x00, 0x01, 0x06, +0x00, 0x83, 0x12, 0x00, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, +0x13, 0x23, 0x35, 0x20, 0x15, 0x50, 0x02, 0x09, 0x2d, 0x4f, +0x01, 0x09, 0x21, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0xff, 0xff, 0x00, 0x09, 0xff, 0xf8, 0x01, 0xee, 0x03, 0x3e, +0x02, 0x26, 0x02, 0xd6, 0x00, 0x00, 0x01, 0x07, 0x01, 0x65, +0x00, 0x24, 0x00, 0x89, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, +0x22, 0x28, 0x2a, 0x0b, 0x15, 0x50, 0x02, 0x0b, 0x2b, 0x4f, +0x01, 0x0b, 0x27, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0x58, 0x01, 0xcd, +0x02, 0xb5, 0x02, 0x26, 0x00, 0x5c, 0x00, 0x00, 0x01, 0x06, +0x01, 0x65, 0x2d, 0x00, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, +0x2e, 0x23, 0x25, 0x20, 0x15, 0x50, 0x02, 0x09, 0x26, 0x4f, +0x01, 0x09, 0x22, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0xff, 0xff, 0x00, 0x36, 0x00, 0x00, 0x01, 0xbf, 0x03, 0x1a, +0x02, 0x26, 0x02, 0xda, 0x00, 0x00, 0x01, 0x07, 0x00, 0x83, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, +0x00, 0x1a, 0x2c, 0x14, 0x0a, 0x50, 0x02, 0x09, 0x24, 0x4f, +0x01, 0x09, 0x18, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x36, 0x00, 0x00, 0x01, 0xad, +0x02, 0x8f, 0x02, 0x26, 0x02, 0xfa, 0x00, 0x00, 0x01, 0x06, +0x00, 0x83, 0x00, 0x00, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, +0x08, 0x1a, 0x2c, 0x15, 0x09, 0x50, 0x02, 0x00, 0x24, 0x4f, +0x01, 0x00, 0x18, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x01, 0x00, 0x36, 0xff, 0x5b, 0x01, 0xcc, 0x02, 0x6b, +0x00, 0x0b, 0x00, 0x28, 0x40, 0x14, 0x03, 0x0d, 0x09, 0x73, +0x06, 0x05, 0x73, 0x00, 0x0b, 0x0c, 0x05, 0x00, 0x79, 0x08, +0x0a, 0x44, 0x04, 0x79, 0x01, 0x41, 0x00, 0x3f, 0xed, 0x3f, +0xce, 0xed, 0x32, 0x01, 0x10, 0xd6, 0xdd, 0xfd, 0xdd, 0xed, +0x10, 0xce, 0x31, 0x30, 0x37, 0x11, 0x21, 0x15, 0x23, 0x11, +0x33, 0x15, 0x23, 0x35, 0x23, 0x35, 0x8f, 0x01, 0x3d, 0xeb, +0x86, 0x4f, 0xe2, 0x46, 0x02, 0x25, 0x46, 0xfe, 0x21, 0xeb, +0xa5, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x6b, 0xff, 0x7f, +0x01, 0xb8, 0x01, 0xd0, 0x00, 0x09, 0x00, 0x24, 0x40, 0x12, +0x04, 0x0b, 0x07, 0x7f, 0x00, 0x06, 0x7f, 0x01, 0x0a, 0x05, +0x85, 0x02, 0x49, 0x09, 0x06, 0x85, 0x01, 0x4a, 0x00, 0x3f, +0xed, 0xce, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0xed, 0xdd, 0xed, +0x10, 0xce, 0x31, 0x30, 0x33, 0x23, 0x11, 0x21, 0x15, 0x23, +0x11, 0x33, 0x15, 0x23, 0xa3, 0x38, 0x01, 0x4d, 0xfb, 0x35, +0x4f, 0x01, 0xd0, 0x45, 0xfe, 0xbb, 0xc7, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x24, 0xff, 0xfa, 0x01, 0xd0, 0x03, 0x1a, +0x02, 0x26, 0x02, 0xde, 0x00, 0x00, 0x01, 0x07, 0x00, 0x83, +0x00, 0x00, 0x00, 0x8b, 0x00, 0x17, 0x40, 0x10, 0x04, 0x03, +0x00, 0x24, 0x36, 0x06, 0x1f, 0x50, 0x04, 0x07, 0x2e, 0x4f, +0x03, 0x07, 0x22, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x2d, 0xff, 0xf6, 0x01, 0xc7, +0x02, 0x8f, 0x02, 0x26, 0x02, 0xfe, 0x00, 0x00, 0x01, 0x06, +0x00, 0x83, 0x00, 0x00, 0x00, 0x17, 0x40, 0x10, 0x04, 0x03, +0x00, 0x24, 0x36, 0x0d, 0x1e, 0x50, 0x04, 0x0d, 0x2e, 0x4f, +0x03, 0x0d, 0x22, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x04, 0x00, 0x24, 0x00, 0x00, 0x01, 0xe2, 0x02, 0x78, +0x00, 0x0b, 0x00, 0x17, 0x00, 0x1b, 0x00, 0x27, 0x00, 0x9d, +0xb9, 0x00, 0x0a, 0xff, 0xf0, 0xb4, 0x0e, 0x0f, 0x00, 0x4c, +0x0a, 0xb8, 0xff, 0xe8, 0x40, 0x18, 0x0d, 0x00, 0x4d, 0x08, +0x10, 0x0f, 0x00, 0x4d, 0x08, 0x10, 0x0d, 0x00, 0x4d, 0x04, +0x10, 0x0f, 0x00, 0x4d, 0x04, 0x18, 0x0d, 0x00, 0x4d, 0x02, +0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x02, 0xb8, 0xff, +0xe8, 0x40, 0x35, 0x0d, 0x0e, 0x00, 0x4c, 0x18, 0x18, 0x06, +0x0c, 0x12, 0x00, 0x19, 0x19, 0x00, 0x29, 0x26, 0x20, 0x21, +0x20, 0x7e, 0x27, 0x26, 0x14, 0x27, 0x27, 0x26, 0x27, 0x1d, +0x21, 0x24, 0x4f, 0x23, 0x01, 0x23, 0x1d, 0x1e, 0x28, 0x21, +0x26, 0x44, 0x23, 0x41, 0x27, 0x20, 0x41, 0x0f, 0x03, 0x18, +0x1b, 0x1e, 0x44, 0x15, 0x09, 0x45, 0x00, 0x3f, 0xcd, 0x3f, +0xdc, 0xdd, 0xde, 0xcd, 0x3f, 0x33, 0x3f, 0x3f, 0x33, 0x01, +0x10, 0xd6, 0xdd, 0xdc, 0x5d, 0xcd, 0x33, 0x11, 0x33, 0x87, +0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, 0x10, 0xc6, 0x32, +0x2f, 0x10, 0xdd, 0xde, 0xcd, 0x32, 0x2f, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x14, 0x06, +0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x07, +0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, +0x06, 0x03, 0x33, 0x15, 0x23, 0x27, 0x15, 0x23, 0x11, 0x33, +0x13, 0x27, 0x35, 0x33, 0x11, 0x23, 0x03, 0x01, 0xe2, 0x25, +0x2b, 0x2b, 0x26, 0x26, 0x2b, 0x2b, 0x25, 0x6b, 0x0f, 0x0c, +0x0b, 0x10, 0x10, 0x0b, 0x0c, 0x0f, 0x36, 0xa1, 0xa1, 0xdf, +0x3e, 0x42, 0x77, 0x09, 0x3e, 0x42, 0x77, 0x01, 0xcf, 0x4e, +0x5c, 0x5c, 0x4e, 0x4e, 0x5b, 0x5b, 0x4f, 0x38, 0x38, 0x38, +0x38, 0x38, 0x37, 0x37, 0xfe, 0xc5, 0x45, 0x75, 0xfb, 0x02, +0x6b, 0xfe, 0x4c, 0xb7, 0xfd, 0xfd, 0x95, 0x01, 0xb4, 0x00, +0x00, 0x01, 0x00, 0x00, 0x00, 0xec, 0x01, 0xf4, 0x01, 0x32, +0x00, 0x03, 0x00, 0x0d, 0xb3, 0x03, 0x02, 0x00, 0x03, 0x00, +0x2f, 0xcd, 0x01, 0x2f, 0x2f, 0x31, 0x30, 0x11, 0x21, 0x15, +0x21, 0x01, 0xf4, 0xfe, 0x0c, 0x01, 0x32, 0x46, 0x00, 0x00, +0x00, 0x01, 0x00, 0x1f, 0xff, 0xf3, 0x01, 0xd4, 0x02, 0x78, +0x00, 0x3c, 0x00, 0xe8, 0x40, 0x11, 0x30, 0x18, 0x0d, 0x00, +0x4d, 0x30, 0x10, 0x0c, 0x00, 0x4d, 0x30, 0x18, 0x0a, 0x0b, +0x00, 0x4c, 0x2b, 0xb8, 0xff, 0xe8, 0xb4, 0x11, 0x12, 0x00, +0x4c, 0x2b, 0xb8, 0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x25, +0xb8, 0xff, 0xf0, 0xb3, 0x12, 0x00, 0x4d, 0x25, 0xb8, 0xff, +0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x13, 0xb8, 0xff, 0xf0, 0xb3, +0x12, 0x00, 0x4d, 0x13, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, +0x4d, 0x13, 0xb8, 0xff, 0xf8, 0xb3, 0x0c, 0x00, 0x4d, 0x13, +0xb8, 0xff, 0xf0, 0x40, 0x54, 0x09, 0x0b, 0x00, 0x4c, 0x1f, +0x18, 0x18, 0x21, 0x1e, 0x1a, 0x17, 0x04, 0x15, 0x23, 0x35, +0x38, 0x3c, 0x02, 0x04, 0x32, 0x04, 0x76, 0x15, 0x2a, 0x2a, +0x15, 0x3e, 0x00, 0x36, 0x36, 0x23, 0x76, 0x32, 0x0d, 0x0d, +0x00, 0x32, 0x10, 0x32, 0x20, 0x32, 0x03, 0x08, 0x32, 0x3d, +0x1a, 0x3c, 0x79, 0x02, 0x17, 0x02, 0x21, 0x35, 0x79, 0x38, +0x1e, 0x38, 0xaf, 0x02, 0xbf, 0x02, 0x02, 0x0f, 0x38, 0x1f, +0x38, 0x02, 0x02, 0x38, 0x02, 0x38, 0x10, 0x29, 0x29, 0x26, +0x7c, 0x2d, 0x46, 0x0c, 0x0c, 0x09, 0x7c, 0x10, 0x45, 0x00, +0x3f, 0xed, 0x32, 0x2f, 0x3f, 0xed, 0x32, 0x2f, 0x11, 0x39, +0x39, 0x2f, 0x2f, 0x5d, 0x5d, 0x11, 0x33, 0x10, 0xed, 0x32, +0x11, 0x33, 0x10, 0xed, 0x32, 0x01, 0x10, 0xc6, 0x5e, 0x5d, +0x32, 0x2f, 0x10, 0xed, 0x33, 0x2f, 0x33, 0x10, 0xcc, 0x32, +0x2f, 0x10, 0xed, 0x11, 0x17, 0x39, 0x11, 0x12, 0x17, 0x39, +0x32, 0x2f, 0x33, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x35, 0x21, 0x36, +0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, +0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x07, 0x33, 0x15, +0x23, 0x06, 0x06, 0x07, 0x07, 0x33, 0x15, 0x21, 0x06, 0x15, +0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, 0x06, 0x23, +0x22, 0x2e, 0x02, 0x35, 0x34, 0x36, 0x37, 0x23, 0x35, 0x33, +0x36, 0x36, 0x37, 0x37, 0x1f, 0x01, 0x31, 0x0c, 0x13, 0x1e, +0x26, 0x14, 0x2e, 0x3d, 0x15, 0x11, 0x26, 0x46, 0x25, 0x34, +0x49, 0x2c, 0x14, 0x09, 0x2f, 0x51, 0x15, 0x39, 0x23, 0x27, +0xe9, 0xfe, 0xd2, 0x0e, 0x38, 0x40, 0x34, 0x43, 0x1e, 0x18, +0x2a, 0x59, 0x2b, 0x3b, 0x4d, 0x2e, 0x13, 0x04, 0x05, 0x30, +0x53, 0x15, 0x40, 0x28, 0x21, 0x01, 0x66, 0x3c, 0x16, 0x1c, +0x17, 0x23, 0x17, 0x0c, 0x11, 0x08, 0x48, 0x0b, 0x0d, 0x1d, +0x2f, 0x3b, 0x1e, 0x1c, 0x15, 0x3c, 0x13, 0x24, 0x15, 0x16, +0x3c, 0x15, 0x1f, 0x2a, 0x30, 0x13, 0x0e, 0x42, 0x16, 0x10, +0x1a, 0x2b, 0x38, 0x1e, 0x11, 0x1d, 0x0c, 0x3c, 0x14, 0x24, +0x17, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x21, 0x00, 0x00, +0x01, 0xd2, 0x02, 0x6b, 0x00, 0x17, 0x00, 0x97, 0x40, 0x4e, +0x07, 0x10, 0x0f, 0x08, 0x0f, 0x14, 0x03, 0x04, 0x13, 0x13, +0x13, 0x0f, 0x16, 0x0d, 0x0a, 0x0d, 0x0e, 0x09, 0x0e, 0x06, +0x11, 0x12, 0x05, 0x05, 0x05, 0x09, 0x01, 0x07, 0x06, 0x03, +0x0a, 0x73, 0x14, 0x11, 0x10, 0x0d, 0x0d, 0x19, 0x18, 0x12, +0x0e, 0x08, 0x04, 0x02, 0x15, 0x79, 0x17, 0x05, 0x04, 0x09, +0x08, 0x13, 0x12, 0x0f, 0x0e, 0x10, 0x08, 0x20, 0x08, 0x02, +0x00, 0x0e, 0x01, 0x08, 0x04, 0x08, 0x12, 0x0e, 0x0e, 0x12, +0x08, 0x04, 0x04, 0x0c, 0x17, 0x41, 0x0c, 0x44, 0x00, 0x3f, +0x3f, 0x12, 0x17, 0x39, 0x2f, 0x2f, 0x2f, 0x2f, 0x5e, 0x5d, +0x5d, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x10, +0xed, 0x32, 0x01, 0x2f, 0x2f, 0x2f, 0x2f, 0x11, 0x12, 0x39, +0x2f, 0x33, 0x33, 0x33, 0xfd, 0x32, 0x32, 0x32, 0xcc, 0xcd, +0x32, 0x2f, 0x7d, 0x87, 0x04, 0xc4, 0xc4, 0x10, 0x87, 0xc4, +0xc4, 0x01, 0x18, 0x10, 0xcc, 0xcd, 0x32, 0x2f, 0x7d, 0x87, +0x04, 0xc4, 0xc4, 0x10, 0x87, 0xc4, 0xc4, 0x31, 0x30, 0x01, +0x15, 0x23, 0x15, 0x37, 0x17, 0x07, 0x15, 0x37, 0x17, 0x07, +0x15, 0x23, 0x35, 0x07, 0x27, 0x37, 0x35, 0x07, 0x27, 0x37, +0x35, 0x23, 0x35, 0x01, 0xd2, 0xb0, 0x68, 0x1b, 0x83, 0x68, +0x1b, 0x83, 0x51, 0x68, 0x1a, 0x82, 0x68, 0x1a, 0x82, 0xb0, +0x02, 0x6b, 0x48, 0x88, 0x31, 0x38, 0x3e, 0x67, 0x31, 0x38, +0x3d, 0xab, 0x89, 0x31, 0x39, 0x3c, 0x67, 0x30, 0x38, 0x3d, +0xaa, 0x48, 0x00, 0x02, 0x00, 0x28, 0x00, 0x00, 0x01, 0xcb, +0x02, 0x6b, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x2b, 0x40, 0x15, +0x0a, 0x06, 0x04, 0x09, 0x01, 0x03, 0x73, 0x04, 0x04, 0x0c, +0x0d, 0x02, 0x06, 0x79, 0x07, 0x0a, 0x79, 0x0b, 0x41, 0x04, +0x44, 0x00, 0x3f, 0x3f, 0xfd, 0xde, 0xed, 0x32, 0x01, 0x11, +0x12, 0x39, 0x2f, 0xfd, 0xce, 0x32, 0x10, 0xce, 0x32, 0x31, +0x30, 0x01, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, 0x25, +0x15, 0x21, 0x35, 0x01, 0xcb, 0xa9, 0x51, 0xa9, 0x01, 0xa3, +0xfe, 0x5d, 0x01, 0xd0, 0x45, 0xfe, 0x75, 0x01, 0x8b, 0x45, +0x9b, 0x46, 0x46, 0x00, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x00, +0x01, 0xd0, 0x02, 0x6f, 0x00, 0x18, 0x00, 0x27, 0x00, 0x9c, +0xb5, 0x21, 0x10, 0x10, 0x00, 0x4d, 0x14, 0xb8, 0xff, 0xd8, +0xb4, 0x11, 0x12, 0x00, 0x4c, 0x14, 0xb8, 0xff, 0xe0, 0xb4, +0x09, 0x0a, 0x00, 0x4c, 0x12, 0xb8, 0xff, 0xe0, 0xb3, 0x12, +0x00, 0x4d, 0x12, 0xb8, 0xff, 0xd0, 0xb3, 0x11, 0x00, 0x4d, +0x12, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x12, 0xb8, +0xff, 0xe0, 0xb3, 0x09, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xe0, +0x40, 0x30, 0x12, 0x00, 0x4d, 0x23, 0x76, 0x13, 0x00, 0x00, +0x13, 0x29, 0x0a, 0x06, 0x1d, 0x18, 0x03, 0x73, 0x0c, 0x08, +0x04, 0x28, 0x09, 0x17, 0x79, 0x1d, 0x0c, 0x1d, 0x05, 0x02, +0x79, 0x18, 0x08, 0x18, 0x0f, 0x1d, 0x1f, 0x1d, 0x02, 0x1d, +0x18, 0x1d, 0x18, 0x04, 0x19, 0x7c, 0x10, 0x41, 0x04, 0x44, +0x00, 0x3f, 0x3f, 0xed, 0x12, 0x39, 0x39, 0x2f, 0x2f, 0x5d, +0x11, 0x33, 0x10, 0xed, 0x32, 0x11, 0x33, 0x10, 0xed, 0x32, +0x01, 0x10, 0xd6, 0x32, 0x32, 0xed, 0x32, 0x32, 0xce, 0x32, +0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x15, 0x23, 0x15, +0x23, 0x35, 0x23, 0x35, 0x33, 0x35, 0x23, 0x35, 0x33, 0x11, +0x36, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x23, +0x15, 0x13, 0x22, 0x06, 0x07, 0x15, 0x33, 0x32, 0x3e, 0x02, +0x35, 0x34, 0x2e, 0x02, 0x01, 0x7e, 0xc9, 0x51, 0x49, 0x49, +0x49, 0x49, 0x21, 0x4c, 0x23, 0x6c, 0x70, 0x7b, 0x78, 0x28, +0x45, 0x1f, 0x1e, 0x07, 0x23, 0x25, 0x3d, 0x2a, 0x17, 0x15, +0x24, 0x2f, 0x9e, 0x3f, 0x5f, 0x5f, 0x3f, 0x5b, 0x40, 0x01, +0x27, 0x09, 0x06, 0x5e, 0x5e, 0x62, 0x58, 0x5b, 0x01, 0x8c, +0x02, 0x01, 0xee, 0x0a, 0x1b, 0x30, 0x26, 0x22, 0x2d, 0x1b, +0x0c, 0x00, 0x00, 0x01, 0x00, 0x74, 0x02, 0x1b, 0x01, 0x7f, +0x02, 0x98, 0x00, 0x0d, 0x00, 0x15, 0xb7, 0x0b, 0x0a, 0x03, +0x04, 0x0a, 0x04, 0x07, 0x00, 0x00, 0x2f, 0xdd, 0xce, 0x32, +0x01, 0x2f, 0xcd, 0xde, 0xcd, 0x31, 0x30, 0x13, 0x22, 0x26, +0x27, 0x37, 0x16, 0x16, 0x33, 0x32, 0x36, 0x37, 0x17, 0x06, +0x06, 0xfa, 0x38, 0x46, 0x08, 0x3f, 0x08, 0x22, 0x1d, 0x1d, +0x22, 0x08, 0x3e, 0x08, 0x45, 0x02, 0x1b, 0x39, 0x33, 0x11, +0x1d, 0x23, 0x23, 0x1d, 0x11, 0x33, 0x39, 0x00, 0xff, 0xff, +0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x02, 0x6b, 0x02, 0x06, +0x00, 0x24, 0x00, 0x00, 0x00, 0x03, 0x00, 0x36, 0xff, 0xfb, +0x01, 0xc2, 0x02, 0x71, 0x00, 0x1a, 0x00, 0x29, 0x00, 0x38, +0x00, 0x7a, 0x40, 0x51, 0x7b, 0x32, 0x01, 0x6a, 0x32, 0x01, +0x79, 0x2e, 0x01, 0x6a, 0x2e, 0x01, 0x6a, 0x26, 0x7a, 0x26, +0x02, 0x6b, 0x22, 0x7b, 0x22, 0x02, 0x85, 0x19, 0x95, 0x19, +0x02, 0x95, 0x17, 0x01, 0x81, 0x16, 0x01, 0x94, 0x13, 0x01, +0x85, 0x13, 0x01, 0x90, 0x0e, 0x01, 0x14, 0x0e, 0x84, 0x0e, +0x02, 0x05, 0x0e, 0x01, 0x15, 0x30, 0x76, 0x10, 0x10, 0x24, +0x76, 0x18, 0x3a, 0x2a, 0x1b, 0x73, 0x10, 0x05, 0x01, 0x05, +0x39, 0x15, 0x1b, 0x79, 0x2a, 0x2a, 0x1f, 0x35, 0x7c, 0x0b, +0x41, 0x1f, 0x7c, 0x00, 0x43, 0x00, 0x3f, 0xed, 0x3f, 0xed, +0x12, 0x39, 0x2f, 0xed, 0x39, 0x01, 0x10, 0xd6, 0x5d, 0xed, +0x32, 0x10, 0xde, 0xed, 0x33, 0x2f, 0xed, 0x32, 0x31, 0x30, +0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, +0x5d, 0x5d, 0x5d, 0x5d, 0x17, 0x22, 0x2e, 0x02, 0x27, 0x11, +0x3e, 0x03, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, +0x07, 0x16, 0x16, 0x15, 0x14, 0x06, 0x03, 0x15, 0x16, 0x16, +0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x27, +0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, +0x06, 0x07, 0xcc, 0x0f, 0x28, 0x28, 0x28, 0x0f, 0x0f, 0x27, +0x29, 0x27, 0x10, 0x2e, 0x50, 0x3b, 0x21, 0x0e, 0x18, 0x1e, +0x10, 0x30, 0x40, 0x75, 0xc5, 0x02, 0x29, 0x1f, 0x1f, 0x39, +0x2c, 0x1a, 0x14, 0x24, 0x31, 0x1e, 0x61, 0x4e, 0x19, 0x2e, +0x23, 0x14, 0x16, 0x24, 0x2f, 0x1a, 0x1a, 0x27, 0x08, 0x05, +0x02, 0x03, 0x06, 0x04, 0x02, 0x58, 0x04, 0x06, 0x03, 0x02, +0x10, 0x26, 0x3e, 0x2e, 0x16, 0x28, 0x22, 0x1c, 0x09, 0x11, +0x48, 0x3c, 0x5c, 0x5e, 0x01, 0x26, 0xdd, 0x01, 0x03, 0x0a, +0x1b, 0x2c, 0x23, 0x1f, 0x2a, 0x19, 0x0b, 0x44, 0x0a, 0x16, +0x26, 0x1d, 0x1b, 0x26, 0x18, 0x0a, 0x01, 0x02, 0xff, 0xff, +0x00, 0x36, 0x00, 0x00, 0x01, 0xcc, 0x02, 0x6b, 0x02, 0x06, +0x02, 0xc6, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0x00, 0x00, +0x01, 0xeb, 0x02, 0x6b, 0x00, 0x0b, 0x00, 0x16, 0x00, 0x4c, +0x40, 0x29, 0x06, 0x12, 0x0c, 0x12, 0x78, 0x0b, 0x06, 0x14, +0x0b, 0x0b, 0x06, 0x05, 0x11, 0x0c, 0x11, 0x78, 0x00, 0x05, +0x14, 0x00, 0x00, 0x05, 0x0c, 0x0c, 0x00, 0x0b, 0x18, 0x00, +0x17, 0x0b, 0x44, 0x06, 0x41, 0x0c, 0x05, 0x41, 0x12, 0x11, +0x79, 0x00, 0x44, 0x00, 0x3f, 0xed, 0x32, 0x3f, 0x33, 0x3f, +0x3f, 0x01, 0x10, 0xc6, 0x10, 0xce, 0x11, 0x39, 0x3d, 0x2f, +0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x87, 0x18, 0x10, +0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x33, 0x3e, 0x03, 0x37, +0x33, 0x1e, 0x03, 0x17, 0x03, 0x0e, 0x03, 0x07, 0x21, 0x2e, +0x03, 0x09, 0x17, 0x2d, 0x2e, 0x33, 0x1e, 0x5f, 0x1b, 0x36, +0x33, 0x2c, 0x10, 0xee, 0x09, 0x21, 0x27, 0x2b, 0x14, 0x01, +0x17, 0x14, 0x29, 0x24, 0x1e, 0x59, 0x9d, 0x95, 0x92, 0x4e, +0x46, 0xa3, 0xa5, 0x9d, 0x40, 0x02, 0x23, 0x19, 0x5b, 0x7c, +0x98, 0x55, 0x55, 0x98, 0x7c, 0x5c, 0xff, 0xff, 0x00, 0x5b, +0x00, 0x00, 0x01, 0xcc, 0x02, 0x6b, 0x02, 0x06, 0x00, 0x28, +0x00, 0x00, 0x00, 0x01, 0x00, 0x36, 0x00, 0x00, 0x01, 0xc7, +0x02, 0x6b, 0x00, 0x11, 0x00, 0x37, 0x40, 0x1d, 0x05, 0x0e, +0x09, 0x0e, 0x78, 0x00, 0x05, 0x14, 0x00, 0x00, 0x05, 0x06, +0x06, 0x00, 0x13, 0x0f, 0x0f, 0x09, 0x12, 0x00, 0x0e, 0x79, +0x10, 0x41, 0x09, 0x05, 0x79, 0x08, 0x44, 0x00, 0x3f, 0xed, +0x32, 0x3f, 0xed, 0x32, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, +0xce, 0x32, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x31, +0x30, 0x01, 0x0e, 0x03, 0x07, 0x21, 0x15, 0x21, 0x35, 0x3e, +0x03, 0x37, 0x21, 0x35, 0x21, 0x01, 0xbf, 0x20, 0x4f, 0x52, +0x4d, 0x1d, 0x01, 0x33, 0xfe, 0x6f, 0x21, 0x4b, 0x4e, 0x4d, +0x23, 0xfe, 0xe5, 0x01, 0x7a, 0x02, 0x28, 0x2c, 0x78, 0x83, +0x84, 0x37, 0x46, 0x43, 0x3d, 0x7f, 0x7d, 0x76, 0x33, 0x46, +0x00, 0x00, 0xff, 0xff, 0x00, 0x2d, 0x00, 0x00, 0x01, 0xc7, +0x02, 0x6b, 0x02, 0x06, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x03, +0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, 0x02, 0x79, 0x00, 0x03, +0x00, 0x17, 0x00, 0x23, 0x00, 0xd0, 0xb9, 0x00, 0x22, 0xff, +0xf0, 0x40, 0x15, 0x0d, 0x0e, 0x00, 0x4c, 0x20, 0x10, 0x0d, +0x0e, 0x00, 0x4c, 0x1c, 0x18, 0x0e, 0x00, 0x4d, 0x1c, 0x10, +0x0d, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xf0, 0xb3, 0x0e, 0x00, +0x4d, 0x1a, 0xb8, 0xff, 0xe0, 0x40, 0x13, 0x0d, 0x00, 0x4d, +0x15, 0x20, 0x10, 0x00, 0x4d, 0x15, 0x10, 0x0f, 0x00, 0x4d, +0x15, 0x18, 0x08, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xe8, 0xb3, +0x10, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xf0, 0xb3, 0x0f, 0x00, +0x4d, 0x11, 0xb8, 0xff, 0xf0, 0xb3, 0x08, 0x00, 0x4d, 0x0b, +0xb8, 0xff, 0xf0, 0xb3, 0x10, 0x00, 0x4d, 0x0b, 0xb8, 0xff, +0xe8, 0xb3, 0x0f, 0x00, 0x4d, 0x0b, 0xb8, 0xff, 0xf0, 0x40, +0x3b, 0x08, 0x00, 0x4d, 0x07, 0x08, 0x10, 0x00, 0x4d, 0x07, +0x18, 0x0f, 0x00, 0x4d, 0x07, 0x10, 0x08, 0x00, 0x4d, 0x4f, +0x01, 0x5f, 0x01, 0x02, 0x40, 0x00, 0x50, 0x00, 0x02, 0x01, +0x00, 0x01, 0x00, 0x18, 0x1e, 0x76, 0x0e, 0x25, 0x18, 0x76, +0x04, 0x40, 0x0b, 0x10, 0x48, 0x04, 0x24, 0x03, 0x79, 0x00, +0x00, 0x09, 0x1b, 0x7c, 0x13, 0x46, 0x21, 0x7c, 0x09, 0x45, +0x00, 0x3f, 0xed, 0x3f, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x01, +0x10, 0xd6, 0x2b, 0xed, 0x10, 0xde, 0xed, 0x11, 0x39, 0x39, +0x2f, 0x2f, 0x5d, 0x5d, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x33, 0x15, 0x23, 0x27, 0x34, +0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, +0x23, 0x22, 0x2e, 0x02, 0x37, 0x14, 0x16, 0x33, 0x32, 0x36, +0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0xaf, 0x98, 0x98, 0x92, +0x20, 0x3a, 0x51, 0x32, 0x31, 0x52, 0x3a, 0x21, 0x21, 0x3a, +0x52, 0x31, 0x32, 0x51, 0x3a, 0x20, 0x54, 0x42, 0x45, 0x46, +0x46, 0x46, 0x46, 0x45, 0x42, 0x01, 0x5b, 0x47, 0x22, 0x53, +0x7a, 0x4f, 0x27, 0x27, 0x4f, 0x7a, 0x53, 0x53, 0x7a, 0x50, +0x26, 0x26, 0x50, 0x7a, 0x53, 0x7a, 0x82, 0x82, 0x7a, 0x7a, +0x82, 0x82, 0x00, 0x00, 0xff, 0xff, 0x00, 0x59, 0x00, 0x00, +0x01, 0x9b, 0x02, 0x6b, 0x02, 0x06, 0x00, 0x2c, 0x00, 0x00, +0x00, 0x01, 0x00, 0x40, 0x00, 0x00, 0x01, 0xd0, 0x02, 0x6b, +0x00, 0x1a, 0x00, 0x63, 0x40, 0x38, 0x05, 0x05, 0x0a, 0x1a, +0x15, 0x1a, 0x78, 0x00, 0x05, 0x14, 0x00, 0x00, 0x05, 0x0b, +0x05, 0x0a, 0x05, 0x78, 0x10, 0x0b, 0x14, 0x10, 0x10, 0x0b, +0x00, 0x00, 0x0a, 0x1c, 0x15, 0x10, 0x73, 0x00, 0x12, 0x10, +0x12, 0x20, 0x12, 0x03, 0x08, 0x12, 0x1b, 0x15, 0x10, 0x05, +0x05, 0x12, 0x13, 0x41, 0x12, 0x44, 0x0b, 0x0a, 0x44, 0x1a, +0x00, 0x41, 0x00, 0x3f, 0x32, 0x3f, 0x33, 0x3f, 0x3f, 0x12, +0x39, 0x19, 0x2f, 0x33, 0x33, 0x01, 0x18, 0x10, 0xd6, 0x5e, +0x5d, 0xed, 0x32, 0x10, 0xce, 0x32, 0x2f, 0x87, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x08, 0x7d, +0xc4, 0x31, 0x30, 0x01, 0x0e, 0x03, 0x07, 0x1e, 0x03, 0x17, +0x23, 0x2e, 0x03, 0x27, 0x11, 0x23, 0x11, 0x33, 0x11, 0x3e, +0x03, 0x37, 0x01, 0xbb, 0x1e, 0x34, 0x32, 0x34, 0x1f, 0x1e, +0x42, 0x3f, 0x38, 0x15, 0x5d, 0x16, 0x34, 0x3a, 0x3e, 0x1f, +0x52, 0x52, 0x1c, 0x39, 0x34, 0x2e, 0x13, 0x02, 0x6b, 0x32, +0x4d, 0x44, 0x3e, 0x22, 0x1b, 0x47, 0x55, 0x5f, 0x32, 0x2e, +0x58, 0x4e, 0x3f, 0x17, 0xfe, 0xd6, 0x02, 0x6b, 0xfe, 0xec, +0x20, 0x46, 0x47, 0x46, 0x21, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x02, 0x6b, 0x00, 0x16, +0x00, 0x4a, 0x40, 0x27, 0x10, 0x0a, 0x05, 0x0a, 0x78, 0x0b, +0x10, 0x14, 0x0b, 0x0b, 0x10, 0x11, 0x00, 0x05, 0x00, 0x78, +0x16, 0x11, 0x14, 0x16, 0x16, 0x11, 0x05, 0x05, 0x0b, 0x16, +0x18, 0x0b, 0x17, 0x00, 0x16, 0x44, 0x11, 0x05, 0x10, 0x41, +0x0a, 0x0b, 0x44, 0x00, 0x3f, 0x33, 0x3f, 0x33, 0x33, 0x3f, +0x33, 0x01, 0x10, 0xc6, 0x10, 0xce, 0x11, 0x39, 0x3d, 0x2f, +0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x87, 0x18, 0x10, +0x2b, 0x87, 0x7d, 0xc4, 0x31, 0x30, 0x21, 0x2e, 0x03, 0x27, +0x0e, 0x03, 0x07, 0x23, 0x3e, 0x03, 0x37, 0x33, 0x1e, 0x03, +0x17, 0x01, 0x92, 0x14, 0x2f, 0x2b, 0x23, 0x08, 0x09, 0x24, +0x2c, 0x2f, 0x14, 0x54, 0x17, 0x2c, 0x2d, 0x32, 0x1e, 0x66, +0x1a, 0x36, 0x31, 0x2b, 0x10, 0x65, 0xb2, 0x8f, 0x65, 0x18, +0x19, 0x67, 0x90, 0xb1, 0x62, 0x59, 0x9d, 0x95, 0x92, 0x4e, +0x46, 0xa3, 0xa5, 0x9d, 0x40, 0x00, 0x00, 0x01, 0x00, 0x22, +0x00, 0x00, 0x01, 0xd3, 0x02, 0x6b, 0x00, 0x1a, 0x00, 0x99, +0x40, 0x23, 0x01, 0x28, 0x0f, 0x00, 0x4d, 0x01, 0x20, 0x0d, +0x0e, 0x00, 0x4c, 0x01, 0x18, 0x0c, 0x00, 0x4d, 0x01, 0x20, +0x0b, 0x00, 0x4d, 0x01, 0x0e, 0x0d, 0x0e, 0x7b, 0x00, 0x01, +0x14, 0x00, 0x00, 0x01, 0x0d, 0x08, 0x1a, 0xb8, 0xff, 0xd8, +0xb3, 0x0f, 0x00, 0x4d, 0x1a, 0xb8, 0xff, 0xe8, 0xb4, 0x0c, +0x0e, 0x00, 0x4c, 0x1a, 0xb8, 0xff, 0xe0, 0x40, 0x2b, 0x0b, +0x00, 0x4d, 0x0f, 0x1a, 0x00, 0x1a, 0x7e, 0x10, 0x0f, 0x14, +0x10, 0x10, 0x0f, 0x00, 0x15, 0x08, 0x73, 0x02, 0x07, 0x1c, +0x10, 0x15, 0x73, 0x19, 0x16, 0x1b, 0x10, 0x1a, 0x41, 0x0e, +0x00, 0x0f, 0x0f, 0x15, 0x16, 0x44, 0x08, 0x07, 0x44, 0x0d, +0x01, 0x41, 0x00, 0x3f, 0x33, 0x3f, 0x33, 0x3f, 0x33, 0x33, +0x2f, 0x33, 0x33, 0x3f, 0x33, 0x01, 0x10, 0xd6, 0x32, 0xed, +0x32, 0x10, 0xde, 0x32, 0xed, 0x11, 0x39, 0x87, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x01, 0x2b, 0x2b, 0x2b, 0x11, 0x33, 0x87, +0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x2b, 0x2b, 0x2b, +0x2b, 0x31, 0x30, 0x13, 0x13, 0x33, 0x1e, 0x03, 0x17, 0x23, +0x2e, 0x03, 0x27, 0x03, 0x23, 0x03, 0x14, 0x0e, 0x02, 0x07, +0x23, 0x36, 0x12, 0x37, 0x33, 0xfa, 0x5b, 0x5b, 0x06, 0x0a, +0x08, 0x08, 0x03, 0x4f, 0x02, 0x02, 0x03, 0x03, 0x02, 0x55, +0x52, 0x57, 0x02, 0x03, 0x03, 0x01, 0x4f, 0x06, 0x0e, 0x0e, +0x5b, 0x01, 0x37, 0x01, 0x34, 0x3b, 0x92, 0xa1, 0xaa, 0x53, +0x36, 0x82, 0x8a, 0x8d, 0x41, 0xfe, 0xdb, 0x01, 0x25, 0x41, +0x8d, 0x8a, 0x82, 0x36, 0xa1, 0x01, 0x2f, 0x9b, 0x00, 0x00, +0x00, 0x01, 0x00, 0x37, 0x00, 0x00, 0x01, 0xbe, 0x02, 0x6b, +0x00, 0x11, 0x00, 0x4e, 0x40, 0x30, 0x1a, 0x00, 0x01, 0x0d, +0x00, 0x01, 0x26, 0x09, 0x01, 0x04, 0x09, 0x14, 0x09, 0x02, +0x09, 0x00, 0x05, 0x00, 0x7e, 0x0e, 0x09, 0x14, 0x0e, 0x09, +0x0e, 0x73, 0x11, 0x13, 0x05, 0x73, 0x10, 0x07, 0x01, 0x01, +0x07, 0x01, 0x07, 0x12, 0x0f, 0x41, 0x05, 0x09, 0x41, 0x07, +0x44, 0x0e, 0x00, 0x44, 0x00, 0x3f, 0x32, 0x3f, 0x3f, 0x33, +0x3f, 0x01, 0x10, 0xd6, 0x5d, 0x5d, 0xed, 0x10, 0xde, 0xfd, +0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x5d, 0x5d, 0x5d, 0x5d, +0x31, 0x30, 0x21, 0x2e, 0x03, 0x27, 0x11, 0x23, 0x11, 0x33, +0x1e, 0x03, 0x17, 0x11, 0x33, 0x11, 0x01, 0x6b, 0x11, 0x31, +0x3c, 0x46, 0x25, 0x4b, 0x53, 0x1f, 0x46, 0x40, 0x35, 0x0f, +0x4b, 0x2a, 0x6d, 0x7f, 0x8e, 0x4a, 0xfe, 0x12, 0x02, 0x6b, +0x36, 0x83, 0x84, 0x79, 0x2b, 0x01, 0xe1, 0xfd, 0x95, 0x00, +0x00, 0x03, 0x00, 0x25, 0x00, 0x00, 0x01, 0xcf, 0x02, 0x6b, +0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x33, 0x40, 0x19, +0x0a, 0x0a, 0x00, 0x00, 0x05, 0x0d, 0x0b, 0x0b, 0x01, 0x01, +0x04, 0x0c, 0x0b, 0x79, 0x08, 0x08, 0x02, 0x04, 0x79, 0x07, +0x44, 0x01, 0x79, 0x02, 0x41, 0x00, 0x3f, 0xed, 0x3f, 0xed, +0x11, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x32, +0x2f, 0x10, 0xce, 0x32, 0x2f, 0x32, 0x2f, 0x31, 0x30, 0x01, +0x21, 0x35, 0x21, 0x01, 0x21, 0x15, 0x21, 0x13, 0x21, 0x15, +0x21, 0x01, 0xc7, 0xfe, 0x67, 0x01, 0x99, 0xfe, 0x5e, 0x01, +0xaa, 0xfe, 0x56, 0x30, 0x01, 0x4a, 0xfe, 0xb6, 0x02, 0x24, +0x47, 0xfd, 0xdc, 0x47, 0x01, 0x69, 0x49, 0x00, 0xff, 0xff, +0x00, 0x1d, 0xff, 0xf3, 0x01, 0xd8, 0x02, 0x79, 0x02, 0x06, +0x00, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x2d, 0x00, 0x00, +0x01, 0xc7, 0x02, 0x6b, 0x02, 0x06, 0x02, 0xd2, 0x00, 0x00, +0x00, 0x02, 0x00, 0x49, 0x00, 0x00, 0x01, 0xc7, 0x02, 0x71, +0x00, 0x0e, 0x00, 0x1d, 0x00, 0x87, 0x40, 0x15, 0x1b, 0x18, +0x10, 0x00, 0x4d, 0x1b, 0x10, 0x0f, 0x00, 0x4d, 0x17, 0x18, +0x0f, 0x00, 0x4d, 0x16, 0x28, 0x10, 0x00, 0x4d, 0x04, 0xb8, +0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x04, 0xb8, 0xff, 0xf0, +0xb3, 0x09, 0x00, 0x4d, 0x04, 0xb8, 0xff, 0xe0, 0xb3, 0x08, +0x00, 0x4d, 0x02, 0xb8, 0xff, 0xe8, 0xb3, 0x12, 0x00, 0x4d, +0x02, 0xb8, 0xff, 0xf0, 0xb3, 0x11, 0x00, 0x4d, 0x02, 0xb8, +0xff, 0xf0, 0xb4, 0x09, 0x0a, 0x00, 0x4c, 0x02, 0xb8, 0xff, +0xe0, 0x40, 0x1b, 0x08, 0x00, 0x4d, 0x19, 0x76, 0x03, 0x1f, +0x13, 0x07, 0x73, 0x00, 0x09, 0x01, 0x08, 0x09, 0x1e, 0x07, +0x79, 0x13, 0x13, 0x00, 0x09, 0x44, 0x0f, 0x7c, 0x00, 0x41, +0x00, 0x3f, 0xed, 0x3f, 0x12, 0x39, 0x2f, 0xed, 0x01, 0x10, +0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x13, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x23, 0x15, +0x23, 0x11, 0x3e, 0x03, 0x17, 0x22, 0x06, 0x07, 0x15, 0x33, +0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, 0xeb, 0x6a, 0x72, +0x7a, 0x6a, 0x48, 0x52, 0x12, 0x2b, 0x2b, 0x29, 0x17, 0x1a, +0x30, 0x0c, 0x44, 0x21, 0x36, 0x27, 0x16, 0x16, 0x24, 0x2f, +0x02, 0x71, 0x63, 0x62, 0x6b, 0x5b, 0xe6, 0x02, 0x61, 0x04, +0x07, 0x03, 0x02, 0x47, 0x02, 0x02, 0xfa, 0x0c, 0x1e, 0x31, +0x26, 0x24, 0x31, 0x1c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x28, 0x00, 0x00, 0x01, 0xbf, 0x02, 0x6b, 0x00, 0x15, +0x00, 0x59, 0x40, 0x2f, 0x0a, 0x0a, 0x07, 0x11, 0x00, 0x11, +0x78, 0x0d, 0x0a, 0x14, 0x0d, 0x0d, 0x0a, 0x10, 0x10, 0x04, +0x17, 0x03, 0x0a, 0x07, 0x0a, 0x78, 0x00, 0x03, 0x14, 0x00, +0x00, 0x03, 0x0d, 0x0d, 0x07, 0x16, 0x0a, 0x0a, 0x00, 0x00, +0x03, 0x0d, 0x11, 0x79, 0x0e, 0x41, 0x07, 0x03, 0x79, 0x06, +0x44, 0x00, 0x3f, 0xed, 0x32, 0x3f, 0xed, 0x32, 0x11, 0x39, +0x19, 0x2f, 0x33, 0x01, 0x18, 0x2f, 0x10, 0xc6, 0x32, 0x2f, +0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, 0x18, 0x10, 0xce, +0x32, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x08, 0x7d, 0xc4, 0x31, +0x30, 0x01, 0x06, 0x06, 0x07, 0x21, 0x15, 0x21, 0x35, 0x36, +0x36, 0x37, 0x26, 0x26, 0x27, 0x35, 0x21, 0x15, 0x21, 0x1e, +0x03, 0x01, 0x45, 0x31, 0x6a, 0x2a, 0x01, 0x3f, 0xfe, 0x69, +0x22, 0x6a, 0x36, 0x34, 0x63, 0x1e, 0x01, 0x89, 0xfe, 0xdc, +0x0d, 0x26, 0x2e, 0x32, 0x01, 0x42, 0x40, 0x80, 0x3c, 0x46, +0x41, 0x37, 0x84, 0x45, 0x45, 0x81, 0x2d, 0x37, 0x46, 0x13, +0x34, 0x3c, 0x41, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x24, +0x00, 0x00, 0x01, 0xd0, 0x02, 0x6b, 0x00, 0x07, 0x00, 0x20, +0x40, 0x0f, 0x01, 0x03, 0x73, 0x06, 0x04, 0x04, 0x09, 0x08, +0x02, 0x05, 0x79, 0x07, 0x41, 0x04, 0x44, 0x00, 0x3f, 0x3f, +0xed, 0x32, 0x01, 0x11, 0x12, 0x39, 0x2f, 0xce, 0xfd, 0xce, +0x31, 0x30, 0x01, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, +0x01, 0xd0, 0xad, 0x52, 0xad, 0x02, 0x6b, 0x46, 0xfd, 0xdb, +0x02, 0x25, 0x46, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x00, +0x01, 0xe8, 0x02, 0x6b, 0x02, 0x06, 0x00, 0x3c, 0x00, 0x00, +0xff, 0xff, 0x00, 0x2a, 0x00, 0x00, 0x01, 0xd4, 0x02, 0x93, +0x02, 0x06, 0x02, 0xd7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x16, +0x00, 0x00, 0x01, 0xd8, 0x02, 0x6b, 0x00, 0x15, 0x00, 0x55, +0x40, 0x2d, 0x0f, 0x0c, 0x09, 0x08, 0x10, 0x09, 0x10, 0x78, +0x11, 0x08, 0x14, 0x11, 0x08, 0x11, 0x11, 0x15, 0x00, 0x0e, +0x15, 0x0e, 0x78, 0x0d, 0x00, 0x14, 0x0d, 0x0d, 0x00, 0x15, +0x17, 0x0d, 0x0d, 0x09, 0x16, 0x11, 0x10, 0x41, 0x0e, 0x0d, +0x41, 0x09, 0x08, 0x44, 0x15, 0x00, 0x44, 0x00, 0x3f, 0x32, +0x3f, 0x33, 0x3f, 0x33, 0x3f, 0x33, 0x01, 0x10, 0xc6, 0x32, +0x2f, 0x10, 0xce, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x01, +0x11, 0x33, 0x18, 0x2f, 0x87, 0x2b, 0x87, 0x7d, 0xc4, 0x10, +0x0e, 0xc4, 0xc4, 0x31, 0x30, 0x21, 0x2e, 0x03, 0x27, 0x06, +0x06, 0x07, 0x23, 0x36, 0x36, 0x37, 0x03, 0x33, 0x17, 0x37, +0x33, 0x03, 0x16, 0x16, 0x17, 0x01, 0x7d, 0x0b, 0x1e, 0x22, +0x27, 0x15, 0x23, 0x45, 0x1e, 0x5a, 0x21, 0x59, 0x32, 0xa2, +0x5b, 0x7a, 0x81, 0x59, 0xa4, 0x30, 0x5a, 0x23, 0x1b, 0x44, +0x48, 0x48, 0x1f, 0x38, 0x91, 0x45, 0x4a, 0xad, 0x4f, 0x01, +0x25, 0xed, 0xed, 0xfe, 0xdf, 0x4e, 0xa8, 0x54, 0x00, 0x00, +0x00, 0x01, 0x00, 0x2b, 0x00, 0x00, 0x01, 0xc9, 0x02, 0x6b, +0x00, 0x1b, 0x00, 0x76, 0xb9, 0x00, 0x19, 0xff, 0xe8, 0xb4, +0x13, 0x14, 0x00, 0x4c, 0x19, 0xb8, 0xff, 0xe0, 0xb3, 0x12, +0x00, 0x4d, 0x19, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, +0x0c, 0xb8, 0xff, 0xf0, 0xb3, 0x10, 0x00, 0x4d, 0x0c, 0xb8, +0xff, 0xe8, 0x40, 0x2c, 0x0f, 0x00, 0x4d, 0x04, 0x10, 0x13, +0x14, 0x00, 0x4c, 0x04, 0x20, 0x11, 0x12, 0x00, 0x4c, 0x1b, +0x0f, 0x73, 0x02, 0x0e, 0x0e, 0x07, 0x13, 0x73, 0x16, 0x1d, +0x0a, 0x73, 0x07, 0x1c, 0x1b, 0x02, 0x79, 0x10, 0x0d, 0x0e, +0x0d, 0x0e, 0x01, 0x14, 0x08, 0x41, 0x01, 0x44, 0x00, 0x3f, +0x3f, 0x33, 0x12, 0x39, 0x39, 0x2f, 0x2f, 0x33, 0xed, 0x32, +0x01, 0x10, 0xd6, 0xed, 0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, +0x33, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x21, 0x23, 0x35, 0x22, 0x2e, 0x02, 0x35, 0x35, +0x33, 0x15, 0x14, 0x16, 0x33, 0x35, 0x33, 0x15, 0x32, 0x36, +0x35, 0x35, 0x33, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x01, 0x1f, +0x4a, 0x2f, 0x41, 0x28, 0x12, 0x52, 0x27, 0x31, 0x4a, 0x31, +0x27, 0x52, 0x12, 0x28, 0x41, 0x2f, 0x9e, 0x24, 0x42, 0x5d, +0x39, 0xd1, 0xce, 0x65, 0x54, 0xf7, 0xf7, 0x54, 0x65, 0xce, +0xd1, 0x39, 0x5d, 0x42, 0x24, 0x00, 0x00, 0x01, 0x00, 0x12, +0x00, 0x00, 0x01, 0xe2, 0x02, 0x79, 0x00, 0x2b, 0x00, 0x98, +0xb9, 0x00, 0x21, 0xff, 0xe8, 0x40, 0x09, 0x0d, 0x00, 0x4d, +0x1d, 0x18, 0x0d, 0x00, 0x4d, 0x11, 0xb8, 0xff, 0xe8, 0xb4, +0x0f, 0x10, 0x00, 0x4c, 0x0b, 0xb8, 0xff, 0xe8, 0x40, 0x51, +0x0e, 0x10, 0x00, 0x4c, 0x07, 0x18, 0x10, 0x00, 0x4d, 0x07, +0x10, 0x0f, 0x00, 0x4d, 0x07, 0x18, 0x0e, 0x00, 0x4d, 0x01, +0x18, 0x10, 0x00, 0x4d, 0x01, 0x10, 0x0f, 0x00, 0x4d, 0x11, +0x6f, 0x15, 0x7f, 0x15, 0xaf, 0x15, 0xbf, 0x15, 0x04, 0x15, +0x15, 0x1a, 0x76, 0x0e, 0x12, 0x12, 0x0e, 0x2d, 0x01, 0x60, +0x29, 0x70, 0x29, 0xa0, 0x29, 0xb0, 0x29, 0x04, 0x29, 0x29, +0x24, 0x76, 0x04, 0x00, 0x00, 0x04, 0x2c, 0x29, 0x01, 0x79, +0x2a, 0x44, 0x15, 0x11, 0x79, 0x14, 0x44, 0x1f, 0x7c, 0x09, +0x45, 0x00, 0x3f, 0xed, 0x3f, 0xed, 0x32, 0x3f, 0xed, 0x32, +0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xed, 0x32, 0x2f, 0x5d, +0x33, 0x10, 0xce, 0x32, 0x2f, 0x10, 0xed, 0x32, 0x2f, 0x5d, +0x33, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x37, 0x33, 0x26, 0x26, 0x35, 0x34, 0x3e, 0x02, +0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, 0x33, 0x15, +0x23, 0x35, 0x3e, 0x03, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, +0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x17, 0x15, 0x23, 0x12, +0x6d, 0x30, 0x2e, 0x1b, 0x37, 0x52, 0x36, 0x36, 0x52, 0x37, +0x1b, 0x2f, 0x2f, 0x6b, 0xc5, 0x18, 0x26, 0x19, 0x0e, 0x10, +0x21, 0x33, 0x23, 0x23, 0x33, 0x21, 0x10, 0x0e, 0x19, 0x26, +0x18, 0xc7, 0x46, 0x3d, 0x95, 0x4a, 0x37, 0x66, 0x4c, 0x2e, +0x2e, 0x4c, 0x66, 0x37, 0x4a, 0x95, 0x3d, 0x46, 0x3c, 0x1a, +0x44, 0x4d, 0x52, 0x28, 0x2a, 0x4c, 0x39, 0x22, 0x22, 0x39, +0x4c, 0x2a, 0x28, 0x52, 0x4d, 0x44, 0x1a, 0x3c, 0x00, 0x02, +0x00, 0x31, 0xff, 0xf6, 0x01, 0xd7, 0x01, 0xda, 0x00, 0x19, +0x00, 0x2b, 0x00, 0x67, 0xb9, 0x00, 0x2a, 0xff, 0xf0, 0xb3, +0x0e, 0x00, 0x4d, 0x25, 0xb8, 0xff, 0xe0, 0xb3, 0x0e, 0x00, +0x4d, 0x25, 0xb8, 0xff, 0xf0, 0x40, 0x34, 0x0d, 0x00, 0x4d, +0x18, 0x10, 0x10, 0x00, 0x4d, 0x18, 0x18, 0x0f, 0x00, 0x4d, +0x12, 0x18, 0x10, 0x00, 0x4d, 0x12, 0x20, 0x0f, 0x00, 0x4d, +0x12, 0x18, 0x08, 0x00, 0x4d, 0x0d, 0x20, 0x7f, 0x04, 0x09, +0x09, 0x04, 0x2d, 0x27, 0x82, 0x15, 0x2c, 0x1a, 0x88, 0x10, +0x51, 0x09, 0x88, 0x0a, 0x51, 0x24, 0x88, 0x00, 0x50, 0x00, +0x3f, 0xed, 0x3f, 0xed, 0x3f, 0xed, 0x01, 0x10, 0xd6, 0xed, +0x10, 0xcc, 0x32, 0x2f, 0x10, 0xed, 0x32, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x32, 0x16, +0x17, 0x11, 0x14, 0x1e, 0x02, 0x17, 0x07, 0x26, 0x26, 0x27, +0x06, 0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, +0x13, 0x32, 0x36, 0x37, 0x26, 0x26, 0x35, 0x35, 0x26, 0x26, +0x23, 0x22, 0x06, 0x15, 0x14, 0x1e, 0x02, 0x01, 0x0d, 0x30, +0x57, 0x17, 0x03, 0x09, 0x12, 0x0e, 0x0d, 0x1d, 0x24, 0x11, +0x14, 0x41, 0x2d, 0x30, 0x4a, 0x31, 0x1a, 0x1f, 0x39, 0x52, +0x22, 0x20, 0x34, 0x0d, 0x03, 0x02, 0x07, 0x2a, 0x18, 0x3f, +0x4b, 0x0d, 0x1d, 0x2d, 0x01, 0xda, 0x13, 0x08, 0xfe, 0xd4, +0x16, 0x1d, 0x13, 0x0c, 0x04, 0x46, 0x06, 0x12, 0x16, 0x11, +0x1e, 0x24, 0x40, 0x58, 0x35, 0x38, 0x5a, 0x3f, 0x22, 0xfe, +0x64, 0x17, 0x0b, 0x0d, 0x1b, 0x0f, 0xf1, 0x03, 0x08, 0x5b, +0x51, 0x24, 0x3d, 0x2e, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x02, +0x00, 0x47, 0xff, 0x5b, 0x01, 0xcc, 0x02, 0xb5, 0x00, 0x1b, +0x00, 0x33, 0x00, 0xb1, 0xb9, 0x00, 0x31, 0xff, 0xe8, 0xb3, +0x12, 0x00, 0x4d, 0x31, 0xb8, 0xff, 0xe0, 0x40, 0x13, 0x11, +0x00, 0x4d, 0x2b, 0x10, 0x12, 0x00, 0x4d, 0x2b, 0x18, 0x11, +0x00, 0x4d, 0x21, 0x20, 0x0f, 0x00, 0x4d, 0x17, 0xb8, 0xff, +0xf0, 0xb3, 0x10, 0x00, 0x4d, 0x16, 0xb8, 0xff, 0xe8, 0xb3, +0x10, 0x00, 0x4d, 0x16, 0xb8, 0xff, 0xe8, 0xb4, 0x08, 0x0a, +0x00, 0x4c, 0x11, 0xb8, 0xff, 0xf0, 0xb4, 0x0e, 0x0f, 0x00, +0x4c, 0x0a, 0xb8, 0xff, 0xe8, 0xb3, 0x0c, 0x00, 0x4d, 0x0a, +0xb8, 0xff, 0xf0, 0xb3, 0x0a, 0x00, 0x4d, 0x0a, 0xb8, 0xff, +0xe8, 0x40, 0x2e, 0x08, 0x09, 0x00, 0x4c, 0x04, 0x10, 0x08, +0x0a, 0x00, 0x4c, 0x29, 0x29, 0x0f, 0x2d, 0x82, 0x0c, 0x0c, +0x24, 0x82, 0x14, 0x35, 0x1c, 0x1b, 0x7f, 0x00, 0x01, 0x01, +0x08, 0x01, 0x34, 0x0f, 0x28, 0x86, 0x29, 0x29, 0x07, 0x1f, +0x88, 0x19, 0x51, 0x30, 0x88, 0x07, 0x4d, 0x01, 0x4b, 0x00, +0x3f, 0x3f, 0xed, 0x3f, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x39, +0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, +0x33, 0x2f, 0xed, 0x32, 0x32, 0x2f, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x17, 0x23, 0x11, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, +0x02, 0x15, 0x14, 0x06, 0x07, 0x1e, 0x03, 0x15, 0x14, 0x0e, +0x02, 0x23, 0x22, 0x27, 0x35, 0x16, 0x16, 0x33, 0x32, 0x3e, +0x02, 0x35, 0x34, 0x26, 0x23, 0x23, 0x35, 0x33, 0x32, 0x36, +0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x9a, 0x53, 0x1d, +0x31, 0x41, 0x24, 0x23, 0x3c, 0x2d, 0x1a, 0x30, 0x2e, 0x25, +0x35, 0x21, 0x0f, 0x23, 0x38, 0x47, 0x24, 0x3d, 0x2f, 0x14, +0x31, 0x19, 0x19, 0x2e, 0x23, 0x15, 0x47, 0x4e, 0x06, 0x07, +0x2d, 0x3d, 0x2d, 0x26, 0x2c, 0x34, 0xa5, 0x02, 0x97, 0x31, +0x49, 0x31, 0x18, 0x16, 0x2c, 0x40, 0x2b, 0x29, 0x4b, 0x13, +0x0a, 0x27, 0x31, 0x3a, 0x1d, 0x38, 0x4f, 0x31, 0x17, 0x1c, +0x4b, 0x11, 0x0f, 0x10, 0x20, 0x32, 0x22, 0x45, 0x4f, 0x44, +0x35, 0x36, 0x33, 0x34, 0x3f, 0x41, 0x00, 0x00, 0x00, 0x01, +0x00, 0x1d, 0xff, 0x5b, 0x01, 0xd4, 0x01, 0xd0, 0x00, 0x15, +0x00, 0x33, 0x40, 0x19, 0x0c, 0x03, 0x00, 0x0f, 0x82, 0x10, +0x10, 0x15, 0x06, 0x82, 0x07, 0x17, 0x00, 0x82, 0x15, 0x16, +0x03, 0x0c, 0x0c, 0x10, 0x06, 0x15, 0x49, 0x10, 0x4b, 0x00, +0x3f, 0x3f, 0x33, 0x12, 0x39, 0x11, 0x33, 0x01, 0x10, 0xd6, +0xed, 0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x11, 0x39, +0x39, 0x31, 0x30, 0x13, 0x16, 0x16, 0x17, 0x36, 0x36, 0x37, +0x33, 0x0e, 0x03, 0x07, 0x16, 0x16, 0x17, 0x23, 0x2e, 0x03, +0x27, 0x79, 0x24, 0x41, 0x18, 0x39, 0x42, 0x11, 0x52, 0x0a, +0x21, 0x31, 0x42, 0x2a, 0x08, 0x0a, 0x02, 0x50, 0x05, 0x29, +0x36, 0x39, 0x16, 0x01, 0xd0, 0x5c, 0xbe, 0x5b, 0x64, 0xc2, +0x4f, 0x2b, 0x6f, 0x7b, 0x82, 0x3f, 0x2a, 0x50, 0x25, 0x57, +0xb4, 0xa6, 0x90, 0x34, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, +0xff, 0xf4, 0x01, 0xcc, 0x02, 0xb5, 0x00, 0x11, 0x00, 0x3a, +0x00, 0xa7, 0x40, 0x0b, 0x3a, 0x10, 0x0b, 0x00, 0x4d, 0x39, +0x10, 0x0c, 0x00, 0x4d, 0x28, 0xb8, 0xff, 0xe8, 0xb3, 0x10, +0x00, 0x4d, 0x28, 0xb8, 0xff, 0xf0, 0x40, 0x34, 0x0f, 0x00, +0x4d, 0x16, 0x18, 0x0e, 0x00, 0x4d, 0x16, 0x10, 0x0d, 0x00, +0x4d, 0x16, 0x20, 0x0b, 0x0c, 0x00, 0x4c, 0x13, 0x38, 0x11, +0x12, 0x00, 0x4c, 0x12, 0x08, 0x11, 0x00, 0x4d, 0x10, 0x18, +0x0c, 0x0d, 0x00, 0x4c, 0x10, 0x20, 0x0b, 0x00, 0x4d, 0x0a, +0x18, 0x10, 0x00, 0x4d, 0x0a, 0x10, 0x0f, 0x00, 0x4d, 0x06, +0xb8, 0xff, 0xe8, 0xb3, 0x10, 0x00, 0x4d, 0x06, 0xb8, 0xff, +0xf0, 0x40, 0x23, 0x0f, 0x00, 0x4d, 0x1b, 0x1b, 0x0d, 0x82, +0x2e, 0x3c, 0x12, 0x26, 0x82, 0x15, 0x15, 0x03, 0x82, 0x38, +0x3b, 0x12, 0x29, 0x88, 0x00, 0x00, 0x01, 0x00, 0x00, 0x18, +0x08, 0x88, 0x33, 0x51, 0x21, 0x89, 0x18, 0x4d, 0x00, 0x3f, +0xed, 0x3f, 0xed, 0x11, 0x39, 0x2f, 0x5d, 0xed, 0x32, 0x01, +0x10, 0xd6, 0xed, 0x33, 0x2f, 0xed, 0x32, 0x10, 0xde, 0xed, +0x33, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, +0x06, 0x06, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, +0x35, 0x34, 0x2e, 0x02, 0x27, 0x26, 0x26, 0x35, 0x34, 0x36, +0x33, 0x32, 0x16, 0x17, 0x07, 0x2e, 0x03, 0x23, 0x22, 0x0e, +0x02, 0x15, 0x14, 0x16, 0x17, 0x1e, 0x03, 0x15, 0x14, 0x0e, +0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x36, 0xff, 0x40, +0x44, 0x0e, 0x1e, 0x30, 0x23, 0x20, 0x30, 0x1f, 0x0f, 0x16, +0x23, 0x2b, 0x56, 0x22, 0x2a, 0x5a, 0x4e, 0x31, 0x49, 0x11, +0x12, 0x05, 0x15, 0x1f, 0x26, 0x16, 0x0c, 0x1f, 0x1d, 0x13, +0x2f, 0x28, 0x24, 0x40, 0x31, 0x1d, 0x17, 0x32, 0x50, 0x3a, +0x36, 0x50, 0x33, 0x19, 0x53, 0x01, 0x98, 0x12, 0x61, 0x43, +0x21, 0x3c, 0x2e, 0x1b, 0x19, 0x2c, 0x3b, 0x21, 0x29, 0x3b, +0x2c, 0x1f, 0x36, 0x18, 0x3c, 0x22, 0x3f, 0x3e, 0x18, 0x08, +0x40, 0x03, 0x09, 0x0a, 0x07, 0x03, 0x0b, 0x15, 0x12, 0x18, +0x25, 0x1c, 0x18, 0x31, 0x3d, 0x4f, 0x36, 0x2a, 0x52, 0x41, +0x28, 0x26, 0x40, 0x56, 0x30, 0x54, 0x73, 0x00, 0x00, 0x01, +0x00, 0x45, 0xff, 0xf5, 0x01, 0xd2, 0x01, 0xdc, 0x00, 0x35, +0x00, 0x56, 0x40, 0x35, 0x34, 0x18, 0x0b, 0x0d, 0x00, 0x4c, +0x34, 0x20, 0x0a, 0x00, 0x4d, 0x29, 0x10, 0x0b, 0x00, 0x4d, +0x29, 0x20, 0x0a, 0x00, 0x4d, 0x14, 0x14, 0x05, 0x23, 0x37, +0x2e, 0x0e, 0x82, 0x33, 0x33, 0x1b, 0x82, 0x00, 0x2b, 0x01, +0x08, 0x2b, 0x36, 0x2e, 0x15, 0x86, 0x14, 0x14, 0x00, 0x1d, +0x88, 0x26, 0x51, 0x0b, 0x88, 0x00, 0x50, 0x00, 0x3f, 0xed, +0x3f, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x39, 0x01, 0x10, 0xd6, +0x5e, 0x5d, 0xed, 0x33, 0x2f, 0xed, 0x32, 0x10, 0xce, 0x32, +0x32, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x32, +0x1e, 0x02, 0x17, 0x07, 0x2e, 0x03, 0x23, 0x22, 0x06, 0x15, +0x14, 0x1e, 0x02, 0x33, 0x33, 0x15, 0x23, 0x22, 0x0e, 0x02, +0x15, 0x14, 0x33, 0x32, 0x3e, 0x02, 0x37, 0x17, 0x06, 0x06, +0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x36, 0x37, 0x2e, 0x03, +0x35, 0x34, 0x36, 0x01, 0x21, 0x17, 0x2e, 0x27, 0x1e, 0x07, +0x0d, 0x05, 0x1b, 0x25, 0x2a, 0x13, 0x35, 0x44, 0x12, 0x1d, +0x24, 0x12, 0x59, 0x5a, 0x17, 0x2a, 0x20, 0x14, 0x83, 0x1b, +0x34, 0x2a, 0x1f, 0x08, 0x16, 0x11, 0x66, 0x49, 0x21, 0x49, +0x3c, 0x27, 0x2c, 0x25, 0x0a, 0x16, 0x13, 0x0d, 0x6e, 0x01, +0xdc, 0x04, 0x07, 0x08, 0x03, 0x47, 0x02, 0x08, 0x07, 0x06, +0x1e, 0x23, 0x15, 0x1a, 0x0e, 0x05, 0x42, 0x07, 0x12, 0x1d, +0x15, 0x49, 0x07, 0x0a, 0x0b, 0x04, 0x46, 0x09, 0x19, 0x0b, +0x1f, 0x37, 0x2c, 0x24, 0x3e, 0x10, 0x04, 0x10, 0x19, 0x21, +0x15, 0x43, 0x42, 0x00, 0x00, 0x01, 0x00, 0x3f, 0xff, 0x58, +0x01, 0xbf, 0x02, 0xaf, 0x00, 0x2c, 0x00, 0x8d, 0xb9, 0x00, +0x2b, 0xff, 0xe8, 0xb4, 0x0b, 0x0e, 0x00, 0x4c, 0x27, 0xb8, +0xff, 0xd0, 0xb3, 0x10, 0x00, 0x4d, 0x27, 0xb8, 0xff, 0xe0, +0xb3, 0x0f, 0x00, 0x4d, 0x27, 0xb8, 0xff, 0xf0, 0xb3, 0x0e, +0x00, 0x4d, 0x23, 0xb8, 0xff, 0xf8, 0xb3, 0x12, 0x00, 0x4d, +0x23, 0xb8, 0xff, 0xf0, 0x40, 0x38, 0x11, 0x00, 0x4d, 0x18, +0x10, 0x11, 0x00, 0x4d, 0x17, 0x10, 0x11, 0x00, 0x4d, 0x10, +0x18, 0x0a, 0x00, 0x4d, 0x10, 0x28, 0x09, 0x00, 0x4d, 0x1a, +0x20, 0x12, 0x00, 0x4d, 0x1a, 0x1e, 0x1e, 0x04, 0x09, 0x82, +0x03, 0x00, 0x2e, 0x25, 0x82, 0x13, 0x1b, 0x1b, 0x13, 0x2d, +0x28, 0x89, 0x0e, 0x0e, 0x2d, 0x1e, 0x1a, 0x85, 0x1d, 0x4d, +0x03, 0x4b, 0x00, 0x3f, 0x3f, 0xed, 0x32, 0x11, 0x33, 0x2f, +0xed, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, 0xed, 0x10, 0xde, +0x32, 0xed, 0x32, 0x33, 0x2f, 0x33, 0x2b, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x05, +0x14, 0x06, 0x07, 0x27, 0x3e, 0x03, 0x35, 0x34, 0x2e, 0x02, +0x27, 0x2e, 0x03, 0x35, 0x34, 0x3e, 0x04, 0x37, 0x23, 0x35, +0x21, 0x15, 0x0e, 0x05, 0x15, 0x14, 0x16, 0x17, 0x1e, 0x03, +0x01, 0xbf, 0x1b, 0x10, 0x48, 0x04, 0x0b, 0x0b, 0x08, 0x0e, +0x1d, 0x2d, 0x20, 0x30, 0x46, 0x2c, 0x15, 0x1b, 0x2d, 0x38, +0x3a, 0x37, 0x14, 0xeb, 0x01, 0x56, 0x15, 0x3b, 0x3f, 0x3d, +0x31, 0x1e, 0x42, 0x4a, 0x2c, 0x3d, 0x25, 0x11, 0x2f, 0x23, +0x3f, 0x17, 0x16, 0x06, 0x15, 0x19, 0x1b, 0x0c, 0x0f, 0x14, +0x0e, 0x0b, 0x05, 0x08, 0x1e, 0x30, 0x44, 0x2e, 0x2c, 0x55, +0x4f, 0x47, 0x3d, 0x31, 0x12, 0x46, 0x41, 0x12, 0x33, 0x3e, +0x49, 0x4f, 0x54, 0x2a, 0x41, 0x3b, 0x0b, 0x07, 0x15, 0x1e, +0x28, 0x00, 0x00, 0x01, 0x00, 0x47, 0xff, 0x5b, 0x01, 0xb0, +0x01, 0xda, 0x00, 0x13, 0x00, 0x52, 0xb6, 0x0c, 0x10, 0x0f, +0x10, 0x00, 0x4c, 0x05, 0xb8, 0xff, 0xe0, 0xb3, 0x12, 0x00, +0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, 0x4d, 0x05, +0xb8, 0xff, 0xe8, 0xb4, 0x08, 0x0a, 0x00, 0x4c, 0x04, 0xb8, +0xff, 0xe0, 0x40, 0x17, 0x11, 0x00, 0x4d, 0x08, 0x7f, 0x07, +0x15, 0x12, 0x7f, 0x00, 0x13, 0x01, 0x08, 0x13, 0x14, 0x13, +0x4a, 0x08, 0x4b, 0x0e, 0x88, 0x03, 0x50, 0x00, 0x3f, 0xed, +0x3f, 0x3f, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x10, 0xde, +0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x36, +0x36, 0x33, 0x32, 0x16, 0x15, 0x11, 0x23, 0x11, 0x34, 0x2e, +0x02, 0x23, 0x22, 0x06, 0x07, 0x11, 0x23, 0x47, 0x2d, 0x59, +0x27, 0x5d, 0x5f, 0x52, 0x10, 0x1d, 0x29, 0x18, 0x14, 0x2d, +0x15, 0x53, 0x01, 0xc3, 0x0b, 0x0c, 0x60, 0x6a, 0xfe, 0x4b, +0x01, 0xa6, 0x2d, 0x38, 0x1f, 0x0c, 0x05, 0x04, 0xfe, 0x78, +0x00, 0x03, 0x00, 0x31, 0xff, 0xf2, 0x01, 0xc3, 0x02, 0xb5, +0x00, 0x13, 0x00, 0x1e, 0x00, 0x29, 0x00, 0xbb, 0x40, 0x0b, +0x28, 0x18, 0x0e, 0x00, 0x4d, 0x28, 0x10, 0x0d, 0x00, 0x4d, +0x21, 0xb8, 0xff, 0xf0, 0xb4, 0x0d, 0x0e, 0x00, 0x4c, 0x1d, +0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, 0x4d, 0x1d, 0xb8, 0xff, +0xf0, 0xb3, 0x0d, 0x00, 0x4d, 0x1c, 0xb8, 0xff, 0xf0, 0xb3, +0x12, 0x00, 0x4d, 0x1c, 0xb8, 0xff, 0xf8, 0x40, 0x15, 0x11, +0x00, 0x4d, 0x17, 0x10, 0x11, 0x12, 0x00, 0x4c, 0x16, 0x10, +0x0d, 0x0e, 0x00, 0x4c, 0x12, 0x18, 0x0f, 0x00, 0x4d, 0x11, +0xb8, 0xff, 0xf0, 0x40, 0x09, 0x0e, 0x00, 0x4d, 0x0c, 0x10, +0x0f, 0x00, 0x4d, 0x0c, 0xb8, 0xff, 0xf0, 0xb3, 0x0e, 0x00, +0x4d, 0x08, 0xb8, 0xff, 0xe8, 0x40, 0x0e, 0x0f, 0x00, 0x4d, +0x08, 0x10, 0x0e, 0x00, 0x4d, 0x03, 0x18, 0x0e, 0x00, 0x4d, +0x02, 0xb8, 0xff, 0xf0, 0x40, 0x1f, 0x0f, 0x00, 0x4d, 0x25, +0x19, 0x82, 0x05, 0x2b, 0x24, 0x1a, 0x82, 0x0f, 0x0f, 0x1f, +0x0f, 0x02, 0x0f, 0x2a, 0x1a, 0x85, 0x24, 0x24, 0x00, 0x14, +0x88, 0x0a, 0x51, 0x1f, 0x88, 0x00, 0x4d, 0x00, 0x3f, 0xed, +0x3f, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x01, 0x10, 0xd6, 0x5d, +0xed, 0x32, 0x10, 0xde, 0xed, 0x32, 0x31, 0x30, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x13, 0x32, 0x1e, 0x02, 0x15, +0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, +0x02, 0x13, 0x32, 0x3e, 0x02, 0x37, 0x23, 0x1e, 0x03, 0x13, +0x22, 0x0e, 0x02, 0x07, 0x33, 0x2e, 0x03, 0xfa, 0x32, 0x4c, +0x32, 0x19, 0x19, 0x32, 0x4c, 0x32, 0x32, 0x4c, 0x32, 0x19, +0x19, 0x32, 0x4c, 0x32, 0x1e, 0x2b, 0x1c, 0x0e, 0x02, 0xeb, +0x01, 0x0e, 0x1d, 0x2c, 0x1e, 0x1e, 0x2b, 0x1c, 0x0f, 0x02, +0xeb, 0x02, 0x0f, 0x1c, 0x2b, 0x02, 0xb5, 0x31, 0x5c, 0x83, +0x52, 0x52, 0x83, 0x5b, 0x31, 0x31, 0x5b, 0x83, 0x52, 0x52, +0x83, 0x5c, 0x31, 0xfd, 0x84, 0x24, 0x43, 0x5e, 0x3a, 0x3a, +0x5e, 0x43, 0x24, 0x02, 0x35, 0x22, 0x3f, 0x59, 0x37, 0x37, +0x59, 0x3f, 0x22, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, +0xff, 0xf5, 0x01, 0xc2, 0x01, 0xd0, 0x00, 0x15, 0x00, 0x23, +0x40, 0x11, 0x0c, 0x7f, 0x09, 0x09, 0x0a, 0x00, 0x17, 0x0a, +0x16, 0x09, 0x85, 0x0c, 0x49, 0x12, 0x88, 0x03, 0x51, 0x00, +0x3f, 0xed, 0x3f, 0xed, 0x01, 0x10, 0xc6, 0x10, 0xce, 0x11, +0x39, 0x2f, 0xed, 0x31, 0x30, 0x25, 0x06, 0x06, 0x23, 0x22, +0x2e, 0x02, 0x35, 0x35, 0x23, 0x35, 0x33, 0x11, 0x14, 0x1e, +0x02, 0x33, 0x32, 0x36, 0x37, 0x01, 0xc2, 0x1c, 0x3c, 0x1c, +0x28, 0x38, 0x22, 0x10, 0x86, 0xd8, 0x08, 0x12, 0x1e, 0x17, +0x0e, 0x34, 0x17, 0x0f, 0x0e, 0x0c, 0x13, 0x2b, 0x44, 0x31, +0xe3, 0x45, 0xfe, 0xe5, 0x24, 0x2e, 0x1a, 0x0a, 0x0a, 0x0c, +0xff, 0xff, 0x00, 0x47, 0x00, 0x00, 0x01, 0xde, 0x01, 0xd0, +0x02, 0x06, 0x01, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1d, +0x00, 0x00, 0x01, 0xd4, 0x02, 0xb5, 0x00, 0x24, 0x00, 0x8a, +0xb9, 0x00, 0x1d, 0xff, 0xe0, 0xb3, 0x0a, 0x00, 0x4d, 0x1c, +0xb8, 0xff, 0xd0, 0x40, 0x4d, 0x0a, 0x00, 0x4d, 0x10, 0x20, +0x0b, 0x0c, 0x00, 0x4c, 0x10, 0x10, 0x08, 0x09, 0x00, 0x4c, +0x0e, 0x18, 0x0e, 0x00, 0x4d, 0x0e, 0x08, 0x03, 0x08, 0x81, +0x09, 0x0e, 0x14, 0x09, 0x09, 0x0e, 0x1f, 0x00, 0x03, 0x00, +0x81, 0x24, 0x1f, 0x14, 0x24, 0x24, 0x1f, 0x03, 0x20, 0x09, +0x00, 0x4d, 0x03, 0x03, 0x09, 0x24, 0x26, 0x17, 0x17, 0x09, +0x25, 0x00, 0x24, 0x4a, 0x1f, 0xa0, 0x03, 0xb0, 0x03, 0xc0, +0x03, 0x03, 0x03, 0x0e, 0x0e, 0x13, 0x89, 0x1a, 0x4d, 0x08, +0x09, 0x4a, 0x00, 0x3f, 0x33, 0x3f, 0xed, 0x32, 0x11, 0x33, +0x5d, 0x33, 0x3f, 0x33, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x10, +0xce, 0x11, 0x39, 0x3d, 0x2f, 0x2b, 0x87, 0x18, 0x10, 0x2b, +0x87, 0x7d, 0xc4, 0x87, 0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x31, 0x30, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x21, 0x26, +0x26, 0x27, 0x0e, 0x03, 0x07, 0x23, 0x3e, 0x03, 0x37, 0x2e, +0x03, 0x23, 0x22, 0x06, 0x07, 0x27, 0x36, 0x36, 0x33, 0x32, +0x1e, 0x02, 0x17, 0x1e, 0x03, 0x17, 0x01, 0x77, 0x16, 0x3c, +0x23, 0x1a, 0x2d, 0x26, 0x1d, 0x09, 0x52, 0x0d, 0x29, 0x33, +0x39, 0x1e, 0x0f, 0x19, 0x19, 0x1e, 0x15, 0x0d, 0x11, 0x05, +0x0c, 0x05, 0x20, 0x16, 0x1e, 0x2d, 0x22, 0x1b, 0x0b, 0x21, +0x3c, 0x34, 0x2b, 0x10, 0x5b, 0xc6, 0x5b, 0x2f, 0x67, 0x65, +0x5d, 0x24, 0x32, 0x76, 0x7c, 0x7c, 0x37, 0x27, 0x3a, 0x26, +0x13, 0x03, 0x02, 0x42, 0x02, 0x05, 0x12, 0x20, 0x2c, 0x1b, +0x4d, 0x99, 0x93, 0x88, 0x3b, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x47, 0xff, 0x5b, 0x01, 0xad, 0x01, 0xd0, 0x02, 0x06, +0x00, 0x90, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1e, 0x00, 0x00, +0x01, 0xd6, 0x01, 0xd0, 0x02, 0x06, 0x00, 0x59, 0x00, 0x00, +0x00, 0x01, 0x00, 0x40, 0xff, 0x58, 0x01, 0xc3, 0x02, 0xb5, +0x00, 0x3a, 0x00, 0xd2, 0xb9, 0x00, 0x3a, 0xff, 0xe0, 0xb3, +0x0f, 0x00, 0x4d, 0x3a, 0xb8, 0xff, 0xe8, 0xb3, 0x0e, 0x00, +0x4d, 0x36, 0xb8, 0xff, 0xd0, 0xb3, 0x0f, 0x00, 0x4d, 0x36, +0xb8, 0xff, 0xd8, 0xb3, 0x0e, 0x00, 0x4d, 0x36, 0xb8, 0xff, +0xf8, 0xb3, 0x0d, 0x00, 0x4d, 0x35, 0xb8, 0xff, 0xd8, 0x40, +0x34, 0x0f, 0x00, 0x4d, 0x1d, 0x10, 0x10, 0x00, 0x4d, 0x1c, +0x20, 0x10, 0x12, 0x00, 0x4c, 0x1c, 0x10, 0x09, 0x00, 0x4d, +0x1c, 0x20, 0x08, 0x00, 0x4d, 0x18, 0x28, 0x12, 0x00, 0x4d, +0x18, 0x20, 0x10, 0x11, 0x00, 0x4c, 0x11, 0x18, 0x10, 0x00, +0x4d, 0x10, 0x28, 0x10, 0x00, 0x4d, 0x10, 0x18, 0x08, 0x0a, +0x00, 0x4c, 0x02, 0xb8, 0xff, 0xf0, 0xb3, 0x0e, 0x00, 0x4d, +0x02, 0xb8, 0xff, 0xe0, 0x40, 0x2d, 0x0d, 0x00, 0x4d, 0x31, +0x31, 0x03, 0x22, 0x22, 0x0c, 0x82, 0x03, 0x3c, 0x17, 0x2b, +0x82, 0x1a, 0x1a, 0x38, 0x82, 0x00, 0x12, 0x01, 0x08, 0x12, +0x3b, 0x17, 0x32, 0x85, 0x31, 0x31, 0x1f, 0x00, 0x89, 0x0f, +0x0f, 0x3b, 0x23, 0x23, 0x26, 0x88, 0x1f, 0x4d, 0x07, 0x06, +0x4b, 0x00, 0x3f, 0x33, 0x3f, 0xed, 0x32, 0x2f, 0x11, 0x33, +0x2f, 0xed, 0x11, 0x39, 0x2f, 0xed, 0x39, 0x01, 0x10, 0xd6, +0x5e, 0x5d, 0xed, 0x33, 0x2f, 0xed, 0x32, 0x10, 0xde, 0xed, +0x33, 0x2f, 0x11, 0x33, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x16, 0x16, 0x15, 0x14, 0x06, +0x07, 0x27, 0x3e, 0x03, 0x35, 0x34, 0x26, 0x27, 0x26, 0x26, +0x35, 0x34, 0x3e, 0x02, 0x37, 0x26, 0x26, 0x35, 0x34, 0x3e, +0x02, 0x33, 0x32, 0x16, 0x17, 0x07, 0x26, 0x26, 0x23, 0x22, +0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x33, 0x15, 0x23, +0x22, 0x0e, 0x02, 0x15, 0x14, 0x16, 0x01, 0x29, 0x56, 0x44, +0x1b, 0x11, 0x47, 0x04, 0x0b, 0x0b, 0x08, 0x36, 0x3d, 0x5f, +0x60, 0x1c, 0x29, 0x2f, 0x13, 0x33, 0x34, 0x20, 0x39, 0x4d, +0x2c, 0x2d, 0x41, 0x0e, 0x0e, 0x0f, 0x35, 0x24, 0x24, 0x32, +0x20, 0x0f, 0x18, 0x2a, 0x3a, 0x21, 0x44, 0x3c, 0x17, 0x42, +0x3f, 0x2c, 0x4c, 0x4d, 0x0f, 0x38, 0x35, 0x23, 0x3f, 0x17, +0x16, 0x06, 0x15, 0x19, 0x1b, 0x0c, 0x1e, 0x18, 0x0b, 0x0f, +0x5a, 0x52, 0x27, 0x3b, 0x2a, 0x1b, 0x07, 0x10, 0x53, 0x2e, +0x2c, 0x42, 0x2d, 0x16, 0x0d, 0x05, 0x47, 0x05, 0x0d, 0x11, +0x1d, 0x27, 0x16, 0x1c, 0x2a, 0x1b, 0x0d, 0x46, 0x0b, 0x1e, +0x36, 0x2b, 0x38, 0x35, 0x00, 0x00, 0xff, 0xff, 0x00, 0x28, +0xff, 0xf5, 0x01, 0xcc, 0x01, 0xdb, 0x02, 0x06, 0x00, 0x52, +0x00, 0x00, 0xff, 0xff, 0x00, 0x47, 0x00, 0x00, 0x01, 0xad, +0x01, 0xd0, 0x02, 0x06, 0x02, 0xf2, 0x00, 0x00, 0x00, 0x02, +0x00, 0x47, 0xff, 0x5b, 0x01, 0xcc, 0x01, 0xda, 0x00, 0x10, +0x00, 0x1f, 0x00, 0xa2, 0xb9, 0x00, 0x1d, 0xff, 0xf0, 0xb3, +0x10, 0x00, 0x4d, 0x1d, 0xb8, 0xff, 0xe8, 0x40, 0x1d, 0x0f, +0x00, 0x4d, 0x1b, 0x18, 0x10, 0x00, 0x4d, 0x1b, 0x20, 0x0f, +0x00, 0x4d, 0x16, 0x18, 0x10, 0x00, 0x4d, 0x16, 0x20, 0x0f, +0x00, 0x4d, 0x16, 0x08, 0x0e, 0x00, 0x4d, 0x0f, 0xb8, 0xff, +0xf0, 0xb3, 0x0a, 0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xe8, 0xb3, +0x09, 0x00, 0x4d, 0x0f, 0xb8, 0xff, 0xe0, 0xb3, 0x08, 0x00, +0x4d, 0x0b, 0xb8, 0xff, 0xe0, 0xb3, 0x09, 0x00, 0x4d, 0x0b, +0xb8, 0xff, 0xe8, 0x40, 0x2f, 0x08, 0x00, 0x4d, 0x08, 0x10, +0x11, 0x12, 0x00, 0x4c, 0x08, 0x10, 0x0a, 0x00, 0x4d, 0x08, +0x20, 0x08, 0x00, 0x4d, 0x07, 0x18, 0x09, 0x00, 0x4d, 0x19, +0x82, 0x0c, 0x21, 0x03, 0x1f, 0x7f, 0x00, 0x06, 0x01, 0x08, +0x06, 0x20, 0x1c, 0x88, 0x09, 0x50, 0x05, 0x4b, 0x14, 0x88, +0x00, 0x51, 0x00, 0x3f, 0xed, 0x3f, 0x3f, 0xed, 0x01, 0x10, +0xd6, 0x5e, 0x5d, 0xed, 0x32, 0x10, 0xde, 0xed, 0x31, 0x30, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x05, 0x22, 0x26, 0x27, +0x15, 0x23, 0x11, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, +0x0e, 0x02, 0x27, 0x16, 0x16, 0x33, 0x32, 0x3e, 0x02, 0x35, +0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x01, 0x08, 0x23, 0x3b, +0x11, 0x52, 0x60, 0x59, 0x63, 0x69, 0x1a, 0x33, 0x49, 0x9d, +0x18, 0x36, 0x17, 0x1f, 0x2e, 0x1e, 0x0e, 0x36, 0x3f, 0x32, +0x37, 0x0b, 0x16, 0x0b, 0xbb, 0x01, 0xa9, 0x67, 0x6f, 0x7c, +0x77, 0x34, 0x59, 0x40, 0x25, 0x6c, 0x14, 0x10, 0x1a, 0x2e, +0x3e, 0x24, 0x51, 0x5b, 0x4c, 0x51, 0x00, 0x00, 0x00, 0x01, +0x00, 0x3f, 0xff, 0x58, 0x01, 0xbf, 0x01, 0xdc, 0x00, 0x26, +0x00, 0x7a, 0xb9, 0x00, 0x25, 0xff, 0xe8, 0xb3, 0x0d, 0x00, +0x4d, 0x20, 0xb8, 0xff, 0xe0, 0xb3, 0x0d, 0x00, 0x4d, 0x20, +0xb8, 0xff, 0xe8, 0x40, 0x1e, 0x0c, 0x00, 0x4d, 0x17, 0x10, +0x0e, 0x00, 0x4d, 0x12, 0x10, 0x0e, 0x10, 0x00, 0x4c, 0x11, +0x20, 0x0e, 0x00, 0x4d, 0x11, 0x18, 0x09, 0x00, 0x4d, 0x11, +0x10, 0x08, 0x00, 0x4d, 0x02, 0xb8, 0xff, 0xf0, 0x40, 0x1f, +0x0f, 0x00, 0x4d, 0x1b, 0x1b, 0x0c, 0x82, 0x03, 0x28, 0x22, +0x82, 0x00, 0x14, 0x01, 0x08, 0x14, 0x27, 0x00, 0x89, 0x0f, +0x0f, 0x27, 0x1c, 0x1c, 0x1f, 0x88, 0x19, 0x50, 0x07, 0x06, +0x4b, 0x00, 0x3f, 0x33, 0x3f, 0xed, 0x32, 0x2f, 0x11, 0x33, +0x2f, 0xed, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, 0x10, 0xde, +0xed, 0x33, 0x2f, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x25, 0x16, 0x16, 0x15, 0x14, 0x06, +0x07, 0x27, 0x3e, 0x03, 0x35, 0x34, 0x26, 0x27, 0x2e, 0x03, +0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x17, 0x07, 0x26, 0x26, +0x23, 0x22, 0x06, 0x15, 0x14, 0x1e, 0x02, 0x01, 0x39, 0x4b, +0x3b, 0x1b, 0x10, 0x48, 0x04, 0x0b, 0x0b, 0x08, 0x29, 0x2e, +0x3e, 0x53, 0x32, 0x15, 0x1f, 0x3f, 0x5e, 0x3e, 0x48, 0x3b, +0x12, 0x14, 0x36, 0x1f, 0x55, 0x5a, 0x1a, 0x2e, 0x3c, 0x48, +0x0e, 0x36, 0x33, 0x23, 0x3f, 0x17, 0x16, 0x06, 0x15, 0x19, +0x1b, 0x0c, 0x1a, 0x19, 0x08, 0x0b, 0x26, 0x38, 0x4a, 0x2f, +0x32, 0x59, 0x44, 0x27, 0x16, 0x45, 0x08, 0x0c, 0x60, 0x4e, +0x2e, 0x39, 0x21, 0x11, 0x00, 0x02, 0x00, 0x28, 0xff, 0xf4, +0x01, 0xd9, 0x01, 0xd0, 0x00, 0x14, 0x00, 0x27, 0x00, 0xc5, +0xb9, 0x00, 0x26, 0xff, 0xf0, 0xb3, 0x0e, 0x00, 0x4d, 0x21, +0xb8, 0xff, 0xe0, 0xb3, 0x0e, 0x00, 0x4d, 0x21, 0xb8, 0xff, +0xf0, 0xb3, 0x0d, 0x00, 0x4d, 0x20, 0xb8, 0xff, 0xe8, 0x40, +0x3b, 0x0c, 0x00, 0x4d, 0x17, 0x10, 0x0e, 0x00, 0x4d, 0x10, +0x10, 0x10, 0x00, 0x4d, 0x10, 0x20, 0x0f, 0x00, 0x4d, 0x10, +0x08, 0x08, 0x00, 0x4d, 0x0f, 0x18, 0x10, 0x00, 0x4d, 0x0f, +0x10, 0x0f, 0x00, 0x4d, 0x0b, 0x18, 0x10, 0x00, 0x4d, 0x0b, +0x20, 0x0f, 0x00, 0x4d, 0x0a, 0x10, 0x10, 0x00, 0x4d, 0x0a, +0x20, 0x0f, 0x00, 0x4d, 0x0a, 0x10, 0x08, 0x00, 0x4d, 0x06, +0xb8, 0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x06, 0xb8, 0xff, +0xf0, 0xb3, 0x0f, 0x00, 0x4d, 0x06, 0xb8, 0xff, 0xe0, 0xb3, +0x08, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xf0, 0xb3, 0x10, 0x00, +0x4d, 0x05, 0xb8, 0xff, 0xe8, 0xb3, 0x0f, 0x00, 0x4d, 0x01, +0xb8, 0xff, 0xe8, 0x40, 0x17, 0x0c, 0x00, 0x4d, 0x1a, 0x82, +0x03, 0x14, 0x14, 0x03, 0x29, 0x23, 0x82, 0x0d, 0x28, 0x00, +0x1e, 0x85, 0x12, 0x49, 0x15, 0x88, 0x08, 0x51, 0x00, 0x3f, +0xed, 0x3f, 0xed, 0x32, 0x01, 0x10, 0xd6, 0xed, 0x10, 0xce, +0x32, 0x2f, 0x10, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x16, 0x16, +0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, +0x3e, 0x02, 0x33, 0x33, 0x15, 0x03, 0x32, 0x3e, 0x02, 0x35, +0x34, 0x26, 0x27, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, +0x02, 0x01, 0x7b, 0x23, 0x21, 0x1d, 0x36, 0x4b, 0x2d, 0x26, +0x4a, 0x39, 0x23, 0x26, 0x41, 0x54, 0x2f, 0xc7, 0xe5, 0x1d, +0x2c, 0x1e, 0x10, 0x25, 0x25, 0x12, 0x15, 0x33, 0x2c, 0x1e, +0x13, 0x21, 0x2b, 0x01, 0x8b, 0x2b, 0x5e, 0x2d, 0x30, 0x53, +0x3c, 0x22, 0x1d, 0x39, 0x57, 0x3b, 0x42, 0x5d, 0x3a, 0x1b, +0x45, 0xfe, 0xb3, 0x19, 0x2a, 0x37, 0x1f, 0x30, 0x60, 0x24, +0x0d, 0x26, 0x45, 0x37, 0x28, 0x3c, 0x27, 0x13, 0x00, 0x00, +0x00, 0x01, 0x00, 0x3f, 0xff, 0xf5, 0x01, 0xc2, 0x01, 0xd0, +0x00, 0x16, 0x00, 0x36, 0x40, 0x1e, 0x05, 0x18, 0x0b, 0x0c, +0x00, 0x4c, 0x0d, 0x7f, 0x08, 0x08, 0x09, 0x00, 0x00, 0x0c, +0x18, 0x00, 0x09, 0x01, 0x08, 0x09, 0x17, 0x0d, 0x08, 0x85, +0x0a, 0x49, 0x13, 0x88, 0x02, 0x51, 0x00, 0x3f, 0xed, 0x3f, +0xed, 0x32, 0x01, 0x10, 0xc6, 0x5e, 0x5d, 0x10, 0xce, 0x32, +0x2f, 0x11, 0x39, 0x2f, 0xed, 0x31, 0x30, 0x2b, 0x25, 0x06, +0x23, 0x22, 0x2e, 0x02, 0x35, 0x35, 0x23, 0x35, 0x21, 0x15, +0x23, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x36, 0x37, 0x01, +0xc2, 0x3b, 0x3f, 0x2a, 0x3f, 0x29, 0x15, 0x62, 0x01, 0x6f, +0xbb, 0x0a, 0x16, 0x25, 0x1a, 0x1f, 0x2e, 0x17, 0x0f, 0x1a, +0x11, 0x2a, 0x48, 0x37, 0xdc, 0x45, 0x45, 0xd6, 0x23, 0x2d, +0x1b, 0x0b, 0x0b, 0x0b, 0x00, 0x01, 0x00, 0x47, 0xff, 0xf6, +0x01, 0xab, 0x01, 0xd0, 0x00, 0x15, 0x00, 0x3c, 0x40, 0x0b, +0x0c, 0x28, 0x12, 0x00, 0x4d, 0x0c, 0x20, 0x11, 0x00, 0x4d, +0x0a, 0xb8, 0xff, 0xd8, 0x40, 0x17, 0x11, 0x12, 0x00, 0x4c, +0x0e, 0x7f, 0x11, 0x17, 0x08, 0x7f, 0x00, 0x05, 0x01, 0x08, +0x05, 0x16, 0x0f, 0x06, 0x49, 0x0b, 0x88, 0x00, 0x51, 0x00, +0x3f, 0xed, 0x3f, 0x33, 0x01, 0x10, 0xd6, 0x5e, 0x5d, 0xed, +0x10, 0xde, 0xed, 0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x17, 0x22, +0x2e, 0x02, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, +0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x0e, 0x02, 0xf9, 0x36, +0x45, 0x28, 0x0f, 0x53, 0x30, 0x2f, 0x30, 0x30, 0x52, 0x0f, +0x28, 0x45, 0x0a, 0x24, 0x3c, 0x4c, 0x27, 0x01, 0x07, 0xfe, +0xfd, 0x4e, 0x41, 0x41, 0x4e, 0x01, 0x03, 0xfe, 0xf9, 0x27, +0x4c, 0x3c, 0x24, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x1a, +0xff, 0x5b, 0x01, 0xda, 0x01, 0xd8, 0x00, 0x06, 0x00, 0x0d, +0x00, 0x24, 0x00, 0x94, 0xb9, 0x00, 0x22, 0xff, 0xf0, 0xb3, +0x10, 0x00, 0x4d, 0x22, 0xb8, 0xff, 0xe0, 0xb3, 0x0f, 0x00, +0x4d, 0x22, 0xb8, 0xff, 0xe0, 0xb3, 0x09, 0x00, 0x4d, 0x21, +0xb8, 0xff, 0xe0, 0xb3, 0x10, 0x00, 0x4d, 0x21, 0xb8, 0xff, +0xd8, 0x40, 0x0e, 0x0a, 0x00, 0x4d, 0x12, 0x20, 0x10, 0x00, +0x4d, 0x12, 0x10, 0x0f, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xd8, +0xb3, 0x0e, 0x00, 0x4d, 0x05, 0xb8, 0xff, 0xe0, 0xb3, 0x0d, +0x00, 0x4d, 0x02, 0xb8, 0xff, 0xd8, 0xb3, 0x0e, 0x00, 0x4d, +0x02, 0xb8, 0xff, 0xe8, 0x40, 0x1f, 0x0d, 0x00, 0x4d, 0x07, +0x24, 0x7f, 0x03, 0x10, 0x10, 0x15, 0x0a, 0x82, 0x1f, 0x26, +0x00, 0x82, 0x15, 0x25, 0x0d, 0x04, 0x88, 0x1a, 0x50, 0x07, +0x03, 0x88, 0x24, 0x10, 0x4c, 0x0f, 0x4b, 0x00, 0x3f, 0x3f, +0x33, 0xed, 0x32, 0x3f, 0xed, 0x32, 0x01, 0x10, 0xd6, 0xed, +0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, 0x33, 0xed, 0x32, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x2b, 0x37, 0x14, 0x16, 0x17, 0x11, 0x06, 0x06, 0x17, +0x36, 0x36, 0x35, 0x34, 0x26, 0x27, 0x11, 0x23, 0x35, 0x2e, +0x03, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, +0x14, 0x0e, 0x02, 0x07, 0x6c, 0x3d, 0x2c, 0x2c, 0x3d, 0xb2, +0x2c, 0x3e, 0x3e, 0x2c, 0x49, 0x26, 0x43, 0x34, 0x1e, 0x23, +0x3d, 0x52, 0x2f, 0x2e, 0x51, 0x3d, 0x23, 0x1e, 0x34, 0x44, +0x26, 0xe8, 0x4e, 0x55, 0x02, 0x01, 0x4a, 0x02, 0x55, 0xf3, +0x02, 0x55, 0x4e, 0x4e, 0x55, 0x02, 0xfd, 0xce, 0xa2, 0x01, +0x20, 0x3c, 0x57, 0x37, 0x3c, 0x5a, 0x3c, 0x1e, 0x1e, 0x3c, +0x5a, 0x3c, 0x37, 0x57, 0x3c, 0x20, 0x01, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x1d, 0x00, 0x00, 0x01, 0xd8, 0x01, 0xd0, +0x02, 0x06, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x25, +0xff, 0x5b, 0x01, 0xce, 0x01, 0xd0, 0x00, 0x1b, 0x00, 0x76, +0xb9, 0x00, 0x19, 0xff, 0xe8, 0xb4, 0x0f, 0x10, 0x00, 0x4c, +0x19, 0xb8, 0xff, 0xe8, 0x40, 0x0a, 0x0d, 0x00, 0x4d, 0x11, +0x10, 0x11, 0x12, 0x00, 0x4c, 0x0a, 0xb8, 0xff, 0xe0, 0xb3, +0x12, 0x00, 0x4d, 0x0a, 0xb8, 0xff, 0xe8, 0xb3, 0x11, 0x00, +0x4d, 0x0a, 0xb8, 0xff, 0xe8, 0xb3, 0x0a, 0x00, 0x4d, 0x0a, +0xb8, 0xff, 0xe0, 0x40, 0x1f, 0x09, 0x00, 0x4d, 0x0c, 0x00, +0x7f, 0x0f, 0x1b, 0x1b, 0x14, 0x04, 0x7f, 0x07, 0x1d, 0x17, +0x7f, 0x14, 0x1c, 0x1b, 0x1b, 0x05, 0x15, 0x49, 0x01, 0x1a, +0x88, 0x0c, 0x0f, 0x51, 0x0e, 0x4b, 0x00, 0x3f, 0x3f, 0x33, +0xed, 0x32, 0x3f, 0x33, 0x33, 0x2f, 0x01, 0x10, 0xd6, 0xed, +0x10, 0xde, 0xed, 0x11, 0x39, 0x2f, 0x33, 0xed, 0x32, 0x31, +0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x11, +0x36, 0x36, 0x35, 0x35, 0x33, 0x15, 0x14, 0x0e, 0x02, 0x07, +0x15, 0x23, 0x35, 0x2e, 0x03, 0x35, 0x35, 0x33, 0x15, 0x14, +0x16, 0x17, 0x11, 0x01, 0x1e, 0x31, 0x2d, 0x52, 0x14, 0x2b, +0x43, 0x2e, 0x49, 0x2f, 0x42, 0x2b, 0x14, 0x52, 0x2c, 0x32, +0x01, 0x65, 0xfe, 0xd7, 0x04, 0x57, 0x5f, 0xda, 0xe6, 0x34, +0x58, 0x40, 0x26, 0x02, 0x9b, 0x9b, 0x02, 0x26, 0x41, 0x58, +0x33, 0xe6, 0xda, 0x5f, 0x57, 0x04, 0x01, 0x29, 0x00, 0x00, +0x00, 0x01, 0x00, 0x24, 0xff, 0xf7, 0x01, 0xd2, 0x01, 0xda, +0x00, 0x34, 0x00, 0x83, 0xb9, 0x00, 0x33, 0xff, 0xf0, 0xb4, +0x0c, 0x0d, 0x00, 0x4c, 0x33, 0xb8, 0xff, 0xe8, 0x40, 0x0a, +0x0b, 0x00, 0x4d, 0x29, 0x10, 0x11, 0x12, 0x00, 0x4c, 0x12, +0xb8, 0xff, 0xf0, 0x40, 0x3f, 0x11, 0x12, 0x00, 0x4c, 0x08, +0x10, 0x0c, 0x00, 0x4d, 0x08, 0x18, 0x0b, 0x00, 0x4d, 0x03, +0x1e, 0x7f, 0x1d, 0x1d, 0x0b, 0x0f, 0x2a, 0x1f, 0x2a, 0xaf, +0x2a, 0xbf, 0x2a, 0x04, 0x2a, 0x2a, 0x25, 0x82, 0x30, 0x36, +0x00, 0x11, 0x10, 0x11, 0xa0, 0x11, 0xb0, 0x11, 0x04, 0x11, +0x11, 0x16, 0x82, 0x0b, 0x35, 0x2b, 0x10, 0x1d, 0x1d, 0x10, +0x50, 0x22, 0x03, 0x19, 0x88, 0x00, 0x06, 0x51, 0x00, 0x3f, +0x33, 0xed, 0x32, 0x32, 0x3f, 0x33, 0x2f, 0x11, 0x33, 0x01, +0x10, 0xd6, 0xed, 0x32, 0x2f, 0x5d, 0x10, 0xde, 0xed, 0x32, +0x2f, 0x5d, 0x11, 0x39, 0x2f, 0xed, 0x39, 0x31, 0x30, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x05, 0x22, 0x26, 0x27, 0x06, +0x06, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x37, +0x17, 0x0e, 0x03, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, +0x35, 0x33, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, +0x2e, 0x02, 0x27, 0x37, 0x1e, 0x03, 0x15, 0x14, 0x0e, 0x02, +0x01, 0x56, 0x1b, 0x30, 0x10, 0x10, 0x31, 0x1a, 0x23, 0x2f, +0x1d, 0x0d, 0x0d, 0x17, 0x20, 0x14, 0x4a, 0x14, 0x1d, 0x15, +0x0a, 0x13, 0x19, 0x17, 0x1d, 0x4a, 0x1d, 0x17, 0x19, 0x13, +0x0a, 0x15, 0x1e, 0x13, 0x4a, 0x13, 0x21, 0x17, 0x0d, 0x0d, +0x1d, 0x30, 0x09, 0x22, 0x25, 0x25, 0x22, 0x1f, 0x35, 0x47, +0x27, 0x27, 0x53, 0x4d, 0x42, 0x18, 0x1a, 0x1b, 0x44, 0x49, +0x4a, 0x20, 0x30, 0x3f, 0x41, 0x3f, 0x57, 0x57, 0x3f, 0x41, +0x3f, 0x30, 0x20, 0x4a, 0x49, 0x44, 0x1b, 0x1a, 0x18, 0x42, +0x4d, 0x53, 0x27, 0x27, 0x47, 0x35, 0x1f, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x02, 0x79, +0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x01, 0x07, 0x03, 0xd7, +0xff, 0x3e, 0x00, 0x00, 0x00, 0x0d, 0xb9, 0x00, 0x02, 0xff, +0x4f, 0xb4, 0x19, 0x17, 0x04, 0x0f, 0x50, 0x2b, 0x34, 0x00, +0xff, 0xff, 0xff, 0xbc, 0x00, 0x00, 0x01, 0xcc, 0x02, 0x79, +0x02, 0x37, 0x03, 0xd7, 0xfe, 0xee, 0x00, 0x00, 0x00, 0x06, +0x00, 0x28, 0x00, 0x00, 0xff, 0xff, 0xff, 0x88, 0x00, 0x00, +0x01, 0xc7, 0x02, 0x79, 0x02, 0x26, 0x00, 0x2b, 0x00, 0x00, +0x01, 0x07, 0x03, 0xd7, 0xfe, 0xba, 0x00, 0x00, 0x00, 0x0d, +0xb9, 0x00, 0x01, 0xfe, 0xcb, 0xb4, 0x0e, 0x0c, 0x07, 0x01, +0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0xff, 0xb6, 0x00, 0x00, +0x01, 0x9b, 0x02, 0x79, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, +0x01, 0x07, 0x03, 0xd7, 0xfe, 0xe8, 0x00, 0x00, 0x00, 0x0d, +0xb9, 0x00, 0x01, 0xfe, 0xf9, 0xb4, 0x0e, 0x0c, 0x04, 0x02, +0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0x00, 0x59, 0x00, 0x00, +0x01, 0x9b, 0x03, 0x1a, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, +0x01, 0x07, 0x00, 0x83, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x17, +0x40, 0x10, 0x02, 0x01, 0x00, 0x0e, 0x20, 0x04, 0x02, 0x50, +0x02, 0x09, 0x18, 0x4f, 0x01, 0x09, 0x0c, 0x4f, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xb8, +0xff, 0xf3, 0x01, 0xd8, 0x02, 0x79, 0x02, 0x37, 0x03, 0xd7, +0xfe, 0xea, 0x00, 0x00, 0x00, 0x06, 0x00, 0x32, 0x00, 0x00, +0xff, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x01, 0xe8, 0x02, 0x79, +0x02, 0x37, 0x03, 0xd7, 0xfe, 0xb0, 0x00, 0x00, 0x00, 0x06, +0x00, 0x3c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x00, +0x01, 0xe8, 0x03, 0x1a, 0x02, 0x26, 0x00, 0x3c, 0x00, 0x00, +0x01, 0x07, 0x00, 0x83, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x17, +0x40, 0x10, 0x02, 0x01, 0x00, 0x13, 0x25, 0x04, 0x0c, 0x50, +0x02, 0x04, 0x1d, 0x4f, 0x01, 0x04, 0x11, 0x4f, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xb6, +0x00, 0x00, 0x01, 0xe2, 0x02, 0x79, 0x02, 0x26, 0x03, 0xa8, +0x00, 0x00, 0x01, 0x07, 0x03, 0xd7, 0xfe, 0xe8, 0x00, 0x00, +0x00, 0x0d, 0xb9, 0x00, 0x01, 0xfe, 0xf9, 0xb4, 0x2e, 0x2c, +0x00, 0x12, 0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0x00, 0x31, +0xff, 0xf6, 0x01, 0xd7, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xa9, +0x00, 0x00, 0x01, 0x06, 0x03, 0xd6, 0x1e, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x02, 0x10, 0x2e, 0x2c, 0x14, 0x09, 0x50, 0x02, +0x00, 0x2d, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x45, +0xff, 0xf5, 0x01, 0xd2, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xad, +0x00, 0x00, 0x01, 0x06, 0x03, 0xd6, 0x2b, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x16, 0x38, 0x36, 0x2a, 0x23, 0x50, 0x01, +0x00, 0x37, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x47, +0xff, 0x5b, 0x01, 0xb0, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xaf, +0x00, 0x00, 0x01, 0x06, 0x03, 0xd6, 0x16, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x11, 0x16, 0x14, 0x00, 0x05, 0x50, 0x01, +0x02, 0x15, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x36, +0xff, 0xf5, 0x01, 0xc2, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xb1, +0x00, 0x00, 0x01, 0x06, 0x03, 0xd6, 0x09, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x03, 0x18, 0x16, 0x0a, 0x00, 0x50, 0x01, +0x0b, 0x17, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x36, +0xff, 0xf5, 0x01, 0xc2, 0x02, 0x8f, 0x02, 0x26, 0x03, 0xb1, +0x00, 0x00, 0x01, 0x06, 0x00, 0x83, 0xdd, 0x00, 0x00, 0x1a, +0xb1, 0x02, 0x01, 0xb8, 0xff, 0xdb, 0x40, 0x0d, 0x18, 0x2a, +0x0a, 0x00, 0x50, 0x02, 0x0b, 0x22, 0x4f, 0x01, 0x0b, 0x16, +0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x26, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0xb9, 0x02, 0x26, +0x03, 0xb1, 0x00, 0x00, 0x01, 0x06, 0x03, 0xd8, 0xe6, 0x00, +0x00, 0x21, 0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, 0xdb, 0x40, +0x11, 0x28, 0x22, 0x0a, 0x00, 0x50, 0x03, 0x0b, 0x26, 0x4f, +0x02, 0x0b, 0x1a, 0x4f, 0x01, 0x0b, 0x17, 0x4f, 0x2b, 0x2b, +0x2b, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0xbb, 0x02, 0x26, +0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x03, 0xd6, 0x16, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x02, 0x12, 0x22, 0x20, 0x09, 0x00, +0x50, 0x02, 0x0e, 0x21, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x47, 0xff, 0xf6, 0x01, 0xab, 0x02, 0x8f, 0x02, 0x26, +0x03, 0xbd, 0x00, 0x00, 0x01, 0x06, 0x00, 0x83, 0x00, 0x00, +0x00, 0x17, 0x40, 0x10, 0x02, 0x01, 0x01, 0x18, 0x2a, 0x04, +0x10, 0x50, 0x02, 0x06, 0x22, 0x4f, 0x01, 0x06, 0x16, 0x4f, +0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x47, +0xff, 0xf6, 0x01, 0xab, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xbd, +0x00, 0x00, 0x01, 0x06, 0x03, 0xd6, 0x16, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x13, 0x18, 0x16, 0x04, 0x10, 0x50, 0x01, +0x06, 0x17, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x47, +0xff, 0xf6, 0x01, 0xab, 0x02, 0xb9, 0x02, 0x26, 0x03, 0xbd, +0x00, 0x00, 0x01, 0x06, 0x03, 0xd8, 0x09, 0x00, 0x00, 0x1e, +0x40, 0x15, 0x03, 0x02, 0x01, 0x01, 0x28, 0x22, 0x04, 0x10, +0x50, 0x03, 0x06, 0x26, 0x4f, 0x02, 0x06, 0x1a, 0x4f, 0x01, +0x06, 0x17, 0x4f, 0x2b, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0xf7, 0x01, 0xd2, +0x02, 0xbb, 0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, 0x01, 0x06, +0x03, 0xd6, 0x19, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x14, +0x37, 0x35, 0x0a, 0x2f, 0x50, 0x01, 0x10, 0x36, 0x4f, 0x2b, +0x2b, 0x34, 0x00, 0x01, 0x00, 0xa4, 0x02, 0x01, 0x01, 0x49, +0x02, 0xbb, 0x00, 0x03, 0x00, 0x1b, 0x40, 0x09, 0x03, 0x00, +0x01, 0x02, 0x00, 0x03, 0x80, 0x02, 0x01, 0x00, 0x2f, 0x33, +0x1a, 0xcd, 0x32, 0x01, 0x2f, 0x19, 0xc5, 0x18, 0xdd, 0x19, +0xc5, 0x31, 0x30, 0x01, 0x07, 0x27, 0x37, 0x01, 0x49, 0x74, +0x31, 0x65, 0x02, 0x8f, 0x8e, 0x22, 0x98, 0x00, 0x00, 0x01, +0x00, 0xce, 0x01, 0xb7, 0x01, 0x48, 0x02, 0x79, 0x00, 0x03, +0x00, 0x12, 0xb6, 0x03, 0x00, 0x01, 0x02, 0x01, 0x03, 0x45, +0x00, 0x3f, 0xcd, 0x01, 0x2f, 0xcd, 0xdd, 0xcd, 0x31, 0x30, +0x01, 0x07, 0x27, 0x37, 0x01, 0x48, 0x3d, 0x3d, 0x29, 0x02, +0x65, 0xae, 0x0f, 0xb3, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, +0x02, 0x04, 0x01, 0xa2, 0x02, 0xb9, 0x00, 0x03, 0x00, 0x0f, +0x00, 0x1b, 0x00, 0x30, 0x40, 0x15, 0x0d, 0x07, 0x19, 0x03, +0x00, 0x01, 0x02, 0x02, 0x13, 0x19, 0x0a, 0x16, 0x40, 0x04, +0x10, 0x10, 0x00, 0x03, 0x80, 0x02, 0x01, 0x00, 0x2f, 0x33, +0x1a, 0xcd, 0x32, 0x33, 0x2f, 0x33, 0x1a, 0xcd, 0x32, 0x01, +0x2f, 0xcd, 0x33, 0x2f, 0x33, 0xcd, 0x32, 0x10, 0xdc, 0xcd, +0x31, 0x30, 0x01, 0x07, 0x27, 0x37, 0x17, 0x22, 0x26, 0x35, +0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x21, 0x22, +0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, +0x01, 0x37, 0x5d, 0x2f, 0x50, 0x77, 0x15, 0x1c, 0x1c, 0x15, +0x14, 0x1c, 0x1c, 0xfe, 0xeb, 0x14, 0x1d, 0x1d, 0x14, 0x14, +0x1c, 0x1c, 0x02, 0x92, 0x8e, 0x1c, 0x99, 0x8e, 0x1a, 0x17, +0x16, 0x1b, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, +0x1b, 0x16, 0x17, 0x1a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x31, +0xff, 0xf6, 0x01, 0xd7, 0x02, 0xb9, 0x02, 0x26, 0x03, 0xa9, +0x00, 0x00, 0x01, 0x06, 0x04, 0x87, 0x00, 0x00, 0x00, 0x13, +0xb9, 0x00, 0x02, 0xff, 0xf6, 0x40, 0x09, 0x2c, 0x37, 0x14, +0x09, 0x50, 0x02, 0x00, 0x3d, 0x4f, 0x2b, 0x2b, 0x34, 0x00, +0xff, 0xff, 0x00, 0x31, 0xff, 0xf6, 0x01, 0xd7, 0x02, 0xb9, +0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, 0x01, 0x06, 0x04, 0xc1, +0x09, 0x00, 0x00, 0x13, 0xb9, 0x00, 0x02, 0xff, 0xff, 0x40, +0x09, 0x30, 0x3c, 0x14, 0x09, 0x50, 0x02, 0x00, 0x2c, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, 0x00, 0x31, 0xff, 0xf6, +0x01, 0xd7, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, +0x01, 0x06, 0x04, 0x96, 0x00, 0x00, 0x00, 0x1a, 0xb1, 0x03, +0x02, 0xb8, 0xff, 0xf6, 0x40, 0x0d, 0x2c, 0x3f, 0x14, 0x09, +0x50, 0x03, 0x00, 0x40, 0x4f, 0x02, 0x00, 0x3d, 0x4f, 0x2b, +0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x31, +0xff, 0xf6, 0x01, 0xd7, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xa9, +0x00, 0x00, 0x01, 0x06, 0x04, 0xa3, 0x00, 0x00, 0x00, 0x1a, +0xb1, 0x03, 0x02, 0xb8, 0xff, 0xf6, 0x40, 0x0d, 0x2e, 0x3d, +0x14, 0x09, 0x50, 0x03, 0x00, 0x3e, 0x4f, 0x02, 0x00, 0x2c, +0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x31, 0xff, 0xf6, 0x01, 0xd7, 0x02, 0xbb, 0x02, 0x26, +0x03, 0xa9, 0x00, 0x00, 0x01, 0x06, 0x04, 0x97, 0x24, 0x00, +0x00, 0x17, 0x40, 0x10, 0x03, 0x02, 0x1a, 0x2c, 0x3e, 0x14, +0x09, 0x50, 0x03, 0x00, 0x3f, 0x4f, 0x02, 0x00, 0x3d, 0x4f, +0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x31, +0xff, 0xf6, 0x01, 0xd7, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xa9, +0x00, 0x00, 0x01, 0x06, 0x04, 0xa4, 0x12, 0x00, 0x00, 0x17, +0x40, 0x10, 0x03, 0x02, 0x08, 0x2e, 0x3c, 0x14, 0x09, 0x50, +0x03, 0x00, 0x3d, 0x4f, 0x02, 0x00, 0x2c, 0x4f, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x31, 0xff, 0xf6, +0x01, 0xd7, 0x03, 0x13, 0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, +0x01, 0x06, 0x04, 0x98, 0x12, 0x00, 0x00, 0x17, 0x40, 0x10, +0x03, 0x02, 0x08, 0x4b, 0x41, 0x14, 0x09, 0x50, 0x03, 0x00, +0x43, 0x4f, 0x02, 0x00, 0x3c, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, +0x34, 0x00, 0xff, 0xff, 0x00, 0x31, 0xff, 0xf6, 0x01, 0xd7, +0x03, 0x13, 0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, 0x01, 0x06, +0x04, 0xa5, 0x00, 0x00, 0x00, 0x1a, 0xb1, 0x03, 0x02, 0xb8, +0xff, 0xf6, 0x40, 0x0d, 0x4b, 0x41, 0x14, 0x09, 0x50, 0x03, +0x00, 0x43, 0x4f, 0x02, 0x00, 0x2c, 0x4f, 0x2b, 0x2b, 0x2b, +0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x06, 0x00, 0x00, +0x01, 0xeb, 0x02, 0x7a, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, +0x01, 0x07, 0x04, 0x87, 0xff, 0x4d, 0xff, 0xc1, 0x00, 0x0d, +0xb9, 0x00, 0x02, 0xff, 0x4d, 0xb4, 0x17, 0x22, 0x04, 0x0f, +0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0xff, 0xf5, 0x00, 0x00, +0x01, 0xeb, 0x02, 0x7a, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, +0x01, 0x07, 0x04, 0xc1, 0xff, 0x3c, 0xff, 0xc1, 0x00, 0x0d, +0xb9, 0x00, 0x02, 0xff, 0x3c, 0xb4, 0x1b, 0x27, 0x04, 0x0f, +0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0xff, 0x45, 0x00, 0x00, +0x01, 0xeb, 0x02, 0x7c, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, +0x01, 0x07, 0x04, 0x96, 0xfe, 0xe5, 0xff, 0xc1, 0x00, 0x0f, +0xb1, 0x03, 0x02, 0xb8, 0xfe, 0xe5, 0xb4, 0x17, 0x2a, 0x04, +0x0f, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0xff, 0x58, 0x00, 0x00, 0x01, 0xeb, 0x02, 0x7c, 0x02, 0x26, +0x00, 0x24, 0x00, 0x00, 0x01, 0x07, 0x04, 0xa3, 0xfe, 0xef, +0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, 0xfe, 0xef, +0xb4, 0x19, 0x28, 0x04, 0x0f, 0x50, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0xff, 0x78, 0x00, 0x00, 0x01, 0xeb, +0x02, 0x7c, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x01, 0x07, +0x04, 0x97, 0xff, 0x0e, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x03, +0x02, 0xb8, 0xff, 0x0e, 0xb4, 0x17, 0x29, 0x04, 0x0f, 0x50, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x62, +0x00, 0x00, 0x01, 0xeb, 0x02, 0x7c, 0x02, 0x26, 0x00, 0x24, +0x00, 0x00, 0x01, 0x07, 0x04, 0xa4, 0xff, 0x02, 0xff, 0xc1, +0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, 0xff, 0x02, 0xb4, 0x19, +0x27, 0x04, 0x0f, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0xae, 0x00, 0x00, 0x01, 0xeb, 0x02, 0xb4, +0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x01, 0x07, 0x04, 0x98, +0xff, 0x2b, 0xff, 0xa1, 0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, +0xff, 0x2b, 0xb4, 0x36, 0x2c, 0x04, 0x0f, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa4, 0x00, 0x00, +0x01, 0xeb, 0x02, 0xb4, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, +0x01, 0x07, 0x04, 0xa5, 0xff, 0x21, 0xff, 0xa1, 0x00, 0x0f, +0xb1, 0x03, 0x02, 0xb8, 0xff, 0x21, 0xb4, 0x36, 0x2c, 0x04, +0x0f, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x45, 0xff, 0xf5, 0x01, 0xd2, 0x02, 0xb9, 0x02, 0x26, +0x03, 0xad, 0x00, 0x00, 0x01, 0x06, 0x04, 0x87, 0x1b, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x09, 0x36, 0x41, 0x2a, 0x23, +0x50, 0x01, 0x00, 0x47, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x45, 0xff, 0xf5, 0x01, 0xd2, 0x02, 0xb9, 0x02, 0x26, +0x03, 0xad, 0x00, 0x00, 0x01, 0x06, 0x04, 0xc1, 0x09, 0x00, +0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xf7, 0x40, 0x09, 0x3a, +0x46, 0x2a, 0x23, 0x50, 0x01, 0x00, 0x36, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0xff, 0xff, 0x00, 0x45, 0xff, 0xf5, 0x01, 0xd2, +0x02, 0xbb, 0x02, 0x26, 0x03, 0xad, 0x00, 0x00, 0x01, 0x06, +0x04, 0x96, 0x24, 0x00, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, +0x12, 0x36, 0x49, 0x2a, 0x23, 0x50, 0x02, 0x00, 0x4a, 0x4f, +0x01, 0x00, 0x47, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0xff, 0xff, 0x00, 0x45, 0xff, 0xf5, 0x01, 0xd2, 0x02, 0xbb, +0x02, 0x26, 0x03, 0xad, 0x00, 0x00, 0x01, 0x06, 0x04, 0xa3, +0x00, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, 0xff, 0xef, +0x40, 0x0d, 0x38, 0x47, 0x2a, 0x23, 0x50, 0x02, 0x00, 0x48, +0x4f, 0x01, 0x00, 0x36, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x45, 0xff, 0xf5, 0x01, 0xd2, +0x02, 0xbb, 0x02, 0x26, 0x03, 0xad, 0x00, 0x00, 0x01, 0x06, +0x04, 0x97, 0x00, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, +0xff, 0xef, 0x40, 0x0d, 0x36, 0x48, 0x2a, 0x23, 0x50, 0x02, +0x00, 0x49, 0x4f, 0x01, 0x00, 0x47, 0x4f, 0x2b, 0x2b, 0x2b, +0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x45, 0xff, 0xf5, +0x01, 0xd2, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xad, 0x00, 0x00, +0x01, 0x06, 0x04, 0xa4, 0x12, 0x00, 0x00, 0x17, 0x40, 0x10, +0x02, 0x01, 0x00, 0x38, 0x46, 0x2a, 0x23, 0x50, 0x02, 0x00, +0x47, 0x4f, 0x01, 0x00, 0x36, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, +0x34, 0x00, 0xff, 0xff, 0xff, 0xb1, 0x00, 0x00, 0x01, 0xcc, +0x02, 0x7a, 0x02, 0x26, 0x00, 0x28, 0x00, 0x00, 0x01, 0x07, +0x04, 0x87, 0xfe, 0xf8, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, +0x01, 0xfe, 0xde, 0xb4, 0x0c, 0x17, 0x00, 0x0a, 0x50, 0x2b, +0x34, 0x00, 0xff, 0xff, 0xff, 0xb5, 0x00, 0x00, 0x01, 0xcc, +0x02, 0x7a, 0x02, 0x26, 0x00, 0x28, 0x00, 0x00, 0x01, 0x07, +0x04, 0xc1, 0xfe, 0xfc, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, +0x01, 0xfe, 0xe2, 0xb4, 0x10, 0x1c, 0x00, 0x0a, 0x50, 0x2b, +0x34, 0x00, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x01, 0xcc, +0x02, 0x7c, 0x02, 0x26, 0x00, 0x28, 0x00, 0x00, 0x01, 0x07, +0x04, 0x96, 0xfe, 0xa7, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x02, +0x01, 0xb8, 0xfe, 0x8e, 0xb4, 0x0c, 0x1f, 0x00, 0x0a, 0x50, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x19, +0x00, 0x00, 0x01, 0xcc, 0x02, 0x7c, 0x02, 0x26, 0x00, 0x28, +0x00, 0x00, 0x01, 0x07, 0x04, 0xa3, 0xfe, 0xb0, 0xff, 0xc1, +0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, 0xfe, 0x97, 0xb4, 0x0e, +0x1d, 0x00, 0x0a, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0x1a, 0x00, 0x00, 0x01, 0xcc, 0x02, 0x7c, +0x02, 0x26, 0x00, 0x28, 0x00, 0x00, 0x01, 0x07, 0x04, 0x97, +0xfe, 0xb0, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, +0xfe, 0x97, 0xb4, 0x0c, 0x1e, 0x00, 0x0a, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, +0x01, 0xcc, 0x02, 0x7c, 0x02, 0x26, 0x00, 0x28, 0x00, 0x00, +0x01, 0x07, 0x04, 0xa4, 0xfe, 0xa7, 0xff, 0xc1, 0x00, 0x0f, +0xb1, 0x02, 0x01, 0xb8, 0xfe, 0x8e, 0xb4, 0x0e, 0x1c, 0x00, +0x0a, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x47, 0xff, 0x5b, 0x01, 0xb0, 0x02, 0xb9, 0x02, 0x26, +0x03, 0xaf, 0x00, 0x00, 0x01, 0x06, 0x04, 0x87, 0x00, 0x00, +0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xfe, 0x40, 0x09, 0x14, +0x1f, 0x00, 0x05, 0x50, 0x01, 0x02, 0x25, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0xff, 0xff, 0x00, 0x47, 0xff, 0x5b, 0x01, 0xb0, +0x02, 0xb9, 0x02, 0x26, 0x03, 0xaf, 0x00, 0x00, 0x01, 0x06, +0x04, 0xc1, 0x09, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x07, +0x18, 0x24, 0x00, 0x05, 0x50, 0x01, 0x02, 0x14, 0x4f, 0x2b, +0x2b, 0x34, 0xff, 0xff, 0x00, 0x47, 0xff, 0x5b, 0x01, 0xb0, +0x02, 0xbb, 0x02, 0x26, 0x03, 0xaf, 0x00, 0x00, 0x01, 0x06, +0x04, 0x96, 0x00, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, +0xff, 0xff, 0x40, 0x0d, 0x14, 0x27, 0x00, 0x05, 0x50, 0x02, +0x02, 0x28, 0x4f, 0x01, 0x02, 0x25, 0x4f, 0x2b, 0x2b, 0x2b, +0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x47, 0xff, 0x5b, +0x01, 0xb0, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xaf, 0x00, 0x00, +0x01, 0x06, 0x04, 0xa3, 0x00, 0x00, 0x00, 0x1a, 0xb1, 0x02, +0x01, 0xb8, 0xff, 0xff, 0x40, 0x0d, 0x16, 0x25, 0x00, 0x05, +0x50, 0x02, 0x02, 0x26, 0x4f, 0x01, 0x02, 0x14, 0x4f, 0x2b, +0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x47, +0xff, 0x5b, 0x01, 0xb0, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xaf, +0x00, 0x00, 0x01, 0x06, 0x04, 0x97, 0x00, 0x00, 0x00, 0x1a, +0xb1, 0x02, 0x01, 0xb8, 0xff, 0xff, 0x40, 0x0d, 0x14, 0x26, +0x00, 0x05, 0x50, 0x02, 0x02, 0x27, 0x4f, 0x01, 0x02, 0x25, +0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x47, 0xff, 0x5b, 0x01, 0xb0, 0x02, 0xbb, 0x02, 0x26, +0x03, 0xaf, 0x00, 0x00, 0x01, 0x06, 0x04, 0xa4, 0x12, 0x00, +0x00, 0x17, 0x40, 0x10, 0x02, 0x01, 0x10, 0x16, 0x24, 0x00, +0x05, 0x50, 0x02, 0x02, 0x25, 0x4f, 0x01, 0x02, 0x14, 0x4f, +0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x47, +0xff, 0x5b, 0x01, 0xb0, 0x03, 0x13, 0x02, 0x26, 0x03, 0xaf, +0x00, 0x00, 0x01, 0x06, 0x04, 0x98, 0x00, 0x00, 0x00, 0x1a, +0xb1, 0x02, 0x01, 0xb8, 0xff, 0xff, 0x40, 0x0d, 0x33, 0x29, +0x00, 0x05, 0x50, 0x02, 0x02, 0x2b, 0x4f, 0x01, 0x02, 0x24, +0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x47, 0xff, 0x5b, 0x01, 0xb0, 0x03, 0x13, 0x02, 0x26, +0x03, 0xaf, 0x00, 0x00, 0x01, 0x06, 0x04, 0xa5, 0x00, 0x00, +0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, 0xff, 0xff, 0x40, 0x0d, +0x33, 0x29, 0x00, 0x05, 0x50, 0x02, 0x02, 0x2b, 0x4f, 0x01, +0x02, 0x14, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, +0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x01, 0xc7, 0x02, 0x7a, +0x02, 0x26, 0x00, 0x2b, 0x00, 0x00, 0x01, 0x07, 0x04, 0x87, +0xfe, 0xca, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, 0x01, 0xfe, +0xca, 0xb4, 0x0c, 0x17, 0x07, 0x01, 0x50, 0x2b, 0x34, 0x00, +0xff, 0xff, 0xff, 0x88, 0x00, 0x00, 0x01, 0xc7, 0x02, 0x7a, +0x02, 0x26, 0x00, 0x2b, 0x00, 0x00, 0x01, 0x07, 0x04, 0xc1, +0xfe, 0xcf, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, 0x01, 0xfe, +0xcf, 0xb4, 0x10, 0x1c, 0x07, 0x01, 0x50, 0x2b, 0x34, 0x00, +0xff, 0xff, 0xfe, 0xd9, 0x00, 0x00, 0x01, 0xc7, 0x02, 0x7c, +0x02, 0x26, 0x00, 0x2b, 0x00, 0x00, 0x01, 0x07, 0x04, 0x96, +0xfe, 0x79, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, +0xfe, 0x79, 0xb4, 0x0c, 0x1f, 0x07, 0x01, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xea, 0x00, 0x00, +0x01, 0xc7, 0x02, 0x7c, 0x02, 0x26, 0x00, 0x2b, 0x00, 0x00, +0x01, 0x07, 0x04, 0xa3, 0xfe, 0x81, 0xff, 0xc1, 0x00, 0x0f, +0xb1, 0x02, 0x01, 0xb8, 0xfe, 0x81, 0xb4, 0x0e, 0x1d, 0x07, +0x01, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0xfe, 0xec, 0x00, 0x00, 0x01, 0xc7, 0x02, 0x7c, 0x02, 0x26, +0x00, 0x2b, 0x00, 0x00, 0x01, 0x07, 0x04, 0x97, 0xfe, 0x82, +0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, 0xfe, 0x82, +0xb4, 0x0c, 0x1e, 0x07, 0x01, 0x50, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0xfe, 0xd9, 0x00, 0x00, 0x01, 0xc7, +0x02, 0x7c, 0x02, 0x26, 0x00, 0x2b, 0x00, 0x00, 0x01, 0x07, +0x04, 0xa4, 0xfe, 0x79, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x02, +0x01, 0xb8, 0xfe, 0x79, 0xb4, 0x0e, 0x1c, 0x07, 0x01, 0x50, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1a, +0x00, 0x00, 0x01, 0xc7, 0x02, 0xb4, 0x02, 0x26, 0x00, 0x2b, +0x00, 0x00, 0x01, 0x07, 0x04, 0x98, 0xfe, 0x97, 0xff, 0xa1, +0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, 0xfe, 0x97, 0xb4, 0x2b, +0x21, 0x07, 0x01, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0x1a, 0x00, 0x00, 0x01, 0xc7, 0x02, 0xb4, +0x02, 0x26, 0x00, 0x2b, 0x00, 0x00, 0x01, 0x07, 0x04, 0xa5, +0xfe, 0x97, 0xff, 0xa1, 0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, +0xfe, 0x97, 0xb4, 0x2b, 0x21, 0x07, 0x01, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, +0x01, 0xc2, 0x02, 0xb9, 0x02, 0x26, 0x03, 0xb1, 0x00, 0x00, +0x01, 0x06, 0x04, 0x87, 0xdd, 0x00, 0x00, 0x13, 0xb9, 0x00, +0x01, 0xff, 0xdb, 0x40, 0x09, 0x16, 0x21, 0x0a, 0x00, 0x50, +0x01, 0x0b, 0x27, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, +0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0xb9, 0x02, 0x26, +0x03, 0xb1, 0x00, 0x00, 0x01, 0x06, 0x04, 0xc1, 0xe6, 0x00, +0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xe4, 0x40, 0x09, 0x1a, +0x26, 0x0a, 0x00, 0x50, 0x01, 0x0b, 0x16, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, +0x02, 0xbb, 0x02, 0x26, 0x03, 0xb1, 0x00, 0x00, 0x01, 0x06, +0x04, 0x96, 0xe6, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, +0xff, 0xe4, 0x40, 0x0d, 0x16, 0x29, 0x0a, 0x00, 0x50, 0x02, +0x0b, 0x2a, 0x4f, 0x01, 0x0b, 0x27, 0x4f, 0x2b, 0x2b, 0x2b, +0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, +0x01, 0xc2, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xb1, 0x00, 0x00, +0x01, 0x06, 0x04, 0xa3, 0xe6, 0x00, 0x00, 0x1a, 0xb1, 0x02, +0x01, 0xb8, 0xff, 0xe4, 0x40, 0x0d, 0x18, 0x27, 0x0a, 0x00, +0x50, 0x02, 0x0b, 0x28, 0x4f, 0x01, 0x0b, 0x16, 0x4f, 0x2b, +0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x36, +0xff, 0xf5, 0x01, 0xc2, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xb1, +0x00, 0x00, 0x01, 0x06, 0x04, 0x97, 0xf8, 0x00, 0x00, 0x1a, +0xb1, 0x02, 0x01, 0xb8, 0xff, 0xf6, 0x40, 0x0d, 0x16, 0x28, +0x0a, 0x00, 0x50, 0x02, 0x0b, 0x29, 0x4f, 0x01, 0x0b, 0x27, +0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0xbb, 0x02, 0x26, +0x03, 0xb1, 0x00, 0x00, 0x01, 0x06, 0x04, 0xa4, 0xef, 0x00, +0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, 0xff, 0xed, 0x40, 0x0d, +0x18, 0x26, 0x0a, 0x00, 0x50, 0x02, 0x0b, 0x27, 0x4f, 0x01, +0x0b, 0x16, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x03, 0x13, +0x02, 0x26, 0x03, 0xb1, 0x00, 0x00, 0x01, 0x06, 0x04, 0x98, +0xe6, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, 0xff, 0xe4, +0x40, 0x0d, 0x35, 0x2b, 0x0a, 0x00, 0x50, 0x02, 0x0b, 0x2d, +0x4f, 0x01, 0x0b, 0x26, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, +0x03, 0x13, 0x02, 0x26, 0x03, 0xb1, 0x00, 0x00, 0x01, 0x06, +0x04, 0xa5, 0xe6, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, +0xff, 0xe4, 0x40, 0x0d, 0x35, 0x2b, 0x0a, 0x00, 0x50, 0x02, +0x0b, 0x2d, 0x4f, 0x01, 0x0b, 0x16, 0x4f, 0x2b, 0x2b, 0x2b, +0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0xff, 0xb0, 0x00, 0x00, +0x01, 0x9b, 0x02, 0x7a, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, +0x01, 0x07, 0x04, 0x87, 0xfe, 0xf7, 0xff, 0xc1, 0x00, 0x0d, +0xb9, 0x00, 0x01, 0xfe, 0xf7, 0xb4, 0x0c, 0x17, 0x04, 0x02, +0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0xff, 0xb4, 0x00, 0x00, +0x01, 0x9b, 0x02, 0x7a, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, +0x01, 0x07, 0x04, 0xc1, 0xfe, 0xfb, 0xff, 0xc1, 0x00, 0x0d, +0xb9, 0x00, 0x01, 0xfe, 0xfb, 0xb4, 0x10, 0x1c, 0x04, 0x02, +0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0xff, 0x06, 0x00, 0x00, +0x01, 0x9b, 0x02, 0x7c, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, +0x01, 0x07, 0x04, 0x96, 0xfe, 0xa6, 0xff, 0xc1, 0x00, 0x0f, +0xb1, 0x02, 0x01, 0xb8, 0xfe, 0xa6, 0xb4, 0x0c, 0x1f, 0x04, +0x02, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0xff, 0x18, 0x00, 0x00, 0x01, 0x9b, 0x02, 0x7c, 0x02, 0x26, +0x00, 0x2c, 0x00, 0x00, 0x01, 0x07, 0x04, 0xa3, 0xfe, 0xaf, +0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, 0xfe, 0xaf, +0xb4, 0x0e, 0x1d, 0x04, 0x02, 0x50, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0xff, 0x19, 0x00, 0x00, 0x01, 0x9b, +0x02, 0x7c, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x07, +0x04, 0x97, 0xfe, 0xaf, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x02, +0x01, 0xb8, 0xfe, 0xaf, 0xb4, 0x0c, 0x1e, 0x04, 0x02, 0x50, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x06, +0x00, 0x00, 0x01, 0x9b, 0x02, 0x7c, 0x02, 0x26, 0x00, 0x2c, +0x00, 0x00, 0x01, 0x07, 0x04, 0xa4, 0xfe, 0xa6, 0xff, 0xc1, +0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, 0xfe, 0xa6, 0xb4, 0x0e, +0x1c, 0x04, 0x02, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0x48, 0x00, 0x00, 0x01, 0x9b, 0x02, 0xb4, +0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x07, 0x04, 0x98, +0xfe, 0xc5, 0xff, 0xa1, 0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, +0xfe, 0xc5, 0xb4, 0x2b, 0x21, 0x04, 0x02, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x48, 0x00, 0x00, +0x01, 0x9b, 0x02, 0xb4, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, +0x01, 0x07, 0x04, 0xa5, 0xfe, 0xc5, 0xff, 0xa1, 0x00, 0x0f, +0xb1, 0x02, 0x01, 0xb8, 0xfe, 0xc5, 0xb4, 0x2b, 0x21, 0x04, +0x02, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0xb9, 0x02, 0x26, +0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x04, 0x87, 0x00, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x20, 0x2b, 0x09, 0x00, +0x50, 0x02, 0x0e, 0x31, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0xb9, 0x02, 0x26, +0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x04, 0xc1, 0x09, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x02, 0x08, 0x24, 0x30, 0x09, 0x00, +0x50, 0x02, 0x0e, 0x20, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0xbb, 0x02, 0x26, +0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x04, 0x96, 0x00, 0x00, +0x00, 0x17, 0x40, 0x10, 0x03, 0x02, 0x00, 0x20, 0x33, 0x09, +0x00, 0x50, 0x03, 0x0e, 0x34, 0x4f, 0x02, 0x0e, 0x31, 0x4f, +0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x28, +0xff, 0xf5, 0x01, 0xcc, 0x02, 0xbb, 0x02, 0x26, 0x00, 0x52, +0x00, 0x00, 0x01, 0x06, 0x04, 0xa3, 0x00, 0x00, 0x00, 0x17, +0x40, 0x10, 0x03, 0x02, 0x00, 0x22, 0x31, 0x09, 0x00, 0x50, +0x03, 0x0e, 0x32, 0x4f, 0x02, 0x0e, 0x20, 0x4f, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, +0x01, 0xcc, 0x02, 0xbb, 0x02, 0x26, 0x00, 0x52, 0x00, 0x00, +0x01, 0x06, 0x04, 0x97, 0x00, 0x00, 0x00, 0x17, 0x40, 0x10, +0x03, 0x02, 0x00, 0x20, 0x32, 0x09, 0x00, 0x50, 0x03, 0x0e, +0x33, 0x4f, 0x02, 0x0e, 0x31, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, +0x34, 0x00, 0xff, 0xff, 0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, +0x02, 0xbb, 0x02, 0x26, 0x00, 0x52, 0x00, 0x00, 0x01, 0x06, +0x04, 0xa4, 0x12, 0x00, 0x00, 0x17, 0x40, 0x10, 0x03, 0x02, +0x12, 0x22, 0x30, 0x09, 0x00, 0x50, 0x03, 0x0e, 0x31, 0x4f, +0x02, 0x0e, 0x20, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0xff, 0xff, 0xff, 0xa2, 0xff, 0xf3, 0x01, 0xd8, 0x02, 0x7a, +0x02, 0x26, 0x00, 0x32, 0x00, 0x00, 0x01, 0x07, 0x04, 0x87, +0xfe, 0xe9, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, 0x02, 0xfe, +0xe8, 0xb4, 0x20, 0x2b, 0x00, 0x09, 0x50, 0x2b, 0x34, 0x00, +0xff, 0xff, 0xff, 0x86, 0xff, 0xf3, 0x01, 0xd8, 0x02, 0x7a, +0x02, 0x26, 0x00, 0x32, 0x00, 0x00, 0x01, 0x07, 0x04, 0xc1, +0xfe, 0xcd, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, 0x02, 0xfe, +0xcc, 0xb4, 0x24, 0x30, 0x00, 0x09, 0x50, 0x2b, 0x34, 0x00, +0xff, 0xff, 0xfe, 0xd6, 0xff, 0xf3, 0x01, 0xd8, 0x02, 0x7c, +0x02, 0x26, 0x00, 0x32, 0x00, 0x00, 0x01, 0x07, 0x04, 0x96, +0xfe, 0x76, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, +0xfe, 0x76, 0xb4, 0x20, 0x33, 0x00, 0x09, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xe8, 0xff, 0xf3, +0x01, 0xd8, 0x02, 0x7c, 0x02, 0x26, 0x00, 0x32, 0x00, 0x00, +0x01, 0x07, 0x04, 0xa3, 0xfe, 0x7f, 0xff, 0xc1, 0x00, 0x0f, +0xb1, 0x03, 0x02, 0xb8, 0xfe, 0x7f, 0xb4, 0x22, 0x31, 0x00, +0x09, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0xff, 0x19, 0xff, 0xf3, 0x01, 0xd8, 0x02, 0x7c, 0x02, 0x26, +0x00, 0x32, 0x00, 0x00, 0x01, 0x07, 0x04, 0x97, 0xfe, 0xaf, +0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, 0xfe, 0xaf, +0xb4, 0x20, 0x32, 0x00, 0x09, 0x50, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0xff, 0x04, 0xff, 0xf3, 0x01, 0xd8, +0x02, 0x7c, 0x02, 0x26, 0x00, 0x32, 0x00, 0x00, 0x01, 0x07, +0x04, 0xa4, 0xfe, 0xa4, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x03, +0x02, 0xb8, 0xfe, 0xa4, 0xb4, 0x22, 0x30, 0x00, 0x09, 0x50, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x47, +0xff, 0xf6, 0x01, 0xab, 0x02, 0xb9, 0x02, 0x26, 0x03, 0xbd, +0x00, 0x00, 0x01, 0x06, 0x04, 0x87, 0x00, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x00, 0x16, 0x21, 0x04, 0x10, 0x50, 0x01, +0x06, 0x27, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x47, +0xff, 0xf6, 0x01, 0xab, 0x02, 0xb9, 0x02, 0x26, 0x03, 0xbd, +0x00, 0x00, 0x01, 0x06, 0x04, 0xc1, 0x09, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x09, 0x1a, 0x26, 0x04, 0x10, 0x50, 0x01, +0x06, 0x16, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x47, +0xff, 0xf6, 0x01, 0xab, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xbd, +0x00, 0x00, 0x01, 0x06, 0x04, 0x96, 0x00, 0x00, 0x00, 0x17, +0x40, 0x10, 0x02, 0x01, 0x01, 0x16, 0x29, 0x04, 0x10, 0x50, +0x02, 0x06, 0x2a, 0x4f, 0x01, 0x06, 0x27, 0x4f, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x47, 0xff, 0xf6, +0x01, 0xab, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xbd, 0x00, 0x00, +0x01, 0x06, 0x04, 0xa3, 0x00, 0x00, 0x00, 0x17, 0x40, 0x10, +0x02, 0x01, 0x01, 0x18, 0x27, 0x04, 0x10, 0x50, 0x02, 0x06, +0x28, 0x4f, 0x01, 0x06, 0x16, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, +0x34, 0x00, 0xff, 0xff, 0x00, 0x47, 0xff, 0xf6, 0x01, 0xab, +0x02, 0xbb, 0x02, 0x26, 0x03, 0xbd, 0x00, 0x00, 0x01, 0x06, +0x04, 0x97, 0x00, 0x00, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, +0x01, 0x16, 0x28, 0x04, 0x10, 0x50, 0x02, 0x06, 0x29, 0x4f, +0x01, 0x06, 0x27, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, +0xff, 0xff, 0x00, 0x47, 0xff, 0xf6, 0x01, 0xab, 0x02, 0xbb, +0x02, 0x26, 0x03, 0xbd, 0x00, 0x00, 0x01, 0x06, 0x04, 0xa4, +0x12, 0x00, 0x00, 0x17, 0x40, 0x10, 0x02, 0x01, 0x13, 0x18, +0x26, 0x04, 0x10, 0x50, 0x02, 0x06, 0x27, 0x4f, 0x01, 0x06, +0x16, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, +0x00, 0x47, 0xff, 0xf6, 0x01, 0xab, 0x03, 0x13, 0x02, 0x26, +0x03, 0xbd, 0x00, 0x00, 0x01, 0x06, 0x04, 0x98, 0x00, 0x00, +0x00, 0x17, 0x40, 0x10, 0x02, 0x01, 0x01, 0x35, 0x2b, 0x04, +0x10, 0x50, 0x02, 0x06, 0x2d, 0x4f, 0x01, 0x06, 0x26, 0x4f, +0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x47, +0xff, 0xf6, 0x01, 0xab, 0x03, 0x13, 0x02, 0x26, 0x03, 0xbd, +0x00, 0x00, 0x01, 0x06, 0x04, 0xa5, 0x00, 0x00, 0x00, 0x17, +0x40, 0x10, 0x02, 0x01, 0x01, 0x35, 0x2b, 0x04, 0x10, 0x50, +0x02, 0x06, 0x2d, 0x4f, 0x01, 0x06, 0x16, 0x4f, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0xff, 0x85, 0x00, 0x00, +0x01, 0xe8, 0x02, 0x7a, 0x02, 0x26, 0x00, 0x3c, 0x00, 0x00, +0x01, 0x07, 0x04, 0xc1, 0xfe, 0xcc, 0xff, 0xc1, 0x00, 0x0d, +0xb9, 0x00, 0x01, 0xfe, 0xcb, 0xb4, 0x15, 0x21, 0x04, 0x0c, +0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0xfe, 0xf3, 0x00, 0x00, +0x01, 0xe8, 0x02, 0x7c, 0x02, 0x26, 0x00, 0x3c, 0x00, 0x00, +0x01, 0x07, 0x04, 0xa3, 0xfe, 0x8a, 0xff, 0xc1, 0x00, 0x0f, +0xb1, 0x02, 0x01, 0xb8, 0xfe, 0x8a, 0xb4, 0x13, 0x22, 0x04, +0x0c, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0xfe, 0xc4, 0x00, 0x00, 0x01, 0xe8, 0x02, 0x7c, 0x02, 0x26, +0x00, 0x3c, 0x00, 0x00, 0x01, 0x07, 0x04, 0xa4, 0xfe, 0x64, +0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, 0xfe, 0x64, +0xb4, 0x13, 0x21, 0x04, 0x0c, 0x50, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0x01, 0xe8, +0x02, 0xb4, 0x02, 0x26, 0x00, 0x3c, 0x00, 0x00, 0x01, 0x07, +0x04, 0xa5, 0xfe, 0x7c, 0xff, 0xa1, 0x00, 0x0f, 0xb1, 0x02, +0x01, 0xb8, 0xfe, 0x7c, 0xb4, 0x30, 0x26, 0x04, 0x0c, 0x50, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x24, +0xff, 0xf7, 0x01, 0xd2, 0x02, 0xb9, 0x02, 0x26, 0x03, 0xc1, +0x00, 0x00, 0x01, 0x06, 0x04, 0x87, 0x00, 0x00, 0x00, 0x13, +0xb9, 0x00, 0x01, 0xff, 0xff, 0x40, 0x09, 0x35, 0x40, 0x0a, +0x2f, 0x50, 0x01, 0x10, 0x46, 0x4f, 0x2b, 0x2b, 0x34, 0x00, +0xff, 0xff, 0x00, 0x24, 0xff, 0xf7, 0x01, 0xd2, 0x02, 0xb9, +0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, 0x01, 0x06, 0x04, 0xc1, +0x09, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x07, 0x39, 0x45, +0x0a, 0x2f, 0x50, 0x01, 0x10, 0x35, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x24, 0xff, 0xf7, 0x01, 0xd2, 0x02, 0xbb, +0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, 0x01, 0x06, 0x04, 0x96, +0x00, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, 0xff, 0xff, +0x40, 0x0d, 0x35, 0x48, 0x0a, 0x2f, 0x50, 0x02, 0x10, 0x49, +0x4f, 0x01, 0x10, 0x46, 0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0xf7, 0x01, 0xd2, +0x02, 0xbb, 0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, 0x01, 0x06, +0x04, 0xa3, 0x00, 0x00, 0x00, 0x1a, 0xb1, 0x02, 0x01, 0xb8, +0xff, 0xff, 0x40, 0x0d, 0x37, 0x46, 0x0a, 0x2f, 0x50, 0x02, +0x10, 0x47, 0x4f, 0x01, 0x10, 0x35, 0x4f, 0x2b, 0x2b, 0x2b, +0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0xf7, +0x01, 0xd2, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, +0x01, 0x06, 0x04, 0x97, 0x00, 0x00, 0x00, 0x1a, 0xb1, 0x02, +0x01, 0xb8, 0xff, 0xff, 0x40, 0x0d, 0x35, 0x47, 0x0a, 0x2f, +0x50, 0x02, 0x10, 0x48, 0x4f, 0x01, 0x10, 0x46, 0x4f, 0x2b, +0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x24, +0xff, 0xf7, 0x01, 0xd2, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xc1, +0x00, 0x00, 0x01, 0x06, 0x04, 0xa4, 0x12, 0x00, 0x00, 0x17, +0x40, 0x10, 0x02, 0x01, 0x11, 0x37, 0x45, 0x0a, 0x2f, 0x50, +0x02, 0x10, 0x46, 0x4f, 0x01, 0x10, 0x35, 0x4f, 0x2b, 0x2b, +0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0xf7, +0x01, 0xd2, 0x03, 0x13, 0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, +0x01, 0x06, 0x04, 0x98, 0x00, 0x00, 0x00, 0x1a, 0xb1, 0x02, +0x01, 0xb8, 0xff, 0xff, 0x40, 0x0d, 0x54, 0x4a, 0x0a, 0x2f, +0x50, 0x02, 0x10, 0x4c, 0x4f, 0x01, 0x10, 0x45, 0x4f, 0x2b, +0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x24, +0xff, 0xf7, 0x01, 0xd2, 0x03, 0x13, 0x02, 0x26, 0x03, 0xc1, +0x00, 0x00, 0x01, 0x06, 0x04, 0xa5, 0x00, 0x00, 0x00, 0x1a, +0xb1, 0x02, 0x01, 0xb8, 0xff, 0xff, 0x40, 0x0d, 0x54, 0x4a, +0x0a, 0x2f, 0x50, 0x02, 0x10, 0x4c, 0x4f, 0x01, 0x10, 0x35, +0x4f, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, +0xff, 0x9f, 0x00, 0x00, 0x01, 0xe2, 0x02, 0x7a, 0x02, 0x26, +0x03, 0xa8, 0x00, 0x00, 0x01, 0x07, 0x04, 0x87, 0xfe, 0xe6, +0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, 0x01, 0xfe, 0xe6, 0xb4, +0x2c, 0x37, 0x00, 0x12, 0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, +0xff, 0x84, 0x00, 0x00, 0x01, 0xe2, 0x02, 0x7a, 0x02, 0x26, +0x03, 0xa8, 0x00, 0x00, 0x01, 0x07, 0x04, 0xc1, 0xfe, 0xcb, +0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, 0x01, 0xfe, 0xcb, 0xb4, +0x30, 0x3c, 0x00, 0x12, 0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, +0xfe, 0xd5, 0x00, 0x00, 0x01, 0xe2, 0x02, 0x7c, 0x02, 0x26, +0x03, 0xa8, 0x00, 0x00, 0x01, 0x07, 0x04, 0x96, 0xfe, 0x75, +0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, 0xfe, 0x75, +0xb4, 0x2c, 0x3f, 0x00, 0x12, 0x50, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0xfe, 0xe7, 0x00, 0x00, 0x01, 0xe2, +0x02, 0x7c, 0x02, 0x26, 0x03, 0xa8, 0x00, 0x00, 0x01, 0x07, +0x04, 0xa3, 0xfe, 0x7e, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x02, +0x01, 0xb8, 0xfe, 0x7e, 0xb4, 0x2e, 0x3d, 0x00, 0x12, 0x50, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x17, +0x00, 0x00, 0x01, 0xe2, 0x02, 0x7c, 0x02, 0x26, 0x03, 0xa8, +0x00, 0x00, 0x01, 0x07, 0x04, 0x97, 0xfe, 0xad, 0xff, 0xc1, +0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, 0xfe, 0xad, 0xb4, 0x2c, +0x3e, 0x00, 0x12, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x01, 0xe2, 0x02, 0x7c, +0x02, 0x26, 0x03, 0xa8, 0x00, 0x00, 0x01, 0x07, 0x04, 0xa4, +0xfe, 0xa2, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, +0xfe, 0xa2, 0xb4, 0x2e, 0x3c, 0x00, 0x12, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x56, 0x00, 0x00, +0x01, 0xe2, 0x02, 0xb4, 0x02, 0x26, 0x03, 0xa8, 0x00, 0x00, +0x01, 0x07, 0x04, 0x98, 0xfe, 0xd3, 0xff, 0xa1, 0x00, 0x0f, +0xb1, 0x02, 0x01, 0xb8, 0xfe, 0xd3, 0xb4, 0x4b, 0x41, 0x00, +0x12, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0xff, 0x3c, 0x00, 0x00, 0x01, 0xe2, 0x02, 0xb4, 0x02, 0x26, +0x03, 0xa8, 0x00, 0x00, 0x01, 0x07, 0x04, 0xa5, 0xfe, 0xb9, +0xff, 0xa1, 0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, 0xfe, 0xb9, +0xb4, 0x4b, 0x41, 0x00, 0x12, 0x50, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0x00, 0x31, 0xff, 0xf6, 0x01, 0xd7, +0x02, 0xb5, 0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, 0x01, 0x06, +0x04, 0xb5, 0x04, 0x00, 0x00, 0x13, 0xb9, 0x00, 0x02, 0xff, +0xfa, 0x40, 0x09, 0x2f, 0x2d, 0x14, 0x09, 0x50, 0x02, 0x00, +0x2e, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, 0x00, 0x31, +0xff, 0xf6, 0x01, 0xd7, 0x02, 0xb5, 0x02, 0x26, 0x03, 0xa9, +0x00, 0x00, 0x01, 0x06, 0x04, 0xc0, 0x1e, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x02, 0x13, 0x2e, 0x2c, 0x14, 0x09, 0x50, 0x02, +0x00, 0x2d, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x45, +0xff, 0xf5, 0x01, 0xd2, 0x02, 0xb5, 0x02, 0x26, 0x03, 0xad, +0x00, 0x00, 0x01, 0x06, 0x04, 0xb5, 0x04, 0x00, 0x00, 0x13, +0xb9, 0x00, 0x01, 0xff, 0xf2, 0x40, 0x09, 0x39, 0x37, 0x2a, +0x23, 0x50, 0x01, 0x00, 0x38, 0x4f, 0x2b, 0x2b, 0x34, 0x00, +0xff, 0xff, 0x00, 0x45, 0xff, 0xf5, 0x01, 0xd2, 0x02, 0xb5, +0x02, 0x26, 0x03, 0xad, 0x00, 0x00, 0x01, 0x06, 0x04, 0xc0, +0x1e, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x0c, 0x38, 0x36, +0x2a, 0x23, 0x50, 0x01, 0x00, 0x37, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x47, 0xff, 0x5b, 0x01, 0xb0, 0x02, 0xb5, +0x02, 0x26, 0x03, 0xaf, 0x00, 0x00, 0x01, 0x06, 0x04, 0xb5, +0x04, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x02, 0x17, 0x15, +0x00, 0x05, 0x50, 0x01, 0x02, 0x16, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x47, 0xff, 0x5b, 0x01, 0xb0, 0x02, 0xb5, +0x02, 0x26, 0x03, 0xaf, 0x00, 0x00, 0x01, 0x06, 0x04, 0xc0, +0x1e, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x1c, 0x16, 0x14, +0x00, 0x05, 0x50, 0x01, 0x02, 0x15, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0xb5, +0x02, 0x26, 0x03, 0xb1, 0x00, 0x00, 0x01, 0x06, 0x04, 0xb5, +0xe6, 0x00, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xe4, 0x40, +0x09, 0x19, 0x17, 0x0a, 0x00, 0x50, 0x01, 0x0b, 0x18, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, +0x01, 0xc2, 0x02, 0xb5, 0x02, 0x26, 0x03, 0xb1, 0x00, 0x00, +0x01, 0x06, 0x04, 0xc0, 0xf8, 0x00, 0x00, 0x13, 0xb9, 0x00, +0x01, 0xff, 0xf6, 0x40, 0x09, 0x18, 0x16, 0x0a, 0x00, 0x50, +0x01, 0x0b, 0x17, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0xb5, 0x02, 0x26, +0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x04, 0xb5, 0x04, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x02, 0x03, 0x23, 0x21, 0x09, 0x00, +0x50, 0x02, 0x0e, 0x22, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x28, 0xff, 0xf5, 0x01, 0xcc, 0x02, 0xb5, 0x02, 0x26, +0x00, 0x52, 0x00, 0x00, 0x01, 0x06, 0x04, 0xc0, 0x1e, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x02, 0x1d, 0x22, 0x20, 0x09, 0x00, +0x50, 0x02, 0x0e, 0x21, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x47, 0xff, 0xf6, 0x01, 0xab, 0x02, 0xb5, 0x02, 0x26, +0x03, 0xbd, 0x00, 0x00, 0x01, 0x06, 0x04, 0xb5, 0x04, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x04, 0x19, 0x17, 0x04, 0x10, +0x50, 0x01, 0x06, 0x18, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x47, 0xff, 0xf6, 0x01, 0xab, 0x02, 0xb5, 0x02, 0x26, +0x03, 0xbd, 0x00, 0x00, 0x01, 0x06, 0x04, 0xc0, 0x1e, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x1e, 0x18, 0x16, 0x04, 0x10, +0x50, 0x01, 0x06, 0x17, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x24, 0xff, 0xf7, 0x01, 0xd2, 0x02, 0xb5, 0x02, 0x26, +0x03, 0xc1, 0x00, 0x00, 0x01, 0x06, 0x04, 0xb5, 0x04, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x02, 0x38, 0x36, 0x0a, 0x2f, +0x50, 0x01, 0x10, 0x37, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x24, 0xff, 0xf7, 0x01, 0xd2, 0x02, 0xb5, 0x02, 0x26, +0x03, 0xc1, 0x00, 0x00, 0x01, 0x06, 0x04, 0xc0, 0x1e, 0x00, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x1c, 0x37, 0x35, 0x0a, 0x2f, +0x50, 0x01, 0x10, 0x36, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, +0x00, 0x31, 0xff, 0x56, 0x01, 0xd7, 0x02, 0xb9, 0x02, 0x26, +0x03, 0xa9, 0x00, 0x00, 0x00, 0x26, 0x04, 0x87, 0x00, 0x00, +0x01, 0x06, 0x04, 0x88, 0x12, 0x00, 0x00, 0x0c, 0xb7, 0x03, +0x02, 0x05, 0x2c, 0x42, 0x14, 0x09, 0x50, 0x2b, 0x34, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x31, 0xff, 0x56, 0x01, 0xd7, +0x02, 0xb9, 0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, 0x00, 0x26, +0x04, 0xc1, 0x09, 0x00, 0x01, 0x06, 0x04, 0x88, 0x12, 0x00, +0x00, 0x0c, 0xb7, 0x03, 0x02, 0x0a, 0x30, 0x41, 0x14, 0x09, +0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x31, +0xff, 0x56, 0x01, 0xd7, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xa9, +0x00, 0x00, 0x00, 0x26, 0x04, 0x96, 0x00, 0x00, 0x01, 0x06, +0x04, 0x88, 0x12, 0x00, 0x00, 0x11, 0xb2, 0x04, 0x03, 0x02, +0xb8, 0xff, 0xf6, 0xb4, 0x2c, 0x3f, 0x14, 0x09, 0x50, 0x2b, +0x34, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x31, 0xff, 0x56, +0x01, 0xd7, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, +0x00, 0x26, 0x04, 0xa3, 0x00, 0x00, 0x01, 0x06, 0x04, 0x88, +0x12, 0x00, 0x00, 0x11, 0xb2, 0x04, 0x03, 0x02, 0xb8, 0xff, +0xf6, 0xb4, 0x2e, 0x3d, 0x14, 0x09, 0x50, 0x2b, 0x34, 0x34, +0x34, 0x00, 0xff, 0xff, 0x00, 0x31, 0xff, 0x56, 0x01, 0xd7, +0x02, 0xbb, 0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, 0x00, 0x26, +0x04, 0x97, 0x24, 0x00, 0x01, 0x06, 0x04, 0x88, 0x12, 0x00, +0x00, 0x0f, 0x40, 0x09, 0x04, 0x03, 0x02, 0x1a, 0x2c, 0x3e, +0x14, 0x09, 0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x31, 0xff, 0x56, 0x01, 0xd7, 0x02, 0xbb, +0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, 0x00, 0x26, 0x04, 0xa4, +0x12, 0x00, 0x01, 0x06, 0x04, 0x88, 0x12, 0x00, 0x00, 0x0f, +0x40, 0x09, 0x04, 0x03, 0x02, 0x08, 0x2e, 0x3c, 0x14, 0x09, +0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x31, 0xff, 0x56, 0x01, 0xd7, 0x03, 0x13, 0x02, 0x26, +0x03, 0xa9, 0x00, 0x00, 0x00, 0x26, 0x04, 0x98, 0x12, 0x00, +0x01, 0x06, 0x04, 0x88, 0x12, 0x00, 0x00, 0x0f, 0x40, 0x09, +0x04, 0x03, 0x02, 0x08, 0x4b, 0x41, 0x14, 0x09, 0x50, 0x2b, +0x34, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x31, +0xff, 0x56, 0x01, 0xd7, 0x03, 0x13, 0x02, 0x26, 0x03, 0xa9, +0x00, 0x00, 0x00, 0x26, 0x04, 0xa5, 0x00, 0x00, 0x01, 0x06, +0x04, 0x88, 0x12, 0x00, 0x00, 0x11, 0xb2, 0x04, 0x03, 0x02, +0xb8, 0xff, 0xf6, 0xb4, 0x4b, 0x41, 0x14, 0x09, 0x50, 0x2b, +0x34, 0x34, 0x34, 0x00, 0xff, 0xff, 0xff, 0xb9, 0xff, 0xf7, +0x01, 0xf4, 0x02, 0x7a, 0x02, 0x26, 0x04, 0x86, 0x00, 0x00, +0x01, 0x07, 0x04, 0x87, 0xff, 0x00, 0xff, 0xc1, 0x00, 0x0d, +0xb9, 0x00, 0x03, 0xfe, 0xfb, 0xb4, 0x29, 0x34, 0x03, 0x1d, +0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xf7, +0x01, 0xf4, 0x02, 0x7a, 0x02, 0x26, 0x04, 0x86, 0x00, 0x00, +0x01, 0x07, 0x04, 0xc1, 0xfe, 0xef, 0xff, 0xc1, 0x00, 0x0d, +0xb9, 0x00, 0x03, 0xfe, 0xea, 0xb4, 0x2d, 0x39, 0x03, 0x1d, +0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0xfe, 0xf8, 0xff, 0xf7, +0x01, 0xf4, 0x02, 0x7c, 0x02, 0x26, 0x04, 0x86, 0x00, 0x00, +0x01, 0x07, 0x04, 0x96, 0xfe, 0x98, 0xff, 0xc1, 0x00, 0x0f, +0xb1, 0x04, 0x03, 0xb8, 0xfe, 0x94, 0xb4, 0x29, 0x3c, 0x03, +0x1d, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0xff, 0x0b, 0xff, 0xf7, 0x01, 0xf4, 0x02, 0x7c, 0x02, 0x26, +0x04, 0x86, 0x00, 0x00, 0x01, 0x07, 0x04, 0xa3, 0xfe, 0xa2, +0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x04, 0x03, 0xb8, 0xfe, 0x9e, +0xb4, 0x2b, 0x3a, 0x03, 0x1d, 0x50, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0xff, 0x2b, 0xff, 0xf7, 0x01, 0xf4, +0x02, 0x7c, 0x02, 0x26, 0x04, 0x86, 0x00, 0x00, 0x01, 0x07, +0x04, 0x97, 0xfe, 0xc1, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x04, +0x03, 0xb8, 0xfe, 0xbd, 0xb4, 0x29, 0x3b, 0x03, 0x1d, 0x50, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x16, +0xff, 0xf7, 0x01, 0xf4, 0x02, 0x7c, 0x02, 0x26, 0x04, 0x86, +0x00, 0x00, 0x01, 0x07, 0x04, 0xa4, 0xfe, 0xb6, 0xff, 0xc1, +0x00, 0x0f, 0xb1, 0x04, 0x03, 0xb8, 0xfe, 0xb2, 0xb4, 0x2b, +0x39, 0x03, 0x1d, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0x60, 0xff, 0xf7, 0x01, 0xf4, 0x02, 0xb4, +0x02, 0x26, 0x04, 0x86, 0x00, 0x00, 0x01, 0x07, 0x04, 0x98, +0xfe, 0xdd, 0xff, 0xa1, 0x00, 0x0f, 0xb1, 0x04, 0x03, 0xb8, +0xfe, 0xd9, 0xb4, 0x48, 0x3e, 0x03, 0x1d, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x57, 0xff, 0xf7, +0x01, 0xf4, 0x02, 0xb4, 0x02, 0x26, 0x04, 0x86, 0x00, 0x00, +0x01, 0x07, 0x04, 0xa5, 0xfe, 0xd4, 0xff, 0xa1, 0x00, 0x0f, +0xb1, 0x04, 0x03, 0xb8, 0xfe, 0xd0, 0xb4, 0x48, 0x3e, 0x03, +0x1d, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x47, 0xff, 0x56, 0x01, 0xb0, 0x02, 0xb9, 0x02, 0x26, +0x03, 0xaf, 0x00, 0x00, 0x00, 0x26, 0x04, 0x87, 0x00, 0x00, +0x01, 0x06, 0x04, 0x88, 0x95, 0x00, 0x00, 0x0f, 0xb1, 0x02, +0x01, 0xb8, 0xff, 0xc6, 0xb4, 0x2f, 0x1f, 0x00, 0x05, 0x50, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x47, +0xff, 0x56, 0x01, 0xb0, 0x02, 0xb9, 0x02, 0x26, 0x03, 0xaf, +0x00, 0x00, 0x00, 0x26, 0x04, 0xc1, 0x09, 0x00, 0x01, 0x06, +0x04, 0x88, 0x95, 0x00, 0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, +0xff, 0xca, 0xb4, 0x2e, 0x24, 0x00, 0x05, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x47, 0xff, 0x56, +0x01, 0xb0, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xaf, 0x00, 0x00, +0x00, 0x26, 0x04, 0x96, 0x00, 0x00, 0x01, 0x06, 0x04, 0x88, +0x95, 0x00, 0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, +0xf3, 0xb4, 0x33, 0x27, 0x00, 0x05, 0x50, 0x2b, 0x34, 0x34, +0x34, 0x00, 0xff, 0xff, 0x00, 0x47, 0xff, 0x56, 0x01, 0xb0, +0x02, 0xbb, 0x02, 0x26, 0x03, 0xaf, 0x00, 0x00, 0x00, 0x26, +0x04, 0xa3, 0x00, 0x00, 0x01, 0x06, 0x04, 0x88, 0x95, 0x00, +0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, 0xee, 0xb4, +0x31, 0x25, 0x00, 0x05, 0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, +0xff, 0xff, 0x00, 0x47, 0xff, 0x56, 0x01, 0xb0, 0x02, 0xbb, +0x02, 0x26, 0x03, 0xaf, 0x00, 0x00, 0x00, 0x26, 0x04, 0x97, +0x00, 0x00, 0x01, 0x06, 0x04, 0x88, 0x95, 0x00, 0x00, 0x11, +0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, 0xee, 0xb4, 0x33, 0x26, +0x00, 0x05, 0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0xff, 0xff, +0x00, 0x47, 0xff, 0x56, 0x01, 0xb0, 0x02, 0xbb, 0x02, 0x26, +0x03, 0xaf, 0x00, 0x00, 0x00, 0x26, 0x04, 0xa4, 0x12, 0x00, +0x01, 0x06, 0x04, 0x88, 0x95, 0x00, 0x00, 0x11, 0xb2, 0x03, +0x02, 0x01, 0xb8, 0xff, 0xfc, 0xb4, 0x31, 0x24, 0x00, 0x05, +0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x47, +0xff, 0x56, 0x01, 0xb0, 0x03, 0x13, 0x02, 0x26, 0x03, 0xaf, +0x00, 0x00, 0x00, 0x26, 0x04, 0x98, 0x00, 0x00, 0x01, 0x06, +0x04, 0x88, 0x95, 0x00, 0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, +0xb8, 0xff, 0xe1, 0xb4, 0x42, 0x29, 0x00, 0x05, 0x50, 0x2b, +0x34, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x47, 0xff, 0x56, +0x01, 0xb0, 0x03, 0x13, 0x02, 0x26, 0x03, 0xaf, 0x00, 0x00, +0x00, 0x26, 0x04, 0xa5, 0x00, 0x00, 0x01, 0x06, 0x04, 0x88, +0x95, 0x00, 0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, +0xe1, 0xb4, 0x42, 0x29, 0x00, 0x05, 0x50, 0x2b, 0x34, 0x34, +0x34, 0x00, 0xff, 0xff, 0xff, 0x83, 0xff, 0xf7, 0x01, 0xf4, +0x02, 0x7a, 0x02, 0x37, 0x04, 0x87, 0xfe, 0xca, 0xff, 0xc1, +0x00, 0x06, 0x04, 0x95, 0x00, 0x00, 0xff, 0xff, 0xff, 0x83, +0xff, 0xf7, 0x01, 0xf4, 0x02, 0x7a, 0x02, 0x37, 0x04, 0xc1, +0xfe, 0xca, 0xff, 0xc1, 0x00, 0x06, 0x04, 0x95, 0x00, 0x00, +0xff, 0xff, 0xfe, 0xd9, 0xff, 0xf7, 0x01, 0xf4, 0x02, 0x7c, +0x02, 0x26, 0x04, 0x95, 0x00, 0x00, 0x01, 0x07, 0x04, 0x96, +0xfe, 0x79, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, +0xfe, 0x63, 0xb4, 0x1a, 0x2d, 0x15, 0x0d, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xea, 0xff, 0xf7, +0x01, 0xf4, 0x02, 0x7c, 0x02, 0x26, 0x04, 0x95, 0x00, 0x00, +0x01, 0x07, 0x04, 0xa3, 0xfe, 0x81, 0xff, 0xc1, 0x00, 0x0f, +0xb1, 0x03, 0x02, 0xb8, 0xfe, 0x6b, 0xb4, 0x1c, 0x2b, 0x15, +0x0d, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0xfe, 0xec, 0xff, 0xf7, 0x01, 0xf4, 0x02, 0x7c, 0x02, 0x26, +0x04, 0x95, 0x00, 0x00, 0x01, 0x07, 0x04, 0x97, 0xfe, 0x82, +0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, 0xfe, 0x6c, +0xb4, 0x1a, 0x2c, 0x15, 0x0d, 0x50, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0xfe, 0xd9, 0xff, 0xf7, 0x01, 0xf4, +0x02, 0x7c, 0x02, 0x26, 0x04, 0x95, 0x00, 0x00, 0x01, 0x07, +0x04, 0xa4, 0xfe, 0x79, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x03, +0x02, 0xb8, 0xfe, 0x63, 0xb4, 0x1c, 0x2a, 0x15, 0x0d, 0x50, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1a, +0xff, 0xf7, 0x01, 0xf4, 0x02, 0xb4, 0x02, 0x26, 0x04, 0x95, +0x00, 0x00, 0x01, 0x07, 0x04, 0x98, 0xfe, 0x97, 0xff, 0xa1, +0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, 0xfe, 0x81, 0xb4, 0x39, +0x2f, 0x15, 0x0d, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0x1a, 0xff, 0xf7, 0x01, 0xf4, 0x02, 0xb4, +0x02, 0x26, 0x04, 0x95, 0x00, 0x00, 0x01, 0x07, 0x04, 0xa5, +0xfe, 0x97, 0xff, 0xa1, 0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, +0xfe, 0x81, 0xb4, 0x39, 0x2f, 0x15, 0x0d, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0x56, +0x01, 0xd2, 0x02, 0xb9, 0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, +0x00, 0x26, 0x04, 0x87, 0x00, 0x00, 0x01, 0x06, 0x04, 0x88, +0x1b, 0x00, 0x00, 0x0c, 0xb7, 0x02, 0x01, 0x13, 0x35, 0x4b, +0x0a, 0x2f, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x24, 0xff, 0x56, 0x01, 0xd2, 0x02, 0xb9, 0x02, 0x26, +0x03, 0xc1, 0x00, 0x00, 0x00, 0x26, 0x04, 0xc1, 0x09, 0x00, +0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, 0x00, 0x0c, 0xb7, 0x02, +0x01, 0x17, 0x39, 0x4a, 0x0a, 0x2f, 0x50, 0x2b, 0x34, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0x56, 0x01, 0xd2, +0x02, 0xbb, 0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, 0x00, 0x26, +0x04, 0x96, 0x00, 0x00, 0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, +0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, 0xff, 0xb4, +0x35, 0x48, 0x0a, 0x2f, 0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, +0xff, 0xff, 0x00, 0x24, 0xff, 0x56, 0x01, 0xd2, 0x02, 0xbb, +0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, 0x00, 0x26, 0x04, 0xa3, +0x00, 0x00, 0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, 0x00, 0x11, +0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, 0xff, 0xb4, 0x37, 0x46, +0x0a, 0x2f, 0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0xff, 0xff, +0x00, 0x24, 0xff, 0x56, 0x01, 0xd2, 0x02, 0xbb, 0x02, 0x26, +0x03, 0xc1, 0x00, 0x00, 0x00, 0x26, 0x04, 0x97, 0x00, 0x00, +0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, 0x00, 0x11, 0xb2, 0x03, +0x02, 0x01, 0xb8, 0xff, 0xff, 0xb4, 0x35, 0x47, 0x0a, 0x2f, +0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0xff, 0xff, 0x00, 0x24, +0xff, 0x56, 0x01, 0xd2, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xc1, +0x00, 0x00, 0x00, 0x26, 0x04, 0xa4, 0x12, 0x00, 0x01, 0x06, +0x04, 0x88, 0x1b, 0x00, 0x00, 0x0f, 0x40, 0x09, 0x03, 0x02, +0x01, 0x11, 0x37, 0x45, 0x0a, 0x2f, 0x50, 0x2b, 0x34, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0x56, +0x01, 0xd2, 0x03, 0x13, 0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, +0x00, 0x26, 0x04, 0x98, 0x00, 0x00, 0x01, 0x06, 0x04, 0x88, +0x1b, 0x00, 0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, +0xff, 0xb4, 0x54, 0x4a, 0x0a, 0x2f, 0x50, 0x2b, 0x34, 0x34, +0x34, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0x56, 0x01, 0xd2, +0x03, 0x13, 0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, 0x00, 0x26, +0x04, 0xa5, 0x00, 0x00, 0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, +0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, 0xff, 0xb4, +0x54, 0x4a, 0x0a, 0x2f, 0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, +0xff, 0xff, 0xff, 0x96, 0xff, 0xf7, 0x01, 0xf4, 0x02, 0x7a, +0x02, 0x26, 0x04, 0xbf, 0x00, 0x00, 0x01, 0x07, 0x04, 0x87, +0xfe, 0xdd, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, 0x02, 0xfe, +0xd4, 0xb4, 0x3e, 0x49, 0x01, 0x3d, 0x50, 0x2b, 0x34, 0x00, +0xff, 0xff, 0xff, 0x7b, 0xff, 0xf7, 0x01, 0xf4, 0x02, 0x7a, +0x02, 0x26, 0x04, 0xbf, 0x00, 0x00, 0x01, 0x07, 0x04, 0xc1, +0xfe, 0xc2, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, 0x02, 0xfe, +0xb9, 0xb4, 0x42, 0x4e, 0x01, 0x3d, 0x50, 0x2b, 0x34, 0x00, +0xff, 0xff, 0xfe, 0xcc, 0xff, 0xf7, 0x01, 0xf4, 0x02, 0x7c, +0x02, 0x26, 0x04, 0xbf, 0x00, 0x00, 0x01, 0x07, 0x04, 0x96, +0xfe, 0x6c, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, +0xfe, 0x63, 0xb4, 0x3e, 0x51, 0x01, 0x3d, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xde, 0xff, 0xf7, +0x01, 0xf4, 0x02, 0x7c, 0x02, 0x26, 0x04, 0xbf, 0x00, 0x00, +0x01, 0x07, 0x04, 0xa3, 0xfe, 0x75, 0xff, 0xc1, 0x00, 0x0f, +0xb1, 0x03, 0x02, 0xb8, 0xfe, 0x6c, 0xb4, 0x40, 0x4f, 0x01, +0x3d, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0xff, 0x0e, 0xff, 0xf7, 0x01, 0xf4, 0x02, 0x7c, 0x02, 0x26, +0x04, 0xbf, 0x00, 0x00, 0x01, 0x07, 0x04, 0x97, 0xfe, 0xa4, +0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, 0xfe, 0x9b, +0xb4, 0x3e, 0x50, 0x01, 0x3d, 0x50, 0x2b, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0xfe, 0xf9, 0xff, 0xf7, 0x01, 0xf4, +0x02, 0x7c, 0x02, 0x26, 0x04, 0xbf, 0x00, 0x00, 0x01, 0x07, +0x04, 0xa4, 0xfe, 0x99, 0xff, 0xc1, 0x00, 0x0f, 0xb1, 0x03, +0x02, 0xb8, 0xfe, 0x90, 0xb4, 0x40, 0x4e, 0x01, 0x3d, 0x50, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x44, +0xff, 0xf7, 0x01, 0xf4, 0x02, 0xb4, 0x02, 0x26, 0x04, 0xbf, +0x00, 0x00, 0x01, 0x07, 0x04, 0x98, 0xfe, 0xc1, 0xff, 0xa1, +0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, 0xfe, 0xb8, 0xb4, 0x5d, +0x53, 0x01, 0x3d, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0x2a, 0xff, 0xf7, 0x01, 0xf4, 0x02, 0xb4, +0x02, 0x26, 0x04, 0xbf, 0x00, 0x00, 0x01, 0x07, 0x04, 0xa5, +0xfe, 0xa7, 0xff, 0xa1, 0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, +0xfe, 0x9e, 0xb4, 0x5d, 0x53, 0x01, 0x3d, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x31, 0xff, 0xf6, +0x01, 0xd7, 0x02, 0x9d, 0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, +0x01, 0x06, 0x01, 0x61, 0x00, 0x00, 0x00, 0x13, 0xb9, 0x00, +0x02, 0xff, 0xf6, 0x40, 0x09, 0x30, 0x3e, 0x14, 0x09, 0x50, +0x02, 0x00, 0x2c, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, +0x00, 0x31, 0xff, 0xf6, 0x01, 0xd7, 0x02, 0x7b, 0x02, 0x26, +0x03, 0xa9, 0x00, 0x00, 0x01, 0x06, 0x00, 0x8a, 0x00, 0x00, +0x00, 0x13, 0xb9, 0x00, 0x02, 0xff, 0xf6, 0x40, 0x09, 0x2c, +0x2d, 0x14, 0x09, 0x50, 0x02, 0x00, 0x2e, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0xff, 0xff, 0x00, 0x31, 0xff, 0x56, 0x01, 0xd7, +0x02, 0xb5, 0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, 0x00, 0x26, +0x04, 0xb5, 0x04, 0x00, 0x01, 0x06, 0x04, 0x88, 0x12, 0x00, +0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, 0xff, 0xfa, 0xb4, 0x2f, +0x2d, 0x14, 0x09, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x31, 0xff, 0x56, 0x01, 0xd7, 0x01, 0xda, +0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, 0x01, 0x06, 0x04, 0x88, +0x12, 0x00, 0x00, 0x0a, 0xb6, 0x02, 0x0b, 0x35, 0x30, 0x14, +0x09, 0x50, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x31, +0xff, 0x56, 0x01, 0xd7, 0x02, 0xb5, 0x02, 0x26, 0x03, 0xa9, +0x00, 0x00, 0x00, 0x26, 0x04, 0xc0, 0x1e, 0x00, 0x01, 0x06, +0x04, 0x88, 0x12, 0x00, 0x00, 0x0c, 0xb7, 0x03, 0x02, 0x13, +0x2e, 0x2c, 0x14, 0x09, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, +0xff, 0xff, 0x00, 0x31, 0xff, 0xf6, 0x01, 0xd7, 0x02, 0x9d, +0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, 0x01, 0x06, 0x04, 0x8a, +0x12, 0x00, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x08, 0x3e, 0x30, +0x14, 0x09, 0x50, 0x02, 0x00, 0x31, 0x4f, 0x2b, 0x2b, 0x34, +0xff, 0xff, 0x00, 0x31, 0xff, 0x56, 0x01, 0xd7, 0x02, 0x9d, +0x02, 0x26, 0x03, 0xa9, 0x00, 0x00, 0x00, 0x26, 0x04, 0x8a, +0x12, 0x00, 0x01, 0x06, 0x04, 0x88, 0x12, 0x00, 0x00, 0x0c, +0xb7, 0x03, 0x02, 0x08, 0x3e, 0x30, 0x14, 0x09, 0x50, 0x2b, +0x34, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x00, +0x01, 0xeb, 0x03, 0x28, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, +0x01, 0x07, 0x01, 0x61, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x02, 0x00, 0x1b, 0x29, 0x04, 0x0f, 0x50, 0x02, +0x09, 0x17, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x09, 0x00, 0x00, 0x01, 0xeb, 0x03, 0x06, 0x02, 0x26, +0x00, 0x24, 0x00, 0x00, 0x01, 0x07, 0x00, 0x8a, 0x00, 0x00, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x02, 0x00, 0x17, 0x18, +0x04, 0x0f, 0x50, 0x02, 0x09, 0x19, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0xff, 0xbf, 0x00, 0x00, 0x01, 0xeb, +0x02, 0x76, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x01, 0x07, +0x00, 0x43, 0xff, 0x1c, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, +0x02, 0xff, 0x19, 0xb4, 0x1a, 0x18, 0x04, 0x0f, 0x50, 0x2b, +0x34, 0x00, 0xff, 0xff, 0xff, 0xe2, 0x00, 0x00, 0x01, 0xeb, +0x02, 0x76, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x01, 0x07, +0x00, 0x8f, 0xff, 0x38, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, +0x02, 0xff, 0x3c, 0xb4, 0x19, 0x17, 0x04, 0x0f, 0x50, 0x2b, +0x34, 0x00, 0x00, 0x03, 0x00, 0x09, 0xff, 0xf7, 0x01, 0xf4, +0x02, 0x6b, 0x00, 0x0f, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x88, +0x40, 0x4b, 0x00, 0x24, 0x26, 0x27, 0x28, 0x1e, 0x09, 0x0f, +0x1e, 0x0f, 0x78, 0x0e, 0x09, 0x14, 0x0e, 0x0e, 0x09, 0x01, +0x21, 0x20, 0x1f, 0x1e, 0x08, 0x02, 0x1e, 0x02, 0x78, 0x03, +0x08, 0x14, 0x03, 0x03, 0x08, 0x1e, 0x03, 0xaf, 0x0e, 0xbf, +0x0e, 0x02, 0x39, 0x0e, 0x01, 0x0e, 0x0e, 0x15, 0x73, 0x18, +0x18, 0x1d, 0x03, 0x16, 0x49, 0x1d, 0x7c, 0x10, 0x46, 0x0f, +0x0e, 0x44, 0x09, 0x41, 0x00, 0x01, 0x79, 0x24, 0x23, 0x23, +0x03, 0x1e, 0x08, 0x41, 0x02, 0x03, 0x44, 0x00, 0x3f, 0x33, +0x3f, 0x33, 0x12, 0x39, 0x2f, 0x33, 0xed, 0x32, 0x3f, 0x3f, +0x33, 0x3f, 0xed, 0x3f, 0x01, 0x2f, 0x2f, 0x32, 0x2f, 0xed, +0x32, 0x2f, 0x5d, 0x5d, 0x12, 0x39, 0x87, 0x10, 0x2b, 0x87, +0x7d, 0xc4, 0x10, 0x0e, 0xc4, 0xc4, 0xc4, 0x05, 0xc4, 0x87, +0x18, 0x10, 0x2b, 0x87, 0x7d, 0xc4, 0x10, 0x0e, 0xc4, 0xc4, +0xc4, 0x05, 0xc4, 0xc4, 0x31, 0x30, 0x37, 0x23, 0x07, 0x23, +0x3e, 0x03, 0x37, 0x33, 0x1e, 0x03, 0x17, 0x23, 0x17, 0x2e, +0x03, 0x35, 0x11, 0x33, 0x11, 0x14, 0x1e, 0x02, 0x17, 0x01, +0x0e, 0x03, 0x07, 0x33, 0x2e, 0x03, 0xee, 0x84, 0x16, 0x4b, +0x0b, 0x19, 0x1c, 0x21, 0x12, 0x66, 0x12, 0x20, 0x1c, 0x18, +0x0b, 0x4e, 0xe4, 0x23, 0x2d, 0x19, 0x09, 0x49, 0x04, 0x0c, +0x14, 0x10, 0xfe, 0xb8, 0x05, 0x0b, 0x0d, 0x11, 0x0a, 0x70, +0x0a, 0x11, 0x0d, 0x0c, 0xa2, 0xa2, 0x42, 0x9a, 0xa2, 0xa3, +0x4a, 0x4a, 0xa3, 0xa2, 0x9a, 0x42, 0x09, 0x03, 0x14, 0x21, +0x2e, 0x1e, 0x01, 0x55, 0xfe, 0xb9, 0x13, 0x19, 0x12, 0x0a, +0x04, 0x01, 0xe6, 0x17, 0x37, 0x4b, 0x62, 0x42, 0x43, 0x63, +0x4a, 0x37, 0x00, 0x01, 0x00, 0xb9, 0x02, 0x01, 0x01, 0x3a, +0x02, 0xb9, 0x00, 0x11, 0x00, 0x18, 0x40, 0x09, 0x03, 0x0c, +0x11, 0x00, 0x06, 0x09, 0x03, 0x00, 0x11, 0x00, 0x2f, 0x33, +0xdd, 0xcd, 0x01, 0x2f, 0xce, 0x32, 0xcd, 0x32, 0x31, 0x30, +0x13, 0x36, 0x36, 0x37, 0x26, 0x26, 0x35, 0x34, 0x36, 0x33, +0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, 0x07, 0xb9, 0x12, 0x1c, +0x0a, 0x0f, 0x13, 0x1e, 0x16, 0x17, 0x20, 0x10, 0x1a, 0x24, +0x13, 0x02, 0x20, 0x0f, 0x1c, 0x11, 0x06, 0x18, 0x0f, 0x15, +0x1b, 0x1c, 0x1b, 0x0f, 0x22, 0x23, 0x20, 0x0d, 0x00, 0x00, +0x00, 0x01, 0x00, 0xb3, 0xff, 0x56, 0x01, 0x48, 0xff, 0xd3, +0x00, 0x0e, 0x00, 0x13, 0xb6, 0x05, 0x00, 0x0a, 0x07, 0x03, +0x0e, 0x0f, 0x00, 0x10, 0xde, 0xde, 0xcd, 0x01, 0x2f, 0xdd, +0xcc, 0x31, 0x30, 0x05, 0x14, 0x16, 0x33, 0x33, 0x15, 0x06, +0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37, 0x33, 0x01, 0x05, +0x13, 0x21, 0x0f, 0x17, 0x13, 0x2e, 0x3d, 0x01, 0x01, 0x50, +0x3a, 0x1d, 0x1d, 0x30, 0x06, 0x30, 0x39, 0x04, 0x0b, 0x05, +0x00, 0x00, 0xff, 0xff, 0x00, 0xb9, 0x02, 0x01, 0x01, 0x3a, +0x02, 0xb9, 0x02, 0x06, 0x04, 0x87, 0x00, 0x00, 0x00, 0x01, +0x00, 0x82, 0x02, 0x21, 0x01, 0x72, 0x02, 0x9d, 0x00, 0x15, +0x00, 0x15, 0xb7, 0x05, 0x06, 0x11, 0x10, 0x00, 0x0b, 0x06, +0x10, 0x00, 0x2f, 0x33, 0xde, 0xcd, 0x01, 0x2f, 0xcd, 0xde, +0xcd, 0x31, 0x30, 0x13, 0x32, 0x1e, 0x02, 0x07, 0x23, 0x2e, +0x03, 0x23, 0x22, 0x0e, 0x02, 0x07, 0x23, 0x26, 0x3e, 0x02, +0xfa, 0x19, 0x2c, 0x21, 0x12, 0x01, 0x36, 0x01, 0x06, 0x0e, +0x19, 0x13, 0x13, 0x18, 0x0f, 0x06, 0x01, 0x36, 0x01, 0x12, +0x21, 0x2c, 0x02, 0x9d, 0x11, 0x20, 0x2e, 0x1d, 0x0a, 0x17, +0x13, 0x0c, 0x0c, 0x13, 0x17, 0x0a, 0x1d, 0x2e, 0x20, 0x11, +0x00, 0x03, 0x00, 0x70, 0x02, 0x0c, 0x01, 0x84, 0x03, 0x04, +0x00, 0x0b, 0x00, 0x17, 0x00, 0x2b, 0x00, 0x28, 0x40, 0x11, +0x1d, 0x1f, 0x26, 0x25, 0x09, 0x15, 0x0f, 0x03, 0x09, 0x18, +0x22, 0x1f, 0x25, 0x12, 0x06, 0x0c, 0x00, 0x00, 0x2f, 0x32, +0xdd, 0x32, 0xde, 0x32, 0xde, 0xcd, 0x01, 0x2f, 0xcd, 0xde, +0xcd, 0x10, 0xd4, 0xcd, 0xde, 0xcd, 0x31, 0x30, 0x13, 0x22, +0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, +0x33, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, +0x14, 0x06, 0x27, 0x32, 0x1e, 0x02, 0x15, 0x15, 0x23, 0x26, +0x26, 0x23, 0x22, 0x06, 0x07, 0x23, 0x35, 0x34, 0x3e, 0x02, +0xa0, 0x15, 0x1b, 0x1b, 0x15, 0x15, 0x1b, 0x1b, 0x9f, 0x14, +0x1c, 0x1c, 0x14, 0x14, 0x1c, 0x1c, 0x6e, 0x17, 0x2b, 0x21, +0x14, 0x30, 0x02, 0x22, 0x23, 0x23, 0x22, 0x02, 0x30, 0x14, +0x21, 0x2b, 0x02, 0x0c, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, +0x16, 0x1b, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, +0xf8, 0x0e, 0x1c, 0x28, 0x1b, 0x02, 0x15, 0x24, 0x24, 0x15, +0x02, 0x1b, 0x28, 0x1c, 0x0e, 0x00, 0x00, 0x00, 0xff, 0xff, +0x00, 0x47, 0xff, 0x56, 0x01, 0xb0, 0x02, 0xb5, 0x02, 0x26, +0x03, 0xaf, 0x00, 0x00, 0x00, 0x26, 0x04, 0xb5, 0x04, 0x00, +0x01, 0x06, 0x04, 0x88, 0x95, 0x00, 0x00, 0x0f, 0xb1, 0x02, +0x01, 0xb8, 0xff, 0xd8, 0xb4, 0x21, 0x15, 0x00, 0x05, 0x50, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x47, +0xff, 0x56, 0x01, 0xb0, 0x01, 0xda, 0x02, 0x26, 0x03, 0xaf, +0x00, 0x00, 0x01, 0x06, 0x04, 0x88, 0x95, 0x00, 0x00, 0x0d, +0xb9, 0x00, 0x01, 0xff, 0x97, 0xb4, 0x1d, 0x18, 0x00, 0x05, +0x50, 0x2b, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x47, +0xff, 0x56, 0x01, 0xb0, 0x02, 0xb5, 0x02, 0x26, 0x03, 0xaf, +0x00, 0x00, 0x00, 0x26, 0x04, 0xc0, 0x1e, 0x00, 0x01, 0x06, +0x04, 0x88, 0x95, 0x00, 0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, +0xff, 0xe5, 0xb4, 0x21, 0x14, 0x00, 0x05, 0x50, 0x2b, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x47, 0xff, 0x5b, +0x01, 0xb0, 0x02, 0x9d, 0x02, 0x26, 0x03, 0xaf, 0x00, 0x00, +0x01, 0x06, 0x04, 0x8a, 0x00, 0x00, 0x00, 0x13, 0xb9, 0x00, +0x01, 0xff, 0xff, 0x40, 0x09, 0x26, 0x18, 0x00, 0x05, 0x50, +0x01, 0x02, 0x19, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, +0x00, 0x47, 0xff, 0x56, 0x01, 0xb0, 0x02, 0x9d, 0x02, 0x26, +0x03, 0xaf, 0x00, 0x00, 0x00, 0x26, 0x04, 0x8a, 0x00, 0x00, +0x01, 0x06, 0x04, 0x88, 0x95, 0x00, 0x00, 0x0f, 0xb1, 0x02, +0x01, 0xb8, 0xff, 0xe2, 0xb4, 0x33, 0x18, 0x00, 0x05, 0x50, +0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x84, +0x00, 0x00, 0x01, 0xcc, 0x02, 0x76, 0x02, 0x26, 0x00, 0x28, +0x00, 0x00, 0x01, 0x07, 0x00, 0x43, 0xfe, 0xe1, 0xff, 0xc1, +0x00, 0x0d, 0xb9, 0x00, 0x01, 0xfe, 0xc4, 0xb4, 0x0f, 0x0d, +0x00, 0x0a, 0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0xff, 0x86, +0x00, 0x00, 0x01, 0xcc, 0x02, 0x76, 0x02, 0x26, 0x00, 0x28, +0x00, 0x00, 0x01, 0x07, 0x00, 0x8f, 0xfe, 0xdc, 0xff, 0xc1, +0x00, 0x0d, 0xb9, 0x00, 0x01, 0xfe, 0xc7, 0xb4, 0x0e, 0x0c, +0x00, 0x0a, 0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0xff, 0x55, +0x00, 0x00, 0x01, 0xc7, 0x02, 0x76, 0x02, 0x26, 0x00, 0x2b, +0x00, 0x00, 0x01, 0x07, 0x00, 0x43, 0xfe, 0xb2, 0xff, 0xc1, +0x00, 0x0d, 0xb9, 0x00, 0x01, 0xfe, 0xaf, 0xb4, 0x0f, 0x0d, +0x07, 0x01, 0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0xff, 0x59, +0x00, 0x00, 0x01, 0xc7, 0x02, 0x76, 0x02, 0x26, 0x00, 0x2b, +0x00, 0x00, 0x01, 0x07, 0x00, 0x8f, 0xfe, 0xaf, 0xff, 0xc1, +0x00, 0x0d, 0xb9, 0x00, 0x01, 0xfe, 0xb3, 0xb4, 0x0e, 0x0c, +0x07, 0x01, 0x50, 0x2b, 0x34, 0x00, 0x00, 0x02, 0x00, 0x2d, +0xff, 0xf7, 0x01, 0xf4, 0x02, 0x6b, 0x00, 0x0d, 0x00, 0x19, +0x00, 0x4b, 0x40, 0x2d, 0x18, 0x14, 0x73, 0x30, 0x15, 0x40, +0x15, 0x02, 0x15, 0x19, 0x11, 0x73, 0x0f, 0x10, 0x2f, 0x10, +0x02, 0x10, 0x05, 0x73, 0x0f, 0x08, 0x1f, 0x08, 0x02, 0x08, +0x08, 0x0d, 0x13, 0x79, 0x18, 0x18, 0x15, 0x0e, 0x16, 0x41, +0x11, 0x15, 0x44, 0x06, 0x49, 0x0d, 0x88, 0x00, 0x51, 0x00, +0x3f, 0xed, 0x3f, 0x3f, 0x33, 0x3f, 0x33, 0x12, 0x39, 0x2f, +0xed, 0x01, 0x2f, 0xde, 0x5e, 0x5d, 0xfd, 0xde, 0x5d, 0xed, +0x32, 0x2f, 0x5d, 0xed, 0x32, 0x31, 0x30, 0x05, 0x2e, 0x03, +0x35, 0x11, 0x33, 0x11, 0x14, 0x1e, 0x02, 0x17, 0x01, 0x33, +0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, 0x33, 0x11, 0x33, +0x01, 0xe9, 0x23, 0x2d, 0x19, 0x09, 0x49, 0x04, 0x0c, 0x14, +0x10, 0xfe, 0xfb, 0x4a, 0x4a, 0x79, 0x49, 0x49, 0x79, 0x09, +0x03, 0x14, 0x21, 0x2e, 0x1e, 0x01, 0x55, 0xfe, 0xb9, 0x13, +0x19, 0x12, 0x0a, 0x04, 0x02, 0x2e, 0xfd, 0x95, 0x01, 0x20, +0xfe, 0xe0, 0x02, 0x6b, 0xfe, 0xfb, 0x00, 0x02, 0x00, 0x60, +0x02, 0x01, 0x01, 0x94, 0x02, 0xbb, 0x00, 0x11, 0x00, 0x15, +0x00, 0x34, 0x40, 0x17, 0x14, 0x40, 0x13, 0x80, 0x12, 0x15, +0x0c, 0x11, 0x00, 0x06, 0x03, 0x0c, 0x13, 0x14, 0x14, 0x11, +0x15, 0x12, 0x12, 0x09, 0x03, 0x00, 0x11, 0x00, 0x2f, 0x33, +0xdd, 0xcd, 0x32, 0x2f, 0x33, 0x11, 0x33, 0x2f, 0x33, 0x01, +0x2f, 0x33, 0xdd, 0xce, 0x32, 0x10, 0xde, 0xcd, 0x1a, 0xdd, +0x1a, 0xcd, 0x31, 0x30, 0x13, 0x36, 0x36, 0x37, 0x26, 0x26, +0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, +0x07, 0x37, 0x17, 0x07, 0x27, 0x60, 0x13, 0x1a, 0x0a, 0x10, +0x10, 0x1b, 0x17, 0x15, 0x1f, 0x10, 0x19, 0x21, 0x12, 0xb1, +0x62, 0x2f, 0x70, 0x02, 0x20, 0x0f, 0x1c, 0x11, 0x06, 0x18, +0x0f, 0x15, 0x1b, 0x1c, 0x1b, 0x0f, 0x22, 0x22, 0x21, 0x0d, +0xba, 0x98, 0x22, 0x8e, 0x00, 0x02, 0x00, 0x6a, 0x02, 0x01, +0x01, 0x8a, 0x02, 0xbb, 0x00, 0x11, 0x00, 0x15, 0x00, 0x36, +0x40, 0x18, 0x15, 0x40, 0x12, 0x80, 0x13, 0x14, 0x14, 0x0c, +0x11, 0x00, 0x06, 0x03, 0x0c, 0x14, 0x13, 0x13, 0x11, 0x12, +0x15, 0x15, 0x09, 0x03, 0x00, 0x11, 0x00, 0x2f, 0x33, 0xdd, +0xcd, 0x32, 0x2f, 0x33, 0x11, 0x33, 0x2f, 0x33, 0x01, 0x2f, +0x33, 0xdd, 0xce, 0x32, 0x11, 0x33, 0x2f, 0xcd, 0x1a, 0xdd, +0x1a, 0xcd, 0x31, 0x30, 0x13, 0x36, 0x36, 0x37, 0x26, 0x26, +0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, 0x02, +0x07, 0x25, 0x07, 0x27, 0x37, 0x6a, 0x12, 0x1a, 0x0b, 0x10, +0x10, 0x1b, 0x17, 0x15, 0x1e, 0x0f, 0x1a, 0x21, 0x12, 0x01, +0x00, 0x71, 0x2e, 0x61, 0x02, 0x20, 0x0f, 0x1c, 0x11, 0x06, +0x18, 0x0f, 0x15, 0x1b, 0x1c, 0x1b, 0x0f, 0x22, 0x22, 0x21, +0x0d, 0x8e, 0x8e, 0x22, 0x98, 0x00, 0x00, 0x02, 0x00, 0x83, +0x02, 0x01, 0x01, 0x71, 0x03, 0x13, 0x00, 0x10, 0x00, 0x24, +0x00, 0x2c, 0x40, 0x13, 0x16, 0x18, 0x1f, 0x1e, 0x1e, 0x10, +0x00, 0x05, 0x02, 0x0b, 0x11, 0x1b, 0x18, 0x1e, 0x1e, 0x08, +0x02, 0x00, 0x10, 0x00, 0x2f, 0x33, 0xdd, 0xcd, 0x32, 0x2f, +0x33, 0xde, 0xcd, 0x01, 0x2f, 0x33, 0xdd, 0xce, 0x32, 0x33, +0x2f, 0xcd, 0xde, 0xcd, 0x31, 0x30, 0x13, 0x36, 0x37, 0x26, +0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x0e, +0x02, 0x07, 0x13, 0x32, 0x1e, 0x02, 0x15, 0x15, 0x23, 0x26, +0x26, 0x23, 0x22, 0x06, 0x07, 0x23, 0x35, 0x34, 0x3e, 0x02, +0xb3, 0x24, 0x0e, 0x0b, 0x0e, 0x17, 0x19, 0x15, 0x1b, 0x12, +0x1c, 0x22, 0x10, 0x2e, 0x17, 0x2b, 0x21, 0x14, 0x30, 0x02, +0x22, 0x23, 0x23, 0x22, 0x02, 0x30, 0x14, 0x21, 0x2b, 0x02, +0x20, 0x1a, 0x13, 0x08, 0x14, 0x0c, 0x10, 0x1b, 0x1a, 0x1a, +0x11, 0x1f, 0x1b, 0x17, 0x09, 0x01, 0x12, 0x0e, 0x1c, 0x29, +0x1b, 0x02, 0x15, 0x24, 0x24, 0x15, 0x02, 0x1b, 0x29, 0x1c, +0x0e, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, +0x02, 0x9d, 0x02, 0x26, 0x03, 0xb1, 0x00, 0x00, 0x01, 0x06, +0x01, 0x61, 0xdd, 0x00, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, +0xdb, 0x40, 0x09, 0x1a, 0x28, 0x0a, 0x00, 0x50, 0x01, 0x0b, +0x16, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, 0x00, 0x36, +0xff, 0xf5, 0x01, 0xc2, 0x02, 0x7b, 0x02, 0x26, 0x03, 0xb1, +0x00, 0x00, 0x01, 0x06, 0x00, 0x8a, 0xdd, 0x00, 0x00, 0x13, +0xb9, 0x00, 0x01, 0xff, 0xdb, 0x40, 0x09, 0x16, 0x17, 0x0a, +0x00, 0x50, 0x01, 0x0b, 0x18, 0x4f, 0x2b, 0x2b, 0x34, 0x00, +0xff, 0xff, 0x00, 0x26, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0xb9, +0x02, 0x26, 0x03, 0xb1, 0x00, 0x00, 0x01, 0x06, 0x04, 0xb3, +0xdd, 0x00, 0x00, 0x21, 0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, +0xdb, 0x40, 0x11, 0x1c, 0x2e, 0x0a, 0x00, 0x50, 0x03, 0x0b, +0x26, 0x4f, 0x02, 0x0b, 0x1a, 0x4f, 0x01, 0x0b, 0x18, 0x4f, +0x2b, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0xb9, +0x02, 0x26, 0x03, 0xb1, 0x00, 0x00, 0x01, 0x06, 0x03, 0xd8, +0xf8, 0x00, 0x00, 0x21, 0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, +0xed, 0x40, 0x11, 0x28, 0x22, 0x0a, 0x00, 0x50, 0x03, 0x0b, +0x26, 0x4f, 0x02, 0x0b, 0x1a, 0x4f, 0x01, 0x0b, 0x17, 0x4f, +0x2b, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, 0x01, 0xc2, 0x02, 0x9d, +0x02, 0x26, 0x03, 0xb1, 0x00, 0x00, 0x01, 0x06, 0x04, 0x8a, +0xdd, 0x00, 0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xdb, 0x40, +0x09, 0x28, 0x1a, 0x0a, 0x00, 0x50, 0x01, 0x0b, 0x1b, 0x4f, +0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, 0x00, 0x36, 0xff, 0xf5, +0x01, 0xc2, 0x03, 0x04, 0x02, 0x26, 0x03, 0xb1, 0x00, 0x00, +0x01, 0x06, 0x04, 0x8b, 0xdd, 0x00, 0x00, 0x21, 0xb2, 0x03, +0x02, 0x01, 0xb8, 0xff, 0xdb, 0x40, 0x11, 0x18, 0x2a, 0x0a, +0x00, 0x50, 0x03, 0x0b, 0x34, 0x4f, 0x02, 0x0b, 0x22, 0x4f, +0x01, 0x0b, 0x16, 0x4f, 0x2b, 0x2b, 0x2b, 0x2b, 0x34, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x59, 0x00, 0x00, +0x01, 0x9b, 0x03, 0x28, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, +0x01, 0x07, 0x01, 0x61, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x00, 0x10, 0x1e, 0x04, 0x02, 0x50, 0x01, +0x09, 0x0c, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x59, 0x00, 0x00, 0x01, 0x9b, 0x03, 0x06, 0x02, 0x26, +0x00, 0x2c, 0x00, 0x00, 0x01, 0x07, 0x00, 0x8a, 0x00, 0x00, +0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x0c, 0x0d, +0x04, 0x02, 0x50, 0x01, 0x09, 0x0e, 0x4f, 0x2b, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x01, 0x9b, +0x02, 0x76, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x07, +0x00, 0x43, 0xfe, 0xe0, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, +0x01, 0xfe, 0xdd, 0xb4, 0x0f, 0x0d, 0x04, 0x02, 0x50, 0x2b, +0x34, 0x00, 0xff, 0xff, 0xff, 0x85, 0x00, 0x00, 0x01, 0x9b, +0x02, 0x76, 0x02, 0x26, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x07, +0x00, 0x8f, 0xfe, 0xdb, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, +0x01, 0xfe, 0xdf, 0xb4, 0x0e, 0x0c, 0x04, 0x02, 0x50, 0x2b, +0x34, 0x00, 0x00, 0x02, 0x00, 0x69, 0x02, 0x01, 0x01, 0x8b, +0x02, 0xbb, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x32, 0x40, 0x16, +0x12, 0x40, 0x11, 0x80, 0x10, 0x13, 0x00, 0x0f, 0x0c, 0x03, +0x09, 0x11, 0x12, 0x12, 0x00, 0x13, 0x10, 0x10, 0x06, 0x0c, +0x0f, 0x00, 0x00, 0x2f, 0x32, 0xdd, 0xcd, 0x32, 0x2f, 0x33, +0x11, 0x33, 0x2f, 0x33, 0x01, 0x2f, 0xcd, 0x32, 0xce, 0x32, +0xde, 0xcd, 0x1a, 0xdd, 0x1a, 0xcd, 0x31, 0x30, 0x13, 0x26, +0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, +0x07, 0x16, 0x16, 0x17, 0x37, 0x17, 0x07, 0x27, 0xc5, 0x24, +0x38, 0x1f, 0x15, 0x17, 0x1b, 0x10, 0x10, 0x0a, 0x1a, 0x13, +0x43, 0x62, 0x2f, 0x70, 0x02, 0x01, 0x1c, 0x46, 0x1f, 0x1b, +0x1c, 0x1b, 0x15, 0x0f, 0x18, 0x06, 0x11, 0x1c, 0x0f, 0x9b, +0x98, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x60, +0x02, 0x01, 0x01, 0x94, 0x02, 0xbb, 0x00, 0x0f, 0x00, 0x13, +0x00, 0x32, 0x40, 0x16, 0x13, 0x40, 0x10, 0x80, 0x11, 0x12, +0x00, 0x0f, 0x0c, 0x03, 0x09, 0x12, 0x11, 0x11, 0x00, 0x10, +0x13, 0x13, 0x06, 0x0c, 0x0f, 0x00, 0x00, 0x2f, 0x32, 0xdd, +0xcd, 0x32, 0x2f, 0x33, 0x11, 0x33, 0x2f, 0x33, 0x01, 0x2f, +0xcd, 0x32, 0xce, 0x32, 0xde, 0xcd, 0x1a, 0xdd, 0x1a, 0xcd, +0x31, 0x30, 0x13, 0x26, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, +0x16, 0x15, 0x14, 0x06, 0x07, 0x16, 0x16, 0x17, 0x37, 0x07, +0x27, 0x37, 0xbc, 0x24, 0x38, 0x1f, 0x15, 0x17, 0x1b, 0x10, +0x10, 0x0a, 0x1a, 0x13, 0xb7, 0x71, 0x2e, 0x61, 0x02, 0x01, +0x1c, 0x46, 0x1f, 0x1b, 0x1c, 0x1b, 0x15, 0x0f, 0x18, 0x06, +0x11, 0x1c, 0x0f, 0x6f, 0x8e, 0x22, 0x98, 0x00, 0x00, 0x00, +0x00, 0x02, 0x00, 0x83, 0x02, 0x01, 0x01, 0x71, 0x03, 0x13, +0x00, 0x10, 0x00, 0x24, 0x00, 0x2e, 0x40, 0x14, 0x00, 0x10, +0x0b, 0x16, 0x18, 0x1f, 0x1e, 0x1e, 0x0e, 0x05, 0x0b, 0x11, +0x1b, 0x18, 0x1e, 0x1e, 0x08, 0x0e, 0x10, 0x00, 0x00, 0x2f, +0x32, 0xdd, 0xcd, 0x32, 0x2f, 0x33, 0xde, 0xcd, 0x01, 0x2f, +0xcd, 0x32, 0x32, 0x2f, 0xcd, 0xde, 0xcd, 0x10, 0xce, 0x32, +0x31, 0x30, 0x01, 0x2e, 0x03, 0x35, 0x34, 0x36, 0x33, 0x32, +0x16, 0x15, 0x14, 0x06, 0x07, 0x16, 0x17, 0x27, 0x32, 0x1e, +0x02, 0x15, 0x15, 0x23, 0x26, 0x26, 0x23, 0x22, 0x06, 0x07, +0x23, 0x35, 0x34, 0x3e, 0x02, 0x01, 0x28, 0x10, 0x22, 0x1c, +0x12, 0x1c, 0x14, 0x19, 0x17, 0x0e, 0x0b, 0x0e, 0x24, 0x47, +0x17, 0x2b, 0x21, 0x14, 0x30, 0x02, 0x22, 0x23, 0x23, 0x22, +0x02, 0x30, 0x14, 0x21, 0x2b, 0x02, 0x01, 0x09, 0x17, 0x1b, +0x1f, 0x11, 0x1a, 0x1a, 0x1b, 0x10, 0x0c, 0x14, 0x08, 0x13, +0x1a, 0xf3, 0x0e, 0x1c, 0x29, 0x1b, 0x02, 0x15, 0x24, 0x24, +0x15, 0x02, 0x1b, 0x29, 0x1c, 0x0e, 0xff, 0xff, 0x00, 0x47, +0xff, 0xf6, 0x01, 0xab, 0x02, 0x9d, 0x02, 0x26, 0x03, 0xbd, +0x00, 0x00, 0x01, 0x06, 0x01, 0x61, 0x00, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x01, 0x1a, 0x28, 0x04, 0x10, 0x50, 0x01, +0x06, 0x16, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x47, +0xff, 0xf6, 0x01, 0xab, 0x02, 0x7b, 0x02, 0x26, 0x03, 0xbd, +0x00, 0x00, 0x01, 0x06, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x01, 0x16, 0x17, 0x04, 0x10, 0x50, 0x01, +0x06, 0x18, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x47, +0xff, 0xf6, 0x01, 0xab, 0x02, 0xb9, 0x02, 0x26, 0x03, 0xbd, +0x00, 0x00, 0x01, 0x06, 0x04, 0xb3, 0x00, 0x00, 0x00, 0x1e, +0x40, 0x15, 0x03, 0x02, 0x01, 0x01, 0x1c, 0x2e, 0x04, 0x10, +0x50, 0x03, 0x06, 0x26, 0x4f, 0x02, 0x06, 0x1a, 0x4f, 0x01, +0x06, 0x18, 0x4f, 0x2b, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x47, 0xff, 0xf6, 0x01, 0xab, +0x02, 0xb9, 0x02, 0x26, 0x03, 0xbd, 0x00, 0x00, 0x01, 0x06, +0x03, 0xd8, 0x09, 0x00, 0x00, 0x1e, 0x40, 0x15, 0x03, 0x02, +0x01, 0x01, 0x28, 0x22, 0x04, 0x10, 0x50, 0x03, 0x06, 0x26, +0x4f, 0x02, 0x06, 0x1a, 0x4f, 0x01, 0x06, 0x17, 0x4f, 0x2b, +0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x47, 0xff, 0x5b, 0x01, 0xcc, 0x02, 0xb9, 0x02, 0x26, +0x03, 0xb9, 0x00, 0x00, 0x01, 0x06, 0x04, 0x87, 0x00, 0x00, +0x00, 0x13, 0xb9, 0x00, 0x02, 0xff, 0xf0, 0x40, 0x09, 0x20, +0x2b, 0x05, 0x0b, 0x50, 0x02, 0x08, 0x31, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0xff, 0xff, 0x00, 0x47, 0xff, 0x5b, 0x01, 0xcc, +0x02, 0xb9, 0x02, 0x26, 0x03, 0xb9, 0x00, 0x00, 0x01, 0x06, +0x04, 0xc1, 0x09, 0x00, 0x00, 0x13, 0xb9, 0x00, 0x02, 0xff, +0xf9, 0x40, 0x09, 0x24, 0x30, 0x05, 0x0b, 0x50, 0x02, 0x08, +0x20, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0xff, 0xff, 0x00, 0x47, +0xff, 0xf6, 0x01, 0xab, 0x02, 0x9d, 0x02, 0x26, 0x03, 0xbd, +0x00, 0x00, 0x01, 0x06, 0x04, 0x8a, 0x00, 0x00, 0x00, 0x10, +0x40, 0x0b, 0x01, 0x01, 0x28, 0x1a, 0x04, 0x10, 0x50, 0x01, +0x06, 0x1b, 0x4f, 0x2b, 0x2b, 0x34, 0xff, 0xff, 0x00, 0x47, +0xff, 0xf6, 0x01, 0xab, 0x03, 0x04, 0x02, 0x26, 0x03, 0xbd, +0x00, 0x00, 0x01, 0x06, 0x04, 0x8b, 0x00, 0x00, 0x00, 0x1e, +0x40, 0x15, 0x03, 0x02, 0x01, 0x01, 0x18, 0x2a, 0x04, 0x10, +0x50, 0x03, 0x06, 0x34, 0x4f, 0x02, 0x06, 0x22, 0x4f, 0x01, +0x06, 0x16, 0x4f, 0x2b, 0x2b, 0x2b, 0x2b, 0x34, 0x34, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x00, 0x01, 0xe8, +0x03, 0x28, 0x02, 0x26, 0x00, 0x3c, 0x00, 0x00, 0x01, 0x07, +0x01, 0x61, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x10, 0x40, 0x0b, +0x01, 0x00, 0x15, 0x23, 0x04, 0x0c, 0x50, 0x01, 0x04, 0x11, +0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0d, +0x00, 0x00, 0x01, 0xe8, 0x03, 0x06, 0x02, 0x26, 0x00, 0x3c, +0x00, 0x00, 0x01, 0x07, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x8b, +0x00, 0x10, 0x40, 0x0b, 0x01, 0x00, 0x11, 0x12, 0x04, 0x0c, +0x50, 0x01, 0x04, 0x13, 0x4f, 0x2b, 0x2b, 0x34, 0x00, 0x00, +0xff, 0xff, 0xff, 0x66, 0x00, 0x00, 0x01, 0xe8, 0x02, 0x76, +0x02, 0x26, 0x00, 0x3c, 0x00, 0x00, 0x01, 0x07, 0x00, 0x43, +0xfe, 0xc3, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, 0x01, 0xfe, +0xbf, 0xb4, 0x14, 0x12, 0x04, 0x0c, 0x50, 0x2b, 0x34, 0x00, +0xff, 0xff, 0xff, 0x42, 0x00, 0x00, 0x01, 0xe8, 0x02, 0x76, +0x02, 0x37, 0x00, 0x8f, 0xfe, 0x98, 0xff, 0xc1, 0x00, 0x06, +0x00, 0x3c, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa4, 0x00, 0x00, +0x01, 0xc7, 0x02, 0x7a, 0x02, 0x26, 0x03, 0xa1, 0x00, 0x00, +0x01, 0x07, 0x04, 0xc1, 0xfe, 0xeb, 0xff, 0xc1, 0x00, 0x0d, +0xb9, 0x00, 0x02, 0xfe, 0xdd, 0xb4, 0x22, 0x2e, 0x09, 0x02, +0x50, 0x2b, 0x34, 0x00, 0x00, 0x03, 0x00, 0x49, 0x02, 0x04, +0x01, 0xab, 0x02, 0xb9, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x1b, +0x00, 0x34, 0x40, 0x17, 0x19, 0x13, 0x13, 0x02, 0x40, 0x01, +0x80, 0x00, 0x03, 0x03, 0x07, 0x0d, 0x16, 0x0a, 0x40, 0x10, +0x04, 0x04, 0x03, 0x00, 0x80, 0x01, 0x02, 0x00, 0x2f, 0x33, +0x1a, 0xcd, 0x32, 0x33, 0x2f, 0x33, 0x1a, 0xcd, 0x32, 0x01, +0x2f, 0xcd, 0x33, 0x2f, 0xcd, 0x1a, 0xdd, 0x1a, 0xcd, 0x33, +0x2f, 0xcd, 0x31, 0x30, 0x13, 0x17, 0x07, 0x27, 0x07, 0x22, +0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, +0x33, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, +0x14, 0x06, 0xf0, 0x50, 0x2f, 0x5d, 0x3b, 0x14, 0x1c, 0x1c, +0x14, 0x15, 0x1c, 0x1c, 0xed, 0x15, 0x1c, 0x1c, 0x15, 0x14, +0x1c, 0x1c, 0x02, 0xb9, 0x99, 0x1c, 0x8e, 0x67, 0x1a, 0x17, +0x16, 0x1b, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x1b, +0x1b, 0x16, 0x17, 0x1a, 0x00, 0x03, 0x00, 0x49, 0x02, 0x04, +0x01, 0xab, 0x02, 0xb9, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x1b, +0x00, 0x34, 0x40, 0x17, 0x0d, 0x07, 0x07, 0x03, 0x40, 0x00, +0x80, 0x01, 0x02, 0x02, 0x13, 0x19, 0x0a, 0x16, 0x40, 0x04, +0x10, 0x10, 0x00, 0x03, 0x80, 0x02, 0x01, 0x00, 0x2f, 0x33, +0x1a, 0xcd, 0x32, 0x33, 0x2f, 0x33, 0x1a, 0xcd, 0x32, 0x01, +0x2f, 0xcd, 0x33, 0x2f, 0xcd, 0x1a, 0xdd, 0x1a, 0xcd, 0x33, +0x2f, 0xcd, 0x31, 0x30, 0x01, 0x07, 0x27, 0x37, 0x17, 0x22, +0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, +0x21, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, +0x14, 0x06, 0x01, 0x40, 0x5d, 0x2f, 0x50, 0x77, 0x15, 0x1c, +0x1c, 0x15, 0x14, 0x1c, 0x1c, 0xfe, 0xea, 0x13, 0x1d, 0x1d, +0x13, 0x15, 0x1c, 0x1c, 0x02, 0x92, 0x8e, 0x1c, 0x99, 0x8e, +0x1a, 0x17, 0x16, 0x1b, 0x1b, 0x16, 0x17, 0x1a, 0x1a, 0x17, +0x16, 0x1b, 0x1b, 0x16, 0x17, 0x1a, 0x00, 0x00, 0x00, 0x01, +0x00, 0x98, 0x02, 0x06, 0x01, 0x5b, 0x02, 0xb5, 0x00, 0x03, +0x00, 0x1a, 0x40, 0x0a, 0x00, 0x03, 0x02, 0x01, 0x03, 0x40, +0x00, 0x80, 0x01, 0x02, 0x00, 0x2f, 0xcd, 0x1a, 0xdd, 0x1a, +0xcd, 0x01, 0x2f, 0x33, 0xcd, 0x32, 0x31, 0x30, 0x13, 0x17, +0x07, 0x27, 0xc7, 0x94, 0x23, 0xa0, 0x02, 0xb5, 0x81, 0x2e, +0x71, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0x56, +0x01, 0xd2, 0x02, 0xb5, 0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, +0x00, 0x26, 0x04, 0xb5, 0x04, 0x00, 0x01, 0x06, 0x04, 0x88, +0x1b, 0x00, 0x00, 0x0c, 0xb7, 0x02, 0x01, 0x04, 0x38, 0x3d, +0x0a, 0x2f, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x24, 0xff, 0x56, 0x01, 0xd2, 0x01, 0xda, 0x02, 0x26, +0x03, 0xc1, 0x00, 0x00, 0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, +0x00, 0x0a, 0xb6, 0x01, 0x1d, 0x3e, 0x39, 0x0a, 0x2f, 0x50, +0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0x56, +0x01, 0xd2, 0x02, 0xbb, 0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, +0x00, 0x26, 0x03, 0xd6, 0x19, 0x00, 0x01, 0x06, 0x04, 0x88, +0x1b, 0x00, 0x00, 0x0c, 0xb7, 0x02, 0x01, 0x15, 0x37, 0x3d, +0x0a, 0x2f, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x24, 0xff, 0xf7, 0x01, 0xd2, 0x02, 0x9d, 0x02, 0x26, +0x03, 0xc1, 0x00, 0x00, 0x01, 0x06, 0x04, 0x8a, 0x00, 0x00, +0x00, 0x13, 0xb9, 0x00, 0x01, 0xff, 0xff, 0x40, 0x09, 0x47, +0x39, 0x0a, 0x2f, 0x50, 0x01, 0x10, 0x3a, 0x4f, 0x2b, 0x2b, +0x34, 0x00, 0xff, 0xff, 0x00, 0x24, 0xff, 0x56, 0x01, 0xd2, +0x02, 0x9d, 0x02, 0x26, 0x03, 0xc1, 0x00, 0x00, 0x00, 0x26, +0x04, 0x88, 0x1b, 0x00, 0x01, 0x06, 0x04, 0x8a, 0x00, 0x00, +0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, 0xff, 0xff, 0xb4, 0x56, +0x48, 0x0a, 0x2f, 0x50, 0x2b, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0x70, 0xff, 0xf3, 0x01, 0xd8, 0x02, 0x79, +0x02, 0x26, 0x00, 0x32, 0x00, 0x00, 0x01, 0x07, 0x00, 0x43, +0xfe, 0xcd, 0xff, 0xc1, 0x00, 0x0d, 0xb9, 0x00, 0x02, 0xfe, +0xc9, 0xb4, 0x23, 0x21, 0x00, 0x09, 0x50, 0x2b, 0x34, 0x00, +0xff, 0xff, 0xff, 0x9c, 0xff, 0xf3, 0x01, 0xd8, 0x02, 0x79, +0x02, 0x37, 0x00, 0x8f, 0xfe, 0xf2, 0xff, 0xc1, 0x00, 0x06, +0x00, 0x32, 0x00, 0x00, 0xff, 0xff, 0xff, 0x6e, 0x00, 0x00, +0x01, 0xe2, 0x02, 0x79, 0x02, 0x26, 0x03, 0xa8, 0x00, 0x00, +0x01, 0x07, 0x00, 0x43, 0xfe, 0xcb, 0xff, 0xc1, 0x00, 0x0d, +0xb9, 0x00, 0x01, 0xfe, 0xc8, 0xb4, 0x2f, 0x2d, 0x00, 0x12, +0x50, 0x2b, 0x34, 0x00, 0xff, 0xff, 0xff, 0x9a, 0x00, 0x00, +0x01, 0xe2, 0x02, 0x79, 0x02, 0x26, 0x03, 0xa8, 0x00, 0x00, +0x01, 0x07, 0x00, 0x8f, 0xfe, 0xf0, 0xff, 0xc1, 0x00, 0x0d, +0xb9, 0x00, 0x01, 0xfe, 0xf4, 0xb4, 0x2e, 0x2c, 0x00, 0x12, +0x50, 0x2b, 0x34, 0x00, 0x00, 0x02, 0x00, 0x12, 0xff, 0xf7, +0x01, 0xf4, 0x02, 0x79, 0x00, 0x2f, 0x00, 0x3d, 0x00, 0xb4, +0xb9, 0x00, 0x27, 0xff, 0xf0, 0x40, 0x0f, 0x0f, 0x10, 0x00, +0x4c, 0x23, 0x20, 0x10, 0x00, 0x4d, 0x23, 0x18, 0x0f, 0x00, +0x4d, 0x0f, 0xb8, 0xff, 0xe0, 0xb3, 0x14, 0x00, 0x4d, 0x0f, +0xb8, 0xff, 0xf0, 0xb3, 0x13, 0x00, 0x4d, 0x0f, 0xb8, 0xff, +0xe8, 0x40, 0x57, 0x11, 0x12, 0x00, 0x4c, 0x0b, 0x10, 0x12, +0x14, 0x00, 0x4c, 0x0b, 0x18, 0x11, 0x00, 0x4d, 0x17, 0x5f, +0x1b, 0x6f, 0x1b, 0x02, 0x1b, 0x40, 0x13, 0x16, 0x48, 0x1b, +0x1b, 0x20, 0x76, 0x12, 0x18, 0x18, 0x0f, 0x12, 0x1f, 0x12, +0x2f, 0x12, 0x03, 0x12, 0x35, 0x73, 0x0f, 0x38, 0x01, 0x08, +0x38, 0x3d, 0x03, 0xb0, 0x2f, 0xc0, 0x2f, 0xd0, 0x2f, 0x03, +0xa1, 0x2f, 0x01, 0x2f, 0x2f, 0x2a, 0x76, 0x08, 0x02, 0x02, +0x08, 0x36, 0x49, 0x3d, 0x88, 0x30, 0x51, 0x25, 0x7c, 0x0d, +0x45, 0x1b, 0x2f, 0x2f, 0x17, 0x03, 0x79, 0x1a, 0x00, 0x44, +0x00, 0x3f, 0x32, 0xed, 0x32, 0x32, 0x11, 0x33, 0x3f, 0xed, +0x3f, 0xed, 0x3f, 0x01, 0x2f, 0x33, 0x2f, 0x10, 0xed, 0x32, +0x2f, 0x5d, 0x5d, 0x33, 0x2f, 0xde, 0x5e, 0x5d, 0xfd, 0xce, +0x5d, 0x32, 0x2f, 0x10, 0xed, 0x32, 0x2f, 0x2b, 0x5d, 0x33, +0x31, 0x30, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x33, 0x23, 0x35, 0x33, 0x2e, 0x03, 0x35, 0x34, 0x3e, 0x02, +0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x33, +0x15, 0x23, 0x35, 0x3e, 0x03, 0x35, 0x34, 0x2e, 0x02, 0x23, +0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x17, 0x05, 0x2e, +0x03, 0x35, 0x11, 0x33, 0x11, 0x14, 0x1e, 0x02, 0x17, 0x9a, +0x88, 0x43, 0x0d, 0x16, 0x11, 0x09, 0x11, 0x23, 0x38, 0x27, +0x27, 0x37, 0x23, 0x11, 0x0a, 0x10, 0x16, 0x0d, 0x41, 0x86, +0x0c, 0x15, 0x0f, 0x09, 0x07, 0x10, 0x1c, 0x16, 0x16, 0x1c, +0x11, 0x07, 0x09, 0x0f, 0x15, 0x0c, 0x01, 0x4f, 0x23, 0x2d, +0x19, 0x09, 0x49, 0x04, 0x0c, 0x14, 0x10, 0x46, 0x16, 0x41, +0x4c, 0x51, 0x27, 0x39, 0x66, 0x4c, 0x2d, 0x2d, 0x4c, 0x65, +0x39, 0x27, 0x52, 0x4c, 0x41, 0x16, 0x46, 0x3c, 0x15, 0x40, +0x4b, 0x50, 0x26, 0x2f, 0x52, 0x3c, 0x23, 0x23, 0x3c, 0x52, +0x2f, 0x26, 0x50, 0x4b, 0x40, 0x15, 0x45, 0x03, 0x14, 0x21, +0x2e, 0x1e, 0x01, 0x55, 0xfe, 0xb9, 0x13, 0x19, 0x12, 0x0a, +0x04, 0x00, 0x00, 0x01, 0x00, 0x98, 0x02, 0x06, 0x01, 0x5b, +0x02, 0xb5, 0x00, 0x03, 0x00, 0x1a, 0x40, 0x0a, 0x03, 0x00, +0x01, 0x02, 0x00, 0x40, 0x03, 0x80, 0x02, 0x01, 0x00, 0x2f, +0xcd, 0x1a, 0xdd, 0x1a, 0xcd, 0x01, 0x2f, 0x33, 0xcd, 0x32, +0x31, 0x30, 0x01, 0x07, 0x27, 0x37, 0x01, 0x5b, 0x9f, 0x24, +0x94, 0x02, 0x77, 0x71, 0x2e, 0x81, 0x00, 0x00, 0x00, 0x01, +0x00, 0xb9, 0x02, 0x01, 0x01, 0x3a, 0x02, 0xb9, 0x00, 0x10, +0x00, 0x18, 0x40, 0x09, 0x00, 0x10, 0x0d, 0x05, 0x0b, 0x08, +0x0d, 0x10, 0x00, 0x00, 0x2f, 0x32, 0xdd, 0xcd, 0x01, 0x2f, +0xcd, 0x32, 0xce, 0x32, 0x31, 0x30, 0x01, 0x2e, 0x03, 0x35, +0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x07, 0x16, 0x16, +0x17, 0x01, 0x1a, 0x14, 0x23, 0x1a, 0x10, 0x20, 0x17, 0x17, +0x1d, 0x22, 0x0a, 0x1c, 0x12, 0x02, 0x01, 0x0d, 0x20, 0x23, +0x22, 0x0f, 0x1b, 0x1c, 0x1b, 0x15, 0x20, 0x0d, 0x11, 0x1c, +0x0f, 0x00, 0xff, 0xff, 0x00, 0x06, 0xff, 0x56, 0x01, 0xeb, +0x02, 0x7a, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x00, 0x27, +0x04, 0x87, 0xff, 0x4d, 0xff, 0xc1, 0x01, 0x06, 0x04, 0x88, +0x12, 0x00, 0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, 0xff, 0xb6, +0xb4, 0x17, 0x2d, 0x04, 0x0f, 0x50, 0x2b, 0x34, 0x34, 0x00, +0xff, 0xff, 0xff, 0xf5, 0xff, 0x56, 0x01, 0xeb, 0x02, 0x7a, +0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x00, 0x27, 0x04, 0xc1, +0xff, 0x3c, 0xff, 0xc1, 0x01, 0x06, 0x04, 0x88, 0x12, 0x00, +0x00, 0x0f, 0xb1, 0x03, 0x02, 0xb8, 0xff, 0xae, 0xb4, 0x1b, +0x2c, 0x04, 0x0f, 0x50, 0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, +0xff, 0x45, 0xff, 0x56, 0x01, 0xeb, 0x02, 0x7c, 0x02, 0x26, +0x00, 0x24, 0x00, 0x00, 0x00, 0x27, 0x04, 0x96, 0xfe, 0xe5, +0xff, 0xc1, 0x01, 0x06, 0x04, 0x88, 0x12, 0x00, 0x00, 0x11, +0xb2, 0x04, 0x03, 0x02, 0xb8, 0xff, 0x56, 0xb4, 0x17, 0x31, +0x04, 0x0f, 0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0x58, 0xff, 0x56, 0x01, 0xeb, 0x02, 0x7c, +0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x00, 0x27, 0x04, 0xa3, +0xfe, 0xef, 0xff, 0xc1, 0x01, 0x06, 0x04, 0x88, 0x12, 0x00, +0x00, 0x11, 0xb2, 0x04, 0x03, 0x02, 0xb8, 0xff, 0x5f, 0xb4, +0x19, 0x2f, 0x04, 0x0f, 0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0xff, 0x78, 0xff, 0x56, 0x01, 0xeb, +0x02, 0x7c, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, 0x00, 0x27, +0x04, 0x97, 0xff, 0x0e, 0xff, 0xc1, 0x01, 0x06, 0x04, 0x88, +0x12, 0x00, 0x00, 0x11, 0xb2, 0x04, 0x03, 0x02, 0xb8, 0xff, +0x6f, 0xb4, 0x17, 0x31, 0x04, 0x0f, 0x50, 0x2b, 0x34, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x62, 0xff, 0x56, +0x01, 0xeb, 0x02, 0x7c, 0x02, 0x26, 0x00, 0x24, 0x00, 0x00, +0x00, 0x27, 0x04, 0xa4, 0xff, 0x02, 0xff, 0xc1, 0x01, 0x06, +0x04, 0x88, 0x12, 0x00, 0x00, 0x11, 0xb2, 0x04, 0x03, 0x02, +0xb8, 0xff, 0x64, 0xb4, 0x19, 0x2f, 0x04, 0x0f, 0x50, 0x2b, +0x34, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xae, +0xff, 0x56, 0x01, 0xeb, 0x02, 0xb4, 0x02, 0x26, 0x00, 0x24, +0x00, 0x00, 0x00, 0x27, 0x04, 0x98, 0xff, 0x2b, 0xff, 0xa1, +0x01, 0x06, 0x04, 0x88, 0x12, 0x00, 0x00, 0x11, 0xb2, 0x04, +0x03, 0x02, 0xb8, 0xff, 0x8a, 0xb4, 0x36, 0x40, 0x04, 0x0f, +0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0xff, 0xa4, 0xff, 0x56, 0x01, 0xeb, 0x02, 0xb4, 0x02, 0x26, +0x00, 0x24, 0x00, 0x00, 0x00, 0x27, 0x04, 0xa5, 0xff, 0x21, +0xff, 0xa1, 0x01, 0x06, 0x04, 0x88, 0x12, 0x00, 0x00, 0x11, +0xb2, 0x04, 0x03, 0x02, 0xb8, 0xff, 0x85, 0xb4, 0x36, 0x40, +0x04, 0x0f, 0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0x83, 0xff, 0x56, 0x01, 0xc7, 0x02, 0x7a, +0x02, 0x26, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x27, 0x04, 0x87, +0xfe, 0xca, 0xff, 0xc1, 0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, +0x00, 0x0f, 0xb1, 0x02, 0x01, 0xb8, 0xff, 0x79, 0xb4, 0x0c, +0x22, 0x07, 0x01, 0x50, 0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, +0xff, 0x88, 0xff, 0x56, 0x01, 0xc7, 0x02, 0x7a, 0x02, 0x26, +0x00, 0x2b, 0x00, 0x00, 0x00, 0x27, 0x04, 0xc1, 0xfe, 0xcf, +0xff, 0xc1, 0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, 0x00, 0x0f, +0xb1, 0x02, 0x01, 0xb8, 0xff, 0x7c, 0xb4, 0x10, 0x21, 0x07, +0x01, 0x50, 0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0xfe, 0xd9, +0xff, 0x56, 0x01, 0xc7, 0x02, 0x7c, 0x02, 0x26, 0x00, 0x2b, +0x00, 0x00, 0x00, 0x27, 0x04, 0x96, 0xfe, 0x79, 0xff, 0xc1, +0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, 0x00, 0x11, 0xb2, 0x03, +0x02, 0x01, 0xb8, 0xff, 0x24, 0xb4, 0x0c, 0x26, 0x07, 0x01, +0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0xfe, 0xea, 0xff, 0x56, 0x01, 0xc7, 0x02, 0x7c, 0x02, 0x26, +0x00, 0x2b, 0x00, 0x00, 0x00, 0x27, 0x04, 0xa3, 0xfe, 0x81, +0xff, 0xc1, 0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, 0x00, 0x11, +0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, 0x2d, 0xb4, 0x0e, 0x24, +0x07, 0x01, 0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0xfe, 0xec, 0xff, 0x56, 0x01, 0xc7, 0x02, 0x7c, +0x02, 0x26, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x27, 0x04, 0x97, +0xfe, 0x82, 0xff, 0xc1, 0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, +0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, 0x2e, 0xb4, +0x0c, 0x26, 0x07, 0x01, 0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0xfe, 0xd9, 0xff, 0x56, 0x01, 0xc7, +0x02, 0x7c, 0x02, 0x26, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x27, +0x04, 0xa4, 0xfe, 0x79, 0xff, 0xc1, 0x01, 0x06, 0x04, 0x88, +0x1b, 0x00, 0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, +0x24, 0xb4, 0x0e, 0x24, 0x07, 0x01, 0x50, 0x2b, 0x34, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1a, 0xff, 0x56, +0x01, 0xc7, 0x02, 0xb4, 0x02, 0x26, 0x00, 0x2b, 0x00, 0x00, +0x00, 0x27, 0x04, 0x98, 0xfe, 0x97, 0xff, 0xa1, 0x01, 0x06, +0x04, 0x88, 0x1b, 0x00, 0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, +0xb8, 0xff, 0x45, 0xb4, 0x2b, 0x35, 0x07, 0x01, 0x50, 0x2b, +0x34, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1a, +0xff, 0x56, 0x01, 0xc7, 0x02, 0xb4, 0x02, 0x26, 0x00, 0x2b, +0x00, 0x00, 0x00, 0x27, 0x04, 0xa5, 0xfe, 0x97, 0xff, 0xa1, +0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, 0x00, 0x11, 0xb2, 0x03, +0x02, 0x01, 0xb8, 0xff, 0x45, 0xb4, 0x2b, 0x35, 0x07, 0x01, +0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0xff, 0x9f, 0xff, 0x56, 0x01, 0xe2, 0x02, 0x7a, 0x02, 0x26, +0x03, 0xa8, 0x00, 0x00, 0x00, 0x27, 0x04, 0x87, 0xfe, 0xe6, +0xff, 0xc1, 0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, 0x00, 0x0f, +0xb1, 0x02, 0x01, 0xb8, 0xff, 0x87, 0xb4, 0x2c, 0x42, 0x00, +0x12, 0x50, 0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0xff, 0x84, +0xff, 0x56, 0x01, 0xe2, 0x02, 0x7a, 0x02, 0x26, 0x03, 0xa8, +0x00, 0x00, 0x00, 0x27, 0x04, 0xc1, 0xfe, 0xcb, 0xff, 0xc1, +0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, 0x00, 0x0f, 0xb1, 0x02, +0x01, 0xb8, 0xff, 0x7a, 0xb4, 0x30, 0x41, 0x00, 0x12, 0x50, +0x2b, 0x34, 0x34, 0x00, 0xff, 0xff, 0xfe, 0xd5, 0xff, 0x56, +0x01, 0xe2, 0x02, 0x7c, 0x02, 0x26, 0x03, 0xa8, 0x00, 0x00, +0x00, 0x27, 0x04, 0x96, 0xfe, 0x75, 0xff, 0xc1, 0x01, 0x06, +0x04, 0x88, 0x1b, 0x00, 0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, +0xb8, 0xff, 0x22, 0xb4, 0x2c, 0x46, 0x00, 0x12, 0x50, 0x2b, +0x34, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xe7, +0xff, 0x56, 0x01, 0xe2, 0x02, 0x7c, 0x02, 0x26, 0x03, 0xa8, +0x00, 0x00, 0x00, 0x27, 0x04, 0xa3, 0xfe, 0x7e, 0xff, 0xc1, +0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, 0x00, 0x11, 0xb2, 0x03, +0x02, 0x01, 0xb8, 0xff, 0x2b, 0xb4, 0x2e, 0x44, 0x00, 0x12, +0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, +0xff, 0x17, 0xff, 0x56, 0x01, 0xe2, 0x02, 0x7c, 0x02, 0x26, +0x03, 0xa8, 0x00, 0x00, 0x00, 0x27, 0x04, 0x97, 0xfe, 0xad, +0xff, 0xc1, 0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, 0x00, 0x11, +0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, 0x43, 0xb4, 0x2c, 0x46, +0x00, 0x12, 0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0x02, 0xff, 0x56, 0x01, 0xe2, 0x02, 0x7c, +0x02, 0x26, 0x03, 0xa8, 0x00, 0x00, 0x00, 0x27, 0x04, 0xa4, +0xfe, 0xa2, 0xff, 0xc1, 0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, +0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, 0x39, 0xb4, +0x2e, 0x44, 0x00, 0x12, 0x50, 0x2b, 0x34, 0x34, 0x34, 0x00, +0x00, 0x00, 0xff, 0xff, 0xff, 0x56, 0xff, 0x56, 0x01, 0xe2, +0x02, 0xb4, 0x02, 0x26, 0x03, 0xa8, 0x00, 0x00, 0x00, 0x27, +0x04, 0x98, 0xfe, 0xd3, 0xff, 0xa1, 0x01, 0x06, 0x04, 0x88, +0x1b, 0x00, 0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, 0xb8, 0xff, +0x63, 0xb4, 0x4b, 0x55, 0x00, 0x12, 0x50, 0x2b, 0x34, 0x34, +0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x3c, 0xff, 0x56, +0x01, 0xe2, 0x02, 0xb4, 0x02, 0x26, 0x03, 0xa8, 0x00, 0x00, +0x00, 0x27, 0x04, 0xa5, 0xfe, 0xb9, 0xff, 0xa1, 0x01, 0x06, +0x04, 0x88, 0x1b, 0x00, 0x00, 0x11, 0xb2, 0x03, 0x02, 0x01, +0xb8, 0xff, 0x56, 0xb4, 0x4b, 0x55, 0x00, 0x12, 0x50, 0x2b, +0x34, 0x34, 0x34, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x09, +0xff, 0x56, 0x01, 0xeb, 0x02, 0x6b, 0x02, 0x26, 0x00, 0x24, +0x00, 0x00, 0x01, 0x06, 0x04, 0x88, 0x12, 0x00, 0x00, 0x0a, +0xb6, 0x02, 0x15, 0x20, 0x1b, 0x04, 0x0f, 0x50, 0x2b, 0x34, +0x00, 0x00, 0xff, 0xff, 0x00, 0x2d, 0xff, 0x56, 0x01, 0xc7, +0x02, 0x6b, 0x02, 0x26, 0x00, 0x2b, 0x00, 0x00, 0x01, 0x06, +0x04, 0x88, 0x1b, 0x00, 0x00, 0x0a, 0xb6, 0x01, 0x1e, 0x15, +0x10, 0x07, 0x01, 0x50, 0x2b, 0x34, 0x00, 0x00, 0xff, 0xff, +0x00, 0x12, 0xff, 0x56, 0x01, 0xe2, 0x02, 0x79, 0x02, 0x26, +0x03, 0xa8, 0x00, 0x00, 0x01, 0x06, 0x04, 0x88, 0x1b, 0x00, +0x00, 0x0a, 0xb6, 0x01, 0x1e, 0x35, 0x30, 0x00, 0x12, 0x50, +0x2b, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3f, 0x00, 0x00, +0x01, 0xd9, 0x02, 0x6b, 0x00, 0x28, 0x00, 0x74, 0x40, 0x40, +0x0b, 0x20, 0x11, 0x00, 0x4d, 0x23, 0x1d, 0x22, 0x1d, 0x78, +0x28, 0x23, 0x14, 0x28, 0x28, 0x23, 0x22, 0x22, 0x06, 0x09, +0x76, 0x15, 0x18, 0x16, 0x16, 0x13, 0x11, 0x11, 0x15, 0x2a, +0x0f, 0x0f, 0x07, 0x07, 0x28, 0x29, 0x18, 0x07, 0x79, 0x08, +0x15, 0x08, 0x1d, 0x28, 0x79, 0x00, 0x20, 0x00, 0x30, 0x00, +0x02, 0x08, 0x00, 0x08, 0x00, 0x10, 0x23, 0x22, 0x44, 0x13, +0x0f, 0x79, 0x10, 0x41, 0x00, 0x3f, 0xed, 0x32, 0x3f, 0x33, +0x12, 0x39, 0x39, 0x2f, 0x2f, 0x5d, 0x10, 0xed, 0x32, 0x11, +0x33, 0x10, 0xed, 0x32, 0x01, 0x10, 0xc6, 0x32, 0x2f, 0x32, +0x2f, 0x10, 0xcc, 0x32, 0x2f, 0x32, 0x32, 0x2f, 0x32, 0x10, +0xed, 0x32, 0x33, 0x2f, 0x87, 0x10, 0x2b, 0x87, 0x7d, 0xc4, +0x31, 0x30, 0x01, 0x2b, 0x13, 0x33, 0x32, 0x3e, 0x02, 0x37, +0x23, 0x35, 0x33, 0x2e, 0x03, 0x23, 0x23, 0x35, 0x21, 0x07, +0x23, 0x16, 0x17, 0x33, 0x07, 0x23, 0x0e, 0x03, 0x07, 0x1e, +0x03, 0x17, 0x23, 0x2e, 0x03, 0x27, 0x3f, 0x41, 0x19, 0x37, +0x30, 0x25, 0x08, 0xee, 0xf0, 0x04, 0x17, 0x21, 0x2a, 0x17, +0x73, 0x01, 0x9a, 0x0c, 0x7c, 0x27, 0x09, 0x3b, 0x0d, 0x31, +0x06, 0x29, 0x3b, 0x4a, 0x27, 0x19, 0x3c, 0x3b, 0x36, 0x14, +0x61, 0x19, 0x3a, 0x3b, 0x39, 0x16, 0x01, 0x3e, 0x08, 0x13, +0x21, 0x19, 0x40, 0x1b, 0x22, 0x14, 0x07, 0x40, 0x40, 0x21, +0x37, 0x40, 0x26, 0x34, 0x23, 0x12, 0x04, 0x18, 0x3e, 0x45, +0x46, 0x1f, 0x23, 0x46, 0x41, 0x38, 0x15, 0x00, 0x00, 0x00, +0x00, 0x07, 0x00, 0x3a, 0x01, 0x34, 0x01, 0xbb, 0x02, 0xb5, +0x00, 0x13, 0x00, 0x1f, 0x00, 0x2b, 0x00, 0x3c, 0x00, 0x4e, +0x00, 0x60, 0x00, 0x6c, 0x00, 0x37, 0x40, 0x1d, 0x65, 0x41, +0x28, 0x5d, 0x40, 0x5e, 0x33, 0x37, 0x37, 0x2c, 0x5e, 0x5d, +0x04, 0x00, 0x0a, 0x67, 0x4a, 0x25, 0x55, 0x55, 0x50, 0x1a, +0x14, 0x3d, 0x4a, 0x06, 0x05, 0x0f, 0x4d, 0x00, 0x3f, 0xcc, +0x17, 0x39, 0x11, 0x33, 0x11, 0x33, 0x01, 0x2f, 0xcc, 0x17, +0x39, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x33, 0x33, 0x31, +0x30, 0x01, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, +0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x05, 0x22, 0x06, +0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x17, +0x06, 0x06, 0x17, 0x16, 0x16, 0x37, 0x36, 0x36, 0x27, 0x26, +0x26, 0x27, 0x34, 0x36, 0x37, 0x27, 0x06, 0x06, 0x07, 0x16, +0x15, 0x14, 0x07, 0x16, 0x17, 0x37, 0x26, 0x26, 0x37, 0x32, +0x16, 0x17, 0x37, 0x26, 0x26, 0x27, 0x06, 0x27, 0x26, 0x27, +0x26, 0x23, 0x22, 0x07, 0x17, 0x36, 0x17, 0x22, 0x27, 0x07, +0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x17, 0x36, 0x36, +0x37, 0x27, 0x06, 0x06, 0x37, 0x16, 0x36, 0x37, 0x36, 0x26, +0x27, 0x26, 0x06, 0x07, 0x06, 0x16, 0x01, 0xbb, 0x1e, 0x35, +0x46, 0x28, 0x28, 0x46, 0x34, 0x1e, 0x1e, 0x34, 0x46, 0x28, +0x28, 0x46, 0x35, 0x1e, 0xfe, 0xbd, 0x0b, 0x0f, 0x0f, 0x0b, +0x0b, 0x0f, 0x0f, 0xac, 0x09, 0x06, 0x05, 0x06, 0x14, 0x0a, +0x09, 0x05, 0x05, 0x06, 0x14, 0x89, 0x12, 0x0f, 0x14, 0x11, +0x18, 0x05, 0x0e, 0x0e, 0x0b, 0x23, 0x14, 0x0f, 0x12, 0x4b, +0x1e, 0x2a, 0x03, 0x25, 0x02, 0x12, 0x0e, 0x0f, 0x10, 0x10, +0x01, 0x0c, 0x12, 0x1b, 0x16, 0x12, 0x10, 0x0f, 0x0f, 0x10, +0x12, 0x16, 0x1b, 0x12, 0x0c, 0x01, 0x10, 0x10, 0x0f, 0x0e, +0x12, 0x02, 0x25, 0x03, 0x2a, 0x17, 0x09, 0x14, 0x06, 0x05, +0x05, 0x09, 0x0a, 0x14, 0x06, 0x05, 0x06, 0x01, 0xf4, 0x28, +0x46, 0x34, 0x1e, 0x1e, 0x34, 0x46, 0x28, 0x28, 0x46, 0x35, +0x1e, 0x1e, 0x35, 0x46, 0x0e, 0x0f, 0x0b, 0x0a, 0x0f, 0x0f, +0x0a, 0x0b, 0x0f, 0x75, 0x05, 0x14, 0x0a, 0x09, 0x06, 0x06, +0x05, 0x15, 0x09, 0x0a, 0x04, 0x56, 0x14, 0x1f, 0x0b, 0x20, +0x0c, 0x22, 0x14, 0x09, 0x13, 0x11, 0x0b, 0x27, 0x1a, 0x20, +0x0b, 0x1f, 0x5f, 0x28, 0x1d, 0x01, 0x15, 0x25, 0x0e, 0x05, +0x07, 0x0a, 0x10, 0x04, 0x0c, 0x1f, 0x07, 0x97, 0x07, 0x1f, +0x0c, 0x04, 0x10, 0x0a, 0x07, 0x05, 0x0e, 0x25, 0x15, 0x01, +0x1d, 0x28, 0xa7, 0x06, 0x05, 0x0a, 0x09, 0x15, 0x05, 0x05, +0x06, 0x08, 0x0b, 0x13, 0x00, 0x0e, 0xff, 0x5b, 0x00, 0x00, +0x02, 0x99, 0x02, 0xb4, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, +0x00, 0x0f, 0x00, 0x13, 0x00, 0x17, 0x00, 0x1b, 0x00, 0x1f, +0x00, 0x23, 0x00, 0x27, 0x00, 0x2b, 0x00, 0x2f, 0x00, 0x33, +0x00, 0x37, 0x07, 0xaf, 0x40, 0x1f, 0x33, 0x10, 0x09, 0x00, +0x4d, 0x32, 0x18, 0x09, 0x00, 0x4d, 0x2b, 0x08, 0x09, 0x00, +0x4d, 0x2a, 0x08, 0x09, 0x00, 0x4d, 0x27, 0x10, 0x09, 0x00, +0x4d, 0x26, 0x10, 0x09, 0x00, 0x4d, 0x23, 0xb8, 0xff, 0xf0, +0xb3, 0x09, 0x00, 0x4d, 0x22, 0xb8, 0xff, 0xf8, 0x40, 0x0e, +0x09, 0x00, 0x4d, 0x21, 0x10, 0x09, 0x00, 0x4d, 0x20, 0x08, +0x09, 0x00, 0x4d, 0x1e, 0xb8, 0xff, 0xf8, 0x40, 0xb9, 0x09, +0x00, 0x4d, 0x1d, 0x10, 0x09, 0x00, 0x4d, 0x1c, 0x18, 0x09, +0x00, 0x4d, 0x06, 0x1b, 0x26, 0x1b, 0x36, 0x1b, 0x46, 0x1b, +0x66, 0x1b, 0x86, 0x1b, 0x06, 0x3d, 0x07, 0x1b, 0x01, 0x09, +0x06, 0x1a, 0x26, 0x1a, 0x36, 0x1a, 0x46, 0x1a, 0x66, 0x1a, +0x86, 0x1a, 0x06, 0x3d, 0x07, 0x1a, 0x01, 0x09, 0x06, 0x13, +0x16, 0x13, 0x26, 0x13, 0x66, 0x13, 0x04, 0x06, 0x12, 0x16, +0x12, 0x26, 0x12, 0x66, 0x12, 0x04, 0x3d, 0x09, 0x05, 0x01, +0x09, 0x04, 0x01, 0x3e, 0x09, 0x01, 0x19, 0x01, 0x02, 0x09, +0x00, 0x19, 0x00, 0x02, 0x41, 0x07, 0x26, 0x01, 0x07, 0x25, +0x01, 0x07, 0x22, 0x01, 0x07, 0x21, 0x01, 0x09, 0x1f, 0x01, +0x09, 0x1c, 0x78, 0x09, 0x49, 0x09, 0x17, 0x69, 0x17, 0x02, +0x09, 0x14, 0x69, 0x14, 0x02, 0x06, 0x0e, 0x36, 0x0e, 0x66, +0x0e, 0x03, 0x06, 0x0d, 0x36, 0x0d, 0x66, 0x0d, 0x03, 0x09, +0x0b, 0x39, 0x0b, 0x02, 0x09, 0x08, 0x39, 0x08, 0x02, 0x3d, +0x9a, 0x31, 0xaa, 0x31, 0x02, 0x69, 0x31, 0x79, 0x31, 0x89, +0x31, 0x03, 0x31, 0x40, 0x0a, 0x0e, 0x48, 0x0a, 0x31, 0x01, +0x31, 0x2f, 0x80, 0x34, 0x3b, 0x48, 0x2f, 0x7f, 0x28, 0x8f, +0x28, 0x02, 0x5e, 0x28, 0x6e, 0x28, 0x02, 0x4d, 0x28, 0x01, +0x3e, 0x28, 0x01, 0x28, 0xb8, 0x01, 0x80, 0x40, 0x4e, 0x28, +0x2b, 0x48, 0x9a, 0x28, 0xaa, 0x28, 0x02, 0x69, 0x28, 0x79, +0x28, 0x89, 0x28, 0x03, 0x28, 0x40, 0x0a, 0x0e, 0x48, 0x28, +0xb0, 0x09, 0x49, 0x28, 0x24, 0x80, 0x34, 0x3b, 0x48, 0x7f, +0x24, 0x8f, 0x24, 0x02, 0x5e, 0x24, 0x6e, 0x24, 0x02, 0x4d, +0x24, 0x01, 0x2e, 0x24, 0x3e, 0x24, 0x02, 0x0d, 0x24, 0x1d, +0x24, 0x02, 0xfd, 0x24, 0x01, 0x9a, 0x24, 0xaa, 0x24, 0x02, +0x69, 0x24, 0x79, 0x24, 0x89, 0x24, 0x03, 0x24, 0x40, 0x0a, +0x0e, 0x48, 0x0a, 0x24, 0x01, 0x24, 0x36, 0xb8, 0xff, 0x80, +0x40, 0x09, 0x34, 0x3b, 0x48, 0x07, 0x36, 0x01, 0x36, 0x35, +0x32, 0xb8, 0xff, 0x80, 0x40, 0x0c, 0x0d, 0x13, 0x48, 0x17, +0x32, 0x27, 0x32, 0x37, 0x32, 0x03, 0x32, 0x2b, 0xb8, 0xfe, +0x00, 0x40, 0x13, 0x2d, 0x31, 0x48, 0x31, 0x2b, 0x01, 0x20, +0x2b, 0x01, 0x01, 0x2b, 0x11, 0x2b, 0x02, 0xf1, 0x2b, 0x01, +0x00, 0x2b, 0xb8, 0xff, 0x80, 0x40, 0x0c, 0x0d, 0x13, 0x48, +0x10, 0x2b, 0x20, 0x2b, 0x30, 0x2b, 0x03, 0x2b, 0x27, 0xb8, +0xfe, 0x00, 0xb3, 0x2d, 0x31, 0x48, 0x27, 0xb8, 0xfe, 0x40, +0xb3, 0x28, 0x2c, 0x48, 0x27, 0xb8, 0xff, 0x80, 0x40, 0xff, +0x0d, 0x13, 0x48, 0x10, 0x27, 0x20, 0x27, 0x30, 0x27, 0x03, +0x27, 0x1c, 0x0c, 0x20, 0x01, 0x09, 0x03, 0x20, 0x22, 0x2f, +0x15, 0x8f, 0x15, 0x02, 0x09, 0x15, 0x01, 0x3b, 0x8f, 0x15, +0x9f, 0x15, 0xff, 0x15, 0x03, 0x5e, 0x15, 0x01, 0xbd, 0x15, +0xed, 0x15, 0xfd, 0x15, 0x03, 0x5b, 0x15, 0x01, 0x4c, 0x15, +0x01, 0x1b, 0x15, 0x01, 0xaa, 0x15, 0xba, 0x15, 0x02, 0x79, +0x15, 0x01, 0x08, 0x15, 0x18, 0x15, 0x02, 0x0a, 0x15, 0x09, +0x13, 0x01, 0x3b, 0x13, 0x0f, 0x0c, 0x3f, 0x0c, 0x6f, 0x0c, +0x03, 0x3d, 0x4f, 0x0c, 0x8f, 0x0c, 0xbf, 0x0c, 0xef, 0x0c, +0x04, 0x1e, 0x0c, 0x01, 0xad, 0x0c, 0xed, 0x0c, 0x02, 0x7b, +0x0c, 0x01, 0x4c, 0x0c, 0x01, 0x0b, 0x0c, 0x01, 0xaa, 0x0c, +0xda, 0x0c, 0x02, 0x39, 0x0c, 0x69, 0x0c, 0x02, 0x08, 0x0c, +0x01, 0x0b, 0x0c, 0x2f, 0x08, 0x5f, 0x08, 0x02, 0x09, 0x08, +0x01, 0x3b, 0xe9, 0x08, 0x01, 0x8f, 0x08, 0xbf, 0x08, 0x02, +0x1e, 0x08, 0x01, 0xed, 0x08, 0x01, 0x7b, 0x08, 0x01, 0x4c, +0x08, 0x01, 0xaa, 0x08, 0xda, 0x08, 0x02, 0x08, 0x08, 0x38, +0x08, 0x02, 0x0b, 0x08, 0x66, 0x1a, 0x86, 0x1a, 0x02, 0x07, +0x1a, 0x01, 0x33, 0x1a, 0x19, 0x00, 0x17, 0x60, 0x17, 0x02, +0x3d, 0x50, 0x17, 0x80, 0x17, 0x90, 0x17, 0xf0, 0x17, 0x04, +0xe1, 0x17, 0xf1, 0x17, 0x02, 0xb2, 0x17, 0x01, 0x53, 0x17, +0x01, 0x14, 0x17, 0x44, 0x17, 0x02, 0xb5, 0x17, 0x01, 0x76, +0x17, 0xa6, 0x17, 0x02, 0x07, 0x17, 0x17, 0x17, 0x02, 0x0a, +0x17, 0x00, 0x0f, 0x30, 0x0f, 0x60, 0x0f, 0x03, 0x3d, 0x80, +0x0f, 0xb0, 0x0f, 0xe0, 0x0f, 0x03, 0x11, 0x0f, 0x41, 0x0f, +0x02, 0xe1, 0x0f, 0x01, 0x72, 0x0f, 0xa2, 0x0f, 0x02, 0x04, +0x0f, 0x44, 0x0f, 0x02, 0xd4, 0x40, 0x3e, 0x0f, 0x01, 0xa5, +0x0f, 0x01, 0x66, 0x0f, 0x01, 0x07, 0x0f, 0x37, 0x0f, 0x02, +0x0b, 0x0f, 0x00, 0x0a, 0x30, 0x0a, 0x02, 0x3d, 0x90, 0x0a, +0xc0, 0x0a, 0x02, 0x21, 0x0a, 0x01, 0xf1, 0x0a, 0x01, 0x82, +0x0a, 0x01, 0x54, 0x0a, 0x01, 0xe4, 0x0a, 0x01, 0xb5, 0x0a, +0x01, 0x46, 0x0a, 0x01, 0x17, 0x0a, 0x01, 0x0a, 0x00, 0x04, +0x39, 0xe6, 0x03, 0x01, 0x03, 0x06, 0x10, 0x19, 0x1f, 0xb8, +0xff, 0x80, 0x40, 0x09, 0x34, 0x45, 0x48, 0x1f, 0x22, 0x2c, +0x35, 0x38, 0x35, 0xb8, 0xfe, 0x00, 0x40, 0x3b, 0x31, 0x3b, +0x48, 0x61, 0x35, 0x01, 0x40, 0x35, 0x50, 0x35, 0x02, 0x21, +0x35, 0x31, 0x35, 0x02, 0x10, 0x35, 0x01, 0x01, 0x35, 0x01, +0xe1, 0x35, 0xf1, 0x35, 0x02, 0xb2, 0x35, 0xc2, 0x35, 0xd2, +0x35, 0x03, 0x93, 0x35, 0xa3, 0x35, 0x02, 0x82, 0x35, 0x01, +0x63, 0x35, 0x73, 0x35, 0x02, 0x54, 0x35, 0x01, 0x43, 0x35, +0x01, 0x00, 0x92, 0x35, 0x01, 0x01, 0x35, 0xb8, 0xff, 0x80, +0x40, 0x12, 0x0e, 0x12, 0x48, 0x33, 0x35, 0x01, 0x02, 0x10, +0x35, 0x20, 0x35, 0x02, 0x08, 0x35, 0x01, 0x03, 0x35, 0x22, +0xb8, 0xff, 0x00, 0x40, 0x16, 0x18, 0x1d, 0x48, 0xb5, 0x22, +0xc5, 0x22, 0xd5, 0x22, 0x03, 0xa6, 0x22, 0x01, 0x22, 0x58, +0x33, 0x01, 0x33, 0xdd, 0x2c, 0x01, 0x2c, 0xb8, 0x01, 0x40, +0x40, 0x0c, 0x20, 0x26, 0x48, 0x4b, 0x2c, 0x5b, 0x2c, 0x02, +0x3c, 0x2c, 0x01, 0x2c, 0xb8, 0x01, 0x00, 0x40, 0x1c, 0x17, +0x1c, 0x48, 0xaa, 0x2c, 0xba, 0x2c, 0xca, 0x2c, 0x03, 0x2c, +0x80, 0x10, 0x13, 0x48, 0x5a, 0x2c, 0x01, 0x49, 0x2c, 0x01, +0x2c, 0x40, 0x0a, 0x0d, 0x48, 0x2c, 0x1f, 0xb8, 0x02, 0x00, +0xb7, 0x32, 0x45, 0x48, 0x1f, 0x31, 0x31, 0x26, 0x34, 0xb8, +0x02, 0x00, 0xb3, 0x30, 0x3b, 0x48, 0x34, 0xb8, 0x01, 0xc0, +0xb3, 0x2c, 0x2f, 0x48, 0x34, 0xb8, 0x01, 0x80, 0x40, 0x33, +0x23, 0x2b, 0x48, 0x7c, 0x34, 0x8c, 0x34, 0x02, 0x6b, 0x34, +0x01, 0x5c, 0x34, 0x01, 0x4b, 0x34, 0x01, 0x34, 0x80, 0x10, +0x13, 0x48, 0x5a, 0x34, 0x01, 0x34, 0x40, 0x0a, 0x0e, 0x48, +0x34, 0x1b, 0x23, 0x2b, 0x23, 0x3b, 0x23, 0x03, 0x23, 0xc0, +0x14, 0x1a, 0x48, 0x23, 0x57, 0x29, 0x01, 0x29, 0x2b, 0x5b, +0x2d, 0xb8, 0xfe, 0x80, 0xb3, 0x24, 0x27, 0x48, 0x2d, 0xb8, +0xfe, 0xc0, 0xb3, 0x1e, 0x23, 0x48, 0x2d, 0xb8, 0xff, 0x00, +0xb3, 0x1a, 0x1d, 0x48, 0x2d, 0xb8, 0xff, 0x40, 0xb3, 0x11, +0x19, 0x48, 0x2d, 0xb8, 0xff, 0x80, 0x40, 0x0d, 0x0d, 0x10, +0x48, 0x07, 0x2d, 0x17, 0x2d, 0x27, 0x2d, 0x03, 0x0a, 0x2d, +0x1e, 0xb8, 0xfe, 0x00, 0x40, 0xae, 0x32, 0x45, 0x48, 0x1e, +0x08, 0x24, 0x01, 0x0f, 0x24, 0x26, 0x59, 0x20, 0x19, 0x40, +0x19, 0x50, 0x19, 0x60, 0x19, 0x80, 0x19, 0xa0, 0x19, 0x06, +0x17, 0x19, 0x01, 0x00, 0x19, 0x01, 0x3b, 0xc0, 0x19, 0xe0, +0x19, 0x02, 0xb1, 0x19, 0x01, 0x60, 0x19, 0x80, 0x19, 0xa0, +0x19, 0x03, 0x01, 0x19, 0x11, 0x19, 0x21, 0x19, 0x41, 0x19, +0x04, 0xe1, 0x19, 0x01, 0xa2, 0x19, 0xc2, 0x19, 0x02, 0x83, +0x19, 0x01, 0x72, 0x19, 0x01, 0x63, 0x19, 0x01, 0x04, 0x19, +0x24, 0x19, 0x44, 0x19, 0x03, 0xa5, 0x19, 0xc5, 0x19, 0xd5, +0x19, 0xe5, 0x19, 0x04, 0x66, 0x19, 0x86, 0x19, 0x02, 0x47, +0x19, 0x01, 0x36, 0x19, 0x01, 0x07, 0x19, 0x01, 0x0b, 0x19, +0x20, 0x06, 0x01, 0x07, 0x06, 0x01, 0x3c, 0xd6, 0x06, 0x01, +0x80, 0x06, 0x01, 0x77, 0x06, 0x01, 0xe1, 0x06, 0x01, 0x43, +0x06, 0x01, 0xa5, 0x06, 0x01, 0x07, 0x06, 0x01, 0x0c, 0x06, +0x69, 0x17, 0x99, 0x17, 0x02, 0x08, 0x17, 0x01, 0x33, 0x17, +0x1f, 0x10, 0x2f, 0x10, 0x3f, 0x10, 0x7f, 0x10, 0x04, 0x08, +0x10, 0x01, 0x3c, 0xaf, 0x10, 0xef, 0x10, 0x02, 0x9e, 0x10, +0x01, 0x4f, 0x10, 0x8f, 0x10, 0x02, 0x0d, 0x10, 0x01, 0x10, +0xb8, 0x01, 0x60, 0x40, 0xff, 0x2a, 0x49, 0x4c, 0x10, 0x5c, +0x10, 0x6c, 0x10, 0xac, 0x10, 0xec, 0x10, 0x05, 0x0b, 0x10, +0x01, 0xcb, 0x10, 0x01, 0xaa, 0x10, 0xba, 0x10, 0x02, 0x19, +0x10, 0x29, 0x10, 0x69, 0x10, 0x03, 0x08, 0x10, 0x01, 0x0b, +0x10, 0x0f, 0x03, 0x1f, 0x03, 0x02, 0x41, 0xd8, 0x03, 0x01, +0x8f, 0x03, 0x9f, 0x03, 0x02, 0xfd, 0x03, 0x01, 0xee, 0x03, +0x01, 0x4c, 0x03, 0x5c, 0x03, 0x02, 0xbb, 0x03, 0x01, 0xaa, +0x03, 0x01, 0x09, 0x03, 0x19, 0x03, 0x02, 0x0f, 0x03, 0x17, +0x15, 0x01, 0x15, 0x15, 0x0a, 0x0f, 0x18, 0x2f, 0x18, 0x4f, +0x18, 0x5f, 0x18, 0x6f, 0x18, 0x8f, 0x18, 0xaf, 0x18, 0x07, +0x3b, 0xbf, 0x18, 0xcf, 0x18, 0xef, 0x18, 0x03, 0xae, 0x18, +0x01, 0x4f, 0x18, 0x6f, 0x18, 0x8f, 0x18, 0x03, 0x0e, 0x18, +0x1e, 0x18, 0x2e, 0x18, 0x03, 0x8d, 0x18, 0xad, 0x18, 0xcd, +0x18, 0xed, 0x18, 0x04, 0x4c, 0x18, 0x6c, 0x18, 0x7c, 0x18, +0x03, 0x0b, 0x18, 0x2b, 0x18, 0x02, 0xdb, 0x18, 0xeb, 0x18, +0x02, 0x8a, 0x18, 0xaa, 0x18, 0xca, 0x18, 0x03, 0x49, 0x18, +0x69, 0x18, 0x02, 0x38, 0x18, 0x01, 0x29, 0x18, 0x01, 0x08, +0x18, 0x01, 0x0b, 0x18, 0x0f, 0x07, 0x01, 0x3e, 0xd9, 0x07, +0x01, 0x8e, 0x07, 0x01, 0x78, 0x07, 0x01, 0xed, 0x07, 0x01, +0x4b, 0x07, 0x01, 0xaa, 0x07, 0x01, 0x08, 0x07, 0x01, 0x0c, +0x07, 0x66, 0x0d, 0x01, 0x07, 0x0d, 0x01, 0x33, 0x0d, 0x0f, +0x5b, 0x00, 0x11, 0x10, 0x11, 0x20, 0x11, 0x60, 0x11, 0x04, +0x3d, 0x80, 0x11, 0x90, 0x11, 0xa0, 0x11, 0xe0, 0x11, 0x04, +0x01, 0x11, 0x41, 0x11, 0x02, 0xe1, 0x11, 0xf1, 0x11, 0x02, +0xa2, 0x11, 0x01, 0x53, 0x11, 0x63, 0x11, 0x02, 0x04, 0x11, +0x44, 0x11, 0x02, 0x65, 0x11, 0xa5, 0x11, 0xb5, 0x11, 0xc5, +0x40, 0x39, 0x11, 0x04, 0x07, 0x11, 0x17, 0x11, 0x27, 0x11, +0x03, 0x0b, 0x11, 0x00, 0x02, 0x10, 0x02, 0x02, 0x41, 0xe0, +0x02, 0xf0, 0x02, 0x02, 0xa7, 0x02, 0x01, 0x50, 0x02, 0x01, +0x41, 0x02, 0x01, 0xb2, 0x02, 0x01, 0xa3, 0x02, 0x01, 0x00, +0x00, 0x02, 0x10, 0x02, 0x02, 0x01, 0x60, 0x02, 0x70, 0x02, +0x02, 0x02, 0x02, 0xaf, 0x08, 0x01, 0x08, 0x0a, 0x59, 0x00, +0x3f, 0xcd, 0x72, 0x32, 0x5f, 0x5d, 0x5f, 0x71, 0x5f, 0x71, +0x71, 0x72, 0x72, 0x72, 0x72, 0x5e, 0x5d, 0x32, 0x5e, 0x5d, +0x5d, 0x71, 0x71, 0x71, 0x71, 0x72, 0x72, 0x5e, 0x5d, 0x3f, +0xcd, 0x5e, 0x5d, 0x5d, 0x32, 0x5e, 0x5d, 0x5d, 0x71, 0x71, +0x72, 0x72, 0x72, 0x5e, 0x5d, 0x32, 0x5e, 0x5d, 0x5d, 0x5d, +0x5d, 0x5d, 0x5d, 0x71, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, +0x5e, 0x5d, 0x12, 0x39, 0x2f, 0x5d, 0x33, 0x5e, 0x5d, 0x5d, +0x5d, 0x71, 0x71, 0x71, 0x72, 0x72, 0x5e, 0x5d, 0x33, 0x5e, +0x5d, 0x5d, 0x5d, 0x5d, 0x71, 0x71, 0x2b, 0x72, 0x72, 0x72, +0x72, 0x5e, 0x5d, 0x5d, 0xcd, 0x5e, 0x5d, 0x5d, 0x32, 0x5e, +0x5d, 0x5d, 0x71, 0x71, 0x72, 0x72, 0x72, 0x5e, 0x5d, 0x5d, +0x32, 0x5e, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x71, 0x71, 0x71, +0x71, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, 0x5e, 0x5d, 0x5d, +0x5d, 0x3f, 0xcd, 0x5e, 0x5d, 0x32, 0x2b, 0x32, 0x5e, 0x5d, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x3f, 0xcd, 0x5d, 0x32, 0x2b, +0x71, 0x32, 0x2b, 0x5d, 0x2b, 0x71, 0x71, 0x71, 0x71, 0x2b, +0x2b, 0x2b, 0x12, 0x39, 0x2f, 0x33, 0x2b, 0x33, 0x2b, 0x5d, +0x5d, 0x2b, 0x5d, 0x2b, 0x71, 0x71, 0x2b, 0x71, 0xcd, 0x5d, +0x32, 0x5d, 0x5d, 0x2b, 0x32, 0x5f, 0x5d, 0x5d, 0x5f, 0x5d, +0x2b, 0x5f, 0x5d, 0x5f, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, +0x71, 0x72, 0x72, 0x72, 0x72, 0x72, 0x2b, 0x01, 0x10, 0xdc, +0x32, 0xdc, 0x32, 0x2b, 0xde, 0x32, 0xdc, 0x32, 0x72, 0xcc, +0xcd, 0x32, 0x32, 0x5d, 0x5d, 0x5d, 0x5d, 0x71, 0x71, 0x71, +0x72, 0x72, 0x5e, 0x5d, 0x32, 0x5e, 0x5d, 0x5d, 0x5d, 0x5d, +0x71, 0x71, 0x71, 0x72, 0x72, 0x5e, 0x5d, 0x32, 0x5e, 0x5d, +0x5d, 0x5d, 0x71, 0x71, 0x71, 0x71, 0x72, 0x5e, 0x5d, 0x10, +0xcd, 0x5e, 0x5d, 0x5d, 0x32, 0x5e, 0x5d, 0x5d, 0x71, 0x71, +0x71, 0x72, 0x72, 0x72, 0x5e, 0x5d, 0x5d, 0x32, 0x5e, 0x5d, +0x5d, 0x5d, 0x71, 0x71, 0x71, 0x71, 0x72, 0x72, 0x5e, 0x5d, +0x32, 0x5e, 0x5d, 0x32, 0x5e, 0x5d, 0x5d, 0x5d, 0x71, 0x71, +0x71, 0x71, 0x72, 0x72, 0x5e, 0x5d, 0x5d, 0x10, 0xcd, 0x5f, +0x5e, 0x5d, 0x32, 0x32, 0x5d, 0x2b, 0x2b, 0x2b, 0x32, 0x5d, +0x2b, 0x5f, 0x71, 0x72, 0x72, 0x72, 0x2b, 0x32, 0x5d, 0x2b, +0x10, 0xcd, 0x5d, 0x2b, 0x32, 0x5d, 0x2b, 0x5d, 0x5d, 0x71, +0x72, 0x72, 0x72, 0x72, 0x72, 0x2b, 0x32, 0x2b, 0x2b, 0x5d, +0x5d, 0x2b, 0x72, 0x72, 0x72, 0x72, 0x32, 0x2b, 0x32, 0x5d, +0x2b, 0x5d, 0x5d, 0x31, 0x30, 0x00, 0x5e, 0x5d, 0x5d, 0x5d, +0x5d, 0x5d, 0x5d, 0x2b, 0x5e, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, +0x01, 0x5e, 0x5d, 0x5d, 0x5e, 0x5d, 0x5d, 0x5e, 0x5d, 0x5d, +0x5e, 0x5d, 0x5e, 0x5d, 0x5e, 0x5d, 0x5e, 0x5d, 0x2b, 0x2b, +0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, +0x2b, 0x01, 0x11, 0x33, 0x11, 0x03, 0x11, 0x33, 0x11, 0x01, +0x35, 0x21, 0x15, 0x01, 0x35, 0x21, 0x15, 0x01, 0x11, 0x33, +0x11, 0x15, 0x35, 0x21, 0x15, 0x01, 0x11, 0x33, 0x11, 0x03, +0x11, 0x33, 0x11, 0x03, 0x11, 0x33, 0x11, 0x01, 0x35, 0x21, +0x15, 0x01, 0x35, 0x21, 0x15, 0x01, 0x11, 0x33, 0x11, 0x15, +0x35, 0x21, 0x15, 0x01, 0x11, 0x33, 0x11, 0x02, 0x7c, 0x1d, +0x1d, 0x1d, 0xfe, 0xaf, 0x01, 0x34, 0xfe, 0xcc, 0x01, 0x34, +0xfe, 0xaf, 0x1d, 0x01, 0x34, 0xfe, 0xaf, 0x1d, 0x9b, 0x1c, +0x1c, 0x1c, 0xfe, 0xaf, 0x01, 0x35, 0xfe, 0xcb, 0x01, 0x35, +0xfe, 0xae, 0x1d, 0x01, 0x35, 0xfe, 0xae, 0x1d, 0x01, 0x6b, +0x01, 0x2a, 0xfe, 0xd6, 0xfe, 0xb4, 0x01, 0x2a, 0xfe, 0xd6, +0x02, 0x79, 0x1c, 0x1c, 0xfd, 0x68, 0x1d, 0x1d, 0x01, 0x6b, +0x01, 0x2a, 0xfe, 0xd6, 0x1f, 0x1d, 0x1d, 0xfe, 0xd3, 0x01, +0x2a, 0xfe, 0xd6, 0x01, 0x4c, 0x01, 0x2a, 0xfe, 0xd6, 0xfe, +0xb4, 0x01, 0x2a, 0xfe, 0xd6, 0x02, 0x79, 0x1c, 0x1c, 0xfd, +0x68, 0x1d, 0x1d, 0x01, 0x6b, 0x01, 0x2a, 0xfe, 0xd6, 0x1f, +0x1d, 0x1d, 0xfe, 0xd3, 0x01, 0x2a, 0xfe, 0xd6, 0x00, 0x00, +0x00, 0x03, 0x00, 0x04, 0xff, 0xf3, 0x01, 0xf0, 0x01, 0xde, +0x00, 0x03, 0x00, 0x1d, 0x00, 0x29, 0x00, 0x32, 0x40, 0x16, +0x17, 0x09, 0x21, 0x27, 0x04, 0x1c, 0x11, 0x27, 0x27, 0x02, +0x00, 0x14, 0x0e, 0x04, 0x24, 0x1e, 0x0e, 0x1e, 0x0e, 0x1e, +0x01, 0x03, 0x00, 0x2f, 0xcc, 0x39, 0x39, 0x2f, 0x2f, 0x10, +0xde, 0xcd, 0x10, 0xce, 0x01, 0x2f, 0xcc, 0x39, 0x2f, 0xcd, +0xd4, 0xce, 0x10, 0xde, 0xdc, 0xce, 0x31, 0x30, 0x37, 0x37, +0x17, 0x07, 0x37, 0x34, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, +0x23, 0x22, 0x06, 0x07, 0x17, 0x36, 0x33, 0x32, 0x16, 0x15, +0x14, 0x0e, 0x02, 0x15, 0x17, 0x17, 0x32, 0x36, 0x35, 0x34, +0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x04, 0xf6, 0xf6, +0xf6, 0x14, 0x18, 0x1c, 0x17, 0x09, 0x15, 0x23, 0x19, 0x15, +0x2c, 0x12, 0x11, 0x1d, 0x1d, 0x12, 0x15, 0x17, 0x1b, 0x16, +0x01, 0x1f, 0x0e, 0x15, 0x15, 0x0e, 0x10, 0x16, 0x16, 0xe8, +0xf6, 0xf6, 0xf5, 0xb1, 0x16, 0x21, 0x1d, 0x20, 0x16, 0x0c, +0x1b, 0x15, 0x0e, 0x0b, 0x0c, 0x2e, 0x11, 0x0d, 0x0f, 0x10, +0x18, 0x1b, 0x20, 0x17, 0x0a, 0x69, 0x14, 0x11, 0x11, 0x15, +0x15, 0x11, 0x11, 0x14, 0x00, 0x00, 0xff, 0xff, 0xff, 0xde, +0xff, 0xf4, 0x02, 0x13, 0x02, 0x79, 0x00, 0x27, 0x01, 0x6f, +0xff, 0x6a, 0x00, 0x00, 0x00, 0x26, 0x00, 0x11, 0x00, 0x00, +0x01, 0x07, 0x01, 0x74, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x22, 0x01, 0x22, +0x03, 0x3e, 0x00, 0x05, 0x00, 0x11, 0xb5, 0x04, 0x01, 0x00, +0x02, 0x05, 0x00, 0x00, 0x2f, 0xcd, 0x2f, 0x01, 0x2f, 0x2f, +0xcd, 0x31, 0x30, 0x11, 0x33, 0x11, 0x33, 0x11, 0x21, 0xd2, +0x50, 0xfe, 0xde, 0x01, 0x72, 0x01, 0xcc, 0xfd, 0xe4, 0x00, +0x00, 0x01, 0x00, 0xd2, 0x01, 0x22, 0x01, 0xf4, 0x03, 0x3e, +0x00, 0x05, 0x00, 0x11, 0xb5, 0x02, 0x05, 0x03, 0x05, 0x02, +0x00, 0x00, 0x2f, 0x2f, 0xcd, 0x01, 0x2f, 0x2f, 0xcd, 0x31, +0x30, 0x13, 0x33, 0x11, 0x33, 0x15, 0x21, 0xd2, 0x50, 0xd2, +0xfe, 0xde, 0x03, 0x3e, 0xfe, 0x34, 0x50, 0x00, 0x00, 0x01, +0x00, 0xd2, 0xff, 0x56, 0x01, 0xf4, 0x01, 0x72, 0x00, 0x05, +0x00, 0x11, 0xb5, 0x02, 0x03, 0x00, 0x05, 0x03, 0x00, 0x00, +0x2f, 0xcd, 0x2f, 0x01, 0x2f, 0xcd, 0x2f, 0x31, 0x30, 0x13, +0x21, 0x15, 0x23, 0x11, 0x23, 0xd2, 0x01, 0x22, 0xd2, 0x50, +0x01, 0x72, 0x50, 0xfe, 0x34, 0x00, 0x00, 0x01, 0x00, 0xd2, +0xff, 0x56, 0x01, 0x22, 0x03, 0x3e, 0x00, 0x03, 0x00, 0x0d, +0xb3, 0x03, 0x02, 0x02, 0x01, 0x00, 0x2f, 0x2f, 0x01, 0x2f, +0xcd, 0x31, 0x30, 0x05, 0x23, 0x11, 0x33, 0x01, 0x22, 0x50, +0x50, 0xaa, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +0x01, 0x22, 0x01, 0xf4, 0x01, 0x72, 0x00, 0x03, 0x00, 0x0d, +0xb3, 0x02, 0x01, 0x00, 0x01, 0x00, 0x2f, 0xcd, 0x01, 0x2f, +0x2f, 0x31, 0x30, 0x11, 0x35, 0x21, 0x15, 0x01, 0xf4, 0x01, +0x22, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +0xff, 0x56, 0x01, 0x22, 0x03, 0x3e, 0x00, 0x07, 0x00, 0x15, +0xb7, 0x07, 0x02, 0x05, 0x04, 0x06, 0x03, 0x04, 0x01, 0x00, +0x2f, 0x2f, 0xcd, 0x2f, 0x01, 0x2f, 0x2f, 0x33, 0xcd, 0x31, +0x30, 0x05, 0x23, 0x11, 0x23, 0x35, 0x33, 0x11, 0x33, 0x01, +0x22, 0x50, 0xd2, 0xd2, 0x50, 0xaa, 0x01, 0xcc, 0x50, 0x01, +0xcc, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x56, 0x01, 0xf4, +0x01, 0x72, 0x00, 0x07, 0x00, 0x15, 0xb7, 0x06, 0x02, 0x05, +0x01, 0x02, 0x05, 0x07, 0x04, 0x00, 0x2f, 0x2f, 0xcd, 0x32, +0x01, 0x2f, 0x2f, 0xcd, 0x2f, 0x31, 0x30, 0x01, 0x15, 0x23, +0x11, 0x23, 0x11, 0x23, 0x35, 0x01, 0xf4, 0xd2, 0x50, 0xd2, +0x01, 0x72, 0x50, 0xfe, 0x34, 0x01, 0xcc, 0x50, 0x00, 0x01, +0x00, 0x00, 0x01, 0x22, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x07, +0x00, 0x15, 0xb7, 0x06, 0x05, 0x02, 0x01, 0x03, 0x05, 0x00, +0x01, 0x00, 0x2f, 0xcd, 0x33, 0x2f, 0x01, 0x2f, 0x2f, 0xcd, +0x2f, 0x31, 0x30, 0x11, 0x35, 0x33, 0x11, 0x33, 0x11, 0x33, +0x15, 0xd2, 0x50, 0xd2, 0x01, 0x22, 0x50, 0x01, 0xcc, 0xfe, +0x34, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd2, 0xff, 0x56, +0x01, 0xf4, 0x03, 0x3e, 0x00, 0x07, 0x00, 0x15, 0xb7, 0x03, +0x05, 0x01, 0x00, 0x07, 0x05, 0x02, 0x00, 0x00, 0x2f, 0x2f, +0xcd, 0x2f, 0x01, 0x2f, 0xcd, 0x32, 0x2f, 0x31, 0x30, 0x13, +0x33, 0x11, 0x33, 0x15, 0x23, 0x11, 0x23, 0xd2, 0x50, 0xd2, +0xd2, 0x50, 0x03, 0x3e, 0xfe, 0x34, 0x50, 0xfe, 0x34, 0x00, +0x00, 0x01, 0x00, 0x00, 0xff, 0x56, 0x01, 0xf4, 0x03, 0x3e, +0x00, 0x0b, 0x00, 0x1e, 0x40, 0x0c, 0x07, 0x09, 0x06, 0x00, +0x03, 0x02, 0x0b, 0x04, 0x09, 0x01, 0x06, 0x02, 0x00, 0x2f, +0x33, 0xcd, 0x32, 0x2f, 0x2f, 0x01, 0x2f, 0x2f, 0x33, 0xcd, +0x32, 0x2f, 0x31, 0x30, 0x13, 0x23, 0x35, 0x33, 0x11, 0x33, +0x11, 0x33, 0x15, 0x23, 0x11, 0x23, 0xd2, 0xd2, 0xd2, 0x50, +0xd2, 0xd2, 0x50, 0x01, 0x22, 0x50, 0x01, 0xcc, 0xfe, 0x34, +0x50, 0xfe, 0x34, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, +0xff, 0x56, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x07, 0x00, 0x0f, +0x00, 0x26, 0x40, 0x10, 0x08, 0x07, 0x0a, 0x05, 0x0d, 0x02, +0x0f, 0x00, 0x0a, 0x0e, 0x0f, 0x0c, 0x03, 0x05, 0x01, 0x00, +0x00, 0x2f, 0xc5, 0x32, 0x2f, 0x2f, 0x2f, 0xc5, 0x32, 0x01, +0x2f, 0xc0, 0x2f, 0x33, 0xcd, 0x32, 0x2f, 0xc0, 0x31, 0x30, +0x11, 0x35, 0x33, 0x11, 0x33, 0x11, 0x33, 0x1d, 0x02, 0x23, +0x11, 0x23, 0x11, 0x23, 0x35, 0xd2, 0x50, 0xd2, 0xd2, 0x50, +0xd2, 0x01, 0x72, 0x50, 0x01, 0x7c, 0xfe, 0x84, 0x50, 0x50, +0x50, 0xfe, 0x84, 0x01, 0x7c, 0x50, 0x00, 0x00, 0x00, 0x02, +0x00, 0x00, 0xff, 0x56, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x07, +0x00, 0x0f, 0x00, 0x26, 0x40, 0x10, 0x0b, 0x0d, 0x09, 0x08, +0x02, 0x06, 0x07, 0x04, 0x08, 0x06, 0x0d, 0x03, 0x0a, 0x04, +0x0f, 0x01, 0x00, 0x2f, 0x33, 0x2f, 0x33, 0xc5, 0x32, 0x2f, +0x33, 0x01, 0x2f, 0x2f, 0xc5, 0x32, 0x2f, 0xc5, 0x32, 0x2f, +0x31, 0x30, 0x17, 0x23, 0x11, 0x23, 0x35, 0x33, 0x11, 0x3b, +0x02, 0x11, 0x33, 0x15, 0x23, 0x11, 0x23, 0xd2, 0x50, 0x82, +0x82, 0x50, 0x50, 0x50, 0x82, 0x82, 0x50, 0xaa, 0x01, 0xcc, +0x50, 0x01, 0xcc, 0xfe, 0x34, 0x50, 0xfe, 0x34, 0x00, 0x00, +0x00, 0x01, 0x00, 0x00, 0xff, 0x56, 0x01, 0x22, 0x01, 0x72, +0x00, 0x05, 0x00, 0x11, 0xb5, 0x01, 0x04, 0x00, 0x02, 0x04, +0x01, 0x00, 0x2f, 0xc5, 0x2f, 0x01, 0x2f, 0x2f, 0xc5, 0x31, +0x30, 0x11, 0x21, 0x11, 0x23, 0x11, 0x23, 0x01, 0x22, 0x50, +0xd2, 0x01, 0x72, 0xfd, 0xe4, 0x01, 0xcc, 0x00, 0x00, 0x02, +0x00, 0x00, 0xff, 0x56, 0x01, 0x22, 0x03, 0x3e, 0x00, 0x05, +0x00, 0x0b, 0x00, 0x1e, 0x40, 0x0c, 0x07, 0x0a, 0x06, 0x04, +0x01, 0x00, 0x09, 0x0b, 0x06, 0x00, 0x05, 0x02, 0x00, 0x2f, +0x2f, 0xc5, 0x2f, 0xc5, 0x2f, 0x01, 0x2f, 0x2f, 0xc5, 0x2f, +0x2f, 0xc5, 0x31, 0x30, 0x11, 0x33, 0x11, 0x33, 0x11, 0x21, +0x15, 0x21, 0x11, 0x23, 0x11, 0x23, 0xd2, 0x50, 0xfe, 0xde, +0x01, 0x22, 0x50, 0xd2, 0x01, 0xc2, 0x01, 0x7c, 0xfe, 0x34, +0x50, 0xfe, 0x34, 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x02, +0x00, 0xd2, 0xff, 0x56, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x05, +0x00, 0x0b, 0x00, 0x1e, 0x40, 0x0c, 0x0b, 0x07, 0x0a, 0x04, +0x01, 0x00, 0x07, 0x0a, 0x09, 0x02, 0x04, 0x01, 0x00, 0x2f, +0xc5, 0x2f, 0x2f, 0x2f, 0xc5, 0x01, 0x2f, 0x2f, 0xc5, 0x2f, +0xc5, 0x2f, 0x31, 0x30, 0x01, 0x21, 0x11, 0x33, 0x11, 0x33, +0x15, 0x23, 0x11, 0x23, 0x11, 0x21, 0x01, 0xf4, 0xfe, 0xde, +0x50, 0xd2, 0xd2, 0x50, 0x01, 0x22, 0x01, 0x72, 0x01, 0xcc, +0xfe, 0x84, 0xf0, 0xfe, 0x84, 0x01, 0xcc, 0x00, 0x00, 0x02, +0x00, 0x00, 0x00, 0xd2, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x07, +0x00, 0x0b, 0x00, 0x1e, 0x40, 0x0c, 0x0b, 0x08, 0x07, 0x05, +0x02, 0x00, 0x0a, 0x0b, 0x03, 0x05, 0x02, 0x00, 0x00, 0x2f, +0xc5, 0x32, 0x2f, 0x2f, 0xc5, 0x01, 0x2f, 0x2f, 0xc5, 0x2f, +0x2f, 0x2f, 0x31, 0x30, 0x11, 0x35, 0x33, 0x11, 0x33, 0x11, +0x33, 0x1d, 0x02, 0x21, 0x35, 0xd2, 0x50, 0xd2, 0xfe, 0x0c, +0x01, 0x72, 0x50, 0x01, 0x7c, 0xfe, 0x84, 0x50, 0x50, 0x50, +0x50, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xd2, +0x01, 0x22, 0x03, 0x3e, 0x00, 0x05, 0x00, 0x09, 0x00, 0x1a, +0x40, 0x0a, 0x06, 0x05, 0x07, 0x04, 0x01, 0x09, 0x06, 0x00, +0x05, 0x02, 0x00, 0x2f, 0x2f, 0xc5, 0x2f, 0xc5, 0x01, 0x2f, +0xc5, 0x32, 0x2f, 0x2f, 0x31, 0x30, 0x11, 0x33, 0x11, 0x33, +0x11, 0x21, 0x15, 0x21, 0x15, 0x21, 0xd2, 0x50, 0xfe, 0xde, +0x01, 0x22, 0xfe, 0xde, 0x01, 0xc2, 0x01, 0x7c, 0xfe, 0x34, +0x50, 0x50, 0x00, 0x02, 0x00, 0xd2, 0x00, 0xd2, 0x01, 0xf4, +0x03, 0x3e, 0x00, 0x05, 0x00, 0x09, 0x00, 0x1b, 0x40, 0x0b, +0x07, 0x06, 0x04, 0x01, 0x00, 0x09, 0x06, 0x02, 0x5a, 0x04, +0x01, 0x00, 0x2f, 0xc5, 0x3f, 0x2f, 0xc5, 0x01, 0x2f, 0x2f, +0xc5, 0x2f, 0x2f, 0x31, 0x30, 0x01, 0x21, 0x11, 0x33, 0x11, +0x33, 0x05, 0x21, 0x15, 0x21, 0x01, 0xf4, 0xfe, 0xde, 0x50, +0xd2, 0xfe, 0xde, 0x01, 0x22, 0xfe, 0xde, 0x01, 0x72, 0x01, +0xcc, 0xfe, 0x84, 0xa0, 0x50, 0x00, 0x00, 0x00, 0x00, 0x02, +0x00, 0x00, 0xff, 0x56, 0x01, 0xf4, 0x01, 0xc2, 0x00, 0x07, +0x00, 0x0b, 0x00, 0x1e, 0x40, 0x0c, 0x0b, 0x08, 0x07, 0x02, +0x05, 0x00, 0x09, 0x08, 0x02, 0x06, 0x07, 0x04, 0x00, 0x2f, +0x2f, 0xc5, 0x32, 0x2f, 0xc5, 0x01, 0x2f, 0x2f, 0xc5, 0x2f, +0x2f, 0x2f, 0x31, 0x30, 0x01, 0x15, 0x23, 0x11, 0x23, 0x11, +0x23, 0x3d, 0x02, 0x21, 0x15, 0x01, 0xf4, 0xd2, 0x50, 0xd2, +0x01, 0xf4, 0x01, 0x22, 0x50, 0xfe, 0x84, 0x01, 0x7c, 0x50, +0x50, 0x50, 0x50, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff, 0x56, +0x01, 0x22, 0x01, 0xc2, 0x00, 0x05, 0x00, 0x09, 0x00, 0x1a, +0x40, 0x0a, 0x09, 0x08, 0x01, 0x04, 0x00, 0x06, 0x09, 0x03, +0x05, 0x00, 0x00, 0x2f, 0xc5, 0x2f, 0x2f, 0xc5, 0x01, 0x2f, +0x2f, 0xc5, 0x32, 0x2f, 0x31, 0x30, 0x11, 0x21, 0x11, 0x23, +0x11, 0x23, 0x35, 0x21, 0x15, 0x21, 0x01, 0x22, 0x50, 0xd2, +0x01, 0x22, 0xfe, 0xde, 0x01, 0x22, 0xfe, 0x34, 0x01, 0x7c, +0xf0, 0x50, 0x00, 0x02, 0x00, 0xd2, 0xff, 0x56, 0x01, 0xf4, +0x01, 0xc2, 0x00, 0x05, 0x00, 0x09, 0x00, 0x1a, 0x40, 0x0a, +0x09, 0x08, 0x05, 0x01, 0x04, 0x06, 0x09, 0x01, 0x04, 0x03, +0x00, 0x2f, 0x2f, 0xc5, 0x2f, 0xc5, 0x01, 0x2f, 0xc5, 0x2f, +0x2f, 0x2f, 0x31, 0x30, 0x25, 0x23, 0x11, 0x23, 0x11, 0x21, +0x25, 0x21, 0x15, 0x21, 0x01, 0xf4, 0xd2, 0x50, 0x01, 0x22, +0xfe, 0xde, 0x01, 0x22, 0xfe, 0xde, 0xd2, 0xfe, 0x84, 0x01, +0xcc, 0xa0, 0x50, 0x00, 0x00, 0x02, 0x00, 0x82, 0xff, 0x56, +0x01, 0x72, 0x03, 0x3e, 0x00, 0x03, 0x00, 0x07, 0x00, 0x15, +0xb7, 0x05, 0x04, 0x02, 0x03, 0x04, 0x02, 0x07, 0x01, 0x00, +0x2f, 0x33, 0x2f, 0x33, 0x01, 0x2f, 0xc5, 0x2f, 0xc5, 0x31, +0x30, 0x17, 0x23, 0x11, 0x3b, 0x02, 0x11, 0x23, 0xd2, 0x50, +0x50, 0x50, 0x50, 0x50, 0xaa, 0x03, 0xe8, 0xfc, 0x18, 0x00, +0x00, 0x04, 0x00, 0x00, 0xff, 0x56, 0x01, 0xf4, 0x03, 0x3e, +0x00, 0x05, 0x00, 0x0b, 0x00, 0x11, 0x00, 0x17, 0x00, 0x36, +0x40, 0x18, 0x07, 0x10, 0x0a, 0x0d, 0x0b, 0x0c, 0x12, 0x05, +0x16, 0x01, 0x13, 0x04, 0x09, 0x15, 0x07, 0x16, 0x0a, 0x13, +0x10, 0x01, 0x0d, 0x04, 0x0e, 0x02, 0x00, 0x2f, 0x33, 0x2f, +0x33, 0xc5, 0x32, 0x2f, 0x33, 0xc5, 0x32, 0x2f, 0x33, 0x01, +0x2f, 0x33, 0xc5, 0x32, 0x2f, 0x33, 0x2f, 0x33, 0x2f, 0x33, +0xc5, 0x32, 0x31, 0x30, 0x11, 0x33, 0x11, 0x33, 0x11, 0x23, +0x05, 0x23, 0x11, 0x23, 0x11, 0x33, 0x35, 0x23, 0x11, 0x33, +0x11, 0x33, 0x05, 0x33, 0x11, 0x23, 0x11, 0x23, 0x82, 0x50, +0xd2, 0x01, 0xf4, 0x82, 0x50, 0xd2, 0xd2, 0x50, 0x82, 0xfe, +0x0c, 0xd2, 0x50, 0x82, 0x01, 0xc2, 0x01, 0x7c, 0xfe, 0x34, +0xa0, 0xfe, 0x84, 0x01, 0xcc, 0x50, 0x01, 0xcc, 0xfe, 0x84, +0xa0, 0xfe, 0x34, 0x01, 0x7c, 0x00, 0x00, 0x03, 0x00, 0x00, +0xff, 0x56, 0x01, 0x72, 0x03, 0x3e, 0x00, 0x03, 0x00, 0x09, +0x00, 0x0f, 0x00, 0x26, 0x40, 0x10, 0x0a, 0x09, 0x0e, 0x06, +0x0b, 0x07, 0x01, 0x00, 0x03, 0x0d, 0x0e, 0x0a, 0x05, 0x09, +0x00, 0x06, 0x00, 0x2f, 0x33, 0x2f, 0xc5, 0x2f, 0xc5, 0x2f, +0x33, 0x01, 0x2f, 0xc5, 0x2f, 0x33, 0xc5, 0x32, 0x2f, 0x33, +0x31, 0x30, 0x01, 0x33, 0x11, 0x23, 0x01, 0x33, 0x11, 0x33, +0x11, 0x23, 0x15, 0x33, 0x11, 0x23, 0x11, 0x23, 0x01, 0x22, +0x50, 0x50, 0xfe, 0xde, 0x82, 0x50, 0xd2, 0xd2, 0x50, 0x82, +0x03, 0x3e, 0xfc, 0x18, 0x02, 0x6c, 0x01, 0x7c, 0xfe, 0x34, +0x50, 0xfe, 0x34, 0x01, 0x7c, 0x00, 0x00, 0x03, 0x00, 0x82, +0xff, 0x56, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x03, 0x00, 0x09, +0x00, 0x0f, 0x00, 0x26, 0x40, 0x10, 0x0b, 0x07, 0x0e, 0x06, +0x0f, 0x04, 0x02, 0x03, 0x0b, 0x0e, 0x00, 0x0d, 0x03, 0x06, +0x08, 0x05, 0x00, 0x2f, 0xc5, 0x2f, 0x33, 0x2f, 0x33, 0x2f, +0xc5, 0x01, 0x2f, 0xc5, 0x2f, 0x33, 0x2f, 0x33, 0xc5, 0x32, +0x31, 0x30, 0x17, 0x23, 0x11, 0x33, 0x01, 0x23, 0x11, 0x33, +0x11, 0x33, 0x15, 0x23, 0x11, 0x23, 0x11, 0x33, 0xd2, 0x50, +0x50, 0x01, 0x22, 0xd2, 0x50, 0x82, 0x82, 0x50, 0xd2, 0xaa, +0x03, 0xe8, 0xfe, 0x34, 0x01, 0xcc, 0xfe, 0x84, 0xf0, 0xfe, +0x84, 0x01, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, +0x00, 0xd2, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x03, 0x00, 0x09, +0x00, 0x0f, 0x00, 0x26, 0x40, 0x10, 0x0e, 0x0b, 0x00, 0x0a, +0x03, 0x09, 0x05, 0x08, 0x0e, 0x05, 0x0b, 0x08, 0x0c, 0x06, +0x02, 0x03, 0x00, 0x2f, 0xc5, 0x2f, 0x33, 0x2f, 0x33, 0xc5, +0x32, 0x01, 0x2f, 0xc5, 0x2f, 0x33, 0x2f, 0x33, 0x2f, 0xc5, +0x31, 0x30, 0x01, 0x15, 0x21, 0x35, 0x35, 0x33, 0x11, 0x33, +0x11, 0x23, 0x21, 0x23, 0x11, 0x33, 0x11, 0x33, 0x01, 0xf4, +0xfe, 0x0c, 0x82, 0x50, 0xd2, 0x01, 0xf4, 0xd2, 0x50, 0x82, +0x01, 0x22, 0x50, 0x50, 0xa0, 0x01, 0x7c, 0xfe, 0x34, 0x01, +0xcc, 0xfe, 0x84, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, +0x00, 0xd2, 0x01, 0x72, 0x03, 0x3e, 0x00, 0x05, 0x00, 0x0b, +0x00, 0x1e, 0x40, 0x0c, 0x0a, 0x07, 0x01, 0x04, 0x06, 0x00, +0x0a, 0x07, 0x01, 0x04, 0x08, 0x02, 0x00, 0x2f, 0x33, 0x2f, +0xc5, 0x2f, 0xc5, 0x01, 0x2f, 0x33, 0x2f, 0xc5, 0x2f, 0xc5, +0x31, 0x30, 0x11, 0x33, 0x11, 0x33, 0x11, 0x23, 0x15, 0x21, +0x11, 0x33, 0x11, 0x21, 0x82, 0x50, 0xd2, 0x01, 0x22, 0x50, +0xfe, 0x8e, 0x01, 0xc2, 0x01, 0x7c, 0xfe, 0x34, 0x50, 0x02, +0x1c, 0xfd, 0x94, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x82, +0x00, 0xd2, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x05, 0x00, 0x0b, +0x00, 0x1e, 0x40, 0x0c, 0x07, 0x0a, 0x04, 0x01, 0x0b, 0x00, +0x07, 0x0a, 0x02, 0x08, 0x04, 0x01, 0x00, 0x2f, 0xc5, 0x2f, +0x33, 0x2f, 0xc5, 0x01, 0x2f, 0x33, 0x2f, 0xc5, 0x2f, 0xc5, +0x31, 0x30, 0x01, 0x23, 0x11, 0x33, 0x11, 0x33, 0x15, 0x21, +0x11, 0x33, 0x11, 0x21, 0x01, 0xf4, 0xd2, 0x50, 0x82, 0xfe, +0x8e, 0x50, 0x01, 0x22, 0x01, 0x72, 0x01, 0xcc, 0xfe, 0x84, +0xf0, 0x02, 0x6c, 0xfd, 0xe4, 0x00, 0x00, 0x03, 0x00, 0x00, +0xff, 0x56, 0x01, 0xf4, 0x01, 0xc2, 0x00, 0x03, 0x00, 0x09, +0x00, 0x0f, 0x00, 0x26, 0x40, 0x10, 0x0e, 0x0b, 0x00, 0x0a, +0x03, 0x09, 0x05, 0x08, 0x07, 0x0d, 0x05, 0x0e, 0x08, 0x0b, +0x01, 0x00, 0x00, 0x2f, 0xc5, 0x2f, 0x33, 0xc5, 0x32, 0x2f, +0x33, 0x01, 0x2f, 0xc5, 0x2f, 0x33, 0x2f, 0x33, 0x2f, 0xc5, +0x31, 0x30, 0x11, 0x35, 0x21, 0x15, 0x15, 0x23, 0x11, 0x23, +0x11, 0x33, 0x21, 0x33, 0x11, 0x23, 0x11, 0x23, 0x01, 0xf4, +0x82, 0x50, 0xd2, 0xfe, 0x0c, 0xd2, 0x50, 0x82, 0x01, 0x72, +0x50, 0x50, 0xa0, 0xfe, 0x84, 0x01, 0xcc, 0xfe, 0x34, 0x01, +0x7c, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff, 0x56, 0x01, 0x72, +0x01, 0xc2, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x1e, 0x40, 0x0c, +0x00, 0x0b, 0x07, 0x0a, 0x04, 0x01, 0x07, 0x0a, 0x09, 0x03, +0x04, 0x01, 0x00, 0x2f, 0xc5, 0x2f, 0x33, 0x2f, 0xc5, 0x01, +0x2f, 0xc5, 0x2f, 0xc5, 0x2f, 0x33, 0x31, 0x30, 0x11, 0x33, +0x11, 0x23, 0x11, 0x23, 0x35, 0x21, 0x11, 0x23, 0x11, 0x21, +0xd2, 0x50, 0x82, 0x01, 0x72, 0x50, 0xfe, 0xde, 0x01, 0x22, +0xfe, 0x34, 0x01, 0x7c, 0xf0, 0xfd, 0x94, 0x02, 0x1c, 0x00, +0x00, 0x00, 0x00, 0x02, 0x00, 0x82, 0xff, 0x56, 0x01, 0xf4, +0x01, 0xc2, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x1e, 0x40, 0x0c, +0x0a, 0x07, 0x05, 0x06, 0x01, 0x04, 0x03, 0x09, 0x0a, 0x07, +0x01, 0x04, 0x00, 0x2f, 0xc5, 0x2f, 0xc5, 0x2f, 0x33, 0x01, +0x2f, 0xc5, 0x2f, 0x33, 0x2f, 0xc5, 0x31, 0x30, 0x25, 0x23, +0x11, 0x23, 0x11, 0x33, 0x35, 0x21, 0x11, 0x23, 0x11, 0x21, +0x01, 0xf4, 0x82, 0x50, 0xd2, 0xfe, 0xde, 0x50, 0x01, 0x72, +0xd2, 0xfe, 0x84, 0x01, 0xcc, 0x50, 0xfd, 0xe4, 0x02, 0x6c, +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xd2, 0x01, 0xf4, +0x01, 0xc2, 0x00, 0x03, 0x00, 0x07, 0x00, 0x15, 0xb7, 0x02, +0x07, 0x01, 0x04, 0x05, 0x04, 0x00, 0x01, 0x00, 0x2f, 0xc5, +0x2f, 0xc5, 0x01, 0x2f, 0x33, 0x2f, 0x33, 0x31, 0x30, 0x35, +0x35, 0x21, 0x15, 0x25, 0x35, 0x21, 0x15, 0x01, 0xf4, 0xfe, +0x0c, 0x01, 0xf4, 0xd2, 0x50, 0x50, 0xa0, 0x50, 0x50, 0x00, +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff, 0x56, 0x01, 0x72, +0x03, 0x3e, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x1e, 0x40, 0x0c, +0x0b, 0x0a, 0x02, 0x06, 0x07, 0x03, 0x0a, 0x06, 0x02, 0x05, +0x09, 0x01, 0x00, 0x2f, 0x33, 0x2f, 0xc5, 0x2f, 0x33, 0x01, +0x2f, 0x2f, 0xc5, 0x32, 0x2f, 0xc5, 0x31, 0x30, 0x17, 0x23, +0x11, 0x23, 0x35, 0x33, 0x11, 0x33, 0x13, 0x23, 0x11, 0x33, +0xd2, 0x50, 0x82, 0x82, 0x50, 0xa0, 0x50, 0x50, 0xaa, 0x01, +0xcc, 0x50, 0x01, 0xcc, 0xfc, 0x18, 0x03, 0xe8, 0x00, 0x02, +0x00, 0x82, 0xff, 0x56, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x07, +0x00, 0x0b, 0x00, 0x1e, 0x40, 0x0c, 0x08, 0x09, 0x03, 0x05, +0x01, 0x00, 0x07, 0x0b, 0x00, 0x08, 0x05, 0x02, 0x00, 0x2f, +0xc5, 0x2f, 0x33, 0x2f, 0x33, 0x01, 0x2f, 0xc5, 0x32, 0x2f, +0x2f, 0xc5, 0x31, 0x30, 0x01, 0x33, 0x11, 0x33, 0x15, 0x23, +0x11, 0x23, 0x03, 0x33, 0x11, 0x23, 0x01, 0x22, 0x50, 0x82, +0x82, 0x50, 0xa0, 0x50, 0x50, 0x03, 0x3e, 0xfe, 0x34, 0x50, +0xfe, 0x34, 0x03, 0xe8, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, +0x00, 0x00, 0x01, 0x22, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x0b, +0x00, 0x1e, 0x40, 0x0c, 0x0a, 0x09, 0x05, 0x06, 0x03, 0x00, +0x09, 0x05, 0x0b, 0x07, 0x02, 0x03, 0x00, 0x2f, 0xc5, 0x33, +0x33, 0x2f, 0x33, 0x01, 0x2f, 0x2f, 0x2f, 0xc5, 0x2f, 0xc5, +0x31, 0x30, 0x01, 0x15, 0x21, 0x35, 0x33, 0x11, 0x33, 0x11, +0x33, 0x11, 0x33, 0x11, 0x01, 0xf4, 0xfe, 0x0c, 0x82, 0x50, +0x50, 0x50, 0x01, 0x72, 0x50, 0x50, 0x01, 0xcc, 0xfe, 0x34, +0x01, 0xcc, 0xfe, 0x34, 0x00, 0x02, 0x00, 0x00, 0x01, 0x22, +0x01, 0x72, 0x03, 0x3e, 0x00, 0x05, 0x00, 0x09, 0x00, 0x1c, +0x40, 0x0b, 0x07, 0x06, 0x02, 0x03, 0x00, 0x06, 0x02, 0x09, +0x09, 0x04, 0x00, 0x00, 0x2f, 0xc5, 0x32, 0x2f, 0x2f, 0x33, +0x01, 0x2f, 0x2f, 0xc5, 0x2f, 0xc5, 0x31, 0x30, 0x11, 0x33, +0x11, 0x33, 0x11, 0x23, 0x01, 0x33, 0x11, 0x23, 0x82, 0x50, +0xd2, 0x01, 0x22, 0x50, 0x50, 0x01, 0x72, 0x01, 0xcc, 0xfd, +0xe4, 0x02, 0x1c, 0xfd, 0xe4, 0x00, 0x00, 0x02, 0x00, 0x82, +0x01, 0x22, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x05, 0x00, 0x09, +0x00, 0x1a, 0x40, 0x0a, 0x08, 0x09, 0x05, 0x03, 0x02, 0x02, +0x08, 0x07, 0x01, 0x04, 0x00, 0x2f, 0xc5, 0x32, 0x2f, 0x33, +0x01, 0x2f, 0xc5, 0x2f, 0x2f, 0xc5, 0x31, 0x30, 0x01, 0x23, +0x11, 0x33, 0x11, 0x33, 0x05, 0x23, 0x11, 0x33, 0x01, 0xf4, +0xd2, 0x50, 0x82, 0xfe, 0xde, 0x50, 0x50, 0x01, 0x22, 0x02, +0x1c, 0xfe, 0x34, 0x50, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x01, +0x00, 0x00, 0xff, 0x56, 0x01, 0xf4, 0x01, 0x72, 0x00, 0x0b, +0x00, 0x1e, 0x40, 0x0c, 0x0b, 0x08, 0x04, 0x07, 0x03, 0x00, +0x06, 0x0a, 0x08, 0x04, 0x0b, 0x01, 0x00, 0x2f, 0xc5, 0x32, +0x32, 0x2f, 0x33, 0x01, 0x2f, 0x2f, 0x2f, 0xc5, 0x2f, 0xc5, +0x31, 0x30, 0x11, 0x35, 0x21, 0x15, 0x23, 0x11, 0x23, 0x11, +0x23, 0x11, 0x23, 0x11, 0x01, 0xf4, 0x82, 0x50, 0x50, 0x50, +0x01, 0x22, 0x50, 0x50, 0xfe, 0x34, 0x01, 0xcc, 0xfe, 0x34, +0x01, 0xcc, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff, 0x56, +0x01, 0x72, 0x01, 0x72, 0x00, 0x05, 0x00, 0x09, 0x00, 0x1a, +0x40, 0x0a, 0x07, 0x06, 0x05, 0x04, 0x01, 0x09, 0x03, 0x06, +0x04, 0x01, 0x00, 0x2f, 0xc5, 0x33, 0x2f, 0x33, 0x01, 0x2f, +0xc5, 0x2f, 0x2f, 0xc5, 0x31, 0x30, 0x11, 0x33, 0x11, 0x23, +0x11, 0x23, 0x25, 0x33, 0x11, 0x23, 0xd2, 0x50, 0x82, 0x01, +0x22, 0x50, 0x50, 0x01, 0x72, 0xfd, 0xe4, 0x01, 0xcc, 0x50, +0xfd, 0xe4, 0x00, 0x02, 0x00, 0x82, 0xff, 0x56, 0x01, 0xf4, +0x01, 0x72, 0x00, 0x05, 0x00, 0x09, 0x00, 0x1a, 0x40, 0x0a, +0x08, 0x09, 0x05, 0x01, 0x04, 0x08, 0x01, 0x04, 0x07, 0x03, +0x00, 0x2f, 0x33, 0x2f, 0xc5, 0x33, 0x01, 0x2f, 0xc5, 0x2f, +0x2f, 0xc5, 0x31, 0x30, 0x01, 0x23, 0x11, 0x23, 0x11, 0x33, +0x01, 0x23, 0x11, 0x33, 0x01, 0xf4, 0x82, 0x50, 0xd2, 0xfe, +0xde, 0x50, 0x50, 0x01, 0x22, 0xfe, 0x34, 0x02, 0x1c, 0xfd, +0xe4, 0x02, 0x1c, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x56, +0x01, 0xf4, 0x03, 0x3e, 0x00, 0x03, 0x00, 0x0d, 0xb3, 0x03, +0x00, 0x03, 0x02, 0x00, 0x2f, 0x2f, 0x01, 0x2f, 0x2f, 0x31, +0x30, 0x01, 0x11, 0x21, 0x11, 0x01, 0xf4, 0xfe, 0x0c, 0x03, +0x3e, 0xfc, 0x18, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x2e, +0x00, 0x00, 0xff, 0x6e, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x03, +0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x17, +0x00, 0x1b, 0x00, 0x1f, 0x00, 0x23, 0x00, 0x27, 0x00, 0x2b, +0x00, 0x2f, 0x00, 0x33, 0x00, 0x37, 0x00, 0x3b, 0x00, 0x3f, +0x00, 0x43, 0x00, 0x47, 0x00, 0x4b, 0x00, 0x4f, 0x00, 0x53, +0x00, 0x57, 0x00, 0x5b, 0x00, 0x5f, 0x00, 0x63, 0x00, 0x67, +0x00, 0x6b, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x77, 0x00, 0x7b, +0x00, 0x7f, 0x00, 0x83, 0x00, 0x87, 0x00, 0x8b, 0x00, 0x8f, +0x00, 0x93, 0x00, 0x97, 0x00, 0x9b, 0x00, 0x9f, 0x00, 0xa3, +0x00, 0xa7, 0x00, 0xab, 0x00, 0xaf, 0x00, 0xb3, 0x00, 0xb7, +0x00, 0x00, 0x11, 0x33, 0x15, 0x23, 0x17, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x17, 0x33, 0x15, 0x23, 0x07, 0x33, +0x15, 0x23, 0x17, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x17, 0x33, 0x15, 0x23, 0x07, 0x33, 0x15, 0x23, 0x17, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x17, 0x33, 0x15, 0x23, +0x07, 0x33, 0x15, 0x23, 0x17, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x17, 0x33, 0x15, 0x23, 0x07, 0x33, 0x15, 0x23, +0x17, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x17, 0x33, +0x15, 0x23, 0x07, 0x33, 0x15, 0x23, 0x17, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x17, 0x33, 0x15, 0x23, 0x07, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x13, 0x33, 0x15, 0x23, +0x17, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x07, 0x33, +0x15, 0x23, 0x17, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x07, 0x33, 0x15, 0x23, 0x17, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x07, 0x33, 0x15, 0x23, 0x17, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x07, 0x33, 0x15, 0x23, 0x17, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x07, 0x33, 0x15, 0x23, +0x17, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x07, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0xea, 0x27, 0x27, +0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0xea, +0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, +0x27, 0xea, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x4e, 0x27, 0x27, 0xea, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, +0x27, 0x27, 0x4e, 0x27, 0x27, 0xea, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0xea, 0x27, 0x27, +0x9c, 0x27, 0x27, 0x9c, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, +0x20, 0x20, 0x9c, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x20, +0x20, 0x9c, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x20, 0x20, +0x9c, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x20, 0x20, 0x9c, +0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x20, 0x20, 0x9c, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x20, 0x20, 0x9c, 0x27, 0x27, +0x9c, 0x20, 0x20, 0x03, 0x3e, 0x27, 0x27, 0x27, 0x75, 0x27, +0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x75, 0x27, 0x27, 0x27, +0x27, 0x27, 0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x28, 0x27, +0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, +0x75, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x75, 0x27, +0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x03, 0xd0, 0x27, 0x27, +0x27, 0x75, 0x27, 0x75, 0x27, 0x27, 0x27, 0x75, 0x27, 0x75, +0x27, 0x27, 0x27, 0x75, 0x27, 0x76, 0x27, 0x27, 0x27, 0x75, +0x27, 0x75, 0x27, 0x27, 0x27, 0x75, 0x27, 0x75, 0x27, 0x27, +0x27, 0x75, 0x27, 0x75, 0x27, 0x27, 0x27, 0x00, 0x00, 0x55, +0x00, 0x00, 0xff, 0x6e, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x03, +0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x17, +0x00, 0x1b, 0x00, 0x1f, 0x00, 0x23, 0x00, 0x27, 0x00, 0x2b, +0x00, 0x2f, 0x00, 0x33, 0x00, 0x37, 0x00, 0x3b, 0x00, 0x3f, +0x00, 0x43, 0x00, 0x47, 0x00, 0x4b, 0x00, 0x4f, 0x00, 0x53, +0x00, 0x57, 0x00, 0x5b, 0x00, 0x5f, 0x00, 0x63, 0x00, 0x67, +0x00, 0x6b, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x77, 0x00, 0x7b, +0x00, 0x7f, 0x00, 0x83, 0x00, 0x87, 0x00, 0x8b, 0x00, 0x8f, +0x00, 0x93, 0x00, 0x97, 0x00, 0x9b, 0x00, 0x9f, 0x00, 0xa3, +0x00, 0xa7, 0x00, 0xab, 0x00, 0xaf, 0x00, 0xb3, 0x00, 0xb7, +0x00, 0xbb, 0x00, 0xbf, 0x00, 0xc3, 0x00, 0xc7, 0x00, 0xcb, +0x00, 0xcf, 0x00, 0xd3, 0x00, 0xd7, 0x00, 0xdb, 0x00, 0xdf, +0x00, 0xe3, 0x00, 0xe7, 0x00, 0xeb, 0x00, 0xef, 0x00, 0xf3, +0x00, 0xf7, 0x00, 0xfb, 0x00, 0xff, 0x01, 0x03, 0x01, 0x07, +0x01, 0x0b, 0x01, 0x0f, 0x01, 0x13, 0x01, 0x17, 0x01, 0x1b, +0x01, 0x1f, 0x01, 0x23, 0x01, 0x27, 0x01, 0x2b, 0x01, 0x2f, +0x01, 0x33, 0x01, 0x37, 0x01, 0x3b, 0x01, 0x3f, 0x01, 0x43, +0x01, 0x47, 0x01, 0x4b, 0x01, 0x4f, 0x01, 0x53, 0x00, 0x00, +0x11, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x07, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x07, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x07, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x05, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x05, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x05, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x05, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x05, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x13, 0x33, +0x15, 0x23, 0x05, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x05, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x05, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x05, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x05, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x05, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, +0x15, 0x23, 0x37, 0x33, 0x15, 0x23, 0x37, 0x33, 0x15, 0x23, +0x27, 0x27, 0x4e, 0x27, 0x27, 0x27, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x27, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x27, 0x27, 0x27, +0x4e, 0x27, 0x27, 0x27, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x27, +0x27, 0x27, 0x4e, 0x27, 0x27, 0xfe, 0x7a, 0x27, 0x27, 0x4e, +0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x4e, 0x27, 0x27, 0xfe, 0x7a, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x4e, 0x27, 0x27, 0xfe, 0x7a, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, +0x27, 0x27, 0xfe, 0x7a, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, +0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, +0x27, 0xfe, 0x7a, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x27, 0x20, 0x20, 0xfe, 0x2c, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, +0x27, 0x27, 0x4e, 0x20, 0x20, 0xfe, 0x2c, 0x27, 0x27, 0x4e, +0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x20, 0x20, 0xfe, 0x2c, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x20, 0x20, 0xfe, +0x2c, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, +0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x20, +0x20, 0xfe, 0x2c, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x4e, 0x20, 0x20, 0xfe, 0x2c, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, +0x27, 0x27, 0x4e, 0x20, 0x20, 0x03, 0x3e, 0x27, 0x27, 0x27, +0x27, 0x27, 0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x27, 0x27, +0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, +0x75, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, +0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, +0x27, 0x27, 0x27, 0x27, 0x76, 0x27, 0x27, 0x27, 0x27, 0x27, +0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x75, 0x27, 0x27, 0x27, +0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x75, 0x27, +0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, +0x03, 0x82, 0x27, 0x75, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, +0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x75, 0x27, 0x27, +0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, +0x27, 0x76, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, +0x27, 0x27, 0x27, 0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x27, +0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x75, +0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, +0x27, 0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, +0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x00, 0x00, 0x49, +0x00, 0x00, 0xff, 0x56, 0x01, 0xf4, 0x03, 0x3e, 0x00, 0x03, +0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x17, +0x00, 0x1b, 0x00, 0x1f, 0x00, 0x23, 0x00, 0x27, 0x00, 0x2b, +0x00, 0x2f, 0x00, 0x33, 0x00, 0x37, 0x00, 0x3b, 0x00, 0x3f, +0x00, 0x43, 0x00, 0x47, 0x00, 0x4b, 0x00, 0x4f, 0x00, 0x53, +0x00, 0x57, 0x00, 0x5b, 0x00, 0x5f, 0x00, 0x63, 0x00, 0x67, +0x00, 0x6b, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x77, 0x00, 0x7b, +0x00, 0x7f, 0x00, 0x83, 0x00, 0x87, 0x00, 0x8b, 0x00, 0x8f, +0x00, 0x93, 0x00, 0x97, 0x00, 0x9b, 0x00, 0x9f, 0x00, 0xa3, +0x00, 0xa7, 0x00, 0xab, 0x00, 0xaf, 0x00, 0xb3, 0x00, 0xb7, +0x00, 0xbb, 0x00, 0xbf, 0x00, 0xc3, 0x00, 0xc7, 0x00, 0xcb, +0x00, 0xcf, 0x00, 0xd3, 0x00, 0xd7, 0x00, 0xdb, 0x00, 0xdf, +0x00, 0xe3, 0x00, 0xe7, 0x00, 0xeb, 0x00, 0xef, 0x00, 0xf3, +0x00, 0xf7, 0x00, 0xfb, 0x00, 0xff, 0x01, 0x03, 0x01, 0x07, +0x01, 0x0b, 0x01, 0x0f, 0x01, 0x13, 0x01, 0x17, 0x01, 0x1b, +0x01, 0x1f, 0x01, 0x3b, 0x00, 0x00, 0x13, 0x33, 0x35, 0x23, +0x17, 0x33, 0x35, 0x23, 0x07, 0x33, 0x35, 0x23, 0x17, 0x33, +0x35, 0x23, 0x37, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, +0x07, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x37, 0x33, +0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x07, 0x33, 0x35, 0x23, +0x17, 0x33, 0x35, 0x23, 0x05, 0x33, 0x35, 0x23, 0x17, 0x33, +0x35, 0x23, 0x07, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, +0x37, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x07, 0x33, +0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x37, 0x33, 0x35, 0x23, +0x17, 0x33, 0x35, 0x23, 0x07, 0x33, 0x35, 0x23, 0x17, 0x33, +0x35, 0x23, 0x05, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, +0x07, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x37, 0x33, +0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x07, 0x33, 0x35, 0x23, +0x17, 0x33, 0x35, 0x23, 0x37, 0x33, 0x35, 0x23, 0x17, 0x33, +0x35, 0x23, 0x07, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, +0x05, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x07, 0x33, +0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x37, 0x33, 0x35, 0x23, +0x17, 0x33, 0x35, 0x23, 0x07, 0x33, 0x35, 0x23, 0x17, 0x33, +0x35, 0x23, 0x37, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, +0x07, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x05, 0x33, +0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x07, 0x33, 0x35, 0x23, +0x17, 0x33, 0x35, 0x23, 0x37, 0x33, 0x35, 0x23, 0x17, 0x33, +0x35, 0x23, 0x07, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, +0x37, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x07, 0x33, +0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x05, 0x33, 0x35, 0x23, +0x17, 0x33, 0x35, 0x23, 0x07, 0x33, 0x35, 0x23, 0x17, 0x33, +0x35, 0x23, 0x37, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, +0x07, 0x33, 0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x37, 0x33, +0x35, 0x23, 0x17, 0x33, 0x35, 0x23, 0x07, 0x33, 0x35, 0x23, +0x17, 0x33, 0x35, 0x23, 0x13, 0x11, 0x23, 0x35, 0x23, 0x15, +0x23, 0x35, 0x23, 0x15, 0x23, 0x35, 0x23, 0x15, 0x23, 0x35, +0x23, 0x15, 0x23, 0x35, 0x23, 0x15, 0x23, 0x35, 0x23, 0x15, +0x23, 0x11, 0x27, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, +0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0xfe, 0x7a, +0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, +0x27, 0x27, 0x4e, 0x27, 0x27, 0xfe, 0x7a, 0x27, 0x27, 0x4e, +0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, +0x27, 0x27, 0xfe, 0x7a, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, +0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0xfe, +0x7a, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, +0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0xfe, 0x7a, 0x27, 0x27, +0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, +0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, +0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, 0x4e, 0x27, 0x27, +0x4e, 0x27, 0x27, 0x47, 0x20, 0x27, 0x27, 0x27, 0x27, 0x27, +0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x02, 0xf0, 0x27, +0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, +0x75, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x75, 0x27, +0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x75, 0x27, 0x27, 0x27, +0x27, 0x27, 0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x27, 0x27, +0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x75, 0x27, 0x27, 0x27, +0x76, 0x28, 0x28, 0x28, 0x27, 0x27, 0x27, 0x27, 0x76, 0x28, +0x28, 0x28, 0x27, 0x27, 0x27, 0x27, 0x76, 0x28, 0x28, 0x28, +0x76, 0x27, 0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x27, 0x27, +0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, +0x75, 0x27, 0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x75, 0x27, +0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x75, 0x27, 0x27, 0x27, +0x27, 0x27, 0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x75, 0x27, +0x27, 0x27, 0x75, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, +0x75, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x75, 0x27, +0x27, 0x27, 0x03, 0x82, 0xfc, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x03, 0xe8, +0x00, 0x01, 0x00, 0x00, 0xff, 0x56, 0x01, 0xf4, 0x03, 0x3e, +0x00, 0x13, 0x00, 0x2e, 0x40, 0x14, 0x03, 0x00, 0x06, 0x11, +0x0a, 0x0d, 0x07, 0x10, 0x0c, 0x01, 0x12, 0x0e, 0x07, 0x03, +0x0a, 0x10, 0x00, 0x0d, 0x05, 0x09, 0x00, 0x2f, 0x33, 0x2f, +0x33, 0x33, 0xc5, 0x32, 0x32, 0x2f, 0x33, 0x01, 0x2f, 0x2f, +0x2f, 0x33, 0xc5, 0x32, 0x2f, 0x33, 0xc5, 0x32, 0x31, 0x30, +0x01, 0x33, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, +0x11, 0x23, 0x35, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, +0x01, 0x72, 0x82, 0x82, 0x50, 0x50, 0x50, 0x82, 0x82, 0x50, +0x50, 0x50, 0x01, 0x72, 0x50, 0xfe, 0x34, 0x01, 0xcc, 0xfe, +0x34, 0x01, 0xcc, 0x50, 0x01, 0xcc, 0xfe, 0x34, 0x01, 0xcc, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x56, 0x01, 0xf4, +0x03, 0x3e, 0x00, 0x13, 0x00, 0x2e, 0x40, 0x14, 0x00, 0x11, +0x13, 0x02, 0x0f, 0x09, 0x05, 0x0c, 0x07, 0x0a, 0x0d, 0x0f, +0x0c, 0x12, 0x09, 0x02, 0x05, 0x13, 0x08, 0x04, 0x00, 0x2f, +0x2f, 0x33, 0xc5, 0x32, 0x2f, 0x33, 0xc5, 0x32, 0x2f, 0x01, +0x2f, 0x33, 0x2f, 0x32, 0x32, 0xc5, 0x32, 0x32, 0x2f, 0x33, +0x31, 0x30, 0x01, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, +0x33, 0x35, 0x23, 0x35, 0x33, 0x11, 0x33, 0x11, 0x33, 0x15, +0x23, 0x15, 0x01, 0xf4, 0xd2, 0x50, 0xd2, 0xd2, 0xd2, 0xd2, +0x50, 0xd2, 0xd2, 0x01, 0x22, 0x50, 0xfe, 0x84, 0x01, 0x7c, +0x50, 0x50, 0x50, 0x01, 0x7c, 0xfe, 0x84, 0x50, 0x50, 0x00, +0x00, 0x00, 0x00, 0x1e, 0x01, 0x6e, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x49, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, +0x00, 0x54, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, +0x00, 0x20, 0x00, 0x5b, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, +0x00, 0x04, 0x00, 0x0b, 0x00, 0x49, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x7b, 0x00, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x12, 0x00, 0x87, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x40, +0x00, 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, +0x00, 0x0f, 0x00, 0xd9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, +0x00, 0x09, 0x00, 0x0f, 0x00, 0xd9, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x00, 0x0b, 0x00, 0x1a, 0x00, 0xe8, 0x00, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x1a, 0x00, 0xe8, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0b, +0x00, 0x49, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, +0x00, 0x07, 0x00, 0x54, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, +0x00, 0x12, 0x00, 0x0b, 0x00, 0x49, 0x00, 0x03, 0x00, 0x01, +0x04, 0x09, 0x00, 0x00, 0x00, 0x92, 0x01, 0x02, 0x00, 0x03, +0x00, 0x01, 0x04, 0x09, 0x00, 0x01, 0x00, 0x16, 0x01, 0x94, +0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x0e, +0x01, 0xaa, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x03, +0x00, 0x40, 0x01, 0xb8, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, +0x00, 0x04, 0x00, 0x16, 0x01, 0x94, 0x00, 0x03, 0x00, 0x01, +0x04, 0x09, 0x00, 0x05, 0x00, 0x18, 0x01, 0xf8, 0x00, 0x03, +0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x24, 0x02, 0x10, +0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x07, 0x00, 0x80, +0x02, 0x34, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x08, +0x00, 0x1e, 0x02, 0xb4, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, +0x00, 0x09, 0x00, 0x1e, 0x02, 0xb4, 0x00, 0x03, 0x00, 0x01, +0x04, 0x09, 0x00, 0x0b, 0x00, 0x34, 0x02, 0xd2, 0x00, 0x03, +0x00, 0x01, 0x04, 0x09, 0x00, 0x0c, 0x00, 0x34, 0x02, 0xd2, +0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x10, 0x00, 0x16, +0x01, 0x94, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x11, +0x00, 0x0e, 0x01, 0xaa, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, +0x00, 0x12, 0x00, 0x16, 0x01, 0x94, 0x43, 0x6f, 0x70, 0x79, +0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, 0x31, 0x31, +0x20, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, +0x20, 0x4c, 0x74, 0x64, 0x2e, 0x20, 0x20, 0x4c, 0x69, 0x63, +0x65, 0x6e, 0x73, 0x65, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, +0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55, 0x62, 0x75, 0x6e, +0x74, 0x75, 0x20, 0x46, 0x6f, 0x6e, 0x74, 0x20, 0x4c, 0x69, +0x63, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x31, 0x2e, 0x30, 0x55, +0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, 0x4d, 0x6f, 0x6e, 0x6f, +0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x55, 0x62, 0x75, +0x6e, 0x74, 0x75, 0x20, 0x4d, 0x6f, 0x6e, 0x6f, 0x20, 0x52, +0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x20, 0x56, 0x65, 0x72, +0x73, 0x69, 0x6f, 0x6e, 0x20, 0x30, 0x2e, 0x38, 0x30, 0x56, +0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x30, 0x2e, 0x38, +0x30, 0x55, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x4d, 0x6f, 0x6e, +0x6f, 0x2d, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x55, +0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, 0x61, 0x6e, 0x64, 0x20, +0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x20, +0x61, 0x72, 0x65, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, +0x65, 0x72, 0x65, 0x64, 0x20, 0x74, 0x72, 0x61, 0x64, 0x65, +0x6d, 0x61, 0x72, 0x6b, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x43, +0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x4c, +0x74, 0x64, 0x2e, 0x44, 0x61, 0x6c, 0x74, 0x6f, 0x6e, 0x20, +0x4d, 0x61, 0x61, 0x67, 0x20, 0x4c, 0x74, 0x64, 0x68, 0x74, +0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x64, +0x61, 0x6c, 0x74, 0x6f, 0x6e, 0x6d, 0x61, 0x61, 0x67, 0x2e, +0x63, 0x6f, 0x6d, 0x2f, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x70, +0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, +0x00, 0x74, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x31, +0x00, 0x31, 0x00, 0x20, 0x00, 0x43, 0x00, 0x61, 0x00, 0x6e, +0x00, 0x6f, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, +0x00, 0x6c, 0x00, 0x20, 0x00, 0x4c, 0x00, 0x74, 0x00, 0x64, +0x00, 0x2e, 0x00, 0x20, 0x00, 0x20, 0x00, 0x4c, 0x00, 0x69, +0x00, 0x63, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x65, +0x00, 0x64, 0x00, 0x20, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x64, +0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, +0x00, 0x65, 0x00, 0x20, 0x00, 0x55, 0x00, 0x62, 0x00, 0x75, +0x00, 0x6e, 0x00, 0x74, 0x00, 0x75, 0x00, 0x20, 0x00, 0x46, +0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x4c, +0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x63, +0x00, 0x65, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x30, +0x00, 0x55, 0x00, 0x62, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x74, +0x00, 0x75, 0x00, 0x20, 0x00, 0x4d, 0x00, 0x6f, 0x00, 0x6e, +0x00, 0x6f, 0x00, 0x52, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75, +0x00, 0x6c, 0x00, 0x61, 0x00, 0x72, 0x00, 0x55, 0x00, 0x62, +0x00, 0x75, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x75, 0x00, 0x20, +0x00, 0x4d, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x20, +0x00, 0x52, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75, 0x00, 0x6c, +0x00, 0x61, 0x00, 0x72, 0x00, 0x20, 0x00, 0x56, 0x00, 0x65, +0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, +0x00, 0x20, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x38, 0x00, 0x30, +0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, +0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x30, 0x00, 0x2e, +0x00, 0x38, 0x00, 0x30, 0x00, 0x55, 0x00, 0x62, 0x00, 0x75, +0x00, 0x6e, 0x00, 0x74, 0x00, 0x75, 0x00, 0x4d, 0x00, 0x6f, +0x00, 0x6e, 0x00, 0x6f, 0x00, 0x2d, 0x00, 0x52, 0x00, 0x65, +0x00, 0x67, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x72, +0x00, 0x55, 0x00, 0x62, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x74, +0x00, 0x75, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, +0x00, 0x20, 0x00, 0x43, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x6f, +0x00, 0x6e, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x6c, +0x00, 0x20, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, +0x00, 0x72, 0x00, 0x65, 0x00, 0x67, 0x00, 0x69, 0x00, 0x73, +0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, +0x00, 0x20, 0x00, 0x74, 0x00, 0x72, 0x00, 0x61, 0x00, 0x64, +0x00, 0x65, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x72, 0x00, 0x6b, +0x00, 0x73, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, +0x00, 0x43, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x6e, +0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, +0x00, 0x4c, 0x00, 0x74, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x44, +0x00, 0x61, 0x00, 0x6c, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x6e, +0x00, 0x20, 0x00, 0x4d, 0x00, 0x61, 0x00, 0x61, 0x00, 0x67, +0x00, 0x20, 0x00, 0x4c, 0x00, 0x74, 0x00, 0x64, 0x00, 0x68, +0x00, 0x74, 0x00, 0x74, 0x00, 0x70, 0x00, 0x3a, 0x00, 0x2f, +0x00, 0x2f, 0x00, 0x77, 0x00, 0x77, 0x00, 0x77, 0x00, 0x2e, +0x00, 0x64, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x74, 0x00, 0x6f, +0x00, 0x6e, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x61, 0x00, 0x67, +0x00, 0x2e, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2f, +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x85, +0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, +0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, +0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, +0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, +0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, +0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, +0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, +0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, +0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, +0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, +0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, +0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, +0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, +0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, +0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, +0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, +0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, +0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, +0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, +0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, +0x01, 0x03, 0x00, 0xc4, 0x00, 0xa6, 0x00, 0xc5, 0x00, 0xab, +0x00, 0x82, 0x00, 0xc2, 0x00, 0xd8, 0x00, 0xc6, 0x00, 0xe4, +0x00, 0xbe, 0x00, 0xb0, 0x00, 0xb6, 0x00, 0xb7, 0x00, 0xb4, +0x00, 0xb5, 0x00, 0x87, 0x00, 0xb2, 0x00, 0xb3, 0x00, 0xd9, +0x00, 0x8c, 0x00, 0xe5, 0x00, 0xbf, 0x00, 0xb1, 0x00, 0xbb, +0x01, 0x04, 0x00, 0xa3, 0x00, 0x84, 0x00, 0x85, 0x00, 0xbd, +0x00, 0x96, 0x00, 0xe8, 0x00, 0x86, 0x00, 0x8e, 0x00, 0x8b, +0x00, 0x9d, 0x00, 0xa9, 0x00, 0xa4, 0x01, 0x05, 0x00, 0x8a, +0x01, 0x06, 0x00, 0x83, 0x00, 0x93, 0x00, 0xf2, 0x00, 0xf3, +0x00, 0x8d, 0x00, 0x97, 0x00, 0x88, 0x01, 0x07, 0x00, 0xde, +0x00, 0xf1, 0x00, 0x9e, 0x00, 0xaa, 0x00, 0xf5, 0x00, 0xf4, +0x00, 0xf6, 0x00, 0xa2, 0x00, 0xad, 0x00, 0xc9, 0x00, 0xc7, +0x00, 0xae, 0x00, 0x62, 0x00, 0x63, 0x00, 0x90, 0x00, 0x64, +0x00, 0xcb, 0x00, 0x65, 0x00, 0xc8, 0x00, 0xca, 0x00, 0xcf, +0x00, 0xcc, 0x00, 0xcd, 0x00, 0xce, 0x00, 0xe9, 0x00, 0x66, +0x00, 0xd3, 0x00, 0xd0, 0x00, 0xd1, 0x00, 0xaf, 0x00, 0x67, +0x00, 0xf0, 0x00, 0x91, 0x00, 0xd6, 0x00, 0xd4, 0x00, 0xd5, +0x00, 0x68, 0x00, 0xeb, 0x00, 0xed, 0x00, 0x89, 0x00, 0x6a, +0x00, 0x69, 0x00, 0x6b, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x6e, +0x00, 0xa0, 0x00, 0x6f, 0x00, 0x71, 0x00, 0x70, 0x00, 0x72, +0x00, 0x73, 0x00, 0x75, 0x00, 0x74, 0x00, 0x76, 0x00, 0x77, +0x00, 0xea, 0x00, 0x78, 0x00, 0x7a, 0x00, 0x79, 0x00, 0x7b, +0x00, 0x7d, 0x00, 0x7c, 0x00, 0xb8, 0x00, 0xa1, 0x00, 0x7f, +0x00, 0x7e, 0x00, 0x80, 0x00, 0x81, 0x00, 0xec, 0x00, 0xee, +0x00, 0xba, 0x01, 0x08, 0x01, 0x09, 0x01, 0x0a, 0x01, 0x0b, +0x01, 0x0c, 0x01, 0x0d, 0x00, 0xfd, 0x00, 0xfe, 0x01, 0x0e, +0x01, 0x0f, 0x01, 0x10, 0x01, 0x11, 0x00, 0xff, 0x01, 0x00, +0x01, 0x12, 0x01, 0x13, 0x01, 0x14, 0x01, 0x15, 0x01, 0x16, +0x01, 0x17, 0x01, 0x18, 0x01, 0x19, 0x01, 0x1a, 0x01, 0x1b, +0x01, 0x1c, 0x01, 0x1d, 0x01, 0x1e, 0x01, 0x1f, 0x01, 0x20, +0x01, 0x21, 0x00, 0xf8, 0x00, 0xf9, 0x01, 0x22, 0x01, 0x23, +0x01, 0x24, 0x01, 0x25, 0x01, 0x26, 0x01, 0x27, 0x01, 0x28, +0x01, 0x29, 0x01, 0x2a, 0x01, 0x2b, 0x01, 0x2c, 0x01, 0x2d, +0x01, 0x2e, 0x01, 0x2f, 0x01, 0x30, 0x01, 0x31, 0x01, 0x32, +0x00, 0xd7, 0x01, 0x33, 0x01, 0x34, 0x01, 0x35, 0x01, 0x36, +0x01, 0x37, 0x01, 0x38, 0x01, 0x39, 0x01, 0x3a, 0x01, 0x3b, +0x01, 0x3c, 0x01, 0x3d, 0x01, 0x3e, 0x01, 0x3f, 0x01, 0x40, +0x01, 0x41, 0x01, 0x42, 0x01, 0x43, 0x00, 0xe2, 0x00, 0xe3, +0x01, 0x44, 0x01, 0x45, 0x01, 0x46, 0x01, 0x47, 0x01, 0x48, +0x01, 0x49, 0x01, 0x4a, 0x01, 0x4b, 0x01, 0x4c, 0x01, 0x4d, +0x01, 0x4e, 0x01, 0x4f, 0x01, 0x50, 0x01, 0x51, 0x01, 0x52, +0x01, 0x53, 0x01, 0x54, 0x01, 0x55, 0x01, 0x56, 0x01, 0x57, +0x01, 0x58, 0x01, 0x59, 0x01, 0x5a, 0x01, 0x5b, 0x01, 0x5c, +0x01, 0x5d, 0x00, 0xfb, 0x00, 0xfc, 0x01, 0x5e, 0x01, 0x5f, +0x01, 0x60, 0x01, 0x61, 0x01, 0x62, 0x01, 0x63, 0x01, 0x64, +0x01, 0x65, 0x01, 0x66, 0x01, 0x67, 0x01, 0x68, 0x01, 0x69, +0x01, 0x6a, 0x01, 0x6b, 0x01, 0x6c, 0x01, 0x6d, 0x01, 0x6e, +0x01, 0x6f, 0x01, 0x70, 0x01, 0x71, 0x01, 0x72, 0x01, 0x73, +0x01, 0x74, 0x01, 0x75, 0x01, 0x76, 0x01, 0x77, 0x00, 0xe6, +0x00, 0xe7, 0x01, 0x78, 0x01, 0x79, 0x01, 0x7a, 0x01, 0x7b, +0x01, 0x7c, 0x01, 0x7d, 0x01, 0x7e, 0x00, 0xe1, 0x01, 0x7f, +0x00, 0xdb, 0x00, 0xdc, 0x00, 0xdd, 0x00, 0xe0, 0x00, 0xdf, +0x01, 0x80, 0x01, 0x81, 0x01, 0x82, 0x01, 0x83, 0x01, 0x84, +0x01, 0x85, 0x01, 0x86, 0x01, 0x87, 0x00, 0xbc, 0x01, 0x88, +0x01, 0x89, 0x01, 0x8a, 0x01, 0x8b, 0x01, 0x8c, 0x01, 0x8d, +0x01, 0x8e, 0x01, 0x8f, 0x01, 0x90, 0x01, 0x91, 0x01, 0x92, +0x01, 0x93, 0x01, 0x94, 0x01, 0x95, 0x01, 0x96, 0x01, 0x97, +0x01, 0x98, 0x01, 0x99, 0x01, 0x9a, 0x01, 0x9b, 0x01, 0x9c, +0x01, 0x9d, 0x01, 0x9e, 0x01, 0x9f, 0x01, 0xa0, 0x01, 0xa1, +0x01, 0xa2, 0x01, 0xa3, 0x01, 0xa4, 0x01, 0xa5, 0x01, 0xa6, +0x01, 0xa7, 0x01, 0xa8, 0x01, 0xa9, 0x01, 0xaa, 0x01, 0xab, +0x01, 0xac, 0x01, 0xad, 0x01, 0xae, 0x01, 0xaf, 0x01, 0xb0, +0x01, 0xb1, 0x01, 0xb2, 0x00, 0x98, 0x01, 0xb3, 0x00, 0x9a, +0x00, 0x99, 0x01, 0xb4, 0x00, 0xef, 0x01, 0xb5, 0x01, 0xb6, +0x00, 0xa5, 0x00, 0x92, 0x00, 0x9c, 0x00, 0xa7, 0x00, 0x8f, +0x00, 0x94, 0x00, 0x95, 0x00, 0xb9, 0x00, 0xc0, 0x01, 0xb7, +0x00, 0xc1, 0x01, 0xb8, 0x01, 0xb9, 0x01, 0xba, 0x01, 0xbb, +0x01, 0xbc, 0x01, 0xbd, 0x01, 0xbe, 0x01, 0xbf, 0x01, 0xc0, +0x01, 0xc1, 0x01, 0xc2, 0x01, 0xc3, 0x01, 0xc4, 0x01, 0xc5, +0x01, 0xc6, 0x01, 0xc7, 0x01, 0xc8, 0x01, 0xc9, 0x01, 0xca, +0x01, 0xcb, 0x01, 0xcc, 0x01, 0xcd, 0x01, 0xce, 0x01, 0xcf, +0x01, 0xd0, 0x01, 0xd1, 0x01, 0xd2, 0x01, 0xd3, 0x01, 0xd4, +0x01, 0xd5, 0x01, 0xd6, 0x01, 0xd7, 0x01, 0xd8, 0x01, 0xd9, +0x01, 0xda, 0x01, 0xdb, 0x01, 0xdc, 0x01, 0xdd, 0x01, 0xde, +0x01, 0xdf, 0x01, 0xe0, 0x01, 0xe1, 0x01, 0xe2, 0x01, 0xe3, +0x01, 0xe4, 0x01, 0xe5, 0x01, 0xe6, 0x01, 0xe7, 0x01, 0xe8, +0x01, 0xe9, 0x01, 0xea, 0x01, 0xeb, 0x01, 0xec, 0x01, 0xed, +0x01, 0xee, 0x01, 0xef, 0x01, 0xf0, 0x01, 0xf1, 0x01, 0xf2, +0x01, 0xf3, 0x01, 0xf4, 0x01, 0xf5, 0x01, 0xf6, 0x01, 0xf7, +0x01, 0xf8, 0x01, 0xf9, 0x01, 0xfa, 0x01, 0xfb, 0x01, 0xfc, +0x01, 0xfd, 0x01, 0xfe, 0x01, 0xff, 0x02, 0x00, 0x02, 0x01, +0x02, 0x02, 0x02, 0x03, 0x02, 0x04, 0x02, 0x05, 0x02, 0x06, +0x02, 0x07, 0x02, 0x08, 0x02, 0x09, 0x02, 0x0a, 0x02, 0x0b, +0x02, 0x0c, 0x02, 0x0d, 0x02, 0x0e, 0x02, 0x0f, 0x02, 0x10, +0x02, 0x11, 0x02, 0x12, 0x02, 0x13, 0x02, 0x14, 0x02, 0x15, +0x02, 0x16, 0x02, 0x17, 0x02, 0x18, 0x02, 0x19, 0x02, 0x1a, +0x02, 0x1b, 0x02, 0x1c, 0x02, 0x1d, 0x02, 0x1e, 0x02, 0x1f, +0x02, 0x20, 0x02, 0x21, 0x02, 0x22, 0x02, 0x23, 0x02, 0x24, +0x02, 0x25, 0x02, 0x26, 0x02, 0x27, 0x02, 0x28, 0x02, 0x29, +0x02, 0x2a, 0x02, 0x2b, 0x02, 0x2c, 0x02, 0x2d, 0x02, 0x2e, +0x02, 0x2f, 0x02, 0x30, 0x02, 0x31, 0x02, 0x32, 0x02, 0x33, +0x02, 0x34, 0x02, 0x35, 0x02, 0x36, 0x02, 0x37, 0x02, 0x38, +0x02, 0x39, 0x02, 0x3a, 0x02, 0x3b, 0x02, 0x3c, 0x02, 0x3d, +0x02, 0x3e, 0x02, 0x3f, 0x02, 0x40, 0x02, 0x41, 0x02, 0x42, +0x02, 0x43, 0x02, 0x44, 0x02, 0x45, 0x02, 0x46, 0x02, 0x47, +0x02, 0x48, 0x02, 0x49, 0x02, 0x4a, 0x02, 0x4b, 0x02, 0x4c, +0x02, 0x4d, 0x02, 0x4e, 0x02, 0x4f, 0x02, 0x50, 0x02, 0x51, +0x02, 0x52, 0x02, 0x53, 0x02, 0x54, 0x02, 0x55, 0x02, 0x56, +0x02, 0x57, 0x02, 0x58, 0x02, 0x59, 0x02, 0x5a, 0x02, 0x5b, +0x02, 0x5c, 0x02, 0x5d, 0x02, 0x5e, 0x02, 0x5f, 0x02, 0x60, +0x02, 0x61, 0x02, 0x62, 0x02, 0x63, 0x02, 0x64, 0x02, 0x65, +0x02, 0x66, 0x02, 0x67, 0x02, 0x68, 0x02, 0x69, 0x02, 0x6a, +0x02, 0x6b, 0x02, 0x6c, 0x02, 0x6d, 0x02, 0x6e, 0x02, 0x6f, +0x02, 0x70, 0x02, 0x71, 0x02, 0x72, 0x02, 0x73, 0x02, 0x74, +0x02, 0x75, 0x02, 0x76, 0x02, 0x77, 0x02, 0x78, 0x02, 0x79, +0x02, 0x7a, 0x02, 0x7b, 0x02, 0x7c, 0x02, 0x7d, 0x02, 0x7e, +0x02, 0x7f, 0x02, 0x80, 0x02, 0x81, 0x02, 0x82, 0x02, 0x83, +0x02, 0x84, 0x02, 0x85, 0x02, 0x86, 0x02, 0x87, 0x02, 0x88, +0x02, 0x89, 0x02, 0x8a, 0x02, 0x8b, 0x02, 0x8c, 0x02, 0x8d, +0x02, 0x8e, 0x02, 0x8f, 0x02, 0x90, 0x02, 0x91, 0x02, 0x92, +0x02, 0x93, 0x02, 0x94, 0x02, 0x95, 0x02, 0x96, 0x02, 0x97, +0x02, 0x98, 0x02, 0x99, 0x02, 0x9a, 0x02, 0x9b, 0x02, 0x9c, +0x02, 0x9d, 0x02, 0x9e, 0x02, 0x9f, 0x02, 0xa0, 0x02, 0xa1, +0x02, 0xa2, 0x02, 0xa3, 0x02, 0xa4, 0x02, 0xa5, 0x02, 0xa6, +0x02, 0xa7, 0x02, 0xa8, 0x02, 0xa9, 0x02, 0xaa, 0x02, 0xab, +0x02, 0xac, 0x02, 0xad, 0x02, 0xae, 0x02, 0xaf, 0x02, 0xb0, +0x02, 0xb1, 0x02, 0xb2, 0x02, 0xb3, 0x02, 0xb4, 0x02, 0xb5, +0x02, 0xb6, 0x02, 0xb7, 0x02, 0xb8, 0x02, 0xb9, 0x02, 0xba, +0x02, 0xbb, 0x02, 0xbc, 0x02, 0xbd, 0x02, 0xbe, 0x02, 0xbf, +0x02, 0xc0, 0x02, 0xc1, 0x02, 0xc2, 0x02, 0xc3, 0x02, 0xc4, +0x02, 0xc5, 0x02, 0xc6, 0x02, 0xc7, 0x02, 0xc8, 0x02, 0xc9, +0x02, 0xca, 0x02, 0xcb, 0x02, 0xcc, 0x02, 0xcd, 0x02, 0xce, +0x02, 0xcf, 0x02, 0xd0, 0x02, 0xd1, 0x02, 0xd2, 0x02, 0xd3, +0x02, 0xd4, 0x02, 0xd5, 0x02, 0xd6, 0x02, 0xd7, 0x02, 0xd8, +0x02, 0xd9, 0x02, 0xda, 0x02, 0xdb, 0x02, 0xdc, 0x02, 0xdd, +0x02, 0xde, 0x02, 0xdf, 0x02, 0xe0, 0x02, 0xe1, 0x02, 0xe2, +0x02, 0xe3, 0x02, 0xe4, 0x02, 0xe5, 0x02, 0xe6, 0x02, 0xe7, +0x02, 0xe8, 0x02, 0xe9, 0x02, 0xea, 0x02, 0xeb, 0x02, 0xec, +0x02, 0xed, 0x02, 0xee, 0x02, 0xef, 0x02, 0xf0, 0x02, 0xf1, +0x02, 0xf2, 0x02, 0xf3, 0x02, 0xf4, 0x02, 0xf5, 0x02, 0xf6, +0x02, 0xf7, 0x02, 0xf8, 0x02, 0xf9, 0x02, 0xfa, 0x02, 0xfb, +0x02, 0xfc, 0x02, 0xfd, 0x02, 0xfe, 0x02, 0xff, 0x03, 0x00, +0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x03, 0x04, 0x03, 0x05, +0x03, 0x06, 0x03, 0x07, 0x03, 0x08, 0x03, 0x09, 0x03, 0x0a, +0x03, 0x0b, 0x03, 0x0c, 0x03, 0x0d, 0x03, 0x0e, 0x03, 0x0f, +0x03, 0x10, 0x03, 0x11, 0x03, 0x12, 0x03, 0x13, 0x03, 0x14, +0x03, 0x15, 0x03, 0x16, 0x03, 0x17, 0x03, 0x18, 0x03, 0x19, +0x03, 0x1a, 0x03, 0x1b, 0x03, 0x1c, 0x03, 0x1d, 0x03, 0x1e, +0x03, 0x1f, 0x03, 0x20, 0x03, 0x21, 0x03, 0x22, 0x03, 0x23, +0x03, 0x24, 0x03, 0x25, 0x03, 0x26, 0x03, 0x27, 0x03, 0x28, +0x03, 0x29, 0x03, 0x2a, 0x03, 0x2b, 0x03, 0x2c, 0x03, 0x2d, +0x03, 0x2e, 0x03, 0x2f, 0x03, 0x30, 0x03, 0x31, 0x03, 0x32, +0x03, 0x33, 0x03, 0x34, 0x03, 0x35, 0x03, 0x36, 0x03, 0x37, +0x03, 0x38, 0x03, 0x39, 0x03, 0x3a, 0x03, 0x3b, 0x03, 0x3c, +0x03, 0x3d, 0x03, 0x3e, 0x03, 0x3f, 0x03, 0x40, 0x03, 0x41, +0x03, 0x42, 0x03, 0x43, 0x03, 0x44, 0x03, 0x45, 0x03, 0x46, +0x03, 0x47, 0x03, 0x48, 0x03, 0x49, 0x03, 0x4a, 0x03, 0x4b, +0x03, 0x4c, 0x03, 0x4d, 0x03, 0x4e, 0x03, 0x4f, 0x03, 0x50, +0x03, 0x51, 0x03, 0x52, 0x03, 0x53, 0x03, 0x54, 0x03, 0x55, +0x03, 0x56, 0x03, 0x57, 0x03, 0x58, 0x03, 0x59, 0x03, 0x5a, +0x03, 0x5b, 0x03, 0x5c, 0x03, 0x5d, 0x03, 0x5e, 0x03, 0x5f, +0x03, 0x60, 0x03, 0x61, 0x03, 0x62, 0x03, 0x63, 0x03, 0x64, +0x03, 0x65, 0x03, 0x66, 0x03, 0x67, 0x03, 0x68, 0x03, 0x69, +0x03, 0x6a, 0x03, 0x6b, 0x03, 0x6c, 0x03, 0x6d, 0x03, 0x6e, +0x03, 0x6f, 0x03, 0x70, 0x03, 0x71, 0x03, 0x72, 0x03, 0x73, +0x03, 0x74, 0x03, 0x75, 0x03, 0x76, 0x03, 0x77, 0x03, 0x78, +0x03, 0x79, 0x03, 0x7a, 0x03, 0x7b, 0x03, 0x7c, 0x03, 0x7d, +0x03, 0x7e, 0x03, 0x7f, 0x03, 0x80, 0x03, 0x81, 0x03, 0x82, +0x03, 0x83, 0x03, 0x84, 0x03, 0x85, 0x03, 0x86, 0x03, 0x87, +0x03, 0x88, 0x03, 0x89, 0x03, 0x8a, 0x03, 0x8b, 0x03, 0x8c, +0x03, 0x8d, 0x03, 0x8e, 0x03, 0x8f, 0x03, 0x90, 0x03, 0x91, +0x03, 0x92, 0x03, 0x93, 0x03, 0x94, 0x03, 0x95, 0x03, 0x96, +0x03, 0x97, 0x03, 0x98, 0x03, 0x99, 0x03, 0x9a, 0x03, 0x9b, +0x03, 0x9c, 0x03, 0x9d, 0x03, 0x9e, 0x03, 0x9f, 0x03, 0xa0, +0x03, 0xa1, 0x03, 0xa2, 0x03, 0xa3, 0x03, 0xa4, 0x03, 0xa5, +0x03, 0xa6, 0x03, 0xa7, 0x03, 0xa8, 0x03, 0xa9, 0x03, 0xaa, +0x03, 0xab, 0x03, 0xac, 0x03, 0xad, 0x03, 0xae, 0x03, 0xaf, +0x03, 0xb0, 0x03, 0xb1, 0x03, 0xb2, 0x00, 0x9f, 0x03, 0xb3, +0x03, 0xb4, 0x03, 0xb5, 0x03, 0xb6, 0x03, 0xb7, 0x03, 0xb8, +0x03, 0xb9, 0x03, 0xba, 0x03, 0xbb, 0x03, 0xbc, 0x03, 0xbd, +0x03, 0xbe, 0x03, 0xbf, 0x03, 0xc0, 0x03, 0xc1, 0x00, 0x9b, +0x03, 0xc2, 0x03, 0xc3, 0x03, 0xc4, 0x03, 0xc5, 0x03, 0xc6, +0x03, 0xc7, 0x03, 0xc8, 0x03, 0xc9, 0x03, 0xca, 0x03, 0xcb, +0x03, 0xcc, 0x03, 0xcd, 0x03, 0xce, 0x03, 0xcf, 0x03, 0xd0, +0x03, 0xd1, 0x03, 0xd2, 0x03, 0xd3, 0x03, 0xd4, 0x03, 0xd5, +0x03, 0xd6, 0x03, 0xd7, 0x03, 0xd8, 0x03, 0xd9, 0x03, 0xda, +0x03, 0xdb, 0x03, 0xdc, 0x03, 0xdd, 0x03, 0xde, 0x03, 0xdf, +0x03, 0xe0, 0x03, 0xe1, 0x03, 0xe2, 0x03, 0xe3, 0x03, 0xe4, +0x03, 0xe5, 0x03, 0xe6, 0x03, 0xe7, 0x03, 0xe8, 0x03, 0xe9, +0x03, 0xea, 0x03, 0xeb, 0x03, 0xec, 0x03, 0xed, 0x03, 0xee, +0x03, 0xef, 0x03, 0xf0, 0x03, 0xf1, 0x03, 0xf2, 0x03, 0xf3, +0x03, 0xf4, 0x03, 0xf5, 0x03, 0xf6, 0x03, 0xf7, 0x03, 0xf8, +0x03, 0xf9, 0x03, 0xfa, 0x03, 0xfb, 0x03, 0xfc, 0x03, 0xfd, +0x03, 0xfe, 0x03, 0xff, 0x04, 0x00, 0x04, 0x01, 0x04, 0x02, +0x04, 0x03, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, +0x04, 0x08, 0x04, 0x09, 0x04, 0x0a, 0x04, 0x0b, 0x04, 0x0c, +0x04, 0x0d, 0x04, 0x0e, 0x04, 0x0f, 0x04, 0x10, 0x04, 0x11, +0x04, 0x12, 0x04, 0x13, 0x04, 0x14, 0x04, 0x15, 0x04, 0x16, +0x04, 0x17, 0x04, 0x18, 0x04, 0x19, 0x04, 0x1a, 0x04, 0x1b, +0x04, 0x1c, 0x04, 0x1d, 0x04, 0x1e, 0x04, 0x1f, 0x04, 0x20, +0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, 0x24, 0x04, 0x25, +0x04, 0x26, 0x04, 0x27, 0x04, 0x28, 0x04, 0x29, 0x04, 0x2a, +0x04, 0x2b, 0x04, 0x2c, 0x04, 0x2d, 0x04, 0x2e, 0x04, 0x2f, +0x04, 0x30, 0x04, 0x31, 0x04, 0x32, 0x04, 0x33, 0x04, 0x34, +0x04, 0x35, 0x04, 0x36, 0x04, 0x37, 0x04, 0x38, 0x04, 0x39, +0x04, 0x3a, 0x04, 0x3b, 0x04, 0x3c, 0x04, 0x3d, 0x04, 0x3e, +0x04, 0x3f, 0x04, 0x40, 0x04, 0x41, 0x04, 0x42, 0x04, 0x43, +0x04, 0x44, 0x04, 0x45, 0x04, 0x46, 0x04, 0x47, 0x04, 0x48, +0x04, 0x49, 0x04, 0x4a, 0x04, 0x4b, 0x04, 0x4c, 0x04, 0x4d, +0x04, 0x4e, 0x04, 0x4f, 0x04, 0x50, 0x04, 0x51, 0x04, 0x52, +0x04, 0x53, 0x04, 0x54, 0x04, 0x55, 0x04, 0x56, 0x04, 0x57, +0x04, 0x58, 0x04, 0x59, 0x04, 0x5a, 0x04, 0x5b, 0x04, 0x5c, +0x04, 0x5d, 0x04, 0x5e, 0x04, 0x5f, 0x04, 0x60, 0x04, 0x61, +0x04, 0x62, 0x04, 0x63, 0x04, 0x64, 0x04, 0x65, 0x04, 0x66, +0x04, 0x67, 0x04, 0x68, 0x04, 0x69, 0x04, 0x6a, 0x04, 0x6b, +0x04, 0x6c, 0x04, 0x6d, 0x04, 0x6e, 0x04, 0x6f, 0x04, 0x70, +0x04, 0x71, 0x04, 0x72, 0x04, 0x73, 0x04, 0x74, 0x04, 0x75, +0x04, 0x76, 0x04, 0x77, 0x04, 0x78, 0x04, 0x79, 0x04, 0x7a, +0x04, 0x7b, 0x04, 0x7c, 0x04, 0x7d, 0x04, 0x7e, 0x04, 0x7f, +0x04, 0x80, 0x04, 0x81, 0x04, 0x82, 0x04, 0x83, 0x04, 0x84, +0x04, 0x85, 0x04, 0x86, 0x04, 0x87, 0x04, 0x88, 0x04, 0x89, +0x04, 0x8a, 0x04, 0x8b, 0x04, 0x8c, 0x04, 0x8d, 0x04, 0x8e, +0x04, 0x8f, 0x04, 0x90, 0x04, 0x91, 0x04, 0x92, 0x04, 0x93, +0x04, 0x94, 0x04, 0x95, 0x04, 0x96, 0x04, 0x97, 0x04, 0x98, +0x04, 0x99, 0x04, 0x9a, 0x04, 0x9b, 0x04, 0x9c, 0x04, 0x9d, +0x04, 0x9e, 0x04, 0x9f, 0x04, 0xa0, 0x04, 0xa1, 0x04, 0xa2, +0x04, 0xa3, 0x04, 0xa4, 0x04, 0xa5, 0x04, 0xa6, 0x04, 0xa7, +0x04, 0xa8, 0x04, 0xa9, 0x04, 0xaa, 0x04, 0xab, 0x04, 0xac, +0x04, 0xad, 0x04, 0xae, 0x04, 0xaf, 0x04, 0xb0, 0x04, 0xb1, +0x04, 0xb2, 0x04, 0xb3, 0x04, 0xb4, 0x04, 0xb5, 0x04, 0xb6, +0x04, 0xb7, 0x04, 0xb8, 0x04, 0xb9, 0x04, 0xba, 0x04, 0xbb, +0x04, 0xbc, 0x04, 0xbd, 0x04, 0xbe, 0x04, 0xbf, 0x04, 0xc0, +0x04, 0xc1, 0x04, 0xc2, 0x04, 0xc3, 0x04, 0xc4, 0x04, 0xc5, +0x04, 0xc6, 0x04, 0xc7, 0x04, 0xc8, 0x04, 0xc9, 0x04, 0xca, +0x04, 0xcb, 0x04, 0xcc, 0x04, 0xcd, 0x04, 0xce, 0x04, 0xcf, +0x04, 0xd0, 0x04, 0xd1, 0x04, 0xd2, 0x04, 0xd3, 0x04, 0xd4, +0x04, 0xd5, 0x04, 0xd6, 0x04, 0xd7, 0x04, 0xd8, 0x04, 0xd9, +0x04, 0xda, 0x04, 0xdb, 0x04, 0xdc, 0x04, 0xdd, 0x04, 0xde, +0x04, 0xdf, 0x04, 0xe0, 0x04, 0xe1, 0x04, 0xe2, 0x04, 0xe3, +0x04, 0xe4, 0x04, 0xe5, 0x04, 0xe6, 0x04, 0xe7, 0x04, 0xe8, +0x04, 0xe9, 0x04, 0xea, 0x05, 0x19, 0x05, 0x1a, 0x05, 0x1b, +0x05, 0x1c, 0x05, 0x1d, 0x05, 0x1e, 0x05, 0x1f, 0x05, 0x20, +0x05, 0x21, 0x05, 0x22, 0x04, 0xf5, 0x04, 0xf6, 0x05, 0x23, +0x04, 0xf8, 0x04, 0xf9, 0x04, 0xfa, 0x04, 0xfb, 0x04, 0xfc, +0x04, 0xfd, 0x04, 0xfe, 0x04, 0xff, 0x05, 0x00, 0x05, 0x01, +0x05, 0x02, 0x05, 0x03, 0x05, 0x04, 0x05, 0x05, 0x05, 0x06, +0x05, 0x07, 0x05, 0x08, 0x05, 0x09, 0x05, 0x0a, 0x05, 0x0b, +0x05, 0x0c, 0x05, 0x0d, 0x05, 0x0e, 0x05, 0x0f, 0x05, 0x10, +0x05, 0x11, 0x05, 0x12, 0x05, 0x13, 0x05, 0x14, 0x05, 0x15, +0x05, 0x16, 0x05, 0x17, 0x05, 0x18, 0x05, 0x2e, 0x6e, 0x75, +0x6c, 0x6c, 0x04, 0x45, 0x75, 0x72, 0x6f, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x30, 0x41, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x30, 0x41, 0x44, 0x06, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, +0x0e, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x63, 0x65, 0x6e, +0x74, 0x65, 0x72, 0x65, 0x64, 0x07, 0x41, 0x6d, 0x61, 0x63, +0x72, 0x6f, 0x6e, 0x07, 0x61, 0x6d, 0x61, 0x63, 0x72, 0x6f, +0x6e, 0x06, 0x41, 0x62, 0x72, 0x65, 0x76, 0x65, 0x06, 0x61, +0x62, 0x72, 0x65, 0x76, 0x65, 0x07, 0x41, 0x6f, 0x67, 0x6f, +0x6e, 0x65, 0x6b, 0x07, 0x61, 0x6f, 0x67, 0x6f, 0x6e, 0x65, +0x6b, 0x0b, 0x43, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, +0x6c, 0x65, 0x78, 0x0b, 0x63, 0x63, 0x69, 0x72, 0x63, 0x75, +0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0a, 0x43, 0x64, 0x6f, 0x74, +0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0a, 0x63, 0x64, 0x6f, +0x74, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x06, 0x44, 0x63, +0x61, 0x72, 0x6f, 0x6e, 0x06, 0x64, 0x63, 0x61, 0x72, 0x6f, +0x6e, 0x06, 0x44, 0x63, 0x72, 0x6f, 0x61, 0x74, 0x06, 0x64, +0x63, 0x72, 0x6f, 0x61, 0x74, 0x07, 0x45, 0x6d, 0x61, 0x63, +0x72, 0x6f, 0x6e, 0x07, 0x65, 0x6d, 0x61, 0x63, 0x72, 0x6f, +0x6e, 0x06, 0x45, 0x62, 0x72, 0x65, 0x76, 0x65, 0x06, 0x65, +0x62, 0x72, 0x65, 0x76, 0x65, 0x0a, 0x45, 0x64, 0x6f, 0x74, +0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0a, 0x65, 0x64, 0x6f, +0x74, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x07, 0x45, 0x6f, +0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x07, 0x65, 0x6f, 0x67, 0x6f, +0x6e, 0x65, 0x6b, 0x06, 0x45, 0x63, 0x61, 0x72, 0x6f, 0x6e, +0x06, 0x65, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x0b, 0x47, 0x63, +0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0b, +0x67, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, +0x78, 0x0a, 0x47, 0x64, 0x6f, 0x74, 0x61, 0x63, 0x63, 0x65, +0x6e, 0x74, 0x0a, 0x67, 0x64, 0x6f, 0x74, 0x61, 0x63, 0x63, +0x65, 0x6e, 0x74, 0x0c, 0x47, 0x63, 0x6f, 0x6d, 0x6d, 0x61, +0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x67, 0x63, 0x6f, +0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0b, +0x48, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, +0x78, 0x0b, 0x68, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, +0x6c, 0x65, 0x78, 0x04, 0x48, 0x62, 0x61, 0x72, 0x04, 0x68, +0x62, 0x61, 0x72, 0x06, 0x49, 0x74, 0x69, 0x6c, 0x64, 0x65, +0x06, 0x69, 0x74, 0x69, 0x6c, 0x64, 0x65, 0x07, 0x49, 0x6d, +0x61, 0x63, 0x72, 0x6f, 0x6e, 0x07, 0x69, 0x6d, 0x61, 0x63, +0x72, 0x6f, 0x6e, 0x06, 0x49, 0x62, 0x72, 0x65, 0x76, 0x65, +0x06, 0x69, 0x62, 0x72, 0x65, 0x76, 0x65, 0x07, 0x49, 0x6f, +0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x07, 0x69, 0x6f, 0x67, 0x6f, +0x6e, 0x65, 0x6b, 0x0a, 0x49, 0x64, 0x6f, 0x74, 0x61, 0x63, +0x63, 0x65, 0x6e, 0x74, 0x06, 0x69, 0x2e, 0x6c, 0x6f, 0x63, +0x6c, 0x02, 0x49, 0x4a, 0x02, 0x69, 0x6a, 0x0b, 0x4a, 0x63, +0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0b, +0x6a, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, +0x78, 0x0c, 0x4b, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63, +0x63, 0x65, 0x6e, 0x74, 0x0c, 0x6b, 0x63, 0x6f, 0x6d, 0x6d, +0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x11, 0x6b, 0x67, +0x72, 0x65, 0x65, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x69, 0x63, +0x2e, 0x63, 0x61, 0x73, 0x65, 0x0c, 0x6b, 0x67, 0x72, 0x65, +0x65, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x69, 0x63, 0x06, 0x4c, +0x61, 0x63, 0x75, 0x74, 0x65, 0x06, 0x6c, 0x61, 0x63, 0x75, +0x74, 0x65, 0x0c, 0x4c, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, +0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x6c, 0x63, 0x6f, 0x6d, +0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x06, 0x4c, +0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, 0x6c, 0x63, 0x61, 0x72, +0x6f, 0x6e, 0x04, 0x4c, 0x64, 0x6f, 0x74, 0x04, 0x6c, 0x64, +0x6f, 0x74, 0x06, 0x4e, 0x61, 0x63, 0x75, 0x74, 0x65, 0x06, +0x6e, 0x61, 0x63, 0x75, 0x74, 0x65, 0x0c, 0x4e, 0x63, 0x6f, +0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, +0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, +0x6e, 0x74, 0x06, 0x4e, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, +0x6e, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x10, 0x6e, 0x61, 0x70, +0x6f, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x68, 0x65, 0x2e, 0x63, +0x61, 0x73, 0x65, 0x0b, 0x6e, 0x61, 0x70, 0x6f, 0x73, 0x74, +0x72, 0x6f, 0x70, 0x68, 0x65, 0x03, 0x45, 0x6e, 0x67, 0x03, +0x65, 0x6e, 0x67, 0x07, 0x4f, 0x6d, 0x61, 0x63, 0x72, 0x6f, +0x6e, 0x07, 0x6f, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x06, +0x4f, 0x62, 0x72, 0x65, 0x76, 0x65, 0x06, 0x6f, 0x62, 0x72, +0x65, 0x76, 0x65, 0x0d, 0x4f, 0x68, 0x75, 0x6e, 0x67, 0x61, +0x72, 0x75, 0x6d, 0x6c, 0x61, 0x75, 0x74, 0x0d, 0x6f, 0x68, +0x75, 0x6e, 0x67, 0x61, 0x72, 0x75, 0x6d, 0x6c, 0x61, 0x75, +0x74, 0x06, 0x52, 0x61, 0x63, 0x75, 0x74, 0x65, 0x06, 0x72, +0x61, 0x63, 0x75, 0x74, 0x65, 0x0c, 0x52, 0x63, 0x6f, 0x6d, +0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x72, +0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, +0x74, 0x06, 0x52, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, 0x72, +0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, 0x53, 0x61, 0x63, 0x75, +0x74, 0x65, 0x06, 0x73, 0x61, 0x63, 0x75, 0x74, 0x65, 0x0b, +0x53, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, +0x78, 0x0b, 0x73, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, +0x6c, 0x65, 0x78, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x36, +0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x36, 0x33, 0x06, +0x54, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, 0x74, 0x63, 0x61, +0x72, 0x6f, 0x6e, 0x04, 0x54, 0x62, 0x61, 0x72, 0x04, 0x74, +0x62, 0x61, 0x72, 0x06, 0x55, 0x74, 0x69, 0x6c, 0x64, 0x65, +0x06, 0x75, 0x74, 0x69, 0x6c, 0x64, 0x65, 0x07, 0x55, 0x6d, +0x61, 0x63, 0x72, 0x6f, 0x6e, 0x07, 0x75, 0x6d, 0x61, 0x63, +0x72, 0x6f, 0x6e, 0x06, 0x55, 0x62, 0x72, 0x65, 0x76, 0x65, +0x06, 0x75, 0x62, 0x72, 0x65, 0x76, 0x65, 0x05, 0x55, 0x72, +0x69, 0x6e, 0x67, 0x05, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x0d, +0x55, 0x68, 0x75, 0x6e, 0x67, 0x61, 0x72, 0x75, 0x6d, 0x6c, +0x61, 0x75, 0x74, 0x0d, 0x75, 0x68, 0x75, 0x6e, 0x67, 0x61, +0x72, 0x75, 0x6d, 0x6c, 0x61, 0x75, 0x74, 0x07, 0x55, 0x6f, +0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x07, 0x75, 0x6f, 0x67, 0x6f, +0x6e, 0x65, 0x6b, 0x0b, 0x57, 0x63, 0x69, 0x72, 0x63, 0x75, +0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0b, 0x77, 0x63, 0x69, 0x72, +0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0b, 0x59, 0x63, +0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0b, +0x79, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, +0x78, 0x06, 0x5a, 0x61, 0x63, 0x75, 0x74, 0x65, 0x06, 0x7a, +0x61, 0x63, 0x75, 0x74, 0x65, 0x0a, 0x5a, 0x64, 0x6f, 0x74, +0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0a, 0x7a, 0x64, 0x6f, +0x74, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x05, 0x6c, 0x6f, +0x6e, 0x67, 0x73, 0x0c, 0x53, 0x63, 0x6f, 0x6d, 0x6d, 0x61, +0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x73, 0x63, 0x6f, +0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x41, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x31, 0x42, 0x08, 0x64, 0x6f, 0x74, 0x6c, +0x65, 0x73, 0x73, 0x6a, 0x0a, 0x61, 0x70, 0x6f, 0x73, 0x74, +0x72, 0x6f, 0x70, 0x68, 0x65, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x43, 0x39, 0x06, 0x57, 0x67, 0x72, 0x61, 0x76, 0x65, +0x06, 0x77, 0x67, 0x72, 0x61, 0x76, 0x65, 0x06, 0x57, 0x61, +0x63, 0x75, 0x74, 0x65, 0x06, 0x77, 0x61, 0x63, 0x75, 0x74, +0x65, 0x09, 0x57, 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, +0x73, 0x09, 0x77, 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, +0x73, 0x06, 0x59, 0x67, 0x72, 0x61, 0x76, 0x65, 0x06, 0x79, +0x67, 0x72, 0x61, 0x76, 0x65, 0x0c, 0x7a, 0x65, 0x72, 0x6f, +0x73, 0x75, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x72, 0x0c, 0x66, +0x6f, 0x75, 0x72, 0x73, 0x75, 0x70, 0x65, 0x72, 0x69, 0x6f, +0x72, 0x0c, 0x66, 0x69, 0x76, 0x65, 0x73, 0x75, 0x70, 0x65, +0x72, 0x69, 0x6f, 0x72, 0x0b, 0x73, 0x69, 0x78, 0x73, 0x75, +0x70, 0x65, 0x72, 0x69, 0x6f, 0x72, 0x0d, 0x73, 0x65, 0x76, +0x65, 0x6e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x72, +0x0d, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x75, 0x70, 0x65, +0x72, 0x69, 0x6f, 0x72, 0x0c, 0x6e, 0x69, 0x6e, 0x65, 0x73, +0x75, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x72, 0x0c, 0x7a, 0x65, +0x72, 0x6f, 0x69, 0x6e, 0x66, 0x65, 0x72, 0x69, 0x6f, 0x72, +0x0b, 0x6f, 0x6e, 0x65, 0x69, 0x6e, 0x66, 0x65, 0x72, 0x69, +0x6f, 0x72, 0x0b, 0x74, 0x77, 0x6f, 0x69, 0x6e, 0x66, 0x65, +0x72, 0x69, 0x6f, 0x72, 0x0d, 0x74, 0x68, 0x72, 0x65, 0x65, +0x69, 0x6e, 0x66, 0x65, 0x72, 0x69, 0x6f, 0x72, 0x0c, 0x66, +0x6f, 0x75, 0x72, 0x69, 0x6e, 0x66, 0x65, 0x72, 0x69, 0x6f, +0x72, 0x0c, 0x66, 0x69, 0x76, 0x65, 0x69, 0x6e, 0x66, 0x65, +0x72, 0x69, 0x6f, 0x72, 0x0b, 0x73, 0x69, 0x78, 0x69, 0x6e, +0x66, 0x65, 0x72, 0x69, 0x6f, 0x72, 0x0d, 0x73, 0x65, 0x76, +0x65, 0x6e, 0x69, 0x6e, 0x66, 0x65, 0x72, 0x69, 0x6f, 0x72, +0x0d, 0x65, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x66, 0x65, +0x72, 0x69, 0x6f, 0x72, 0x0c, 0x6e, 0x69, 0x6e, 0x65, 0x69, +0x6e, 0x66, 0x65, 0x72, 0x69, 0x6f, 0x72, 0x09, 0x61, 0x66, +0x69, 0x69, 0x36, 0x31, 0x32, 0x38, 0x39, 0x09, 0x65, 0x73, +0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x08, 0x6f, 0x6e, +0x65, 0x74, 0x68, 0x69, 0x72, 0x64, 0x09, 0x74, 0x77, 0x6f, +0x74, 0x68, 0x69, 0x72, 0x64, 0x73, 0x09, 0x6f, 0x6e, 0x65, +0x65, 0x69, 0x67, 0x68, 0x74, 0x68, 0x0c, 0x74, 0x68, 0x72, +0x65, 0x65, 0x65, 0x69, 0x67, 0x68, 0x74, 0x68, 0x73, 0x0b, +0x66, 0x69, 0x76, 0x65, 0x65, 0x69, 0x67, 0x68, 0x74, 0x68, +0x73, 0x0c, 0x73, 0x65, 0x76, 0x65, 0x6e, 0x65, 0x69, 0x67, +0x68, 0x74, 0x68, 0x73, 0x08, 0x6f, 0x6e, 0x65, 0x66, 0x69, +0x66, 0x74, 0x68, 0x09, 0x74, 0x77, 0x6f, 0x66, 0x69, 0x66, +0x74, 0x68, 0x73, 0x0b, 0x74, 0x68, 0x72, 0x65, 0x65, 0x66, +0x69, 0x66, 0x74, 0x68, 0x73, 0x0a, 0x66, 0x6f, 0x75, 0x72, +0x66, 0x69, 0x66, 0x74, 0x68, 0x73, 0x08, 0x6f, 0x6e, 0x65, +0x73, 0x69, 0x78, 0x74, 0x68, 0x0a, 0x66, 0x69, 0x76, 0x65, +0x73, 0x69, 0x78, 0x74, 0x68, 0x73, 0x0a, 0x6f, 0x6e, 0x65, +0x73, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, 0x0b, 0x74, 0x77, +0x6f, 0x73, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, 0x73, 0x0d, +0x74, 0x68, 0x72, 0x65, 0x65, 0x73, 0x65, 0x76, 0x65, 0x6e, +0x74, 0x68, 0x73, 0x0c, 0x66, 0x6f, 0x75, 0x72, 0x73, 0x65, +0x76, 0x65, 0x6e, 0x74, 0x68, 0x73, 0x0c, 0x66, 0x69, 0x76, +0x65, 0x73, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, 0x73, 0x0b, +0x73, 0x69, 0x78, 0x73, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, +0x73, 0x08, 0x6f, 0x6e, 0x65, 0x6e, 0x69, 0x6e, 0x74, 0x68, +0x09, 0x74, 0x77, 0x6f, 0x6e, 0x69, 0x6e, 0x74, 0x68, 0x73, +0x0a, 0x66, 0x6f, 0x75, 0x72, 0x6e, 0x69, 0x6e, 0x74, 0x68, +0x73, 0x0a, 0x66, 0x69, 0x76, 0x65, 0x6e, 0x69, 0x6e, 0x74, +0x68, 0x73, 0x0b, 0x73, 0x65, 0x76, 0x65, 0x6e, 0x6e, 0x69, +0x6e, 0x74, 0x68, 0x73, 0x0b, 0x65, 0x69, 0x67, 0x68, 0x74, +0x6e, 0x69, 0x6e, 0x74, 0x68, 0x73, 0x05, 0x44, 0x65, 0x6c, +0x74, 0x61, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x32, 0x36, +0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x31, 0x35, 0x07, 0x75, +0x6e, 0x69, 0x32, 0x32, 0x31, 0x39, 0x03, 0x66, 0x5f, 0x69, +0x03, 0x66, 0x5f, 0x6c, 0x09, 0x7a, 0x65, 0x72, 0x6f, 0x2e, +0x73, 0x75, 0x70, 0x73, 0x08, 0x6f, 0x6e, 0x65, 0x2e, 0x73, +0x75, 0x70, 0x73, 0x08, 0x74, 0x77, 0x6f, 0x2e, 0x73, 0x75, +0x70, 0x73, 0x0a, 0x74, 0x68, 0x72, 0x65, 0x65, 0x2e, 0x73, +0x75, 0x70, 0x73, 0x09, 0x66, 0x6f, 0x75, 0x72, 0x2e, 0x73, +0x75, 0x70, 0x73, 0x09, 0x66, 0x69, 0x76, 0x65, 0x2e, 0x73, +0x75, 0x70, 0x73, 0x08, 0x73, 0x69, 0x78, 0x2e, 0x73, 0x75, +0x70, 0x73, 0x0a, 0x73, 0x65, 0x76, 0x65, 0x6e, 0x2e, 0x73, +0x75, 0x70, 0x73, 0x0a, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2e, +0x73, 0x75, 0x70, 0x73, 0x09, 0x6e, 0x69, 0x6e, 0x65, 0x2e, +0x73, 0x75, 0x70, 0x73, 0x09, 0x7a, 0x65, 0x72, 0x6f, 0x2e, +0x73, 0x69, 0x6e, 0x66, 0x08, 0x6f, 0x6e, 0x65, 0x2e, 0x73, +0x69, 0x6e, 0x66, 0x08, 0x74, 0x77, 0x6f, 0x2e, 0x73, 0x69, +0x6e, 0x66, 0x0a, 0x74, 0x68, 0x72, 0x65, 0x65, 0x2e, 0x73, +0x69, 0x6e, 0x66, 0x09, 0x66, 0x6f, 0x75, 0x72, 0x2e, 0x73, +0x69, 0x6e, 0x66, 0x09, 0x66, 0x69, 0x76, 0x65, 0x2e, 0x73, +0x69, 0x6e, 0x66, 0x08, 0x73, 0x69, 0x78, 0x2e, 0x73, 0x69, +0x6e, 0x66, 0x0a, 0x73, 0x65, 0x76, 0x65, 0x6e, 0x2e, 0x73, +0x69, 0x6e, 0x66, 0x0a, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2e, +0x73, 0x69, 0x6e, 0x66, 0x09, 0x6e, 0x69, 0x6e, 0x65, 0x2e, +0x73, 0x69, 0x6e, 0x66, 0x09, 0x63, 0x61, 0x72, 0x6f, 0x6e, +0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x61, +0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0e, 0x72, 0x65, 0x76, +0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, +0x74, 0x0f, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x2e, 0x61, 0x6c, +0x74, 0x2e, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x09, 0x50, 0x61, +0x72, 0x65, 0x6e, 0x6c, 0x65, 0x66, 0x74, 0x0a, 0x50, 0x61, +0x72, 0x65, 0x6e, 0x72, 0x69, 0x67, 0x68, 0x74, 0x06, 0x48, +0x79, 0x70, 0x68, 0x65, 0x6e, 0x05, 0x53, 0x6c, 0x61, 0x73, +0x68, 0x02, 0x41, 0x74, 0x0b, 0x42, 0x72, 0x61, 0x63, 0x6b, +0x65, 0x74, 0x6c, 0x65, 0x66, 0x74, 0x09, 0x42, 0x61, 0x63, +0x6b, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x0c, 0x42, 0x72, 0x61, +0x63, 0x6b, 0x65, 0x74, 0x72, 0x69, 0x67, 0x68, 0x74, 0x09, +0x42, 0x72, 0x61, 0x63, 0x65, 0x6c, 0x65, 0x66, 0x74, 0x0a, +0x42, 0x72, 0x61, 0x63, 0x65, 0x72, 0x69, 0x67, 0x68, 0x74, +0x0d, 0x47, 0x75, 0x69, 0x6c, 0x73, 0x69, 0x6e, 0x67, 0x6c, +0x6c, 0x65, 0x66, 0x74, 0x06, 0x42, 0x75, 0x6c, 0x6c, 0x65, +0x74, 0x06, 0x45, 0x6e, 0x64, 0x61, 0x73, 0x68, 0x06, 0x45, +0x6d, 0x64, 0x61, 0x73, 0x68, 0x0e, 0x47, 0x75, 0x69, 0x6c, +0x73, 0x69, 0x6e, 0x67, 0x6c, 0x72, 0x69, 0x67, 0x68, 0x74, +0x0a, 0x45, 0x78, 0x63, 0x6c, 0x61, 0x6d, 0x64, 0x6f, 0x77, +0x6e, 0x0d, 0x47, 0x75, 0x69, 0x6c, 0x6c, 0x65, 0x6d, 0x6f, +0x74, 0x6c, 0x65, 0x66, 0x74, 0x0e, 0x47, 0x75, 0x69, 0x6c, +0x6c, 0x65, 0x6d, 0x6f, 0x74, 0x72, 0x69, 0x67, 0x68, 0x74, +0x0c, 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x64, +0x6f, 0x77, 0x6e, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, +0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, 0x31, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, 0x32, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x38, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x38, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, +0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, 0x36, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, 0x37, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x38, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x38, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, +0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, 0x42, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, 0x43, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x38, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x38, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, +0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, 0x30, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, 0x31, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x39, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x39, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, +0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, 0x36, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, 0x37, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x39, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x39, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, +0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, 0x42, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, 0x43, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x39, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x39, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, +0x46, 0x05, 0x4f, 0x68, 0x6f, 0x72, 0x6e, 0x05, 0x6f, 0x68, +0x6f, 0x72, 0x6e, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x41, +0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x41, 0x33, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x41, 0x34, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x41, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x41, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x41, +0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x41, 0x38, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x41, 0x39, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x41, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x41, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x41, +0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x41, 0x44, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x41, 0x45, 0x05, 0x55, 0x68, +0x6f, 0x72, 0x6e, 0x05, 0x75, 0x68, 0x6f, 0x72, 0x6e, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, 0x31, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x42, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x42, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, +0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, 0x35, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, 0x36, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x42, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x42, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, +0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, 0x41, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, 0x42, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x42, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x42, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, +0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, 0x46, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x43, 0x30, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x43, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x43, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x43, +0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x43, 0x34, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x43, 0x35, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x43, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x43, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x43, +0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x43, 0x39, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x43, 0x41, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x43, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x43, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x43, +0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x43, 0x45, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x43, 0x46, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x44, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x44, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, +0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, 0x33, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, 0x34, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x44, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x44, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, +0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, 0x38, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, 0x39, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x44, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x44, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, +0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, 0x44, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, 0x45, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x44, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x45, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x45, +0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x45, 0x32, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x45, 0x33, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x45, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x45, 0x35, 0x06, 0x47, 0x63, 0x61, 0x72, 0x6f, 0x6e, +0x06, 0x67, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x45, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x45, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x45, +0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x45, 0x42, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x45, 0x43, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x45, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x45, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x45, +0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x46, 0x30, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x46, 0x31, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x46, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x46, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x46, +0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x46, 0x35, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x31, 0x46, 0x36, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x31, 0x46, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x31, 0x46, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x46, +0x39, 0x0a, 0x41, 0x72, 0x69, 0x6e, 0x67, 0x61, 0x63, 0x75, +0x74, 0x65, 0x0a, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x61, 0x63, +0x75, 0x74, 0x65, 0x07, 0x41, 0x45, 0x61, 0x63, 0x75, 0x74, +0x65, 0x07, 0x61, 0x65, 0x61, 0x63, 0x75, 0x74, 0x65, 0x0b, +0x4f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x61, 0x63, 0x75, 0x74, +0x65, 0x0b, 0x6f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x61, 0x63, +0x75, 0x74, 0x65, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, +0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x31, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x32, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x30, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x30, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, +0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x36, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x37, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x30, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x30, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, +0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x42, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x43, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x30, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x30, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, +0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x30, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x31, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x31, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x31, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, +0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x35, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x36, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x31, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x31, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, +0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x45, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x46, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x32, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x32, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, +0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, 0x33, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, 0x34, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x32, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x32, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, +0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, 0x38, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, 0x39, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x32, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x32, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, +0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, 0x44, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, 0x45, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x32, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x33, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, +0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x32, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x33, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x33, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x33, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, +0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x38, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x39, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x33, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x33, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, +0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x44, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x45, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x33, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x34, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x34, +0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x34, 0x32, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x34, 0x33, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x34, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x34, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x34, +0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x34, 0x37, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x34, 0x38, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x34, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x34, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x34, +0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x34, 0x43, 0x07, +0x75, 0x6e, 0x69, 0x30, 0x32, 0x34, 0x44, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x32, 0x34, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x32, 0x34, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x39, +0x32, 0x0e, 0x62, 0x72, 0x65, 0x76, 0x65, 0x5f, 0x69, 0x6e, +0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x0c, 0x64, 0x6f, 0x75, +0x62, 0x6c, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x76, 0x65, 0x0a, +0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x63, 0x75, 0x74, 0x65, +0x0f, 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x5f, +0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x0a, 0x64, 0x6f, 0x74, +0x5f, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x0e, 0x64, 0x69, +0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x67, 0x72, 0x61, +0x76, 0x65, 0x0e, 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, +0x73, 0x5f, 0x61, 0x63, 0x75, 0x74, 0x65, 0x0e, 0x64, 0x69, +0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x62, 0x72, 0x65, +0x76, 0x65, 0x0c, 0x74, 0x69, 0x6c, 0x64, 0x65, 0x5f, 0x6d, +0x61, 0x63, 0x72, 0x6f, 0x6e, 0x09, 0x61, 0x63, 0x75, 0x74, +0x65, 0x2e, 0x61, 0x73, 0x63, 0x0e, 0x63, 0x69, 0x72, 0x63, +0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x2e, 0x61, 0x73, 0x63, +0x09, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x2e, 0x61, 0x73, 0x63, +0x12, 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x5f, +0x67, 0x72, 0x61, 0x76, 0x65, 0x2e, 0x63, 0x61, 0x70, 0x12, +0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x61, +0x63, 0x75, 0x74, 0x65, 0x2e, 0x63, 0x61, 0x70, 0x12, 0x64, +0x69, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x62, 0x72, +0x65, 0x76, 0x65, 0x2e, 0x63, 0x61, 0x70, 0x07, 0x75, 0x6e, +0x69, 0x30, 0x34, 0x30, 0x30, 0x09, 0x61, 0x66, 0x69, 0x69, +0x31, 0x30, 0x30, 0x32, 0x33, 0x09, 0x61, 0x66, 0x69, 0x69, +0x31, 0x30, 0x30, 0x35, 0x31, 0x09, 0x61, 0x66, 0x69, 0x69, +0x31, 0x30, 0x30, 0x35, 0x32, 0x09, 0x61, 0x66, 0x69, 0x69, +0x31, 0x30, 0x30, 0x35, 0x33, 0x09, 0x61, 0x66, 0x69, 0x69, +0x31, 0x30, 0x30, 0x35, 0x34, 0x09, 0x61, 0x66, 0x69, 0x69, +0x31, 0x30, 0x30, 0x35, 0x35, 0x09, 0x61, 0x66, 0x69, 0x69, +0x31, 0x30, 0x30, 0x35, 0x36, 0x09, 0x61, 0x66, 0x69, 0x69, +0x31, 0x30, 0x30, 0x35, 0x37, 0x09, 0x61, 0x66, 0x69, 0x69, +0x31, 0x30, 0x30, 0x35, 0x38, 0x09, 0x61, 0x66, 0x69, 0x69, +0x31, 0x30, 0x30, 0x35, 0x39, 0x09, 0x61, 0x66, 0x69, 0x69, +0x31, 0x30, 0x30, 0x36, 0x30, 0x09, 0x61, 0x66, 0x69, 0x69, +0x31, 0x30, 0x30, 0x36, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x34, 0x30, 0x44, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x36, 0x32, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x31, 0x34, 0x35, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x31, 0x37, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x31, 0x38, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x31, 0x39, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x32, 0x30, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x32, 0x31, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x32, 0x32, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x32, 0x34, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x32, 0x35, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x32, 0x36, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x32, 0x37, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x32, 0x38, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x32, 0x39, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x33, 0x30, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x33, 0x31, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x33, 0x32, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x33, 0x33, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x33, 0x34, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x33, 0x35, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x33, 0x36, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x33, 0x37, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x33, 0x38, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x33, 0x39, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x34, 0x30, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x34, 0x31, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x34, 0x32, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x34, 0x33, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x34, 0x34, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x34, 0x35, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x34, 0x36, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x34, 0x37, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x34, 0x38, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x34, 0x39, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x36, 0x35, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x36, 0x36, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x36, 0x37, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x36, 0x38, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x36, 0x39, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x37, 0x30, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x37, 0x32, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x37, 0x33, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x37, 0x34, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x37, 0x35, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x37, 0x36, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x37, 0x37, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x37, 0x38, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x37, 0x39, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x38, 0x30, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x38, 0x31, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x38, 0x32, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x38, 0x33, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x38, 0x34, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x38, 0x35, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x38, 0x36, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x38, 0x37, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x38, 0x38, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x38, 0x39, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x39, 0x30, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x39, 0x31, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x39, 0x32, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x39, 0x33, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x39, 0x34, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x39, 0x35, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x39, 0x36, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, +0x30, 0x39, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x35, +0x30, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x30, 0x37, +0x31, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x30, 0x39, +0x39, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x31, 0x30, +0x30, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x31, 0x30, +0x31, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x31, 0x30, +0x32, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x31, 0x30, +0x33, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x31, 0x30, +0x34, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x31, 0x30, +0x35, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x31, 0x30, +0x36, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x31, 0x30, +0x37, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x31, 0x30, +0x38, 0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x31, 0x30, +0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x35, 0x44, 0x09, +0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x31, 0x31, 0x30, 0x09, +0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x31, 0x39, 0x33, 0x0e, +0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x30, 0x36, 0x36, 0x2e, +0x6c, 0x6f, 0x63, 0x6c, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x36, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x36, 0x33, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x37, 0x32, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x37, 0x33, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x37, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x37, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x38, 0x41, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x38, 0x42, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x38, 0x43, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x38, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x38, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x38, 0x46, +0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x30, 0x35, 0x30, +0x09, 0x61, 0x66, 0x69, 0x69, 0x31, 0x30, 0x30, 0x39, 0x38, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x39, 0x32, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x39, 0x33, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x39, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x39, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x39, 0x36, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x39, 0x37, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x39, 0x38, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x39, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x39, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x39, 0x42, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x39, 0x43, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x39, 0x44, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x39, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x39, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x30, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x31, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x41, 0x32, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x41, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x41, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x35, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x36, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x41, 0x37, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x41, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x41, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x41, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x42, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x41, 0x43, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x41, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x41, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x46, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x42, 0x30, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x42, 0x31, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x42, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x42, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x42, 0x34, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x42, 0x35, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x42, 0x36, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x42, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x42, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x42, 0x39, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x42, 0x41, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x42, 0x42, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x42, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x42, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x42, 0x45, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x42, 0x46, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x43, 0x30, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x43, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x43, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x43, 0x33, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x43, 0x34, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x43, 0x35, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x43, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x43, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x43, 0x38, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x43, 0x39, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x43, 0x41, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x43, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x43, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x43, 0x44, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x43, 0x45, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x43, 0x46, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x44, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x44, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x32, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x33, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x44, 0x34, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x44, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x44, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x37, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x38, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x44, 0x39, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x44, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x44, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x43, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x44, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x44, 0x45, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x44, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x45, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x31, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x32, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x45, 0x33, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x45, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x45, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x36, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x37, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x45, 0x38, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x45, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x45, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x42, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x43, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x45, 0x44, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x45, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x45, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x46, 0x30, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x46, 0x31, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x46, 0x32, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x46, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x46, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x46, 0x35, +0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x46, 0x36, 0x07, 0x75, +0x6e, 0x69, 0x30, 0x34, 0x46, 0x37, 0x07, 0x75, 0x6e, 0x69, +0x30, 0x34, 0x46, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, +0x46, 0x39, 0x09, 0x61, 0x66, 0x69, 0x69, 0x36, 0x31, 0x33, +0x35, 0x32, 0x09, 0x61, 0x66, 0x69, 0x69, 0x30, 0x30, 0x32, +0x30, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x42, 0x34, +0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x41, 0x45, 0x05, 0x74, +0x65, 0x6e, 0x67, 0x65, 0x06, 0x72, 0x6f, 0x75, 0x62, 0x6c, +0x65, 0x06, 0x6b, 0x72, 0x61, 0x74, 0x6b, 0x61, 0x05, 0x41, +0x6c, 0x70, 0x68, 0x61, 0x04, 0x42, 0x65, 0x74, 0x61, 0x05, +0x47, 0x61, 0x6d, 0x6d, 0x61, 0x07, 0x75, 0x6e, 0x69, 0x30, +0x33, 0x39, 0x34, 0x07, 0x45, 0x70, 0x73, 0x69, 0x6c, 0x6f, +0x6e, 0x04, 0x5a, 0x65, 0x74, 0x61, 0x03, 0x45, 0x74, 0x61, +0x05, 0x54, 0x68, 0x65, 0x74, 0x61, 0x04, 0x49, 0x6f, 0x74, +0x61, 0x05, 0x4b, 0x61, 0x70, 0x70, 0x61, 0x06, 0x4c, 0x61, +0x6d, 0x62, 0x64, 0x61, 0x02, 0x4d, 0x75, 0x02, 0x4e, 0x75, +0x02, 0x58, 0x69, 0x07, 0x4f, 0x6d, 0x69, 0x63, 0x72, 0x6f, +0x6e, 0x02, 0x50, 0x69, 0x03, 0x52, 0x68, 0x6f, 0x05, 0x53, +0x69, 0x67, 0x6d, 0x61, 0x03, 0x54, 0x61, 0x75, 0x07, 0x55, +0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x03, 0x50, 0x68, 0x69, +0x03, 0x43, 0x68, 0x69, 0x03, 0x50, 0x73, 0x69, 0x05, 0x61, +0x6c, 0x70, 0x68, 0x61, 0x04, 0x62, 0x65, 0x74, 0x61, 0x05, +0x67, 0x61, 0x6d, 0x6d, 0x61, 0x05, 0x64, 0x65, 0x6c, 0x74, +0x61, 0x07, 0x65, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x04, +0x7a, 0x65, 0x74, 0x61, 0x03, 0x65, 0x74, 0x61, 0x05, 0x74, +0x68, 0x65, 0x74, 0x61, 0x04, 0x69, 0x6f, 0x74, 0x61, 0x05, +0x6b, 0x61, 0x70, 0x70, 0x61, 0x06, 0x6c, 0x61, 0x6d, 0x62, +0x64, 0x61, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x42, 0x43, +0x02, 0x6e, 0x75, 0x02, 0x78, 0x69, 0x07, 0x6f, 0x6d, 0x69, +0x63, 0x72, 0x6f, 0x6e, 0x03, 0x72, 0x68, 0x6f, 0x06, 0x73, +0x69, 0x67, 0x6d, 0x61, 0x31, 0x05, 0x73, 0x69, 0x67, 0x6d, +0x61, 0x03, 0x74, 0x61, 0x75, 0x07, 0x75, 0x70, 0x73, 0x69, +0x6c, 0x6f, 0x6e, 0x03, 0x70, 0x68, 0x69, 0x03, 0x63, 0x68, +0x69, 0x03, 0x70, 0x73, 0x69, 0x05, 0x6f, 0x6d, 0x65, 0x67, +0x61, 0x0a, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x74, 0x6f, 0x6e, +0x6f, 0x73, 0x0c, 0x45, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, +0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x08, 0x45, 0x74, 0x61, 0x74, +0x6f, 0x6e, 0x6f, 0x73, 0x09, 0x49, 0x6f, 0x74, 0x61, 0x74, +0x6f, 0x6e, 0x6f, 0x73, 0x0c, 0x49, 0x6f, 0x74, 0x61, 0x64, +0x69, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x0c, 0x4f, 0x6d, +0x69, 0x63, 0x72, 0x6f, 0x6e, 0x74, 0x6f, 0x6e, 0x6f, 0x73, +0x0c, 0x55, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x74, 0x6f, +0x6e, 0x6f, 0x73, 0x0f, 0x55, 0x70, 0x73, 0x69, 0x6c, 0x6f, +0x6e, 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x0a, +0x4f, 0x6d, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x6e, 0x6f, 0x73, +0x0a, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x74, 0x6f, 0x6e, 0x6f, +0x73, 0x0c, 0x65, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x74, +0x6f, 0x6e, 0x6f, 0x73, 0x08, 0x65, 0x74, 0x61, 0x74, 0x6f, +0x6e, 0x6f, 0x73, 0x09, 0x69, 0x6f, 0x74, 0x61, 0x74, 0x6f, +0x6e, 0x6f, 0x73, 0x0c, 0x69, 0x6f, 0x74, 0x61, 0x64, 0x69, +0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x11, 0x69, 0x6f, 0x74, +0x61, 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x74, +0x6f, 0x6e, 0x6f, 0x73, 0x0c, 0x6f, 0x6d, 0x69, 0x63, 0x72, +0x6f, 0x6e, 0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x0f, 0x75, 0x70, +0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x64, 0x69, 0x65, 0x72, 0x65, +0x73, 0x69, 0x73, 0x0c, 0x75, 0x70, 0x73, 0x69, 0x6c, 0x6f, +0x6e, 0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x14, 0x75, 0x70, 0x73, +0x69, 0x6c, 0x6f, 0x6e, 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, +0x69, 0x73, 0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x0a, 0x6f, 0x6d, +0x65, 0x67, 0x61, 0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x05, 0x74, +0x6f, 0x6e, 0x6f, 0x73, 0x09, 0x74, 0x6f, 0x6e, 0x6f, 0x73, +0x2e, 0x63, 0x61, 0x70, 0x0d, 0x64, 0x69, 0x65, 0x72, 0x65, +0x73, 0x69, 0x73, 0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x30, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x30, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x30, 0x33, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x30, 0x34, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x30, 0x35, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x30, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x30, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x30, 0x38, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x30, 0x39, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x30, 0x41, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x30, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x30, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x30, 0x44, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x30, 0x45, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x30, 0x46, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x31, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x31, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x31, 0x32, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x31, 0x33, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x31, 0x34, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x31, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x31, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x31, 0x39, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x31, 0x41, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x31, 0x42, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x31, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x31, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x32, 0x30, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x32, 0x31, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x32, 0x32, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x32, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x32, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x32, 0x35, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x32, 0x36, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x32, 0x37, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x32, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x32, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x32, 0x41, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x32, 0x42, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x32, 0x43, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x32, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x32, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x32, 0x46, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x33, 0x30, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x33, 0x31, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x33, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x33, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x33, 0x34, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x33, 0x35, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x33, 0x36, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x33, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x33, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x33, 0x39, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x33, 0x41, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x33, 0x42, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x33, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x33, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x33, 0x45, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x33, 0x46, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x34, 0x30, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x34, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x34, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x34, 0x33, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x34, 0x34, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x34, 0x35, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x34, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x34, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x34, 0x41, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x34, 0x42, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x34, 0x43, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x34, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x35, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x35, 0x31, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x35, 0x32, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x35, 0x33, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x35, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x35, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x35, 0x36, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x35, 0x37, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x35, 0x39, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x35, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x35, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x35, 0x46, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x36, 0x30, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x36, 0x31, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x36, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x36, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x36, 0x34, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x36, 0x35, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x36, 0x36, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x36, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x36, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x36, 0x39, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x36, 0x41, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x36, 0x42, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x36, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x36, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x36, 0x45, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x36, 0x46, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x37, 0x30, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x37, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x37, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x37, 0x33, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x37, 0x34, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x37, 0x35, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x37, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x37, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x37, 0x38, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x37, 0x39, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x37, 0x41, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x37, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x37, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x37, 0x44, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x30, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x38, 0x31, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x38, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x38, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x34, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x35, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x38, 0x36, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x38, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x38, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x39, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x41, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x38, 0x42, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x38, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x38, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x45, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x46, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x39, 0x30, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x39, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x39, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x33, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x34, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x39, 0x35, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x39, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x39, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x38, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x39, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x39, 0x41, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x39, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x39, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x44, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x45, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x39, 0x46, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x41, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x41, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x41, 0x32, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x41, 0x33, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x41, 0x34, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x41, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x41, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x41, 0x37, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x41, 0x38, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x41, 0x39, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x41, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x41, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x41, 0x43, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x41, 0x44, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x41, 0x45, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x41, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x42, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x42, 0x31, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x42, 0x32, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x42, 0x33, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x42, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x42, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x42, 0x37, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x42, 0x38, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x42, 0x39, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x42, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x42, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x42, 0x43, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x42, 0x44, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x42, 0x45, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x42, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x43, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x43, 0x31, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x43, 0x32, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x43, 0x33, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x43, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x43, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x43, 0x37, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x43, 0x38, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x43, 0x39, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x43, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x43, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x43, 0x43, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x43, 0x44, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x43, 0x45, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x43, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x44, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x44, 0x31, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x44, 0x32, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x44, 0x33, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x44, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x44, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x44, 0x38, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x44, 0x39, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x44, 0x41, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x44, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x44, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x44, 0x45, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x44, 0x46, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x45, 0x30, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x45, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x45, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x45, 0x33, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x45, 0x34, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x45, 0x35, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x45, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x45, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x45, 0x38, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x45, 0x39, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x45, 0x41, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x45, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x45, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x45, 0x44, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x45, 0x45, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x45, 0x46, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x46, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x46, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x46, 0x34, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x46, 0x36, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x46, 0x37, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x46, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x46, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x46, 0x41, +0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x46, 0x42, 0x07, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x46, 0x43, 0x07, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x46, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x46, 0x45, 0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x38, +0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x38, 0x39, 0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x38, 0x41, 0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x38, 0x42, 0x2e, 0x61, 0x6c, 0x74, +0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x43, 0x2e, 0x61, +0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x44, +0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x38, 0x45, 0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x38, 0x46, 0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x39, 0x38, 0x2e, 0x61, 0x6c, 0x74, +0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x39, 0x2e, 0x61, +0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x41, +0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x39, 0x42, 0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x39, 0x43, 0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x39, 0x44, 0x2e, 0x61, 0x6c, 0x74, +0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x45, 0x2e, 0x61, +0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x46, +0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x41, 0x38, 0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x41, 0x39, 0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x41, 0x41, 0x2e, 0x61, 0x6c, 0x74, +0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x41, 0x42, 0x2e, 0x61, +0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x41, 0x43, +0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x41, 0x44, 0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, +0x31, 0x46, 0x41, 0x45, 0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, +0x6e, 0x69, 0x31, 0x46, 0x41, 0x46, 0x2e, 0x61, 0x6c, 0x74, +0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x42, 0x43, 0x2e, 0x61, +0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x43, 0x43, +0x2e, 0x61, 0x6c, 0x74, 0x0b, 0x75, 0x6e, 0x69, 0x31, 0x46, +0x46, 0x43, 0x2e, 0x61, 0x6c, 0x74, 0x07, 0x75, 0x6e, 0x69, +0x32, 0x30, 0x42, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30, +0x46, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x30, 0x30, 0x30, +0x07, 0x75, 0x6e, 0x69, 0x46, 0x46, 0x46, 0x44, 0x07, 0x75, +0x6e, 0x69, 0x45, 0x46, 0x46, 0x44, 0x0c, 0x53, 0x46, 0x30, +0x34, 0x30, 0x30, 0x30, 0x30, 0x2e, 0x30, 0x30, 0x31, 0x0c, +0x53, 0x46, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x2e, 0x30, +0x30, 0x31, 0x0c, 0x53, 0x46, 0x30, 0x31, 0x30, 0x30, 0x30, +0x30, 0x2e, 0x30, 0x30, 0x31, 0x0c, 0x53, 0x46, 0x31, 0x31, +0x30, 0x30, 0x30, 0x30, 0x2e, 0x30, 0x30, 0x31, 0x0c, 0x53, +0x46, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2e, 0x30, 0x30, +0x31, 0x0c, 0x53, 0x46, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, +0x2e, 0x30, 0x30, 0x31, 0x0c, 0x53, 0x46, 0x30, 0x36, 0x30, +0x30, 0x30, 0x30, 0x2e, 0x30, 0x30, 0x31, 0x0c, 0x53, 0x46, +0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x2e, 0x30, 0x30, 0x31, +0x0c, 0x53, 0x46, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, 0x2e, +0x30, 0x30, 0x31, 0x0c, 0x53, 0x46, 0x30, 0x35, 0x30, 0x30, +0x30, 0x30, 0x2e, 0x30, 0x30, 0x31, 0x0c, 0x53, 0x46, 0x35, +0x34, 0x30, 0x30, 0x30, 0x30, 0x2e, 0x30, 0x30, 0x31, 0x0c, +0x53, 0x46, 0x35, 0x33, 0x30, 0x30, 0x30, 0x30, 0x2e, 0x30, +0x30, 0x31, 0x0c, 0x53, 0x46, 0x30, 0x33, 0x30, 0x30, 0x30, +0x30, 0x2e, 0x30, 0x30, 0x31, 0x08, 0x53, 0x46, 0x31, 0x39, +0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x33, 0x36, 0x30, +0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x34, 0x35, 0x30, 0x30, +0x30, 0x30, 0x08, 0x53, 0x46, 0x32, 0x38, 0x30, 0x30, 0x30, +0x30, 0x08, 0x53, 0x46, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, +0x08, 0x53, 0x46, 0x34, 0x37, 0x30, 0x30, 0x30, 0x30, 0x08, +0x53, 0x46, 0x32, 0x32, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, +0x46, 0x35, 0x31, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, +0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x34, +0x34, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x32, 0x33, +0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x34, 0x32, 0x30, +0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x34, 0x30, 0x30, 0x30, +0x30, 0x30, 0x08, 0x53, 0x46, 0x32, 0x36, 0x30, 0x30, 0x30, +0x30, 0x08, 0x53, 0x46, 0x33, 0x38, 0x30, 0x30, 0x30, 0x30, +0x08, 0x53, 0x46, 0x34, 0x31, 0x30, 0x30, 0x30, 0x30, 0x08, +0x53, 0x46, 0x32, 0x35, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, +0x46, 0x33, 0x39, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, +0x34, 0x33, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x32, +0x30, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x33, 0x37, +0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x34, 0x36, 0x30, +0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x32, 0x37, 0x30, 0x30, +0x30, 0x30, 0x08, 0x53, 0x46, 0x34, 0x39, 0x30, 0x30, 0x30, +0x30, 0x08, 0x53, 0x46, 0x34, 0x38, 0x30, 0x30, 0x30, 0x30, +0x08, 0x53, 0x46, 0x32, 0x31, 0x30, 0x30, 0x30, 0x30, 0x08, +0x53, 0x46, 0x35, 0x32, 0x30, 0x30, 0x30, 0x30, 0x05, 0x62, +0x6c, 0x6f, 0x63, 0x6b, 0x07, 0x6c, 0x74, 0x73, 0x68, 0x61, +0x64, 0x65, 0x05, 0x73, 0x68, 0x61, 0x64, 0x65, 0x07, 0x64, +0x6b, 0x73, 0x68, 0x61, 0x64, 0x65, 0x08, 0x53, 0x46, 0x35, +0x33, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x35, 0x34, +0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x30, 0x34, 0x30, +0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x30, 0x32, 0x30, 0x30, +0x30, 0x30, 0x08, 0x53, 0x46, 0x30, 0x31, 0x30, 0x30, 0x30, +0x30, 0x08, 0x53, 0x46, 0x31, 0x31, 0x30, 0x30, 0x30, 0x30, +0x08, 0x53, 0x46, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x08, +0x53, 0x46, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, +0x46, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, +0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x30, +0x38, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x30, 0x35, +0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x30, 0x33, 0x30, +0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +0xff, 0xff, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, +0x01, 0x74, 0x07, 0x16, 0x00, 0x03, 0x63, 0x79, 0x72, 0x6c, +0x00, 0x14, 0x67, 0x72, 0x65, 0x6b, 0x00, 0x90, 0x6c, 0x61, +0x74, 0x6e, 0x00, 0xb0, 0x00, 0x16, 0x00, 0x03, 0x42, 0x47, +0x52, 0x20, 0x00, 0x2e, 0x4d, 0x4b, 0x44, 0x20, 0x00, 0x48, +0x53, 0x52, 0x42, 0x20, 0x00, 0x62, 0x00, 0x00, 0xff, 0xff, +0x00, 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x1f, +0x00, 0x30, 0x00, 0x3e, 0x00, 0x4b, 0x00, 0x56, 0x00, 0x61, +0x00, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x0c, +0x00, 0x15, 0x00, 0x20, 0x00, 0x2a, 0x00, 0x31, 0x00, 0x3f, +0x00, 0x4c, 0x00, 0x57, 0x00, 0x62, 0x00, 0x00, 0xff, 0xff, +0x00, 0x0a, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x16, 0x00, 0x21, +0x00, 0x2b, 0x00, 0x32, 0x00, 0x40, 0x00, 0x4d, 0x00, 0x58, +0x00, 0x63, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x17, 0x00, 0x22, 0x00, 0x2c, 0x00, 0x33, +0x00, 0x41, 0x00, 0x4e, 0x00, 0x59, 0x00, 0x64, 0x00, 0x04, +0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x04, +0x00, 0x0f, 0x00, 0x18, 0x00, 0x23, 0x00, 0x34, 0x00, 0x3c, +0x00, 0x42, 0x00, 0x49, 0x00, 0x4f, 0x00, 0x5a, 0x00, 0x65, +0x00, 0x22, 0x00, 0x05, 0x41, 0x5a, 0x45, 0x20, 0x00, 0x40, +0x43, 0x52, 0x54, 0x20, 0x00, 0x5a, 0x4d, 0x4f, 0x4c, 0x20, +0x00, 0x74, 0x52, 0x4f, 0x4d, 0x20, 0x00, 0x8a, 0x54, 0x52, +0x4b, 0x20, 0x00, 0xa0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0c, +0x00, 0x05, 0x00, 0x10, 0x00, 0x19, 0x00, 0x24, 0x00, 0x35, +0x00, 0x3b, 0x00, 0x3d, 0x00, 0x43, 0x00, 0x4a, 0x00, 0x50, +0x00, 0x5b, 0x00, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0a, +0x00, 0x06, 0x00, 0x11, 0x00, 0x1a, 0x00, 0x25, 0x00, 0x2d, +0x00, 0x36, 0x00, 0x44, 0x00, 0x51, 0x00, 0x5c, 0x00, 0x67, +0x00, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x12, +0x00, 0x1b, 0x00, 0x26, 0x00, 0x2e, 0x00, 0x37, 0x00, 0x45, +0x00, 0x52, 0x00, 0x5d, 0x00, 0x68, 0x00, 0x00, 0xff, 0xff, +0x00, 0x08, 0x00, 0x08, 0x00, 0x1c, 0x00, 0x27, 0x00, 0x38, +0x00, 0x46, 0x00, 0x53, 0x00, 0x5e, 0x00, 0x69, 0x00, 0x00, +0xff, 0xff, 0x00, 0x08, 0x00, 0x09, 0x00, 0x1d, 0x00, 0x28, +0x00, 0x39, 0x00, 0x47, 0x00, 0x54, 0x00, 0x5f, 0x00, 0x6a, +0x00, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x13, +0x00, 0x1e, 0x00, 0x29, 0x00, 0x2f, 0x00, 0x3a, 0x00, 0x48, +0x00, 0x55, 0x00, 0x60, 0x00, 0x6b, 0x00, 0x6c, 0x61, 0x66, +0x72, 0x63, 0x02, 0x8a, 0x61, 0x66, 0x72, 0x63, 0x02, 0x94, +0x61, 0x66, 0x72, 0x63, 0x02, 0x9e, 0x61, 0x66, 0x72, 0x63, +0x02, 0xa8, 0x61, 0x66, 0x72, 0x63, 0x02, 0xb2, 0x61, 0x66, +0x72, 0x63, 0x02, 0xbc, 0x61, 0x66, 0x72, 0x63, 0x02, 0xc6, +0x61, 0x66, 0x72, 0x63, 0x02, 0xd0, 0x61, 0x66, 0x72, 0x63, +0x02, 0xda, 0x61, 0x66, 0x72, 0x63, 0x02, 0xe4, 0x61, 0x66, +0x72, 0x63, 0x02, 0xee, 0x63, 0x61, 0x73, 0x65, 0x02, 0xf8, +0x63, 0x61, 0x73, 0x65, 0x03, 0x00, 0x63, 0x61, 0x73, 0x65, +0x03, 0x08, 0x63, 0x61, 0x73, 0x65, 0x03, 0x10, 0x63, 0x61, +0x73, 0x65, 0x03, 0x18, 0x63, 0x61, 0x73, 0x65, 0x03, 0x20, +0x63, 0x61, 0x73, 0x65, 0x03, 0x28, 0x63, 0x61, 0x73, 0x65, +0x03, 0x30, 0x63, 0x61, 0x73, 0x65, 0x03, 0x38, 0x64, 0x6e, +0x6f, 0x6d, 0x03, 0x40, 0x64, 0x6e, 0x6f, 0x6d, 0x03, 0x46, +0x64, 0x6e, 0x6f, 0x6d, 0x03, 0x4c, 0x64, 0x6e, 0x6f, 0x6d, +0x03, 0x52, 0x64, 0x6e, 0x6f, 0x6d, 0x03, 0x58, 0x64, 0x6e, +0x6f, 0x6d, 0x03, 0x5e, 0x64, 0x6e, 0x6f, 0x6d, 0x03, 0x64, +0x64, 0x6e, 0x6f, 0x6d, 0x03, 0x6a, 0x64, 0x6e, 0x6f, 0x6d, +0x03, 0x70, 0x64, 0x6e, 0x6f, 0x6d, 0x03, 0x76, 0x64, 0x6e, +0x6f, 0x6d, 0x03, 0x7c, 0x66, 0x72, 0x61, 0x63, 0x03, 0x82, +0x66, 0x72, 0x61, 0x63, 0x03, 0x8a, 0x66, 0x72, 0x61, 0x63, +0x03, 0x92, 0x66, 0x72, 0x61, 0x63, 0x03, 0x9a, 0x66, 0x72, +0x61, 0x63, 0x03, 0xa2, 0x66, 0x72, 0x61, 0x63, 0x03, 0xaa, +0x66, 0x72, 0x61, 0x63, 0x03, 0xb2, 0x66, 0x72, 0x61, 0x63, +0x03, 0xba, 0x66, 0x72, 0x61, 0x63, 0x03, 0xc2, 0x66, 0x72, +0x61, 0x63, 0x03, 0xca, 0x66, 0x72, 0x61, 0x63, 0x03, 0xd2, +0x6c, 0x6f, 0x63, 0x6c, 0x03, 0xda, 0x6c, 0x6f, 0x63, 0x6c, +0x03, 0xe0, 0x6c, 0x6f, 0x63, 0x6c, 0x03, 0xe6, 0x6c, 0x6f, +0x63, 0x6c, 0x03, 0xec, 0x6c, 0x6f, 0x63, 0x6c, 0x03, 0xf2, +0x6c, 0x6f, 0x63, 0x6c, 0x03, 0xf8, 0x6e, 0x75, 0x6d, 0x72, +0x03, 0xfe, 0x6e, 0x75, 0x6d, 0x72, 0x04, 0x04, 0x6e, 0x75, +0x6d, 0x72, 0x04, 0x0a, 0x6e, 0x75, 0x6d, 0x72, 0x04, 0x10, +0x6e, 0x75, 0x6d, 0x72, 0x04, 0x16, 0x6e, 0x75, 0x6d, 0x72, +0x04, 0x1c, 0x6e, 0x75, 0x6d, 0x72, 0x04, 0x22, 0x6e, 0x75, +0x6d, 0x72, 0x04, 0x28, 0x6e, 0x75, 0x6d, 0x72, 0x04, 0x2e, +0x6e, 0x75, 0x6d, 0x72, 0x04, 0x34, 0x6e, 0x75, 0x6d, 0x72, +0x04, 0x3a, 0x6f, 0x72, 0x64, 0x6e, 0x04, 0x40, 0x73, 0x61, +0x6c, 0x74, 0x04, 0x46, 0x73, 0x61, 0x6c, 0x74, 0x04, 0x50, +0x73, 0x69, 0x6e, 0x66, 0x04, 0x5a, 0x73, 0x69, 0x6e, 0x66, +0x04, 0x60, 0x73, 0x69, 0x6e, 0x66, 0x04, 0x66, 0x73, 0x69, +0x6e, 0x66, 0x04, 0x6c, 0x73, 0x69, 0x6e, 0x66, 0x04, 0x72, +0x73, 0x69, 0x6e, 0x66, 0x04, 0x78, 0x73, 0x69, 0x6e, 0x66, +0x04, 0x7e, 0x73, 0x69, 0x6e, 0x66, 0x04, 0x84, 0x73, 0x69, +0x6e, 0x66, 0x04, 0x8a, 0x73, 0x69, 0x6e, 0x66, 0x04, 0x90, +0x73, 0x69, 0x6e, 0x66, 0x04, 0x96, 0x73, 0x73, 0x30, 0x31, +0x04, 0x9c, 0x73, 0x73, 0x30, 0x31, 0x04, 0xa6, 0x73, 0x73, +0x30, 0x32, 0x04, 0xb0, 0x73, 0x73, 0x30, 0x32, 0x04, 0xba, +0x73, 0x73, 0x30, 0x32, 0x04, 0xc4, 0x73, 0x73, 0x30, 0x32, +0x04, 0xce, 0x73, 0x73, 0x30, 0x32, 0x04, 0xd8, 0x73, 0x73, +0x30, 0x32, 0x04, 0xe2, 0x73, 0x73, 0x30, 0x32, 0x04, 0xec, +0x73, 0x73, 0x30, 0x32, 0x04, 0xf6, 0x73, 0x73, 0x30, 0x32, +0x05, 0x00, 0x73, 0x73, 0x30, 0x32, 0x05, 0x0a, 0x73, 0x73, +0x30, 0x32, 0x05, 0x14, 0x73, 0x75, 0x62, 0x73, 0x05, 0x1e, +0x73, 0x75, 0x62, 0x73, 0x05, 0x24, 0x73, 0x75, 0x62, 0x73, +0x05, 0x2a, 0x73, 0x75, 0x62, 0x73, 0x05, 0x30, 0x73, 0x75, +0x62, 0x73, 0x05, 0x36, 0x73, 0x75, 0x62, 0x73, 0x05, 0x3c, +0x73, 0x75, 0x62, 0x73, 0x05, 0x42, 0x73, 0x75, 0x62, 0x73, +0x05, 0x48, 0x73, 0x75, 0x62, 0x73, 0x05, 0x4e, 0x73, 0x75, +0x62, 0x73, 0x05, 0x54, 0x73, 0x75, 0x62, 0x73, 0x05, 0x5a, +0x73, 0x75, 0x70, 0x73, 0x05, 0x60, 0x73, 0x75, 0x70, 0x73, +0x05, 0x66, 0x73, 0x75, 0x70, 0x73, 0x05, 0x6c, 0x73, 0x75, +0x70, 0x73, 0x05, 0x72, 0x73, 0x75, 0x70, 0x73, 0x05, 0x78, +0x73, 0x75, 0x70, 0x73, 0x05, 0x7e, 0x73, 0x75, 0x70, 0x73, +0x05, 0x84, 0x73, 0x75, 0x70, 0x73, 0x05, 0x8a, 0x73, 0x75, +0x70, 0x73, 0x05, 0x90, 0x73, 0x75, 0x70, 0x73, 0x05, 0x96, +0x73, 0x75, 0x70, 0x73, 0x05, 0x9c, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, +0x00, 0x11, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x11, +0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x11, 0x00, 0x12, +0x00, 0x00, 0x00, 0x02, 0x00, 0x11, 0x00, 0x12, 0x00, 0x00, +0x00, 0x02, 0x00, 0x11, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, +0x00, 0x11, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x11, +0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x11, 0x00, 0x12, +0x00, 0x00, 0x00, 0x02, 0x00, 0x11, 0x00, 0x12, 0x00, 0x00, +0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, +0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, +0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, +0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, +0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, +0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, +0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, +0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x0d, +0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x00, +0x00, 0x02, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, +0x00, 0x0c, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, +0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x0d, +0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x00, +0x00, 0x02, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, +0x00, 0x0c, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, +0x00, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, +0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, +0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, +0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, +0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, +0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, +0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, +0x00, 0x00, 0x00, 0x03, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, +0x00, 0x00, 0x00, 0x03, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, +0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, +0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x00, +0x00, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, +0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, +0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x00, +0x00, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, +0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x03, +0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x00, 0x00, 0x03, +0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, +0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, +0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, +0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0a, +0x00, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, +0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, +0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0a, +0x00, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, +0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, +0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, +0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, +0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, +0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, +0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, +0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x17, +0x00, 0x30, 0x00, 0x38, 0x00, 0x40, 0x00, 0x48, 0x00, 0x50, +0x00, 0x58, 0x00, 0x60, 0x00, 0x68, 0x00, 0x70, 0x00, 0x78, +0x00, 0x80, 0x00, 0x88, 0x00, 0x90, 0x00, 0x98, 0x00, 0xa0, +0x00, 0xa8, 0x00, 0xb0, 0x00, 0xb8, 0x00, 0xc0, 0x00, 0xc8, +0x00, 0xd0, 0x00, 0xd8, 0x00, 0xe0, 0x00, 0x01, 0x00, 0x00, +0x00, 0x01, 0x00, 0xb8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, +0x00, 0xb6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb4, +0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb2, 0x00, 0x01, +0x00, 0x00, 0x00, 0x01, 0x00, 0xb0, 0x00, 0x01, 0x00, 0x00, +0x00, 0x01, 0x00, 0xae, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, +0x00, 0xac, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xfa, +0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xfc, 0x00, 0x01, +0x00, 0x00, 0x00, 0x01, 0x01, 0x4a, 0x00, 0x01, 0x00, 0x00, +0x00, 0x01, 0x01, 0x98, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, +0x01, 0xe6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x34, +0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, 0x00, 0x01, +0x00, 0x00, 0x00, 0x01, 0x1d, 0x32, 0x00, 0x01, 0x00, 0x00, +0x00, 0x01, 0x1d, 0x34, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, +0x1d, 0x82, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1d, 0x8c, +0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1d, 0xb4, 0x00, 0x01, +0x00, 0x00, 0x00, 0x01, 0x1e, 0xb0, 0x00, 0x01, 0x00, 0x00, +0x00, 0x01, 0x1e, 0xc0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, +0x1e, 0xd0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1e, 0xe0, +0x00, 0x01, 0x1e, 0xf2, 0x00, 0xc1, 0x00, 0x01, 0x1e, 0xec, +0x00, 0xc1, 0x00, 0x01, 0x1e, 0xe6, 0x00, 0xc1, 0x00, 0x01, +0x1e, 0xe6, 0x00, 0x2f, 0x00, 0x01, 0x1e, 0xe0, 0x00, 0x2f, +0x00, 0x01, 0x1e, 0xda, 0x00, 0x2f, 0x00, 0x02, 0x1e, 0xda, +0x00, 0x28, 0x01, 0x6f, 0x00, 0x94, 0x00, 0x8d, 0x00, 0x8e, +0x01, 0x70, 0x01, 0x71, 0x01, 0x72, 0x01, 0x73, 0x01, 0x74, +0x01, 0x75, 0x01, 0x6f, 0x00, 0x94, 0x00, 0x8d, 0x00, 0x8e, +0x01, 0x70, 0x01, 0x71, 0x01, 0x72, 0x01, 0x73, 0x01, 0x74, +0x01, 0x75, 0x01, 0x6f, 0x00, 0x94, 0x00, 0x8d, 0x00, 0x8e, +0x01, 0x70, 0x01, 0x71, 0x01, 0x72, 0x01, 0x73, 0x01, 0x74, +0x01, 0x75, 0x01, 0x6f, 0x00, 0x94, 0x00, 0x8d, 0x00, 0x8e, +0x01, 0x70, 0x01, 0x71, 0x01, 0x72, 0x01, 0x73, 0x01, 0x74, +0x01, 0x75, 0x00, 0x02, 0x1e, 0x9a, 0x00, 0x02, 0x00, 0x85, +0x00, 0x95, 0x00, 0x02, 0x1e, 0x98, 0x00, 0x28, 0x01, 0x76, +0x01, 0x77, 0x01, 0x78, 0x01, 0x79, 0x01, 0x7a, 0x01, 0x7b, +0x01, 0x7c, 0x01, 0x7d, 0x01, 0x7e, 0x01, 0x7f, 0x01, 0x78, +0x01, 0x79, 0x01, 0x77, 0x01, 0x76, 0x01, 0x7a, 0x01, 0x7b, +0x01, 0x7c, 0x01, 0x7d, 0x01, 0x7e, 0x01, 0x7f, 0x01, 0x76, +0x01, 0x77, 0x01, 0x78, 0x01, 0x79, 0x01, 0x7a, 0x01, 0x7b, +0x01, 0x7c, 0x01, 0x7d, 0x01, 0x7e, 0x01, 0x7f, 0x01, 0x76, +0x01, 0x77, 0x01, 0x78, 0x01, 0x79, 0x01, 0x7a, 0x01, 0x7b, +0x01, 0x7c, 0x01, 0x7d, 0x01, 0x7e, 0x01, 0x7f, 0x00, 0x02, +0x1e, 0x64, 0x00, 0x28, 0x01, 0xae, 0x01, 0xaf, 0x01, 0xb0, +0x01, 0xb1, 0x01, 0xb2, 0x01, 0xb3, 0x01, 0xb4, 0x01, 0xb5, +0x01, 0xb6, 0x01, 0xb7, 0x01, 0xb0, 0x01, 0xb1, 0x01, 0xaf, +0x01, 0xae, 0x01, 0xb2, 0x01, 0xb3, 0x01, 0xb4, 0x01, 0xb5, +0x01, 0xb6, 0x01, 0xb7, 0x01, 0xae, 0x01, 0xaf, 0x01, 0xb0, +0x01, 0xb1, 0x01, 0xb2, 0x01, 0xb3, 0x01, 0xb4, 0x01, 0xb5, +0x01, 0xb6, 0x01, 0xb7, 0x01, 0xae, 0x01, 0xaf, 0x01, 0xb0, +0x01, 0xb1, 0x01, 0xb2, 0x01, 0xb3, 0x01, 0xb4, 0x01, 0xb5, +0x01, 0xb6, 0x01, 0xb7, 0x00, 0x02, 0x1e, 0x30, 0x00, 0x28, +0x01, 0xb8, 0x01, 0xb9, 0x01, 0xba, 0x01, 0xbb, 0x01, 0xbc, +0x01, 0xbd, 0x01, 0xbe, 0x01, 0xbf, 0x01, 0xc0, 0x01, 0xc1, +0x01, 0xba, 0x01, 0xbb, 0x01, 0xb9, 0x01, 0xb8, 0x01, 0xbc, +0x01, 0xbd, 0x01, 0xbe, 0x01, 0xbf, 0x01, 0xc0, 0x01, 0xc1, +0x01, 0xb8, 0x01, 0xb9, 0x01, 0xba, 0x01, 0xbb, 0x01, 0xbc, +0x01, 0xbd, 0x01, 0xbe, 0x01, 0xbf, 0x01, 0xc0, 0x01, 0xc1, +0x01, 0xb8, 0x01, 0xb9, 0x01, 0xba, 0x01, 0xbb, 0x01, 0xbc, +0x01, 0xbd, 0x01, 0xbe, 0x01, 0xbf, 0x01, 0xc0, 0x01, 0xc1, +0x00, 0x02, 0x1d, 0xda, 0x00, 0x28, 0x01, 0xb8, 0x01, 0xb9, +0x01, 0xba, 0x01, 0xbb, 0x01, 0xbc, 0x01, 0xbd, 0x01, 0xbe, +0x01, 0xbf, 0x01, 0xc0, 0x01, 0xc1, 0x01, 0xba, 0x01, 0xbb, +0x01, 0xb9, 0x01, 0xb8, 0x01, 0xbc, 0x01, 0xbd, 0x01, 0xbe, +0x01, 0xbf, 0x01, 0xc0, 0x01, 0xc1, 0x01, 0xb8, 0x01, 0xb9, +0x01, 0xba, 0x01, 0xbb, 0x01, 0xbc, 0x01, 0xbd, 0x01, 0xbe, +0x01, 0xbf, 0x01, 0xc0, 0x01, 0xc1, 0x01, 0xb8, 0x01, 0xb9, +0x01, 0xba, 0x01, 0xbb, 0x01, 0xbc, 0x01, 0xbd, 0x01, 0xbe, +0x01, 0xbf, 0x01, 0xc0, 0x01, 0xc1, 0x00, 0x02, 0x1d, 0xa6, +0x00, 0x02, 0x01, 0x6e, 0x01, 0x6e, 0x00, 0x01, 0x1d, 0xa4, +0x00, 0x28, 0x00, 0x56, 0x01, 0xe8, 0x02, 0xb2, 0x03, 0x7c, +0x04, 0x14, 0x04, 0xde, 0x05, 0x12, 0x05, 0x78, 0x05, 0xac, +0x06, 0x76, 0x07, 0x40, 0x08, 0xd2, 0x09, 0x6a, 0x0a, 0x34, +0x0a, 0x68, 0x0a, 0xce, 0x0b, 0x02, 0x0c, 0x94, 0x0d, 0x5e, +0x0e, 0x28, 0x0e, 0xc0, 0x0f, 0x8a, 0x0f, 0xbe, 0x10, 0x24, +0x10, 0x58, 0x11, 0xea, 0x12, 0xb4, 0x13, 0x7e, 0x14, 0x16, +0x14, 0xe0, 0x15, 0x14, 0x15, 0x7a, 0x15, 0xae, 0x17, 0x40, +0x18, 0x0a, 0x18, 0xd4, 0x19, 0x6c, 0x1a, 0x36, 0x1a, 0x6a, +0x1a, 0xd0, 0x00, 0x28, 0x00, 0x52, 0x00, 0x5a, 0x00, 0x62, +0x00, 0x6a, 0x00, 0x72, 0x00, 0x7a, 0x00, 0x82, 0x00, 0x8a, +0x00, 0x92, 0x00, 0x9a, 0x00, 0xa2, 0x00, 0xaa, 0x00, 0xb2, +0x00, 0xba, 0x00, 0xc2, 0x00, 0xca, 0x00, 0xd2, 0x00, 0xda, +0x00, 0xe2, 0x00, 0xea, 0x00, 0xf2, 0x00, 0xfa, 0x01, 0x02, +0x01, 0x0a, 0x01, 0x12, 0x01, 0x1a, 0x01, 0x22, 0x01, 0x2a, +0x01, 0x32, 0x01, 0x3a, 0x01, 0x42, 0x01, 0x4a, 0x01, 0x52, +0x01, 0x5a, 0x01, 0x62, 0x01, 0x6a, 0x01, 0x72, 0x01, 0x7a, +0x01, 0x82, 0x01, 0x8a, 0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x15, 0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x16, +0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x17, 0x01, 0x88, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x18, 0x01, 0x8c, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x19, 0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1a, 0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1b, +0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, 0x00, 0x98, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x8d, 0x01, 0x82, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x8e, 0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x70, 0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x71, +0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x72, 0x01, 0x8e, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x84, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x74, 0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x75, 0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x78, +0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x79, 0x00, 0x97, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7a, 0x01, 0x88, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7b, 0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7c, 0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, +0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7e, 0x01, 0x94, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, 0x00, 0x98, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb0, 0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb1, 0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb2, +0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb3, 0x01, 0x8c, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb4, 0x01, 0x8e, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb5, 0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb6, 0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, +0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xba, 0x01, 0x82, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbb, 0x00, 0x97, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbc, 0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbd, 0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbe, +0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, 0x01, 0x84, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xc0, 0x01, 0x94, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xc1, 0x00, 0x14, 0x00, 0x2a, 0x00, 0x32, +0x00, 0x3a, 0x00, 0x42, 0x00, 0x4a, 0x00, 0x52, 0x00, 0x5a, +0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, 0x00, 0x7a, 0x00, 0x82, +0x00, 0x8a, 0x00, 0x92, 0x00, 0x9a, 0x00, 0xa2, 0x00, 0xaa, +0x00, 0xb2, 0x00, 0xba, 0x00, 0xc2, 0x01, 0x83, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x16, 0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x18, 0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, +0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, 0x01, 0x83, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x8e, 0x01, 0x89, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x71, 0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x73, 0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, +0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x79, 0x01, 0x89, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7b, 0x01, 0x8f, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7d, 0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7f, 0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb1, +0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb3, 0x01, 0x8f, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, 0x01, 0x95, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb7, 0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbb, 0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbd, +0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, 0x01, 0x95, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, 0x00, 0x14, 0x00, 0x2a, +0x00, 0x32, 0x00, 0x3a, 0x00, 0x42, 0x00, 0x4a, 0x00, 0x52, +0x00, 0x5a, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, 0x00, 0x7a, +0x00, 0x82, 0x00, 0x8a, 0x00, 0x92, 0x00, 0x9a, 0x00, 0xa2, +0x00, 0xaa, 0x00, 0xb2, 0x00, 0xba, 0x00, 0xc2, 0x00, 0x99, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x17, 0x01, 0x8a, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x18, 0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1a, 0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1b, +0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x70, 0x01, 0x8a, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x71, 0x01, 0x90, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x73, 0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x74, 0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7a, +0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7b, 0x01, 0x90, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, 0x01, 0x85, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7e, 0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb2, 0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb3, +0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, 0x01, 0x85, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb6, 0x00, 0x99, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbc, 0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbd, 0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, +0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc0, 0x00, 0x0f, +0x00, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, 0x38, 0x00, 0x40, +0x00, 0x48, 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x68, +0x00, 0x70, 0x00, 0x78, 0x00, 0x80, 0x00, 0x88, 0x00, 0x90, +0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x18, 0x01, 0x91, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, 0x01, 0x96, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1c, 0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x71, 0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, +0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x8b, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7b, 0x01, 0x91, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7d, 0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7f, 0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb3, +0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, 0x01, 0x96, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, 0x01, 0x8b, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbd, 0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbf, 0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, +0x00, 0x14, 0x00, 0x2a, 0x00, 0x32, 0x00, 0x3a, 0x00, 0x42, +0x00, 0x4a, 0x00, 0x52, 0x00, 0x5a, 0x00, 0x62, 0x00, 0x6a, +0x00, 0x72, 0x00, 0x7a, 0x00, 0x82, 0x00, 0x8a, 0x00, 0x92, +0x00, 0x9a, 0x00, 0xa2, 0x00, 0xaa, 0x00, 0xb2, 0x00, 0xba, +0x00, 0xc2, 0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x19, +0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, 0x01, 0x86, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1b, 0x01, 0x97, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1c, 0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x72, 0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, +0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x97, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x8d, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7c, 0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7d, 0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7e, +0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, 0x01, 0x8d, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb4, 0x01, 0x92, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb5, 0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb6, 0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, +0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbe, 0x01, 0x92, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, 0x01, 0x86, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xc0, 0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xc1, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x1c, +0x00, 0x24, 0x00, 0x2c, 0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1a, 0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, +0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, 0x01, 0x93, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, 0x01, 0x93, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbf, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x1e, +0x00, 0x26, 0x00, 0x2e, 0x00, 0x36, 0x00, 0x3e, 0x00, 0x46, +0x00, 0x4e, 0x00, 0x56, 0x00, 0x5e, 0x01, 0x87, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1b, 0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1c, 0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x74, +0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x87, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7e, 0x01, 0x98, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7f, 0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb6, 0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, +0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc0, 0x01, 0x98, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, 0x00, 0x05, 0x00, 0x0c, +0x00, 0x14, 0x00, 0x1c, 0x00, 0x24, 0x00, 0x2c, 0x01, 0x99, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, 0x01, 0x99, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x75, 0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7f, 0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, +0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, 0x00, 0x14, +0x00, 0x2a, 0x00, 0x32, 0x00, 0x3a, 0x00, 0x42, 0x00, 0x4a, +0x00, 0x52, 0x00, 0x5a, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, +0x00, 0x7a, 0x00, 0x82, 0x00, 0x8a, 0x00, 0x92, 0x00, 0x9a, +0x00, 0xa2, 0x00, 0xaa, 0x00, 0xb2, 0x00, 0xba, 0x00, 0xc2, +0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x16, 0x01, 0x89, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x18, 0x01, 0x8f, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1a, 0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1c, 0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x8e, +0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x71, 0x01, 0x8f, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x95, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x75, 0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x79, 0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7b, +0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, 0x01, 0x95, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, 0x01, 0x83, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb1, 0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb3, 0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, +0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, 0x01, 0x83, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbb, 0x01, 0x89, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbd, 0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbf, 0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, +0x00, 0x14, 0x00, 0x2a, 0x00, 0x32, 0x00, 0x3a, 0x00, 0x42, +0x00, 0x4a, 0x00, 0x52, 0x00, 0x5a, 0x00, 0x62, 0x00, 0x6a, +0x00, 0x72, 0x00, 0x7a, 0x00, 0x82, 0x00, 0x8a, 0x00, 0x92, +0x00, 0x9a, 0x00, 0xa2, 0x00, 0xaa, 0x00, 0xb2, 0x00, 0xba, +0x00, 0xc2, 0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x17, +0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x18, 0x01, 0x90, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, 0x01, 0x85, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1b, 0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x70, 0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x71, +0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x85, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x74, 0x00, 0x99, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7a, 0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7b, 0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, +0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7e, 0x00, 0x99, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb2, 0x01, 0x8a, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb3, 0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb5, 0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb6, +0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbc, 0x01, 0x8a, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbd, 0x01, 0x90, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbf, 0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xc0, 0x00, 0x28, 0x00, 0x52, 0x00, 0x5a, 0x00, 0x62, +0x00, 0x6a, 0x00, 0x72, 0x00, 0x7a, 0x00, 0x82, 0x00, 0x8a, +0x00, 0x92, 0x00, 0x9a, 0x00, 0xa2, 0x00, 0xaa, 0x00, 0xb2, +0x00, 0xba, 0x00, 0xc2, 0x00, 0xca, 0x00, 0xd2, 0x00, 0xda, +0x00, 0xe2, 0x00, 0xea, 0x00, 0xf2, 0x00, 0xfa, 0x01, 0x02, +0x01, 0x0a, 0x01, 0x12, 0x01, 0x1a, 0x01, 0x22, 0x01, 0x2a, +0x01, 0x32, 0x01, 0x3a, 0x01, 0x42, 0x01, 0x4a, 0x01, 0x52, +0x01, 0x5a, 0x01, 0x62, 0x01, 0x6a, 0x01, 0x72, 0x01, 0x7a, +0x01, 0x82, 0x01, 0x8a, 0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x15, 0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x16, +0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x17, 0x01, 0x88, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x18, 0x01, 0x8c, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x19, 0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1a, 0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1b, +0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, 0x00, 0x98, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x8d, 0x01, 0x82, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x8e, 0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x70, 0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x71, +0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x72, 0x01, 0x8e, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x84, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x74, 0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x75, 0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x78, +0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x79, 0x00, 0x97, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7a, 0x01, 0x88, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7b, 0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7c, 0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, +0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7e, 0x01, 0x94, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, 0x00, 0x98, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb0, 0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb1, 0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb2, +0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb3, 0x01, 0x8c, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb4, 0x01, 0x8e, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb5, 0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb6, 0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, +0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xba, 0x01, 0x82, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbb, 0x00, 0x97, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbc, 0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbd, 0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbe, +0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, 0x01, 0x84, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xc0, 0x01, 0x94, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xc1, 0x00, 0x0f, 0x00, 0x20, 0x00, 0x28, +0x00, 0x30, 0x00, 0x38, 0x00, 0x40, 0x00, 0x48, 0x00, 0x50, +0x00, 0x58, 0x00, 0x60, 0x00, 0x68, 0x00, 0x70, 0x00, 0x78, +0x00, 0x80, 0x00, 0x88, 0x00, 0x90, 0x01, 0x8b, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x18, 0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1a, 0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, +0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x71, 0x01, 0x91, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x96, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x75, 0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7b, 0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, +0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, 0x01, 0x8b, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb3, 0x01, 0x91, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb5, 0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb7, 0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbd, +0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, 0x01, 0x96, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, 0x00, 0x14, 0x00, 0x2a, +0x00, 0x32, 0x00, 0x3a, 0x00, 0x42, 0x00, 0x4a, 0x00, 0x52, +0x00, 0x5a, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, 0x00, 0x7a, +0x00, 0x82, 0x00, 0x8a, 0x00, 0x92, 0x00, 0x9a, 0x00, 0xa2, +0x00, 0xaa, 0x00, 0xb2, 0x00, 0xba, 0x00, 0xc2, 0x01, 0x8d, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x19, 0x01, 0x92, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1a, 0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1b, 0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, +0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x72, 0x01, 0x92, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x86, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x74, 0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x75, 0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7c, +0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, 0x01, 0x86, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7e, 0x01, 0x97, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7f, 0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb4, 0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, +0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb6, 0x01, 0x97, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, 0x01, 0x8d, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbe, 0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbf, 0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc0, +0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, 0x00, 0x05, +0x00, 0x0c, 0x00, 0x14, 0x00, 0x1c, 0x00, 0x24, 0x00, 0x2c, +0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, 0x01, 0x93, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x93, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7d, 0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb5, 0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, +0x00, 0x0a, 0x00, 0x16, 0x00, 0x1e, 0x00, 0x26, 0x00, 0x2e, +0x00, 0x36, 0x00, 0x3e, 0x00, 0x46, 0x00, 0x4e, 0x00, 0x56, +0x00, 0x5e, 0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1b, +0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, 0x01, 0x87, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x98, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x75, 0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7e, 0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, +0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb6, 0x01, 0x98, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, 0x01, 0x87, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xc0, 0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xc1, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x1c, +0x00, 0x24, 0x00, 0x2c, 0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1c, 0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, +0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, 0x01, 0x99, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, 0x01, 0x99, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xc1, 0x00, 0x28, 0x00, 0x52, 0x00, 0x5a, +0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, 0x00, 0x7a, 0x00, 0x82, +0x00, 0x8a, 0x00, 0x92, 0x00, 0x9a, 0x00, 0xa2, 0x00, 0xaa, +0x00, 0xb2, 0x00, 0xba, 0x00, 0xc2, 0x00, 0xca, 0x00, 0xd2, +0x00, 0xda, 0x00, 0xe2, 0x00, 0xea, 0x00, 0xf2, 0x00, 0xfa, +0x01, 0x02, 0x01, 0x0a, 0x01, 0x12, 0x01, 0x1a, 0x01, 0x22, +0x01, 0x2a, 0x01, 0x32, 0x01, 0x3a, 0x01, 0x42, 0x01, 0x4a, +0x01, 0x52, 0x01, 0x5a, 0x01, 0x62, 0x01, 0x6a, 0x01, 0x72, +0x01, 0x7a, 0x01, 0x82, 0x01, 0x8a, 0x00, 0x98, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x15, 0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x16, 0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x17, +0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x18, 0x01, 0x8c, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x19, 0x01, 0x8e, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1a, 0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1b, 0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, +0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x8d, 0x01, 0x82, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x8e, 0x00, 0x97, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x70, 0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x71, 0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x72, +0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x84, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x94, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x75, 0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x78, 0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x79, +0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7a, 0x01, 0x88, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7b, 0x01, 0x8c, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7c, 0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7d, 0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7e, +0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, 0x00, 0x98, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb0, 0x01, 0x82, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb1, 0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb2, 0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb3, +0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb4, 0x01, 0x8e, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, 0x01, 0x84, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb6, 0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb7, 0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xba, +0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbb, 0x00, 0x97, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbc, 0x01, 0x88, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbd, 0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbe, 0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, +0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc0, 0x01, 0x94, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, 0x00, 0x14, 0x00, 0x2a, +0x00, 0x32, 0x00, 0x3a, 0x00, 0x42, 0x00, 0x4a, 0x00, 0x52, +0x00, 0x5a, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, 0x00, 0x7a, +0x00, 0x82, 0x00, 0x8a, 0x00, 0x92, 0x00, 0x9a, 0x00, 0xa2, +0x00, 0xaa, 0x00, 0xb2, 0x00, 0xba, 0x00, 0xc2, 0x01, 0x83, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x16, 0x01, 0x89, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x18, 0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1a, 0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, +0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x8e, 0x01, 0x89, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x71, 0x01, 0x8f, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x73, 0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x75, 0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x79, +0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7b, 0x01, 0x8f, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, 0x01, 0x95, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7f, 0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb1, 0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb3, +0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, 0x01, 0x95, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, 0x01, 0x83, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbb, 0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbd, 0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, +0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, 0x00, 0x14, +0x00, 0x2a, 0x00, 0x32, 0x00, 0x3a, 0x00, 0x42, 0x00, 0x4a, +0x00, 0x52, 0x00, 0x5a, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, +0x00, 0x7a, 0x00, 0x82, 0x00, 0x8a, 0x00, 0x92, 0x00, 0x9a, +0x00, 0xa2, 0x00, 0xaa, 0x00, 0xb2, 0x00, 0xba, 0x00, 0xc2, +0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x17, 0x01, 0x8a, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x18, 0x01, 0x90, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1a, 0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1b, 0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x70, +0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x71, 0x01, 0x90, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x85, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x74, 0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7a, 0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7b, +0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, 0x01, 0x85, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7e, 0x00, 0x99, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb2, 0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb3, 0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, +0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb6, 0x00, 0x99, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbc, 0x01, 0x8a, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbd, 0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbf, 0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc0, +0x00, 0x0f, 0x00, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, 0x38, +0x00, 0x40, 0x00, 0x48, 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, +0x00, 0x68, 0x00, 0x70, 0x00, 0x78, 0x00, 0x80, 0x00, 0x88, +0x00, 0x90, 0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x18, +0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, 0x01, 0x96, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, 0x01, 0x8b, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x71, 0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x73, 0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, +0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7b, 0x01, 0x91, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, 0x01, 0x96, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7f, 0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb3, 0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, +0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, 0x01, 0x8b, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbd, 0x01, 0x91, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbf, 0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xc1, 0x00, 0x14, 0x00, 0x2a, 0x00, 0x32, 0x00, 0x3a, +0x00, 0x42, 0x00, 0x4a, 0x00, 0x52, 0x00, 0x5a, 0x00, 0x62, +0x00, 0x6a, 0x00, 0x72, 0x00, 0x7a, 0x00, 0x82, 0x00, 0x8a, +0x00, 0x92, 0x00, 0x9a, 0x00, 0xa2, 0x00, 0xaa, 0x00, 0xb2, +0x00, 0xba, 0x00, 0xc2, 0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x19, 0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, +0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1b, 0x01, 0x97, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, 0x01, 0x8d, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x72, 0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x73, 0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x74, +0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x8d, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7c, 0x01, 0x92, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7d, 0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7e, 0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, +0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb4, 0x01, 0x92, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, 0x01, 0x86, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb6, 0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb7, 0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbe, +0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, 0x01, 0x86, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xc0, 0x01, 0x97, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xc1, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x14, +0x00, 0x1c, 0x00, 0x24, 0x00, 0x2c, 0x01, 0x93, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1a, 0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x73, 0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, +0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, 0x01, 0x93, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, 0x00, 0x0a, 0x00, 0x16, +0x00, 0x1e, 0x00, 0x26, 0x00, 0x2e, 0x00, 0x36, 0x00, 0x3e, +0x00, 0x46, 0x00, 0x4e, 0x00, 0x56, 0x00, 0x5e, 0x01, 0x87, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1b, 0x01, 0x98, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1c, 0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x74, 0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, +0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7e, 0x01, 0x98, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, 0x01, 0x87, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb6, 0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb7, 0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc0, +0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, 0x00, 0x05, +0x00, 0x0c, 0x00, 0x14, 0x00, 0x1c, 0x00, 0x24, 0x00, 0x2c, +0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, 0x01, 0x99, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x99, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7f, 0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb7, 0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, +0x00, 0x28, 0x00, 0x52, 0x00, 0x5a, 0x00, 0x62, 0x00, 0x6a, +0x00, 0x72, 0x00, 0x7a, 0x00, 0x82, 0x00, 0x8a, 0x00, 0x92, +0x00, 0x9a, 0x00, 0xa2, 0x00, 0xaa, 0x00, 0xb2, 0x00, 0xba, +0x00, 0xc2, 0x00, 0xca, 0x00, 0xd2, 0x00, 0xda, 0x00, 0xe2, +0x00, 0xea, 0x00, 0xf2, 0x00, 0xfa, 0x01, 0x02, 0x01, 0x0a, +0x01, 0x12, 0x01, 0x1a, 0x01, 0x22, 0x01, 0x2a, 0x01, 0x32, +0x01, 0x3a, 0x01, 0x42, 0x01, 0x4a, 0x01, 0x52, 0x01, 0x5a, +0x01, 0x62, 0x01, 0x6a, 0x01, 0x72, 0x01, 0x7a, 0x01, 0x82, +0x01, 0x8a, 0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x15, +0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x16, 0x00, 0x97, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x17, 0x01, 0x88, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x18, 0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x19, 0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, +0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1b, 0x01, 0x94, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, 0x00, 0x98, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x8d, 0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x8e, 0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x70, +0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x71, 0x01, 0x8c, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x72, 0x01, 0x8e, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x73, 0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x74, 0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, +0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x78, 0x01, 0x82, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x79, 0x00, 0x97, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7a, 0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7b, 0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7c, +0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, 0x01, 0x84, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7e, 0x01, 0x94, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7f, 0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb0, 0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb1, +0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb2, 0x01, 0x88, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb3, 0x01, 0x8c, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb4, 0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb5, 0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb6, +0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, 0x00, 0x98, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xba, 0x01, 0x82, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbb, 0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbc, 0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbd, +0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbe, 0x01, 0x8e, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, 0x01, 0x84, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xc0, 0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xc1, 0x00, 0x14, 0x00, 0x2a, 0x00, 0x32, 0x00, 0x3a, +0x00, 0x42, 0x00, 0x4a, 0x00, 0x52, 0x00, 0x5a, 0x00, 0x62, +0x00, 0x6a, 0x00, 0x72, 0x00, 0x7a, 0x00, 0x82, 0x00, 0x8a, +0x00, 0x92, 0x00, 0x9a, 0x00, 0xa2, 0x00, 0xaa, 0x00, 0xb2, +0x00, 0xba, 0x00, 0xc2, 0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x16, 0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x18, +0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, 0x01, 0x95, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, 0x01, 0x83, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x8e, 0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x71, 0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, +0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x83, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x79, 0x01, 0x89, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7b, 0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7d, 0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, +0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb1, 0x01, 0x89, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb3, 0x01, 0x8f, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb5, 0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb7, 0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbb, +0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbd, 0x01, 0x8f, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, 0x01, 0x95, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xc1, 0x00, 0x14, 0x00, 0x2a, 0x00, 0x32, +0x00, 0x3a, 0x00, 0x42, 0x00, 0x4a, 0x00, 0x52, 0x00, 0x5a, +0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, 0x00, 0x7a, 0x00, 0x82, +0x00, 0x8a, 0x00, 0x92, 0x00, 0x9a, 0x00, 0xa2, 0x00, 0xaa, +0x00, 0xb2, 0x00, 0xba, 0x00, 0xc2, 0x00, 0x99, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x17, 0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x18, 0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, +0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1b, 0x00, 0x99, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x70, 0x01, 0x8a, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x71, 0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x73, 0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x74, +0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7a, 0x01, 0x8a, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7b, 0x01, 0x90, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7d, 0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7e, 0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb2, +0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb3, 0x01, 0x90, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, 0x01, 0x85, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb6, 0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbc, 0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbd, +0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, 0x01, 0x85, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xc0, 0x00, 0x0f, 0x00, 0x20, +0x00, 0x28, 0x00, 0x30, 0x00, 0x38, 0x00, 0x40, 0x00, 0x48, +0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x68, 0x00, 0x70, +0x00, 0x78, 0x00, 0x80, 0x00, 0x88, 0x00, 0x90, 0x01, 0x8b, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x18, 0x01, 0x91, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1a, 0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1c, 0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x71, +0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x96, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x8b, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7b, 0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7d, 0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, +0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb3, 0x01, 0x91, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, 0x01, 0x96, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb7, 0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbd, 0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, +0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, 0x00, 0x14, +0x00, 0x2a, 0x00, 0x32, 0x00, 0x3a, 0x00, 0x42, 0x00, 0x4a, +0x00, 0x52, 0x00, 0x5a, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, +0x00, 0x7a, 0x00, 0x82, 0x00, 0x8a, 0x00, 0x92, 0x00, 0x9a, +0x00, 0xa2, 0x00, 0xaa, 0x00, 0xb2, 0x00, 0xba, 0x00, 0xc2, +0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x19, 0x01, 0x92, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, 0x01, 0x86, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1b, 0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1c, 0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x72, +0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x86, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x97, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x75, 0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7c, 0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, +0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7e, 0x01, 0x97, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, 0x01, 0x8d, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb4, 0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb5, 0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb6, +0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, 0x01, 0x8d, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbe, 0x01, 0x92, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbf, 0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xc0, 0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, +0x00, 0x05, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x1c, 0x00, 0x24, +0x00, 0x2c, 0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, +0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x93, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, 0x01, 0x93, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb5, 0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbf, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x1e, 0x00, 0x26, +0x00, 0x2e, 0x00, 0x36, 0x00, 0x3e, 0x00, 0x46, 0x00, 0x4e, +0x00, 0x56, 0x00, 0x5e, 0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1b, 0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, +0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x98, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x87, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7e, 0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7f, 0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb6, +0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, 0x01, 0x87, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xc0, 0x01, 0x98, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xc1, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x14, +0x00, 0x1c, 0x00, 0x24, 0x00, 0x2c, 0x01, 0x99, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1c, 0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x75, 0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, +0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, 0x01, 0x99, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, 0x00, 0x28, 0x00, 0x52, +0x00, 0x5a, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, 0x00, 0x7a, +0x00, 0x82, 0x00, 0x8a, 0x00, 0x92, 0x00, 0x9a, 0x00, 0xa2, +0x00, 0xaa, 0x00, 0xb2, 0x00, 0xba, 0x00, 0xc2, 0x00, 0xca, +0x00, 0xd2, 0x00, 0xda, 0x00, 0xe2, 0x00, 0xea, 0x00, 0xf2, +0x00, 0xfa, 0x01, 0x02, 0x01, 0x0a, 0x01, 0x12, 0x01, 0x1a, +0x01, 0x22, 0x01, 0x2a, 0x01, 0x32, 0x01, 0x3a, 0x01, 0x42, +0x01, 0x4a, 0x01, 0x52, 0x01, 0x5a, 0x01, 0x62, 0x01, 0x6a, +0x01, 0x72, 0x01, 0x7a, 0x01, 0x82, 0x01, 0x8a, 0x00, 0x98, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x15, 0x01, 0x82, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x16, 0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x17, 0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x18, +0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x19, 0x01, 0x8e, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, 0x01, 0x84, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1b, 0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1c, 0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x8d, +0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x8e, 0x00, 0x97, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x70, 0x01, 0x88, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x71, 0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x72, 0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, +0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x94, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, 0x00, 0x98, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x78, 0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x79, 0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7a, +0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7b, 0x01, 0x8c, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7c, 0x01, 0x8e, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7d, 0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7e, 0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, +0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb0, 0x01, 0x82, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb1, 0x00, 0x97, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb2, 0x01, 0x88, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb3, 0x01, 0x8c, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb4, +0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, 0x01, 0x84, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb6, 0x01, 0x94, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb7, 0x00, 0x98, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xba, 0x01, 0x82, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbb, +0x00, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbc, 0x01, 0x88, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbd, 0x01, 0x8c, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbe, 0x01, 0x8e, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbf, 0x01, 0x84, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc0, +0x01, 0x94, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, 0x00, 0x14, +0x00, 0x2a, 0x00, 0x32, 0x00, 0x3a, 0x00, 0x42, 0x00, 0x4a, +0x00, 0x52, 0x00, 0x5a, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, +0x00, 0x7a, 0x00, 0x82, 0x00, 0x8a, 0x00, 0x92, 0x00, 0x9a, +0x00, 0xa2, 0x00, 0xaa, 0x00, 0xb2, 0x00, 0xba, 0x00, 0xc2, +0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x16, 0x01, 0x89, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x18, 0x01, 0x8f, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1a, 0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1c, 0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x8e, +0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x71, 0x01, 0x8f, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x95, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x75, 0x01, 0x83, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x79, 0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7b, +0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, 0x01, 0x95, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, 0x01, 0x83, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb1, 0x01, 0x89, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb3, 0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, +0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, 0x01, 0x83, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbb, 0x01, 0x89, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbd, 0x01, 0x8f, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbf, 0x01, 0x95, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, +0x00, 0x14, 0x00, 0x2a, 0x00, 0x32, 0x00, 0x3a, 0x00, 0x42, +0x00, 0x4a, 0x00, 0x52, 0x00, 0x5a, 0x00, 0x62, 0x00, 0x6a, +0x00, 0x72, 0x00, 0x7a, 0x00, 0x82, 0x00, 0x8a, 0x00, 0x92, +0x00, 0x9a, 0x00, 0xa2, 0x00, 0xaa, 0x00, 0xb2, 0x00, 0xba, +0x00, 0xc2, 0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x17, +0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x18, 0x01, 0x90, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, 0x01, 0x85, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x1b, 0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x70, 0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x71, +0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x73, 0x01, 0x85, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x74, 0x00, 0x99, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7a, 0x01, 0x8a, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7b, 0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, +0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7e, 0x00, 0x99, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb2, 0x01, 0x8a, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb3, 0x01, 0x90, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb5, 0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb6, +0x00, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbc, 0x01, 0x8a, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbd, 0x01, 0x90, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xbf, 0x01, 0x85, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xc0, 0x00, 0x0f, 0x00, 0x20, 0x00, 0x28, 0x00, 0x30, +0x00, 0x38, 0x00, 0x40, 0x00, 0x48, 0x00, 0x50, 0x00, 0x58, +0x00, 0x60, 0x00, 0x68, 0x00, 0x70, 0x00, 0x78, 0x00, 0x80, +0x00, 0x88, 0x00, 0x90, 0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x18, 0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, +0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, 0x01, 0x8b, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x71, 0x01, 0x91, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x73, 0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x75, 0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7b, +0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, 0x01, 0x96, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, 0x01, 0x8b, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb3, 0x01, 0x91, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xb5, 0x01, 0x96, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb7, +0x01, 0x8b, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbd, 0x01, 0x91, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, 0x01, 0x96, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xc1, 0x00, 0x14, 0x00, 0x2a, 0x00, 0x32, +0x00, 0x3a, 0x00, 0x42, 0x00, 0x4a, 0x00, 0x52, 0x00, 0x5a, +0x00, 0x62, 0x00, 0x6a, 0x00, 0x72, 0x00, 0x7a, 0x00, 0x82, +0x00, 0x8a, 0x00, 0x92, 0x00, 0x9a, 0x00, 0xa2, 0x00, 0xaa, +0x00, 0xb2, 0x00, 0xba, 0x00, 0xc2, 0x01, 0x8d, 0x00, 0x03, +0x01, 0x6e, 0x00, 0x19, 0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, +0x00, 0x1a, 0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1b, +0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, 0x01, 0x8d, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x72, 0x01, 0x92, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x73, 0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x74, 0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, +0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7c, 0x01, 0x92, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7d, 0x01, 0x86, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x7e, 0x01, 0x97, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7f, 0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb4, +0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, 0x01, 0x86, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb6, 0x01, 0x97, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb7, 0x01, 0x8d, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xbe, 0x01, 0x92, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, +0x01, 0x86, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc0, 0x01, 0x97, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, 0x00, 0x05, 0x00, 0x0c, +0x00, 0x14, 0x00, 0x1c, 0x00, 0x24, 0x00, 0x2c, 0x01, 0x93, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1a, 0x01, 0x93, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x73, 0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x7d, 0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xb5, +0x01, 0x93, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xbf, 0x00, 0x0a, +0x00, 0x16, 0x00, 0x1e, 0x00, 0x26, 0x00, 0x2e, 0x00, 0x36, +0x00, 0x3e, 0x00, 0x46, 0x00, 0x4e, 0x00, 0x56, 0x00, 0x5e, +0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1b, 0x01, 0x98, +0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, 0x01, 0x87, 0x00, 0x03, +0x01, 0x6e, 0x01, 0x74, 0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, +0x01, 0x75, 0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7e, +0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, 0x01, 0x87, +0x00, 0x03, 0x01, 0x6e, 0x01, 0xb6, 0x01, 0x98, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb7, 0x01, 0x87, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xc0, 0x01, 0x98, 0x00, 0x03, 0x01, 0x6e, 0x01, 0xc1, +0x00, 0x05, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x1c, 0x00, 0x24, +0x00, 0x2c, 0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x00, 0x1c, +0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x99, +0x00, 0x03, 0x01, 0x6e, 0x01, 0x7f, 0x01, 0x99, 0x00, 0x03, +0x01, 0x6e, 0x01, 0xb7, 0x01, 0x99, 0x00, 0x03, 0x01, 0x6e, +0x01, 0xc1, 0x00, 0x02, 0x02, 0x98, 0x00, 0x02, 0x01, 0x6e, +0x01, 0x6e, 0x00, 0x02, 0x02, 0x0a, 0x00, 0x28, 0x01, 0x6f, +0x00, 0x94, 0x00, 0x8d, 0x00, 0x8e, 0x01, 0x70, 0x01, 0x71, +0x01, 0x72, 0x01, 0x73, 0x01, 0x74, 0x01, 0x75, 0x01, 0x6f, +0x00, 0x94, 0x00, 0x8d, 0x00, 0x8e, 0x01, 0x70, 0x01, 0x71, +0x01, 0x72, 0x01, 0x73, 0x01, 0x74, 0x01, 0x75, 0x01, 0x6f, +0x00, 0x94, 0x00, 0x8d, 0x00, 0x8e, 0x01, 0x70, 0x01, 0x71, +0x01, 0x72, 0x01, 0x73, 0x01, 0x74, 0x01, 0x75, 0x01, 0x6f, +0x00, 0x94, 0x00, 0x8d, 0x00, 0x8e, 0x01, 0x70, 0x01, 0x71, +0x01, 0x72, 0x01, 0x73, 0x01, 0x74, 0x01, 0x75, 0x00, 0x03, +0x00, 0x01, 0x02, 0x6e, 0x00, 0x01, 0x02, 0x7e, 0x00, 0x00, +0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x02, 0x02, 0x82, +0x00, 0x15, 0x01, 0xc6, 0x01, 0xc7, 0x01, 0xc8, 0x01, 0xc9, +0x01, 0xca, 0x01, 0xcb, 0x01, 0xcc, 0x01, 0xcd, 0x01, 0xce, +0x01, 0xcf, 0x01, 0xd0, 0x01, 0xd1, 0x01, 0xd2, 0x01, 0xd3, +0x01, 0xd4, 0x01, 0xd5, 0x01, 0xd6, 0x01, 0xd7, 0x01, 0xd8, +0x00, 0x36, 0x00, 0x2d, 0x00, 0x02, 0x02, 0x80, 0x00, 0x7f, +0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, +0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, +0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, +0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, +0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, +0x00, 0x3d, 0x00, 0x6b, 0x00, 0x6d, 0x00, 0x9b, 0x00, 0x9c, +0x00, 0x9d, 0x00, 0x9e, 0x00, 0x9f, 0x00, 0xa0, 0x00, 0xa1, +0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa5, 0x00, 0xa6, +0x00, 0xa7, 0x00, 0xa8, 0x00, 0xa9, 0x00, 0xaa, 0x00, 0xab, +0x00, 0xac, 0x00, 0xad, 0x00, 0xae, 0x00, 0xaf, 0x00, 0xb0, +0x00, 0xb1, 0x00, 0xb3, 0x00, 0xb4, 0x00, 0xb5, 0x00, 0xb6, +0x00, 0xb7, 0x00, 0xb8, 0x00, 0xb9, 0x00, 0x7a, 0x00, 0xdb, +0x00, 0xdd, 0x00, 0xdf, 0x00, 0xe1, 0x00, 0xe3, 0x00, 0xe5, +0x00, 0xe7, 0x00, 0xe9, 0x00, 0xeb, 0x00, 0xed, 0x00, 0xef, +0x00, 0xf1, 0x00, 0xf3, 0x00, 0xf5, 0x00, 0xf7, 0x00, 0xf9, +0x00, 0xfb, 0x00, 0xfd, 0x00, 0xff, 0x01, 0x01, 0x01, 0x03, +0x01, 0x05, 0x01, 0x07, 0x01, 0x09, 0x01, 0x0b, 0x01, 0x0e, +0x01, 0x10, 0x01, 0x12, 0x01, 0x14, 0x01, 0x16, 0x01, 0x18, +0x01, 0x1a, 0x01, 0x1c, 0x01, 0x1e, 0x01, 0x20, 0x01, 0x22, +0x01, 0x24, 0x01, 0x26, 0x01, 0x28, 0x01, 0x2a, 0x01, 0x2c, +0x01, 0x2e, 0x01, 0x30, 0x01, 0x32, 0x01, 0x34, 0x01, 0x36, +0x01, 0x38, 0x01, 0x3a, 0x01, 0x3c, 0x01, 0x3e, 0x01, 0x40, +0x01, 0x42, 0x01, 0x44, 0x01, 0x46, 0x01, 0x48, 0x01, 0x4a, +0x01, 0x4c, 0x01, 0x4e, 0x01, 0x50, 0x01, 0x52, 0x01, 0x54, +0x01, 0x56, 0x01, 0x59, 0x01, 0x5b, 0x01, 0x66, 0x01, 0x68, +0x01, 0x6a, 0x01, 0x6c, 0x00, 0x02, 0x02, 0x7e, 0x00, 0x09, +0x04, 0xc2, 0x04, 0xc3, 0x04, 0xc4, 0x04, 0xc5, 0x04, 0xc6, +0x04, 0xc7, 0x04, 0xc8, 0x04, 0xc9, 0x04, 0xda, 0x00, 0x02, +0x02, 0x76, 0x00, 0x09, 0x04, 0xca, 0x04, 0xcb, 0x04, 0xcc, +0x04, 0xcd, 0x04, 0xce, 0x04, 0xcf, 0x04, 0xd0, 0x04, 0xd1, +0x04, 0xdb, 0x00, 0x02, 0x02, 0x6e, 0x00, 0x09, 0x04, 0xd2, +0x04, 0xd3, 0x04, 0xd4, 0x04, 0xd5, 0x04, 0xd6, 0x04, 0xd7, +0x04, 0xd8, 0x04, 0xd9, 0x04, 0xdc, 0x00, 0x02, 0x00, 0xf0, +0x00, 0x0a, 0x01, 0x78, 0x01, 0x79, 0x01, 0x77, 0x01, 0x76, +0x01, 0x7a, 0x01, 0x7b, 0x01, 0x7c, 0x01, 0x7d, 0x01, 0x7e, +0x01, 0x7f, 0x00, 0x01, 0x00, 0x01, 0x00, 0x4c, 0x00, 0x01, +0x00, 0x01, 0x02, 0xe4, 0x00, 0x02, 0x00, 0x03, 0x00, 0x13, +0x00, 0x1c, 0x00, 0x00, 0x01, 0x76, 0x01, 0x7f, 0x00, 0x0a, +0x01, 0xae, 0x01, 0xc1, 0x00, 0x14, 0x00, 0x01, 0x00, 0x02, +0x00, 0x44, 0x00, 0x52, 0x00, 0x02, 0x00, 0x05, 0x00, 0x13, +0x00, 0x1c, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x0a, +0x00, 0x94, 0x00, 0x94, 0x00, 0x0c, 0x01, 0x6f, 0x01, 0x75, +0x00, 0x0d, 0x01, 0xae, 0x01, 0xc1, 0x00, 0x14, 0x00, 0x02, +0x00, 0x05, 0x00, 0x13, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x8d, +0x00, 0x8e, 0x00, 0x0a, 0x00, 0x94, 0x00, 0x94, 0x00, 0x0c, +0x01, 0x6f, 0x01, 0x7f, 0x00, 0x0d, 0x01, 0xb8, 0x01, 0xc1, +0x00, 0x1e, 0x00, 0x02, 0x00, 0x05, 0x00, 0x13, 0x00, 0x1c, +0x00, 0x00, 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x0a, 0x00, 0x94, +0x00, 0x94, 0x00, 0x0c, 0x01, 0x6f, 0x01, 0x7f, 0x00, 0x0d, +0x01, 0xae, 0x01, 0xb7, 0x00, 0x1e, 0x00, 0x01, 0x00, 0x02, +0x00, 0x12, 0x01, 0xa0, 0x00, 0x02, 0x00, 0x07, 0x00, 0x14, +0x00, 0x1b, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x08, +0x00, 0x94, 0x00, 0x94, 0x00, 0x0a, 0x01, 0x70, 0x01, 0x74, +0x00, 0x0b, 0x01, 0x77, 0x01, 0x7e, 0x00, 0x10, 0x01, 0xaf, +0x01, 0xb6, 0x00, 0x18, 0x01, 0xb9, 0x01, 0xc0, 0x00, 0x20, +0x00, 0x02, 0x00, 0x02, 0x01, 0x6e, 0x01, 0x6e, 0x00, 0x00, +0x01, 0x76, 0x01, 0x7f, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, +0x00, 0x8d, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x94, 0x00, 0x94, +0x00, 0x02, 0x01, 0x6f, 0x01, 0x75, 0x00, 0x03, 0x00, 0x01, +0x00, 0x15, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x12, +0x00, 0x23, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x5e, +0x00, 0x60, 0x00, 0x6c, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, +0x00, 0x78, 0x00, 0x7c, 0x00, 0x86, 0x00, 0x96, 0x00, 0x9a, +0x01, 0x58, 0x01, 0x5d, 0x00, 0x01, 0x00, 0x7f, 0x00, 0x44, +0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, +0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, +0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, +0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, +0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, +0x00, 0x77, 0x00, 0x79, 0x00, 0xbb, 0x00, 0xbc, 0x00, 0xbd, +0x00, 0xbe, 0x00, 0xbf, 0x00, 0xc0, 0x00, 0xc1, 0x00, 0xc2, +0x00, 0xc3, 0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, +0x00, 0xc8, 0x00, 0xc9, 0x00, 0xca, 0x00, 0xcb, 0x00, 0xcc, +0x00, 0xcd, 0x00, 0xce, 0x00, 0xcf, 0x00, 0xd0, 0x00, 0xd1, +0x00, 0xd3, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0xd6, 0x00, 0xd7, +0x00, 0xd8, 0x00, 0xd9, 0x00, 0xda, 0x00, 0xdc, 0x00, 0xde, +0x00, 0xe0, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xe6, 0x00, 0xe8, +0x00, 0xea, 0x00, 0xec, 0x00, 0xee, 0x00, 0xf0, 0x00, 0xf2, +0x00, 0xf4, 0x00, 0xf6, 0x00, 0xf8, 0x00, 0xfa, 0x00, 0xfc, +0x00, 0xfe, 0x01, 0x00, 0x01, 0x02, 0x01, 0x04, 0x01, 0x06, +0x01, 0x08, 0x01, 0x0a, 0x01, 0x0d, 0x01, 0x0f, 0x01, 0x11, +0x01, 0x13, 0x01, 0x15, 0x01, 0x17, 0x01, 0x19, 0x01, 0x1b, +0x01, 0x1d, 0x01, 0x1f, 0x01, 0x21, 0x01, 0x23, 0x01, 0x25, +0x01, 0x27, 0x01, 0x29, 0x01, 0x2b, 0x01, 0x2d, 0x01, 0x2f, +0x01, 0x31, 0x01, 0x33, 0x01, 0x35, 0x01, 0x37, 0x01, 0x39, +0x01, 0x3b, 0x01, 0x3d, 0x01, 0x3f, 0x01, 0x41, 0x01, 0x43, +0x01, 0x45, 0x01, 0x47, 0x01, 0x49, 0x01, 0x4b, 0x01, 0x4d, +0x01, 0x4f, 0x01, 0x51, 0x01, 0x53, 0x01, 0x55, 0x01, 0x57, +0x01, 0x5a, 0x01, 0x5c, 0x01, 0x67, 0x01, 0x69, 0x01, 0x6b, +0x01, 0x6d, 0x00, 0x02, 0x00, 0x02, 0x04, 0x53, 0x04, 0x5a, +0x00, 0x00, 0x04, 0x86, 0x04, 0x86, 0x00, 0x08, 0x00, 0x02, +0x00, 0x02, 0x04, 0x63, 0x04, 0x6a, 0x00, 0x00, 0x04, 0x95, +0x04, 0x95, 0x00, 0x08, 0x00, 0x02, 0x00, 0x02, 0x04, 0x73, +0x04, 0x7a, 0x00, 0x00, 0x04, 0xbf, 0x04, 0xbf, 0x00, 0x08, +0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, +0x00, 0x01, 0x00, 0x00, 0x19, 0x1a, 0x00, 0x00, 0x00, 0x14, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x12, 0x30, 0x82, +0x19, 0x0e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, +0x01, 0x07, 0x02, 0xa0, 0x82, 0x18, 0xff, 0x30, 0x82, 0x18, +0xfb, 0x02, 0x01, 0x01, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x05, +0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x61, 0x06, +0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, +0x04, 0xa0, 0x53, 0x30, 0x51, 0x30, 0x2c, 0x06, 0x0a, 0x2b, +0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x1c, 0xa2, +0x1e, 0x80, 0x1c, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00, +0x4f, 0x00, 0x62, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x6c, 0x00, +0x65, 0x00, 0x74, 0x00, 0x65, 0x00, 0x3e, 0x00, 0x3e, 0x00, +0x3e, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, +0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x60, 0x78, 0x1c, 0x38, +0xd3, 0x3b, 0xc9, 0x0d, 0xcc, 0x82, 0xb5, 0xf1, 0x6c, 0x28, +0x2d, 0x07, 0x79, 0x83, 0x0b, 0x8e, 0xa0, 0x82, 0x13, 0x82, +0x30, 0x82, 0x05, 0x56, 0x30, 0x82, 0x04, 0x3e, 0xa0, 0x03, +0x02, 0x01, 0x02, 0x02, 0x02, 0x20, 0x05, 0x30, 0x0d, 0x06, +0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, +0x05, 0x00, 0x30, 0x81, 0xcf, 0x31, 0x0b, 0x30, 0x09, 0x06, +0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, +0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, +0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, +0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, +0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x25, 0x30, +0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, 0x74, +0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, +0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, +0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x3a, 0x30, 0x38, +0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x68, 0x74, 0x74, +0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, +0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x61, +0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, +0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, +0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x31, 0x36, 0x30, 0x34, +0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x53, 0x74, 0x61, +0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x53, 0x65, 0x72, +0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, +0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, +0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, +0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x35, +0x30, 0x33, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, +0x0d, 0x31, 0x36, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, 0x30, +0x30, 0x30, 0x30, 0x5a, 0x30, 0x81, 0xc1, 0x31, 0x0b, 0x30, +0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, +0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, +0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, +0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, +0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, +0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, +0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, +0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, +0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33, +0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, +0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, +0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, +0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, +0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, +0x2f, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, +0x13, 0x26, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, +0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, +0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, +0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, +0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, +0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, +0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, +0x01, 0x01, 0x00, 0xf2, 0xb3, 0x91, 0xa5, 0xba, 0xd7, 0xd6, +0x49, 0x0d, 0xf6, 0x7d, 0xd6, 0xc2, 0x2d, 0x90, 0xce, 0xfb, +0xe9, 0x60, 0x5a, 0x1a, 0x63, 0x15, 0x19, 0x9c, 0xb4, 0x30, +0xa0, 0x9b, 0xd4, 0x78, 0xea, 0x06, 0x43, 0x3b, 0xed, 0x9d, +0x23, 0x28, 0x32, 0x26, 0x5f, 0x32, 0x25, 0xe8, 0x95, 0x85, +0x0d, 0x3e, 0x4f, 0x80, 0xb4, 0x20, 0xb0, 0x9c, 0xa2, 0x5e, +0x3e, 0x51, 0x8f, 0xfa, 0x93, 0x2e, 0xbb, 0xb2, 0xca, 0xc6, +0x3b, 0x11, 0x02, 0x56, 0x00, 0x20, 0x8b, 0x41, 0x29, 0x84, +0xb4, 0x2b, 0x35, 0x79, 0xfb, 0xb0, 0x69, 0x07, 0xf1, 0x88, +0x5d, 0x72, 0xad, 0xc0, 0xe2, 0xcb, 0x45, 0x0e, 0x25, 0xaf, +0xc4, 0xb4, 0xc2, 0xd6, 0xac, 0x65, 0xb4, 0x61, 0x1a, 0xe2, +0xdf, 0x2d, 0x12, 0x0c, 0x76, 0x97, 0x63, 0x19, 0x4c, 0x79, +0x3c, 0xbb, 0x0c, 0x74, 0x66, 0xf5, 0x01, 0x19, 0x59, 0x50, +0xe2, 0x0d, 0x9b, 0x5f, 0x59, 0x24, 0xfa, 0x39, 0x1f, 0x99, +0xd3, 0x89, 0x70, 0x55, 0x48, 0xa6, 0x99, 0xa6, 0x0b, 0xe0, +0x7b, 0xa6, 0x28, 0x20, 0xe5, 0x8a, 0xcb, 0x5d, 0x92, 0xad, +0x50, 0x28, 0xff, 0x80, 0x20, 0xcc, 0x2a, 0x2f, 0xd3, 0xbf, +0xf1, 0xb9, 0xab, 0x4a, 0x5e, 0x3d, 0x97, 0x7a, 0x75, 0x08, +0xa1, 0x15, 0x99, 0x02, 0x5f, 0x5e, 0xed, 0xcc, 0xa7, 0x40, +0xd6, 0x81, 0x55, 0x5d, 0xe8, 0x45, 0x27, 0xee, 0xbb, 0xff, +0x9d, 0xf8, 0x18, 0xc2, 0x80, 0xf5, 0xb7, 0xec, 0x74, 0xb0, +0xce, 0xc2, 0x3f, 0x3e, 0x33, 0xf7, 0xef, 0xc1, 0x1c, 0x0b, +0xd5, 0x48, 0xc9, 0x65, 0x32, 0x37, 0x6d, 0x0b, 0x55, 0xc9, +0x55, 0x4f, 0xcd, 0x22, 0x1c, 0xbf, 0x9f, 0xf1, 0x94, 0x2f, +0x2b, 0xab, 0xa0, 0xa8, 0x30, 0x74, 0x43, 0x2c, 0xe7, 0x8a, +0x4b, 0x20, 0x0d, 0x22, 0xab, 0x40, 0x78, 0x51, 0xcb, 0x02, +0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x46, 0x30, 0x82, +0x01, 0x42, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, +0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, +0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, +0x06, 0xc0, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, +0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, +0x01, 0x05, 0x05, 0x07, 0x03, 0x08, 0x30, 0x1d, 0x06, 0x03, +0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xca, 0x23, 0xa3, +0x20, 0xb4, 0xb1, 0x6b, 0x72, 0x9f, 0xba, 0x6f, 0x9a, 0x83, +0x3e, 0x0b, 0xc9, 0xd8, 0xb1, 0xd8, 0xa7, 0x30, 0x1f, 0x06, +0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, +0xb4, 0xc6, 0x7f, 0x1a, 0x43, 0xcc, 0x9b, 0x75, 0x5d, 0x2f, +0xc4, 0x4b, 0xf2, 0x8b, 0x98, 0x10, 0xe9, 0xf1, 0x51, 0x10, +0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, +0x01, 0x01, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0x06, 0x08, +0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1e, +0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, +0x70, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, +0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, +0x30, 0x39, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x32, 0x30, +0x30, 0x30, 0x2e, 0xa0, 0x2c, 0xa0, 0x2a, 0x86, 0x28, 0x68, +0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, +0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, +0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, +0x73, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, +0x53, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4c, 0x30, 0x4a, +0x30, 0x48, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, +0x6e, 0x01, 0x07, 0x18, 0x02, 0x30, 0x39, 0x30, 0x37, 0x06, +0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, +0x2b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, +0x65, 0x72, 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, +0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, +0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, +0x6f, 0x72, 0x79, 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, +0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, +0x82, 0x01, 0x01, 0x00, 0x18, 0x53, 0x7e, 0x74, 0xac, 0xa7, +0x7a, 0xa3, 0x2b, 0xea, 0x78, 0x59, 0xd2, 0x3c, 0xc2, 0xf9, +0xc2, 0xf7, 0x25, 0x5f, 0x42, 0x37, 0x5b, 0x3c, 0x11, 0x61, +0x1c, 0xa6, 0x03, 0xff, 0x34, 0x6a, 0x68, 0xbe, 0xda, 0x22, +0xa4, 0x21, 0x5a, 0x48, 0x85, 0x90, 0x55, 0x4d, 0xce, 0xab, +0xa6, 0xcb, 0x34, 0xc6, 0xc0, 0xc6, 0xad, 0xba, 0xb6, 0x80, +0xbe, 0x0b, 0x79, 0xc0, 0xa7, 0xe4, 0xda, 0xa7, 0x1a, 0xe7, +0xcf, 0x57, 0x1e, 0xc8, 0x39, 0xf9, 0xef, 0xdf, 0x30, 0x30, +0xd0, 0xa0, 0x2a, 0xaf, 0x5c, 0x8d, 0x25, 0x53, 0x2d, 0x4c, +0xf7, 0xf5, 0x6d, 0xb4, 0x7b, 0x72, 0xae, 0x52, 0xa3, 0xb7, +0xb9, 0xea, 0x55, 0x83, 0x3e, 0x3a, 0x45, 0x4b, 0x94, 0x1a, +0x96, 0x64, 0x16, 0xd6, 0xe8, 0x60, 0xe3, 0xaf, 0x35, 0x8d, +0x54, 0x25, 0x4c, 0x5b, 0xf8, 0xd6, 0x37, 0xd9, 0x04, 0xab, +0xb8, 0x36, 0xe0, 0x4a, 0x89, 0xfb, 0x0a, 0x69, 0x6f, 0xcc, +0x57, 0xe1, 0xea, 0xdc, 0x22, 0xb2, 0xb5, 0xc5, 0x41, 0x1e, +0xd7, 0x63, 0xe9, 0x9e, 0x64, 0xac, 0xb2, 0xc3, 0xc7, 0xbe, +0xda, 0x77, 0xe0, 0x58, 0x9d, 0x36, 0x01, 0x99, 0xae, 0x86, +0x17, 0x66, 0x38, 0x1d, 0xbd, 0x64, 0xf6, 0xc6, 0x52, 0x5e, +0x10, 0x2f, 0x60, 0xd0, 0xca, 0xcb, 0xc3, 0xc4, 0x72, 0x6f, +0x36, 0x85, 0x44, 0x22, 0x40, 0x9c, 0xc5, 0x41, 0x54, 0x33, +0x23, 0x6c, 0x7b, 0xa3, 0x8e, 0xd9, 0x58, 0x85, 0xf1, 0xaa, +0xb8, 0x34, 0x7e, 0xbb, 0xb5, 0xae, 0x68, 0x54, 0x78, 0x20, +0x0c, 0x52, 0x93, 0x4d, 0xb2, 0x4b, 0x01, 0xf2, 0xc1, 0x88, +0x47, 0x95, 0xcd, 0x6c, 0xd2, 0x53, 0xa8, 0x4c, 0xf0, 0x18, +0x3e, 0x8c, 0x33, 0xa3, 0xc4, 0x8a, 0xcf, 0xce, 0x73, 0x92, +0x49, 0x22, 0x8f, 0xed, 0xbb, 0xc8, 0x9c, 0x7c, 0x63, 0xab, +0x30, 0x82, 0x04, 0x00, 0x30, 0x82, 0x02, 0xe8, 0xa0, 0x03, +0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, +0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, +0x00, 0x30, 0x63, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, +0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1f, +0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x54, 0x68, 0x65, +0x20, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, +0x47, 0x72, 0x6f, 0x75, 0x70, 0x2c, 0x20, 0x49, 0x6e, 0x63, +0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, +0x13, 0x28, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, +0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, +0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, +0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, +0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x36, +0x32, 0x39, 0x31, 0x37, 0x30, 0x36, 0x32, 0x30, 0x5a, 0x17, +0x0d, 0x33, 0x34, 0x30, 0x36, 0x32, 0x39, 0x31, 0x37, 0x30, +0x36, 0x32, 0x30, 0x5a, 0x30, 0x63, 0x31, 0x0b, 0x30, 0x09, +0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, +0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, +0x54, 0x68, 0x65, 0x20, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, +0x64, 0x79, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2c, 0x20, +0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, +0x55, 0x04, 0x0b, 0x13, 0x28, 0x47, 0x6f, 0x20, 0x44, 0x61, +0x64, 0x64, 0x79, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, +0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, +0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, +0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x82, 0x01, 0x20, 0x30, +0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, +0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0d, 0x00, 0x30, +0x82, 0x01, 0x08, 0x02, 0x82, 0x01, 0x01, 0x00, 0xde, 0x9d, +0xd7, 0xea, 0x57, 0x18, 0x49, 0xa1, 0x5b, 0xeb, 0xd7, 0x5f, +0x48, 0x86, 0xea, 0xbe, 0xdd, 0xff, 0xe4, 0xef, 0x67, 0x1c, +0xf4, 0x65, 0x68, 0xb3, 0x57, 0x71, 0xa0, 0x5e, 0x77, 0xbb, +0xed, 0x9b, 0x49, 0xe9, 0x70, 0x80, 0x3d, 0x56, 0x18, 0x63, +0x08, 0x6f, 0xda, 0xf2, 0xcc, 0xd0, 0x3f, 0x7f, 0x02, 0x54, +0x22, 0x54, 0x10, 0xd8, 0xb2, 0x81, 0xd4, 0xc0, 0x75, 0x3d, +0x4b, 0x7f, 0xc7, 0x77, 0xc3, 0x3e, 0x78, 0xab, 0x1a, 0x03, +0xb5, 0x20, 0x6b, 0x2f, 0x6a, 0x2b, 0xb1, 0xc5, 0x88, 0x7e, +0xc4, 0xbb, 0x1e, 0xb0, 0xc1, 0xd8, 0x45, 0x27, 0x6f, 0xaa, +0x37, 0x58, 0xf7, 0x87, 0x26, 0xd7, 0xd8, 0x2d, 0xf6, 0xa9, +0x17, 0xb7, 0x1f, 0x72, 0x36, 0x4e, 0xa6, 0x17, 0x3f, 0x65, +0x98, 0x92, 0xdb, 0x2a, 0x6e, 0x5d, 0xa2, 0xfe, 0x88, 0xe0, +0x0b, 0xde, 0x7f, 0xe5, 0x8d, 0x15, 0xe1, 0xeb, 0xcb, 0x3a, +0xd5, 0xe2, 0x12, 0xa2, 0x13, 0x2d, 0xd8, 0x8e, 0xaf, 0x5f, +0x12, 0x3d, 0xa0, 0x08, 0x05, 0x08, 0xb6, 0x5c, 0xa5, 0x65, +0x38, 0x04, 0x45, 0x99, 0x1e, 0xa3, 0x60, 0x60, 0x74, 0xc5, +0x41, 0xa5, 0x72, 0x62, 0x1b, 0x62, 0xc5, 0x1f, 0x6f, 0x5f, +0x1a, 0x42, 0xbe, 0x02, 0x51, 0x65, 0xa8, 0xae, 0x23, 0x18, +0x6a, 0xfc, 0x78, 0x03, 0xa9, 0x4d, 0x7f, 0x80, 0xc3, 0xfa, +0xab, 0x5a, 0xfc, 0xa1, 0x40, 0xa4, 0xca, 0x19, 0x16, 0xfe, +0xb2, 0xc8, 0xef, 0x5e, 0x73, 0x0d, 0xee, 0x77, 0xbd, 0x9a, +0xf6, 0x79, 0x98, 0xbc, 0xb1, 0x07, 0x67, 0xa2, 0x15, 0x0d, +0xdd, 0xa0, 0x58, 0xc6, 0x44, 0x7b, 0x0a, 0x3e, 0x62, 0x28, +0x5f, 0xba, 0x41, 0x07, 0x53, 0x58, 0xcf, 0x11, 0x7e, 0x38, +0x74, 0xc5, 0xf8, 0xff, 0xb5, 0x69, 0x90, 0x8f, 0x84, 0x74, +0xea, 0x97, 0x1b, 0xaf, 0x02, 0x01, 0x03, 0xa3, 0x81, 0xc0, +0x30, 0x81, 0xbd, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, +0x04, 0x16, 0x04, 0x14, 0xd2, 0xc4, 0xb0, 0xd2, 0x91, 0xd4, +0x4c, 0x11, 0x71, 0xb3, 0x61, 0xcb, 0x3d, 0xa1, 0xfe, 0xdd, +0xa8, 0x6a, 0xd4, 0xe3, 0x30, 0x81, 0x8d, 0x06, 0x03, 0x55, +0x1d, 0x23, 0x04, 0x81, 0x85, 0x30, 0x81, 0x82, 0x80, 0x14, +0xd2, 0xc4, 0xb0, 0xd2, 0x91, 0xd4, 0x4c, 0x11, 0x71, 0xb3, +0x61, 0xcb, 0x3d, 0xa1, 0xfe, 0xdd, 0xa8, 0x6a, 0xd4, 0xe3, +0xa1, 0x67, 0xa4, 0x65, 0x30, 0x63, 0x31, 0x0b, 0x30, 0x09, +0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, +0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, +0x54, 0x68, 0x65, 0x20, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, +0x64, 0x79, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2c, 0x20, +0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, +0x55, 0x04, 0x0b, 0x13, 0x28, 0x47, 0x6f, 0x20, 0x44, 0x61, +0x64, 0x64, 0x79, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, +0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, +0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, +0x6f, 0x72, 0x69, 0x74, 0x79, 0x82, 0x01, 0x00, 0x30, 0x0c, +0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, +0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, +0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, +0x01, 0x00, 0x32, 0x4b, 0xf3, 0xb2, 0xca, 0x3e, 0x91, 0xfc, +0x12, 0xc6, 0xa1, 0x07, 0x8c, 0x8e, 0x77, 0xa0, 0x33, 0x06, +0x14, 0x5c, 0x90, 0x1e, 0x18, 0xf7, 0x08, 0xa6, 0x3d, 0x0a, +0x19, 0xf9, 0x87, 0x80, 0x11, 0x6e, 0x69, 0xe4, 0x96, 0x17, +0x30, 0xff, 0x34, 0x91, 0x63, 0x72, 0x38, 0xee, 0xcc, 0x1c, +0x01, 0xa3, 0x1d, 0x94, 0x28, 0xa4, 0x31, 0xf6, 0x7a, 0xc4, +0x54, 0xd7, 0xf6, 0xe5, 0x31, 0x58, 0x03, 0xa2, 0xcc, 0xce, +0x62, 0xdb, 0x94, 0x45, 0x73, 0xb5, 0xbf, 0x45, 0xc9, 0x24, +0xb5, 0xd5, 0x82, 0x02, 0xad, 0x23, 0x79, 0x69, 0x8d, 0xb8, +0xb6, 0x4d, 0xce, 0xcf, 0x4c, 0xca, 0x33, 0x23, 0xe8, 0x1c, +0x88, 0xaa, 0x9d, 0x8b, 0x41, 0x6e, 0x16, 0xc9, 0x20, 0xe5, +0x89, 0x9e, 0xcd, 0x3b, 0xda, 0x70, 0xf7, 0x7e, 0x99, 0x26, +0x20, 0x14, 0x54, 0x25, 0xab, 0x6e, 0x73, 0x85, 0xe6, 0x9b, +0x21, 0x9d, 0x0a, 0x6c, 0x82, 0x0e, 0xa8, 0xf8, 0xc2, 0x0c, +0xfa, 0x10, 0x1e, 0x6c, 0x96, 0xef, 0x87, 0x0d, 0xc4, 0x0f, +0x61, 0x8b, 0xad, 0xee, 0x83, 0x2b, 0x95, 0xf8, 0x8e, 0x92, +0x84, 0x72, 0x39, 0xeb, 0x20, 0xea, 0x83, 0xed, 0x83, 0xcd, +0x97, 0x6e, 0x08, 0xbc, 0xeb, 0x4e, 0x26, 0xb6, 0x73, 0x2b, +0xe4, 0xd3, 0xf6, 0x4c, 0xfe, 0x26, 0x71, 0xe2, 0x61, 0x11, +0x74, 0x4a, 0xff, 0x57, 0x1a, 0x87, 0x0f, 0x75, 0x48, 0x2e, +0xcf, 0x51, 0x69, 0x17, 0xa0, 0x02, 0x12, 0x61, 0x95, 0xd5, +0xd1, 0x40, 0xb2, 0x10, 0x4c, 0xee, 0xc4, 0xac, 0x10, 0x43, +0xa6, 0xa5, 0x9e, 0x0a, 0xd5, 0x95, 0x62, 0x9a, 0x0d, 0xcf, +0x88, 0x82, 0xc5, 0x32, 0x0c, 0xe4, 0x2b, 0x9f, 0x45, 0xe6, +0x0d, 0x9f, 0x28, 0x9c, 0xb1, 0xb9, 0x2a, 0x5a, 0x57, 0xad, +0x37, 0x0f, 0xaf, 0x1d, 0x7f, 0xdb, 0xbd, 0x9f, 0x30, 0x82, +0x04, 0xde, 0x30, 0x82, 0x03, 0xc6, 0xa0, 0x03, 0x02, 0x01, +0x02, 0x02, 0x02, 0x03, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, +0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, +0x30, 0x63, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, +0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1f, 0x06, +0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x54, 0x68, 0x65, 0x20, +0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x47, +0x72, 0x6f, 0x75, 0x70, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, +0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, +0x28, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, +0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, +0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, +0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, +0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x31, +0x36, 0x30, 0x31, 0x35, 0x34, 0x33, 0x37, 0x5a, 0x17, 0x0d, +0x32, 0x36, 0x31, 0x31, 0x31, 0x36, 0x30, 0x31, 0x35, 0x34, +0x33, 0x37, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b, 0x30, 0x09, +0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, +0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, +0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, +0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, +0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, +0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x47, +0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, +0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31, +0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, 0x74, 0x74, +0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, +0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, +0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, +0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x31, +0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x27, +0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53, +0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, +0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, +0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, +0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x08, +0x30, 0x37, 0x39, 0x36, 0x39, 0x32, 0x38, 0x37, 0x30, 0x82, +0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, +0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, +0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, +0x00, 0xc4, 0x2d, 0xd5, 0x15, 0x8c, 0x9c, 0x26, 0x4c, 0xec, +0x32, 0x35, 0xeb, 0x5f, 0xb8, 0x59, 0x01, 0x5a, 0xa6, 0x61, +0x81, 0x59, 0x3b, 0x70, 0x63, 0xab, 0xe3, 0xdc, 0x3d, 0xc7, +0x2a, 0xb8, 0xc9, 0x33, 0xd3, 0x79, 0xe4, 0x3a, 0xed, 0x3c, +0x30, 0x23, 0x84, 0x8e, 0xb3, 0x30, 0x14, 0xb6, 0xb2, 0x87, +0xc3, 0x3d, 0x95, 0x54, 0x04, 0x9e, 0xdf, 0x99, 0xdd, 0x0b, +0x25, 0x1e, 0x21, 0xde, 0x65, 0x29, 0x7e, 0x35, 0xa8, 0xa9, +0x54, 0xeb, 0xf6, 0xf7, 0x32, 0x39, 0xd4, 0x26, 0x55, 0x95, +0xad, 0xef, 0xfb, 0xfe, 0x58, 0x86, 0xd7, 0x9e, 0xf4, 0x00, +0x8d, 0x8c, 0x2a, 0x0c, 0xbd, 0x42, 0x04, 0xce, 0xa7, 0x3f, +0x04, 0xf6, 0xee, 0x80, 0xf2, 0xaa, 0xef, 0x52, 0xa1, 0x69, +0x66, 0xda, 0xbe, 0x1a, 0xad, 0x5d, 0xda, 0x2c, 0x66, 0xea, +0x1a, 0x6b, 0xbb, 0xe5, 0x1a, 0x51, 0x4a, 0x00, 0x2f, 0x48, +0xc7, 0x98, 0x75, 0xd8, 0xb9, 0x29, 0xc8, 0xee, 0xf8, 0x66, +0x6d, 0x0a, 0x9c, 0xb3, 0xf3, 0xfc, 0x78, 0x7c, 0xa2, 0xf8, +0xa3, 0xf2, 0xb5, 0xc3, 0xf3, 0xb9, 0x7a, 0x91, 0xc1, 0xa7, +0xe6, 0x25, 0x2e, 0x9c, 0xa8, 0xed, 0x12, 0x65, 0x6e, 0x6a, +0xf6, 0x12, 0x44, 0x53, 0x70, 0x30, 0x95, 0xc3, 0x9c, 0x2b, +0x58, 0x2b, 0x3d, 0x08, 0x74, 0x4a, 0xf2, 0xbe, 0x51, 0xb0, +0xbf, 0x87, 0xd0, 0x4c, 0x27, 0x58, 0x6b, 0xb5, 0x35, 0xc5, +0x9d, 0xaf, 0x17, 0x31, 0xf8, 0x0b, 0x8f, 0xee, 0xad, 0x81, +0x36, 0x05, 0x89, 0x08, 0x98, 0xcf, 0x3a, 0xaf, 0x25, 0x87, +0xc0, 0x49, 0xea, 0xa7, 0xfd, 0x67, 0xf7, 0x45, 0x8e, 0x97, +0xcc, 0x14, 0x39, 0xe2, 0x36, 0x85, 0xb5, 0x7e, 0x1a, 0x37, +0xfd, 0x16, 0xf6, 0x71, 0x11, 0x9a, 0x74, 0x30, 0x16, 0xfe, +0x13, 0x94, 0xa3, 0x3f, 0x84, 0x0d, 0x4f, 0x02, 0x03, 0x01, +0x00, 0x01, 0xa3, 0x82, 0x01, 0x32, 0x30, 0x82, 0x01, 0x2e, +0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, +0x14, 0xfd, 0xac, 0x61, 0x32, 0x93, 0x6c, 0x45, 0xd6, 0xe2, +0xee, 0x85, 0x5f, 0x9a, 0xba, 0xe7, 0x76, 0x99, 0x68, 0xcc, +0xe7, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, +0x30, 0x16, 0x80, 0x14, 0xd2, 0xc4, 0xb0, 0xd2, 0x91, 0xd4, +0x4c, 0x11, 0x71, 0xb3, 0x61, 0xcb, 0x3d, 0xa1, 0xfe, 0xdd, +0xa8, 0x6a, 0xd4, 0xe3, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, +0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, +0xff, 0x02, 0x01, 0x00, 0x30, 0x33, 0x06, 0x08, 0x2b, 0x06, +0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25, +0x30, 0x23, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, +0x30, 0x01, 0x86, 0x17, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, +0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, 0x61, +0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x46, 0x06, +0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, +0xa0, 0x39, 0xa0, 0x37, 0x86, 0x35, 0x68, 0x74, 0x74, 0x70, +0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, +0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, +0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, +0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, +0x64, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, +0x4b, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x44, 0x30, 0x42, +0x30, 0x40, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x38, +0x30, 0x36, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, +0x02, 0x01, 0x16, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, +0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, +0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, +0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, +0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x30, 0x0e, 0x06, 0x03, +0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, +0x01, 0x06, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, +0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, +0x01, 0x00, 0xd2, 0x86, 0xc0, 0xec, 0xbd, 0xf9, 0xa1, 0xb6, +0x67, 0xee, 0x66, 0x0b, 0xa2, 0x06, 0x3a, 0x04, 0x50, 0x8e, +0x15, 0x72, 0xac, 0x4a, 0x74, 0x95, 0x53, 0xcb, 0x37, 0xcb, +0x44, 0x49, 0xef, 0x07, 0x90, 0x6b, 0x33, 0xd9, 0x96, 0xf0, +0x94, 0x56, 0xa5, 0x13, 0x30, 0x05, 0x3c, 0x85, 0x32, 0x21, +0x7b, 0xc9, 0xc7, 0x0a, 0xa8, 0x24, 0xa4, 0x90, 0xde, 0x46, +0xd3, 0x25, 0x23, 0x14, 0x03, 0x67, 0xc2, 0x10, 0xd6, 0x6f, +0x0f, 0x5d, 0x7b, 0x7a, 0xcc, 0x9f, 0xc5, 0x58, 0x2a, 0xc1, +0xc4, 0x9e, 0x21, 0xa8, 0x5a, 0xf3, 0xac, 0xa4, 0x46, 0xf3, +0x9e, 0xe4, 0x63, 0xcb, 0x2f, 0x90, 0xa4, 0x29, 0x29, 0x01, +0xd9, 0x72, 0x2c, 0x29, 0xdf, 0x37, 0x01, 0x27, 0xbc, 0x4f, +0xee, 0x68, 0xd3, 0x21, 0x8f, 0xc0, 0xb3, 0xe4, 0xf5, 0x09, +0xed, 0xd2, 0x10, 0xaa, 0x53, 0xb4, 0xbe, 0xf0, 0xcc, 0x59, +0x0b, 0xd6, 0x3b, 0x96, 0x1c, 0x95, 0x24, 0x49, 0xdf, 0xce, +0xec, 0xfd, 0xa7, 0x48, 0x91, 0x14, 0x45, 0x0e, 0x3a, 0x36, +0x6f, 0xda, 0x45, 0xb3, 0x45, 0xa2, 0x41, 0xc9, 0xd4, 0xd7, +0x44, 0x4e, 0x3e, 0xb9, 0x74, 0x76, 0xd5, 0xa2, 0x13, 0x55, +0x2c, 0xc6, 0x87, 0xa3, 0xb5, 0x99, 0xac, 0x06, 0x84, 0x87, +0x7f, 0x75, 0x06, 0xfc, 0xbf, 0x14, 0x4c, 0x0e, 0xcc, 0x6e, +0xc4, 0xdf, 0x3d, 0xb7, 0x12, 0x71, 0xf4, 0xe8, 0xf1, 0x51, +0x40, 0x22, 0x28, 0x49, 0xe0, 0x1d, 0x4b, 0x87, 0xa8, 0x34, +0xcc, 0x06, 0xa2, 0xdd, 0x12, 0x5a, 0xd1, 0x86, 0x36, 0x64, +0x03, 0x35, 0x6f, 0x6f, 0x77, 0x6e, 0xeb, 0xf2, 0x85, 0x50, +0x98, 0x5e, 0xab, 0x03, 0x53, 0xad, 0x91, 0x23, 0x63, 0x1f, +0x16, 0x9c, 0xcd, 0xb9, 0xb2, 0x05, 0x63, 0x3a, 0xe1, 0xf4, +0x68, 0x1b, 0x17, 0x05, 0x35, 0x95, 0x53, 0xee, 0x30, 0x82, +0x05, 0x3e, 0x30, 0x82, 0x04, 0x26, 0xa0, 0x03, 0x02, 0x01, +0x02, 0x02, 0x06, 0x0b, 0xef, 0xf4, 0xbf, 0x69, 0x7b, 0x30, +0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, +0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0xca, 0x31, 0x0b, 0x30, +0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, +0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, +0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, +0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, +0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, +0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, +0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, +0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, +0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, 0x74, +0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, +0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, +0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, +0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, +0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, +0x27, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, +0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, +0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, +0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, +0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, +0x08, 0x30, 0x37, 0x39, 0x36, 0x39, 0x32, 0x38, 0x37, 0x30, +0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x39, 0x32, 0x34, 0x31, +0x33, 0x34, 0x34, 0x32, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x32, +0x30, 0x39, 0x32, 0x34, 0x31, 0x33, 0x34, 0x34, 0x32, 0x33, +0x5a, 0x30, 0x6b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, +0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x0f, 0x30, 0x0d, +0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x06, 0x4c, 0x6f, 0x6e, +0x64, 0x6f, 0x6e, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, +0x04, 0x07, 0x13, 0x06, 0x4c, 0x6f, 0x6e, 0x64, 0x6f, 0x6e, +0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, +0x13, 0x44, 0x61, 0x6c, 0x74, 0x6f, 0x6e, 0x20, 0x4d, 0x61, +0x61, 0x67, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, +0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, +0x13, 0x44, 0x61, 0x6c, 0x74, 0x6f, 0x6e, 0x20, 0x4d, 0x61, +0x61, 0x67, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, +0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, +0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, +0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, +0x01, 0x01, 0x00, 0xa2, 0x04, 0x5f, 0xe6, 0xd8, 0xdb, 0xd2, +0xa1, 0xa2, 0xf3, 0x7e, 0xc5, 0x34, 0xe7, 0x72, 0xd8, 0xae, +0xfb, 0x95, 0xcf, 0xec, 0xa4, 0xea, 0x0e, 0x1d, 0x00, 0x07, +0x92, 0xdb, 0x16, 0xf6, 0xac, 0x53, 0x1f, 0x35, 0xf1, 0x94, +0x01, 0x9c, 0xa3, 0x8e, 0x90, 0x99, 0x08, 0x46, 0xe0, 0x05, +0x0f, 0x2b, 0x91, 0xb6, 0xa6, 0xff, 0x0b, 0x1b, 0x0c, 0xba, +0x2b, 0x46, 0x6e, 0x62, 0xe6, 0x89, 0xa7, 0x0b, 0x41, 0xf5, +0x14, 0xe6, 0xc0, 0xea, 0x6b, 0x55, 0x72, 0x11, 0x5d, 0x8e, +0xcf, 0xdc, 0x58, 0x33, 0x89, 0xff, 0xe5, 0x90, 0x75, 0xdc, +0xc3, 0xcc, 0x2d, 0x60, 0x3e, 0xd6, 0x03, 0xe9, 0xa9, 0xc6, +0x54, 0x3e, 0x94, 0xbc, 0xec, 0x8a, 0x91, 0x36, 0x7a, 0xed, +0x55, 0xfd, 0xd8, 0x3d, 0x6b, 0x27, 0x46, 0x09, 0x5f, 0xd4, +0xdb, 0xc1, 0x5f, 0xa2, 0xf7, 0x88, 0xe4, 0x88, 0x7e, 0xfa, +0xe3, 0x82, 0xe0, 0x2f, 0x42, 0x62, 0x51, 0x46, 0xbb, 0xc6, +0x30, 0x71, 0x7b, 0xb2, 0xcc, 0x8c, 0x33, 0x76, 0xed, 0xe0, +0xb5, 0x99, 0xad, 0xc3, 0x1d, 0x0d, 0xe3, 0x88, 0x77, 0x78, +0x31, 0x3c, 0x54, 0x52, 0x15, 0x6c, 0xde, 0xdc, 0xcc, 0x70, +0x97, 0x1c, 0x9b, 0x85, 0xf4, 0x38, 0xf7, 0x05, 0x47, 0x4b, +0x27, 0xb0, 0x5d, 0xa3, 0x3c, 0x66, 0x22, 0xa5, 0x28, 0x97, +0x0a, 0x76, 0x94, 0x67, 0xc1, 0xbb, 0x8f, 0x9f, 0x1a, 0xf0, +0x06, 0x7c, 0x80, 0x91, 0x58, 0x1a, 0x75, 0x20, 0x20, 0x06, +0x94, 0x5a, 0x0b, 0x71, 0xef, 0x26, 0xed, 0xf2, 0x5e, 0x82, +0xd3, 0x9a, 0x0b, 0xe6, 0x93, 0xb7, 0x07, 0x16, 0x41, 0xea, +0x62, 0xd5, 0xd4, 0xd2, 0x8c, 0x93, 0xaa, 0xf8, 0xc1, 0x34, +0xd7, 0x8a, 0xfb, 0x8d, 0x45, 0x4c, 0x6e, 0x6f, 0x8c, 0x7c, +0xaf, 0x01, 0x8d, 0x66, 0xf4, 0x31, 0xeb, 0xae, 0x1d, 0x02, +0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x86, 0x30, 0x82, +0x01, 0x82, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, +0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0x00, 0x30, +0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, +0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, +0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, +0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x32, 0x06, 0x03, +0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, +0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, +0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x6f, 0x64, 0x61, +0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x64, +0x73, 0x32, 0x2d, 0x30, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x53, +0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4c, 0x30, 0x4a, 0x30, +0x48, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, 0x6d, +0x01, 0x07, 0x17, 0x02, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, +0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2b, +0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, +0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, +0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, +0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, +0x72, 0x79, 0x2f, 0x30, 0x81, 0x80, 0x06, 0x08, 0x2b, 0x06, +0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x74, 0x30, 0x72, +0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, +0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, +0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, 0x61, +0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x4a, +0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, +0x86, 0x3e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, +0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, +0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, +0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, +0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x64, 0x5f, 0x69, 0x6e, +0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, +0x2e, 0x63, 0x72, 0x74, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, +0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xfd, 0xac, 0x61, +0x32, 0x93, 0x6c, 0x45, 0xd6, 0xe2, 0xee, 0x85, 0x5f, 0x9a, +0xba, 0xe7, 0x76, 0x99, 0x68, 0xcc, 0xe7, 0x30, 0x1d, 0x06, +0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x68, 0x66, +0x30, 0x10, 0x67, 0x55, 0xa1, 0xb3, 0xa1, 0xe9, 0x37, 0xc6, +0x75, 0x11, 0x89, 0x33, 0xe3, 0x85, 0xd7, 0x13, 0x30, 0x0d, +0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, +0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xbd, 0x56, +0x3e, 0x09, 0xb4, 0x13, 0x7d, 0xfa, 0xed, 0xd3, 0xfe, 0x45, +0xb6, 0xdf, 0xdf, 0x19, 0x48, 0xf8, 0xa3, 0x8c, 0xd5, 0x11, +0x54, 0x8f, 0xd4, 0x92, 0x44, 0x13, 0xc1, 0x71, 0x69, 0xa3, +0xc3, 0x30, 0x06, 0x80, 0x1d, 0xda, 0x37, 0xae, 0xca, 0x47, +0x68, 0xd9, 0xb3, 0x25, 0x09, 0x36, 0x0c, 0xe9, 0x04, 0x3b, +0xe2, 0xdb, 0x51, 0x10, 0x74, 0xfe, 0x10, 0x5e, 0xc9, 0xde, +0x3b, 0x0f, 0x24, 0x03, 0xb1, 0x9e, 0x39, 0x96, 0xc3, 0xa0, +0x0f, 0x4c, 0x52, 0xca, 0xe7, 0x42, 0x66, 0x11, 0x5a, 0x75, +0x68, 0x49, 0x3a, 0x2d, 0x23, 0x6b, 0x5e, 0x06, 0xc4, 0x43, +0xf1, 0x9e, 0x01, 0xb1, 0x2f, 0x0b, 0xa5, 0x9c, 0x12, 0x1e, +0x3e, 0x3d, 0x18, 0x6e, 0x5a, 0xb0, 0x95, 0x74, 0x3f, 0x2e, +0x4b, 0xe1, 0x30, 0x6d, 0x73, 0xc3, 0x9e, 0x6f, 0xaf, 0xe3, +0x0f, 0x47, 0xfa, 0xdd, 0x24, 0x60, 0x64, 0xa7, 0x5c, 0x63, +0x00, 0xdd, 0xa9, 0xb7, 0x50, 0x34, 0x65, 0xc7, 0x28, 0x05, +0x49, 0xfe, 0x5a, 0x7a, 0x18, 0xea, 0x1c, 0xc0, 0x46, 0xb6, +0x9a, 0x2a, 0xd9, 0x81, 0x65, 0xb2, 0x91, 0xca, 0x0c, 0xd6, +0x7b, 0x88, 0xf0, 0xea, 0x3e, 0xe9, 0x18, 0x55, 0x30, 0x87, +0xcf, 0xaf, 0x91, 0xa8, 0x1e, 0x23, 0x08, 0x6b, 0x45, 0x90, +0x99, 0x06, 0xdc, 0x91, 0x37, 0x0d, 0xbf, 0xd4, 0xdd, 0x66, +0x5f, 0x55, 0x00, 0xf4, 0xf1, 0xe3, 0xed, 0x60, 0x34, 0x95, +0x3e, 0x97, 0xa2, 0xc2, 0xca, 0x6a, 0x8d, 0x61, 0x40, 0x30, +0x91, 0xc4, 0xa5, 0x01, 0x06, 0x5b, 0xd0, 0x60, 0x6d, 0x4f, +0x34, 0x1f, 0x7e, 0x9d, 0x09, 0x31, 0x53, 0xe5, 0xe9, 0x78, +0x96, 0xd0, 0x83, 0xc4, 0xaa, 0xbd, 0xe5, 0x62, 0xaa, 0x32, +0x1c, 0x22, 0x23, 0x4e, 0x12, 0x2e, 0x7c, 0x08, 0xb6, 0x9f, +0xdf, 0x5c, 0x23, 0x96, 0x31, 0x82, 0x04, 0xfe, 0x30, 0x82, +0x04, 0xfa, 0x02, 0x01, 0x01, 0x30, 0x81, 0xd5, 0x30, 0x81, +0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, +0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, +0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, +0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, +0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, +0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, +0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, +0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, +0x2e, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, +0x13, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, +0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, +0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, +0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, +0x74, 0x6f, 0x72, 0x79, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, +0x55, 0x04, 0x03, 0x13, 0x27, 0x47, 0x6f, 0x20, 0x44, 0x61, +0x64, 0x64, 0x79, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, +0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, +0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, +0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, +0x55, 0x04, 0x05, 0x13, 0x08, 0x30, 0x37, 0x39, 0x36, 0x39, +0x32, 0x38, 0x37, 0x02, 0x06, 0x0b, 0xef, 0xf4, 0xbf, 0x69, +0x7b, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, +0x05, 0x00, 0xa0, 0x81, 0x86, 0x30, 0x10, 0x06, 0x0a, 0x2b, +0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x0c, 0x31, +0x02, 0x30, 0x00, 0x30, 0x14, 0x06, 0x09, 0x2b, 0x06, 0x01, +0x04, 0x01, 0x82, 0x37, 0x28, 0x01, 0x31, 0x07, 0x03, 0x05, +0x00, 0x03, 0x00, 0x00, 0x00, 0x30, 0x19, 0x06, 0x09, 0x2a, +0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0c, +0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, +0x01, 0x04, 0x30, 0x1c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, +0x01, 0x82, 0x37, 0x02, 0x01, 0x0b, 0x31, 0x0e, 0x30, 0x0c, +0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, +0x01, 0x15, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, +0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16, 0x04, 0x14, 0x49, +0xbc, 0x7b, 0x59, 0x20, 0xf3, 0xe8, 0x1e, 0x10, 0xd4, 0xf7, +0xd9, 0x16, 0x41, 0x17, 0x0b, 0xcd, 0x6f, 0x48, 0x6a, 0x30, +0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, +0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x5a, 0xc1, +0x1a, 0x27, 0xe6, 0x62, 0x7c, 0x20, 0x75, 0x37, 0x81, 0xf2, +0x3a, 0x5b, 0x3f, 0x96, 0x43, 0x80, 0x2b, 0x3b, 0xd1, 0x63, +0xba, 0xa4, 0x48, 0x5d, 0xd4, 0x56, 0x4c, 0x4d, 0x24, 0x6b, +0x9a, 0xa7, 0x31, 0x76, 0x0a, 0xd4, 0xbc, 0x21, 0x6f, 0x80, +0xb2, 0xf2, 0xbd, 0x6d, 0x41, 0x66, 0xf9, 0xfa, 0xa0, 0x4f, +0xcd, 0x46, 0x4b, 0x75, 0xa8, 0x04, 0xe7, 0xef, 0xe5, 0xfc, +0xa3, 0x9d, 0x4f, 0xfe, 0x82, 0x33, 0xbe, 0xbc, 0x57, 0x9c, +0x43, 0x41, 0x6e, 0x2c, 0x50, 0xbc, 0x23, 0xf2, 0xd1, 0xdc, +0x17, 0xb8, 0xad, 0x2b, 0xa4, 0x55, 0x02, 0x20, 0xfd, 0x2e, +0xd1, 0x20, 0x7d, 0xfa, 0x4c, 0xf5, 0x6c, 0xd0, 0xa5, 0xd2, +0xc8, 0xaa, 0xc6, 0x29, 0xd1, 0x33, 0x46, 0x52, 0x94, 0xde, +0x1f, 0x27, 0xae, 0xf9, 0xc6, 0x06, 0xe6, 0x0b, 0xdf, 0xc4, +0xfc, 0x2d, 0x41, 0xea, 0x8a, 0xde, 0xb5, 0xab, 0xb7, 0xb7, +0xbe, 0xfd, 0x9e, 0xe0, 0xdb, 0x04, 0x28, 0x6c, 0xd7, 0xd9, +0x1f, 0xb8, 0x9c, 0xb2, 0xad, 0x31, 0xa8, 0xdd, 0xb1, 0x03, +0x72, 0x30, 0xb7, 0xf2, 0x5e, 0xa2, 0x97, 0x25, 0x68, 0xef, +0xf6, 0x61, 0xeb, 0x72, 0xe1, 0xc3, 0x98, 0x44, 0x62, 0x72, +0x93, 0xe9, 0xf2, 0x1a, 0x17, 0x89, 0x5e, 0x42, 0x1f, 0x2c, +0x3d, 0x27, 0xd4, 0x4b, 0x5b, 0x43, 0x26, 0x30, 0x9a, 0x9c, +0x40, 0xba, 0xc2, 0x45, 0x9b, 0x8f, 0xcf, 0x00, 0x33, 0x6b, +0x68, 0xb9, 0x40, 0xd2, 0x0f, 0xff, 0x82, 0xf0, 0x61, 0xe2, +0xc2, 0x81, 0xdf, 0x52, 0x98, 0x34, 0xf9, 0xf2, 0x8d, 0x09, +0x2f, 0xef, 0x96, 0x8b, 0xae, 0x04, 0x66, 0x32, 0x5c, 0xd8, +0x05, 0xaa, 0xf4, 0x92, 0x53, 0xe6, 0xce, 0xe3, 0xbc, 0xcf, +0xbc, 0xaa, 0x8e, 0x1d, 0x15, 0xbc, 0x1e, 0x8f, 0x03, 0x56, +0x55, 0x85, 0x4c, 0x6e, 0xa1, 0x82, 0x02, 0x74, 0x30, 0x82, +0x02, 0x70, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, +0x01, 0x09, 0x06, 0x31, 0x82, 0x02, 0x61, 0x30, 0x82, 0x02, +0x5d, 0x02, 0x01, 0x01, 0x30, 0x81, 0xd6, 0x30, 0x81, 0xcf, +0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, +0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, +0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, +0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, +0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, +0x6c, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, +0x0a, 0x13, 0x1c, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, +0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, +0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, +0x2e, 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, +0x13, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, +0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, +0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, +0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, +0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, +0x2f, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, +0x13, 0x2d, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, +0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, +0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, +0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, +0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x02, 0x02, 0x20, +0x05, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, +0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0xa0, 0x5d, 0x30, 0x18, +0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, +0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, +0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, +0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, +0x0d, 0x31, 0x31, 0x30, 0x39, 0x32, 0x32, 0x31, 0x35, 0x34, +0x30, 0x34, 0x33, 0x5a, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, +0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x16, 0x04, +0x14, 0x97, 0x38, 0x26, 0xe8, 0x00, 0xf7, 0x04, 0xfe, 0xb2, +0x23, 0xcb, 0x7f, 0xd1, 0xa4, 0x5d, 0x48, 0xd8, 0x2d, 0x39, +0x34, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, +0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, +0xc8, 0xf5, 0x91, 0xe0, 0xf2, 0x90, 0x31, 0xcc, 0x84, 0x86, +0xb2, 0x50, 0x66, 0x89, 0x15, 0xa7, 0x76, 0x05, 0x4c, 0xa2, +0x3d, 0x52, 0x80, 0x39, 0xd2, 0x70, 0x56, 0x88, 0x33, 0x1d, +0x89, 0x43, 0xc4, 0xe7, 0x86, 0x8c, 0x7b, 0x1b, 0xc2, 0x44, +0xb3, 0x71, 0xbf, 0x44, 0x0a, 0x8c, 0xba, 0xb1, 0x67, 0xcd, +0xc2, 0xdc, 0xe8, 0x26, 0xa8, 0x69, 0x99, 0x42, 0x43, 0x46, +0x93, 0x48, 0x61, 0x9d, 0x0c, 0x56, 0x76, 0xa1, 0xaf, 0x30, +0xcd, 0x4c, 0x13, 0xfd, 0x34, 0x74, 0x6d, 0xa5, 0xaf, 0x5b, +0x3c, 0x7a, 0x77, 0xf8, 0x96, 0x7c, 0x3e, 0xf8, 0xce, 0xcf, +0x89, 0x52, 0x50, 0x62, 0x3b, 0x42, 0xce, 0xa1, 0x76, 0xf3, +0xa0, 0x15, 0x18, 0x24, 0xac, 0x01, 0x97, 0x89, 0x86, 0x4c, +0xe3, 0xea, 0xc2, 0x91, 0x24, 0xa9, 0x11, 0x2a, 0x51, 0xad, +0x01, 0xe0, 0xda, 0x76, 0x6b, 0xb7, 0xba, 0xb2, 0xe1, 0x45, +0xc6, 0x3c, 0xeb, 0xc5, 0x6c, 0x6d, 0x15, 0x65, 0x92, 0x80, +0xb4, 0xbe, 0x1f, 0x70, 0xf6, 0x0a, 0xb7, 0x13, 0x02, 0x5f, +0x7d, 0x2b, 0x6c, 0xcc, 0x0c, 0x86, 0x0e, 0x38, 0xc1, 0xf6, +0x1f, 0x45, 0xe1, 0xb8, 0x17, 0x3a, 0x9a, 0xf8, 0x6f, 0xd3, +0xee, 0x56, 0x9d, 0x93, 0xd5, 0x0b, 0xa6, 0x01, 0xee, 0x8a, +0x92, 0x83, 0xfd, 0x00, 0x33, 0xce, 0x4b, 0x1a, 0x85, 0x33, +0xe6, 0xc0, 0xd3, 0xd0, 0x88, 0xb1, 0x77, 0xb9, 0x98, 0xc2, +0xc6, 0x30, 0xb1, 0x86, 0xeb, 0x5a, 0x92, 0xe8, 0x98, 0x02, +0x4a, 0x1a, 0x0b, 0xc3, 0x41, 0x94, 0x45, 0x5c, 0x86, 0x71, +0xf2, 0x58, 0x02, 0xd8, 0x46, 0xff, 0x7f, 0xbd, 0x31, 0x00, +0x23, 0xb1, 0x19, 0x64, 0x69, 0x21, 0xe8, 0xce, 0xba, 0x6e, +0xa5, 0x71, 0x92, 0x6b, 0x61, 0xd0, 0x1c, 0x0c, 0xe5, 0xce, +0x68, 0x37, 0x14, 0x4e, 0x59, 0xd1, 0x00, 0x00, +}; +const size_t ubuntu_mono_ttf_len = sizeof(ubuntu_mono_ttf); + diff --git a/CameraParameterEstimation/apps/basics/window/ui.h b/CameraParameterEstimation/apps/basics/window/ui.h new file mode 100644 index 0000000..654f27e --- /dev/null +++ b/CameraParameterEstimation/apps/basics/window/ui.h @@ -0,0 +1,1144 @@ +// ui.h + +// TODO: compile time string hashing +// TODO: implement progress bar +// TODO: add game controler support? +// TODO: add modifiers to mouse click queries +// TODO: Work on slider - make it templated, add sizing, add styling, add vertical vs horizontal option +// TODO: change hot to hover? +// TODO: Implement text editing using stb_textedit +#pragma once + +namespace bsc +{ + namespace ui + { + // keys / modifiers and mouse button identifiers + enum keys + { + key_space = 32, + key_apostrophe = 39, /* ' */ + key_comma = 44, /* , */ + key_minus = 45, /* - */ + key_period = 46, /* . */ + key_slash = 47, /* / */ + key_0 = 48, + key_1 = 49, + key_2 = 50, + key_3 = 51, + key_4 = 52, + key_5 = 53, + key_6 = 54, + key_7 = 55, + key_8 = 56, + key_9 = 57, + key_semicolon = 59, /* ; */ + key_equal = 61, /* = */ + key_a = 65, + key_b = 66, + key_c = 67, + key_d = 68, + key_e = 69, + key_f = 70, + key_g = 71, + key_h = 72, + key_i = 73, + key_j = 74, + key_k = 75, + key_l = 76, + key_m = 77, + key_n = 78, + key_o = 79, + key_p = 80, + key_q = 81, + key_r = 82, + key_s = 83, + key_t = 84, + key_u = 85, + key_v = 86, + key_w = 87, + key_x = 88, + key_y = 89, + key_z = 90, + key_left_bracket = 91, /* [ */ + key_backslash = 92, /* \ */ + key_right_bracket = 93, /* ] */ + key_grave_accent = 96, /* ` */ + key_world_1 = 161, /* non-us #1 */ + key_world_2 = 162, /* non-us #2 */ + key_escape = 256, + key_enter = 257, + key_tab = 258, + key_backspace = 259, + key_insert = 260, + key_delete = 261, + key_right = 262, + key_left = 263, + key_down = 264, + key_up = 265, + key_page_up = 266, + key_page_down = 267, + key_home = 268, + key_end = 269, + key_caps_lock = 280, + key_scroll_lock = 281, + key_num_lock = 282, + key_pri32_screen = 283, + key_pause = 284, + key_f1 = 290, + key_f2 = 291, + key_f3 = 292, + key_f4 = 293, + key_f5 = 294, + key_f6 = 295, + key_f7 = 296, + key_f8 = 297, + key_f9 = 298, + key_f10 = 299, + key_f11 = 300, + key_f12 = 301, + key_f13 = 302, + key_f14 = 303, + key_f15 = 304, + key_f16 = 305, + key_f17 = 306, + key_f18 = 307, + key_f19 = 308, + key_f20 = 309, + key_f21 = 310, + key_f22 = 311, + key_f23 = 312, + key_f24 = 313, + key_f25 = 314, + key_kp_0 = 320, + key_kp_1 = 321, + key_kp_2 = 322, + key_kp_3 = 323, + key_kp_4 = 324, + key_kp_5 = 325, + key_kp_6 = 326, + key_kp_7 = 327, + key_kp_8 = 328, + key_kp_9 = 329, + key_kp_decimal = 330, + key_kp_divide = 331, + key_kp_multiply = 332, + key_kp_subtract = 333, + key_kp_add = 334, + key_kp_enter = 335, + key_kp_equal = 336, + key_left_shift = 340, + key_left_control = 341, + key_left_alt = 342, + key_left_super = 343, + key_right_shift = 344, + key_right_control = 345, + key_right_alt = 346, + key_right_super = 347, + key_menu = 348, + no_of_keys = key_menu + }; + + enum mod + { + shift, + ctrl, + alt, + super + }; + + enum mouse_button + { + lmb, + rmb, + mmb + }; + + // main state of ui - tells us everything we need to know about the window + // TODO: Should this be renamed to context? + struct state + { + // graphical user i32raface state + i32 hot_item; + i32 active_item; + + // user input state + i32 keys_down[ bsc::ui::no_of_keys ]; + r32 keys_down_duration[ bsc::ui::no_of_keys ]; + r32 keys_down_prev_duration[ bsc::ui::no_of_keys ]; + + i32 mods_down[ 4 ]; + r32 mods_down_duration[ 4 ]; + + i32 mouse_down[ 3 ]; + r32 mouse_down_duration[ 3 ]; + r32 mouse_down_prev_duration[ 3 ]; + + vec2d mouse_pos; + vec2d mouse_prev_pos; + vec2d mouse_clicked_pos; + vec2d mouse_released_pos; + + r32 mouse_wheel_offset; + r32 mouse_wheel_prev_offset; + + i32 mouse_is_hovering_window; + + r32 frame_start_time; + r32 frame_end_time; + r32 delta_time; + }; + + void begin_frame(); + void end_frame(); +#ifdef BSC_USE_IMGUI + void init_imgui(); +#endif + // simplistic graphical user interface + + i32 button ( const char * text, const r32 x, const r32 y, + const r32 w = 128, const r32 h=32, const r32 cor_rad=3 ); + i32 label ( const char * text, const r32 x, const r32 y ); + + i32 slider ( const char * text, const i32 x, const i32 y, + const i32 max, i32 &value ); + i32 slider ( const char * text, const i32 x, const i32 y, + const r32 max, r32 &value ); + i32 slider ( const char * text, const i32 x, const i32 y, + const r64 max, r64 &value ); + + i32 flip_switch ( const char * text, const i32 x, const i32 y, bool & value ); + i32 checkbox( const char * text, const i32 x, const i32 y, bool & value ); + + // TODO: implement those + // i32 ProgressBar(); + // i32 ProgressCircle(); + // i32 InputText( const i32 id, const i32 x, i32 y, const char * text ); + + // query based keyboard and mouse input handling + i32 is_key_pressed( const i32 key_idx, const i8 mod_idx = -1 ); + i32 is_key_down( const i32 key_idx, const i8 mod_idx = -1 ); + i32 is_key_held( const i32 key_idx, const i8 mod_idx = -1 ); + i32 is_key_released( const i32 key_idx, const i8 mod_idx = -1 ); + + i32 is_mouse_clicked ( const i32 button_idx, const i8 mod_idx = -1 ); + i32 is_mouse_held ( const i32 button_idx, const i8 mod_idx = -1 ); + i32 is_mouse_released ( const i32 button_idx, const i8 mod_idx = -1 ); + + i32 is_mouse_over( const vec4i & rect ); + + vec2d get_mouse_drag_delta( const i32 button_idx ); + r32 get_mouse_wheel_offset(); + + } + + // TODO : This should return pointer, not reference + static ui::state g_UI; + ui::state & get_UI(); + +} + +// TODO: asserts should not be in release code +// TODO: possible readability issues due to overuse of the if/else shortcut. Remodel, unroll loops? +// TODO: keyboard support for slider, use inputs values by hand + +//////////////////////////////////////////////////////////////////////////////// +// UI implementation +//////////////////////////////////////////////////////////////////////////////// + +#ifdef BSC_IMPLEMENTATION + +bsc::ui::state & bsc:: +get_UI() +{ + return g_UI; +} + +#ifdef BSC_USE_IMGUI +// Forward declare new frame function for imgui +void ImGui_BscImpl_NewFrame( const bsc::window * window, + const bsc::ui::state * ui_state ); +#endif + +void bsc::ui:: +begin_frame() +{ + bsc::window & g_window = bsc::get_window(); + + // we will decide which item is hot on per-frame basis + g_UI.hot_item = 0; + + // update current mouse position within specified window + g_UI.mouse_prev_pos = g_UI.mouse_pos; + glfwGetCursorPos( g_window.handle, &g_UI.mouse_pos.x, &g_UI.mouse_pos.y); + if ( !glfwGetWindowAttrib( g_window.handle, GLFW_FOCUSED) ) + { + g_UI.mouse_pos = bsc::vec2d( -1.0f, -1.0f ); + } + + // update key durations -> based on a clever trick from ocornut's dear imgui + for ( i32 key_idx = 0 ; key_idx < bsc::ui::no_of_keys ; ++key_idx ) + { + g_UI.keys_down_prev_duration[ key_idx ] = g_UI.keys_down_duration[ key_idx ]; + g_UI.keys_down_duration[ key_idx ] = + g_UI.keys_down[ key_idx ] ? ( g_UI.keys_down_duration[ key_idx ] == -1.0f ? 0.0f + : (g_UI.keys_down_duration[ key_idx ] + g_UI.delta_time) ) + : -1.0f; + } + + // update modifiers durations + for ( i32 mod_idx = 0 ; mod_idx < 4 ; ++mod_idx ) + { + g_UI.mods_down_duration[ mod_idx ] = + g_UI.mods_down[ mod_idx ] ? ( g_UI.mods_down_duration[ mod_idx ] == -1.0f ? 0.0f + : g_UI.mods_down_duration[ mod_idx ] + g_UI.delta_time ) + : -1.0f; + } + + // update mouse_buttons durations + for ( i32 mb_idx = 0 ; mb_idx < 3 ; ++mb_idx ) + { + g_UI.mouse_down_prev_duration[ mb_idx ] = g_UI.mouse_down_duration[ mb_idx ]; + g_UI.mouse_down_duration[ mb_idx ] = + g_UI.mouse_down[ mb_idx ] ? ( g_UI.mouse_down_duration[ mb_idx ] == -1.0f ? 0.0f + : g_UI.mouse_down_duration[ mb_idx ] + g_UI.delta_time ) + : -1.0f; + // HACK -> if any of mouse buttons is down, let's force glfw to refresh + // if ( g_UI.mouse_down[ mb_idx ] ) glfwPostEmptyEvent(); + + } + + // reset mouse state - based on dear imgui glfw example + g_UI.mouse_wheel_offset = g_UI.mouse_wheel_prev_offset; + g_UI.mouse_wheel_prev_offset = 0.0f; + + // HACK -> if there has been a wheel spin, let's force glfw to refresh + // if ( g_UI.mouse_wheel_offset != 0.0f ) glfwPostEmptyEvent(); + + g_UI.frame_start_time = glfwGetTime(); + +#ifdef BSC_USE_IMGUI + ImGui_BscImpl_NewFrame( &g_window, &g_UI ); +#endif +} + +void bsc::ui:: +end_frame () +{ + // if left mouse button is not down on this frame, reset active item + if ( g_UI.mouse_down[ bsc::ui::lmb ] == 0 ) + { + g_UI.active_item = 0; + } + + // update frame time + g_UI.frame_end_time = glfwGetTime(); + g_UI.delta_time = g_UI.frame_end_time - g_UI.frame_start_time; + +} + + +// mouse and keyboard input +i32 bsc::ui:: +is_key_down ( const i32 key_idx, const i8 mod_idx ) +{ + assert( key_idx >= 0 && key_idx < bsc::ui::no_of_keys ); + + return ( mod_idx < 0 ) ? g_UI.keys_down_duration[ key_idx ] >= 0.0f + : ( g_UI.keys_down_duration[ key_idx ] >= 0.0f && + g_UI.mods_down_duration[ mod_idx ] >= 0.0f ); +} + +i32 bsc::ui:: +is_key_pressed ( const i32 key_idx, const i8 mod_idx ) +{ + assert( key_idx >= 0 && key_idx < bsc::ui::no_of_keys ); + + return ( mod_idx < 0 ) ? g_UI.keys_down_duration[ key_idx ] == 0.0f + : ( g_UI.keys_down_duration[ key_idx ] == 0.0f && + g_UI.mods_down_duration[ mod_idx ] >= 0.0f ); +} + +i32 bsc::ui:: +is_key_held ( const i32 key_idx, const i8 mod_idx ) +{ + assert( key_idx >= 0 && key_idx < bsc::ui::no_of_keys ); + + return ( mod_idx < 0 ) ? g_UI.keys_down_duration[ key_idx ] > 0.0f + : ( g_UI.keys_down_duration[ key_idx ] > 0.0f && + g_UI.mods_down_duration[ mod_idx ] >= 0.0f ); +} + +i32 bsc::ui:: +is_key_released ( const i32 key_idx, const i8 mod_idx ) +{ + assert( key_idx >= 0 && key_idx < bsc::ui::no_of_keys ); + + bool was_released = ( g_UI.keys_down_duration[ key_idx ] == -1.0f && + g_UI.keys_down_prev_duration[ key_idx ] > 0.0f ); + bool was_released_mod = was_released && + g_UI.mods_down_duration[ mod_idx ] >= 0.0f; + + return ( mod_idx < 0 ) ? was_released + : was_released_mod; +} + +i32 bsc::ui:: +is_mouse_clicked( const i32 button_idx, const i8 mod_idx ) +{ + assert( button_idx >= 0 && button_idx < 3 ); + + bool was_clicked = (g_UI.mouse_down_duration[ button_idx ] == 0.0f); + + if ( mod_idx < 0 ) + { + if ( was_clicked ) g_UI.mouse_clicked_pos = g_UI.mouse_pos; + return was_clicked; + } + else + { + bool was_clicked_mod = was_clicked && + g_UI.mods_down_duration[ mod_idx ] >= 0.0f; + if ( was_clicked_mod ) g_UI.mouse_clicked_pos = g_UI.mouse_pos; + return was_clicked_mod; + } +} + +i32 bsc::ui:: +is_mouse_held( const i32 button_idx, const i8 mod_idx ) +{ + assert ( button_idx >= 0 && button_idx < 3 ); + + bool mod_is_on = (g_UI.mods_down_duration[ shift ] >= 0.0) || + (g_UI.mods_down_duration[ ctrl ] >= 0.0) || + (g_UI.mods_down_duration[ alt ] >= 0.0) || + (g_UI.mods_down_duration[ super ] >= 0.0); + + if ( mod_is_on ) + { + + if ( mod_idx < 0 ) + { + // we're holding modifier, but function doesn't specify one -> no held + return false; + } + else + { + return ( g_UI.mouse_down_duration[ button_idx ] > 0.0f && + g_UI.mods_down_duration[ mod_idx ] >= 0.0f ) ? 1 + : 0; + } + } + else + { + if ( mod_idx >= 0 ) + { + // we are not holding modifier, but function specifies one -> no held + return false; + } + else + { + return ( g_UI.mouse_down_duration[ button_idx ] > 0.0f ) ? 1 + : 0; + } + } + return false; +} + +i32 bsc::ui:: +is_mouse_over( const vec4i & rect ) +{ + return ( g_UI.mouse_pos.x > rect.x && + g_UI.mouse_pos.y > rect.y && + g_UI.mouse_pos.x <= (rect.x + rect.z) && + g_UI.mouse_pos.y <= (rect.y + rect.w) ) ? 1 : 0; +} + +i32 bsc::ui:: +is_mouse_released ( const i32 button_idx, const i8 mod_idx ) +{ + assert( button_idx >= 0 && button_idx < 3 ); + + bool was_released = ( g_UI.mouse_down_duration[ button_idx ] == -1.0f ) && + ( g_UI.mouse_down_prev_duration[ button_idx ] > 0.0f ); + + if ( was_released ) g_UI.mouse_released_pos = g_UI.mouse_pos; + + return was_released; +} + +bsc::vec2d bsc::ui:: +get_mouse_drag_delta ( const i32 button_idx ) +{ + assert ( button_idx >= 0 && button_idx < 3 ); + + bool is_duration_positive = ( g_UI.mouse_down_duration[ button_idx ] > 0.0f ); + return is_duration_positive ? ( g_UI.mouse_pos - g_UI.mouse_prev_pos ) + : bsc::vec2d( 0.0, 0.0 ); +} + +r32 bsc::ui:: +get_mouse_wheel_offset () +{ + return g_UI.mouse_wheel_offset; +} + +i32 bsc::ui:: +button ( const char * title, const r32 x, const r32 y, + const r32 w, const r32 h, const r32 corner_rad ) +{ + i32 retval = false; +//Basic interface is currently disabled +#if 0 + // manage ui state + int id = string_hash( title ); + vec4f rect ( x, y, w, h ); + if ( ui::is_mouse_over( rect ) ) + { + g_UI.hot_item = id; + } + + if ( ui::is_mouse_over( rect ) && ui::is_mouse_clicked( ui::lmb ) ) + { + g_UI.active_item = id; + } + + if ( g_UI.active_item == id && ui::is_mouse_released ( ui::lmb ) ) + { + g_UI.active_item = 0; + retval = true; + } +#endif + return retval; +} + +i32 bsc::ui:: +slider ( const char * title, const i32 x, const i32 y, const i32 max, + i32 &value ) +{ + int retval = 0; +//Basic interface is currently disabled +#if 0 + int id = string_hash( title ); + + // Check for hotness + vec4f rect ( x, y, 255, 8 ); + if ( ui::is_mouse_over( rect ) ) + { + g_UI.hot_item = id; + if (g_UI.active_item == 0 && g_UI.mouse_down[ lmb ] ) + g_UI.active_item = id; + } + + // Update widget value + if ( g_UI.active_item == id) + { + int mousepos = g_UI.mouse_pos.x - x; + if (mousepos < 0) mousepos = 0; + if (mousepos > 255) mousepos = 255; + int v = (mousepos * max) / 255; + if (v != value) + { + value = v; + retval = 1; + } + } +#endif + return retval; +} + +i32 bsc::ui:: +flip_switch ( const char * title, const i32 x, const i32 y, bool & value ) +{ + i32 retval = false; + int id = string_hash( title ); + + // manage ui state + vec4i rect ( x, y, 56, 24 ); + if ( ui::is_mouse_over( rect ) ) + { + g_UI.hot_item = id; + } + + if ( ui::is_mouse_over( rect ) && ui::is_mouse_clicked( ui::lmb ) ) + { + g_UI.active_item = id; + } + + if ( g_UI.active_item == id && ui::is_mouse_released ( ui::lmb ) ) + { + g_UI.active_item = 0; + value = !value; + retval = true; + } + + return retval; +} + + +i32 bsc::ui:: +checkbox ( const char * text, const i32 x, const i32 y, bool & value ) +{ + i32 retval = false; + int id = string_hash( text ); + + // manage ui state + // TODO: checked rectange width should be given by the text bounds + vec4i rect ( x, y, 128, 24 ); + + if ( ui::is_mouse_over( rect ) ) + { + g_UI.hot_item = id; + } + + if ( ui::is_mouse_over( rect ) && ui::is_mouse_clicked( ui::lmb ) ) + { + g_UI.active_item = id; + } + + if ( g_UI.active_item == id && ui::is_mouse_released ( ui::lmb ) ) + { + g_UI.active_item = 0; + value = !value; + retval = true; + } + + + return retval; +} + + +i32 bsc::ui:: +label ( const char * text, const r32 x, const r32 y ) +{ + return 0; +} + + +//////////////////////////////////////////////////////////////////////////////// +// Callbacks +//////////////////////////////////////////////////////////////////////////////// + +void +keyboard_callback ( GLFWwindow*, i32 key, i32, i32 action, i32 mods ) +{ + using namespace bsc; + + bsc::ui::state & ui = bsc::get_UI(); + + // record key presses + if ( action == GLFW_PRESS ) + ui.keys_down[ key ] = true; + if ( action == GLFW_RELEASE ) + ui.keys_down[ key ] = false; + + // record modifiers separately for convenience + ui.mods_down[ ui::shift ] = ui.keys_down[ ui::key_left_shift ] || + ui.keys_down[ ui::key_right_shift ]; + ui.mods_down[ ui::alt ] = ui.keys_down[ ui::key_left_alt ] || + ui.keys_down[ ui::key_right_alt ]; + ui.mods_down[ ui::ctrl ] = ui.keys_down[ ui::key_left_control ] || + ui.keys_down[ ui::key_right_control ]; + ui.mods_down[ ui::super ] = ui.keys_down[ ui::key_left_super ] || + ui.keys_down[ ui::key_right_super ]; +#ifdef BSC_USE_IMGUI + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +#endif +} + +void +char_callback( GLFWwindow*, unsigned int c ) +{ +#ifdef BSC_USE_IMGUI + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +#endif +} + +void +mouse_button_callback( GLFWwindow* window, i32 button, i32 action, i32 ) +{ + bsc::ui::state & ui = bsc::get_UI(); + + if ( action == GLFW_PRESS ) ui.mouse_down[ button ] = true; + if ( action == GLFW_RELEASE ) ui.mouse_down[ button ] = false; +#ifdef BSC_USE_IMGUI + +#endif +} + +void +scroll_callback( GLFWwindow* window, double /**/, double yoffset ) +{ + bsc::ui::state & ui = bsc::get_UI(); + ui.mouse_wheel_prev_offset += yoffset; + +} + +void +cursor_enter_callback( GLFWwindow* window, i32 entered ) +{ + bsc::ui::state & ui = bsc::get_UI(); + + if ( entered ) ui.mouse_is_hovering_window = true; + else ui.mouse_is_hovering_window = false; +} + +void +window_size_callback( GLFWwindow* window, i32 width, i32 height ) +{ + bsc::window & g_window = bsc::get_window(); + g_window.size.x = width; + g_window.size.y = height; + g_window.pixel_ratio = (r32)g_window.fb_size.x / (r32)g_window.size.x; + g_window.aspect_ratio = (r32)g_window.size.x / (r32)g_window.size.y; +} + +void +framebuffer_size_callback( GLFWwindow* window, i32 width, i32 height ) +{ + bsc::window & g_window = bsc::get_window(); + g_window.fb_size.x = width; + g_window.fb_size.y = height; + g_window.pixel_ratio = (r32)g_window.fb_size.x / (r32)g_window.size.x; + g_window.aspect_ratio = (r32)g_window.size.x / (r32)g_window.size.y; +} + +// this is called when window is resized! +void +window_refresh_callback( GLFWwindow* window ) +{ + bsc::window & g_window = bsc::get_window(); + + g_window.display(); + + glfwSwapBuffers( window ); +} + +void +drop_callback( GLFWwindow* window, i32 count, const char ** paths ) +{ + bsc::window & g_window = bsc::get_window(); + g_window.drag_and_drop( count, paths ); +} + +#ifdef BSC_USE_IMGUI + +// TODO all the good biz with the render drawlist and initialization +static double g_Time = 0.0f; +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; + + +void +ImGui_BscImpl_SetupStyle() +{ + ImGuiStyle& style = ImGui::GetStyle(); + style.Colors[ImGuiCol_Text] = ImVec4( 0.9f, 0.9f, 0.9f, 1.00f ); + style.Colors[ImGuiCol_WindowBg] = ImVec4( 0.2f, 0.2f, 0.2f, 1.00f ); + + // Background of sliders / checkboxes etc. + style.Colors[ImGuiCol_FrameBg] = ImVec4( 0.37f, 0.39f, 0.43f, 1.00f ); + style.Colors[ImGuiCol_FrameBgHovered] = ImVec4( 0.47f, 0.49f, 0.53f, 1.00f ); + style.Colors[ImGuiCol_FrameBgActive] = ImVec4( 0.57f, 0.59f, 0.63f, 1.00f ); + + // Window header + style.Colors[ImGuiCol_TitleBg] = ImVec4( 0.29f, 0.3f, 0.31f, 1.00f ); + style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4( 0.19f, 0.2f, 0.21f, 1.00f ); + style.Colors[ImGuiCol_TitleBgActive] = ImVec4( 0.19f, 0.2f, 0.21f, 1.00f ); + + // Checkbox + style.Colors[ImGuiCol_CheckMark] = ImVec4( 0.29f, 0.30f, 0.31f, 1.00f ); + + // Slider grab + style.Colors[ImGuiCol_SliderGrab] = ImVec4( 0.29f, 0.30f, 0.31f, 1.00f ); + style.Colors[ImGuiCol_SliderGrabActive] = ImVec4( 0.20f, 0.20f, 0.20f, 1.00f ); + + // Button + style.Colors[ImGuiCol_Button] = ImVec4( 0.31f, 0.32f, 0.36f, 1.00f ); + style.Colors[ImGuiCol_ButtonHovered] = ImVec4( 0.33f, 0.34f, 0.38f, 1.00f ); + style.Colors[ImGuiCol_ButtonActive] = ImVec4( 0.15f, 0.16f, 0.19f, 1.00f ); + + // Collapsing lists + style.Colors[ImGuiCol_Header] = ImVec4( 0.15f, 0.16f, 0.16f, 1.00f ); + style.Colors[ImGuiCol_HeaderHovered] = ImVec4( 0.43f, 0.44f, 0.48f, 1.00f ); + style.Colors[ImGuiCol_HeaderActive] = ImVec4( 0.15f, 0.16f, 0.19f, 1.00f ); + + // Scrollbag + style.Colors[ImGuiCol_ScrollbarBg] = ImVec4( 0.20f, 0.20f, 0.20f, 1.00f); + style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4( 0.29f, 0.30f, 0.31f, 1.00f ); + style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4( 0.29f, 0.30f, 0.31f, 1.00f ); + style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4( 0.29f, 0.30f, 0.31f, 1.00f ); + + + style.Alpha = 1.0f; + style.WindowPadding = ImVec2( 10.0f, 10.0f ); + style.WindowMinSize = ImVec2( 32.0f, 32.0f ); + style.WindowRounding = 0.0f; + style.ChildWindowRounding = 2.0f; + style.FramePadding = ImVec2( 3.0f, 3.0f );; + style.FrameRounding = 7.5f; + style.ItemSpacing = ImVec2( 6.0f, 4.0f ); + style.ItemInnerSpacing = ImVec2( 6.0f, 4.0f ); + style.IndentSpacing = 16.0f; + style.ColumnsMinSpacing = 1.0f; + style.ScrollbarSize = 20.0f; + style.ScrollbarRounding = 2.0f; + style.GrabMinSize = 6.0f; + style.GrabRounding = 7.5f; +} + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +void +ImGui_BscImpl_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // Backup GL state + GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture); + GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); + GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); + GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); + GLint last_blend_src; glGetIntegerv(GL_BLEND_SRC, &last_blend_src); + GLint last_blend_dst; glGetIntegerv(GL_BLEND_DST, &last_blend_dst); + GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); + GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); + GLboolean last_enable_blend = glIsEnabled(GL_BLEND); + GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); + GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); + GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); + + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + const float ortho_projection[4][4] = + { + { 2.0f/io.DisplaySize.x, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-io.DisplaySize.y, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + {-1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const ImDrawIdx* idx_buffer_offset = 0; + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); + } + idx_buffer_offset += pcmd->ElemCount; + } + } + + // Restore modified GL state + glUseProgram(last_program); + glActiveTexture(last_active_texture); + glBindTexture(GL_TEXTURE_2D, last_texture); + glBindVertexArray(last_vertex_array); + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); + glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); + glBlendFunc(last_blend_src, last_blend_dst); + if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); + if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); + if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); + if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); + glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); +} + +static const char* ImGui_BscImpl_GetClipboardText() +{ + return glfwGetClipboardString( bsc::g_window.handle ); +} + +static void ImGui_BscImpl_SetClipboardText(const char* text) +{ + glfwSetClipboardString( bsc::g_window.handle, text ); +} + +bool ImGui_BscImpl_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +// TODO: Do it with basics? +bool +ImGui_BscImpl_CreateDeviceObjects() +{ + // Backup GL state + GLint last_texture, last_array_buffer, last_vertex_array; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); + + const GLchar *vertex_shader = + "#version 330\n" + "uniform mat4 ProjMtx;\n" + "in vec2 Position;\n" + "in vec2 UV;\n" + "in vec4 Color;\n" + "out vec2 Frag_UV;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "#version 330\n" + "uniform sampler2D Texture;\n" + "in vec2 Frag_UV;\n" + "in vec4 Frag_Color;\n" + "out vec4 Out_Color;\n" + "void main()\n" + "{\n" + " Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + glCompileShader(g_FragHandle); + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + glGenBuffers(1, &g_ElementsHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + + ImGui_BscImpl_CreateFontsTexture(); + + // Restore modified GL state + glBindTexture(GL_TEXTURE_2D, last_texture); + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + glBindVertexArray(last_vertex_array); + + return true; +} + +void +ImGui_BscImpl_InvalidateDeviceObjects() +{ + if ( g_VaoHandle ) glDeleteVertexArrays(1, &g_VaoHandle); + if ( g_VboHandle ) glDeleteBuffers( 1, &g_VboHandle); + if ( g_ElementsHandle ) glDeleteBuffers( 1, &g_ElementsHandle ); + g_VaoHandle = g_VboHandle = g_ElementsHandle = 0; + + glDetachShader(g_ShaderHandle, g_VertHandle); + glDeleteShader(g_VertHandle); + g_VertHandle = 0; + + glDetachShader(g_ShaderHandle, g_FragHandle); + glDeleteShader(g_FragHandle); + g_FragHandle = 0; + + glDeleteProgram(g_ShaderHandle); + g_ShaderHandle = 0; + + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool +ImGui_BscImpl_Init( GLFWwindow* window ) +{ + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_BscImpl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_BscImpl_SetClipboardText; + io.GetClipboardTextFn = ImGui_BscImpl_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + ImGui_BscImpl_SetupStyle(); + + // I guess imgui is trying to delete this? + void * font_data = malloc( ubuntu_mono_ttf_len ); + memcpy( font_data, &(ubuntu_mono_ttf[0]), ubuntu_mono_ttf_len ); + ImFont * font = io.Fonts->AddFontFromMemoryTTF( font_data, + ubuntu_mono_ttf_len, + 14.0); + font->DisplayOffset.y -= 1; + return true; +} + +void ImGui_BscImpl_Shutdown() +{ + ImGui_BscImpl_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_BscImpl_NewFrame( const bsc::window * window, + const bsc::ui::state * ui_state ) +{ + + if ( !g_FontTexture ) + ImGui_BscImpl_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + io.DisplaySize = ImVec2( window->size.x, window->size.y ); + io.DisplayFramebufferScale = ImVec2( window->fb_size.x / window->size.x, + window->fb_size.y / window->size.y ); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib( window->handle, GLFW_FOCUSED)) + { + io.MousePos = ImVec2( ui_state->mouse_pos.x, + ui_state->mouse_pos.y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = ui_state->mouse_down[i] || + glfwGetMouseButton( window->handle, i ) != 0; + } + + io.MouseWheel = ui_state->mouse_wheel_offset; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode( window->handle, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} + +#endif + +#endif diff --git a/CameraParameterEstimation/apps/basics/window/win.h b/CameraParameterEstimation/apps/basics/window/win.h new file mode 100644 index 0000000..2e18b61 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/window/win.h @@ -0,0 +1,352 @@ +// basics window + +// simple window handler, wrapping around the glfw for window and ogl3.3 context creation, with glew for gl extensions. +#pragma once + + + +namespace bsc +{ + + struct window + { + GLFWwindow * handle = NULL; + struct NVGcontext * vg = NULL; // this really should be part of gui.h + vec2i size = vec2i( -1, -1 ); + vec2i fb_size = vec2i( -1, -1 ); + vec4i viewport = vec4i(-1, -1, -1, -1); + r64 pixel_ratio = -1.0; + r64 aspect_ratio = -1.0; + vec3f bckgrd_col_top; + vec3f bckgrd_col_bot; + r32 buffer_swap_time; + + // TODO Change these to function pointers? More C style? + std::function< void() > display; + std::function< i32() > init; + std::function< void( i32, const char **) > drag_and_drop; + }; + + static window g_window; + window & get_window(); + + i32 create_window( const char * title, const i32 width, const i32 height, + const vec3 color_top = vec3( 0.45, 0.45, 0.45 ), + const vec3 color_bot = vec3( 0.45, 0.45, 0.45 )); + i32 clear_window( vec4i viewport = vec4i( -1, -1, -1, -1 ) ); + i32 main_loop(); + + void take_screenshot( vec4i viewport ); + void refresh_display(); + + void set_display_funct( std::function< void() > display_funct ); + void set_init_funct( std::function< i32() > init_funct ); + void set_drag_and_drop_funct ( + std::function < void( i32, const char **) > drag_and_drop_funct ); + + void install_callbacks( GLFWwindow * handle ); + + // graphics context should be owned by io, not window (?) + struct NVGcontext * get_vector_graphics_context(); +} + + +// bascics window functions + +#ifdef BSC_IMPLEMENTATION + + +//////////////////////////////////////////////////////////////////////////////// +// Implementation +//////////////////////////////////////////////////////////////////////////////// +bsc::window & bsc:: +get_window() +{ + return g_window; +} + +void bsc:: +set_display_funct( std::function< void() > display_funct ) +{ + g_window.display = display_funct; +} + +void bsc:: +set_init_funct( std::function< i32() > init_funct ) +{ + g_window.init = init_funct; +} + +void bsc:: +set_drag_and_drop_funct( std::function < void( i32, const char ** ) > drag_and_drop_funct ) +{ + g_window.drag_and_drop = drag_and_drop_funct; +} + +i32 bsc:: +create_window ( const char * title, const i32 width, const i32 height, + const bsc::vec3 color_top, const bsc::vec3 color_bot ) +{ + + // initialize and create GLFW window to obtain modern opengl context(not so modern on mac, haha) + if ( !glfwInit() ) + { + printf( "Could not init glfw\n" ); + return 0; + } + + glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 4 ); + glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 1 ); + glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE ); + glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE ); + glfwWindowHint( GLFW_SAMPLES, 4 ); // INVESTIGATE! + // glfwWindowHint( GLFW_DECORATED, GL_FALSE ); // <- this will remove "fluff" + glfwWindowHint( GLFW_RESIZABLE, GL_TRUE ); + + g_window.handle = glfwCreateWindow( width, height, title, NULL, NULL ); + + if ( !g_window.handle ) + { + printf( "Could not create glfw window\n" ); + glfwTerminate(); + return 0; + } + + install_callbacks( g_window.handle ); + + // Note seting SwapInterval to 0 essentialy disables v_sync! + glfwMakeContextCurrent( g_window.handle ); + glfwSwapInterval( 0 ); + + // lets get gl extension from glew + // TODO: need to replace this library + #if defined(_WIN32) || defined(_WIN64) + #ifndef __EMSCRIPTEN__ + glewExperimental = GL_TRUE; + if ( glewInit() != GLEW_OK ) + { + printf( "Could not init glew\n" ); + return 0; + } + #endif + #endif + + // lets create the vector graphics context + #ifdef __EMSCRIPTEN__ + // g_window.vg = nvgCreateGLES2( NVG_ANTIALIAS | NVG_STENCIL_STROKES ); + #else + // g_window.vg = nvgCreateGL3( NVG_ANTIALIAS | NVG_STENCIL_STROKES ); + #endif + + // if ( g_window.vg == NULL ) + // { + // printf( "Could not init nanovg\n" ); + // return 0; + // } + + // some sane opengl defaults + glEnable( GL_DEPTH_TEST ); + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + glBlendEquation( GL_FUNC_ADD ); + + glfwGetWindowSize( g_window.handle, &g_window.size.x, &g_window.size.y ); + glfwGetFramebufferSize( g_window.handle, + &g_window.fb_size.x, &g_window.fb_size.y ); + g_window.pixel_ratio = (r32)g_window.fb_size.x / (r32)g_window.size.x; + g_window.aspect_ratio = (r32)g_window.size.x / (r32)g_window.size.y; + g_window.viewport = bsc::vec4i( 0, 0, g_window.fb_size.x, g_window.fb_size.y); + g_window.bckgrd_col_top = color_top; + g_window.bckgrd_col_bot = color_bot; + + return 1; +} + +// This is a set of shaders for rendering the gradient backgroud +void render_background( bsc::vec3 col_top, bsc::vec3 col_bot ) +{ + static GLuint background_vao = 0; + static bsc::shader_prog background_shader; + + if (background_vao == 0) + { + glGenVertexArrays(1, &background_vao); + + // vertex shader ( full screen quad by Morgan McGuire) + char* vs_src = (char*) SHADER_HEAD STR + ( + out vec2 v_texcoords; + void main() + { + uint idx = uint( gl_VertexID % 3 ); + gl_Position = vec4( + (float( idx & 1U ) ) * 4.0 - 1.0, + (float( ( idx >> 1U )& 1U ) ) * 4.0 - 1.0, + 0.0, 1.0); + v_texcoords = gl_Position.xy * 0.5 + 0.5; + } + ); + + char* fs_src = (char*) SHADER_HEAD STR + ( + in vec2 v_texcoords; + uniform vec3 col_top; + uniform vec3 col_bot; + out vec4 frag_color; + void main() + { + frag_color = vec4( v_texcoords.y * col_top + + ( 1.0 - v_texcoords.y ) * col_bot , 1.0 ); + } + ); + + bsc::create_shader_prog_from_source( vs_src, fs_src, background_shader ); + } + + bsc::use_program( background_shader ); + bsc::set_uniform( background_shader, "col_top", col_top ); + bsc::set_uniform( background_shader, "col_bot", col_bot ); + glBindVertexArray( background_vao ); + glDrawArrays(GL_TRIANGLES, 0, 3); + glBindVertexArray(0); +} + +static i32 screenshot_count = 0; + +void bsc:: +take_screenshot( bsc::vec4i viewport ) +{ + i32 w = g_window.pixel_ratio*(viewport.z - viewport.x); + i32 h = g_window.pixel_ratio*(viewport.w - viewport.y); + bsc::img screenshot( w, h, 3 ); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glReadPixels( g_window.pixel_ratio * viewport.x, + g_window.pixel_ratio * viewport.y, + w, h, + GL_RGB, GL_UNSIGNED_BYTE, screenshot.data ); + + screenshot.vert_flip(); + char name[512]; + sprintf( name, "screenshot_%d.jpg", screenshot_count++ ); + screenshot.write( name ); + +} + +i32 bsc:: +clear_window( bsc::vec4i viewport ) +{ + // TODO: Basics will most likely be deferred renderer. We need to remove this. + // Also this is strictly renderer dependent + if ( viewport != bsc::vec4i( -1, -1, -1, -1 ) ) + { + g_window.viewport = viewport; + } + glViewport( g_window.pixel_ratio * viewport[0], + g_window.pixel_ratio * viewport[1], + g_window.pixel_ratio * viewport[2], + g_window.pixel_ratio * viewport[3] ); + g_window.aspect_ratio = (r32)viewport[2] / (r32)viewport[3]; + glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); + + glDisable( GL_DEPTH_TEST ); + render_background( g_window.bckgrd_col_top, + g_window.bckgrd_col_bot ); + glEnable( GL_DEPTH_TEST ); + + return 1; +} + +#ifdef BSC_USE_IMGUI + bool ImGui_BscImpl_Init( GLFWwindow* window ); +#endif + +static void +display_loop() +{ + using namespace bsc; + r32 start = glfwGetTime(); + + // TODO: add state variable to control whether we are waiting or polling for events + // TODO: add state variable to control vsync? + glfwPollEvents(); + + g_window.display(); + + glfwSwapBuffers( g_window.handle ); + + r32 end = glfwGetTime(); + + g_window.buffer_swap_time = end - start; +} + +// TODO: Error types? +i32 bsc:: +main_loop () +{ + if ( !g_window.handle ) + { + printf( "Window not created, terminating!\n" ); + return 0; + } + + if ( !g_window.init() ) + { + printf( "Initialization function failed!\n" ); + return 0; + } + +#ifdef BSC_USE_IMGUI + ImGui_BscImpl_Init( g_window.handle ); +#endif + + +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop( display_loop, 0, 0); +#else + while ( !glfwWindowShouldClose( g_window.handle ) ) + { + display_loop(); + } +#endif + + return 1; +} + +void bsc:: +refresh_display() +{ + glfwSwapBuffers( g_window.handle ); +} + +//////////////////////////////////////////////////////////////////////////////// +// Callbacks Forward Declarations +//////////////////////////////////////////////////////////////////////////////// + +void keyboard_callback ( GLFWwindow*, i32 key, i32, i32 action, i32 ); +void char_callback( GLFWwindow*, unsigned int c ); +void mouse_button_callback( GLFWwindow* window, i32 button, i32 action, i32 ); +void scroll_callback( GLFWwindow* window, double /**/, double yoffset ); +void cursor_enter_callback( GLFWwindow* window, i32 entered ); +void window_size_callback( GLFWwindow* window, i32 width, i32 height ); +void framebuffer_size_callback( GLFWwindow* window, i32 width, i32 height ); +void window_refresh_callback( GLFWwindow* window ); +void drop_callback( GLFWwindow* window, i32 count, const char ** paths ); + +void bsc:: +install_callbacks( GLFWwindow * window_handle ) +{ + glfwSetKeyCallback( window_handle, keyboard_callback ); + glfwSetCharCallback( window_handle, char_callback ); + glfwSetMouseButtonCallback( window_handle, mouse_button_callback ); + glfwSetCursorEnterCallback( window_handle, cursor_enter_callback ); + glfwSetWindowSizeCallback ( window_handle, window_size_callback ); + glfwSetFramebufferSizeCallback ( window_handle, framebuffer_size_callback ); + glfwSetWindowRefreshCallback( window_handle, window_refresh_callback ); + glfwSetScrollCallback ( window_handle, scroll_callback ); +#ifndef __EMSCRIPTEN__ + glfwSetDropCallback ( window_handle, drop_callback ); +#endif +} +#endif diff --git a/CameraParameterEstimation/apps/basics/window/window.h b/CameraParameterEstimation/apps/basics/window/window.h new file mode 100644 index 0000000..b756ff6 --- /dev/null +++ b/CameraParameterEstimation/apps/basics/window/window.h @@ -0,0 +1,6 @@ +// window.h +#pragma once + +#include "win.h" +#include "ui.h" + diff --git a/CameraParameterEstimation/apps/calibrate_depth/src/calibrate_depth.cpp b/CameraParameterEstimation/apps/calibrate_depth/src/calibrate_depth.cpp new file mode 100644 index 0000000..f8c55b8 --- /dev/null +++ b/CameraParameterEstimation/apps/calibrate_depth/src/calibrate_depth.cpp @@ -0,0 +1,1236 @@ +#define BSC_IMPLEMENTATION +#define BSC_USE_WINDOW +#define BSC_USE_IMGUI +#include +#include "grid3d.h" + +//////////////////////////////////////////////////////////////////////////////// +// GPU CODE +//////////////////////////////////////////////////////////////////////////////// +char * debug_vs = (char *)SHADER_HEAD STR +( + layout (location = 0) in vec3 position; + layout (location = 4) in vec4 color; + out vec4 v_color; + uniform mat4 mvp; + void main() + { + gl_Position = mvp * vec4(position, 1.0); + v_color = color; + } +); + +char * debug_fs = (char *)SHADER_HEAD STR +( + in vec4 v_color; + out vec4 frag_color; + void main() + { + frag_color = v_color; + } +); + +char * pointcloud_vs = (char *)SHADER_HEAD STR +( + layout(location = 0) in vec3 position; + layout(location = 1) in vec3 normal; + layout(location = 4) in vec4 color; + out vec4 v_color; + out vec3 v_normal; + uniform mat4 mvp; + void main() { + gl_Position = mvp * vec4(position, 1.0); + v_normal = normal; + v_color = color; + } +); + +char * pointcloud_fs = (char *)SHADER_HEAD STR +( + in vec4 v_color; + in vec3 v_normal; + out vec4 frag_color; + uniform bool show_normals; + void main() { + if (!show_normals) + { + frag_color = v_color; + } + else + { + frag_color = vec4(0.5 * (v_normal + 1.0), 1.0); + } + } +); + +char *plane_vs = (char *)SHADER_HEAD STR +( + layout(location = 0) in vec3 position; + uniform mat4 mvp; + void main() { + gl_Position = mvp * vec4(position, 1.0); + } +); + +char *plane_fs = (char *)SHADER_HEAD STR +( + uniform vec4 color; + out vec4 frag_color; + void main() { + frag_color = color; + } +); + +//////////////////////////////////////////////////////////////////////////////// +// I/O +//////////////////////////////////////////////////////////////////////////////// + +struct SequenceData +{ + bsc::mat3 depth_intrinsics; + bsc::mat4 depth_to_color; + std::vector plane_poses; + std::vector image_names; + int n_images; +}; + +struct Options +{ + bool print_verbose; + bool save_slice_visualization; + bool bitshift; + std::string configuration_filename; + std::string estimated_lut_filename; + std::string applied_lut_filename; + float n_slices; + float max_depth; +}; + +static SequenceData seq_data; +static Options opts; + +static int +ReadParametersFile( bsc::mat3 &intrinsics, + bsc::mat4 &extrinsics, + const char* filename ) +{ + intrinsics = bsc::mat3(); + extrinsics = bsc::mat4(); + FILE * params_file = fopen( filename, "r" ); + if ( params_file ) + { + // Parse file + char buffer[1024]; + int line_number = 0; + + while (fgets(buffer, 1024, params_file)) + { + char cmd[1024]; + line_number++; + bool success = 1; + if (sscanf(buffer, "%s =", cmd) != (unsigned int)1) + { + continue; + } + if (cmd[0] == '#') + continue; + + if (!strcmp(cmd, "fx_depth")) + { + success = (sscanf(buffer, "%s = %f\n", cmd, &intrinsics[0][0] ) != 2); + } + else if (!strcmp(cmd, "fy_depth")) + { + success = (sscanf(buffer, "%s = %f\n", cmd, &intrinsics[1][1] ) != 2); + } + else if (!strcmp(cmd, "mx_depth")) + { + success = (sscanf(buffer, "%s = %f\n", cmd, &intrinsics[2][0] ) != 2); + } + else if (!strcmp(cmd, "my_depth")) + { + success = (sscanf(buffer, "%s = %f\n", cmd, &intrinsics[2][1] ) != 2); + } + else if (!strcmp(cmd, "depthToColorExtrinsics")) + { + bsc::mat4 m; + success = (sscanf(buffer, + "%s = %f %f %f %f\n" + "%f %f %f %f\n" + "%f %f %f %f\n" + "%f %f %f %f\n", + cmd, + &m[0][0], &m[1][0], &m[2][0], &m[3][0], + &m[0][1], &m[1][1], &m[2][1], &m[3][1], + &m[0][2], &m[1][2], &m[2][2], &m[3][2], + &m[0][3], &m[1][3], &m[2][3], &m[3][3] ) != 17); + extrinsics = m; + } + else + { + continue; + } + } + fclose(params_file); + return 1; + } + + printf( "Could not open parameters file %s\n", filename ); + + return 0; +} + +static int +ReadPlanePoses( bsc::mat4 depth_to_color, + std::vector &plane_poses, + const int n_poses, + const char *filename ) +{ + bsc::mat4 flip; // since Tom also has orgin in bottom left we need to flip. + flip[1][1] = -1; + flip[2][2] = -1; + depth_to_color = flip * depth_to_color * flip; + + // We actually want color to depth + bsc::mat4 color_to_depth = bsc::inverse( depth_to_color ); + + // Open camera poses file + FILE * fp = fopen(filename, "r"); + if (!fp) + { + return 0; + } + + // Read file with plane poses( from matlab ) + plane_poses.reserve(n_poses); + for (int i = 0; i < n_poses; i++) + { + // Load in the plane pose + bsc::mat4 pose; + fscanf(fp, "%f %f %f %f", &(pose[0][0]), &(pose[1][0]), &(pose[2][0]), &(pose[3][0])); + fscanf(fp, "%f %f %f %f", &(pose[0][1]), &(pose[1][1]), &(pose[2][1]), &(pose[3][1])); + fscanf(fp, "%f %f %f %f", &(pose[0][2]), &(pose[1][2]), &(pose[2][2]), &(pose[3][2])); + fscanf(fp, "%f %f %f %f", &(pose[0][3]), &(pose[1][3]), &(pose[2][3]), &(pose[3][3])); + + plane_poses.push_back( color_to_depth * pose ); + } + + // Close file + fclose(fp); + + // Return success + return 1; +} + +int ParseParametersCmd(const char *buffer, char *cmd, SequenceData *data) +{ + char filename[1024]; + if (sscanf(buffer, "%s%s", cmd, filename) != (unsigned int)2) + return 0; + + bsc::mat3 intrinsics_matrix; + bsc::mat4 extrinsics_matrix; + if (!ReadParametersFile(intrinsics_matrix, + extrinsics_matrix, + filename)) + { + fprintf(stderr, "\nUnable to read parameters file %s\n", filename); + exit(-1); + return 0; + } + + data->depth_intrinsics = intrinsics_matrix; + data->depth_to_color = extrinsics_matrix; + + return 1; +} + +int ParsePlanePosesCmd(const char *buffer, char *cmd, SequenceData *data) +{ + char filename[1024]; + if (sscanf(buffer, "%s%s", cmd, filename) != (unsigned int)2) + return 0; + + if (!ReadPlanePoses( data->depth_to_color, + data->plane_poses, + data->n_images, + filename ) ) + { + fprintf(stderr, "\nUnable to read plane_poses file %s\n", filename); + exit(-1); + return 0; + } + + return 1; +} + +int ParseNImagesCmd(const char *buffer, char *cmd, SequenceData *data) +{ + int n_images = 0; + if (sscanf(buffer, "%s%d", cmd, &n_images) != (unsigned int)2) + return 0; + + data->n_images = n_images; + + return 1; +} + +int ParseScanCmd(const char *buffer, char *cmd, SequenceData *data) +{ + char depth_name[1024], rgb_name[1024]; + float dummy[16]; + if (sscanf(buffer, "%s%s%s%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f", cmd, + depth_name, rgb_name, + &dummy[0], &dummy[1], &dummy[2], &dummy[3], + &dummy[4], &dummy[5], &dummy[6], &dummy[7], + &dummy[8], &dummy[9], &dummy[10], &dummy[11], + &dummy[12], &dummy[13], &dummy[14], &dummy[15]) != (unsigned int)19) + { + return 0; + } + + data->image_names.push_back(std::string(depth_name)); + return 1; +} + +int ReadConfigurationFile(SequenceData *data, const Options *opts) +{ + bsc::stop_watch timer; + timer.start(); + const char *configuration_filename = opts->configuration_filename.c_str(); + int n_read_scans = 0; + + // Open configuration file + FILE *configuration_fp = fopen(configuration_filename, "r"); + if (!configuration_fp) + { + fprintf(stderr, "Unable to open configuration file %s\n", + configuration_filename); + exit(-1); + return 0; + } + + if (opts->print_verbose) + { + printf("Reading configuration file...\n"); + } + + // Parse file + char buffer[1024]; + int line_number = 0; + + while (fgets(buffer, 1024, configuration_fp)) + { + char cmd[1024]; + line_number++; + bool success = 1; + if (sscanf(buffer, "%s", cmd) != (unsigned int)1) + continue; + + if (cmd[0] == '#') + continue; + + if (!strcmp(cmd, "parameters")) + { + success = ParseParametersCmd(buffer, cmd, data); + } + else if (!strcmp(cmd, "plane_poses")) + { + success = ParsePlanePosesCmd(buffer, cmd, data); + } + else if (!strcmp(cmd, "n_images")) + { + success = ParseNImagesCmd(buffer, cmd, data); + } + else if (!strcmp(cmd, "scan")) + { + success &= ParseScanCmd(buffer, cmd, data); + n_read_scans++; + } + } + fclose(configuration_fp); + + // Print statistics + if (opts->print_verbose) + { + printf(" # Images = %lu (%d)\n", data->image_names.size(), data->n_images); + printf("Done in %f sec\n\n", timer.elapsed() ); + } + + // Return success + return 1; +} + +//////////////////////////////////////////////////////////////////////////////// +// Drawing +//////////////////////////////////////////////////////////////////////////////// + +void update_pointcloud(const bsc::img_u16 *depth_image, + const bsc::img_u8 *color_image, + const bsc::mat3 &K, + bsc::geometry_data *p, + bool show_colors, + bsc::vec3 col, + bool bitshift ) +{ + i32 w = depth_image->width; + i32 h = depth_image->height; + + r32 scale = 1.0f; + if ( color_image != NULL ) + { + i32 ch = color_image->height; + scale = (r32) ch / h; + } + for (i32 j = 0; j < h; j++) + { + for (i32 i = 0; i < w; i++) + { + int idx = j * w + i; + uint16_t d = *depth_image->at(i, j); + if (bitshift) d = ((d >> 3) & 0x1FFF) | ((d & 0x7) << 13); + r32 depth = d * 0.001f; + + p->positions[3 * idx + 0] = ((i)-K[2][0]) * depth / K[0][0]; + p->positions[3 * idx + 1] = ((h-j)-K[2][1]) * depth / K[1][1]; + p->positions[3 * idx + 2] = -depth; + + if ( show_colors && color_image != NULL ) + { + const u8* cur_color = color_image->at(scale*i, scale*j); + p->colors_a[4 * idx + 0] = cur_color[0]; + p->colors_a[4 * idx + 1] = cur_color[1]; + p->colors_a[4 * idx + 2] = cur_color[2]; + p->colors_a[4 * idx + 3] = 255; + } + else + { + p->colors_a[4 * idx + 0] = col.r * 255; + p->colors_a[4 * idx + 1] = col.g * 255; + p->colors_a[4 * idx + 2] = col.b * 255; + p->colors_a[4 * idx + 3] = 255; + } + } + } +} + +void init_pointcloud(const bsc::img_u16 *depth_image, + const bsc::img_u8 *image, + const bsc::mat3 &K, + bsc::geometry_data *p, + bool bitshift ) +{ + i32 w = depth_image->width; + i32 h = depth_image->height; + + p->positions = (r32 *)calloc(w * h * 3, sizeof(r32)); + p->colors_a = (u8 *)calloc(w * h * 4, sizeof(u8)); + p->normals = (r32 *)calloc(w * h * 3, sizeof(r32)); + p->n_vertices = w * h; + + update_pointcloud(depth_image, + image, + K, + p, + true, bsc::vec3(1.0, 1.0, 1.0), + bitshift ); +} + +void init_axes(bsc::gpu_geometry *cmd) +{ + bsc::geometry_data axes; + float positions[18] = {0, 0, 0, + 1, 0, 0, + 0, 0, 0, + 0, 1, 0, + 0, 0, 0, + 0, 0, 1}; + u8 colors[24] = {255, 0, 0, 255, 255, 0, 0, 255, + 0, 255, 0, 255, 0, 255, 0, 255, + 0, 0, 255, 255, 0, 0, 255, 255}; + axes.positions = positions; + axes.colors_a = colors; + axes.n_vertices = 6; + + bsc::init_gpu_geo(&axes, cmd, POSITION | COLOR_A); +} + +void init_planes(bsc::gpu_geometry *cmds) +{ + float depths[6] = {0.5, 1, 2, 3, 4, 5}; + for (int i = 0; i < 6; ++i) + { + bsc::geometry_data plane; + plane.n_vertices = 4; + float positions[12] = {-0.64f * depths[i], -0.48f * depths[i], -depths[i], + 0.64f * depths[i], -0.48f * depths[i], -depths[i], + 0.64f * depths[i], 0.48f * depths[i], -depths[i], + -0.64f * depths[i], 0.48f * depths[i], -depths[i]}; + plane.positions = positions; + + bsc::init_gpu_geo(&plane, &(cmds[i]), POSITION); + } +} + +void init_grid(bsc::gpu_geometry *cmd) +{ + bsc::geometry_data grid; + grid.n_vertices = 34; + r32 positions[34 * 3]; + r32 width = 0.054f; + i32 idx = 0; + for (int row = 0; row < 10; ++row) + { + positions[idx + 0] = row * width; + positions[idx + 1] = 0; + positions[idx + 2] = 0; + + positions[idx + 3] = row * width; + positions[idx + 4] = -6 * width; + positions[idx + 5] = 0; + idx += 6; + } + + for (int col = 0; col < 7; ++col) + { + positions[idx + 0] = 0; + positions[idx + 1] = -col * width; + positions[idx + 2] = 0; + + positions[idx + 3] = 9 * width; + positions[idx + 4] = -col * width; + positions[idx + 5] = 0; + idx += 6; + } + + grid.positions = positions; + bsc::init_gpu_geo(&grid, cmd, POSITION); +} + +//////////////////////////////////////////////////////////////////////////////// +// Frame Conversion +//////////////////////////////////////////////////////////////////////////////// + +static float angle_threshold = 25.0f; + +void +ReportBinCounts( const SequenceData * seq_data, + const Options * opts ) +{ + i32 max_idx = opts->n_slices; + int z_bin = opts->n_slices / opts->max_depth; + i32 bin_counts[ 128 ] = {0}; + i32 total_count = 0; + std::vector bin_names[128]; + + r32 max_pairwise_dist = 0.0f; + + for ( size_t i = 0 ; + i < seq_data->plane_poses.size() ; + ++i ) + { + r32 angle = bsc::rad2deg( + bsc::angle( bsc::vec3( 0.0f, 0.0f, 1.0f ), + bsc::vec3( seq_data->plane_poses[i][2] ) ) ); + if ( angle < angle_threshold ) + { + r32 distance = -seq_data->plane_poses[i][3][2]; + if ( i > 0 ) + { + r32 pairwise_dist = distance + seq_data->plane_poses[i-1][3][2]; + if ( pairwise_dist > max_pairwise_dist ) + { + max_pairwise_dist = pairwise_dist; + } + } + i32 idx = distance * z_bin; + bin_counts[idx] += 1; + bin_names[idx].push_back( seq_data->image_names[i] ); + total_count++; + } + } + printf("Depth Bins: \n"); + for ( i32 i = 0 ; + i < max_idx; + i++ ) + { + r32 min_dist = i * (1.0f / z_bin); + r32 max_dist = (i + 1) * (1.0f / z_bin); + printf( "\tBin %3d (%5.3f - %5.3f) : %3d\n", i, min_dist, max_dist, bin_counts[i] ); + } + printf("Will use %d/%d images for calibration\n", total_count, + seq_data->n_images ); +} + +void +ApplyUndistortion( const SequenceData * seq_data, const Options * opts ) +{ + bsc::stop_watch timer; + if ( opts->print_verbose ) + { + printf("Applying undistortion volume\n"); + timer.read(); + } + + // extract relevant info + i32 w = 640; + i32 h = 480; + bsc::img_u16 raw_depth_im; + bsc::img_u16 depth_im( w, h, 1 ); + Grid3D undistort_table; + undistort_table.ReadFile( opts->applied_lut_filename.c_str() ); + i32 n_slices = undistort_table.ZRes(); + + r32 x_bin = w / undistort_table.XRes(); + r32 y_bin = h / undistort_table.YRes(); + r32 z_bin = undistort_table.ZRes() / undistort_table.MaxDist(); + + // check if depth folder exists + + #if defined(_WIN32) + _mkdir((const char*)"depth"); + #else + mkdir((const char*)"depth", 0775); // notice that 777 is different than 0777 + #endif + + // save out images + for (i32 im_idx = 0; + im_idx < seq_data->n_images; + im_idx++) + { + + if ( opts->print_verbose ) + { + float percentage = (float)(im_idx + 1) / seq_data->n_images * 100.0f; + printf("Progress %5.2f%% (%d/%d)\r", percentage, + im_idx + 1, + seq_data->n_images ); + fflush(stdout); + } + std::string im_name = seq_data->image_names[im_idx]; + int name_length = im_name.length(); + const char *img_name = im_name.substr(0, name_length - 4).c_str(); + char depth_name[256], depth_raw_name[256]; + sprintf( depth_raw_name, "depth_raw/%s.png", img_name ); + sprintf( depth_name, "depth/%s.png", img_name ); + raw_depth_im.read( depth_raw_name ); + + for ( i32 j = 0; j < h; ++j ) + { + for ( i32 i = 0; i < w; ++i ) + { + uint16_t d = *raw_depth_im(i, j); + if (opts->bitshift) d = ((d >> 3) & 0x1FFF) | ((d & 0x7) << 13); + r32 depth = d * 0.001f; + + r32 z_idx = std::min( (r32)depth * z_bin, (r32)n_slices - 1.0f ); + + r32 multiplier2 = 1.0f / undistort_table.GetValue( (float) i / x_bin, + (float) j / y_bin, + z_idx ); + r32 new_depth = depth * multiplier2; + uint16_t new_d = 1000.0f * new_depth; + if (opts->bitshift) new_d = ((new_d & 0xE000) >> 13) | ((new_d << 3) & 0xFFF8); + *depth_im(i, j) = new_d; + } + } + + depth_im.write( depth_name ) ; + } + if ( opts->print_verbose ) + { + printf("\nDone in %f sec.\n", timer.elapsed() ); + } +} + + +void EstimateDistortion(const SequenceData *seq_data, const Options *opts) +{ + + // Storage + useful variables + bsc::img_u16 raw_depth_im; + bsc::vec2 *train_data = (bsc::vec2 *)calloc( 640 * 480 * seq_data->n_images, + 2 * sizeof(r32)); + std::vector skipped; + skipped.reserve(100); + + bsc::stop_watch timer; + + + // Gather training data step + if ( opts->print_verbose ) + { + printf("\nGathering training data\n"); + timer.read(); + } + for (int im_idx = 0; + im_idx < seq_data->n_images; + ++im_idx) + { + + // Read in images + char depth_raw_name[256]; + const char *img_name = seq_data->image_names[im_idx].c_str(); + sprintf( depth_raw_name, "depth_raw/%s", img_name ); + raw_depth_im.read(depth_raw_name); + + // gather important info + i32 w = raw_depth_im.width; + i32 h = raw_depth_im.height; + bsc::mat4 T = seq_data->plane_poses[im_idx]; + bsc::mat3 K = seq_data->depth_intrinsics; + + // get plane equation + bsc::vec3 n(T[2]); + bsc::vec3 p(T[3]); + bsc::plane plane; + plane.n = n; + plane.d = -bsc::dot(n, p); + + // if image deviates from angle, lets skip it + r32 angle = bsc::rad2deg( bsc::angle( bsc::vec3( 0.0f, 0.0f, 1.0f ), n ) ); + r32 percentage = (float)(im_idx+1) / seq_data->n_images * 100.0f; + if ( angle > angle_threshold ) + { + skipped.push_back( im_idx ); + continue; + } + else + { + if ( opts->print_verbose ) + { + printf( "Progress : %5.2f%% (%d/%d)\r", percentage, + im_idx+1, + seq_data->n_images ); + fflush(stdout); + } + } + + // generate pointcloud + bsc::geometry_data input_pointcloud; + init_pointcloud(&raw_depth_im, NULL, + K, &input_pointcloud, + opts->bitshift); + + // gather the important training data + for (i32 j = 0; j < h; j++) + { + for (i32 i = 0; i < w; i++) + { + int idx = j * w + i; + bsc::vec3 pos; + bsc::vec3 normal; + + pos.x = input_pointcloud.positions[3 * idx + 0]; + pos.y = input_pointcloud.positions[3 * idx + 1]; + pos.z = input_pointcloud.positions[3 * idx + 2]; + + i8 is_valid = (-pos.z > 0.01); + + if (is_valid) + { + bsc::vec3 origin(0.0f, 0.0f, 0.0f); + bsc::vec3 v = pos - origin; + v = bsc::normalize(v); + + bsc::ray ray; + ray.o = origin; + ray.v = v; + + bsc::vec3 new_pos = bsc::intersect(ray, plane); + train_data[(w * h) * im_idx + idx].x = -pos.z; + train_data[(w * h) * im_idx + idx].y = -new_pos.z; + } + else + { + train_data[(w * h) * im_idx + idx].x = -pos.z; + train_data[(w * h) * im_idx + idx].y = -pos.z; + } + } + } + } + + // print info regarding finished process. + if ( opts->print_verbose ) + { + printf("\nDone in %f sec.\n", timer.elapsed() ); + if ( !skipped.empty() ) + { + printf("Skipped images: \n"); + for ( size_t idx = 0 ; idx < skipped.size() ; ++idx ) + { + const char *img_name = seq_data->image_names[ skipped[idx] ].c_str(); + printf("\t %s\n", img_name ); + } + } + printf("\nComputing undistortion LUT\n"); + timer.read(); + } + + // Training to volume conversion + i32 w = 640, h = 480; + r32 x_bin = 2; + r32 y_bin = 2; + r32 z_bin = opts->n_slices / opts->max_depth; + Grid3D accumulation( w / x_bin, h / y_bin, opts->n_slices, opts->max_depth ); + Grid3D divisor( w / x_bin, h / y_bin, opts->n_slices, opts->max_depth ); + + for (i32 im_idx = 0; + im_idx < seq_data->n_images; + im_idx++) + { + // we limit the borders as the normals there are bad + for (i32 j = 0; j < h; ++j) + { + for (i32 i = 0; i < w; ++i) + { + bsc::vec2 pair = train_data[(w * h) * im_idx + j * w + i]; + + i32 x = floor((r32)i / x_bin); + i32 y = floor((r32)j / y_bin); + i32 z = floor( pair.x * z_bin ); + + if ( z > opts->n_slices - 1 || z == 0.0 ) + { + continue; + } + else + { + r32 observed_depth = pair.x; + r32 real_depth = pair.y; + accumulation.Add(x, y, z, observed_depth * real_depth ); + divisor.Add(x, y, z, real_depth * real_depth ); + } + } + } + } + + // Compute the multiplier values + Grid3D multipliers( accumulation ); + multipliers.Divide( divisor ); + + // deal with side strip + int stripe_width = 8 / x_bin; + for (int z = 0; z < multipliers.ZRes(); ++z) + { + for (int y = 0; y < multipliers.YRes(); ++y) + { + float val = multipliers.GetValue( multipliers.XRes() - stripe_width - 1, y, z ); + for (int x = multipliers.XRes()-stripe_width; x < multipliers.XRes(); ++x ) + { + multipliers.SetValue( x, y, z, val ); + } + } + } + + // Replace unknowns -> This should be like a cross bilateral filter + for ( int i = 0 ; i < multipliers.NElements() ; ++i ) + { + if ( multipliers.GetValue(i) == UNKNOWN_GRID_VALUE ) + { + multipliers.SetValue( i, 1.0 ); + } + } + + multipliers.WriteFile( opts->estimated_lut_filename.c_str() ); + free(train_data); + + // Save slices for debugging + if ( opts->save_slice_visualization ) + { + if ( opts->print_verbose ) + { + printf( "Saving volume visualization!\n" ); + } + r32 min = multipliers.Min(); + r32 max = multipliers.Max(); + for (int i = 0; i < multipliers.ZRes(); ++i) + { + bsc::image slice( multipliers.XRes(), multipliers.YRes(), 1 ); + int n_entries = slice.width * slice.height; + for ( int j = 0 ; j < n_entries ; ++j) + { + *(slice( j )) = multipliers.GetValue( i * n_entries + j ); + } + bsc::img_u8 slice_img( slice.width, slice.height, 3 ); + if ( opts->print_verbose ) + { + printf( "\tSlice %3d -> Min: %5.4f Max %5.4f\n", + i, slice.minimum(), slice.maximum() ); + } + for ( int j = 0 ; j < n_entries ; ++j ) + { + r32 val = *slice( j ); + if ( val != UNKNOWN_GRID_VALUE ) + val = (val - min) / (max - min); + bsc::vec3 color( 1.0, 0.5, 0.0 ); + + if ( val != UNKNOWN_GRID_VALUE ) + { + color =bsc::vec3( 0.0, 0.0, 0.0 ); + if ( val < 0.5 ) + { + color[0] = 1.0 - 2.0 * val; + color[1] = 2.0 * val; + } + else + { + color[1] = 1 - 2 * (val - 0.5); + color[2] = 2 * (val - 0.5); + } + }; + u8 *pixel = slice_img( j % slice.width, + j / slice.width ); + pixel[0] = (u8)(color.r * 255.0f); + pixel[1] = (u8)(color.g * 255.0f); + pixel[2] = (u8)(color.b * 255.0f); + } + char name[256]; + sprintf( name, "slice_%03d.png", i ); + slice_img.write(name); + } + } + printf("Done in %f sec.\n", timer.elapsed() ); +} + +//////////////////////////////////////////////////////////////////////////////// +// Main functionality +//////////////////////////////////////////////////////////////////////////////// + +static bsc::camera cam; +static bsc::mat4 view; +static bsc::trackball_controls cam_controls; +static bsc::shader_prog debug_prog; +static bsc::shader_prog pointcloud_prog; +static bsc::shader_prog plane_prog; + +static bsc::gpu_geometry raw_pointcloud_cmd; +static bsc::gpu_geometry fixed_pointcloud_cmd; +static bsc::gpu_geometry axes_cmd; +static bsc::gpu_geometry grid_cmd; +static bsc::gpu_geometry planes_cmds[6]; + +static bsc::img_u16 raw_image; +static bsc::img_u16 fixed_image; +static bsc::img_u8 color_image; +static bsc::geometry_data raw_pointcloud; +static bsc::geometry_data fixed_pointcloud; + +static bool use_raw = 1; +static int cur_idx = 0; +static bool show_planes = 0; +static bool show_normals = 0; +static bool show_colors = 1; + +int Init() +{ + using namespace bsc; + + view = cam_controls.initialize( &cam, vec3f( 0.0f, 0.0f, 7.0f ), + vec3f( 0.0f, 0.0f, 0.0f ), + vec3f( 0.0f, 1.0f, 0.0f ) ); + + bsc::create_shader_prog_from_source(debug_vs, + debug_fs, + debug_prog); + bsc::create_shader_prog_from_source(plane_vs, + plane_fs, + plane_prog); + bsc::create_shader_prog_from_source(pointcloud_vs, + pointcloud_fs, + pointcloud_prog); + + // prepare the pointcloud data to draw on cpu + int name_length = seq_data.image_names[0].length(); + std::string base_name = seq_data.image_names[0].substr(0, name_length - 4); + + raw_image.read(("depth_raw/" + base_name + ".png").c_str()); + fixed_image.read(("depth/" + base_name + ".png").c_str()); + color_image.read(("color/" + base_name + ".jpg").c_str()); + + init_pointcloud(&raw_image, &color_image, + seq_data.depth_intrinsics, + &raw_pointcloud, opts.bitshift ); + init_pointcloud(&fixed_image, &color_image, + seq_data.depth_intrinsics, + &fixed_pointcloud, opts.bitshift ); + + // send it to gpu + bsc::init_gpu_geo(&raw_pointcloud, &raw_pointcloud_cmd, + POSITION | COLOR_A | NORMAL); + bsc::init_gpu_geo(&fixed_pointcloud, &fixed_pointcloud_cmd, + POSITION | COLOR_A | NORMAL); + + // TODO FIx point cloud initialization and the rest.. we dont need local geometry_data for axes or planes + init_axes(&axes_cmd); + init_grid(&grid_cmd); + init_planes(&planes_cmds[0]); + + return 1; +} + +int Display() +{ + using namespace bsc; + + bsc::clear_window(); + bsc::ui::begin_frame(); + + std::string raw_image_name = "depth_raw/" + seq_data.image_names[cur_idx]; + std::string fixed_image_name = "depth/" + seq_data.image_names[cur_idx]; + std::string color_image_name = "color/" + seq_data.image_names[cur_idx].substr(0, seq_data.image_names[cur_idx].size() - 3) + "jpg"; + + // User input + if (ui::is_key_pressed(ui::keys::key_s)) + { + use_raw = !use_raw; + } + + if (ui::is_key_pressed(ui::keys::key_n)) + { + show_normals = !show_normals; + } + + bool need_update = false; + if (ui::is_key_pressed(ui::keys::key_c)) + { + need_update = true; + show_colors = !show_colors; + } + + if (ui::is_key_pressed(ui::keys::key_a)) + { + cur_idx = std::max( 0, cur_idx - 1 ); + need_update = true; + } + + if (ui::is_key_pressed(ui::keys::key_d)) + { + cur_idx = std::min( cur_idx + 1, seq_data.n_images - 1 ); + need_update = true; + } + + if (ui::is_key_pressed(ui::keys::key_p)) + { + show_planes = !show_planes; + } + + if ( 1 ) + { + ImGui::SetNextWindowPos(ImVec2(0, 0)); + ImGui::Begin("TEST", NULL, ImVec2(380, -1), -1.0f, + ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings); + ImGui::Text("%s", color_image_name.c_str() ); + int selected_idx = cur_idx; + ImGui::SliderInt("Image Idx", &selected_idx, 0, seq_data.n_images - 1 ); + ImGui::PushButtonRepeat(true); + if ( ImGui::Button("<<", ImVec2(178, 18) ) ) + { + selected_idx = std::max( 0, cur_idx - 1 ); + } + ImGui::SameLine(); + if ( ImGui::Button(">>", ImVec2(178, 18) ) ) + { + selected_idx = std::min( cur_idx + 1, seq_data.n_images - 1 ); + } + ImGui::PopButtonRepeat(); + ImGui::Checkbox("Use Raw Data", &use_raw ); + ImGui::End(); + + if ( selected_idx != cur_idx ) + { + cur_idx = selected_idx; + need_update = true; + } + } + + if (need_update) + { + raw_image_name = "depth_raw/" + seq_data.image_names[cur_idx]; + fixed_image_name = "depth/" + seq_data.image_names[cur_idx]; + color_image_name = "color/" + seq_data.image_names[cur_idx].substr(0, seq_data.image_names[cur_idx].size() - 3) + "jpg"; + raw_image.read(raw_image_name.c_str()); + fixed_image.read(fixed_image_name.c_str()); + color_image.read(color_image_name.c_str()); + update_pointcloud(&raw_image, &color_image, + seq_data.depth_intrinsics, + &raw_pointcloud, show_colors, bsc::vec3( 214.0f / 255.0f, + 39.0f / 255.0f, + 40.0f / 255.0f), + opts.bitshift ); + update_pointcloud( &fixed_image, &color_image, + seq_data.depth_intrinsics, + &fixed_pointcloud, show_colors, bsc::vec3( 44.0f / 255.0f, + 160.0f / 255.0f, + 44.0f / 255.0f), + opts.bitshift ); + + bsc::update_gpu_geo(&raw_pointcloud, &raw_pointcloud_cmd, POSITION | COLOR_A | NORMAL); + bsc::update_gpu_geo(&fixed_pointcloud, &fixed_pointcloud_cmd, POSITION | COLOR_A | NORMAL); + } + + glEnable(GL_LINE_SMOOTH); + + // Update camera ( view matrix ) + cam_controls.update(&cam, &view, &bsc::g_window.viewport ); + + // viewport + projective transformation setup + glViewport(0, 0, g_window.fb_size.x, g_window.fb_size.y); + static r32 near = 0.1f; + static r32 far = 100.0f; + static r32 fovy = deg2rad(56.25f); + r32 aspect_ratio = (r32)g_window.size.x / (r32)g_window.size.y; + + mat4f projection = perspective(fovy, + aspect_ratio, + near, + far); + + // Setup some OpenGL options + glEnable(GL_DEPTH_TEST); + + mat4 vp = projection * view; + bsc::use_program(debug_prog); + bsc::set_uniform(debug_prog, "mvp", vp); + + bsc::draw(&axes_cmd, GL_LINES); + + if ( !seq_data.plane_poses.empty() ) + { + bsc::mat4 xform = seq_data.plane_poses[cur_idx]; + bsc::set_uniform(debug_prog, "mvp", vp * xform); + bsc::draw(&axes_cmd, GL_LINES); + bsc::draw(&grid_cmd, GL_LINES); + } + + bsc::use_program(pointcloud_prog); + bsc::set_uniform(pointcloud_prog, "mvp", vp); + bsc::set_uniform(pointcloud_prog, "show_normals", show_normals); + if (use_raw) + { + bsc::draw(&raw_pointcloud_cmd, GL_POINTS); + } + else + { + bsc::draw(&fixed_pointcloud_cmd, GL_POINTS); + } + + if (show_planes) + { + bsc::use_program(plane_prog); + bsc::set_uniform(plane_prog, "mvp", vp); + + bsc::vec4 colors[6] = {bsc::vec4(0.12, 0.46, 0.7, 0.5), + bsc::vec4(0.12, 0.46, 0.7, 0.5), + bsc::vec4(0.12, 0.46, 0.7, 0.5), + bsc::vec4(0.12, 0.46, 0.7, 0.5), + bsc::vec4(0.12, 0.46, 0.7, 0.5), + bsc::vec4(0.12, 0.46, 0.7, 0.5)}; + for (int i = 6; i >= 0; --i) + { + bsc::set_uniform(plane_prog, "color", colors[i]); + bsc::draw(&(planes_cmds[i]), GL_TRIANGLE_FAN); + } + } + + if ( 1 ) + { + ImGui::Render(); + } + + bsc::ui::end_frame(); + return 1; +} + +//////////////////////////////////////////////////////////////////////////////// +// Argument Parsing +//////////////////////////////////////////////////////////////////////////////// +static void +ParseArgs(int argc, char **argv) +{ + // Defaults + opts.max_depth = 5; + opts.n_slices = 15; + opts.bitshift = true; + + + bsc::arg_parse args; + args.name = "calibrate_depth"; + args.description = "Program used to estimate and apply " + "undistortion look-up-table."; + + args.add( bsc::argument("configuration_filename", + "Name of the configuration file", + &opts.configuration_filename ) ); + + args.add( bsc::argument( "-e", "--estimate_undistortion", + "Perform undistortion LUT estimation," + " and save it to a file", + &opts.estimated_lut_filename) ); + args.add( bsc::argument( "-a", "--apply_undistortion", + "Apply undistortion LUT to fix depth images", + &opts.applied_lut_filename) ); + + args.add( bsc::argument( "-d", "--max_depth", + "Maximum depth distance we are rectifying." + "Effectively maximum depth value stored in" + " undistortion LUT. In meters. (Default: 5m)", + &opts.max_depth ) ); + + // NOTE: Expose different resolution? + args.add( bsc::argument( "-s", "--n_slices", + "Number of slices along z-dimension of LUT." + "Effectively resolution of LUT in z", + &opts.n_slices ) ); + + args.add( bsc::argument( "-b", "--bitshift", + "Decide wheter a SUN3D circular-bitshift" + "should be performed", + &opts.bitshift, 1 ) ); + + args.add( bsc::argument( "-v", "--verbose", + "Output additional information", + &opts.print_verbose, 0 ) ); + + args.add( bsc::argument( "-l", "--slice_visualization", + "Save visualization of slices of LUT as images", + &opts.save_slice_visualization, 0 ) ); + + args.parse( argc, argv ); + +} + +int main(int argc, char **argv) +{ + ParseArgs( argc, argv ); + + ReadConfigurationFile( &seq_data, &opts ); + + if ( !opts.estimated_lut_filename.empty() ) + { + if ( opts.print_verbose ) + { + ReportBinCounts( &seq_data, &opts ); + } + EstimateDistortion( &seq_data, &opts ); + if ( opts.applied_lut_filename.empty() ) return 1; + } + + if ( !opts.applied_lut_filename.empty() ) + { + ApplyUndistortion( &seq_data, &opts ); + return 1; + } + + bsc::create_window("Calibration Results", 1024, 768, + bsc::vec3( 0.67, 0.67, 0.67), + bsc::vec3( 0.67, 0.97, 0.97)); + + bsc::set_init_funct(Init); + bsc::set_display_funct(Display); + + bsc::main_loop(); + + return 1; +} \ No newline at end of file diff --git a/CameraParameterEstimation/apps/calibrate_depth/src/grid3d.h b/CameraParameterEstimation/apps/calibrate_depth/src/grid3d.h new file mode 100644 index 0000000..5dcff56 --- /dev/null +++ b/CameraParameterEstimation/apps/calibrate_depth/src/grid3d.h @@ -0,0 +1,494 @@ +#pragma once + +#define UNKNOWN_GRID_VALUE -321 + +class Grid3D +{ + public: + Grid3D(); + Grid3D( int xRes, int yRes, int zRes, float maxDist ); + Grid3D( const Grid3D &other ); + Grid3D( const std::string &filename ); + ~Grid3D(); + + int XRes() const; + int YRes() const; + int ZRes() const; + int NElements() const; + float MaxDist() const; + + float GetValue( int i ) const; + float GetValue( int x, int y, int z) const; + float GetValue( float x, float y, float z) const; + void SetValue( int i, float val ); + void SetValue( int x, int y, int z, float val ); + + void Add( const float val ); + void Add( int x, int y, int z, float val ); + void Add( const Grid3D &other ); + + void Multiply( const float val ); + void Multiply( int x, int y, int z, float val ); + void Multiply( const Grid3D &other ); + + void Divide( const float val ); + void Divide( int x, int y, int z, float val ); + void Divide( const Grid3D &other ); + + float Min() const; + float Max() const; + + void InvertElements(); + + int ReadFile( const std::string &filename ); + int WriteFile( const std::string &filename ) const; + + private: + int m_xRes; + int m_yRes; + int m_zRes; + float m_maxDist; + + float * m_data; + + int ToIndex( int x, int y, int z ) const; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// Implementation +//////////////////////////////////////////////////////////////////////////////// + +Grid3D:: +Grid3D() +{ + m_xRes = -1; + m_yRes = -1; + m_zRes = -1; + m_maxDist = -1; + + m_data = nullptr; +} + +Grid3D:: +Grid3D( int xRes, int yRes, int zRes, float maxDist ) +{ + m_xRes = xRes; + m_yRes = yRes; + m_zRes = zRes; + m_maxDist = maxDist; + + int nElements = NElements(); + m_data = new float[ nElements ]; + for ( int i = 0 ; i < nElements ; ++i ) + { + m_data[ i ] = 0.0f; + } +} + +Grid3D:: +Grid3D( const Grid3D &other ) +{ + m_xRes = other.XRes(); + m_yRes = other.YRes(); + m_zRes = other.ZRes(); + m_maxDist = other.MaxDist(); + + int nElements = NElements(); + m_data = new float[ nElements ]; + for ( int i = 0 ; i < nElements ; ++i ) + { + m_data[ i ] = other.GetValue( i ); + } +} + +Grid3D:: +Grid3D( const std::string &filename ) +{ + ReadFile( filename ); +} + +Grid3D:: +~Grid3D() +{ + if ( m_data != nullptr ) + { + delete[] m_data; + m_data = nullptr; + } + m_xRes = -1; + m_yRes = -1; + m_zRes = -1; + m_maxDist = -1; +} + +int Grid3D:: +ToIndex( int x, int y, int z) const +{ + return (z * m_xRes * m_yRes) + (y * m_xRes) + x; +} + +int Grid3D:: +XRes() const +{ + return m_xRes; +} + +int Grid3D:: +YRes() const +{ + return m_yRes; +} + +int Grid3D:: +ZRes() const +{ + return m_zRes; +} + +int Grid3D:: +NElements() const +{ + return m_xRes * m_yRes * m_zRes; +} + +float Grid3D:: +MaxDist() const +{ + return m_maxDist; +} + +float Grid3D:: +GetValue( int i ) const +{ + assert( i >= 0 && i < NElements() ); + return m_data[ i ]; +} + +float Grid3D:: +GetValue( int x, int y, int z ) const +{ + assert( x >= 0 && x < m_xRes ); + assert( y >= 0 && y < m_yRes ); + assert( z >= 0 && z < m_zRes ); + return m_data[ ToIndex( x, y, z ) ]; +} + +float Grid3D:: +GetValue( float x, float y, float z ) const +{ + assert( x >= 0 && x < m_xRes ); + assert( y >= 0 && y < m_yRes ); + assert( z >= 0 && z < m_zRes ); + + int x1 = (int)x; + int y1 = (int)y; + int z1 = (int)z; + int x2 = x1 + 1; + int y2 = y1 + 1; + int z2 = z1 + 1; + if ( x2 >= m_xRes ) x2 = x1; + if ( y2 >= m_yRes ) y2 = y1; + if ( z2 >= m_zRes ) z2 = z1; + float dx = x - x1; + float dy = y - y1; + float dz = z - z1; + + float value = 0.0f; + value += GetValue( x1, y1, z1 ) * (1.0f-dx) * (1.0f-dy) * (1.0f-dz); + value += GetValue( x1, y1, z2 ) * (1.0f-dx) * (1.0f-dy) * dz; + value += GetValue( x1, y2, z1 ) * (1.0f-dx) * dy * (1.0f-dz); + value += GetValue( x1, y2, z2 ) * (1.0f-dx) * dy * dz; + + value += GetValue( x2, y1, z1 ) * dx * (1.0f-dy) * (1.0f-dz); + value += GetValue( x2, y1, z2 ) * dx * (1.0f-dy) * dz; + value += GetValue( x2, y2, z1 ) * dx * dy * (1.0f-dz); + value += GetValue( x2, y2, z2 ) * dx * dy * dz; + + return value; +} + +void Grid3D:: +SetValue( int i, float val ) +{ + assert( i >= 0 && i < NElements() ); + + m_data[ i ] = val; +} + +void Grid3D:: +SetValue( int x, int y, int z, float val ) +{ + assert( x >= 0 && x < m_xRes ); + assert( y >= 0 && y < m_yRes ); + assert( z >= 0 && z < m_zRes ); + + m_data[ ToIndex( x, y, z ) ] = val; +} + +void Grid3D:: +Add( const float val ) +{ + int nElements = NElements(); + for ( int i = 0 ; i < nElements ; ++i ) + { + if ( m_data[i] != UNKNOWN_GRID_VALUE ) + m_data[ i ] += val; + } +} + +void Grid3D:: +Add( int x, int y, int z, float val ) +{ + assert( x >= 0 && x < m_xRes ); + assert( y >= 0 && y < m_yRes ); + assert( z >= 0 && z < m_zRes ); + int i = ToIndex( x, y, z ); + if ( m_data[i] != UNKNOWN_GRID_VALUE ) + { + m_data[i] += val; + } +} + +void Grid3D:: +Add( const Grid3D &other ) +{ + assert( other.XRes() == m_xRes ); + assert( other.YRes() == m_yRes ); + assert( other.ZRes() == m_zRes ); + + int nElements = NElements(); + for ( int i = 0 ; i < nElements ; ++i ) + { + if ( m_data[i] != UNKNOWN_GRID_VALUE && + other.GetValue(i) != UNKNOWN_GRID_VALUE ) + { + m_data[ i ] += other.GetValue( i ); + } + } +} + +void Grid3D:: +Multiply( const float val ) +{ + int nElements = NElements(); + for ( int i = 0 ; i < nElements ; ++i ) + { + if ( m_data[i] != UNKNOWN_GRID_VALUE ) + { + m_data[ i ] *= val; + } + } +} + +void Grid3D:: +Multiply( int x, int y, int z, float val ) +{ + assert( x >= 0 && x < m_xRes ); + assert( y >= 0 && y < m_yRes ); + assert( z >= 0 && z < m_zRes ); + int i = ToIndex( x, y, z ); + if ( m_data[i] != UNKNOWN_GRID_VALUE ) + { + m_data[ i ] *= val; + } +} + +void Grid3D:: +Multiply( const Grid3D &other ) +{ + assert( other.XRes() == m_xRes ); + assert( other.YRes() == m_yRes ); + assert( other.ZRes() == m_zRes ); + + int nElements = NElements(); + for ( int i = 0 ; i < nElements ; ++i ) + { + if ( m_data[i] != UNKNOWN_GRID_VALUE && + other.GetValue(i) != UNKNOWN_GRID_VALUE ) + { + m_data[ i ] *= other.GetValue( i ); + } + } +} + +void Grid3D:: +Divide( const float val ) +{ + if ( val == 0.0f ) return; + + int nElements = NElements(); + for ( int i = 0 ; i < nElements ; ++i ) + { + if ( m_data[i] != UNKNOWN_GRID_VALUE ) + { + m_data[ i ] /= val; + } + } +} + +void Grid3D:: +Divide( int x, int y, int z, float val ) +{ + if ( val == 0.0f ) return; + assert( x >= 0 && x < m_xRes ); + assert( y >= 0 && y < m_yRes ); + assert( z >= 0 && z < m_zRes ); + + int i = ToIndex( x, y, z ); + if ( m_data[i] != UNKNOWN_GRID_VALUE ) + { + m_data[ i ] /= val; + } +} + +void Grid3D:: +Divide( const Grid3D &other ) +{ + assert( other.XRes() == m_xRes ); + assert( other.YRes() == m_yRes ); + assert( other.ZRes() == m_zRes ); + + int nElements = NElements(); + for ( int i = 0 ; i < nElements ; ++i ) + { + if ( other.GetValue( i ) == 0.0f ) // dont divide by zero. + { + m_data[i] = UNKNOWN_GRID_VALUE; + continue; + } + + if ( m_data[i] != UNKNOWN_GRID_VALUE && + other.GetValue(i) != UNKNOWN_GRID_VALUE ) + { + m_data[ i ] /= other.GetValue( i ); + } + } +} + +void Grid3D:: +InvertElements() +{ + int nElements = NElements(); + for ( int i = 0 ; i < nElements ; ++i ) + { + if ( m_data[i] == 0.0f ) // dont divide by zero. + { + m_data[i] = UNKNOWN_GRID_VALUE; + continue; + } + + if ( m_data[i] != UNKNOWN_GRID_VALUE ) + { + m_data[ i ] = 1.0f / m_data[ i ]; + } + } +} + +float Grid3D:: +Min() const +{ + float min = 1e9; + int nElements = NElements(); + for ( int i = 0 ; i < nElements ; ++i ) + { + if ( m_data[i] != UNKNOWN_GRID_VALUE && + m_data[i] < min ) + { + min = m_data[i]; + } + } + return min; +} + +float Grid3D:: +Max() const +{ + float max = -1e9; + int nElements = NElements(); + for ( int i = 0 ; i < nElements ; ++i ) + { + if ( m_data[i] != UNKNOWN_GRID_VALUE && + m_data[i] > max ) + { + max = m_data[i]; + } + } + return max; +} + +int Grid3D:: +ReadFile( const std::string &filename ) +{ + // clear old data + if ( m_data != nullptr ) + { + delete[] m_data; + m_data = nullptr; + } + + // open file + FILE * fp = fopen( filename.c_str(), "rb" ); + if ( !fp ) + { + printf("Could not open file %s for reading!\n", filename.c_str() ); + return 0; + } + + // read in header + int res[3]; + if (fread( res, sizeof(int), 3, fp) != 3) { + printf("Unable to read resolution from file %s\n", filename.c_str() ); + return 0; + } + m_xRes = res[0]; + m_yRes = res[1]; + m_zRes = res[2]; + + if (fread( &m_maxDist, sizeof(float), 1, fp) != 1) { + printf("Unable to read max. distance from file %s\n", filename.c_str() ); + return 0; + } + + // allocate and read data + size_t nElements = NElements(); + m_data = new float[ nElements ]; + if ( fread( &(m_data[0]), sizeof(float), nElements, fp) != nElements ) { + printf("Unable to read grid values from file %s\n", filename.c_str() ); + return 0; + } + + return -1; +} + +int Grid3D:: +WriteFile( const std::string &filename ) const +{ + FILE * fp = fopen( filename.c_str(), "wb" ); + if ( !fp ) + { + printf("Could not open file %s for writing!\n", filename.c_str() ); + return 0; + } + + if ( fwrite( &m_xRes, sizeof(int), 3, fp ) != 3) { + printf("Unable to write resolution to file %s\n", filename.c_str() ); + return 0; + } + + if ( fwrite( &m_maxDist, sizeof(float), 1, fp ) != 1) { + printf("Unable to write maximum distance to file %s\n", filename.c_str() ); + return 0; + } + + const size_t nElements = NElements(); + size_t test = fwrite( &(m_data[0]), sizeof(float), nElements, fp); + if ( test != nElements ) { + printf("Unable to write grid values to file %s\n", filename.c_str() ); + return 0; + } + + fclose(fp); + + return 1; +} \ No newline at end of file diff --git a/CameraParameterEstimation/apps/calibrate_depth/src/makefile b/CameraParameterEstimation/apps/calibrate_depth/src/makefile new file mode 100644 index 0000000..a0d9e54 --- /dev/null +++ b/CameraParameterEstimation/apps/calibrate_depth/src/makefile @@ -0,0 +1,43 @@ +# Executable name +EXE_NAME = calibrate_depth + +# Useful Directories +BIN_DIR = ../../../bin/ +LIB_DIR = /usr/local/lib +OUT_DIR = ../out/ +BSC_DIR = ../../basics/ +IMGUI_DIR = $(BSC_DIR)extern/imgui/ + + +# List of source files +SRCS =calibrate_depth.cpp $(IMGUI_DIR)imgui.cpp $(IMGUI_DIR)imgui_draw.cpp +OBJS = $(SRCS:%.cpp=$(OUT_DIR)%.o) + +# Compile and link options +CC = g++ +WARNINGS = -Wall +CPPFLAGS = -std=c++11 -O -I. -I/usr/local/include -I$(IMGUI_DIR) -I$(BSC_DIR) + +# Libraries +LIBS = -L$(LIB_DIR) -lglew -lglfw3 + +# Frameworks +FRAMEWORKS = -framework OpenGL -framework GLUT + +# Make targets +all: clean calibrate_depth + +calibrate_depth: $(OBJS) + $(CC) $(FRAMEWORKS) $(CPPFLAGS) $(OBJS) $(LIBS) -o ${BIN_DIR}${EXE_NAME} + +clean: + rm -f $(OUT_DIR)*.a $(OUT_DIR)*.o ${BIN_DIR}${EXE_NAME} ${BIN_DIR}${EXE_NAME}.exe + + +# Compile command +$(OUT_DIR)%.o: %.cpp + $(CC) $(WARNINGS) $(CPPFLAGS) -c $< -o $@ + + +# GNU Make: targets that don't build files +.PHONY: all clean diff --git a/CameraParameterEstimation/apps/calibration_explorer/src/calibration_explorer.cpp b/CameraParameterEstimation/apps/calibration_explorer/src/calibration_explorer.cpp new file mode 100644 index 0000000..e411e96 --- /dev/null +++ b/CameraParameterEstimation/apps/calibration_explorer/src/calibration_explorer.cpp @@ -0,0 +1,820 @@ +#define BSC_IMPLEMENTATION +#define BSC_USE_IMGUI +#define BSC_USE_WINDOW +#include "basics.h" + +//////////////////////////////////////////////////////////////////////////////// +// GLOBAL STATE +//////////////////////////////////////////////////////////////////////////////// + +struct Options +{ + char * color_filename; + char * depth_filename; + char * input_parameter_filename; + char * output_parameter_filename; +}; + +struct CameraParams +{ + bsc::mat3 cK, dK; + bsc::mat4 d2c_T; + bsc::vec2i c_size; + bsc::vec2i d_size; + r32 dc[5], cc[5]; +}; + +enum ViewMode +{ + IMAGE_MODE, + POINTCLOUD_MODE +}; + +static ViewMode view_mode; + +static Options opts; +static CameraParams cam_params; +static CameraParams init_cam_params; +static r32 alpha = 0.5f; + +static bsc::img color_img; +static bsc::img_u16 depth_img; +static bsc::img undistorted_color_img; +static bsc::img_u16 undistorted_depth_img; +static bsc::img_u16 registered_depth_img; + +static bsc::gpu_geometry pointcloud_geo; +static bsc::mat4 view; +static bsc::mat4 proj; +static bsc::camera cam; +static bsc::trackball_controls cam_controls; + +static bsc::gpu_texture color_tex; +static bsc::gpu_texture depth_tex; + +static bsc::shader_prog explorer_shader; +static bsc::shader_prog pointcloud_shader; +static i32 panel_width = 400; +static bool use_bitshift = false; +//////////////////////////////////////////////////////////////////////////////// +// GPU CODE +//////////////////////////////////////////////////////////////////////////////// + +// vertex shader ( full screen quad by Morgan McGuire) +char* vs_image = (char*) SHADER_HEAD STR +( + out vec2 v_texcoords; + void main() + { + uint idx = uint( gl_VertexID % 3 ); + gl_Position = vec4( + (float( idx & 1U ) ) * 4.0 - 1.0, + (float( ( idx >> 1U )& 1U ) ) * 4.0 - 1.0, + 0.0, 1.0); + v_texcoords = gl_Position.xy * 0.5 + 0.5; + } +); + +char* fs_image = (char*) SHADER_HEAD STR +( + uniform sampler2D color_tex; + uniform sampler2D depth_tex; + + in vec2 v_texcoords; + uniform float alpha; + + out vec4 frag_color; + + void main() + { + vec2 flipped_coord = vec2( v_texcoords.x, + 1.0 - v_texcoords.y ); + + vec3 color = texture( color_tex, flipped_coord ).rgb; + float depth = texture( depth_tex, flipped_coord ).r * 8; + vec3 d = vec3(depth); + frag_color = vec4( alpha * d + (1-alpha) * color, 1.0 ); + } +); + +char *vs_pointcloud = (char *)SHADER_HEAD STR( + layout(location = 0) in vec3 position; + layout(location = 4) in vec4 color_a; + uniform mat4 mvp; + uniform float point_size; + out vec4 v_color; + + void main() { + gl_Position = mvp * vec4(position, 1.0); + gl_PointSize = point_size; + + v_color = vec4(color_a.rgb, 1.0f); + }); + +char *fs_pointcloud = (char *)SHADER_HEAD STR( + in vec4 v_color; + out vec4 frag_color; + void main() + { + // cute hack of round points + vec2 coord = gl_PointCoord - vec2(0.5); //from [0,1] to [-0.5,0.5] + if(length(coord) > 0.5) //outside of circle radius? + discard; + frag_color = v_color; + }); + +//////////////////////////////////////////////////////////////////////////////// +// CPU CODE +//////////////////////////////////////////////////////////////////////////////// + +void +render_explorer_image( r32 alpha, char * vs_src, char * fs_src ) +{ + static GLuint exploerer_vao = 0; + + if (exploerer_vao == 0) + { + glGenVertexArrays(1, &exploerer_vao); + + bsc::create_shader_prog_from_source( vs_src, fs_src, explorer_shader ); + } + + bsc::use_program( explorer_shader ); + bsc::set_uniform( explorer_shader, "color_tex", 1 ); + bsc::set_uniform( explorer_shader, "depth_tex", 2 ); + bsc::set_uniform( explorer_shader, "alpha", alpha ); + glBindVertexArray( exploerer_vao ); + glDrawArrays(GL_TRIANGLES, 0, 3); + + glBindVertexArray(0); +} + +void +generate_pointcloud_data( bsc::geometry_data & pointcloud_data, + const bsc::img * color_image, + const bsc::img_u16 *depth_image, + const bsc::mat3 K ) +{ + using namespace bsc; + u32 n_pos = depth_image->width * depth_image->height; + vec3 * positions = (vec3*)malloc( n_pos * sizeof(vec3) ); + vector4 * colors = (vector4*)malloc( n_pos * sizeof(vector4) ); + + r32 scale = (r32)color_image->height / depth_image->height; + + i32 pos_idx = 0, col_idx = 0; + for ( i32 y = 0 ; y < depth_image->height ; y++ ) + { + for ( i32 x = 0 ; x < depth_image->width ; x++ ) + { + u16 depth = *(depth_image->at(x,y)); + const u8 * rgb = color_image->at( scale * x, scale * y ); + if ( depth == 0 ) {continue;} + if ( rgb[0] == 0 && rgb[1] == 0 && rgb[2] == 0 ) {continue;} + r32 d = depth * 0.001f; + + vec3 pos; + pos.x = ((x - 2.025 * K[2][0]) * d) / (2.025 * K[0][0]); + pos.y = ((y - 2.025 * K[2][1]) * d) / (2.025 * K[1][1]); + pos.z = d; + positions[ pos_idx++ ] = pos; + + vector4 color; + color.r = rgb[0]; + color.g = rgb[1]; + color.b = rgb[2]; + color.a = 255; + colors[ col_idx++ ] = color; + } + } + + pointcloud_data.positions = &(positions[0].x); + pointcloud_data.colors_a = &(colors[0].r); + pointcloud_data.n_vertices = col_idx; +} + +void +create_3d_pointcloud ( bsc::gpu_geometry *pointcloud_geo, + const bsc::img * color_image, + const bsc::img_u16 *depth_image, + const bsc::mat3 K, + bool first ) +{ + using namespace bsc; + geometry_data pointcloud_data; + + generate_pointcloud_data( pointcloud_data, color_image, depth_image, K ); + + if ( first ) + { + init_gpu_geo( &pointcloud_data, pointcloud_geo, POSITION | COLOR_A ); + } + else + { + update_gpu_geo( &pointcloud_data, pointcloud_geo, POSITION | COLOR_A ); + } + free( pointcloud_data.colors_a ); + free( pointcloud_data.positions ); +} + +void +render_explorer_pointcloud( bsc::gpu_geometry *pointcloud_geo, + const bsc::img *color_image, + const bsc::img_u16 *depth_image, + const bsc::mat3 K, + bool should_update, + char * vs_src, char * fs_src ) +{ + if ( pointcloud_geo->vao == -1 ) + { + create_3d_pointcloud( pointcloud_geo, color_image, depth_image, K, true ); + bsc::create_shader_prog_from_source( vs_src, fs_src, pointcloud_shader ); + } + + glEnable(GL_PROGRAM_POINT_SIZE); + + if ( should_update ) + { + create_3d_pointcloud( pointcloud_geo, color_image, depth_image, K, false ); + } + + bsc::use_program( pointcloud_shader ); + bsc::set_uniform( pointcloud_shader, "mvp", proj * view ); + bsc::set_uniform( pointcloud_shader, "point_size", 3.0f ); + bsc::draw( pointcloud_geo, GL_POINTS ); +} + +bool +is_valid( bsc::vec2 loc, bsc::vec2 size ) +{ + return ( loc.x >= 0 && loc.x < size.x && loc.y >= 0 && loc.y < size.y ); +} + +template +void +undistort ( const bsc::image *src, + bsc::image *dst, + bsc::mat3 K, + r32 coeff[5] ) +{ + using namespace bsc; + + for ( i32 y = 0 ; y < src->height ; y++ ) + { + for ( i32 x = 0 ; x < src->width ; x++ ) + { + vec2 nic_loc; + vec2 sample_loc; + + //Normalized image coords + nic_loc.x = ( (x+0.5) - K[2][0]) / K[0][0]; + nic_loc.y = ( (y+0.5) - K[2][1]) / K[1][1]; + + float r2 = nic_loc.x * nic_loc.x + nic_loc.y * nic_loc.y; + + // Radial distortion + sample_loc.x = nic_loc.x * (1.0f + r2 * coeff[0] + r2*r2 * coeff[1] + r2*r2*r2 * coeff[4] ); + sample_loc.y = nic_loc.y * (1.0f + r2 * coeff[0] + r2*r2 * coeff[1] + r2*r2*r2 * coeff[4] ); + + // Tangential distortion + sample_loc.x += 2.0f * coeff[2] * nic_loc.x * nic_loc.y + coeff[3] * ( r2 + 2.0f * nic_loc.x * nic_loc.x ); + sample_loc.y += coeff[2] * ( r2 + 2.0f * nic_loc.y * nic_loc.y ) + 2.0f * coeff[3] * nic_loc.x * nic_loc.y ; + + // Move back to the image space + sample_loc.x = sample_loc.x * K[0][0] + K[2][0]; + sample_loc.y = sample_loc.y * K[1][1] + K[2][1]; + + if ( is_valid ( sample_loc, bsc::vec2( dst->width, dst->height ) ) ) + { + const T * src_ptr = src->at( sample_loc.x, sample_loc.y ); + T * dst_ptr = dst->at( x, y ); + for ( i32 n = 0 ; n < src->ncomp ; ++n ) + { + dst_ptr[n] = src_ptr[n]; + } + // *(dst->at( x, y )) = *(src->at( sample_loc.x, sample_loc.y )); + } + } + } +} + + +void +splat( bsc::img_u16 * image, bsc::vec2 coord, u16 value ) +{ + coord.x = round(coord.x); + coord.y = round(coord.y); + + i32 splat_rad = 1; + for ( i32 oy = -splat_rad ; oy <= splat_rad ; ++oy ) + { + for ( i32 ox= -splat_rad ; ox <= splat_rad ; ++ox ) + { + if ( *(image->at( coord.x + ox, coord.y + oy )) == 0 ) + *(image->at( coord.x + ox, coord.y + oy )) = value; + else if ( *(image->at( coord.x + ox, coord.y + oy ) ) > value ) + *(image->at( coord.x + ox, coord.y + oy ) ) = value; + } + } +} + +void +transform_img ( const bsc::img_u16 *src, + bsc::img_u16 *dst, + CameraParams * cam_params ) +{ + using namespace bsc; + + // extract useful data + mat4 T = cam_params->d2c_T; + // Switches - from the d2d to our + mat4 C1; + C1[1][1] = -1; + C1[2][2] = -1; + T = C1 * T * C1; + // image origin at the top + mat4 C2; + C2[1][1] = -1; + T = C2 * T * C2; + + + mat3 dK = cam_params->dK; + mat3 cK = cam_params->cK; + + // imitialize positions + u32 n_pos = src->width * src->height; + u32 size = n_pos * sizeof(bsc::vec3); + vec3 * positions = (vec3*)malloc(size); + memset( positions, 0, size ); + + // backproject + for ( i32 y = 0 ; y < src->height ; y++ ) + { + for ( i32 x = 0 ; x < src->width ; x++ ) + { + u16 depth = *(src->at(x,y)); + if ( depth == 0 ) {continue;} + r32 d = depth * 0.001f; + + vec3 pos; + pos.x = ((x - dK[2][0]) * d) / dK[0][0]; + pos.y = ((y - dK[2][1]) * d) / dK[1][1]; + pos.z = -d; + positions[ y * src->width + x] = pos; + } + } + + // transform + for ( size_t pos_idx = 0 ; pos_idx < n_pos ; ++pos_idx ) + { + vec3 pos = positions[ pos_idx ]; + + if ( pos == vec3( 0.0f, 0.0f, 0.0f ) ) { continue; } + vec4 homogenous_pos = vec4( pos, 1.0f ); + homogenous_pos = T * homogenous_pos; + positions[pos_idx] = vec3( homogenous_pos ); + } + + // project back + for ( i32 y = 0 ; y < src->height ; y++ ) + { + for ( i32 x = 0 ; x < src->width ; x++ ) + { + vec3 pos = positions[ y * src->width + x]; + if ( pos == vec3( 0.0f, 0.0f, 0.0f ) ) { continue; } + + vec3 projected_pos;// = cK * pos; + // projected_pos.x /= projected_pos.z; + // projected_pos.y /= projected_pos.z; + projected_pos.x = cK[2][0] + pos.x * cK[0][0] / -pos.z; + projected_pos.y = cK[2][1] + pos.y * cK[1][1] / -pos.z; + projected_pos.z = pos.z; + // if ( x < 10 && y <10) + // { + // print_vec3( projected_pos ); + // } + + if ( is_valid( projected_pos, bsc::vec2(dst->width, dst->height) ) ) + { + splat( dst, projected_pos, (u16)( -projected_pos.z * 1000.0f) ); + } + } + } + + free(positions); +} +i32 +read_parameters( const char * filename, CameraParams * cam_params ) +{ + FILE * f = fopen( filename, "r" ); + if ( f ) + { + fscanf( f, "colorWidth = %d\n", &(cam_params->c_size.x) ); + fscanf( f, "colorHeight = %d\n", &(cam_params->c_size.y)); + fscanf( f, "depthWidth = %d\n", &(cam_params->d_size.x)); + fscanf( f, "depthHeight = %d\n", &(cam_params->d_size.y)); + fscanf( f, "fx_color = %f\n", &(cam_params->cK[0][0]) ); + fscanf( f, "fy_color = %f\n", &(cam_params->cK[1][1]) ); + fscanf( f, "mx_color = %f\n", &(cam_params->cK[2][0]) ); + fscanf( f, "my_color = %f\n", &(cam_params->cK[2][1]) ); + fscanf( f, "fx_depth = %f\n", &(cam_params->dK[0][0]) ); + fscanf( f, "fy_depth = %f\n", &(cam_params->dK[1][1]) ); + fscanf( f, "mx_depth = %f\n", &(cam_params->dK[2][0]) ); + fscanf( f, "my_depth = %f\n", &(cam_params->dK[2][1]) ); + fscanf( f, "k1_color = %f\n", &cam_params->cc[0] ); + fscanf( f, "k2_color = %f\n", &cam_params->cc[1] ); + fscanf( f, "k3_color = %f\n", &cam_params->cc[2] ); + fscanf( f, "k4_color = %f\n", &cam_params->cc[3] ); + fscanf( f, "k5_color = %f\n", &cam_params->cc[4] ); + fscanf( f, "k1_depth = %f\n", &cam_params->dc[0] ); + fscanf( f, "k2_depth = %f\n", &cam_params->dc[1] ); + fscanf( f, "k3_depth = %f\n", &cam_params->dc[2] ); + fscanf( f, "k4_depth = %f\n", &cam_params->dc[3] ); + fscanf( f, "k5_depth = %f\n", &cam_params->dc[4] ); + bsc::mat4f m; + fscanf( f, "depthToColorExtrinsics = %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n", + &(m[0][0]), &(m[1][0]), &(m[2][0]), &(m[3][0]), + &(m[0][1]), &(m[1][1]), &(m[2][1]), &(m[3][1]), + &(m[0][2]), &(m[1][2]), &(m[2][2]), &(m[3][2]), + &(m[0][3]), &(m[1][3]), &(m[2][3]), &(m[3][3]) ); + cam_params->d2c_T = m; + fclose(f); + return 1; + } + else + { + printf("Unable to open files %s\n", filename ); + return 0; + } +} + +i32 +write_parameters( const char * filename, const CameraParams * cam_params ) +{ + FILE * f = fopen( filename, "w" ); + if ( f ) + { + fprintf( f, "colorWidth = %d\n", cam_params->c_size.x); + fprintf( f, "colorHeight = %d\n", cam_params->c_size.y); + fprintf( f, "depthWidth = %d\n", cam_params->d_size.x); + fprintf( f, "depthHeight = %d\n", cam_params->d_size.y); + fprintf( f, "fx_color = %f\n", cam_params->cK[0][0] ); + fprintf( f, "fy_color = %f\n", cam_params->cK[1][1] ); + fprintf( f, "mx_color = %f\n", cam_params->cK[2][0] ); + fprintf( f, "my_color = %f\n", cam_params->cK[2][1] ); + fprintf( f, "fx_depth = %f\n", cam_params->dK[0][0] ); + fprintf( f, "fy_depth = %f\n", cam_params->dK[1][1] ); + fprintf( f, "mx_depth = %f\n", cam_params->dK[2][0] ); + fprintf( f, "my_depth = %f\n", cam_params->dK[2][1] ); + fprintf( f, "k1_color = %f\n", cam_params->cc[0] ); + fprintf( f, "k2_color = %f\n", cam_params->cc[1] ); + fprintf( f, "k3_color = %f\n", cam_params->cc[2] ); + fprintf( f, "k4_color = %f\n", cam_params->cc[3] ); + fprintf( f, "k5_color = %f\n", cam_params->cc[4] ); + fprintf( f, "k1_depth = %f\n", cam_params->dc[0] ); + fprintf( f, "k2_depth = %f\n", cam_params->dc[1] ); + fprintf( f, "k3_depth = %f\n", cam_params->dc[2] ); + fprintf( f, "k4_depth = %f\n", cam_params->dc[3] ); + fprintf( f, "k5_depth = %f\n", cam_params->dc[4] ); + bsc::mat4f m = cam_params->d2c_T; + fprintf( f, "depthToColorExtrinsics = %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n", + m[0][0], m[1][0], m[2][0], m[3][0], + m[0][1], m[1][1], m[2][1], m[3][1], + m[0][2], m[1][2], m[2][2], m[3][2], + m[0][3], m[1][3], m[2][3], m[3][3] ); + fclose(f); + return 1; + } + return 0; +} + +i32 +write_ply( const char * filename, const bsc::geometry_data * data ) +{ + FILE * f = fopen( filename, "w" ); + if ( f ) + { + int n_points = data->n_vertices; + + fprintf( f, "ply\n" ); + fprintf( f, "format ascii 1.0\n" ); + fprintf( f, "element vertex %d\n", n_points ); + fprintf( f, "property float x\n" ); + fprintf( f, "property float y\n" ); + fprintf( f, "property float z\n" ); + fprintf( f, "property uchar red\n" ); + fprintf( f, "property uchar green\n" ); + fprintf( f, "property uchar blue\n" ); + fprintf( f, "end_header\n" ); + for ( i32 i = 0 ; i < n_points ; i++ ) + { + fprintf( f, "%f %f %f %u %u %u\n", data->positions[ 3 * i + 0 ] + , data->positions[ 3 * i + 1 ] + , data->positions[ 3 * i + 2 ] + , data->colors_a[ 4 * i + 0 ] + , data->colors_a[ 4 * i + 1 ] + , data->colors_a[ 4 * i + 2 ] ); + } + fclose( f ); + return 1; + } + printf( "Could not write to file %s\n", filename ); + return 0; +} + +i32 +init() +{ + // Just load in images + color_img.read( opts.color_filename ); + depth_img.read( opts.depth_filename ); + + undistorted_color_img = bsc::img( color_img ); + undistorted_depth_img = bsc::img_u16( depth_img ); + registered_depth_img = bsc::img_u16( color_img.width, color_img.height, 1 ); + + for ( i32 i = 0 ; i < depth_img.width * depth_img.height ; ++i ) + { + u16 d_raw = depth_img.data[i]; + if ( use_bitshift ) + { + depth_img.data[i] = ((d_raw >> 3) & 0x1FFF) | ((d_raw & 0x7) << 13); + } + undistorted_depth_img.data[i] = 0; + } + + for ( i32 i = 0; i < color_img.width * depth_img.height ; ++i ) + { + undistorted_color_img.data[ 3 * i + 0 ] = 0; + undistorted_color_img.data[ 3 * i + 1 ] = 0; + undistorted_color_img.data[ 3 * i + 2 ] = 0; + + registered_depth_img.data[i] = 0; + } + + init_gpu_tex( color_img.data, + color_img.width, + color_img.height, + color_img.ncomp, + &color_tex, + 1 ); + + init_gpu_tex( registered_depth_img.data, + registered_depth_img.width, // we need to move depth to color! + registered_depth_img.height, + registered_depth_img.ncomp, + &depth_tex, + 2 ); + + // Initialize camera parameters + cam_params.dK[0][0] = 570.5; init_cam_params.dK[0][0] = 570.5; + cam_params.dK[1][1] = 570.5; init_cam_params.dK[1][1] = 570.5; + cam_params.dK[2][0] = 317.0; init_cam_params.dK[2][0] = 320.0; + cam_params.dK[2][1] = 246.0; init_cam_params.dK[2][1] = 240.0; + cam_params.cK[0][0] = 578.0; init_cam_params.cK[0][0] = 578.0; + cam_params.cK[1][1] = 578.0; init_cam_params.cK[1][1] = 578.0; + cam_params.cK[2][0] = 320.0; init_cam_params.cK[2][0] = 320.0; + cam_params.cK[2][1] = 244.0; init_cam_params.cK[2][1] = 240.0; + cam_params.dc[0] = -0.024f; init_cam_params.dc[0] = 0.0f; + cam_params.dc[1] = 0.0f; init_cam_params.dc[1] = 0.0f; + cam_params.dc[2] = 0.0f; init_cam_params.dc[2] = 0.0f; + cam_params.dc[3] = 0.0f; init_cam_params.dc[3] = 0.0f; + cam_params.dc[4] = 0.0f; init_cam_params.dc[4] = 0.0f; + cam_params.cc[0] = 0.126f; init_cam_params.cc[0] = 0.0f; + cam_params.cc[1] = -0.236f; init_cam_params.cc[1] = 0.0f; + cam_params.cc[2] = 0.0f; init_cam_params.cc[2] = 0.0f; + cam_params.cc[3] = 0.0f; init_cam_params.cc[3] = 0.0f; + cam_params.cc[4] = 0.0f; init_cam_params.cc[4] = 0.0f; + cam_params.d2c_T = bsc::mat4(); init_cam_params.d2c_T = bsc::mat4(); + cam_params.d2c_T[1][0] = -0.004f; + cam_params.d2c_T[2][0] = 0.009f; + cam_params.d2c_T[2][1] = 0.01f; + cam_params.d2c_T[0][1] = 0.004f; + cam_params.d2c_T[0][2] = -0.009f; + cam_params.d2c_T[1][2] = -0.01f; + cam_params.d2c_T[3][0] = 0.038f; + cam_params.d2c_T[3][1] = 0.003f; + cam_params.d2c_T[3][2] = 0.022f; + + cam_params.c_size = bsc::vec2i( color_img.width, color_img.height ); + cam_params.d_size = bsc::vec2i( depth_img.width, depth_img.height ); + + read_parameters( opts.input_parameter_filename, &cam_params ); + + // 3d camera controls + view = cam_controls.initialize(&cam, + bsc::vec3(5.0f, 5.0f, 5.0f), + bsc::vec3(0.0f, 0.0f, 0.0f), + bsc::vec3(0.0f, 1.0f, 0.0f)); + + return 1; +} + + +void +display() +{ + bsc::vec4i viewport( 0, 0, bsc::g_window.size.x - panel_width, bsc::g_window.size.y ); + bsc::clear_window( viewport ); + + bsc::ui::begin_frame(); + + ImGui::SetNextWindowPos(ImVec2(bsc::g_window.size.x - panel_width, 0)); + ImGui::SetNextWindowSize(ImVec2(panel_width, bsc::g_window.size.y)); + ImGui::Begin("Camera Parameters Widget", NULL, ImVec2(-1, -1), -1.0f, + ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings); + + static bool start = true; + bool should_update = false; + if ( start ) { should_update = true; start = false; }; + // should_update |= ImGui::SliderFloat("d_f1", &(cam_params.dK[0][0]), 500.0f, 650.0f ); + // should_update |= ImGui::SliderFloat("d_f2", &(cam_params.dK[1][1]), 500.0f, 650.0f ); + if ( ImGui::CollapsingHeader( "Depth Intrinsics" ) ) + { + should_update |= ImGui::SliderFloat("d_f1", &(cam_params.dK[0][0]), 500.0f, 650.0f ); + should_update |= ImGui::SliderFloat("d_f2", &(cam_params.dK[1][1]), 500.0f, 650.0f ); + should_update |= ImGui::SliderFloat("d_c1", &(cam_params.dK[2][0]), 280.0f, 360.0f ); + should_update |= ImGui::SliderFloat("d_c2", &(cam_params.dK[2][1]), 200.0f, 280.0f ); + } + + if ( ImGui::CollapsingHeader ("Depth Distortion Coeffs." ) ) + { + should_update |= ImGui::SliderFloat( "d_k1", &(cam_params.dc[0]), -1.0f, 1.0f ); + should_update |= ImGui::SliderFloat( "d_k2", &(cam_params.dc[1]), -1.0f, 1.0f ); + should_update |= ImGui::SliderFloat( "d_p1", &(cam_params.dc[2]), -1.0f, 1.0f ); + should_update |= ImGui::SliderFloat( "d_p2", &(cam_params.dc[3]), -1.0f, 1.0f ); + should_update |= ImGui::SliderFloat( "d_k3", &(cam_params.dc[4]), -1.0f, 1.0f ); + } + + if ( ImGui::CollapsingHeader( "Color Intrinsics" ) ) + { + should_update |= ImGui::SliderFloat("c_f1", &(cam_params.cK[0][0]), 1000.0f, 1250.0f ); + should_update |= ImGui::SliderFloat("c_f2", &(cam_params.cK[1][1]), 1000.0f, 1250.0f ); + should_update |= ImGui::SliderFloat("c_c1", &(cam_params.cK[2][0]), 560.0f, 800.0f ); + should_update |= ImGui::SliderFloat("c_c2", &(cam_params.cK[2][1]), 400.0f, 560.0f ); + } + + if ( ImGui::CollapsingHeader ("Color Distortion Coeffs." ) ) + { + should_update |= ImGui::SliderFloat( "c_k1", &(cam_params.cc[0]), -1.0f, 1.0f ); + should_update |= ImGui::SliderFloat( "c_k2", &(cam_params.cc[1]), -1.0f, 1.0f ); + should_update |= ImGui::SliderFloat( "c_p1", &(cam_params.cc[2]), -1.0f, 1.0f ); + should_update |= ImGui::SliderFloat( "c_p2", &(cam_params.cc[3]), -1.0f, 1.0f ); + should_update |= ImGui::SliderFloat( "c_k3", &(cam_params.cc[4]), -1.0f, 1.0f ); + } + + if ( ImGui::CollapsingHeader( "Extrinsics" ) ) + { + should_update |= ImGui::SliderFloat4("X", (float*)&(cam_params.d2c_T[0]), -1.0f, 1.0f ); + should_update |= ImGui::SliderFloat4("Y", (float*)&(cam_params.d2c_T[1]), -1.0f, 1.0f ); + should_update |= ImGui::SliderFloat4("Z", (float*)&(cam_params.d2c_T[2]), -1.0f, 1.0f ); + should_update |= ImGui::SliderFloat4("POS", (float*)&(cam_params.d2c_T[3]), -0.1f, 0.1f ); + } + ImGui::Separator(); + ImGui::SliderFloat("Alpha", &alpha, 0.0f, 1.0f); + + CameraParams * cur_params = &cam_params; + static bool show_initial = false; + if ( bsc::ui::is_key_pressed( bsc::ui::key_m ) ) + { + view_mode = (view_mode == IMAGE_MODE ) ? POINTCLOUD_MODE : IMAGE_MODE; + } + + if ( bsc::ui::is_key_pressed( bsc::ui::key_a ) ) + { + alpha = (r32)(!(bool)alpha); + } + + if ( show_initial ) + { + ImGui::Separator(); + ImGui::Text( "Showing Initial Parameters!" ); + } + + if ( bsc::ui::is_key_pressed( bsc::ui::key_s ) ) + { + cur_params = (show_initial) ? &cam_params : &init_cam_params; + show_initial = !show_initial; + should_update = true; + } + + + if ( should_update ) + { + bsc::stop_watch timer; + timer.start(); + u32 depth_size = depth_img.width * depth_img.height * sizeof(u16); + u32 color_size = color_img.width * color_img.height * 3 * sizeof(u8); + memset( undistorted_depth_img.data, 0, depth_size ); + memset( registered_depth_img.data, 0, color_img.width * color_img.height * sizeof(u16) ); + memset( undistorted_color_img.data, 0, color_size ); + + undistort( &depth_img, &undistorted_depth_img, cur_params->dK, cur_params->dc ); + transform_img( &undistorted_depth_img, ®istered_depth_img, cur_params ); + undistort( &color_img, &undistorted_color_img, cur_params->cK, cur_params->cc ); + + update_gpu_tex( registered_depth_img.data, + &depth_tex ); + update_gpu_tex( undistorted_color_img.data, + &color_tex ); + + ImGui::Separator(); + ImGui::Text("Last Update time: %f\n", timer.elapsed() ); + } + + static char filename[512] = "Test.ply"; + ImGui::Separator(); + ImGui::InputText("Ply Name", filename, 512); + if ( ImGui::Button("Save Ply", ImVec2( 336, 24 ) ) ) + { + bsc::geometry_data pc_data; + generate_pointcloud_data( pc_data, &color_img, ®istered_depth_img, cur_params->dK ); + write_ply( filename, &pc_data ); + } + + if ( opts.output_parameter_filename && ImGui::Button("Save Parameters", ImVec2( 336, 24 ) ) ) + { + write_parameters( opts.output_parameter_filename, &cam_params ); + } + if ( view_mode == IMAGE_MODE ) + { + bsc::use_texture( &color_tex ); + bsc::use_texture( &depth_tex ); + render_explorer_image( alpha, vs_image, fs_image ); + } + if ( view_mode == POINTCLOUD_MODE ) + { + if (bsc::ui::is_mouse_over(viewport) && !ImGui::IsMouseHoveringAnyWindow()) + { + cam_controls.update( &cam, &view, &viewport ); + } + + static r32 near = 0.1f; + static r32 far = 100.0f; + r32 fovy = bsc::deg2rad(45.0f); + r32 aspect_ratio = bsc::get_window().aspect_ratio; + proj = bsc::perspective(fovy, aspect_ratio, near, far); + + render_explorer_pointcloud( &pointcloud_geo, + &undistorted_color_img, + ®istered_depth_img, + cur_params->dK, + should_update, + vs_pointcloud, + fs_pointcloud ); + + } + if ( ImGui::Button( "Take Screenshot", ImVec2( 336, 24 ) ) ) + { + bsc::take_screenshot( viewport ); + } + + ImGui::End(); + ImGui::Render(); + + bsc::ui::end_frame(); +} + +void +parse_arguments( int argc, char **argv ) +{ + opts.color_filename = NULL; + opts.depth_filename = NULL; + opts.input_parameter_filename = NULL; + opts.output_parameter_filename = NULL; + + bsc::arg_parse args; + args.add(bsc::argument("parameter_file", + "File containing camera parameters", + &(opts.input_parameter_filename))); + + args.add(bsc::argument("color_image", + "Name of color image", + &(opts.color_filename))); + + args.add(bsc::argument("depth_image", + "Name of depth image encoded as 16bit png", + &(opts.depth_filename))); + + args.add(bsc::argument("-o", "--output_parameters", + "Output modified parameters", + &(opts.output_parameter_filename), 1 ) ); + + args.add(bsc::argument("-b", "--use_bitshift", + "Should modify depth values?", + &(use_bitshift), 0 ) ); + + args.parse( argc, argv ); +} + +int main( int argc, char **argv ) +{ + parse_arguments( argc, argv ); + bsc::create_window( "Calibration Explorer", 1296 + panel_width, 968 ); + bsc::set_init_funct( init ); + bsc::set_display_funct( display ); + bsc::main_loop(); + + return 0; +} diff --git a/CameraParameterEstimation/apps/calibration_explorer/src/makefile b/CameraParameterEstimation/apps/calibration_explorer/src/makefile new file mode 100644 index 0000000..746ecbd --- /dev/null +++ b/CameraParameterEstimation/apps/calibration_explorer/src/makefile @@ -0,0 +1,43 @@ +# Executable name +EXE_NAME = calibration_explorer + +# Useful Directories +BIN_DIR = ../../../bin/ +LIB_DIR = /usr/local/lib/ +OUT_DIR = ../out/ + +BSC_DIR = ../../basics/ +IMGUI_DIR = $(BSC_DIR)extern/imgui/ + +# List of source files +SRCS = calibration_explorer.cpp $(IMGUI_DIR)imgui.cpp $(IMGUI_DIR)imgui_draw.cpp +OBJS = $(SRCS:%.cpp=$(OUT_DIR)%.o) + +# Compile and link options +CC = g++ +WARNINGS = -Wall +CPPFLAGS = -std=c++11 -O -I. -I/usr/local/include -I$(IMGUI_DIR) -I$(BSC_DIR) + +# Libraries +LIBS = -L$(LIB_DIR) -lglew -lglfw3 + +# Frameworks +FRAMEWORKS = -framework opengl + +# Make targets +all: clean calibration_explorer + +calibration_explorer: $(OBJS) + $(CC) $(FRAMEWORKS) $(CPPFLAGS) $(OBJS) $(LIBS) -o ${BIN_DIR}${EXE_NAME} + +clean: + rm -f $(OUT_DIR)*.a $(OUT_DIR)*.o ${BIN_DIR}${EXE_NAME} ${BIN_DIR}${EXE_NAME}.exe + + +# Compile command +$(OUT_DIR)%.o: %.cpp + $(CC) $(WARNINGS) $(CPPFLAGS) -c $< -o $@ + + +# GNU Make: targets that don't build files +.PHONY: all clean diff --git a/CameraParameterEstimation/scripts/cross_times_matrix.m b/CameraParameterEstimation/scripts/cross_times_matrix.m new file mode 100644 index 0000000..59a6f94 --- /dev/null +++ b/CameraParameterEstimation/scripts/cross_times_matrix.m @@ -0,0 +1,27 @@ +function V_times = cross_times_matrix(V) +% CROSSTIMESMATRIX +% V_TIMES = CROSSTIMESMATRIX(V) returns a 3x3 (or a series of 3x3) cross times matrices of input vector(s) V +% +% Input: +% V a 3xN matrix, rpresenting a series of 3x1 vectors +% +% Output: +% V_TIMES (Vx) a series of 3x3 matrices where V_times(:,:,i) is the Vx matrix for the vector V(:,i) +% +% Babak Taati, 2003 +% (revised 2009) + +[a,b] = size(V); +V_times = zeros(a, 3, b); + +% V_times(1,1,:) = 0; +V_times(1,2,:) = - V(3,:); +V_times(1,3,:) = V(2,:); + +V_times(2,1,:) = V(3,:); +% V_times(2,2,:) = 0; +V_times(2,3,:) = - V(1,:); + +V_times(3,1,:) = - V(2,:); +V_times(3,2,:) = V(1,:); +% V_times(3,3,:) = 0; diff --git a/CameraParameterEstimation/scripts/estimate_depth_distortion_plane_poses.m b/CameraParameterEstimation/scripts/estimate_depth_distortion_plane_poses.m new file mode 100644 index 0000000..e275f39 --- /dev/null +++ b/CameraParameterEstimation/scripts/estimate_depth_distortion_plane_poses.m @@ -0,0 +1,45 @@ +function [plane_poses, depth_distortion_images_info] = estimate_depth_distortion_plane_poses( color_session, depth_distortion_folder ) + +% Get depth distortion session color images +depth_distortion_images_info = dir(fullfile(depth_distortion_folder,'*.jpg')); +n_images = length(depth_distortion_images_info); + +% Get camera parameters && board set +camera_params = color_session.CameraParameters; +board_set = color_session.BoardSet; + +% Get the ideal world points ( assumes same calibration grid has been used!) +board_size = board_set.BoardSize; +square_size = board_set.SquareSize; % in millimeters +world_points = generateCheckerboardPoints(board_size, square_size); + +% Prealocate storage for plane poses +plane_poses = zeros(4, 4, n_images); + +% Matrix to convert matlab extrinsics to our format +conversion_matrix = [1 0 0 0 ; 0 -1 0 0 ; 0 0 -1 0 ; 0 0 0 1]; + +% Extract extrinsics +progress = 0.025; +fprintf('Progress: ['); +for image_idx=1:n_images; + if image_idx / n_images > progress + progress = progress + 0.025; + fprintf('.'); + end + image_info = depth_distortion_images_info(image_idx); + image_name = fullfile( image_info.folder, image_info.name ); + image = imread(image_name); + undistorted_image = undistortImage(image, camera_params); + [image_points, board_size] = detectCheckerboardPoints(undistorted_image); + if numel(image_points) == numel(world_points) + [rotation, translation] = extrinsics(image_points, world_points, camera_params); + translation = 0.001 * translation; + pose = [[rotation ; translation], [0 0 0 1]']; + plane_poses(:,:,image_idx) = conversion_matrix * pose * conversion_matrix; + end +end +fprintf('] ', toc ); + + +end diff --git a/CameraParameterEstimation/scripts/estimate_pairwise_transform.m b/CameraParameterEstimation/scripts/estimate_pairwise_transform.m new file mode 100644 index 0000000..60fdd20 --- /dev/null +++ b/CameraParameterEstimation/scripts/estimate_pairwise_transform.m @@ -0,0 +1,60 @@ +function transformation = estimate_pairwise_transform( color_session, ir_session ) + + color_camera_params = color_session.CameraParameters; + ir_camera_params = ir_session.CameraParameters; + + % extract data + col_world_points = color_camera_params.WorldPoints; + col_rotations = color_camera_params.RotationMatrices; + col_translations = color_camera_params.TranslationVectors; + + ir_world_points = ir_camera_params.WorldPoints; + ir_rotations = ir_camera_params.RotationMatrices; + ir_translations = ir_camera_params.TranslationVectors; + + % useful info + n_images = size( col_rotations,3 ); + n_points_per_image = size( col_world_points, 1 ); + + + % points assume z = 0, let's add this dimension + col_world_points = [ col_world_points, zeros( size(col_world_points, 1), 1 ) ]; + ir_world_points = [ ir_world_points, zeros(size(ir_world_points, 1), 1) ]; + + % lets get the points represented with camera centered at origin + + % first color ... + col_camera_points = zeros( n_images * n_points_per_image, 3 ); + for j = 1:size( col_rotations,3 ) + for i = 1:size(col_world_points, 1 ) + col_camera_points( (j-1) * n_points_per_image + i, :) = col_world_points(i,:) * col_rotations(:,:,j) + col_translations(j,:); + end + end + + % ... and ir + ir_camera_points = zeros( n_images * n_points_per_image, 3 ); + for j = 1:size( ir_rotations,3 ) + for i = 1:size(ir_world_points, 1 ) + ir_camera_points( (j-1) * n_points_per_image + i, :) = ir_world_points(i,:) * ir_rotations(:,:,j) + ir_translations(j,:); + end + end + + % convert these points to our coordinate system + conversion = [1 0 0; 0 -1 0 ; 0 0 -1]; + for i = 1:size(ir_camera_points,1) + ir_point = ir_camera_points(i, :); + col_point = col_camera_points(i, :); + ir_camera_points(i, :) = ir_point * conversion; + col_camera_points(i, :) = col_point * conversion; + end + + % now we can estimate the transformation between the two + [transformation, eps] = estimate_rigid_transform(col_camera_points',... + ir_camera_points' ); + transformation(1:3,4) = 0.001 * transformation(1:3,4); + + % adjust the transformation + conversion = [ 1 0 0 0 ; 0 -1 0 0 ; 0 0 -1 0 ; 0 0 0 1 ]; + transformation = conversion * transformation * conversion; + +end \ No newline at end of file diff --git a/CameraParameterEstimation/scripts/estimate_rigid_transform.m b/CameraParameterEstimation/scripts/estimate_rigid_transform.m new file mode 100644 index 0000000..e4205ee --- /dev/null +++ b/CameraParameterEstimation/scripts/estimate_rigid_transform.m @@ -0,0 +1,75 @@ +function [T, Eps] = estimate_rigid_transform(x, y) +% ESTIMATERIGIDTRANSFORM +% [T, EPS] = ESTIMATERIGIDTRANSFORM(X, Y) estimates the rigid transformation +% that best aligns x with y (in the least-squares sense). +% +% Reference: "Estimating Rigid Transformations" in +% "Computer Vision, a modern approach" by Forsyth and Ponce (1993), page 480 +% (page 717(?) of the newer edition) +% +% Input: +% X: 3xN, N 3-D points (N>=3) +% Y: 3xN, N 3-D points (N>=3) +% +% Output +% T: the rigid transformation that aligns x and y as: xh = T * yh +% (h denotes homogenous coordinates) +% (corrspondence between points x(:,i) and y(:,i) is assumed) +% +% EPS: the smallest singular value. The closer this value it is +% to 0, the better the estimate is. (large values mean that the +% transform between the two data sets cannot be approximated +% well with a rigid transform. +% +% Babak Taati, 2003 +% (revised 2009) + +if nargin ~= 2 + error('Requires two input arguments.') +end + +if size(x,1)~=3 || size(y,1)~=3 + error('Input point clouds must be a 3xN matrix.'); +end + +if size(x, 2) ~= size(y,2) + error('Input point clouds must be of the same size'); +end + +if size(x,2)<3 || size(y,2)<3 + error('At least 3 point matches are needed'); +end + +pointCount = length(x); % since x has N=3+ points, length shows the number of points + +x_centroid = sum(x,2) / pointCount; +y_centroid = sum(y,2) / pointCount; + +x_centrized = [x(1,:)-x_centroid(1) ; x(2,:)-x_centroid(2); x(3,:)-x_centroid(3)]; +y_centrized = [y(1,:)-y_centroid(1) ; y(2,:)-y_centroid(2); y(3,:)-y_centroid(3)]; + +R12 = y_centrized' - x_centrized'; +R21 = x_centrized - y_centrized; +R22_1 = y_centrized + x_centrized; +R22 = cross_times_matrix(R22_1(1:3,:)); + +B = zeros(4, 4); +A = zeros(4, 4, pointCount); +for ii=1:pointCount + A(1:4,1:4,ii) = [0, R12(ii,1:3); R21(1:3,ii), R22(1:3,1:3,ii)]; + B = B + A(:,:,ii)' * A(:,:,ii); +end + +[dummy, S, V] = svd(B); +quat = V(:,4); +rot = quat2rot(quat); + +T1 = [eye(3,3), -y_centroid ; 0 0 0 1]; +T2 = [rot, [0; 0; 0]; 0 0 0 1]; +T3 = [eye(3,3), x_centroid ; 0 0 0 1]; + +T = T3 * T2 * T1; +Eps = S(4,4); + + + diff --git a/CameraParameterEstimation/scripts/export_calibration_info.m b/CameraParameterEstimation/scripts/export_calibration_info.m new file mode 100644 index 0000000..d289a5d --- /dev/null +++ b/CameraParameterEstimation/scripts/export_calibration_info.m @@ -0,0 +1,90 @@ +function [] = export_calibration_info( device_folder ) +%EXPORT_CALIBRATION_INFO Exports information from calibration files +% This function expects that user has captured 2 calibration sequences +% -> Color + IR +% -> Color + Depth +% +% Color + IR should be used to calibrate cameras using Calibrator App, +% and saved in device folder as 'color_session.mat' and +% 'infrared_session.mat' respectively. +% +% Color + Depth should be saved in depth_distortion folder in device +% folder. + +% TODO: Check for folder existence! + +% depth_distortion folder path +depth_distortion_folder = fullfile(device_folder, 'depth_distortion'); + +% get the prepared sessions. These contain required calibrated parameters. +color_info = load(fullfile(device_folder,'color_session.mat')); +color_session = color_info.calibrationSession; +ir_info = load(fullfile(device_folder,'infrared_session.mat')); +ir_session = ir_info.calibrationSession; + + +% extract parameters to our format into the depth_distortion folder +parameters_filename = fullfile(depth_distortion_folder, 'parameters.txt'); +fprintf('Exporting color and ir camera parameters to \"%s\" -> ',... + parameters_filename); tic; +export_color_and_ir_params(color_session, ir_session, parameters_filename); +fprintf('Done in %f\n', toc); + + +% estimate plane poses for depth distortion session +fprintf('Estimating plane poses for depth distortion -> '); tic; +[plane_poses, images_info] = estimate_depth_distortion_plane_poses(... + color_session, ... + fullfile( depth_distortion_folder, 'color')); +fprintf('Done in %f\n', toc); + +% save plane poses +pose_filename = fullfile(depth_distortion_folder, 'plane_poses.txt'); +fprintf('Saving estimated plane poses to \"%s\" -> ', pose_filename); tic; +pose_fid = fopen(pose_filename, 'w'); +n_valid = 0; +for pose_idx = 1:size(plane_poses,3) + T = plane_poses(:,:,pose_idx); + if ~any(T) + continue; + end; + + fprintf(pose_fid, '%12.8f %12.8f %12.8f %12.8f ', T(:,1)); + fprintf(pose_fid, '%12.8f %12.8f %12.8f %12.8f ', T(:,2)); + fprintf(pose_fid, '%12.8f %12.8f %12.8f %12.8f ', T(:,3)); + fprintf(pose_fid, '%12.8f %12.8f %12.8f %12.8f\n', T(:,4)); + n_valid = n_valid+1; +end; +fclose(pose_fid); +fprintf('Done in %f\n', toc); + +% save configuration file +conf_filename = fullfile(depth_distortion_folder,... + 'depth_distortion_calibration.conf'); +fprintf('Saving configuration file to \"%s\" -> ', conf_filename); tic; +conf_fid = fopen( conf_filename, 'w'); +fprintf(conf_fid, 'n_images %d\n\n', n_valid); +fprintf(conf_fid, 'parameters parameters.txt\n'); +fprintf(conf_fid, 'plane_poses plane_poses.txt\n'); + +for pose_idx = 1:size(plane_poses,3) + T = plane_poses(:,:,pose_idx); + if ~any(T) + continue; + end; + image_info = images_info(pose_idx); + image_name = fullfile( image_info.folder, image_info.name ); + [~, name, ext] = fileparts(image_name); + color_image_name = strcat(name, ext); + depth_image_name = strcat(name, '.png'); + fprintf(conf_fid,... + 'scan %30s %30s 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1\n',... + depth_image_name,... + color_image_name); +end; + +fclose(conf_fid); +fprintf('Done in %f\n', toc); + +end + diff --git a/CameraParameterEstimation/scripts/export_color_and_ir_params.m b/CameraParameterEstimation/scripts/export_color_and_ir_params.m new file mode 100644 index 0000000..2fa5513 --- /dev/null +++ b/CameraParameterEstimation/scripts/export_color_and_ir_params.m @@ -0,0 +1,80 @@ +function [] = export_color_and_ir_params( color_session,... + ir_session,... + parameter_filename ) +%EXPORT_INFO Writes color depth/extrinsics and color/depth intrinsics. + +%extract info from calibration session file +color_f = color_session.CameraParameters.FocalLength; +color_c = color_session.CameraParameters.PrincipalPoint; +color_rd = color_session.CameraParameters.RadialDistortion; +color_td = color_session.CameraParameters.TangentialDistortion; + +ir_f = ir_session.CameraParameters.FocalLength; +ir_c = ir_session.CameraParameters.PrincipalPoint; +ir_rd = ir_session.CameraParameters.RadialDistortion; +ir_td = ir_session.CameraParameters.TangentialDistortion; + +% get the pariwise transformation +depthToColor = estimate_pairwise_transform( color_session,... + ir_session); + +% get image size +color_im = imread( color_session.BoardSet.FullPathNames{1} ); +depth_im = imread( ir_session.BoardSet.FullPathNames{1} ); + +% output scannet format parameter file +params_fid = fopen( parameter_filename, 'w'); +fprintf(params_fid, 'colorWidth = %d\n', size(color_im, 2) ); +fprintf(params_fid, 'colorHeight = %d\n', size(color_im, 1) ); +fprintf(params_fid, 'depthWidth = %d\n', size(depth_im,2) ); +fprintf(params_fid, 'depthHeight = %d\n', size(depth_im,1) ); +fprintf(params_fid, 'fx_color = %f\n', color_f(1) ); +fprintf(params_fid, 'fy_color = %f\n', color_f(2) ); +fprintf(params_fid, 'mx_color = %f\n', color_c(1) ); +fprintf(params_fid, 'my_color = %f\n', color_c(2) ); +fprintf(params_fid, 'fx_depth = %f\n', ir_f(1) ); +fprintf(params_fid, 'fy_depth = %f\n', ir_f(2) ); +fprintf(params_fid, 'mx_depth = %f\n', ir_c(1) ); +fprintf(params_fid, 'my_depth = %f\n', ir_c(2) ); +fprintf(params_fid, 'k1_color = %f\n', color_rd(1) ); +fprintf(params_fid, 'k2_color = %f\n', color_rd(2) ); +fprintf(params_fid, 'k3_color = %f\n', color_td(1) ); +fprintf(params_fid, 'k4_color = %f\n', color_td(2) ); +fprintf(params_fid, 'k5_color = %f\n', 0.0 ); +fprintf(params_fid, 'k1_depth = %f\n', ir_rd(1) ); +fprintf(params_fid, 'k2_depth = %f\n', ir_rd(2) ); +fprintf(params_fid, 'k3_depth = %f\n', ir_td(1) ); +fprintf(params_fid, 'k4_depth = %f\n', ir_td(2) ); +fprintf(params_fid, 'k5_depth = %f\n', 0.0 ); +fprintf(params_fid, 'depthToColorExtrinsics = %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n', depthToColor(1,:), depthToColor(2,:), depthToColor(3,:), depthToColor(4,:) ); +fclose(params_fid); + +% same information, for compatibility with .conf file. +%TODO: Remove! +% di_fid = fopen(strcat(dst_dir, 'DEPTH_INTRINSICS'), 'w'); +% fprintf( di_fid, '%12.8f %12.8f %12.8f\n', ir_f(1), 0.0, ir_c(1) ); +% fprintf( di_fid, '%12.8f %12.8f %12.8f\n', 0.0, ir_f(2), ir_c(2) ); +% fprintf( di_fid, '%12.8f %12.8f %12.8f\n', 0.0, 0.0, 1.0 ); +% fclose(di_fid); +% +% ci_fid = fopen(strcat(dst_dir, 'COLOR_INTRINSICS'), 'w'); +% fprintf( ci_fid, '%12.8f %12.8f %12.8f\n', color_f(1), 0.0, color_c(1) ); +% fprintf( ci_fid, '%12.8f %12.8f %12.8f\n', 0.0, color_f(2), color_c(2) ); +% fprintf( ci_fid, '%12.8f %12.8f %12.8f\n', 0.0, 0.0, 1.0 ); +% fclose( ci_fid ); +% +% de_fid = fopen(strcat(dst_dir, 'DEPTH_EXTRINSICS'), 'w'); +% fprintf( de_fid, '%12.8f %12.8f %12.8f %12.8f\n', depthToColor(1,:) ); +% fprintf( de_fid, '%12.8f %12.8f %12.8f %12.8f\n', depthToColor(2,:) ); +% fprintf( de_fid, '%12.8f %12.8f %12.8f %12.8f\n', depthToColor(3,:) ); +% fprintf( de_fid, '%12.8f %12.8f %12.8f %12.8f\n', depthToColor(4,:) ); +% fclose( de_fid ); +% +% ce_fid = fopen(strcat(dst_dir, 'COLOR_EXTRINSICS'), 'w'); +% fprintf( ce_fid, '%12.8f %12.8f %12.8f %12.8f\n', 1.0, 0.0, 0.0, 0.0 ); +% fprintf( ce_fid, '%12.8f %12.8f %12.8f %12.8f\n', 0.0, 1.0, 0.0, 0.0 ); +% fprintf( ce_fid, '%12.8f %12.8f %12.8f %12.8f\n', 0.0, 0.0, 1.0, 0.0 ); +% fprintf( ce_fid, '%12.8f %12.8f %12.8f %12.8f\n', 0.0, 0.0, 0.0, 1.0 ); +% fclose( ce_fid ); +end + diff --git a/CameraParameterEstimation/scripts/quat2rot.m b/CameraParameterEstimation/scripts/quat2rot.m new file mode 100644 index 0000000..06ed926 --- /dev/null +++ b/CameraParameterEstimation/scripts/quat2rot.m @@ -0,0 +1,28 @@ +function R = quat2rot(Q) +% QUAT2ROT +% R = QUAT2ROT(Q) converts a quaternion (4x1 or 1x4) into a 3x3 rotation mattrix +% +% reference: google! +% +% Babak Taati, 2003 +% (revised 2009) + +q0 = Q(1); +q1 = Q(2); +q2 = Q(3); +q3 = Q(4); + +R(1,1) = q0*q0 + q1*q1 - q2*q2 - q3*q3; +R(1,2) = 2 * (q1*q2 - q0*q3); +R(1,3) = 2 * (q1*q3 + q0*q2); + +R(2,1) = 2 * (q1*q2 + q0*q3); +R(2,2) = q0*q0 - q1*q1 + q2*q2 - q3*q3; +R(2,3) = 2 * (q2*q3 - q0*q1); + +R(3,1) = 2 * (q1*q3 - q0*q2); +R(3,2) = 2 * (q2*q3 + q0*q1); +R(3,3) = q0*q0 - q1*q1 - q2*q2 + q3*q3; + + + diff --git a/CameraParameterEstimation/tutorial/tutorial.md b/CameraParameterEstimation/tutorial/tutorial.md new file mode 100644 index 0000000..941bad9 --- /dev/null +++ b/CameraParameterEstimation/tutorial/tutorial.md @@ -0,0 +1,110 @@ +Camera Calibration Tutorial +============================================ + +## Step 1 - Data Preparation + +For a specific device we are expecting two sets of images: +1. Depth-to-Color: Around 20-30 color and infrared images showing calibration grid +from different angles and distances. +2. Depth-Distortion: A video sequence of walking from and to a big flat wall with +calibration grid on it. It is important that for all images in this sequence, +the wall covers __entire__ view frustum. Sequence should be saved as jpgs for color +images and 16-bit pngs for depth. + +If you are calibrating your camera, this is where you provide your data. We do +strongly encourage to go through this tutorial and investigate downloaded data. +When providing your own data, the initial state a directory with a calibration +data for a device should have following structure: +~~~~~~~~ +calibration_data +├── depth_distortion +│ ├── color +│ └── depth_raw +├── depth_to_color +│ ├── color +│ └── infrared +└── validate + ├── color + ├── depth_raw + └── validation.conf +~~~~~~~~ + +----------- + +## Step 2 - Calibration of Color and IR +Run matlab Single Camera Calibration App, by typing +~~~~~~~~ +cameraCalibrator +~~~~~~~~ +in Matlab's command line. + +After app is loaded and you are presented with user interface, create new +session, by clicking 'New Session' button. Then click 'Add images' button to +add images from one of the session, color or infrared. This proces will need to +be repeated for both. For our example, the grid size is 53 mm, but change it +for your grid size. + +After images are loaded, simply press the calibrate button (make sure you're +estimating the camera model with 2 distortion coefficients). +The resulting reprojection error will depend on resolution of the images, but +for our experiments for color images with resolution 1296x968, the mean error is +0.23px. For infrared images of with resolution 640x480, it is 0.12 px. + +After calibration is done, save the calibration sessions into +__calibration_data__ folder, as __color_session.mat__ and +__infrared_session.mat__ for color and infrared images respectively. + +Note that if you're excluding some images from __color__ (failed grid detection, +outliers according to optimization, etc.), relating images must be removed from +__infrared__. Simply put you are excluding pairs, not single images. + +----------- + +## Step 3 - Parameters Export +From scripts folder run script +~~~~~~~~ +export_calibration_info( ) +~~~~~~~~ +This will create file _parameters.txt_ and other files required for depth +distortion calibration. Files will be writed into __calibration_data/depth_distortion__ + +----------- + +## Step 4 - Depth Distortion Calibration +Assuming you've compiled __calibrate_depth__ app and added it to your PATH, +you should navigate to __calibration_data/depth_distortion__. Now you should be +able to run: +~~~~~~~~ +calibrate_depth depth_distortion_calibration.conf --estimate_undistortion +~~~~~~~~ +Note that this is possibly the most timely step. It obviously depends on your machine +and the number of images you are using. On a Early 2013 macbook pro, with XXX images + +Now you have all the files required for applying calibration: __parameters.txt__ and +____. __calibrate_depth__ can use these when run in apply mode: +~~~~~~~~ +calibrate_depth depth_distortion_calibration.conf --apply_undistortion +~~~~~~~~ +But this file formats will also work with [ScanNet](http://link) pipeline. + +You can also run the __calibrate_depth__ without any argument to see how the +images got undistorted. + +----------- + +## Step 5 - Validation +Since calibration is a bit of an arcane art, it is often good idea to validate +the results. To do so it is good to prepare some image pairs, that capture +non planar scenes, storing images in a hierarchy as seen in __validate__ folder above. +Then you can run: +~~~~~~~~ +calibrate_depth validation.conf --apply_undistortion +calibration_explorer ../depth_distortion/parameters.txt color/ depth/ +~~~~~~~~ +You will be able to see color image overlayed with depth_image. It is possible +to manually control alpha, as well as switch to 3D view to investigate how +well images are aligned. + +All calibration parameters are also exposed if some manual intervention is needed/wanted. +You can pass __--output_parameters __ to the +__calibration_explorer__ to be able to save the modified parameters. diff --git a/Converter/README.md b/Converter/README.md new file mode 100644 index 0000000..9367517 --- /dev/null +++ b/Converter/README.md @@ -0,0 +1,16 @@ +## Converter from ScannerApp capture to .sens data +=============================================== + +Converts raw capture data (`.h264`, `.depth`, `.txt`, `.imu`) output from the ScannerApp to `.sens` format. + +### Installation. +This code was developed under VS2013. + +Requirements: +- ffmpeg (assumes that `ffmpeg.exe` is at the relativel path `./ffmpeg/ffmpeg.exe`) +- our research library mLib, a git submodule in ../external/mLib +- mLib external libraries can be downloaded [here](https://www.dropbox.com/s/fve3uen5mzonidx/mLibExternal.zip?dl=0) + + +To run: +`converter.exe [path to directory of ScannerApp outputs] [name of ScannerApp output to convert]` diff --git a/Converter/converter.sln b/Converter/converter.sln new file mode 100644 index 0000000..ebfb91a --- /dev/null +++ b/Converter/converter.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "converter", "converter.vcxproj", "{6DFC3959-985F-4B6D-96FC-D6A3CC41BDC3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6DFC3959-985F-4B6D-96FC-D6A3CC41BDC3}.Debug|x64.ActiveCfg = Debug|x64 + {6DFC3959-985F-4B6D-96FC-D6A3CC41BDC3}.Debug|x64.Build.0 = Debug|x64 + {6DFC3959-985F-4B6D-96FC-D6A3CC41BDC3}.Release|x64.ActiveCfg = Release|x64 + {6DFC3959-985F-4B6D-96FC-D6A3CC41BDC3}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Converter/converter.vcxproj b/Converter/converter.vcxproj new file mode 100644 index 0000000..0bbd410 --- /dev/null +++ b/Converter/converter.vcxproj @@ -0,0 +1,123 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {6DFC3959-985F-4B6D-96FC-D6A3CC41BDC3} + Win32Proj + converter + + + + Application + true + v120 + Unicode + + + Application + false + v120 + true + Unicode + + + + + + + + + + + + + true + ./;./src/;../external/mLib/include/;../external/mLibExternal/include/;$(IncludePath) + ../external/mLibExternal/libsWindows/lib64/;$(LibraryPath) + + + false + ./;./src/;../external/mLib/include/;../external/mLibExternal/include/;$(IncludePath) + ../external/mLibExternal/libsWindows/lib64/;$(LibraryPath) + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WINSOCK_DEPRECATED_NO_WARNINGS + true + stdafx.h + + + Console + true + zlib64.lib;FreeImage.lib;%(AdditionalDependencies) + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WINSOCK_DEPRECATED_NO_WARNINGS + true + stdafx.h + + + Console + true + true + true + zlib64.lib;FreeImage.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + + + + + + \ No newline at end of file diff --git a/Converter/converter.vcxproj.filters b/Converter/converter.vcxproj.filters new file mode 100644 index 0000000..d073cfc --- /dev/null +++ b/Converter/converter.vcxproj.filters @@ -0,0 +1,90 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {50fd99dc-5001-4643-abab-04f4c216b8a3} + + + {555583f0-31b9-4962-b5da-bb3133d6e4d9} + + + + + + + input + + + input + + + input + + + input + + + input + + + input + + + input + + + input + + + input + + + input + + + input + + + input + + + input + + + input + + + + sensorData + + + sensorData + + + sensorData + + + sensorData + + + sensorData + + + sensorData + + + sensorData + + + sensorData + + + + + + + \ No newline at end of file diff --git a/Converter/main.cpp b/Converter/main.cpp new file mode 100644 index 0000000..5dd1f21 --- /dev/null +++ b/Converter/main.cpp @@ -0,0 +1,241 @@ +// sensorFile.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include + +#include "metaData.h" + + +//converts from seconds to microseconds +UINT64 timeToUINT64(double d) { + return (UINT64)(d*1000.0*1000.0); +} + + +void convertToSens(const std::string& baseFilename, ml::SensorData& sens) +{ + sens.free(); + + const std::string srcFileMeta = ml::util::removeExtensions(baseFilename) + ".txt"; + const std::string srcFileDepth = ml::util::removeExtensions(baseFilename) + ".depth"; + const std::string srcFileColor = ml::util::removeExtensions(baseFilename) + ".h264"; + const std::string srcFileIMU = ml::util::removeExtensions(baseFilename) + ".imu"; + + + if (!ml::util::fileExists(srcFileMeta)) throw MLIB_EXCEPTION("file not found " + srcFileMeta); + if (!ml::util::fileExists(srcFileDepth)) throw MLIB_EXCEPTION("file not found " + srcFileDepth); + if (!ml::util::fileExists(srcFileColor)) throw MLIB_EXCEPTION("file not found " + srcFileColor); + if (!ml::util::fileExists(srcFileIMU)) throw MLIB_EXCEPTION("file not found " + srcFileIMU); + + MetaData meta(srcFileMeta); + sens.initDefault( + meta.colorWidth, meta.colorHeight, + meta.depthWidth, meta.depthHeight, + meta.colorCalibration, + meta.depthCalibration, + ml::SensorData::COMPRESSION_TYPE_COLOR::TYPE_JPEG, + ml::SensorData::COMPRESSION_TYPE_DEPTH::TYPE_ZLIB_USHORT, + 1000.0f, + ml::SensorData::getName().StructureSensor + ); + + std::string execPath = ml::util::getExecutablePath(); + const std::string tmpDir = execPath + "/tmp1337/"; + ml::util::deleteDirectory(tmpDir); // in case we have a leftover directory + + const std::string baseNameColor = "frame-"; + std::string ffmpegPath = execPath + "../../ffmpeg/ffmpeg.exe"; + if (!ml::util::fileExists(ffmpegPath)) { + ffmpegPath = execPath + "./ffmpeg/ffmpeg.exe"; + } + + if (!ml::util::fileExists(ffmpegPath)) throw MLIB_EXCEPTION("could not find ffmpeg.exe in path: " + ffmpegPath); + std::string command = ffmpegPath + " -i " + srcFileColor + " " + tmpDir + baseNameColor + "%6d.color.png"; + std::cout << "running: " << command << std::endl; + ml::util::makeDirectory(tmpDir); + command = command + " > nul 2>&1"; //pipe output to dev/null + int res = system(command.c_str()); + + + std::ifstream inDepth(srcFileDepth, std::ios::binary); + + ml::Directory dir(tmpDir); + const unsigned int numColorFrames = (unsigned int)dir.getFiles().size(); + unsigned int numFrames = std::min(meta.numDepthFrames, meta.numColorFrames); + numFrames = std::min(numFrames, numColorFrames); + if (numFrames != meta.numDepthFrames || numFrames != meta.numColorFrames || numFrames != numColorFrames) { + MLIB_WARNING("frame counts are different:numColorImages(" + std::to_string(numColorFrames) + ") meta.numDepthImages(" + std::to_string(meta.numDepthFrames) + ") meta.numColorImages(" + std::to_string(meta.numColorFrames) + ")"); + } + + unsigned int frame = 0; + ml::SensorData::StringCounter scColor(tmpDir + "/" + baseNameColor, "color.png", 6); scColor.getNext(); + + while (frame < numFrames) { + assert(inDepth.good()); + + //ml::Timer t; + uint32_t byteSize; + inDepth.read((char*)&byteSize, sizeof(uint32_t)); + char* depthCompressed = new char[byteSize]; + inDepth.read((char*)depthCompressed, byteSize); + + const unsigned int depthWidth = meta.depthWidth; + const unsigned int depthHeight = meta.depthHeight; + + unsigned short* depth = (unsigned short*)std::malloc(depthWidth*depthHeight * 2); + + uplinksimple::decode((unsigned char*)depthCompressed, (unsigned int)byteSize, depthWidth*depthHeight, depth); + uplinksimple::shift2depth(depth, depthWidth*depthHeight); + + //check for invalid values + for (unsigned int i = 0; i < depthWidth*depthHeight; i++) { + if (depth[i] >= uplinksimple::shift2depth(0xffff)) { + depth[i] = 0; + } + } + + SAFE_DELETE(depthCompressed); + + std::string colorFile = scColor.getNext(); + ml::ColorImageR8G8B8 cImage; + ml::FreeImageWrapper::loadImage(colorFile, cImage); + + sens.addFrame(cImage.getData(), depth); + + std::free(depth); + std::cout << "\rframe " << frame << ": read " << byteSize << " [bytes] "; + frame++; + + //std::cout << t.getElapsedTimeMS() << " [ms]" << std::endl << std::endl; + } + + //read the rest of the depth frames + for (; frame < meta.numDepthFrames; frame++) { + assert(inDepth.good()); + uint32_t byteSize; + inDepth.read((char*)&byteSize, sizeof(uint32_t)); + char* depthCompressed = new char[byteSize]; + inDepth.read((char*)depthCompressed, byteSize); + SAFE_DELETE_ARRAY(depthCompressed); + } + + + for (unsigned int i = 0; i < meta.numDepthFrames; i++) { + //TODO read time stamps here + double timeStampDouble; + inDepth.read((char*)&timeStampDouble, sizeof(double)); + UINT64 timeStamp = timeToUINT64(timeStampDouble); + + if (i < (unsigned int)sens.m_frames.size()) { + sens.m_frames[i].setTimeStampColor(timeStamp); + sens.m_frames[i].setTimeStampDepth(timeStamp); + } + + //std::cout << timeStamp << std::endl; + //std::cout << std::setprecision(20) << timeStampDouble << std::endl; + } + + + std::ifstream inIMU(srcFileIMU, std::ios::binary); + for (unsigned int i = 0; i < meta.numIMUmeasurements; i++) { + ml::SensorData::IMUFrame f; + double timeStamp = 0.0; + inIMU.read((char*)&timeStamp, sizeof(double)); + + inIMU.read((char*)&f.rotationRate, sizeof(ml::vec3d)); + inIMU.read((char*)&f.acceleration, sizeof(ml::vec3d)); + inIMU.read((char*)&f.magneticField, sizeof(ml::vec3d)); + inIMU.read((char*)&f.attitude, sizeof(ml::vec3d)); + inIMU.read((char*)&f.gravity, sizeof(ml::vec3d)); + f.timeStamp = timeToUINT64(timeStamp); + + if (f.timeStamp == 0) { + std::cout << "invalid IMUFrame -> skipping" << std::endl; + continue; + } + sens.addIMUFrame(f); + } + inIMU.close(); + + std::cout << std::endl; + + //for (size_t i = 0; i < sens.m_frames.size(); i++) { + // const ml::SensorData::IMUFrame& f = sens.findClosestIMUFrame(i); + // std::cout << "frame time: " << sens.m_frames[i].getTimeStampColor() << "\t imu time: " << f.timeStamp << std::endl; + //} + + for (size_t i = 0; i < sens.m_frames.size(); i++) { + const ml::mat4f& t = sens.m_frames[i].getCameraToWorld(); + const ml::mat4f id = ml::mat4f::identity(); + for (unsigned int i = 0; i < 16; i++) { + if (t[i] != id[i]) throw MLIB_EXCEPTION("matrix needs to be the identity"); + } + + //std::cout << sens.m_frames[i].getCameraToWorld() << std::endl; + } + + ml::util::deleteDirectory(tmpDir); +} + +void processStagingFolder(std::string stagingFolder, const std::string& outSensFilename, bool forceOverwrite = false) +{ + stagingFolder = ml::util::replace(stagingFolder, "\\", "/"); //we assume forward slashes + + ml::Directory stagingFolderDir(stagingFolder); + + const std::vector tmp = ml::util::split(stagingFolder, "/"); + const std::string base = tmp.back(); + const std::string baseFile = stagingFolder + "/" + base; + + std::cout << "converting: " << baseFile << std::endl; + + //const std::string sensFile = baseFile + ".sens"; + if (ml::util::fileExists(outSensFilename)) { + std::cout << "sensFile already available: " << outSensFilename << "\n\t -> skipping folder" << std::endl; + return; + } + + ml::SensorData sd; + convertToSens(baseFile, sd); + sd.saveToFile(outSensFilename); + std::cout << sd << std::endl; + +} + + + +int main(int argc, char* argv[]) +{ +#if defined(DEBUG) | defined(_DEBUG) + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); +#endif + //_CrtSetBreakAlloc(7545); + try { + + if (argc == 3) { //converts a specific scan given by the command line argument + std::string stagingFolder(argv[1]); + std::string outSensFilename(argv[2]); + std::cout << stagingFolder << std::endl; + std::cout << outSensFilename << std::endl; + processStagingFolder(stagingFolder, outSensFilename); + } + else { + throw MLIB_EXCEPTION("requires the path and output file as a command line arguments"); + } + } + catch (const std::exception& e) + { + MessageBoxA(NULL, e.what(), "Exception caught", MB_ICONERROR); + exit(EXIT_FAILURE); + } + catch (...) + { + MessageBoxA(NULL, "UNKNOWN EXCEPTION", "Exception caught", MB_ICONERROR); + exit(EXIT_FAILURE); + } + //std::cout << "" << std::endl; + //getchar(); + return 0; +} + diff --git a/Converter/src/mLibInclude.h b/Converter/src/mLibInclude.h new file mode 100644 index 0000000..6874251 --- /dev/null +++ b/Converter/src/mLibInclude.h @@ -0,0 +1,12 @@ + +// +// mLib includes +// + +#include "mLibCore.h" +//#include "mLibEigen.h" +#include "mLibLodePNG.h" +//#include "mLibZLib.h" +#include "mLibFreeImage.h" //This has to come after OpenMesh otherwise there is a crash +#include "mLibDepthCamera.h" + \ No newline at end of file diff --git a/Converter/src/mLibSource.cpp b/Converter/src/mLibSource.cpp new file mode 100644 index 0000000..826c78f --- /dev/null +++ b/Converter/src/mLibSource.cpp @@ -0,0 +1,7 @@ + +#include "stdafx.h" + +#include "mLibCore.cpp" +#include "mLibLodePNG.cpp" +//#include "mLibZLib.cpp" +#include "mLibDepthCamera.cpp" \ No newline at end of file diff --git a/Converter/src/metaData.h b/Converter/src/metaData.h new file mode 100644 index 0000000..6616c3f --- /dev/null +++ b/Converter/src/metaData.h @@ -0,0 +1,76 @@ + +#pragma once + +#include "stdafx.h" + +#ifndef VAR_NAME +#define VAR_NAME(x) #x +#endif + +struct MetaData { + + MetaData(const std::string& filename) { + loadFromFile(filename); + } + + void loadFromFile(const std::string& filename) { + ml::ParameterFile parameterFile(filename); + readParameter(parameterFile, std::string(VAR_NAME(numColorFrames)), numColorFrames); + readParameter(parameterFile, std::string(VAR_NAME(numDepthFrames)), numDepthFrames); + readParameter(parameterFile, std::string(VAR_NAME(numIMUmeasurements)), numIMUmeasurements); + readParameter(parameterFile, std::string(VAR_NAME(colorWidth)), colorWidth); + readParameter(parameterFile, std::string(VAR_NAME(colorHeight)), colorHeight); + readParameter(parameterFile, std::string(VAR_NAME(depthWidth)), depthWidth); + readParameter(parameterFile, std::string(VAR_NAME(depthHeight)), depthHeight); + + { + float fx_color, fy_color, mx_color, my_color; + readParameter(parameterFile, std::string(VAR_NAME(fx_color)), fx_color); + readParameter(parameterFile, std::string(VAR_NAME(fy_color)), fy_color); + readParameter(parameterFile, std::string(VAR_NAME(mx_color)), mx_color); + readParameter(parameterFile, std::string(VAR_NAME(my_color)), my_color); + colorCalibration = ml::SensorData::CalibrationData( + ml::mat4f( + fx_color, 0.0f, mx_color, 0.0f, + 0.0f, fy_color, my_color, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + ), + ml::mat4f::identity()); + } + { + float fx_depth, fy_depth, mx_depth, my_depth; + readParameter(parameterFile, std::string(VAR_NAME(fx_depth)), fx_depth); + readParameter(parameterFile, std::string(VAR_NAME(fy_depth)), fy_depth); + readParameter(parameterFile, std::string(VAR_NAME(mx_depth)), mx_depth); + readParameter(parameterFile, std::string(VAR_NAME(my_depth)), my_depth); + + ml::mat4f depthToColorExtrinsics = ml::mat4f::identity(); + if (readParameter(parameterFile, std::string(VAR_NAME(colorToDepthExtrinsics)), depthToColorExtrinsics)) depthToColorExtrinsics.invert(); + depthCalibration = ml::SensorData::CalibrationData( + ml::mat4f( + fx_depth, 0.0f, mx_depth, 0.0f, + 0.0f, fy_depth, my_depth, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + ), + depthToColorExtrinsics); + } + } + + template + bool readParameter(const ml::ParameterFile& pf, const std::string& varName, T& var) { + if (!pf.readParameter(varName, var)) { MLIB_WARNING(std::string(varName).append(" ").append("uninitialized")); return false; } + return true; + } + + unsigned int numColorFrames; + unsigned int numDepthFrames; + unsigned int numIMUmeasurements; + unsigned int colorWidth; + unsigned int colorHeight; + unsigned int depthWidth; + unsigned int depthHeight; + ml::SensorData::CalibrationData colorCalibration; + ml::SensorData::CalibrationData depthCalibration; +}; \ No newline at end of file diff --git a/Converter/src/targetver.h b/Converter/src/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/Converter/src/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/Converter/stdafx.cpp b/Converter/stdafx.cpp new file mode 100644 index 0000000..8a34e6e --- /dev/null +++ b/Converter/stdafx.cpp @@ -0,0 +1,10 @@ +// stdafx.cpp : source file that includes just the standard includes +// sensorFile.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file + +#include "mLibSource.cpp" diff --git a/Converter/stdafx.h b/Converter/stdafx.h new file mode 100644 index 0000000..99247d5 --- /dev/null +++ b/Converter/stdafx.h @@ -0,0 +1,18 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include +#include + +#include "WinSock2.h" +#include "windows.h" + +// TODO: reference additional headers your program requires here +#include "mLibInclude.h" + diff --git a/LICENSE b/LICENSE index 4faca51..1b0e2fa 100644 --- a/LICENSE +++ b/LICENSE @@ -1,457 +1,8 @@ +Copyright 2017 +Angela Dai, Angel X. Chang, Manolis Savva, Maciej Halber, Thomas Funkhouser, Matthias Niessner -Copyright (c) 2017 ScanNet - -ScanNet is licensed under a -Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. - - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - - - -Attribution-NonCommercial-ShareAlike 4.0 International - -======================================================================= - -Creative Commons Corporation ("Creative Commons") is not a law firm and -does not provide legal services or legal advice. Distribution of -Creative Commons public licenses does not create a lawyer-client or -other relationship. Creative Commons makes its licenses and related -information available on an "as-is" basis. Creative Commons gives no -warranties regarding its licenses, any material licensed under their -terms and conditions, or any related information. Creative Commons -disclaims all liability for damages resulting from their use to the -fullest extent possible. - -Using Creative Commons Public Licenses - -Creative Commons public licenses provide a standard set of terms and -conditions that creators and other rights holders may use to share -original works of authorship and other material subject to copyright -and certain other rights specified in the public license below. The -following considerations are for informational purposes only, are not -exhaustive, and do not form part of our licenses. - - Considerations for licensors: Our public licenses are - intended for use by those authorized to give the public - permission to use material in ways otherwise restricted by - copyright and certain other rights. Our licenses are - irrevocable. Licensors should read and understand the terms - and conditions of the license they choose before applying it. - Licensors should also secure all rights necessary before - applying our licenses so that the public can reuse the - material as expected. Licensors should clearly mark any - material not subject to the license. This includes other CC- - licensed material, or material used under an exception or - limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors - - Considerations for the public: By using one of our public - licenses, a licensor grants the public permission to use the - licensed material under specified terms and conditions. If - the licensor's permission is not necessary for any reason--for - example, because of any applicable exception or limitation to - copyright--then that use is not regulated by the license. Our - licenses grant only permissions under copyright and certain - other rights that a licensor has authority to grant. Use of - the licensed material may still be restricted for other - reasons, including because others have copyright or other - rights in the material. A licensor may make special requests, - such as asking that all changes be marked or described. - Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More_considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees - -======================================================================= - -Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International -Public License - -By exercising the Licensed Rights (defined below), You accept and agree -to be bound by the terms and conditions of this Creative Commons -Attribution-NonCommercial-ShareAlike 4.0 International Public License -("Public License"). To the extent this Public License may be -interpreted as a contract, You are granted the Licensed Rights in -consideration of Your acceptance of these terms and conditions, and the -Licensor grants You such rights in consideration of benefits the -Licensor receives from making the Licensed Material available under -these terms and conditions. - - -Section 1 -- Definitions. - - a. Adapted Material means material subject to Copyright and Similar - Rights that is derived from or based upon the Licensed Material - and in which the Licensed Material is translated, altered, - arranged, transformed, or otherwise modified in a manner requiring - permission under the Copyright and Similar Rights held by the - Licensor. For purposes of this Public License, where the Licensed - Material is a musical work, performance, or sound recording, - Adapted Material is always produced where the Licensed Material is - synched in timed relation with a moving image. - - b. Adapter's License means the license You apply to Your Copyright - and Similar Rights in Your contributions to Adapted Material in - accordance with the terms and conditions of this Public License. - - c. BY-NC-SA Compatible License means a license listed at - creativecommons.org/compatiblelicenses, approved by Creative - Commons as essentially the equivalent of this Public License. - - d. Copyright and Similar Rights means copyright and/or similar rights - closely related to copyright including, without limitation, - performance, broadcast, sound recording, and Sui Generis Database - Rights, without regard to how the rights are labeled or - categorized. For purposes of this Public License, the rights - specified in Section 2(b)(1)-(2) are not Copyright and Similar - Rights. - - e. Effective Technological Measures means those measures that, in the - absence of proper authority, may not be circumvented under laws - fulfilling obligations under Article 11 of the WIPO Copyright - Treaty adopted on December 20, 1996, and/or similar international - agreements. - - f. Exceptions and Limitations means fair use, fair dealing, and/or - any other exception or limitation to Copyright and Similar Rights - that applies to Your use of the Licensed Material. - - g. License Elements means the license attributes listed in the name - of a Creative Commons Public License. The License Elements of this - Public License are Attribution, NonCommercial, and ShareAlike. - - h. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - - i. Licensed Rights means the rights granted to You subject to the - terms and conditions of this Public License, which are limited to - all Copyright and Similar Rights that apply to Your use of the - Licensed Material and that the Licensor has authority to license. - - j. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - - k. NonCommercial means not primarily intended for or directed towards - commercial advantage or monetary compensation. For purposes of - this Public License, the exchange of the Licensed Material for - other material subject to Copyright and Similar Rights by digital - file-sharing or similar means is NonCommercial provided there is - no payment of monetary compensation in connection with the - exchange. - - l. Share means to provide material to the public by any means or - process that requires permission under the Licensed Rights, such - as reproduction, public display, public performance, distribution, - dissemination, communication, or importation, and to make material - available to the public including in ways that members of the - public may access the material from a place and at a time - individually chosen by them. - - m. Sui Generis Database Rights means rights other than copyright - resulting from Directive 96/9/EC of the European Parliament and of - the Council of 11 March 1996 on the legal protection of databases, - as amended and/or succeeded, as well as other essentially - equivalent rights anywhere in the world. - - n. You means the individual or entity exercising the Licensed Rights - under this Public License. Your has a corresponding meaning. - - -Section 2 -- Scope. - - a. License grant. - - 1. Subject to the terms and conditions of this Public License, - the Licensor hereby grants You a worldwide, royalty-free, - non-sublicensable, non-exclusive, irrevocable license to - exercise the Licensed Rights in the Licensed Material to: - - a. reproduce and Share the Licensed Material, in whole or - in part, for NonCommercial purposes only; and - - b. produce, reproduce, and Share Adapted Material for - NonCommercial purposes only. - - 2. Exceptions and Limitations. For the avoidance of doubt, where - Exceptions and Limitations apply to Your use, this Public - License does not apply, and You do not need to comply with - its terms and conditions. - - 3. Term. The term of this Public License is specified in Section - 6(a). - - 4. Media and formats; technical modifications allowed. The - Licensor authorizes You to exercise the Licensed Rights in - all media and formats whether now known or hereafter created, - and to make technical modifications necessary to do so. The - Licensor waives and/or agrees not to assert any right or - authority to forbid You from making technical modifications - necessary to exercise the Licensed Rights, including - technical modifications necessary to circumvent Effective - Technological Measures. For purposes of this Public License, - simply making modifications authorized by this Section 2(a) - (4) never produces Adapted Material. - - 5. Downstream recipients. - - a. Offer from the Licensor -- Licensed Material. Every - recipient of the Licensed Material automatically - receives an offer from the Licensor to exercise the - Licensed Rights under the terms and conditions of this - Public License. - - b. Additional offer from the Licensor -- Adapted Material. - Every recipient of Adapted Material from You - automatically receives an offer from the Licensor to - exercise the Licensed Rights in the Adapted Material - under the conditions of the Adapter's License You apply. - - c. No downstream restrictions. You may not offer or impose - any additional or different terms or conditions on, or - apply any Effective Technological Measures to, the - Licensed Material if doing so restricts exercise of the - Licensed Rights by any recipient of the Licensed - Material. - - 6. No endorsement. Nothing in this Public License constitutes or - may be construed as permission to assert or imply that You - are, or that Your use of the Licensed Material is, connected - with, or sponsored, endorsed, or granted official status by, - the Licensor or others designated to receive attribution as - provided in Section 3(a)(1)(A)(i). - - b. Other rights. - - 1. Moral rights, such as the right of integrity, are not - licensed under this Public License, nor are publicity, - privacy, and/or other similar personality rights; however, to - the extent possible, the Licensor waives and/or agrees not to - assert any such rights held by the Licensor to the limited - extent necessary to allow You to exercise the Licensed - Rights, but not otherwise. - - 2. Patent and trademark rights are not licensed under this - Public License. - - 3. To the extent possible, the Licensor waives any right to - collect royalties from You for the exercise of the Licensed - Rights, whether directly or through a collecting society - under any voluntary or waivable statutory or compulsory - licensing scheme. In all other cases the Licensor expressly - reserves any right to collect such royalties, including when - the Licensed Material is used other than for NonCommercial - purposes. - - -Section 3 -- License Conditions. - -Your exercise of the Licensed Rights is expressly made subject to the -following conditions. - - a. Attribution. - - 1. If You Share the Licensed Material (including in modified - form), You must: - - a. retain the following if it is supplied by the Licensor - with the Licensed Material: - - i. identification of the creator(s) of the Licensed - Material and any others designated to receive - attribution, in any reasonable manner requested by - the Licensor (including by pseudonym if - designated); - - ii. a copyright notice; - - iii. a notice that refers to this Public License; - - iv. a notice that refers to the disclaimer of - warranties; - - v. a URI or hyperlink to the Licensed Material to the - extent reasonably practicable; - - b. indicate if You modified the Licensed Material and - retain an indication of any previous modifications; and - - c. indicate the Licensed Material is licensed under this - Public License, and include the text of, or the URI or - hyperlink to, this Public License. - - 2. You may satisfy the conditions in Section 3(a)(1) in any - reasonable manner based on the medium, means, and context in - which You Share the Licensed Material. For example, it may be - reasonable to satisfy the conditions by providing a URI or - hyperlink to a resource that includes the required - information. - 3. If requested by the Licensor, You must remove any of the - information required by Section 3(a)(1)(A) to the extent - reasonably practicable. - - b. ShareAlike. - - In addition to the conditions in Section 3(a), if You Share - Adapted Material You produce, the following conditions also apply. - - 1. The Adapter's License You apply must be a Creative Commons - license with the same License Elements, this version or - later, or a BY-NC-SA Compatible License. - - 2. You must include the text of, or the URI or hyperlink to, the - Adapter's License You apply. You may satisfy this condition - in any reasonable manner based on the medium, means, and - context in which You Share Adapted Material. - - 3. You may not offer or impose any additional or different terms - or conditions on, or apply any Effective Technological - Measures to, Adapted Material that restrict exercise of the - rights granted under the Adapter's License You apply. - - -Section 4 -- Sui Generis Database Rights. - -Where the Licensed Rights include Sui Generis Database Rights that -apply to Your use of the Licensed Material: - - a. for the avoidance of doubt, Section 2(a)(1) grants You the right - to extract, reuse, reproduce, and Share all or a substantial - portion of the contents of the database for NonCommercial purposes - only; - - b. if You include all or a substantial portion of the database - contents in a database in which You have Sui Generis Database - Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material, - including for purposes of Section 3(b); and - - c. You must comply with the conditions in Section 3(a) if You Share - all or a substantial portion of the contents of the database. - -For the avoidance of doubt, this Section 4 supplements and does not -replace Your obligations under this Public License where the Licensed -Rights include other Copyright and Similar Rights. - - -Section 5 -- Disclaimer of Warranties and Limitation of Liability. - - a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE - EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS - AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF - ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, - IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, - WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, - ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT - KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT - ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. - - b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE - TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, - NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, - INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, - COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR - USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR - DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR - IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. - - c. The disclaimer of warranties and limitation of liability provided - above shall be interpreted in a manner that, to the extent - possible, most closely approximates an absolute disclaimer and - waiver of all liability. - - -Section 6 -- Term and Termination. - - a. This Public License applies for the term of the Copyright and - Similar Rights licensed here. However, if You fail to comply with - this Public License, then Your rights under this Public License - terminate automatically. - - b. Where Your right to use the Licensed Material has terminated under - Section 6(a), it reinstates: - - 1. automatically as of the date the violation is cured, provided - it is cured within 30 days of Your discovery of the - violation; or - - 2. upon express reinstatement by the Licensor. - - For the avoidance of doubt, this Section 6(b) does not affect any - right the Licensor may have to seek remedies for Your violations - of this Public License. - - c. For the avoidance of doubt, the Licensor may also offer the - Licensed Material under separate terms or conditions or stop - distributing the Licensed Material at any time; however, doing so - will not terminate this Public License. - - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public - License. - - -Section 7 -- Other Terms and Conditions. - - a. The Licensor shall not be bound by any additional or different - terms or conditions communicated by You unless expressly agreed. - - b. Any arrangements, understandings, or agreements regarding the - Licensed Material not stated herein are separate from and - independent of the terms and conditions of this Public License. - - -Section 8 -- Interpretation. - - a. For the avoidance of doubt, this Public License does not, and - shall not be interpreted to, reduce, limit, restrict, or impose - conditions on any use of the Licensed Material that could lawfully - be made without permission under this Public License. - - b. To the extent possible, if any provision of this Public License is - deemed unenforceable, it shall be automatically reformed to the - minimum extent necessary to make it enforceable. If the provision - cannot be reformed, it shall be severed from this Public License - without affecting the enforceability of the remaining terms and - conditions. - - c. No term or condition of this Public License will be waived and no - failure to comply consented to unless expressly agreed to by the - Licensor. - - d. Nothing in this Public License constitutes or may be interpreted - as a limitation upon, or waiver of, any privileges and immunities - that apply to the Licensor or You, including from the legal - processes of any jurisdiction or authority. - -======================================================================= - -Creative Commons is not a party to its public -licenses. Notwithstanding, Creative Commons may elect to apply one of -its public licenses to material it publishes and in those instances -will be considered the “Licensor.” The text of the Creative Commons -public licenses is dedicated to the public domain under the CC0 Public -Domain Dedication. Except for the limited purpose of indicating that -material is shared under a Creative Commons public license or as -otherwise permitted by the Creative Commons policies published at -creativecommons.org/policies, Creative Commons does not authorize the -use of the trademark "Creative Commons" or any other trademark or logo -of Creative Commons without its prior written consent including, -without limitation, in connection with any unauthorized modifications -to any of its public licenses or any other arrangements, -understandings, or agreements concerning use of licensed material. For -the avoidance of doubt, this paragraph does not form part of the -public licenses. - -Creative Commons may be contacted at creativecommons.org. +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 508d77d..17eed44 100644 --- a/README.md +++ b/README.md @@ -4,22 +4,39 @@ ScanNet is an RGB-D video dataset containing 2.5 million views in more than 1500 ## ScanNet Data -If you would like to download the ScanNet data, please fill out an agreement to the [ScanNet Terms of Use](http://dovahkiin.stanford.edu/scannet-public/ScanNet_TOS.pdf) and send it to us at scannet@googlegroups.com +If you would like to download the ScanNet data, fill out an agreement to the [ScanNet Terms of Use](http://kaldir.vc.cit.tum.de/scannet/ScanNet_TOS.pdf), using your institutional email addresses, and send it to us at scannet@googlegroups.com. + +If you have not received a response within a week, it is likely that your email is bouncing - please check this before sending repeat requests. Please do not reply to the noreply email - your email won't be seen. + +Please check the [changelog](http://www.scan-net.org/changelog) for updates to the data release. + ### Data Organization The data in ScanNet is organized by RGB-D sequence. Each sequence is stored under a directory with named `scene_`, or `scene%04d_%02d`, where each space corresponds to a unique location (0-indexed). The raw data captured during scanning, camera poses and surface mesh reconstructions, and annotation metadata are all stored together for the given sequence. The directory has the following structure: ```shell -|-- _vh.sens +|-- .sens RGB-D sensor stream containing color frames, depth frames, camera poses and other data -|-- _vh.ply +|-- _vh_clean.ply High quality reconstructed mesh |-- _vh_clean_2.ply Cleaned and decimated mesh for semantic annotations |-- _vh_clean_2.0.010000.segs.json Over-segmentation of annotation mesh -|-- .aggregation.json - Aggregated instance-level semantic annotations +|-- .aggregation.json, _vh_clean.aggregation.json + Aggregated instance-level semantic annotations on lo-res, hi-res meshes, respectively +|-- _vh_clean_2.0.010000.segs.json, _vh_clean.segs.json + Over-segmentation of lo-res, hi-res meshes, respectively (referenced by aggregated semantic annotations) +|-- _vh_clean_2.labels.ply + Visualization of aggregated semantic segmentation; colored by nyu40 labels (see img/legend; ply property 'label' denotes the nyu40 label id) +|-- _2d-label.zip + Raw 2d projections of aggregated annotation labels as 16-bit pngs with ScanNet label ids +|-- _2d-instance.zip + Raw 2d projections of aggregated annotation instances as 8-bit pngs +|-- _2d-label-filt.zip + Filtered 2d projections of aggregated annotation labels as 16-bit pngs with ScanNet label ids +|-- _2d-instance-filt.zip + Filtered 2d projections of aggregated annotation instances as 8-bit pngs ``` ### Data Formats @@ -29,7 +46,7 @@ The following are overviews of the data formats used in ScanNet: Binary PLY format mesh with +Z axis in upright orientation. **RGB-D sensor stream (`*.sens`)**: -Compressed binary format with per-frame color, depth, camera pose and other data. See [ScanNet C++ Toolkit](#scannet-c-toolkit) for more information and parsing code. +Compressed binary format with per-frame color, depth, camera pose and other data. See [ScanNet C++ Toolkit](#scannet-c-toolkit) for more information and parsing code. See [SensReader/python](SensReader/python) for a very basic python data exporter. **Surface mesh segmentation file (`*.segs.json`)**: ```javascript @@ -65,16 +82,43 @@ Compressed binary format with per-frame color, depth, camera pose and other data "segmentsFile": "..." // id of the *.segs.json segmentation file referenced } ``` +[BenchmarkScripts/util_3d.py](BenchmarkScripts/util_3d.py) gives examples to parsing the semantic instance information from the `*.segs.json`, `*.aggregation.json`, and `*_vh_clean_2.ply` mesh file, with example semantic segmentation visualization in [BenchmarkScripts/3d_helpers/visualize_labels_on_mesh.py](BenchmarkScripts/3d_helpers/visualize_labels_on_mesh.py). + +**2d annotation projections (`*_2d-label.zip`, `*_2d-instance.zip`, `*_2d-label-filt.zip`, `*_2d-instance-filt.zip`)**: +Projection of 3d aggregated annotation of a scan into its RGB-D frames, according to the computed camera trajectory. ### ScanNet C++ Toolkit -Tools for working with ScanNet data. +Tools for working with ScanNet data. [SensReader](SensReader) loads the ScanNet `.sens` data of compressed RGB-D frames, camera intrinsics and extrinsics, and IMU data. -* [SensReader](SensReader) loads the ScanNet `.sens` data of compressed RGB-D frames, camera intrinsics and extrinsics, and IMU data. +### Camera Parameter Estimation Code +Code for estimating camera parameters and depth undistortion. Required to compute sensor calibration files which are used by the pipeline server to undistort depth. See [CameraParameterEstimation](CameraParameterEstimation) for details. + +### Mesh Segmentation Code +Mesh supersegment computation code which we use to preprocess meshes and prepare for semantic annotation. Refer to [Segmentator](Segmentator) directory for building and using code. + +## BundleFusion Reconstruction Code + +ScanNet uses the [BundleFusion](https://github.com/niessner/BundleFusion) code for reconstruction. Please refer to the BundleFusion repository at https://github.com/niessner/BundleFusion . If you use BundleFusion, please cite the original paper: +``` +@article{dai2017bundlefusion, + title={BundleFusion: Real-time Globally Consistent 3D Reconstruction using On-the-fly Surface Re-integration}, + author={Dai, Angela and Nie{\ss}ner, Matthias and Zoll{\"o}fer, Michael and Izadi, Shahram and Theobalt, Christian}, + journal={ACM Transactions on Graphics 2017 (TOG)}, + year={2017} +} +``` ## ScanNet Scanner iPad App +[ScannerApp](ScannerApp) is designed for easy capture of RGB-D sequences using an iPad with attached Structure.io sensor. -* [ScannerApp](ScannerApp) is designed for easy capture of RGB-D sequences using an iPad with attached Structure.io sensor. +## ScanNet Scanner Data Server +[Server](Server) contains the server code that receives RGB-D sequences from iPads running the Scanner app. +## ScanNet Data Management UI +[WebUI](WebUI) contains the web-based data management UI used for providing an overview of available scan data and controlling the processing and annotation pipeline. + +## ScanNet Semantic Annotation Tools +Code and documentation for the ScanNet semantic annotation web-based interfaces is provided as part of the [SSTK](https://github.com/smartscenes/sstk) library. Please refer to https://github.com/smartscenes/sstk/wiki/Scan-Annotation-Pipeline for an overview. ## Benchmark Tasks We provide code for several scene understanding benchmarks on ScanNet: @@ -82,10 +126,13 @@ We provide code for several scene understanding benchmarks on ScanNet: * 3D object retrieval * Semantic voxel labeling -Trained models can be downloaded with the ScanNet data release. +Train/test splits are given at [Tasks/Benchmark](Tasks/Benchmark). +Label mappings and trained models can be downloaded with the ScanNet data release. See [Tasks](Tasks). +### Labels +The label mapping file (`scannet-labels.combined.tsv`) in the ScanNet task data release contains mappings from the labels provided in the ScanNet annotations (`id`) to the object category sets of [NYUv2](http://cs.nyu.edu/~silberman/datasets/nyu_depth_v2.html), [ModelNet](http://modelnet.cs.princeton.edu/), [ShapeNet](https://www.shapenet.org/), and [WordNet](https://wordnet.princeton.edu/) synsets. Download with along with the task data (`--task_data`) or by itself (`--label_map`). ## Citation If you use the ScanNet data or code please cite: @@ -104,7 +151,7 @@ If you have any questions, please contact us at scannet@googlegroups.com ## Changelog - ## License -The data is released under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 License. +The data is released under the [ScanNet Terms of Use](http://kaldir.vc.in.tum.de/scannet/ScanNet_TOS.pdf), and the code is released under the MIT license. + Copyright (c) 2017 diff --git a/ScannerApp/Frameworks/GPUImage/framework/GPUImage.xcodeproj/project.pbxproj b/ScannerApp/Frameworks/GPUImage/framework/GPUImage.xcodeproj/project.pbxproj index 462f2f2..ac85190 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/GPUImage.xcodeproj/project.pbxproj +++ b/ScannerApp/Frameworks/GPUImage/framework/GPUImage.xcodeproj/project.pbxproj @@ -1968,7 +1968,7 @@ isa = PBXProject; attributes = { LastTestingUpgradeCheck = 0510; - LastUpgradeCheck = 0700; + LastUpgradeCheck = 1000; ORGANIZATIONNAME = "Brad Larson"; TargetAttributes = { BCE209E41943F20C002FEED8 = { @@ -2401,6 +2401,7 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; @@ -2436,6 +2437,7 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; @@ -2466,11 +2468,21 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; @@ -2494,7 +2506,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; @@ -2508,11 +2520,21 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; @@ -2528,7 +2550,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; SYMROOT = "$(PROJECT_DIR)/../build"; diff --git a/ScannerApp/Frameworks/GPUImage/framework/GPUImage.xcodeproj/xcshareddata/xcschemes/Documentation.xcscheme b/ScannerApp/Frameworks/GPUImage/framework/GPUImage.xcodeproj/xcshareddata/xcschemes/Documentation.xcscheme index 880c931..9fe101f 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/GPUImage.xcodeproj/xcshareddata/xcschemes/Documentation.xcscheme +++ b/ScannerApp/Frameworks/GPUImage/framework/GPUImage.xcodeproj/xcshareddata/xcschemes/Documentation.xcscheme @@ -1,6 +1,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImage3x3TextureSamplingFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImage3x3TextureSamplingFilter.m index 05c4d50..0550f04 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImage3x3TextureSamplingFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImage3x3TextureSamplingFilter.m @@ -84,16 +84,16 @@ - (void)setupFilterForSize:(CGSize)filterFrameSize; _texelHeight = 1.0 / filterFrameSize.height; runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext setActiveShaderProgram:filterProgram]; - if (GPUImageRotationSwapsWidthAndHeight(inputRotation)) + [GPUImageContext setActiveShaderProgram:self->filterProgram]; + if (GPUImageRotationSwapsWidthAndHeight(self->inputRotation)) { - glUniform1f(texelWidthUniform, _texelHeight); - glUniform1f(texelHeightUniform, _texelWidth); + glUniform1f(self->texelWidthUniform, self->_texelHeight); + glUniform1f(self->texelHeightUniform, self->_texelWidth); } else { - glUniform1f(texelWidthUniform, _texelWidth); - glUniform1f(texelHeightUniform, _texelHeight); + glUniform1f(self->texelWidthUniform, self->_texelWidth); + glUniform1f(self->texelHeightUniform, self->_texelHeight); } }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageAverageColor.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageAverageColor.m index e2dd7e7..2135aaf 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageAverageColor.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageAverageColor.m @@ -168,25 +168,25 @@ - (void)extractAverageColorAtFrameTime:(CMTime)frameTime; NSAssert(self.outputTextureOptions.internalFormat == GL_RGBA, @"The output texture internal format for this filter must be GL_RGBA."); NSAssert(self.outputTextureOptions.type == GL_UNSIGNED_BYTE, @"The type of the output texture of this filter must be GL_UNSIGNED_BYTE."); - NSUInteger totalNumberOfPixels = round(finalStageSize.width * finalStageSize.height); + NSUInteger totalNumberOfPixels = round(self->finalStageSize.width * self->finalStageSize.height); - if (rawImagePixels == NULL) + if (self->rawImagePixels == NULL) { - rawImagePixels = (GLubyte *)malloc(totalNumberOfPixels * 4); + self->rawImagePixels = (GLubyte *)malloc(totalNumberOfPixels * 4); } [GPUImageContext useImageProcessingContext]; - [outputFramebuffer activateFramebuffer]; - glReadPixels(0, 0, (int)finalStageSize.width, (int)finalStageSize.height, GL_RGBA, GL_UNSIGNED_BYTE, rawImagePixels); + [self->outputFramebuffer activateFramebuffer]; + glReadPixels(0, 0, (int)self->finalStageSize.width, (int)self->finalStageSize.height, GL_RGBA, GL_UNSIGNED_BYTE, self->rawImagePixels); NSUInteger redTotal = 0, greenTotal = 0, blueTotal = 0, alphaTotal = 0; NSUInteger byteIndex = 0; for (NSUInteger currentPixel = 0; currentPixel < totalNumberOfPixels; currentPixel++) { - redTotal += rawImagePixels[byteIndex++]; - greenTotal += rawImagePixels[byteIndex++]; - blueTotal += rawImagePixels[byteIndex++]; - alphaTotal += rawImagePixels[byteIndex++]; + redTotal += self->rawImagePixels[byteIndex++]; + greenTotal += self->rawImagePixels[byteIndex++]; + blueTotal += self->rawImagePixels[byteIndex++]; + alphaTotal += self->rawImagePixels[byteIndex++]; } CGFloat normalizedRedTotal = (CGFloat)redTotal / (CGFloat)totalNumberOfPixels / 255.0; @@ -194,9 +194,9 @@ - (void)extractAverageColorAtFrameTime:(CMTime)frameTime; CGFloat normalizedBlueTotal = (CGFloat)blueTotal / (CGFloat)totalNumberOfPixels / 255.0; CGFloat normalizedAlphaTotal = (CGFloat)alphaTotal / (CGFloat)totalNumberOfPixels / 255.0; - if (_colorAverageProcessingFinishedBlock != NULL) + if (self->_colorAverageProcessingFinishedBlock != NULL) { - _colorAverageProcessingFinishedBlock(normalizedRedTotal, normalizedGreenTotal, normalizedBlueTotal, normalizedAlphaTotal, frameTime); + self->_colorAverageProcessingFinishedBlock(normalizedRedTotal, normalizedGreenTotal, normalizedBlueTotal, normalizedAlphaTotal, frameTime); } }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageColorPackingFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageColorPackingFilter.m index 1a087ca..e98ba09 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageColorPackingFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageColorPackingFilter.m @@ -100,9 +100,9 @@ - (void)setupFilterForSize:(CGSize)filterFrameSize; texelHeight = 0.5 / inputTextureSize.height; runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext setActiveShaderProgram:filterProgram]; - glUniform1f(texelWidthUniform, texelWidth); - glUniform1f(texelHeightUniform, texelHeight); + [GPUImageContext setActiveShaderProgram:self->filterProgram]; + glUniform1f(self->texelWidthUniform, self->texelWidth); + glUniform1f(self->texelHeightUniform, self->texelHeight); }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageColourFASTSamplingOperation.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageColourFASTSamplingOperation.m index fc67f47..b2107fe 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageColourFASTSamplingOperation.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageColourFASTSamplingOperation.m @@ -167,16 +167,16 @@ - (void)setupFilterForSize:(CGSize)filterFrameSize; _texelHeight = 1.0 / filterFrameSize.height; runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext setActiveShaderProgram:filterProgram]; - if (GPUImageRotationSwapsWidthAndHeight(inputRotation)) + [GPUImageContext setActiveShaderProgram:self->filterProgram]; + if (GPUImageRotationSwapsWidthAndHeight(self->inputRotation)) { - glUniform1f(texelWidthUniform, _texelHeight); - glUniform1f(texelHeightUniform, _texelWidth); + glUniform1f(self->texelWidthUniform, self->_texelHeight); + glUniform1f(self->texelHeightUniform, self->_texelWidth); } else { - glUniform1f(texelWidthUniform, _texelWidth); - glUniform1f(texelHeightUniform, _texelHeight); + glUniform1f(self->texelWidthUniform, self->_texelWidth); + glUniform1f(self->texelHeightUniform, self->_texelHeight); } }); } @@ -201,4 +201,4 @@ - (void)setTexelHeight:(CGFloat)newValue; [self setFloat:_texelHeight forUniform:texelHeightUniform program:filterProgram]; } -@end \ No newline at end of file +@end diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageCrosshairGenerator.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageCrosshairGenerator.m index 9e2a29a..9c70fc3 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageCrosshairGenerator.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageCrosshairGenerator.m @@ -71,8 +71,8 @@ - (id)init; } runSynchronouslyOnVideoProcessingQueue(^{ - crosshairWidthUniform = [filterProgram uniformIndex:@"crosshairWidth"]; - crosshairColorUniform = [filterProgram uniformIndex:@"crosshairColor"]; + self->crosshairWidthUniform = [self->filterProgram uniformIndex:@"crosshairWidth"]; + self->crosshairColorUniform = [self->filterProgram uniformIndex:@"crosshairColor"]; self.crosshairWidth = 5.0; [self setCrosshairColorRed:0.0 green:1.0 blue:0.0]; @@ -92,7 +92,7 @@ - (void)renderCrosshairsFromArray:(GLfloat *)crosshairCoordinates count:(NSUInte } runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext setActiveShaderProgram:filterProgram]; + [GPUImageContext setActiveShaderProgram:self->filterProgram]; #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE #else @@ -100,13 +100,13 @@ - (void)renderCrosshairsFromArray:(GLfloat *)crosshairCoordinates count:(NSUInte glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); #endif - outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:[self sizeOfFBO] textureOptions:self.outputTextureOptions onlyTexture:NO]; - [outputFramebuffer activateFramebuffer]; + self->outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:[self sizeOfFBO] textureOptions:self.outputTextureOptions onlyTexture:NO]; + [self->outputFramebuffer activateFramebuffer]; glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); - glVertexAttribPointer(filterPositionAttribute, 2, GL_FLOAT, 0, 0, crosshairCoordinates); + glVertexAttribPointer(self->filterPositionAttribute, 2, GL_FLOAT, 0, 0, crosshairCoordinates); glDrawArrays(GL_POINTS, 0, (GLsizei)numberOfCrosshairs); diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageDirectionalNonMaximumSuppressionFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageDirectionalNonMaximumSuppressionFilter.m index b442f3a..d317b2f 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageDirectionalNonMaximumSuppressionFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageDirectionalNonMaximumSuppressionFilter.m @@ -96,9 +96,9 @@ - (void)setupFilterForSize:(CGSize)filterFrameSize; _texelHeight = 1.0 / filterFrameSize.height; runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext setActiveShaderProgram:filterProgram]; - glUniform1f(texelWidthUniform, _texelWidth); - glUniform1f(texelHeightUniform, _texelHeight); + [GPUImageContext setActiveShaderProgram:self->filterProgram]; + glUniform1f(self->texelWidthUniform, self->_texelWidth); + glUniform1f(self->texelHeightUniform, self->_texelHeight); }); } } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFilter.m index 406d707..96d8563 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFilter.m @@ -76,33 +76,33 @@ - (id)initWithVertexShaderFromString:(NSString *)vertexShaderString fragmentShad runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - filterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:vertexShaderString fragmentShaderString:fragmentShaderString]; + self->filterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:vertexShaderString fragmentShaderString:fragmentShaderString]; - if (!filterProgram.initialized) + if (!self->filterProgram.initialized) { [self initializeAttributes]; - if (![filterProgram link]) + if (![self->filterProgram link]) { - NSString *progLog = [filterProgram programLog]; + NSString *progLog = [self->filterProgram programLog]; NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [filterProgram fragmentShaderLog]; + NSString *fragLog = [self->filterProgram fragmentShaderLog]; NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [filterProgram vertexShaderLog]; + NSString *vertLog = [self->filterProgram vertexShaderLog]; NSLog(@"Vertex shader compile log: %@", vertLog); - filterProgram = nil; + self->filterProgram = nil; NSAssert(NO, @"Filter shader link failed"); } } - filterPositionAttribute = [filterProgram attributeIndex:@"position"]; - filterTextureCoordinateAttribute = [filterProgram attributeIndex:@"inputTextureCoordinate"]; - filterInputTextureUniform = [filterProgram uniformIndex:@"inputImageTexture"]; // This does assume a name of "inputImageTexture" for the fragment shader + self->filterPositionAttribute = [self->filterProgram attributeIndex:@"position"]; + self->filterTextureCoordinateAttribute = [self->filterProgram attributeIndex:@"inputTextureCoordinate"]; + self->filterInputTextureUniform = [self->filterProgram uniformIndex:@"inputImageTexture"]; // This does assume a name of "inputImageTexture" for the fragment shader - [GPUImageContext setActiveShaderProgram:filterProgram]; + [GPUImageContext setActiveShaderProgram:self->filterProgram]; - glEnableVertexAttribArray(filterPositionAttribute); - glEnableVertexAttribArray(filterTextureCoordinateAttribute); + glEnableVertexAttribArray(self->filterPositionAttribute); + glEnableVertexAttribArray(self->filterTextureCoordinateAttribute); }); return self; diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFourInputFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFourInputFilter.m index bc660a3..b82558d 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFourInputFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFourInputFilter.m @@ -58,10 +58,10 @@ - (id)initWithVertexShaderFromString:(NSString *)vertexShaderString fragmentShad runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - filterFourthTextureCoordinateAttribute = [filterProgram attributeIndex:@"inputTextureCoordinate4"]; + self->filterFourthTextureCoordinateAttribute = [self->filterProgram attributeIndex:@"inputTextureCoordinate4"]; - filterInputTextureUniform4 = [filterProgram uniformIndex:@"inputImageTexture4"]; // This does assume a name of "inputImageTexture3" for the third input texture in the fragment shader - glEnableVertexAttribArray(filterFourthTextureCoordinateAttribute); + self->filterInputTextureUniform4 = [self->filterProgram uniformIndex:@"inputImageTexture4"]; // This does assume a name of "inputImageTexture3" for the third input texture in the fragment shader + glEnableVertexAttribArray(self->filterFourthTextureCoordinateAttribute); }); return self; diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFramebuffer.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFramebuffer.m index ea55c26..b71a2c9 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFramebuffer.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFramebuffer.m @@ -51,7 +51,7 @@ - (id)initWithSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)fbo runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; [self generateTexture]; - framebuffer = 0; + self->framebuffer = 0; }); } else @@ -133,8 +133,8 @@ - (void)generateFramebuffer; runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - glGenFramebuffers(1, &framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + glGenFramebuffers(1, &self->framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, self->framebuffer); // By default, all framebuffers on iOS 5.0+ devices are backed by texture caches, using one shared cache if ([GPUImageContext supportsFastTextureUpload]) @@ -149,23 +149,23 @@ - (void)generateFramebuffer; attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(attrs, kCVPixelBufferIOSurfacePropertiesKey, empty); - CVReturn err = CVPixelBufferCreate(kCFAllocatorDefault, (int)_size.width, (int)_size.height, kCVPixelFormatType_32BGRA, attrs, &renderTarget); + CVReturn err = CVPixelBufferCreate(kCFAllocatorDefault, (int)self->_size.width, (int)self->_size.height, kCVPixelFormatType_32BGRA, attrs, &self->renderTarget); if (err) { - NSLog(@"FBO size: %f, %f", _size.width, _size.height); + NSLog(@"FBO size: %f, %f", self->_size.width, self->_size.height); NSAssert(NO, @"Error at CVPixelBufferCreate %d", err); } - err = CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault, coreVideoTextureCache, renderTarget, + err = CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault, coreVideoTextureCache, self->renderTarget, NULL, // texture attributes GL_TEXTURE_2D, - _textureOptions.internalFormat, // opengl format - (int)_size.width, - (int)_size.height, - _textureOptions.format, // native iOS format - _textureOptions.type, + self->_textureOptions.internalFormat, // opengl format + (int)self.size.width, + (int)self.size.height, + self.textureOptions.format, // native iOS format + self.textureOptions.type, 0, - &renderTexture); + &self->renderTexture); if (err) { NSAssert(NO, @"Error at CVOpenGLESTextureCacheCreateTextureFromImage %d", err); @@ -174,22 +174,22 @@ - (void)generateFramebuffer; CFRelease(attrs); CFRelease(empty); - glBindTexture(CVOpenGLESTextureGetTarget(renderTexture), CVOpenGLESTextureGetName(renderTexture)); - _texture = CVOpenGLESTextureGetName(renderTexture); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _textureOptions.wrapS); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _textureOptions.wrapT); + glBindTexture(CVOpenGLESTextureGetTarget(self->renderTexture), CVOpenGLESTextureGetName(self->renderTexture)); + self->_texture = CVOpenGLESTextureGetName(self->renderTexture); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, self->_textureOptions.wrapS); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, self->_textureOptions.wrapT); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, CVOpenGLESTextureGetName(renderTexture), 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, CVOpenGLESTextureGetName(self->renderTexture), 0); #endif } else { [self generateTexture]; - glBindTexture(GL_TEXTURE_2D, _texture); + glBindTexture(GL_TEXTURE_2D, self->_texture); - glTexImage2D(GL_TEXTURE_2D, 0, _textureOptions.internalFormat, (int)_size.width, (int)_size.height, 0, _textureOptions.format, _textureOptions.type, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0); + glTexImage2D(GL_TEXTURE_2D, 0, self->_textureOptions.internalFormat, (int)self->_size.width, (int)self->_size.height, 0, self->_textureOptions.format, self->_textureOptions.type, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->_texture, 0); } #ifndef NS_BLOCK_ASSERTIONS @@ -206,32 +206,32 @@ - (void)destroyFramebuffer; runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - if (framebuffer) + if (self->framebuffer) { - glDeleteFramebuffers(1, &framebuffer); - framebuffer = 0; + glDeleteFramebuffers(1, &self->framebuffer); + self->framebuffer = 0; } - if ([GPUImageContext supportsFastTextureUpload] && (!_missingFramebuffer)) + if ([GPUImageContext supportsFastTextureUpload] && (!self->_missingFramebuffer)) { #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE - if (renderTarget) + if (self->renderTarget) { - CFRelease(renderTarget); - renderTarget = NULL; + CFRelease(self->renderTarget); + self->renderTarget = NULL; } - if (renderTexture) + if (self->renderTexture) { - CFRelease(renderTexture); - renderTexture = NULL; + CFRelease(self->renderTexture); + self->renderTexture = NULL; } #endif } else { - glDeleteTextures(1, &_texture); + glDeleteTextures(1, &self->_texture); } }); @@ -317,7 +317,7 @@ - (CGImageRef)newCGImageFromFramebufferContents; runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - NSUInteger totalBytesForImage = (int)_size.width * (int)_size.height * 4; + NSUInteger totalBytesForImage = (int)self->_size.width * (int)self->_size.height * 4; // It appears that the width of a texture must be padded out to be a multiple of 8 (32 bytes) if reading from it using a texture cache GLubyte *rawImagePixels; @@ -326,13 +326,13 @@ - (CGImageRef)newCGImageFromFramebufferContents; if ([GPUImageContext supportsFastTextureUpload]) { #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE - NSUInteger paddedWidthOfImage = CVPixelBufferGetBytesPerRow(renderTarget) / 4.0; - NSUInteger paddedBytesForImage = paddedWidthOfImage * (int)_size.height * 4; + NSUInteger paddedWidthOfImage = CVPixelBufferGetBytesPerRow(self->renderTarget) / 4.0; + NSUInteger paddedBytesForImage = paddedWidthOfImage * (int)self->_size.height * 4; glFinish(); - CFRetain(renderTarget); // I need to retain the pixel buffer here and release in the data source callback to prevent its bytes from being prematurely deallocated during a photo write operation + CFRetain(self->renderTarget); // I need to retain the pixel buffer here and release in the data source callback to prevent its bytes from being prematurely deallocated during a photo write operation [self lockForReading]; - rawImagePixels = (GLubyte *)CVPixelBufferGetBaseAddress(renderTarget); + rawImagePixels = (GLubyte *)CVPixelBufferGetBaseAddress(self->renderTarget); dataProvider = CGDataProviderCreateWithData((__bridge_retained void*)self, rawImagePixels, paddedBytesForImage, dataProviderUnlockCallback); [[GPUImageContext sharedFramebufferCache] addFramebufferToActiveImageCaptureList:self]; // In case the framebuffer is swapped out on the filter, need to have a strong reference to it somewhere for it to hang on while the image is in existence #else @@ -342,7 +342,7 @@ - (CGImageRef)newCGImageFromFramebufferContents; { [self activateFramebuffer]; rawImagePixels = (GLubyte *)malloc(totalBytesForImage); - glReadPixels(0, 0, (int)_size.width, (int)_size.height, GL_RGBA, GL_UNSIGNED_BYTE, rawImagePixels); + glReadPixels(0, 0, (int)self->_size.width, (int)self->_size.height, GL_RGBA, GL_UNSIGNED_BYTE, rawImagePixels); dataProvider = CGDataProviderCreateWithData(NULL, rawImagePixels, totalBytesForImage, dataProviderReleaseCallback); [self unlock]; // Don't need to keep this around anymore } @@ -352,13 +352,13 @@ - (CGImageRef)newCGImageFromFramebufferContents; if ([GPUImageContext supportsFastTextureUpload]) { #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE - cgImageFromBytes = CGImageCreate((int)_size.width, (int)_size.height, 8, 32, CVPixelBufferGetBytesPerRow(renderTarget), defaultRGBColorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst, dataProvider, NULL, NO, kCGRenderingIntentDefault); + cgImageFromBytes = CGImageCreate((int)self->_size.width, (int)self->_size.height, 8, 32, CVPixelBufferGetBytesPerRow(self->renderTarget), defaultRGBColorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst, dataProvider, NULL, NO, kCGRenderingIntentDefault); #else #endif } else { - cgImageFromBytes = CGImageCreate((int)_size.width, (int)_size.height, 8, 32, 4 * (int)_size.width, defaultRGBColorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaLast, dataProvider, NULL, NO, kCGRenderingIntentDefault); + cgImageFromBytes = CGImageCreate((int)self->_size.width, (int)self->_size.height, 8, 32, 4 * (int)self->_size.width, defaultRGBColorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaLast, dataProvider, NULL, NO, kCGRenderingIntentDefault); } // Capture image with current device orientation diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFramebufferCache.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFramebufferCache.m index 53faf2c..aa6e4b1 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFramebufferCache.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageFramebufferCache.m @@ -84,7 +84,7 @@ - (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize texture // dispatch_sync(framebufferCacheQueue, ^{ runSynchronouslyOnVideoProcessingQueue(^{ NSString *lookupHash = [self hashForSize:framebufferSize textureOptions:textureOptions onlyTexture:onlyTexture]; - NSNumber *numberOfMatchingTexturesInCache = [framebufferTypeCounts objectForKey:lookupHash]; + NSNumber *numberOfMatchingTexturesInCache = [self->framebufferTypeCounts objectForKey:lookupHash]; NSInteger numberOfMatchingTextures = [numberOfMatchingTexturesInCache integerValue]; if ([numberOfMatchingTexturesInCache integerValue] < 1) @@ -99,19 +99,19 @@ - (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize texture while ((framebufferFromCache == nil) && (currentTextureID >= 0)) { NSString *textureHash = [NSString stringWithFormat:@"%@-%ld", lookupHash, (long)currentTextureID]; - framebufferFromCache = [framebufferCache objectForKey:textureHash]; + framebufferFromCache = [self->framebufferCache objectForKey:textureHash]; // Test the values in the cache first, to see if they got invalidated behind our back if (framebufferFromCache != nil) { // Withdraw this from the cache while it's in use - [framebufferCache removeObjectForKey:textureHash]; + [self->framebufferCache removeObjectForKey:textureHash]; } currentTextureID--; } currentTextureID++; - [framebufferTypeCounts setObject:[NSNumber numberWithInteger:currentTextureID] forKey:lookupHash]; + [self->framebufferTypeCounts setObject:[NSNumber numberWithInteger:currentTextureID] forKey:lookupHash]; if (framebufferFromCache == nil) { @@ -147,14 +147,14 @@ - (void)returnFramebufferToCache:(GPUImageFramebuffer *)framebuffer; CGSize framebufferSize = framebuffer.size; GPUTextureOptions framebufferTextureOptions = framebuffer.textureOptions; NSString *lookupHash = [self hashForSize:framebufferSize textureOptions:framebufferTextureOptions onlyTexture:framebuffer.missingFramebuffer]; - NSNumber *numberOfMatchingTexturesInCache = [framebufferTypeCounts objectForKey:lookupHash]; + NSNumber *numberOfMatchingTexturesInCache = [self->framebufferTypeCounts objectForKey:lookupHash]; NSInteger numberOfMatchingTextures = [numberOfMatchingTexturesInCache integerValue]; NSString *textureHash = [NSString stringWithFormat:@"%@-%ld", lookupHash, (long)numberOfMatchingTextures]; // [framebufferCache setObject:framebuffer forKey:textureHash cost:round(framebufferSize.width * framebufferSize.height * 4.0)]; - [framebufferCache setObject:framebuffer forKey:textureHash]; - [framebufferTypeCounts setObject:[NSNumber numberWithInteger:(numberOfMatchingTextures + 1)] forKey:lookupHash]; + [self->framebufferCache setObject:framebuffer forKey:textureHash]; + [self->framebufferTypeCounts setObject:[NSNumber numberWithInteger:(numberOfMatchingTextures + 1)] forKey:lookupHash]; }); } @@ -162,8 +162,8 @@ - (void)purgeAllUnassignedFramebuffers; { runAsynchronouslyOnVideoProcessingQueue(^{ // dispatch_async(framebufferCacheQueue, ^{ - [framebufferCache removeAllObjects]; - [framebufferTypeCounts removeAllObjects]; + [self->framebufferCache removeAllObjects]; + [self->framebufferTypeCounts removeAllObjects]; #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE CVOpenGLESTextureCacheFlush([[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache], 0); #else @@ -175,7 +175,7 @@ - (void)addFramebufferToActiveImageCaptureList:(GPUImageFramebuffer *)framebuffe { runAsynchronouslyOnVideoProcessingQueue(^{ // dispatch_async(framebufferCacheQueue, ^{ - [activeImageCaptureList addObject:framebuffer]; + [self->activeImageCaptureList addObject:framebuffer]; }); } @@ -183,7 +183,7 @@ - (void)removeFramebufferFromActiveImageCaptureList:(GPUImageFramebuffer *)frame { runAsynchronouslyOnVideoProcessingQueue(^{ // dispatch_async(framebufferCacheQueue, ^{ - [activeImageCaptureList removeObject:framebuffer]; + [self->activeImageCaptureList removeObject:framebuffer]; }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageGaussianBlurFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageGaussianBlurFilter.m index ec99352..65e25f1 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageGaussianBlurFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageGaussianBlurFilter.m @@ -383,64 +383,64 @@ - (void)switchToVertexShader:(NSString *)newVertexShader fragmentShader:(NSStrin runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - filterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:newVertexShader fragmentShaderString:newFragmentShader]; + self->filterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:newVertexShader fragmentShaderString:newFragmentShader]; - if (!filterProgram.initialized) + if (!self->filterProgram.initialized) { [self initializeAttributes]; - if (![filterProgram link]) + if (![self->filterProgram link]) { - NSString *progLog = [filterProgram programLog]; + NSString *progLog = [self->filterProgram programLog]; NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [filterProgram fragmentShaderLog]; + NSString *fragLog = [self->filterProgram fragmentShaderLog]; NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [filterProgram vertexShaderLog]; + NSString *vertLog = [self->filterProgram vertexShaderLog]; NSLog(@"Vertex shader compile log: %@", vertLog); - filterProgram = nil; + self->filterProgram = nil; NSAssert(NO, @"Filter shader link failed"); } } - filterPositionAttribute = [filterProgram attributeIndex:@"position"]; - filterTextureCoordinateAttribute = [filterProgram attributeIndex:@"inputTextureCoordinate"]; - filterInputTextureUniform = [filterProgram uniformIndex:@"inputImageTexture"]; // This does assume a name of "inputImageTexture" for the fragment shader - verticalPassTexelWidthOffsetUniform = [filterProgram uniformIndex:@"texelWidthOffset"]; - verticalPassTexelHeightOffsetUniform = [filterProgram uniformIndex:@"texelHeightOffset"]; - [GPUImageContext setActiveShaderProgram:filterProgram]; + self->filterPositionAttribute = [self->filterProgram attributeIndex:@"position"]; + self->filterTextureCoordinateAttribute = [self->filterProgram attributeIndex:@"inputTextureCoordinate"]; + self->filterInputTextureUniform = [self->filterProgram uniformIndex:@"inputImageTexture"]; // This does assume a name of "inputImageTexture" for the fragment shader + self->verticalPassTexelWidthOffsetUniform = [self->filterProgram uniformIndex:@"texelWidthOffset"]; + self->verticalPassTexelHeightOffsetUniform = [self->filterProgram uniformIndex:@"texelHeightOffset"]; + [GPUImageContext setActiveShaderProgram:self->filterProgram]; - glEnableVertexAttribArray(filterPositionAttribute); - glEnableVertexAttribArray(filterTextureCoordinateAttribute); + glEnableVertexAttribArray(self->filterPositionAttribute); + glEnableVertexAttribArray(self->filterTextureCoordinateAttribute); - secondFilterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:newVertexShader fragmentShaderString:newFragmentShader]; + self->secondFilterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:newVertexShader fragmentShaderString:newFragmentShader]; - if (!secondFilterProgram.initialized) + if (!self->secondFilterProgram.initialized) { [self initializeSecondaryAttributes]; - if (![secondFilterProgram link]) + if (![self->secondFilterProgram link]) { - NSString *progLog = [secondFilterProgram programLog]; + NSString *progLog = [self->secondFilterProgram programLog]; NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [secondFilterProgram fragmentShaderLog]; + NSString *fragLog = [self->secondFilterProgram fragmentShaderLog]; NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [secondFilterProgram vertexShaderLog]; + NSString *vertLog = [self->secondFilterProgram vertexShaderLog]; NSLog(@"Vertex shader compile log: %@", vertLog); - secondFilterProgram = nil; + self->secondFilterProgram = nil; NSAssert(NO, @"Filter shader link failed"); } } - secondFilterPositionAttribute = [secondFilterProgram attributeIndex:@"position"]; - secondFilterTextureCoordinateAttribute = [secondFilterProgram attributeIndex:@"inputTextureCoordinate"]; - secondFilterInputTextureUniform = [secondFilterProgram uniformIndex:@"inputImageTexture"]; // This does assume a name of "inputImageTexture" for the fragment shader - secondFilterInputTextureUniform2 = [secondFilterProgram uniformIndex:@"inputImageTexture2"]; // This does assume a name of "inputImageTexture2" for second input texture in the fragment shader - horizontalPassTexelWidthOffsetUniform = [secondFilterProgram uniformIndex:@"texelWidthOffset"]; - horizontalPassTexelHeightOffsetUniform = [secondFilterProgram uniformIndex:@"texelHeightOffset"]; - [GPUImageContext setActiveShaderProgram:secondFilterProgram]; - - glEnableVertexAttribArray(secondFilterPositionAttribute); - glEnableVertexAttribArray(secondFilterTextureCoordinateAttribute); + self->secondFilterPositionAttribute = [self->secondFilterProgram attributeIndex:@"position"]; + self->secondFilterTextureCoordinateAttribute = [self->secondFilterProgram attributeIndex:@"inputTextureCoordinate"]; + self->secondFilterInputTextureUniform = [self->secondFilterProgram uniformIndex:@"inputImageTexture"]; // This does assume a name of "inputImageTexture" for the fragment shader + self->secondFilterInputTextureUniform2 = [self->secondFilterProgram uniformIndex:@"inputImageTexture2"]; // This does assume a name of "inputImageTexture2" for second input texture in the fragment shader + self->horizontalPassTexelWidthOffsetUniform = [self->secondFilterProgram uniformIndex:@"texelWidthOffset"]; + self->horizontalPassTexelHeightOffsetUniform = [self->secondFilterProgram uniformIndex:@"texelHeightOffset"]; + [GPUImageContext setActiveShaderProgram:self->secondFilterProgram]; + + glEnableVertexAttribArray(self->secondFilterPositionAttribute); + glEnableVertexAttribArray(self->secondFilterTextureCoordinateAttribute); [self setupFilterForSize:[self sizeOfFBO]]; glFinish(); diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageHistogramFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageHistogramFilter.m index bb7acce..9664144 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageHistogramFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageHistogramFilter.m @@ -145,50 +145,50 @@ - (id)initWithHistogramType:(GPUImageHistogramType)newHistogramType; runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - secondFilterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageGreenHistogramSamplingVertexShaderString fragmentShaderString:kGPUImageHistogramAccumulationFragmentShaderString]; - thirdFilterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageBlueHistogramSamplingVertexShaderString fragmentShaderString:kGPUImageHistogramAccumulationFragmentShaderString]; + self->secondFilterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageGreenHistogramSamplingVertexShaderString fragmentShaderString:kGPUImageHistogramAccumulationFragmentShaderString]; + self->thirdFilterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageBlueHistogramSamplingVertexShaderString fragmentShaderString:kGPUImageHistogramAccumulationFragmentShaderString]; - if (!secondFilterProgram.initialized) + if (!self->secondFilterProgram.initialized) { [self initializeSecondaryAttributes]; - if (![secondFilterProgram link]) + if (![self->secondFilterProgram link]) { - NSString *progLog = [secondFilterProgram programLog]; + NSString *progLog = [self->secondFilterProgram programLog]; NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [secondFilterProgram fragmentShaderLog]; + NSString *fragLog = [self->secondFilterProgram fragmentShaderLog]; NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [secondFilterProgram vertexShaderLog]; + NSString *vertLog = [self->secondFilterProgram vertexShaderLog]; NSLog(@"Vertex shader compile log: %@", vertLog); - filterProgram = nil; + self->filterProgram = nil; NSAssert(NO, @"Filter shader link failed"); } - [GPUImageContext setActiveShaderProgram:secondFilterProgram]; + [GPUImageContext setActiveShaderProgram:self->secondFilterProgram]; - glEnableVertexAttribArray(secondFilterPositionAttribute); + glEnableVertexAttribArray(self->secondFilterPositionAttribute); - if (![thirdFilterProgram link]) + if (![self->thirdFilterProgram link]) { - NSString *progLog = [secondFilterProgram programLog]; + NSString *progLog = [self->secondFilterProgram programLog]; NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [secondFilterProgram fragmentShaderLog]; + NSString *fragLog = [self->secondFilterProgram fragmentShaderLog]; NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [secondFilterProgram vertexShaderLog]; + NSString *vertLog = [self->secondFilterProgram vertexShaderLog]; NSLog(@"Vertex shader compile log: %@", vertLog); - filterProgram = nil; + self->filterProgram = nil; NSAssert(NO, @"Filter shader link failed"); } } - secondFilterPositionAttribute = [secondFilterProgram attributeIndex:@"position"]; + self->secondFilterPositionAttribute = [self->secondFilterProgram attributeIndex:@"position"]; - thirdFilterPositionAttribute = [thirdFilterProgram attributeIndex:@"position"]; - [GPUImageContext setActiveShaderProgram:thirdFilterProgram]; + self->thirdFilterPositionAttribute = [self->thirdFilterProgram attributeIndex:@"position"]; + [GPUImageContext setActiveShaderProgram:self->thirdFilterProgram]; - glEnableVertexAttribArray(thirdFilterPositionAttribute); + glEnableVertexAttribArray(self->thirdFilterPositionAttribute); }); }; break; } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageLanczosResamplingFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageLanczosResamplingFilter.m index a655f48..506359d 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageLanczosResamplingFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageLanczosResamplingFilter.m @@ -145,19 +145,19 @@ - (void)setupFilterForSize:(CGSize)filterFrameSize; { runSynchronouslyOnVideoProcessingQueue(^{ // The first pass through the framebuffer may rotate the inbound image, so need to account for that by changing up the kernel ordering for that pass - if (GPUImageRotationSwapsWidthAndHeight(inputRotation)) + if (GPUImageRotationSwapsWidthAndHeight(self->inputRotation)) { - verticalPassTexelWidthOffset = 1.0 / _originalImageSize.height; - verticalPassTexelHeightOffset = 0.0; + self->verticalPassTexelWidthOffset = 1.0 / self->_originalImageSize.height; + self->verticalPassTexelHeightOffset = 0.0; } else { - verticalPassTexelWidthOffset = 0.0; - verticalPassTexelHeightOffset = 1.0 / _originalImageSize.height; + self->verticalPassTexelWidthOffset = 0.0; + self->verticalPassTexelHeightOffset = 1.0 / self->_originalImageSize.height; } - horizontalPassTexelWidthOffset = 1.0 / _originalImageSize.width; - horizontalPassTexelHeightOffset = 0.0; + self->horizontalPassTexelWidthOffset = 1.0 / self->_originalImageSize.width; + self->horizontalPassTexelHeightOffset = 0.0; }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageLineGenerator.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageLineGenerator.m index 85d93be..52b8662 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageLineGenerator.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageLineGenerator.m @@ -53,8 +53,8 @@ - (id)init; } runSynchronouslyOnVideoProcessingQueue(^{ - lineWidthUniform = [filterProgram uniformIndex:@"lineWidth"]; - lineColorUniform = [filterProgram uniformIndex:@"lineColor"]; + self->lineWidthUniform = [self->filterProgram uniformIndex:@"lineWidth"]; + self->lineColorUniform = [self->filterProgram uniformIndex:@"lineColor"]; self.lineWidth = 1.0; [self setLineColorRed:0.0 green:1.0 blue:0.0]; @@ -117,10 +117,10 @@ - (void)renderLinesFromArray:(GLfloat *)lineSlopeAndIntercepts count:(NSUInteger } runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext setActiveShaderProgram:filterProgram]; + [GPUImageContext setActiveShaderProgram:self->filterProgram]; - outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:[self sizeOfFBO] textureOptions:self.outputTextureOptions onlyTexture:NO]; - [outputFramebuffer activateFramebuffer]; + self->outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:[self sizeOfFBO] textureOptions:self.outputTextureOptions onlyTexture:NO]; + [self->outputFramebuffer activateFramebuffer]; glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); @@ -129,7 +129,7 @@ - (void)renderLinesFromArray:(GLfloat *)lineSlopeAndIntercepts count:(NSUInteger glBlendFunc(GL_ONE, GL_ONE); glEnable(GL_BLEND); - glVertexAttribPointer(filterPositionAttribute, 2, GL_FLOAT, 0, 0, lineCoordinates); + glVertexAttribPointer(self->filterPositionAttribute, 2, GL_FLOAT, 0, 0, self->lineCoordinates); glDrawArrays(GL_LINES, 0, ((unsigned int)numberOfLines * 2)); glDisable(GL_BLEND); diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageLuminosity.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageLuminosity.m index 37f374a..f3b3cab 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageLuminosity.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageLuminosity.m @@ -127,37 +127,37 @@ - (id)init; runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - secondFilterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageColorAveragingVertexShaderString fragmentShaderString:kGPUImageLuminosityFragmentShaderString]; + self->secondFilterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageColorAveragingVertexShaderString fragmentShaderString:kGPUImageLuminosityFragmentShaderString]; - if (!secondFilterProgram.initialized) + if (!self->secondFilterProgram.initialized) { [self initializeSecondaryAttributes]; - if (![secondFilterProgram link]) + if (![self->secondFilterProgram link]) { - NSString *progLog = [secondFilterProgram programLog]; + NSString *progLog = [self->secondFilterProgram programLog]; NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [secondFilterProgram fragmentShaderLog]; + NSString *fragLog = [self->secondFilterProgram fragmentShaderLog]; NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [secondFilterProgram vertexShaderLog]; + NSString *vertLog = [self->secondFilterProgram vertexShaderLog]; NSLog(@"Vertex shader compile log: %@", vertLog); - filterProgram = nil; + self->filterProgram = nil; NSAssert(NO, @"Filter shader link failed"); } } - secondFilterPositionAttribute = [secondFilterProgram attributeIndex:@"position"]; - secondFilterTextureCoordinateAttribute = [secondFilterProgram attributeIndex:@"inputTextureCoordinate"]; - secondFilterInputTextureUniform = [secondFilterProgram uniformIndex:@"inputImageTexture"]; // This does assume a name of "inputImageTexture" for the fragment shader - secondFilterInputTextureUniform2 = [secondFilterProgram uniformIndex:@"inputImageTexture2"]; // This does assume a name of "inputImageTexture2" for second input texture in the fragment shader + self->secondFilterPositionAttribute = [self->secondFilterProgram attributeIndex:@"position"]; + self->secondFilterTextureCoordinateAttribute = [self->secondFilterProgram attributeIndex:@"inputTextureCoordinate"]; + self->secondFilterInputTextureUniform = [self->secondFilterProgram uniformIndex:@"inputImageTexture"]; // This does assume a name of "inputImageTexture" for the fragment shader + self->secondFilterInputTextureUniform2 = [self->secondFilterProgram uniformIndex:@"inputImageTexture2"]; // This does assume a name of "inputImageTexture2" for second input texture in the fragment shader - secondFilterTexelWidthUniform = [secondFilterProgram uniformIndex:@"texelWidth"]; - secondFilterTexelHeightUniform = [secondFilterProgram uniformIndex:@"texelHeight"]; + self->secondFilterTexelWidthUniform = [self->secondFilterProgram uniformIndex:@"texelWidth"]; + self->secondFilterTexelHeightUniform = [self->secondFilterProgram uniformIndex:@"texelHeight"]; - [GPUImageContext setActiveShaderProgram:secondFilterProgram]; + [GPUImageContext setActiveShaderProgram:self->secondFilterProgram]; - glEnableVertexAttribArray(secondFilterPositionAttribute); - glEnableVertexAttribArray(secondFilterTextureCoordinateAttribute); + glEnableVertexAttribArray(self->secondFilterPositionAttribute); + glEnableVertexAttribArray(self->secondFilterTextureCoordinateAttribute); }); return self; @@ -296,31 +296,31 @@ - (void)extractLuminosityAtFrameTime:(CMTime)frameTime; NSAssert(self.outputTextureOptions.internalFormat == GL_RGBA, @"The output texture format for this filter must be GL_RGBA."); NSAssert(self.outputTextureOptions.type == GL_UNSIGNED_BYTE, @"The type of the output texture of this filter must be GL_UNSIGNED_BYTE."); - NSUInteger totalNumberOfPixels = round(finalStageSize.width * finalStageSize.height); + NSUInteger totalNumberOfPixels = round(self->finalStageSize.width * self->finalStageSize.height); - if (rawImagePixels == NULL) + if (self->rawImagePixels == NULL) { - rawImagePixels = (GLubyte *)malloc(totalNumberOfPixels * 4); + self->rawImagePixels = (GLubyte *)malloc(totalNumberOfPixels * 4); } [GPUImageContext useImageProcessingContext]; - [outputFramebuffer activateFramebuffer]; + [self->outputFramebuffer activateFramebuffer]; - glReadPixels(0, 0, (int)finalStageSize.width, (int)finalStageSize.height, GL_RGBA, GL_UNSIGNED_BYTE, rawImagePixels); + glReadPixels(0, 0, (int)self->finalStageSize.width, (int)self->finalStageSize.height, GL_RGBA, GL_UNSIGNED_BYTE, self->rawImagePixels); NSUInteger luminanceTotal = 0; NSUInteger byteIndex = 0; for (NSUInteger currentPixel = 0; currentPixel < totalNumberOfPixels; currentPixel++) { - luminanceTotal += rawImagePixels[byteIndex]; + luminanceTotal += self->rawImagePixels[byteIndex]; byteIndex += 4; } CGFloat normalizedLuminosityTotal = (CGFloat)luminanceTotal / (CGFloat)totalNumberOfPixels / 255.0; - if (_luminosityProcessingFinishedBlock != NULL) + if (self->_luminosityProcessingFinishedBlock != NULL) { - _luminosityProcessingFinishedBlock(normalizedLuminosityTotal, frameTime); + self->_luminosityProcessingFinishedBlock(normalizedLuminosityTotal, frameTime); } }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageMovie.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageMovie.m index 4da050f..7e3de6e 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageMovie.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageMovie.m @@ -101,38 +101,38 @@ - (void)yuvConversionSetup; runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - _preferredConversion = kColorConversion709; - isFullYUVRange = YES; - yuvConversionProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageYUVFullRangeConversionForLAFragmentShaderString]; + self->_preferredConversion = kColorConversion709; + self->isFullYUVRange = YES; + self->yuvConversionProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageYUVFullRangeConversionForLAFragmentShaderString]; - if (!yuvConversionProgram.initialized) + if (!self->yuvConversionProgram.initialized) { - [yuvConversionProgram addAttribute:@"position"]; - [yuvConversionProgram addAttribute:@"inputTextureCoordinate"]; + [self->yuvConversionProgram addAttribute:@"position"]; + [self->yuvConversionProgram addAttribute:@"inputTextureCoordinate"]; - if (![yuvConversionProgram link]) + if (![self->yuvConversionProgram link]) { - NSString *progLog = [yuvConversionProgram programLog]; + NSString *progLog = [self->yuvConversionProgram programLog]; NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [yuvConversionProgram fragmentShaderLog]; + NSString *fragLog = [self->yuvConversionProgram fragmentShaderLog]; NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [yuvConversionProgram vertexShaderLog]; + NSString *vertLog = [self->yuvConversionProgram vertexShaderLog]; NSLog(@"Vertex shader compile log: %@", vertLog); - yuvConversionProgram = nil; + self->yuvConversionProgram = nil; NSAssert(NO, @"Filter shader link failed"); } } - yuvConversionPositionAttribute = [yuvConversionProgram attributeIndex:@"position"]; - yuvConversionTextureCoordinateAttribute = [yuvConversionProgram attributeIndex:@"inputTextureCoordinate"]; - yuvConversionLuminanceTextureUniform = [yuvConversionProgram uniformIndex:@"luminanceTexture"]; - yuvConversionChrominanceTextureUniform = [yuvConversionProgram uniformIndex:@"chrominanceTexture"]; - yuvConversionMatrixUniform = [yuvConversionProgram uniformIndex:@"colorConversionMatrix"]; + self->yuvConversionPositionAttribute = [self->yuvConversionProgram attributeIndex:@"position"]; + self->yuvConversionTextureCoordinateAttribute = [self->yuvConversionProgram attributeIndex:@"inputTextureCoordinate"]; + self->yuvConversionLuminanceTextureUniform = [self->yuvConversionProgram uniformIndex:@"luminanceTexture"]; + self->yuvConversionChrominanceTextureUniform = [self->yuvConversionProgram uniformIndex:@"chrominanceTexture"]; + self->yuvConversionMatrixUniform = [self->yuvConversionProgram uniformIndex:@"colorConversionMatrix"]; - [GPUImageContext setActiveShaderProgram:yuvConversionProgram]; + [GPUImageContext setActiveShaderProgram:self->yuvConversionProgram]; - glEnableVertexAttribArray(yuvConversionPositionAttribute); - glEnableVertexAttribArray(yuvConversionTextureCoordinateAttribute); + glEnableVertexAttribArray(self->yuvConversionPositionAttribute); + glEnableVertexAttribArray(self->yuvConversionTextureCoordinateAttribute); }); } } @@ -317,9 +317,9 @@ - (void)processPlayerItem runSynchronouslyOnVideoProcessingQueue(^{ #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE - displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkCallback:)]; - [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; - [displayLink setPaused:YES]; + self->displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkCallback:)]; + [self->displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + [self->displayLink setPaused:YES]; #else // Suggested implementation: use CVDisplayLink http://stackoverflow.com/questions/14158743/alternative-of-cadisplaylink-for-mac-os-x CGDirectDisplayID displayID = CGMainDisplayID(); @@ -342,11 +342,11 @@ - (void)processPlayerItem else { [pixBuffAttributes setObject:@(kCVPixelFormatType_32BGRA) forKey:(id)kCVPixelBufferPixelFormatTypeKey]; } - playerItemOutput = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:pixBuffAttributes]; - [playerItemOutput setDelegate:self queue:videoProcessingQueue]; + self->playerItemOutput = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:pixBuffAttributes]; + [self->playerItemOutput setDelegate:self queue:videoProcessingQueue]; - [_playerItem addOutput:playerItemOutput]; - [playerItemOutput requestNotificationOfMediaDataChangeWithAdvanceInterval:0.1]; + [self->_playerItem addOutput:self->playerItemOutput]; + [self->playerItemOutput requestNotificationOfMediaDataChangeWithAdvanceInterval:0.1]; }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageOutput.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageOutput.m index d9bdaef..56f8159 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageOutput.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageOutput.m @@ -225,10 +225,10 @@ - (void)addTarget:(id)newTarget atTextureLocation:(NSInteger)text cachedMaximumOutputSize = CGSizeZero; runSynchronouslyOnVideoProcessingQueue(^{ [self setInputFramebufferForTarget:newTarget atIndex:textureLocation]; - [targets addObject:newTarget]; - [targetTextureIndices addObject:[NSNumber numberWithInteger:textureLocation]]; + [self->targets addObject:newTarget]; + [self->targetTextureIndices addObject:[NSNumber numberWithInteger:textureLocation]]; - allTargetsWantMonochromeData = allTargetsWantMonochromeData && [newTarget wantsMonochromeInput]; + self->allTargetsWantMonochromeData = self->allTargetsWantMonochromeData && [newTarget wantsMonochromeInput]; }); } @@ -253,8 +253,8 @@ - (void)removeTarget:(id)targetToRemove; [targetToRemove setInputSize:CGSizeZero atIndex:textureIndexOfTarget]; [targetToRemove setInputRotation:kGPUImageNoRotation atIndex:textureIndexOfTarget]; - [targetTextureIndices removeObjectAtIndex:indexOfObject]; - [targets removeObject:targetToRemove]; + [self->targetTextureIndices removeObjectAtIndex:indexOfObject]; + [self->targets removeObject:targetToRemove]; [targetToRemove endProcessing]; }); } @@ -263,18 +263,18 @@ - (void)removeAllTargets; { cachedMaximumOutputSize = CGSizeZero; runSynchronouslyOnVideoProcessingQueue(^{ - for (id targetToRemove in targets) + for (id targetToRemove in self->targets) { - NSInteger indexOfObject = [targets indexOfObject:targetToRemove]; - NSInteger textureIndexOfTarget = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue]; + NSInteger indexOfObject = [self->targets indexOfObject:targetToRemove]; + NSInteger textureIndexOfTarget = [[self->targetTextureIndices objectAtIndex:indexOfObject] integerValue]; [targetToRemove setInputSize:CGSizeZero atIndex:textureIndexOfTarget]; [targetToRemove setInputRotation:kGPUImageNoRotation atIndex:textureIndexOfTarget]; } - [targets removeAllObjects]; - [targetTextureIndices removeAllObjects]; + [self->targets removeAllObjects]; + [self->targetTextureIndices removeAllObjects]; - allTargetsWantMonochromeData = YES; + self->allTargetsWantMonochromeData = YES; }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageRawDataInput.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageRawDataInput.m index cfa3b12..05c2c87 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageRawDataInput.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageRawDataInput.m @@ -93,17 +93,17 @@ - (void)processData; CGSize pixelSizeOfImage = [self outputImageSize]; - for (id currentTarget in targets) + for (id currentTarget in self->targets) { - NSInteger indexOfObject = [targets indexOfObject:currentTarget]; - NSInteger textureIndexOfTarget = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue]; + NSInteger indexOfObject = [self->targets indexOfObject:currentTarget]; + NSInteger textureIndexOfTarget = [[self->targetTextureIndices objectAtIndex:indexOfObject] integerValue]; [currentTarget setInputSize:pixelSizeOfImage atIndex:textureIndexOfTarget]; - [currentTarget setInputFramebuffer:outputFramebuffer atIndex:textureIndexOfTarget]; + [currentTarget setInputFramebuffer:self->outputFramebuffer atIndex:textureIndexOfTarget]; [currentTarget newFrameReadyAtTime:kCMTimeInvalid atIndex:textureIndexOfTarget]; } - dispatch_semaphore_signal(dataUpdateSemaphore); + dispatch_semaphore_signal(self->dataUpdateSemaphore); }); } @@ -118,16 +118,16 @@ - (void)processDataForTimestamp:(CMTime)frameTime; CGSize pixelSizeOfImage = [self outputImageSize]; - for (id currentTarget in targets) + for (id currentTarget in self->targets) { - NSInteger indexOfObject = [targets indexOfObject:currentTarget]; - NSInteger textureIndexOfTarget = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue]; + NSInteger indexOfObject = [self->targets indexOfObject:currentTarget]; + NSInteger textureIndexOfTarget = [[self->targetTextureIndices objectAtIndex:indexOfObject] integerValue]; [currentTarget setInputSize:pixelSizeOfImage atIndex:textureIndexOfTarget]; [currentTarget newFrameReadyAtTime:frameTime atIndex:textureIndexOfTarget]; } - dispatch_semaphore_signal(dataUpdateSemaphore); + dispatch_semaphore_signal(self->dataUpdateSemaphore); }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageRawDataOutput.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageRawDataOutput.m index 18101e2..7f18c50 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageRawDataOutput.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageRawDataOutput.m @@ -261,16 +261,16 @@ - (GLubyte *)rawBytesForImage; if ([GPUImageContext supportsFastTextureUpload]) { glFinish(); - _rawBytesForImage = [outputFramebuffer byteBuffer]; + self->_rawBytesForImage = [self->outputFramebuffer byteBuffer]; } else { - glReadPixels(0, 0, imageSize.width, imageSize.height, GL_RGBA, GL_UNSIGNED_BYTE, _rawBytesForImage); + glReadPixels(0, 0, self->imageSize.width, self->imageSize.height, GL_RGBA, GL_UNSIGNED_BYTE, self->_rawBytesForImage); // GL_EXT_read_format_bgra // glReadPixels(0, 0, imageSize.width, imageSize.height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, _rawBytesForImage); } - hasReadFromTheCurrentFrame = YES; + self->hasReadFromTheCurrentFrame = YES; }); diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageSharpenFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageSharpenFilter.m index 6d7367a..c14b037 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageSharpenFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageSharpenFilter.m @@ -118,17 +118,17 @@ - (id)init; - (void)setupFilterForSize:(CGSize)filterFrameSize; { runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext setActiveShaderProgram:filterProgram]; + [GPUImageContext setActiveShaderProgram:self->filterProgram]; - if (GPUImageRotationSwapsWidthAndHeight(inputRotation)) + if (GPUImageRotationSwapsWidthAndHeight(self->inputRotation)) { - glUniform1f(imageWidthFactorUniform, 1.0 / filterFrameSize.height); - glUniform1f(imageHeightFactorUniform, 1.0 / filterFrameSize.width); + glUniform1f(self->imageWidthFactorUniform, 1.0 / filterFrameSize.height); + glUniform1f(self->imageHeightFactorUniform, 1.0 / filterFrameSize.width); } else { - glUniform1f(imageWidthFactorUniform, 1.0 / filterFrameSize.width); - glUniform1f(imageHeightFactorUniform, 1.0 / filterFrameSize.height); + glUniform1f(self->imageWidthFactorUniform, 1.0 / filterFrameSize.width); + glUniform1f(self->imageHeightFactorUniform, 1.0 / filterFrameSize.height); } }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageSobelEdgeDetectionFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageSobelEdgeDetectionFilter.m index e193f02..7aac23f 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageSobelEdgeDetectionFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageSobelEdgeDetectionFilter.m @@ -126,9 +126,9 @@ - (void)setupFilterForSize:(CGSize)filterFrameSize; runSynchronouslyOnVideoProcessingQueue(^{ GLProgram *previousProgram = [GPUImageContext sharedImageProcessingContext].currentShaderProgram; - [GPUImageContext setActiveShaderProgram:secondFilterProgram]; - glUniform1f(texelWidthUniform, _texelWidth); - glUniform1f(texelHeightUniform, _texelHeight); + [GPUImageContext setActiveShaderProgram:self->secondFilterProgram]; + glUniform1f(self->texelWidthUniform, self->_texelWidth); + glUniform1f(self->texelHeightUniform, self->_texelHeight); [GPUImageContext setActiveShaderProgram:previousProgram]; }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageSolidColorGenerator.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageSolidColorGenerator.m index 9b555ce..512910b 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageSolidColorGenerator.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageSolidColorGenerator.m @@ -60,12 +60,12 @@ - (void)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates } runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext setActiveShaderProgram:filterProgram]; + [GPUImageContext setActiveShaderProgram:self->filterProgram]; - outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:[self sizeOfFBO] textureOptions:self.outputTextureOptions onlyTexture:NO]; - [outputFramebuffer activateFramebuffer]; + self->outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:[self sizeOfFBO] textureOptions:self.outputTextureOptions onlyTexture:NO]; + [self->outputFramebuffer activateFramebuffer]; - glClearColor(_color.one, _color.two, _color.three, _color.four); + glClearColor(self->_color.one, self->_color.two, self->_color.three, self->_color.four); glClear(GL_COLOR_BUFFER_BIT); }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageStillCamera.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageStillCamera.m index 447f79f..53737ab 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageStillCamera.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageStillCamera.m @@ -161,7 +161,7 @@ - (void)capturePhotoAsImageProcessedUpToFilter:(GPUImageOutput *) if(!error){ filteredPhoto = [finalFilterInChain imageFromCurrentFramebuffer]; } - dispatch_semaphore_signal(frameRenderingSemaphore); + dispatch_semaphore_signal(self->frameRenderingSemaphore); block(filteredPhoto, error); }]; @@ -174,7 +174,7 @@ - (void)capturePhotoAsImageProcessedUpToFilter:(GPUImageOutput *) if(!error) { filteredPhoto = [finalFilterInChain imageFromCurrentFramebufferWithOrientation:orientation]; } - dispatch_semaphore_signal(frameRenderingSemaphore); + dispatch_semaphore_signal(self->frameRenderingSemaphore); block(filteredPhoto, error); }]; @@ -190,7 +190,7 @@ - (void)capturePhotoAsJPEGProcessedUpToFilter:(GPUImageOutput *)f if(!error){ @autoreleasepool { UIImage *filteredPhoto = [finalFilterInChain imageFromCurrentFramebuffer]; - dispatch_semaphore_signal(frameRenderingSemaphore); + dispatch_semaphore_signal(self->frameRenderingSemaphore); // reportAvailableMemoryForGPUImage(@"After UIImage generation"); dataForJPEGFile = UIImageJPEGRepresentation(filteredPhoto,self.jpegCompressionQuality); @@ -199,7 +199,7 @@ - (void)capturePhotoAsJPEGProcessedUpToFilter:(GPUImageOutput *)f // reportAvailableMemoryForGPUImage(@"After autorelease pool"); }else{ - dispatch_semaphore_signal(frameRenderingSemaphore); + dispatch_semaphore_signal(self->frameRenderingSemaphore); } block(dataForJPEGFile, error); @@ -213,12 +213,12 @@ - (void)capturePhotoAsJPEGProcessedUpToFilter:(GPUImageOutput *)f if(!error) { @autoreleasepool { UIImage *filteredPhoto = [finalFilterInChain imageFromCurrentFramebufferWithOrientation:orientation]; - dispatch_semaphore_signal(frameRenderingSemaphore); + dispatch_semaphore_signal(self->frameRenderingSemaphore); dataForJPEGFile = UIImageJPEGRepresentation(filteredPhoto, self.jpegCompressionQuality); } } else { - dispatch_semaphore_signal(frameRenderingSemaphore); + dispatch_semaphore_signal(self->frameRenderingSemaphore); } block(dataForJPEGFile, error); @@ -234,11 +234,11 @@ - (void)capturePhotoAsPNGProcessedUpToFilter:(GPUImageOutput *)fi if(!error){ @autoreleasepool { UIImage *filteredPhoto = [finalFilterInChain imageFromCurrentFramebuffer]; - dispatch_semaphore_signal(frameRenderingSemaphore); + dispatch_semaphore_signal(self->frameRenderingSemaphore); dataForPNGFile = UIImagePNGRepresentation(filteredPhoto); } }else{ - dispatch_semaphore_signal(frameRenderingSemaphore); + dispatch_semaphore_signal(self->frameRenderingSemaphore); } block(dataForPNGFile, error); @@ -256,11 +256,11 @@ - (void)capturePhotoAsPNGProcessedUpToFilter:(GPUImageOutput *)fi if(!error){ @autoreleasepool { UIImage *filteredPhoto = [finalFilterInChain imageFromCurrentFramebufferWithOrientation:orientation]; - dispatch_semaphore_signal(frameRenderingSemaphore); + dispatch_semaphore_signal(self->frameRenderingSemaphore); dataForPNGFile = UIImagePNGRepresentation(filteredPhoto); } }else{ - dispatch_semaphore_signal(frameRenderingSemaphore); + dispatch_semaphore_signal(self->frameRenderingSemaphore); } block(dataForPNGFile, error); @@ -304,32 +304,32 @@ - (void)capturePhotoProcessedUpToFilter:(GPUImageOutput *)finalFi GPUImageCreateResizedSampleBuffer(cameraFrame, scaledImageSizeToFitOnGPU, &sampleBuffer); } - dispatch_semaphore_signal(frameRenderingSemaphore); + dispatch_semaphore_signal(self->frameRenderingSemaphore); [finalFilterInChain useNextFrameForImageCapture]; - [self captureOutput:photoOutput didOutputSampleBuffer:sampleBuffer fromConnection:[[photoOutput connections] objectAtIndex:0]]; - dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_FOREVER); + [self captureOutput:self->photoOutput didOutputSampleBuffer:sampleBuffer fromConnection:[[self->photoOutput connections] objectAtIndex:0]]; + dispatch_semaphore_wait(self->frameRenderingSemaphore, DISPATCH_TIME_FOREVER); if (sampleBuffer != NULL) CFRelease(sampleBuffer); } else { // This is a workaround for the corrupt images that are sometimes returned when taking a photo with the front camera and using the iOS 5.0 texture caches - AVCaptureDevicePosition currentCameraPosition = [[videoInput device] position]; - if ( (currentCameraPosition != AVCaptureDevicePositionFront) || (![GPUImageContext supportsFastTextureUpload]) || !requiresFrontCameraTextureCacheCorruptionWorkaround) + AVCaptureDevicePosition currentCameraPosition = [[self->videoInput device] position]; + if ( (currentCameraPosition != AVCaptureDevicePositionFront) || (![GPUImageContext supportsFastTextureUpload]) || !self->requiresFrontCameraTextureCacheCorruptionWorkaround) { - dispatch_semaphore_signal(frameRenderingSemaphore); + dispatch_semaphore_signal(self->frameRenderingSemaphore); [finalFilterInChain useNextFrameForImageCapture]; - [self captureOutput:photoOutput didOutputSampleBuffer:imageSampleBuffer fromConnection:[[photoOutput connections] objectAtIndex:0]]; - dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_FOREVER); + [self captureOutput:self->photoOutput didOutputSampleBuffer:imageSampleBuffer fromConnection:[[self->photoOutput connections] objectAtIndex:0]]; + dispatch_semaphore_wait(self->frameRenderingSemaphore, DISPATCH_TIME_FOREVER); } } CFDictionaryRef metadata = CMCopyDictionaryOfAttachments(NULL, imageSampleBuffer, kCMAttachmentMode_ShouldPropagate); - _currentCaptureMetadata = (__bridge_transfer NSDictionary *)metadata; + self->_currentCaptureMetadata = (__bridge_transfer NSDictionary *)metadata; block(nil); - _currentCaptureMetadata = nil; + self->_currentCaptureMetadata = nil; }]; } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTextureInput.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTextureInput.m index ad3ca1d..c7f62cc 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTextureInput.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTextureInput.m @@ -19,7 +19,7 @@ - (id)initWithTexture:(GLuint)newInputTexture size:(CGSize)newTextureSize; textureSize = newTextureSize; runSynchronouslyOnVideoProcessingQueue(^{ - outputFramebuffer = [[GPUImageFramebuffer alloc] initWithSize:newTextureSize overriddenTexture:newInputTexture]; + self->outputFramebuffer = [[GPUImageFramebuffer alloc] initWithSize:newTextureSize overriddenTexture:newInputTexture]; }); return self; @@ -31,13 +31,13 @@ - (id)initWithTexture:(GLuint)newInputTexture size:(CGSize)newTextureSize; - (void)processTextureWithFrameTime:(CMTime)frameTime; { runAsynchronouslyOnVideoProcessingQueue(^{ - for (id currentTarget in targets) + for (id currentTarget in self->targets) { - NSInteger indexOfObject = [targets indexOfObject:currentTarget]; - NSInteger targetTextureIndex = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue]; + NSInteger indexOfObject = [self->targets indexOfObject:currentTarget]; + NSInteger targetTextureIndex = [[self->targetTextureIndices objectAtIndex:indexOfObject] integerValue]; - [currentTarget setInputSize:textureSize atIndex:targetTextureIndex]; - [currentTarget setInputFramebuffer:outputFramebuffer atIndex:targetTextureIndex]; + [currentTarget setInputSize:self->textureSize atIndex:targetTextureIndex]; + [currentTarget setInputFramebuffer:self->outputFramebuffer atIndex:targetTextureIndex]; [currentTarget newFrameReadyAtTime:frameTime atIndex:targetTextureIndex]; } }); diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageThreeInputFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageThreeInputFilter.m index 2f4f113..89f62da 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageThreeInputFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageThreeInputFilter.m @@ -55,10 +55,10 @@ - (id)initWithVertexShaderFromString:(NSString *)vertexShaderString fragmentShad runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - filterThirdTextureCoordinateAttribute = [filterProgram attributeIndex:@"inputTextureCoordinate3"]; + self->filterThirdTextureCoordinateAttribute = [self->filterProgram attributeIndex:@"inputTextureCoordinate3"]; - filterInputTextureUniform3 = [filterProgram uniformIndex:@"inputImageTexture3"]; // This does assume a name of "inputImageTexture3" for the third input texture in the fragment shader - glEnableVertexAttribArray(filterThirdTextureCoordinateAttribute); + self->filterInputTextureUniform3 = [self->filterProgram uniformIndex:@"inputImageTexture3"]; // This does assume a name of "inputImageTexture3" for the third input texture in the fragment shader + glEnableVertexAttribArray(self->filterThirdTextureCoordinateAttribute); }); return self; diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageToneCurveFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageToneCurveFilter.m index 18a717e..fa2f9d3 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageToneCurveFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageToneCurveFilter.m @@ -232,11 +232,11 @@ - (void)dealloc runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - if (toneCurveTexture) + if (self->toneCurveTexture) { - glDeleteTextures(1, &toneCurveTexture); - toneCurveTexture = 0; - free(toneCurveByteArray); + glDeleteTextures(1, &self->toneCurveTexture); + self->toneCurveTexture = 0; + free(self->toneCurveByteArray); } }); } @@ -487,39 +487,39 @@ - (void)updateToneCurveTexture; { runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - if (!toneCurveTexture) + if (!self->toneCurveTexture) { glActiveTexture(GL_TEXTURE3); - glGenTextures(1, &toneCurveTexture); - glBindTexture(GL_TEXTURE_2D, toneCurveTexture); + glGenTextures(1, &self->toneCurveTexture); + glBindTexture(GL_TEXTURE_2D, self->toneCurveTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - toneCurveByteArray = calloc(256 * 4, sizeof(GLubyte)); + self->toneCurveByteArray = calloc(256 * 4, sizeof(GLubyte)); } else { glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, toneCurveTexture); + glBindTexture(GL_TEXTURE_2D, self->toneCurveTexture); } - if ( ([_redCurve count] >= 256) && ([_greenCurve count] >= 256) && ([_blueCurve count] >= 256) && ([_rgbCompositeCurve count] >= 256)) + if ( ([self->_redCurve count] >= 256) && ([self->_greenCurve count] >= 256) && ([self->_blueCurve count] >= 256) && ([self->_rgbCompositeCurve count] >= 256)) { for (unsigned int currentCurveIndex = 0; currentCurveIndex < 256; currentCurveIndex++) { // BGRA for upload to texture - GLubyte b = fmin(fmax(currentCurveIndex + [[_blueCurve objectAtIndex:currentCurveIndex] floatValue], 0), 255); - toneCurveByteArray[currentCurveIndex * 4] = fmin(fmax(b + [[_rgbCompositeCurve objectAtIndex:b] floatValue], 0), 255); - GLubyte g = fmin(fmax(currentCurveIndex + [[_greenCurve objectAtIndex:currentCurveIndex] floatValue], 0), 255); - toneCurveByteArray[currentCurveIndex * 4 + 1] = fmin(fmax(g + [[_rgbCompositeCurve objectAtIndex:g] floatValue], 0), 255); - GLubyte r = fmin(fmax(currentCurveIndex + [[_redCurve objectAtIndex:currentCurveIndex] floatValue], 0), 255); - toneCurveByteArray[currentCurveIndex * 4 + 2] = fmin(fmax(r + [[_rgbCompositeCurve objectAtIndex:r] floatValue], 0), 255); - toneCurveByteArray[currentCurveIndex * 4 + 3] = 255; + GLubyte b = fmin(fmax(currentCurveIndex + [[self->_blueCurve objectAtIndex:currentCurveIndex] floatValue], 0), 255); + self->toneCurveByteArray[currentCurveIndex * 4] = fmin(fmax(b + [[self->_rgbCompositeCurve objectAtIndex:b] floatValue], 0), 255); + GLubyte g = fmin(fmax(currentCurveIndex + [[self->_greenCurve objectAtIndex:currentCurveIndex] floatValue], 0), 255); + self->toneCurveByteArray[currentCurveIndex * 4 + 1] = fmin(fmax(g + [[self->_rgbCompositeCurve objectAtIndex:g] floatValue], 0), 255); + GLubyte r = fmin(fmax(currentCurveIndex + [[self->_redCurve objectAtIndex:currentCurveIndex] floatValue], 0), 255); + self->toneCurveByteArray[currentCurveIndex * 4 + 2] = fmin(fmax(r + [[self->_rgbCompositeCurve objectAtIndex:r] floatValue], 0), 255); + self->toneCurveByteArray[currentCurveIndex * 4 + 3] = 255; } - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256 /*width*/, 1 /*height*/, 0, GL_BGRA, GL_UNSIGNED_BYTE, toneCurveByteArray); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256 /*width*/, 1 /*height*/, 0, GL_BGRA, GL_UNSIGNED_BYTE, self->toneCurveByteArray); } }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoInputCrossTextureSamplingFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoInputCrossTextureSamplingFilter.m index aa338f8..6d9b6b3 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoInputCrossTextureSamplingFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoInputCrossTextureSamplingFilter.m @@ -71,16 +71,16 @@ - (void)setupFilterForSize:(CGSize)filterFrameSize; _texelHeight = 1.0 / filterFrameSize.height; runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext setActiveShaderProgram:filterProgram]; - if (GPUImageRotationSwapsWidthAndHeight(inputRotation)) + [GPUImageContext setActiveShaderProgram:self->filterProgram]; + if (GPUImageRotationSwapsWidthAndHeight(self->inputRotation)) { - glUniform1f(texelWidthUniform, _texelHeight); - glUniform1f(texelHeightUniform, _texelWidth); + glUniform1f(self->texelWidthUniform, self->_texelHeight); + glUniform1f(self->texelHeightUniform, self->_texelWidth); } else { - glUniform1f(texelWidthUniform, _texelWidth); - glUniform1f(texelHeightUniform, _texelHeight); + glUniform1f(self->texelWidthUniform, self->_texelWidth); + glUniform1f(self->texelHeightUniform, self->_texelHeight); } }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoInputFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoInputFilter.m index cf31873..17c7a97 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoInputFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoInputFilter.m @@ -56,10 +56,10 @@ - (id)initWithVertexShaderFromString:(NSString *)vertexShaderString fragmentShad runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - filterSecondTextureCoordinateAttribute = [filterProgram attributeIndex:@"inputTextureCoordinate2"]; + self->filterSecondTextureCoordinateAttribute = [self->filterProgram attributeIndex:@"inputTextureCoordinate2"]; - filterInputTextureUniform2 = [filterProgram uniformIndex:@"inputImageTexture2"]; // This does assume a name of "inputImageTexture2" for second input texture in the fragment shader - glEnableVertexAttribArray(filterSecondTextureCoordinateAttribute); + self->filterInputTextureUniform2 = [self->filterProgram uniformIndex:@"inputImageTexture2"]; // This does assume a name of "inputImageTexture2" for second input texture in the fragment shader + glEnableVertexAttribArray(self->filterSecondTextureCoordinateAttribute); }); return self; diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoPassFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoPassFilter.m index 9eb292b..da20514 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoPassFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoPassFilter.m @@ -17,34 +17,34 @@ - (id)initWithFirstStageVertexShaderFromString:(NSString *)firstStageVertexShade runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - secondFilterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:secondStageVertexShaderString fragmentShaderString:secondStageFragmentShaderString]; + self->secondFilterProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:secondStageVertexShaderString fragmentShaderString:secondStageFragmentShaderString]; - if (!secondFilterProgram.initialized) + if (!self->secondFilterProgram.initialized) { [self initializeSecondaryAttributes]; - if (![secondFilterProgram link]) + if (![self->secondFilterProgram link]) { - NSString *progLog = [secondFilterProgram programLog]; + NSString *progLog = [self->secondFilterProgram programLog]; NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [secondFilterProgram fragmentShaderLog]; + NSString *fragLog = [self->secondFilterProgram fragmentShaderLog]; NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [secondFilterProgram vertexShaderLog]; + NSString *vertLog = [self->secondFilterProgram vertexShaderLog]; NSLog(@"Vertex shader compile log: %@", vertLog); - secondFilterProgram = nil; + self->secondFilterProgram = nil; NSAssert(NO, @"Filter shader link failed"); } } - secondFilterPositionAttribute = [secondFilterProgram attributeIndex:@"position"]; - secondFilterTextureCoordinateAttribute = [secondFilterProgram attributeIndex:@"inputTextureCoordinate"]; - secondFilterInputTextureUniform = [secondFilterProgram uniformIndex:@"inputImageTexture"]; // This does assume a name of "inputImageTexture" for the fragment shader - secondFilterInputTextureUniform2 = [secondFilterProgram uniformIndex:@"inputImageTexture2"]; // This does assume a name of "inputImageTexture2" for second input texture in the fragment shader + self->secondFilterPositionAttribute = [self->secondFilterProgram attributeIndex:@"position"]; + self->secondFilterTextureCoordinateAttribute = [self->secondFilterProgram attributeIndex:@"inputTextureCoordinate"]; + self->secondFilterInputTextureUniform = [self->secondFilterProgram uniformIndex:@"inputImageTexture"]; // This does assume a name of "inputImageTexture" for the fragment shader + self->secondFilterInputTextureUniform2 = [self->secondFilterProgram uniformIndex:@"inputImageTexture2"]; // This does assume a name of "inputImageTexture2" for second input texture in the fragment shader - [GPUImageContext setActiveShaderProgram:secondFilterProgram]; + [GPUImageContext setActiveShaderProgram:self->secondFilterProgram]; - glEnableVertexAttribArray(secondFilterPositionAttribute); - glEnableVertexAttribArray(secondFilterTextureCoordinateAttribute); + glEnableVertexAttribArray(self->secondFilterPositionAttribute); + glEnableVertexAttribArray(self->secondFilterTextureCoordinateAttribute); }); return self; diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoPassTextureSamplingFilter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoPassTextureSamplingFilter.m index b6a2ec5..2511181 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoPassTextureSamplingFilter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageTwoPassTextureSamplingFilter.m @@ -18,11 +18,11 @@ - (id)initWithFirstStageVertexShaderFromString:(NSString *)firstStageVertexShade runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - verticalPassTexelWidthOffsetUniform = [filterProgram uniformIndex:@"texelWidthOffset"]; - verticalPassTexelHeightOffsetUniform = [filterProgram uniformIndex:@"texelHeightOffset"]; + self->verticalPassTexelWidthOffsetUniform = [self->filterProgram uniformIndex:@"texelWidthOffset"]; + self->verticalPassTexelHeightOffsetUniform = [self->filterProgram uniformIndex:@"texelHeightOffset"]; - horizontalPassTexelWidthOffsetUniform = [secondFilterProgram uniformIndex:@"texelWidthOffset"]; - horizontalPassTexelHeightOffsetUniform = [secondFilterProgram uniformIndex:@"texelHeightOffset"]; + self->horizontalPassTexelWidthOffsetUniform = [self->secondFilterProgram uniformIndex:@"texelWidthOffset"]; + self->horizontalPassTexelHeightOffsetUniform = [self->secondFilterProgram uniformIndex:@"texelHeightOffset"]; }); self.verticalTexelSpacing = 1.0; @@ -51,19 +51,19 @@ - (void)setupFilterForSize:(CGSize)filterFrameSize; { runSynchronouslyOnVideoProcessingQueue(^{ // The first pass through the framebuffer may rotate the inbound image, so need to account for that by changing up the kernel ordering for that pass - if (GPUImageRotationSwapsWidthAndHeight(inputRotation)) + if (GPUImageRotationSwapsWidthAndHeight(self->inputRotation)) { - verticalPassTexelWidthOffset = _verticalTexelSpacing / filterFrameSize.height; - verticalPassTexelHeightOffset = 0.0; + self->verticalPassTexelWidthOffset = self->_verticalTexelSpacing / filterFrameSize.height; + self->verticalPassTexelHeightOffset = 0.0; } else { - verticalPassTexelWidthOffset = 0.0; - verticalPassTexelHeightOffset = _verticalTexelSpacing / filterFrameSize.height; + self->verticalPassTexelWidthOffset = 0.0; + self->verticalPassTexelHeightOffset = self->_verticalTexelSpacing / filterFrameSize.height; } - horizontalPassTexelWidthOffset = _horizontalTexelSpacing / filterFrameSize.width; - horizontalPassTexelHeightOffset = 0.0; + self->horizontalPassTexelWidthOffset = self->_horizontalTexelSpacing / filterFrameSize.width; + self->horizontalPassTexelHeightOffset = 0.0; }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageVideoCamera.m b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageVideoCamera.m index 18aa60c..9e9721e 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageVideoCamera.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/GPUImageVideoCamera.m @@ -153,7 +153,7 @@ - (id)initWithSessionPreset:(NSString *)sessionPreset cameraPosition:(AVCaptureD runSynchronouslyOnVideoProcessingQueue(^{ - if (captureAsYUV) + if (self->captureAsYUV) { [GPUImageContext useImageProcessingContext]; // if ([GPUImageContext deviceSupportsRedTextures]) @@ -162,45 +162,45 @@ - (id)initWithSessionPreset:(NSString *)sessionPreset cameraPosition:(AVCaptureD // } // else // { - if (isFullYUVRange) + if (self->isFullYUVRange) { - yuvConversionProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageYUVFullRangeConversionForLAFragmentShaderString]; + self->yuvConversionProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageYUVFullRangeConversionForLAFragmentShaderString]; } else { - yuvConversionProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageYUVVideoRangeConversionForLAFragmentShaderString]; + self->yuvConversionProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageYUVVideoRangeConversionForLAFragmentShaderString]; } // } - if (!yuvConversionProgram.initialized) + if (!self->yuvConversionProgram.initialized) { - [yuvConversionProgram addAttribute:@"position"]; - [yuvConversionProgram addAttribute:@"inputTextureCoordinate"]; + [self->yuvConversionProgram addAttribute:@"position"]; + [self->yuvConversionProgram addAttribute:@"inputTextureCoordinate"]; - if (![yuvConversionProgram link]) + if (![self->yuvConversionProgram link]) { - NSString *progLog = [yuvConversionProgram programLog]; + NSString *progLog = [self->yuvConversionProgram programLog]; NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [yuvConversionProgram fragmentShaderLog]; + NSString *fragLog = [self->yuvConversionProgram fragmentShaderLog]; NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [yuvConversionProgram vertexShaderLog]; + NSString *vertLog = [self->yuvConversionProgram vertexShaderLog]; NSLog(@"Vertex shader compile log: %@", vertLog); - yuvConversionProgram = nil; + self->yuvConversionProgram = nil; NSAssert(NO, @"Filter shader link failed"); } } - yuvConversionPositionAttribute = [yuvConversionProgram attributeIndex:@"position"]; - yuvConversionTextureCoordinateAttribute = [yuvConversionProgram attributeIndex:@"inputTextureCoordinate"]; - yuvConversionLuminanceTextureUniform = [yuvConversionProgram uniformIndex:@"luminanceTexture"]; - yuvConversionChrominanceTextureUniform = [yuvConversionProgram uniformIndex:@"chrominanceTexture"]; - yuvConversionMatrixUniform = [yuvConversionProgram uniformIndex:@"colorConversionMatrix"]; + self->yuvConversionPositionAttribute = [self->yuvConversionProgram attributeIndex:@"position"]; + self->yuvConversionTextureCoordinateAttribute = [self->yuvConversionProgram attributeIndex:@"inputTextureCoordinate"]; + self->yuvConversionLuminanceTextureUniform = [self->yuvConversionProgram uniformIndex:@"luminanceTexture"]; + self->yuvConversionChrominanceTextureUniform = [self->yuvConversionProgram uniformIndex:@"chrominanceTexture"]; + self->yuvConversionMatrixUniform = [self->yuvConversionProgram uniformIndex:@"colorConversionMatrix"]; - [GPUImageContext setActiveShaderProgram:yuvConversionProgram]; + [GPUImageContext setActiveShaderProgram:self->yuvConversionProgram]; - glEnableVertexAttribArray(yuvConversionPositionAttribute); - glEnableVertexAttribArray(yuvConversionTextureCoordinateAttribute); + glEnableVertexAttribArray(self->yuvConversionPositionAttribute); + glEnableVertexAttribArray(self->yuvConversionTextureCoordinateAttribute); } }); @@ -896,7 +896,7 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CM [self processVideoSampleBuffer:sampleBuffer]; CFRelease(sampleBuffer); - dispatch_semaphore_signal(frameRenderingSemaphore); + dispatch_semaphore_signal(self->frameRenderingSemaphore); }); } } @@ -925,56 +925,56 @@ - (void)updateOrientationSendToTargets; // From the iOS 5.0 release notes: // In previous iOS versions, the front-facing camera would always deliver buffers in AVCaptureVideoOrientationLandscapeLeft and the back-facing camera would always deliver buffers in AVCaptureVideoOrientationLandscapeRight. - if (captureAsYUV && [GPUImageContext supportsFastTextureUpload]) + if (self->captureAsYUV && [GPUImageContext supportsFastTextureUpload]) { - outputRotation = kGPUImageNoRotation; + self->outputRotation = kGPUImageNoRotation; if ([self cameraPosition] == AVCaptureDevicePositionBack) { - if (_horizontallyMirrorRearFacingCamera) + if (self->_horizontallyMirrorRearFacingCamera) { - switch(_outputImageOrientation) + switch(self->_outputImageOrientation) { - case UIInterfaceOrientationPortrait:internalRotation = kGPUImageRotateRightFlipVertical; break; - case UIInterfaceOrientationPortraitUpsideDown:internalRotation = kGPUImageRotate180; break; - case UIInterfaceOrientationLandscapeLeft:internalRotation = kGPUImageFlipHorizonal; break; - case UIInterfaceOrientationLandscapeRight:internalRotation = kGPUImageFlipVertical; break; - default:internalRotation = kGPUImageNoRotation; + case UIInterfaceOrientationPortrait:self->internalRotation = kGPUImageRotateRightFlipVertical; break; + case UIInterfaceOrientationPortraitUpsideDown:self->internalRotation = kGPUImageRotate180; break; + case UIInterfaceOrientationLandscapeLeft:self->internalRotation = kGPUImageFlipHorizonal; break; + case UIInterfaceOrientationLandscapeRight:self->internalRotation = kGPUImageFlipVertical; break; + default:self->internalRotation = kGPUImageNoRotation; } } else { - switch(_outputImageOrientation) + switch(self->_outputImageOrientation) { - case UIInterfaceOrientationPortrait:internalRotation = kGPUImageRotateRight; break; - case UIInterfaceOrientationPortraitUpsideDown:internalRotation = kGPUImageRotateLeft; break; - case UIInterfaceOrientationLandscapeLeft:internalRotation = kGPUImageRotate180; break; - case UIInterfaceOrientationLandscapeRight:internalRotation = kGPUImageNoRotation; break; - default:internalRotation = kGPUImageNoRotation; + case UIInterfaceOrientationPortrait:self->internalRotation = kGPUImageRotateRight; break; + case UIInterfaceOrientationPortraitUpsideDown:self->internalRotation = kGPUImageRotateLeft; break; + case UIInterfaceOrientationLandscapeLeft:self->internalRotation = kGPUImageRotate180; break; + case UIInterfaceOrientationLandscapeRight:self->internalRotation = kGPUImageNoRotation; break; + default:self->internalRotation = kGPUImageNoRotation; } } } else { - if (_horizontallyMirrorFrontFacingCamera) + if (self->_horizontallyMirrorFrontFacingCamera) { - switch(_outputImageOrientation) + switch(self->_outputImageOrientation) { - case UIInterfaceOrientationPortrait:internalRotation = kGPUImageRotateRightFlipVertical; break; - case UIInterfaceOrientationPortraitUpsideDown:internalRotation = kGPUImageRotateRightFlipHorizontal; break; - case UIInterfaceOrientationLandscapeLeft:internalRotation = kGPUImageFlipHorizonal; break; - case UIInterfaceOrientationLandscapeRight:internalRotation = kGPUImageFlipVertical; break; - default:internalRotation = kGPUImageNoRotation; + case UIInterfaceOrientationPortrait:self->internalRotation = kGPUImageRotateRightFlipVertical; break; + case UIInterfaceOrientationPortraitUpsideDown:self->internalRotation = kGPUImageRotateRightFlipHorizontal; break; + case UIInterfaceOrientationLandscapeLeft:self->internalRotation = kGPUImageFlipHorizonal; break; + case UIInterfaceOrientationLandscapeRight:self->internalRotation = kGPUImageFlipVertical; break; + default:self->internalRotation = kGPUImageNoRotation; } } else { - switch(_outputImageOrientation) + switch(self->_outputImageOrientation) { - case UIInterfaceOrientationPortrait:internalRotation = kGPUImageRotateRight; break; - case UIInterfaceOrientationPortraitUpsideDown:internalRotation = kGPUImageRotateLeft; break; - case UIInterfaceOrientationLandscapeLeft:internalRotation = kGPUImageNoRotation; break; - case UIInterfaceOrientationLandscapeRight:internalRotation = kGPUImageRotate180; break; - default:internalRotation = kGPUImageNoRotation; + case UIInterfaceOrientationPortrait:self->internalRotation = kGPUImageRotateRight; break; + case UIInterfaceOrientationPortraitUpsideDown:self->internalRotation = kGPUImageRotateLeft; break; + case UIInterfaceOrientationLandscapeLeft:self->internalRotation = kGPUImageNoRotation; break; + case UIInterfaceOrientationLandscapeRight:self->internalRotation = kGPUImageRotate180; break; + default:self->internalRotation = kGPUImageNoRotation; } } } @@ -983,60 +983,60 @@ - (void)updateOrientationSendToTargets; { if ([self cameraPosition] == AVCaptureDevicePositionBack) { - if (_horizontallyMirrorRearFacingCamera) + if (self->_horizontallyMirrorRearFacingCamera) { - switch(_outputImageOrientation) + switch(self->_outputImageOrientation) { - case UIInterfaceOrientationPortrait:outputRotation = kGPUImageRotateRightFlipVertical; break; - case UIInterfaceOrientationPortraitUpsideDown:outputRotation = kGPUImageRotate180; break; - case UIInterfaceOrientationLandscapeLeft:outputRotation = kGPUImageFlipHorizonal; break; - case UIInterfaceOrientationLandscapeRight:outputRotation = kGPUImageFlipVertical; break; - default:outputRotation = kGPUImageNoRotation; + case UIInterfaceOrientationPortrait:self->outputRotation = kGPUImageRotateRightFlipVertical; break; + case UIInterfaceOrientationPortraitUpsideDown:self->outputRotation = kGPUImageRotate180; break; + case UIInterfaceOrientationLandscapeLeft:self->outputRotation = kGPUImageFlipHorizonal; break; + case UIInterfaceOrientationLandscapeRight:self->outputRotation = kGPUImageFlipVertical; break; + default:self->outputRotation = kGPUImageNoRotation; } } else { - switch(_outputImageOrientation) + switch(self->_outputImageOrientation) { - case UIInterfaceOrientationPortrait:outputRotation = kGPUImageRotateRight; break; - case UIInterfaceOrientationPortraitUpsideDown:outputRotation = kGPUImageRotateLeft; break; - case UIInterfaceOrientationLandscapeLeft:outputRotation = kGPUImageRotate180; break; - case UIInterfaceOrientationLandscapeRight:outputRotation = kGPUImageNoRotation; break; - default:outputRotation = kGPUImageNoRotation; + case UIInterfaceOrientationPortrait:self->outputRotation = kGPUImageRotateRight; break; + case UIInterfaceOrientationPortraitUpsideDown:self->outputRotation = kGPUImageRotateLeft; break; + case UIInterfaceOrientationLandscapeLeft:self->outputRotation = kGPUImageRotate180; break; + case UIInterfaceOrientationLandscapeRight:self->outputRotation = kGPUImageNoRotation; break; + default:self->outputRotation = kGPUImageNoRotation; } } } else { - if (_horizontallyMirrorFrontFacingCamera) + if (self->_horizontallyMirrorFrontFacingCamera) { - switch(_outputImageOrientation) + switch(self->_outputImageOrientation) { - case UIInterfaceOrientationPortrait:outputRotation = kGPUImageRotateRightFlipVertical; break; - case UIInterfaceOrientationPortraitUpsideDown:outputRotation = kGPUImageRotateRightFlipHorizontal; break; - case UIInterfaceOrientationLandscapeLeft:outputRotation = kGPUImageFlipHorizonal; break; - case UIInterfaceOrientationLandscapeRight:outputRotation = kGPUImageFlipVertical; break; - default:outputRotation = kGPUImageNoRotation; + case UIInterfaceOrientationPortrait:self->outputRotation = kGPUImageRotateRightFlipVertical; break; + case UIInterfaceOrientationPortraitUpsideDown:self->outputRotation = kGPUImageRotateRightFlipHorizontal; break; + case UIInterfaceOrientationLandscapeLeft:self->outputRotation = kGPUImageFlipHorizonal; break; + case UIInterfaceOrientationLandscapeRight:self->outputRotation = kGPUImageFlipVertical; break; + default:self->outputRotation = kGPUImageNoRotation; } } else { - switch(_outputImageOrientation) + switch(self->_outputImageOrientation) { - case UIInterfaceOrientationPortrait:outputRotation = kGPUImageRotateRight; break; - case UIInterfaceOrientationPortraitUpsideDown:outputRotation = kGPUImageRotateLeft; break; - case UIInterfaceOrientationLandscapeLeft:outputRotation = kGPUImageNoRotation; break; - case UIInterfaceOrientationLandscapeRight:outputRotation = kGPUImageRotate180; break; - default:outputRotation = kGPUImageNoRotation; + case UIInterfaceOrientationPortrait:self->outputRotation = kGPUImageRotateRight; break; + case UIInterfaceOrientationPortraitUpsideDown:self->outputRotation = kGPUImageRotateLeft; break; + case UIInterfaceOrientationLandscapeLeft:self->outputRotation = kGPUImageNoRotation; break; + case UIInterfaceOrientationLandscapeRight:self->outputRotation = kGPUImageRotate180; break; + default:self->outputRotation = kGPUImageNoRotation; } } } } - for (id currentTarget in targets) + for (id currentTarget in self->targets) { - NSInteger indexOfObject = [targets indexOfObject:currentTarget]; - [currentTarget setInputRotation:outputRotation atIndex:[[targetTextureIndices objectAtIndex:indexOfObject] integerValue]]; + NSInteger indexOfObject = [self->targets indexOfObject:currentTarget]; + [currentTarget setInputRotation:self->outputRotation atIndex:[[self->targetTextureIndices objectAtIndex:indexOfObject] integerValue]]; } }); } diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImage.h b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImage.h deleted file mode 100755 index 0546740..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImage.h +++ /dev/null @@ -1,167 +0,0 @@ -#import - -// Base classes -#import -#import - -// Sources -#import -#import -#import -#import -#import -#import -#import -#import - -// Filters -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -// Outputs -#import -#import -#import diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageAVCamera.h b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageAVCamera.h deleted file mode 100755 index 54c1a2f..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageAVCamera.h +++ /dev/null @@ -1,132 +0,0 @@ -#import -#import -#import -#import "GPUImageContext.h" -#import "GPUImageOutput.h" - -//Delegate Protocal for Face Detection. -@protocol GPUImageVideoCameraDelegate - -@optional -- (void)willOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer; -@end - - -/** - A GPUImageOutput that provides frames from either camera -*/ -@interface GPUImageAVCamera : GPUImageOutput -{ - NSUInteger numberOfFramesCaptured; - CGFloat totalFrameTimeDuringCapture; - - AVCaptureSession *_captureSession; - AVCaptureDevice *_inputCamera; - AVCaptureDevice *_microphone; - AVCaptureDeviceInput *videoInput; - AVCaptureVideoDataOutput *videoOutput; - - BOOL capturePaused; - GPUImageRotationMode outputRotation; - dispatch_semaphore_t frameRenderingSemaphore; - - BOOL captureAsYUV; - GLuint luminanceTexture, chrominanceTexture; - - __unsafe_unretained id _delegate; -} - -/// The AVCaptureSession used to capture from the camera -@property(readonly, retain, nonatomic) AVCaptureSession *captureSession; - -/// This enables the capture session preset to be changed on the fly -@property (readwrite, nonatomic, copy) NSString *captureSessionPreset; - -/// This sets the frame rate of the camera (iOS 5 and above only) -/** - Setting this to 0 or below will set the frame rate back to the default setting for a particular preset. - */ -@property (readwrite) NSInteger frameRate; - -/// Easy way to tell if front-facing camera is present on device -@property (readonly, getter = isFrontFacingCameraPresent) BOOL frontFacingCameraPresent; - -/// This enables the benchmarking mode, which logs out instantaneous and average frame times to the console -@property(readwrite, nonatomic) BOOL runBenchmark; - -/// Use this property to manage camera settings. Focus point, exposure point, etc. -@property(readonly) AVCaptureDevice *inputCamera; - -/// These properties determine whether or not the two camera orientations should be mirrored. By default, both are NO. -@property(readwrite, nonatomic) BOOL horizontallyMirrorFrontFacingCamera, horizontallyMirrorRearFacingCamera; - -@property(nonatomic, assign) id delegate; - -/// @name Initialization and teardown - -+ (NSArray *)connectedCameraDevices; - -/** Begin a capture session - - See AVCaptureSession for acceptable values - - @param sessionPreset Session preset to use - @param cameraPosition Camera to capture from - */ -- (id)initWithDeviceUniqueID:(NSString *)deviceUniqueID; -- (id)initWithSessionPreset:(NSString *)sessionPreset deviceUniqueID:(NSString *)deviceUniqueID; -- (id)initWithSessionPreset:(NSString *)sessionPreset cameraDevice:(AVCaptureDevice *)cameraDevice; - -/** Tear down the capture session - */ -- (void)removeInputsAndOutputs; - -/// @name Manage the camera video stream - -/** Start camera capturing - */ -- (void)startCameraCapture; - -/** Stop camera capturing - */ -- (void)stopCameraCapture; - -/** Pause camera capturing - */ -- (void)pauseCameraCapture; - -/** Resume camera capturing - */ -- (void)resumeCameraCapture; - -/** Process a video sample - @param sampleBuffer Buffer to process - */ -- (void)processVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer; - -/** Process an audio sample - @param sampleBuffer Buffer to process - */ -- (void)processAudioSampleBuffer:(CMSampleBufferRef)sampleBuffer; - -/** Get the position (front, rear) of the source camera - */ -- (AVCaptureDevicePosition)cameraPosition; - -/** Get the AVCaptureConnection of the source camera - */ -- (AVCaptureConnection *)videoCaptureConnection; - -/** This flips between the front and rear cameras - */ -- (void)rotateCamera; - -/// @name Benchmarking - -/** When benchmarking is enabled, this will keep a running average of the time from uploading, processing, and final recording or display - */ -- (CGFloat)averageFrameDurationDuringCapture; - -- (void)printSupportedPixelFormats; - -@end diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageAVCamera.m b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageAVCamera.m deleted file mode 100644 index 4b26c75..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageAVCamera.m +++ /dev/null @@ -1,771 +0,0 @@ -#import "GPUImageAVCamera.h" -#import "GPUImageMovieWriter.h" -#import "GPUImageFilter.h" -#import "GPUImageColorConversion.h" - -#pragma mark - -#pragma mark Private methods and instance variables - -@interface GPUImageAVCamera () -{ - AVCaptureDeviceInput *audioInput; - AVCaptureAudioDataOutput *audioOutput; - NSDate *startingCaptureTime; - - NSInteger _frameRate; - - dispatch_queue_t cameraProcessingQueue, audioProcessingQueue; - - GLProgram *yuvConversionProgram; - GLint yuvConversionPositionAttribute, yuvConversionTextureCoordinateAttribute; - GLint yuvConversionLuminanceTextureUniform, yuvConversionChrominanceTextureUniform; - - int imageBufferWidth, imageBufferHeight; -} - -- (void)updateOrientationSendToTargets; -- (void)convertYUVToRGBOutput; - -@end - -@implementation GPUImageAVCamera - -@synthesize captureSessionPreset = _captureSessionPreset; -@synthesize captureSession = _captureSession; -@synthesize inputCamera = _inputCamera; -@synthesize runBenchmark = _runBenchmark; -@synthesize delegate = _delegate; -@synthesize horizontallyMirrorFrontFacingCamera = _horizontallyMirrorFrontFacingCamera, horizontallyMirrorRearFacingCamera = _horizontallyMirrorRearFacingCamera; - -#pragma mark - -#pragma mark Initialization and teardown - -+ (NSArray *)connectedCameraDevices; -{ - NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; - return devices; -} - -- (id)init; -{ - if (!(self = [self initWithSessionPreset:AVCaptureSessionPreset640x480 cameraDevice:nil])) - { - return nil; - } - - return self; -} - -- (id)initWithDeviceUniqueID:(NSString *)deviceUniqueID; -{ - if (!(self = [self initWithSessionPreset:AVCaptureSessionPreset640x480 deviceUniqueID:deviceUniqueID])) - { - return nil; - } - - return self; -} - -- (id)initWithSessionPreset:(NSString *)sessionPreset deviceUniqueID:(NSString *)deviceUniqueID; -{ - if (!(self = [self initWithSessionPreset:sessionPreset cameraDevice:[AVCaptureDevice deviceWithUniqueID:deviceUniqueID]])) - { - return nil; - } - - return self; -} - -- (id)initWithSessionPreset:(NSString *)sessionPreset cameraDevice:(AVCaptureDevice *)cameraDevice; -{ - if (!(self = [super init])) - { - return nil; - } - - cameraProcessingQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.cameraProcessingQueue", NULL); - audioProcessingQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.audioProcessingQueue", NULL); - frameRenderingSemaphore = dispatch_semaphore_create(1); - - _frameRate = 0; // This will not set frame rate unless this value gets set to 1 or above - _runBenchmark = NO; - capturePaused = NO; - outputRotation = kGPUImageNoRotation; -// captureAsYUV = YES; - captureAsYUV = NO; - - runSynchronouslyOnVideoProcessingQueue(^{ - - if (captureAsYUV) - { - [GPUImageContext useImageProcessingContext]; -// if ([GPUImageContext deviceSupportsRedTextures]) -// { -// yuvConversionProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageYUVVideoRangeConversionForRGFragmentShaderString]; -// } -// else -// { - yuvConversionProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageYUVVideoRangeConversionForLAFragmentShaderString]; -// } - - if (!yuvConversionProgram.initialized) - { - [yuvConversionProgram addAttribute:@"position"]; - [yuvConversionProgram addAttribute:@"inputTextureCoordinate"]; - - if (![yuvConversionProgram link]) - { - NSString *progLog = [yuvConversionProgram programLog]; - NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [yuvConversionProgram fragmentShaderLog]; - NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [yuvConversionProgram vertexShaderLog]; - NSLog(@"Vertex shader compile log: %@", vertLog); - yuvConversionProgram = nil; - NSAssert(NO, @"Filter shader link failed"); - } - } - - yuvConversionPositionAttribute = [yuvConversionProgram attributeIndex:@"position"]; - yuvConversionTextureCoordinateAttribute = [yuvConversionProgram attributeIndex:@"inputTextureCoordinate"]; - yuvConversionLuminanceTextureUniform = [yuvConversionProgram uniformIndex:@"luminanceTexture"]; - yuvConversionChrominanceTextureUniform = [yuvConversionProgram uniformIndex:@"chrominanceTexture"]; - - [GPUImageContext setActiveShaderProgram:yuvConversionProgram]; - - glEnableVertexAttribArray(yuvConversionPositionAttribute); - glEnableVertexAttribArray(yuvConversionTextureCoordinateAttribute); - } - }); - - // Grab the back-facing or front-facing camera - _inputCamera = nil; - - if (cameraDevice == nil) - { - _inputCamera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; - } - else - { - _inputCamera = cameraDevice; - } - - if (!_inputCamera) { - return nil; - } - - // Create the capture session - _captureSession = [[AVCaptureSession alloc] init]; - - [_captureSession beginConfiguration]; - - // Add the video input - NSError *error = nil; - videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:_inputCamera error:&error]; - if ([_captureSession canAddInput:videoInput]) - { - [_captureSession addInput:videoInput]; - } - - // Add the video frame output - videoOutput = [[AVCaptureVideoDataOutput alloc] init]; - [videoOutput setAlwaysDiscardsLateVideoFrames:NO]; - -// NSLog(@"Camera: %@", _inputCamera); -// [self printSupportedPixelFormats]; - -// if (captureAsYUV && [GPUImageContext deviceSupportsRedTextures]) - if (captureAsYUV && [GPUImageContext supportsFastTextureUpload]) - { - BOOL supportsFullYUVRange = NO; - NSArray *supportedPixelFormats = videoOutput.availableVideoCVPixelFormatTypes; - for (NSNumber *currentPixelFormat in supportedPixelFormats) - { - if ([currentPixelFormat intValue] == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) - { - supportsFullYUVRange = YES; - } - } - - if (supportsFullYUVRange) - { - [videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange] forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; - } - else - { - [videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; - } - } - else - { - // Despite returning a longer list of supported pixel formats, only RGB, RGBA, BGRA, and the YUV 4:2:2 variants seem to return cleanly - [videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; -// [videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_422YpCbCr8_yuvs] forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; - } - - [videoOutput setSampleBufferDelegate:self queue:cameraProcessingQueue]; -// [videoOutput setSampleBufferDelegate:self queue:[GPUImageContext sharedContextQueue]]; - if ([_captureSession canAddOutput:videoOutput]) - { - [_captureSession addOutput:videoOutput]; - } - else - { - NSLog(@"Couldn't add video output"); - return nil; - } - - _captureSessionPreset = sessionPreset; - [_captureSession setSessionPreset:_captureSessionPreset]; - -// This will let you get 60 FPS video from the 720p preset on an iPhone 4S, but only that device and that preset -// AVCaptureConnection *conn = [videoOutput connectionWithMediaType:AVMediaTypeVideo]; -// -// if (conn.supportsVideoMinFrameDuration) -// conn.videoMinFrameDuration = CMTimeMake(1,60); -// if (conn.supportsVideoMaxFrameDuration) -// conn.videoMaxFrameDuration = CMTimeMake(1,60); - - [_captureSession commitConfiguration]; - - return self; -} - -- (void)dealloc -{ - [self stopCameraCapture]; - [videoOutput setSampleBufferDelegate:nil queue:dispatch_get_main_queue()]; - [audioOutput setSampleBufferDelegate:nil queue:dispatch_get_main_queue()]; - - [self removeInputsAndOutputs]; - -// ARC forbids explicit message send of 'release'; since iOS 6 even for dispatch_release() calls: stripping it out in that case is required. -//#if ( (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0) || (!defined(__IPHONE_6_0)) ) -#if __MAC_OS_X_VERSION_MAX_ALLOWED <= __MAC_10_7 - if (cameraProcessingQueue != NULL) - { - dispatch_release(cameraProcessingQueue); - } - - if (audioProcessingQueue != NULL) - { - dispatch_release(audioProcessingQueue); - } - - if (frameRenderingSemaphore != NULL) - { - dispatch_release(frameRenderingSemaphore); - } -#endif -} - -- (void)removeInputsAndOutputs; -{ - [_captureSession removeInput:videoInput]; - [_captureSession removeOutput:videoOutput]; - if (_microphone != nil) - { - [_captureSession removeInput:audioInput]; - [_captureSession removeOutput:audioOutput]; - } -} - -#pragma mark - -#pragma mark Managing targets - -- (void)addTarget:(id)newTarget atTextureLocation:(NSInteger)textureLocation; -{ - [super addTarget:newTarget atTextureLocation:textureLocation]; - - [newTarget setInputRotation:outputRotation atIndex:textureLocation]; -} - -#pragma mark - -#pragma mark Manage the camera video stream - -- (void)startCameraCapture; -{ - if (![_captureSession isRunning]) - { - startingCaptureTime = [NSDate date]; - [_captureSession startRunning]; - }; -} - -- (void)stopCameraCapture; -{ - if ([_captureSession isRunning]) - { - [_captureSession stopRunning]; - } -} - -- (void)pauseCameraCapture; -{ - capturePaused = YES; -} - -- (void)resumeCameraCapture; -{ - capturePaused = NO; -} - -- (void)rotateCamera -{ - if (self.frontFacingCameraPresent == NO) - return; - - NSError *error; - AVCaptureDeviceInput *newVideoInput; - AVCaptureDevicePosition currentCameraPosition = [[videoInput device] position]; - - if (currentCameraPosition == AVCaptureDevicePositionBack) - { - currentCameraPosition = AVCaptureDevicePositionFront; - } - else - { - currentCameraPosition = AVCaptureDevicePositionBack; - } - - AVCaptureDevice *backFacingCamera = nil; - NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; - for (AVCaptureDevice *device in devices) - { - if ([device position] == currentCameraPosition) - { - backFacingCamera = device; - } - } - newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:backFacingCamera error:&error]; - - if (newVideoInput != nil) - { - [_captureSession beginConfiguration]; - - [_captureSession removeInput:videoInput]; - if ([_captureSession canAddInput:newVideoInput]) - { - [_captureSession addInput:newVideoInput]; - videoInput = newVideoInput; - } - else - { - [_captureSession addInput:videoInput]; - } - //captureSession.sessionPreset = oriPreset; - [_captureSession commitConfiguration]; - } - - _inputCamera = backFacingCamera; -} - -- (AVCaptureDevicePosition)cameraPosition -{ - return [[videoInput device] position]; -} - -- (BOOL)isFrontFacingCameraPresent; -{ - NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; - - for (AVCaptureDevice *device in devices) - { - if ([device position] == AVCaptureDevicePositionFront) - return YES; - } - - return NO; -} - -- (void)setCaptureSessionPreset:(NSString *)captureSessionPreset; -{ - [_captureSession beginConfiguration]; - - _captureSessionPreset = captureSessionPreset; - [_captureSession setSessionPreset:_captureSessionPreset]; - - [_captureSession commitConfiguration]; -} - -- (void)setFrameRate:(NSInteger)frameRate; -{ - _frameRate = frameRate; - - if (_frameRate > 0) - { - for (AVCaptureConnection *connection in videoOutput.connections) - { - if ([connection respondsToSelector:@selector(setVideoMinFrameDuration:)]) - connection.videoMinFrameDuration = CMTimeMake(1, (int32_t)_frameRate); - - } - } - else - { - for (AVCaptureConnection *connection in videoOutput.connections) - { - if ([connection respondsToSelector:@selector(setVideoMinFrameDuration:)]) - connection.videoMinFrameDuration = kCMTimeInvalid; // This sets videoMinFrameDuration back to default - } - } -} - -- (NSInteger)frameRate; -{ - return _frameRate; -} - -- (AVCaptureConnection *)videoCaptureConnection { - for (AVCaptureConnection *connection in [videoOutput connections] ) { - for ( AVCaptureInputPort *port in [connection inputPorts] ) { - if ( [[port mediaType] isEqual:AVMediaTypeVideo] ) { - return connection; - } - } - } - - return nil; -} - -#define INITIALFRAMESTOIGNOREFORBENCHMARK 5 - -- (void)updateTargetsForVideoCameraUsingCacheTextureAtWidth:(int)bufferWidth height:(int)bufferHeight time:(CMTime)currentTime; -{ - // First, update all the framebuffers in the targets - for (id currentTarget in targets) - { - if ([currentTarget enabled]) - { - NSInteger indexOfObject = [targets indexOfObject:currentTarget]; - NSInteger textureIndexOfTarget = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue]; - - if (currentTarget != self.targetToIgnoreForUpdates) - { - [currentTarget setInputRotation:outputRotation atIndex:textureIndexOfTarget]; - [currentTarget setInputSize:CGSizeMake(bufferWidth, bufferHeight) atIndex:textureIndexOfTarget]; - - if ([currentTarget wantsMonochromeInput] && captureAsYUV) - { - [currentTarget setCurrentlyReceivingMonochromeInput:YES]; - // TODO: Replace optimization for monochrome output - [currentTarget setInputFramebuffer:outputFramebuffer atIndex:textureIndexOfTarget]; - } - else - { - [currentTarget setCurrentlyReceivingMonochromeInput:NO]; - [currentTarget setInputFramebuffer:outputFramebuffer atIndex:textureIndexOfTarget]; - } - } - else - { - [currentTarget setInputRotation:outputRotation atIndex:textureIndexOfTarget]; - [currentTarget setInputFramebuffer:outputFramebuffer atIndex:textureIndexOfTarget]; - } - } - } - - // Then release our hold on the local framebuffer to send it back to the cache as soon as it's no longer needed - [outputFramebuffer unlock]; - - // Finally, trigger rendering as needed - for (id currentTarget in targets) - { - if ([currentTarget enabled]) - { - NSInteger indexOfObject = [targets indexOfObject:currentTarget]; - NSInteger textureIndexOfTarget = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue]; - - if (currentTarget != self.targetToIgnoreForUpdates) - { - [currentTarget newFrameReadyAtTime:currentTime atIndex:textureIndexOfTarget]; - } - } - } -} - -- (void)processVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer; -{ - if (capturePaused) - { - return; - } - - CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent(); - CVImageBufferRef cameraFrame = CMSampleBufferGetImageBuffer(sampleBuffer); - GLsizei bufferWidth = (GLsizei)CVPixelBufferGetWidth(cameraFrame); - GLsizei bufferHeight = (GLsizei)CVPixelBufferGetHeight(cameraFrame); - - CMTime currentTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); - - [GPUImageContext useImageProcessingContext]; - - CVPixelBufferLockBaseAddress(cameraFrame, 0); - - outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:CGSizeMake(bufferWidth, bufferHeight) onlyTexture:YES]; - - glBindTexture(GL_TEXTURE_2D, [outputFramebuffer texture]); - - // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferWidth, bufferHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress(cameraFrame)); - - // Using BGRA extension to pull in video frame data directly -// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bytesPerRow / 3, bufferHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress(cameraFrame)); -// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferWidth, bufferHeight, 0, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, CVPixelBufferGetBaseAddress(cameraFrame)); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferWidth, bufferHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress(cameraFrame)); - - [self updateTargetsForVideoCameraUsingCacheTextureAtWidth:bufferWidth height:bufferHeight time:currentTime]; - -// for (id currentTarget in targets) -// { -// if ([currentTarget enabled]) -// { -// if (currentTarget != self.targetToIgnoreForUpdates) -// { -// NSInteger indexOfObject = [targets indexOfObject:currentTarget]; -// NSInteger textureIndexOfTarget = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue]; -// -// [currentTarget setInputSize:CGSizeMake(bufferWidth, bufferHeight) atIndex:textureIndexOfTarget]; -// [currentTarget newFrameReadyAtTime:currentTime atIndex:textureIndexOfTarget]; -// } -// } -// } - - CVPixelBufferUnlockBaseAddress(cameraFrame, 0); - - if (_runBenchmark) - { - numberOfFramesCaptured++; - if (numberOfFramesCaptured > INITIALFRAMESTOIGNOREFORBENCHMARK) - { - CFAbsoluteTime currentFrameTime = (CFAbsoluteTimeGetCurrent() - startTime); - totalFrameTimeDuringCapture += currentFrameTime; - NSLog(@"Average frame time : %f ms", [self averageFrameDurationDuringCapture]); - NSLog(@"Current frame time : %f ms", 1000.0 * currentFrameTime); - } - } -} - -- (void)processAudioSampleBuffer:(CMSampleBufferRef)sampleBuffer; -{ - [self.audioEncodingTarget processAudioBuffer:sampleBuffer]; -} - -- (void)convertYUVToRGBOutput; -{ - [GPUImageContext setActiveShaderProgram:yuvConversionProgram]; - - outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:CGSizeMake(imageBufferWidth, imageBufferHeight) textureOptions:self.outputTextureOptions onlyTexture:NO]; - [outputFramebuffer activateFramebuffer]; - - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - static const GLfloat squareVertices[] = { - -1.0f, -1.0f, - 1.0f, -1.0f, - -1.0f, 1.0f, - 1.0f, 1.0f, - }; - - static const GLfloat textureCoordinates[] = { - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - }; - - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, luminanceTexture); - glUniform1i(yuvConversionLuminanceTextureUniform, 4); - - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_2D, chrominanceTexture); - glUniform1i(yuvConversionChrominanceTextureUniform, 5); - - glVertexAttribPointer(yuvConversionPositionAttribute, 2, GL_FLOAT, 0, 0, squareVertices); - glVertexAttribPointer(yuvConversionTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, textureCoordinates); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); -} - -#pragma mark - -#pragma mark Benchmarking - -- (CGFloat)averageFrameDurationDuringCapture; -{ - return (totalFrameTimeDuringCapture / (CGFloat)(numberOfFramesCaptured - INITIALFRAMESTOIGNOREFORBENCHMARK)) * 1000.0; -} - -#pragma mark - -#pragma mark AVCaptureVideoDataOutputSampleBufferDelegate - -- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection -{ - if (captureOutput == audioOutput) - { -// if (dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_NOW) != 0) -// { -// return; -// } - - CFRetain(sampleBuffer); - runAsynchronouslyOnVideoProcessingQueue(^{ - [self processAudioSampleBuffer:sampleBuffer]; - CFRelease(sampleBuffer); -// dispatch_semaphore_signal(frameRenderingSemaphore); - }); - } - else - { - if (dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_NOW) != 0) - { - return; - } - - CFRetain(sampleBuffer); - runAsynchronouslyOnVideoProcessingQueue(^{ - //Feature Detection Hook. - if (self.delegate && [self.delegate respondsToSelector:@selector(willOutputSampleBuffer:)]) - { - [self.delegate willOutputSampleBuffer:sampleBuffer]; - } - - [self processVideoSampleBuffer:sampleBuffer]; - - CFRelease(sampleBuffer); - dispatch_semaphore_signal(frameRenderingSemaphore); - }); - } -} - -#pragma mark - -#pragma mark Accessors - -- (void)setAudioEncodingTarget:(GPUImageMovieWriter *)newValue; -{ - runSynchronouslyOnVideoProcessingQueue(^{ - [_captureSession beginConfiguration]; - - if (newValue == nil) - { - if (audioOutput) - { - [_captureSession removeInput:audioInput]; - [_captureSession removeOutput:audioOutput]; - audioInput = nil; - audioOutput = nil; - _microphone = nil; - } - } - else - { - _microphone = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; - audioInput = [AVCaptureDeviceInput deviceInputWithDevice:_microphone error:nil]; - if ([_captureSession canAddInput:audioInput]) - { - [_captureSession addInput:audioInput]; - } - audioOutput = [[AVCaptureAudioDataOutput alloc] init]; - - if ([_captureSession canAddOutput:audioOutput]) - { - [_captureSession addOutput:audioOutput]; - } - else - { - NSLog(@"Couldn't add audio output"); - } - [audioOutput setSampleBufferDelegate:self queue:audioProcessingQueue]; - } - - [_captureSession commitConfiguration]; - - [super setAudioEncodingTarget:newValue]; - }); -} - -- (void)updateOrientationSendToTargets; -{ - runSynchronouslyOnVideoProcessingQueue(^{ - - // From the iOS 5.0 release notes: - // In previous iOS versions, the front-facing camera would always deliver buffers in AVCaptureVideoOrientationLandscapeLeft and the back-facing camera would always deliver buffers in AVCaptureVideoOrientationLandscapeRight. - - outputRotation = kGPUImageNoRotation; - for (id currentTarget in targets) - { - NSInteger indexOfObject = [targets indexOfObject:currentTarget]; - [currentTarget setInputRotation:outputRotation atIndex:[[targetTextureIndices objectAtIndex:indexOfObject] integerValue]]; - } - }); -} - -- (void)setHorizontallyMirrorFrontFacingCamera:(BOOL)newValue -{ - _horizontallyMirrorFrontFacingCamera = newValue; - [self updateOrientationSendToTargets]; -} - -- (void)setHorizontallyMirrorRearFacingCamera:(BOOL)newValue -{ - _horizontallyMirrorRearFacingCamera = newValue; - [self updateOrientationSendToTargets]; -} - -- (void)printSupportedPixelFormats; -{ - NSArray *supportedPixelFormats = videoOutput.availableVideoCVPixelFormatTypes; - for (NSNumber *currentPixelFormat in supportedPixelFormats) - { - NSString *pixelFormatName = nil; - - switch([currentPixelFormat intValue]) - { - case kCVPixelFormatType_1Monochrome: pixelFormatName = @"kCVPixelFormatType_1Monochrome"; break; - case kCVPixelFormatType_2Indexed: pixelFormatName = @"kCVPixelFormatType_2Indexed"; break; - case kCVPixelFormatType_4Indexed: pixelFormatName = @"kCVPixelFormatType_4Indexed"; break; - case kCVPixelFormatType_8Indexed: pixelFormatName = @"kCVPixelFormatType_8Indexed"; break; - case kCVPixelFormatType_1IndexedGray_WhiteIsZero: pixelFormatName = @"kCVPixelFormatType_1IndexedGray_WhiteIsZero"; break; - case kCVPixelFormatType_2IndexedGray_WhiteIsZero: pixelFormatName = @"kCVPixelFormatType_2IndexedGray_WhiteIsZero"; break; - case kCVPixelFormatType_4IndexedGray_WhiteIsZero: pixelFormatName = @"kCVPixelFormatType_4IndexedGray_WhiteIsZero"; break; - case kCVPixelFormatType_8IndexedGray_WhiteIsZero: pixelFormatName = @"kCVPixelFormatType_8IndexedGray_WhiteIsZero"; break; - case kCVPixelFormatType_16BE555: pixelFormatName = @"kCVPixelFormatType_16BE555"; break; - case kCVPixelFormatType_16LE555: pixelFormatName = @"kCVPixelFormatType_16LE555"; break; - case kCVPixelFormatType_16LE5551: pixelFormatName = @"kCVPixelFormatType_16LE5551"; break; - case kCVPixelFormatType_16BE565: pixelFormatName = @"kCVPixelFormatType_16BE565"; break; - case kCVPixelFormatType_16LE565: pixelFormatName = @"kCVPixelFormatType_16LE565"; break; - case kCVPixelFormatType_24RGB: pixelFormatName = @"kCVPixelFormatType_24RGB"; break; - case kCVPixelFormatType_24BGR: pixelFormatName = @"kCVPixelFormatType_24BGR"; break; - case kCVPixelFormatType_32ARGB: pixelFormatName = @"kCVPixelFormatType_32ARGB"; break; - case kCVPixelFormatType_32BGRA: pixelFormatName = @"kCVPixelFormatType_32BGRA"; break; - case kCVPixelFormatType_32ABGR: pixelFormatName = @"kCVPixelFormatType_32ABGR"; break; - case kCVPixelFormatType_32RGBA: pixelFormatName = @"kCVPixelFormatType_32RGBA"; break; - case kCVPixelFormatType_64ARGB: pixelFormatName = @"kCVPixelFormatType_64ARGB"; break; - case kCVPixelFormatType_48RGB: pixelFormatName = @"kCVPixelFormatType_48RGB"; break; - case kCVPixelFormatType_32AlphaGray: pixelFormatName = @"kCVPixelFormatType_32AlphaGray"; break; - case kCVPixelFormatType_16Gray: pixelFormatName = @"kCVPixelFormatType_16Gray"; break; - case kCVPixelFormatType_30RGB: pixelFormatName = @"kCVPixelFormatType_30RGB"; break; - case kCVPixelFormatType_422YpCbCr8: pixelFormatName = @"kCVPixelFormatType_422YpCbCr8"; break; - case kCVPixelFormatType_4444YpCbCrA8: pixelFormatName = @"kCVPixelFormatType_4444YpCbCrA8"; break; - case kCVPixelFormatType_4444YpCbCrA8R: pixelFormatName = @"kCVPixelFormatType_4444YpCbCrA8R"; break; - case kCVPixelFormatType_4444AYpCbCr8: pixelFormatName = @"kCVPixelFormatType_4444AYpCbCr8"; break; - case kCVPixelFormatType_4444AYpCbCr16: pixelFormatName = @"kCVPixelFormatType_4444AYpCbCr16"; break; - case kCVPixelFormatType_444YpCbCr8: pixelFormatName = @"kCVPixelFormatType_444YpCbCr8"; break; - case kCVPixelFormatType_422YpCbCr16: pixelFormatName = @"kCVPixelFormatType_422YpCbCr16"; break; - case kCVPixelFormatType_422YpCbCr10: pixelFormatName = @"kCVPixelFormatType_422YpCbCr10"; break; - case kCVPixelFormatType_444YpCbCr10: pixelFormatName = @"kCVPixelFormatType_444YpCbCr10"; break; - case kCVPixelFormatType_420YpCbCr8Planar: pixelFormatName = @"kCVPixelFormatType_420YpCbCr8Planar"; break; - case kCVPixelFormatType_420YpCbCr8PlanarFullRange: pixelFormatName = @"kCVPixelFormatType_420YpCbCr8PlanarFullRange"; break; - case kCVPixelFormatType_422YpCbCr_4A_8BiPlanar: pixelFormatName = @"kCVPixelFormatType_422YpCbCr_4A_8BiPlanar"; break; - case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: pixelFormatName = @"kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange"; break; - case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange: pixelFormatName = @"kCVPixelFormatType_420YpCbCr8BiPlanarFullRange"; break; - case kCVPixelFormatType_422YpCbCr8_yuvs: pixelFormatName = @"kCVPixelFormatType_422YpCbCr8_yuvs"; break; - case kCVPixelFormatType_422YpCbCr8FullRange: pixelFormatName = @"kCVPixelFormatType_422YpCbCr8FullRange"; break; - case kCVPixelFormatType_OneComponent8: pixelFormatName = @"kCVPixelFormatType_OneComponent8"; break; - case kCVPixelFormatType_TwoComponent8: pixelFormatName = @"kCVPixelFormatType_TwoComponent8"; break; - } - NSLog(@"Supported pixel format: %@", pixelFormatName); - } -} - -@end diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageContext.h b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageContext.h deleted file mode 100755 index d599601..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageContext.h +++ /dev/null @@ -1,55 +0,0 @@ -#import -#import -#import -#import "GLProgram.h" -#import "GPUImageFramebuffer.h" -#import "GPUImageFramebufferCache.h" - -#define GPUImageRotationSwapsWidthAndHeight(rotation) (((rotation) == kGPUImageRotateLeft) || ((rotation) == kGPUImageRotateRight) || ((rotation) == kGPUImageRotateRightFlipVertical) ) - -typedef enum { kGPUImageNoRotation, kGPUImageRotateLeft, kGPUImageRotateRight, kGPUImageFlipVertical, kGPUImageFlipHorizonal, kGPUImageRotateRightFlipVertical, kGPUImageRotateRightFlipHorizontal, kGPUImageRotate180 } GPUImageRotationMode; - -@interface GPUImageContext : NSObject - -@property(readonly, nonatomic) dispatch_queue_t contextQueue; -@property(readwrite, retain, nonatomic) GLProgram *currentShaderProgram; -@property(readonly, retain, nonatomic) NSOpenGLContext *context; -@property(readonly) CVOpenGLTextureCacheRef coreVideoTextureCache; -@property(readonly) GPUImageFramebufferCache *framebufferCache; - -+ (void *)contextKey; -+ (GPUImageContext *)sharedImageProcessingContext; -+ (dispatch_queue_t)sharedContextQueue; -+ (GPUImageFramebufferCache *)sharedFramebufferCache; -+ (void)useImageProcessingContext; -+ (void)setActiveShaderProgram:(GLProgram *)shaderProgram; -+ (GLint)maximumTextureSizeForThisDevice; -+ (GLint)maximumTextureUnitsForThisDevice; -+ (BOOL)deviceSupportsOpenGLESExtension:(NSString *)extension; -+ (BOOL)deviceSupportsRedTextures; -+ (BOOL)deviceSupportsFramebufferReads; -+ (CGSize)sizeThatFitsWithinATextureForSize:(CGSize)inputSize; - -- (void)presentBufferForDisplay; -- (GLProgram *)programForVertexShaderString:(NSString *)vertexShaderString fragmentShaderString:(NSString *)fragmentShaderString; - -- (void)useSharegroup:(CGLShareGroupObj *)sharegroup; - -// Manage fast texture upload -+ (BOOL)supportsFastTextureUpload; - -@end - -@protocol GPUImageInput -- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex; -- (void)setInputFramebuffer:(GPUImageFramebuffer *)newInputFramebuffer atIndex:(NSInteger)textureIndex; -- (NSInteger)nextAvailableTextureIndex; -- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex; -- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex; -- (CGSize)maximumOutputSize; -- (void)endProcessing; -- (BOOL)shouldIgnoreUpdatesToThisTarget; -- (BOOL)enabled; -- (BOOL)wantsMonochromeInput; -- (void)setCurrentlyReceivingMonochromeInput:(BOOL)newValue; -@end diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageContext.m b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageContext.m deleted file mode 100755 index 0532d95..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageContext.m +++ /dev/null @@ -1,268 +0,0 @@ -#import "GPUImageContext.h" -#import - -@interface GPUImageContext() -{ - NSMutableDictionary *shaderProgramCache; - CGLShareGroupObj *_sharegroup; - NSOpenGLPixelFormat *_pixelFormat; -} - -@end - -@implementation GPUImageContext - -@synthesize context = _context; -@synthesize currentShaderProgram = _currentShaderProgram; -@synthesize contextQueue = _contextQueue; -@synthesize coreVideoTextureCache = _coreVideoTextureCache; -@synthesize framebufferCache = _framebufferCache; - -static void *openGLESContextQueueKey; - -- (id)init; -{ - if (!(self = [super init])) - { - return nil; - } - - openGLESContextQueueKey = &openGLESContextQueueKey; - _contextQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.openGLESContextQueue", NULL); - dispatch_queue_set_specific(_contextQueue, openGLESContextQueueKey, (__bridge void *)self, NULL); - shaderProgramCache = [[NSMutableDictionary alloc] init]; - - return self; -} - -+ (void *)contextKey { - return openGLESContextQueueKey; -} - -// Based on Colin Wheeler's example here: http://cocoasamurai.blogspot.com/2011/04/singletons-your-doing-them-wrong.html -+ (GPUImageContext *)sharedImageProcessingContext; -{ - static dispatch_once_t pred; - static GPUImageContext *sharedImageProcessingContext = nil; - - dispatch_once(&pred, ^{ - sharedImageProcessingContext = [[[self class] alloc] init]; - }); - return sharedImageProcessingContext; -} - -+ (dispatch_queue_t)sharedContextQueue; -{ - return [[self sharedImageProcessingContext] contextQueue]; -} - -+ (GPUImageFramebufferCache *)sharedFramebufferCache; -{ - return [[self sharedImageProcessingContext] framebufferCache]; -} - -+ (void)useImageProcessingContext; -{ - NSOpenGLContext *imageProcessingContext = [[GPUImageContext sharedImageProcessingContext] context]; - if ([NSOpenGLContext currentContext] != imageProcessingContext) - { - [imageProcessingContext makeCurrentContext]; - } -} - -+ (void)setActiveShaderProgram:(GLProgram *)shaderProgram; -{ - GPUImageContext *sharedContext = [GPUImageContext sharedImageProcessingContext]; - NSOpenGLContext *imageProcessingContext = [sharedContext context]; - if ([NSOpenGLContext currentContext] != imageProcessingContext) - { - [imageProcessingContext makeCurrentContext]; - } - - if (sharedContext.currentShaderProgram != shaderProgram) - { - sharedContext.currentShaderProgram = shaderProgram; - [shaderProgram use]; - } -} - -+ (GLint)maximumTextureSizeForThisDevice; -{ - static dispatch_once_t pred; - static GLint maxTextureSize = 0; - - dispatch_once(&pred, ^{ - [self useImageProcessingContext]; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); - }); - - return maxTextureSize; -} - -+ (GLint)maximumTextureUnitsForThisDevice; -{ - GLint maxTextureUnits; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); - return maxTextureUnits; -} - -+ (BOOL)deviceSupportsOpenGLESExtension:(NSString *)extension; -{ - static dispatch_once_t pred; - static NSArray *extensionNames = nil; - - // Cache extensions for later quick reference, since this won't change for a given device - dispatch_once(&pred, ^{ - [GPUImageContext useImageProcessingContext]; - NSString *extensionsString = [NSString stringWithCString:(const char *)glGetString(GL_EXTENSIONS) encoding:NSASCIIStringEncoding]; - extensionNames = [extensionsString componentsSeparatedByString:@" "]; - }); - - return [extensionNames containsObject:extension]; -} - -+ (BOOL)deviceSupportsFramebufferReads; -{ - return NO; -} - -// http://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_rg.txt - -+ (BOOL)deviceSupportsRedTextures; -{ - static dispatch_once_t pred; - static BOOL supportsRedTextures = NO; - - dispatch_once(&pred, ^{ - supportsRedTextures = [GPUImageContext deviceSupportsOpenGLESExtension:@"GL_EXT_texture_rg"]; - }); - - return supportsRedTextures; -} - - -+ (CGSize)sizeThatFitsWithinATextureForSize:(CGSize)inputSize; -{ - GLint maxTextureSize = [self maximumTextureSizeForThisDevice]; - if ( (inputSize.width < maxTextureSize) && (inputSize.height < maxTextureSize) ) - { - return inputSize; - } - - CGSize adjustedSize; - if (inputSize.width > inputSize.height) - { - adjustedSize.width = (CGFloat)maxTextureSize; - adjustedSize.height = ((CGFloat)maxTextureSize / inputSize.width) * inputSize.height; - } - else - { - adjustedSize.height = (CGFloat)maxTextureSize; - adjustedSize.width = ((CGFloat)maxTextureSize / inputSize.height) * inputSize.width; - } - - return adjustedSize; -} - -- (void)presentBufferForDisplay; -{ - [self.context flushBuffer]; -} - -- (GLProgram *)programForVertexShaderString:(NSString *)vertexShaderString fragmentShaderString:(NSString *)fragmentShaderString; -{ - NSString *lookupKeyForShaderProgram = [NSString stringWithFormat:@"V: %@ - F: %@", vertexShaderString, fragmentShaderString]; - GLProgram *programFromCache = [shaderProgramCache objectForKey:lookupKeyForShaderProgram]; - - if (programFromCache == nil) - { - programFromCache = [[GLProgram alloc] initWithVertexShaderString:vertexShaderString fragmentShaderString:fragmentShaderString]; - [shaderProgramCache setObject:programFromCache forKey:lookupKeyForShaderProgram]; - } - - return programFromCache; -} - -- (void)useSharegroup:(CGLShareGroupObj *)sharegroup; -{ - NSAssert(_context == nil, @"Unable to use a share group when the context has already been created. Call this method before you use the context for the first time."); - - _sharegroup = sharegroup; -} - -- (NSOpenGLContext *)createContext; -{ - NSOpenGLPixelFormatAttribute pixelFormatAttributes[] = { - NSOpenGLPFADoubleBuffer, - NSOpenGLPFAAccelerated, 0, - 0 - }; - - _pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes]; - if (_pixelFormat == nil) - { - NSLog(@"Error: No appropriate pixel format found"); - } - // TODO: Take into account the sharegroup - NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:_pixelFormat shareContext:nil]; - - NSAssert(context != nil, @"Unable to create an OpenGL context. The GPUImage framework requires OpenGL support to work."); - return context; -} - -- (CVOpenGLTextureCacheRef)coreVideoTextureCache; -{ - if (_coreVideoTextureCache == NULL) - { - - CVReturn err = CVOpenGLTextureCacheCreate(kCFAllocatorDefault, NULL, (__bridge void *)[self context], [_pixelFormat CGLPixelFormatObj], NULL, &_coreVideoTextureCache); - - if (err) - { - NSAssert(NO, @"Error at CVOpenGLESTextureCacheCreate %d", err); - } - - } - - return _coreVideoTextureCache; -} - - -#pragma mark - -#pragma mark Manage fast texture upload - -+ (BOOL)supportsFastTextureUpload; -{ - // This may need to be redone to account for the Mac's accelerated data transfer methods - return NO; -} - -#pragma mark - -#pragma mark Accessors - -- (NSOpenGLContext *)context; -{ - if (_context == nil) - { - _context = [self createContext]; - [_context makeCurrentContext]; - - // Set up a few global settings for the image processing pipeline - glDisable(GL_DEPTH_TEST); - glEnable(GL_TEXTURE_2D); - } - - return _context; -} - -- (GPUImageFramebufferCache *)framebufferCache; -{ - if (_framebufferCache == nil) - { - _framebufferCache = [[GPUImageFramebufferCache alloc] init]; - } - - return _framebufferCache; -} - -@end diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageMac-Info.plist b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageMac-Info.plist deleted file mode 100644 index 88daf2c..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageMac-Info.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFile - - CFBundleIdentifier - com.sunsetlakesoftware.${PRODUCT_NAME:rfc1034identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - NSHumanReadableCopyright - Copyright © 2013 Sunset Lake Software LLC. All rights reserved. - NSPrincipalClass - - - diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageMac-Prefix.pch b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageMac-Prefix.pch deleted file mode 100644 index f01e581..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageMac-Prefix.pch +++ /dev/null @@ -1,7 +0,0 @@ -// -// Prefix header for all source files of the 'GPUImageMac' target in the 'GPUImageMac' project -// - -#ifdef __OBJC__ - #import -#endif diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageMovieWriter.h b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageMovieWriter.h deleted file mode 100755 index 530e5a6..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageMovieWriter.h +++ /dev/null @@ -1,57 +0,0 @@ -#import -#import -#import "GPUImageContext.h" - -extern NSString *const kGPUImageColorSwizzlingFragmentShaderString; - -@protocol GPUImageMovieWriterDelegate - -@optional -- (void)movieRecordingCompleted; -- (void)movieRecordingFailedWithError:(NSError*)error; - -@end - -@interface GPUImageMovieWriter : NSObject -{ - CMVideoDimensions videoDimensions; - CMVideoCodecType videoType; - - NSURL *movieURL; - NSString *fileType; - AVAssetWriter *assetWriter; - AVAssetWriterInput *assetWriterAudioInput; - AVAssetWriterInput *assetWriterVideoInput; - AVAssetWriterInputPixelBufferAdaptor *assetWriterPixelBufferInput; - dispatch_queue_t movieWritingQueue; - - CGSize videoSize; - GPUImageRotationMode inputRotation; -} - -@property(readwrite, nonatomic) BOOL hasAudioTrack; -@property(readwrite, nonatomic) BOOL shouldPassthroughAudio; -@property(nonatomic, copy) void(^completionBlock)(void); -@property(nonatomic, copy) void(^failureBlock)(NSError*); -@property(nonatomic, assign) id delegate; -@property(readwrite, nonatomic) BOOL encodingLiveVideo; -@property(nonatomic, copy) void(^videoInputReadyCallback)(void); -@property(nonatomic, copy) void(^audioInputReadyCallback)(void); -@property(nonatomic) BOOL enabled; - -// Initialization and teardown -- (id)initWithMovieURL:(NSURL *)newMovieURL size:(CGSize)newSize; -- (id)initWithMovieURL:(NSURL *)newMovieURL size:(CGSize)newSize fileType:(NSString *)newFileType outputSettings:(NSMutableDictionary *)outputSettings; - -- (void)setHasAudioTrack:(BOOL)hasAudioTrack audioSettings:(NSDictionary *)audioOutputSettings; - -// Movie recording -- (void)startRecording; -- (void)startRecordingInOrientation:(CGAffineTransform)orientationTransform; -- (void)finishRecording; -- (void)finishRecordingWithCompletionHandler:(void (^)(void))handler; -- (void)cancelRecording; -- (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer; -- (void)enableSynchronizationCallbacks; - -@end diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageMovieWriter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageMovieWriter.m deleted file mode 100755 index 89f0a37..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageMovieWriter.m +++ /dev/null @@ -1,644 +0,0 @@ -#import "GPUImageMovieWriter.h" - -#import "GPUImageContext.h" -#import "GLProgram.h" -#import "GPUImageFilter.h" - -#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE -NSString *const kGPUImageColorSwizzlingFragmentShaderString = SHADER_STRING -( - varying highp vec2 textureCoordinate; - - uniform sampler2D inputImageTexture; - - void main() - { - gl_FragColor = texture2D(inputImageTexture, textureCoordinate).bgra; - } - ); -#else -NSString *const kGPUImageColorSwizzlingFragmentShaderString = SHADER_STRING -( - varying vec2 textureCoordinate; - - uniform sampler2D inputImageTexture; - - void main() - { - gl_FragColor = texture2D(inputImageTexture, textureCoordinate).bgra; - } - ); -#endif - - -@interface GPUImageMovieWriter () -{ - GPUImageFramebuffer *firstInputFramebuffer; - - GLuint movieFramebuffer, movieRenderbuffer; - - GLProgram *colorSwizzlingProgram; - GLint colorSwizzlingPositionAttribute, colorSwizzlingTextureCoordinateAttribute; - GLint colorSwizzlingInputTextureUniform; - - GLubyte *frameData; - - CMTime startTime, previousFrameTime; - - BOOL isRecording; -} - -// Movie recording -- (void)initializeMovieWithOutputSettings:(NSMutableDictionary *)outputSettings; - -// Frame rendering -- (void)createDataFBO; -- (void)destroyDataFBO; -- (void)setFilterFBO; - -- (void)renderAtInternalSize; - -@end - -@implementation GPUImageMovieWriter - -@synthesize hasAudioTrack = _hasAudioTrack; -@synthesize encodingLiveVideo = _encodingLiveVideo; -@synthesize shouldPassthroughAudio = _shouldPassthroughAudio; -@synthesize completionBlock; -@synthesize failureBlock; -@synthesize videoInputReadyCallback; -@synthesize audioInputReadyCallback; -@synthesize enabled; - -@synthesize delegate = _delegate; - -#pragma mark - -#pragma mark Initialization and teardown - -- (id)initWithMovieURL:(NSURL *)newMovieURL size:(CGSize)newSize; -{ - return [self initWithMovieURL:newMovieURL size:newSize fileType:AVFileTypeQuickTimeMovie outputSettings:nil]; -} - -- (id)initWithMovieURL:(NSURL *)newMovieURL size:(CGSize)newSize fileType:(NSString *)newFileType outputSettings:(NSMutableDictionary *)outputSettings; -{ - if (!(self = [super init])) - { - return nil; - } - - self.enabled = YES; - - videoSize = newSize; - movieURL = newMovieURL; - fileType = newFileType; - startTime = kCMTimeInvalid; - _encodingLiveVideo = YES; - previousFrameTime = kCMTimeNegativeInfinity; - inputRotation = kGPUImageNoRotation; - - runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext useImageProcessingContext]; - - if ([GPUImageContext supportsFastTextureUpload]) - { - colorSwizzlingProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImagePassthroughFragmentShaderString]; - } - else - { - colorSwizzlingProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageColorSwizzlingFragmentShaderString]; - } - - if (!colorSwizzlingProgram.initialized) - { - [colorSwizzlingProgram addAttribute:@"position"]; - [colorSwizzlingProgram addAttribute:@"inputTextureCoordinate"]; - - if (![colorSwizzlingProgram link]) - { - NSString *progLog = [colorSwizzlingProgram programLog]; - NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [colorSwizzlingProgram fragmentShaderLog]; - NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [colorSwizzlingProgram vertexShaderLog]; - NSLog(@"Vertex shader compile log: %@", vertLog); - colorSwizzlingProgram = nil; - NSAssert(NO, @"Filter shader link failed"); - } - } - - colorSwizzlingPositionAttribute = [colorSwizzlingProgram attributeIndex:@"position"]; - colorSwizzlingTextureCoordinateAttribute = [colorSwizzlingProgram attributeIndex:@"inputTextureCoordinate"]; - colorSwizzlingInputTextureUniform = [colorSwizzlingProgram uniformIndex:@"inputImageTexture"]; - - // REFACTOR: Wrap this in a block for the image processing queue - [GPUImageContext setActiveShaderProgram:colorSwizzlingProgram]; - - glEnableVertexAttribArray(colorSwizzlingPositionAttribute); - glEnableVertexAttribArray(colorSwizzlingTextureCoordinateAttribute); - }); - - [self initializeMovieWithOutputSettings:outputSettings]; - - return self; -} - -- (void)dealloc; -{ - [self destroyDataFBO]; - - if (frameData != NULL) - { - free(frameData); - } -} - -#pragma mark - -#pragma mark Movie recording - -- (void)initializeMovieWithOutputSettings:(NSMutableDictionary *)outputSettings; -{ - isRecording = NO; - - self.enabled = YES; - frameData = (GLubyte *) malloc((int)videoSize.width * (int)videoSize.height * 4); - -// frameData = (GLubyte *) calloc(videoSize.width * videoSize.height * 4, sizeof(GLubyte)); - NSError *error = nil; - assetWriter = [[AVAssetWriter alloc] initWithURL:movieURL fileType:fileType error:&error]; - if (error != nil) - { - NSLog(@"Error: %@", error); - if (failureBlock) - { - failureBlock(error); - } - else - { - if(self.delegate && [self.delegate respondsToSelector:@selector(movieRecordingFailedWithError:)]) - { - [self.delegate movieRecordingFailedWithError:error]; - } - } - } - - // Set this to make sure that a functional movie is produced, even if the recording is cut off mid-stream. Only the last second should be lost in that case. - assetWriter.movieFragmentInterval = CMTimeMakeWithSeconds(1.0, 1000); - - // use default output settings if none specified - if (outputSettings == nil) - { - outputSettings = [[NSMutableDictionary alloc] init]; - [outputSettings setObject:AVVideoCodecH264 forKey:AVVideoCodecKey]; - [outputSettings setObject:[NSNumber numberWithInt:videoSize.width] forKey:AVVideoWidthKey]; - [outputSettings setObject:[NSNumber numberWithInt:videoSize.height] forKey:AVVideoHeightKey]; - } - // custom output settings specified - else - { - #ifndef NS_BLOCK_ASSERTIONS - NSString *videoCodec = [outputSettings objectForKey:AVVideoCodecKey]; - NSNumber *width = [outputSettings objectForKey:AVVideoWidthKey]; - NSNumber *height = [outputSettings objectForKey:AVVideoHeightKey]; - - NSAssert(videoCodec && width && height, @"OutputSettings is missing required parameters."); - #endif - } - - /* - NSDictionary *videoCleanApertureSettings = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt:videoSize.width], AVVideoCleanApertureWidthKey, - [NSNumber numberWithInt:videoSize.height], AVVideoCleanApertureHeightKey, - [NSNumber numberWithInt:0], AVVideoCleanApertureHorizontalOffsetKey, - [NSNumber numberWithInt:0], AVVideoCleanApertureVerticalOffsetKey, - nil]; - - NSDictionary *videoAspectRatioSettings = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt:3], AVVideoPixelAspectRatioHorizontalSpacingKey, - [NSNumber numberWithInt:3], AVVideoPixelAspectRatioVerticalSpacingKey, - nil]; - - NSMutableDictionary * compressionProperties = [[NSMutableDictionary alloc] init]; - [compressionProperties setObject:videoCleanApertureSettings forKey:AVVideoCleanApertureKey]; - [compressionProperties setObject:videoAspectRatioSettings forKey:AVVideoPixelAspectRatioKey]; - [compressionProperties setObject:[NSNumber numberWithInt: 2000000] forKey:AVVideoAverageBitRateKey]; - [compressionProperties setObject:[NSNumber numberWithInt: 16] forKey:AVVideoMaxKeyFrameIntervalKey]; - [compressionProperties setObject:AVVideoProfileLevelH264Main31 forKey:AVVideoProfileLevelKey]; - - [outputSettings setObject:compressionProperties forKey:AVVideoCompressionPropertiesKey]; - */ - - assetWriterVideoInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:outputSettings]; - assetWriterVideoInput.expectsMediaDataInRealTime = _encodingLiveVideo; - - // You need to use BGRA for the video in order to get realtime encoding. I use a color-swizzling shader to line up glReadPixels' normal RGBA output with the movie input's BGRA. - NSDictionary *sourcePixelBufferAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey, - [NSNumber numberWithInt:videoSize.width], kCVPixelBufferWidthKey, - [NSNumber numberWithInt:videoSize.height], kCVPixelBufferHeightKey, - nil]; -// NSDictionary *sourcePixelBufferAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, -// nil]; - - assetWriterPixelBufferInput = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:assetWriterVideoInput sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary]; - - [assetWriter addInput:assetWriterVideoInput]; -} - -- (void)startRecording; -{ - isRecording = YES; - startTime = kCMTimeInvalid; - // [assetWriter startWriting]; - - // [assetWriter startSessionAtSourceTime:kCMTimeZero]; -} - -- (void)startRecordingInOrientation:(CGAffineTransform)orientationTransform; -{ - assetWriterVideoInput.transform = orientationTransform; - - [self startRecording]; -} - -- (void)cancelRecording; -{ - if (assetWriter.status == AVAssetWriterStatusCompleted) - { - return; - } - - isRecording = NO; - runOnMainQueueWithoutDeadlocking(^{ - [assetWriterVideoInput markAsFinished]; - [assetWriterAudioInput markAsFinished]; - [assetWriter cancelWriting]; - }); -} - -- (void)finishRecording; -{ - [self finishRecordingWithCompletionHandler:nil]; -} - -- (void)finishRecordingWithCompletionHandler:(void (^)(void))handler; -{ - if (assetWriter.status == AVAssetWriterStatusCompleted) - { - return; - } - - isRecording = NO; - runOnMainQueueWithoutDeadlocking(^{ - [assetWriterVideoInput markAsFinished]; - [assetWriterAudioInput markAsFinished]; -#if (!defined(__IPHONE_6_0) || (__IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)) - // Not iOS 6 SDK - [assetWriter finishWriting]; - if (handler) handler(); -#else - // iOS 6 SDK - if ([assetWriter respondsToSelector:@selector(finishWritingWithCompletionHandler:)]) { - // Running iOS 6 - [assetWriter finishWritingWithCompletionHandler:(handler ?: ^{ })]; - } - else { - // Not running iOS 6 - [assetWriter finishWriting]; - if (handler) handler(); - } -#endif - }); -} - -- (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer; -{ - if (!isRecording) - { - return; - } - - if (_hasAudioTrack) - { - CMTime currentSampleTime = CMSampleBufferGetOutputPresentationTimeStamp(audioBuffer); - - if (CMTIME_IS_INVALID(startTime)) - { - if (audioInputReadyCallback == NULL) - { - [assetWriter startWriting]; - } - [assetWriter startSessionAtSourceTime:currentSampleTime]; - startTime = currentSampleTime; - } - - if (!assetWriterAudioInput.readyForMoreMediaData) - { - NSLog(@"Had to drop an audio frame"); - return; - } - -// NSLog(@"Recorded audio sample time: %lld, %d, %lld", currentSampleTime.value, currentSampleTime.timescale, currentSampleTime.epoch); - [assetWriterAudioInput appendSampleBuffer:audioBuffer]; - } -} - -- (void)enableSynchronizationCallbacks; -{ - if (videoInputReadyCallback != NULL) - { - [assetWriter startWriting]; - [assetWriterVideoInput requestMediaDataWhenReadyOnQueue:[GPUImageContext sharedContextQueue] usingBlock:videoInputReadyCallback]; - } - - if (audioInputReadyCallback != NULL) - { - [assetWriterAudioInput requestMediaDataWhenReadyOnQueue:[GPUImageContext sharedContextQueue] usingBlock:audioInputReadyCallback]; - } - -} - -#pragma mark - -#pragma mark Frame rendering - -- (void)createDataFBO; -{ - glActiveTexture(GL_TEXTURE1); - glGenFramebuffers(1, &movieFramebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, movieFramebuffer); - - glGenRenderbuffers(1, &movieRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, movieRenderbuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, (int)videoSize.width, (int)videoSize.height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, movieRenderbuffer); - - #ifndef NS_BLOCK_ASSERTIONS - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - NSAssert(status == GL_FRAMEBUFFER_COMPLETE, @"Incomplete filter FBO: %d", status); - #endif -} - -- (void)destroyDataFBO; -{ - [GPUImageContext useImageProcessingContext]; - - if (movieFramebuffer) - { - glDeleteFramebuffers(1, &movieFramebuffer); - movieFramebuffer = 0; - } - - if (movieRenderbuffer) - { - glDeleteRenderbuffers(1, &movieRenderbuffer); - movieRenderbuffer = 0; - } -} - -- (void)setFilterFBO; -{ - if (!movieFramebuffer) - { - [self createDataFBO]; - } - - glBindFramebuffer(GL_FRAMEBUFFER, movieFramebuffer); - - glViewport(0, 0, (int)videoSize.width, (int)videoSize.height); -} - -- (void)renderAtInternalSize; -{ - [GPUImageContext useImageProcessingContext]; - [self setFilterFBO]; - - [GPUImageContext setActiveShaderProgram:colorSwizzlingProgram]; - - glClearColor(1.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // This needs to be flipped to write out to video correctly - static const GLfloat squareVertices[] = { - -1.0f, -1.0f, - 1.0f, -1.0f, - -1.0f, 1.0f, - 1.0f, 1.0f, - }; - - static const GLfloat textureCoordinates[] = { - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - }; - - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, [firstInputFramebuffer texture]); - glUniform1i(colorSwizzlingInputTextureUniform, 4); - - glVertexAttribPointer(colorSwizzlingPositionAttribute, 2, GL_FLOAT, 0, 0, squareVertices); - glVertexAttribPointer(colorSwizzlingTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, textureCoordinates); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - glFinish(); - [firstInputFramebuffer unlock]; -} - -#pragma mark - -#pragma mark GPUImageInput protocol - -- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex; -{ - if (!isRecording) - { - [firstInputFramebuffer unlock]; - return; - } - - // Drop frames forced by images and other things with no time constants - // Also, if two consecutive times with the same value are added to the movie, it aborts recording, so I bail on that case - if ( (CMTIME_IS_INVALID(frameTime)) || (CMTIME_COMPARE_INLINE(frameTime, ==, previousFrameTime)) || (CMTIME_IS_INDEFINITE(frameTime)) ) - { - [firstInputFramebuffer unlock]; - return; - } - - if (CMTIME_IS_INVALID(startTime)) - { - if (videoInputReadyCallback == NULL) - { - [assetWriter startWriting]; - } - - [assetWriter startSessionAtSourceTime:frameTime]; - startTime = frameTime; - } - - if (!assetWriterVideoInput.readyForMoreMediaData) - { - [firstInputFramebuffer unlock]; - NSLog(@"Had to drop a video frame"); - return; - } - - // Render the frame with swizzled colors, so that they can be uploaded quickly as BGRA frames - [GPUImageContext useImageProcessingContext]; - [self renderAtInternalSize]; - - CVPixelBufferRef pixel_buffer = NULL; - - CVReturn status = CVPixelBufferPoolCreatePixelBuffer (NULL, [assetWriterPixelBufferInput pixelBufferPool], &pixel_buffer); - if ((pixel_buffer == NULL) || (status != kCVReturnSuccess)) - { - return; - } - else - { - CVPixelBufferLockBaseAddress(pixel_buffer, 0); - - GLubyte *pixelBufferData = (GLubyte *)CVPixelBufferGetBaseAddress(pixel_buffer); - glReadPixels(0, 0, videoSize.width, videoSize.height, GL_RGBA, GL_UNSIGNED_BYTE, pixelBufferData); - } - -// if(![assetWriterPixelBufferInput appendPixelBuffer:pixel_buffer withPresentationTime:CMTimeSubtract(frameTime, startTime)]) - if(![assetWriterPixelBufferInput appendPixelBuffer:pixel_buffer withPresentationTime:frameTime]) - { - NSLog(@"Problem appending pixel buffer at time: %lld", frameTime.value); - } - else - { -// NSLog(@"Recorded video sample time: %lld, %d, %lld", frameTime.value, frameTime.timescale, frameTime.epoch); - } - CVPixelBufferUnlockBaseAddress(pixel_buffer, 0); - - previousFrameTime = frameTime; - - if (![GPUImageContext supportsFastTextureUpload]) - { - CVPixelBufferRelease(pixel_buffer); - } -} - -- (NSInteger)nextAvailableTextureIndex; -{ - return 0; -} - -- (void)setInputFramebuffer:(GPUImageFramebuffer *)newInputFramebuffer atIndex:(NSInteger)textureIndex; -{ - firstInputFramebuffer = newInputFramebuffer; - [firstInputFramebuffer lock]; -} - -- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex; -{ - inputRotation = newInputRotation; -} - -- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex; -{ -} - -- (CGSize)maximumOutputSize; -{ - return videoSize; -} - -- (void)endProcessing -{ - if (completionBlock) - { - completionBlock(); - } - else - { - if (_delegate && [_delegate respondsToSelector:@selector(movieRecordingCompleted)]) - { - [_delegate movieRecordingCompleted]; - } - } -} - -- (BOOL)shouldIgnoreUpdatesToThisTarget; -{ - return NO; -} - -- (void)conserveMemoryForNextFrame; -{ - -} - -- (BOOL)wantsMonochromeInput; -{ - return NO; -} - -- (void)setCurrentlyReceivingMonochromeInput:(BOOL)newValue; -{ - -} - -#pragma mark - -#pragma mark Accessors - -- (void)setHasAudioTrack:(BOOL)newValue -{ - [self setHasAudioTrack:newValue audioSettings:nil]; -} - -- (void)setHasAudioTrack:(BOOL)newValue audioSettings:(NSDictionary *)audioOutputSettings; -{ - _hasAudioTrack = newValue; - - if (_hasAudioTrack) - { - if (_shouldPassthroughAudio) - { - // Do not set any settings so audio will be the same as passthrough - audioOutputSettings = nil; - } - else if (audioOutputSettings == nil) - { -// double preferredHardwareSampleRate = [[AVAudioSession sharedInstance] currentHardwareSampleRate]; - double preferredHardwareSampleRate = 48000; // ? - TODO: Fix this, because it's probably broken - - AudioChannelLayout acl; - bzero( &acl, sizeof(acl)); - acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono; - - audioOutputSettings = [NSDictionary dictionaryWithObjectsAndKeys: - [ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey, - [ NSNumber numberWithInt: 1 ], AVNumberOfChannelsKey, - [ NSNumber numberWithFloat: preferredHardwareSampleRate ], AVSampleRateKey, - [ NSData dataWithBytes: &acl length: sizeof( acl ) ], AVChannelLayoutKey, - //[ NSNumber numberWithInt:AVAudioQualityLow], AVEncoderAudioQualityKey, - [ NSNumber numberWithInt: 64000 ], AVEncoderBitRateKey, - nil]; -/* - AudioChannelLayout acl; - bzero( &acl, sizeof(acl)); - acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono; - - audioOutputSettings = [NSDictionary dictionaryWithObjectsAndKeys: - [ NSNumber numberWithInt: kAudioFormatMPEG4AAC ], AVFormatIDKey, - [ NSNumber numberWithInt: 1 ], AVNumberOfChannelsKey, - [ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey, - [ NSNumber numberWithInt: 64000 ], AVEncoderBitRateKey, - [ NSData dataWithBytes: &acl length: sizeof( acl ) ], AVChannelLayoutKey, - nil];*/ - } - - assetWriterAudioInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioOutputSettings]; - [assetWriter addInput:assetWriterAudioInput]; - assetWriterAudioInput.expectsMediaDataInRealTime = _encodingLiveVideo; - } - else - { - // Remove audio track if it exists - } -} - - -@end diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImagePicture.h b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImagePicture.h deleted file mode 100755 index 6597053..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImagePicture.h +++ /dev/null @@ -1,25 +0,0 @@ -#import -#import "GPUImageOutput.h" - -@interface GPUImagePicture : GPUImageOutput -{ - CGSize pixelSizeOfImage; - BOOL hasProcessedImage; - - dispatch_semaphore_t imageUpdateSemaphore; -} - -// Initialization and teardown -- (id)initWithURL:(NSURL *)url; -- (id)initWithImage:(NSImage *)newImageSource; -- (id)initWithCGImage:(CGImageRef)newImageSource; -- (id)initWithImage:(NSImage *)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput; -- (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput; - -// Image rendering -- (void)processImage; -- (BOOL)processImageWithCompletionHandler:(void (^)(void))completion; -- (void)processImageUpToFilter:(GPUImageOutput *)finalFilterInChain withCompletionHandler:(void (^)(NSImage *processedImage))block; -- (CGSize)outputImageSize; - -@end diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImagePicture.m b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImagePicture.m deleted file mode 100755 index 1ef37bf..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImagePicture.m +++ /dev/null @@ -1,299 +0,0 @@ -#import "GPUImagePicture.h" - -@implementation GPUImagePicture - -#pragma mark - -#pragma mark Initialization and teardown - -- (id)initWithURL:(NSURL *)url; -{ - NSData *imageData = [[NSData alloc] initWithContentsOfURL:url]; - - if (!(self = [self initWithData:imageData])) - { - return nil; - } - - return self; -} - -- (id)initWithData:(NSData *)imageData; -{ - NSImage *inputImage = [[NSImage alloc] initWithData:imageData]; - - if (!(self = [self initWithImage:inputImage])) - { - return nil; - } - - return self; -} - -- (id)initWithImage:(NSImage *)newImageSource; -{ - if (!(self = [self initWithImage:newImageSource smoothlyScaleOutput:NO])) - { - return nil; - } - - return self; -} - -- (id)initWithCGImage:(CGImageRef)newImageSource; -{ - if (!(self = [self initWithCGImage:newImageSource smoothlyScaleOutput:NO])) - { - return nil; - } - return self; -} - -- (id)initWithImage:(NSImage *)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput; -{ - return [self initWithCGImage:[newImageSource CGImageForProposedRect:NULL context:NULL hints:nil] smoothlyScaleOutput:smoothlyScaleOutput]; -} - -- (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput; -{ - if (!(self = [super init])) - { - return nil; - } - - hasProcessedImage = NO; - self.shouldSmoothlyScaleOutput = smoothlyScaleOutput; - imageUpdateSemaphore = dispatch_semaphore_create(1); - - // TODO: Dispatch this whole thing asynchronously to move image loading off main thread - CGFloat widthOfImage = CGImageGetWidth(newImageSource); - CGFloat heightOfImage = CGImageGetHeight(newImageSource); - - // If passed an empty image reference, CGContextDrawImage will fail in future versions of the SDK. - NSAssert( widthOfImage > 0 && heightOfImage > 0, @"Passed image must not be empty - it should be at least 1px tall and wide"); - - pixelSizeOfImage = CGSizeMake(widthOfImage, heightOfImage); - CGSize pixelSizeToUseForTexture = pixelSizeOfImage; - - BOOL shouldRedrawUsingCoreGraphics = NO; - - // For now, deal with images larger than the maximum texture size by resizing to be within that limit - CGSize scaledImageSizeToFitOnGPU = [GPUImageContext sizeThatFitsWithinATextureForSize:pixelSizeOfImage]; - if (!CGSizeEqualToSize(scaledImageSizeToFitOnGPU, pixelSizeOfImage)) - { - pixelSizeOfImage = scaledImageSizeToFitOnGPU; - pixelSizeToUseForTexture = pixelSizeOfImage; - shouldRedrawUsingCoreGraphics = YES; - } - - if (self.shouldSmoothlyScaleOutput) - { - // In order to use mipmaps, you need to provide power-of-two textures, so convert to the next largest power of two and stretch to fill - CGFloat powerClosestToWidth = ceil(log2(pixelSizeOfImage.width)); - CGFloat powerClosestToHeight = ceil(log2(pixelSizeOfImage.height)); - - pixelSizeToUseForTexture = CGSizeMake(pow(2.0, powerClosestToWidth), pow(2.0, powerClosestToHeight)); - - shouldRedrawUsingCoreGraphics = YES; - } - - GLubyte *imageData = NULL; - CFDataRef dataFromImageDataProvider; - GLenum format = GL_BGRA; - - if (!shouldRedrawUsingCoreGraphics) { - /* Check that the memory layout is compatible with GL, as we cannot use glPixelStore to - * tell GL about the memory layout with GLES. - */ - if (CGImageGetBytesPerRow(newImageSource) != CGImageGetWidth(newImageSource) * 4 || - CGImageGetBitsPerPixel(newImageSource) != 32 || - CGImageGetBitsPerComponent(newImageSource) != 8) - { - shouldRedrawUsingCoreGraphics = YES; - } else { - /* Check that the bitmap pixel format is compatible with GL */ - CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(newImageSource); - if ((bitmapInfo & kCGBitmapFloatComponents) != 0) { - /* We don't support float components for use directly in GL */ - shouldRedrawUsingCoreGraphics = YES; - } else { - CGBitmapInfo byteOrderInfo = bitmapInfo & kCGBitmapByteOrderMask; - if (byteOrderInfo == kCGBitmapByteOrder32Little) { - /* Little endian, for alpha-first we can use this bitmap directly in GL */ - CGImageAlphaInfo alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask; - if (alphaInfo != kCGImageAlphaPremultipliedFirst && alphaInfo != kCGImageAlphaFirst && - alphaInfo != kCGImageAlphaNoneSkipFirst) { - shouldRedrawUsingCoreGraphics = YES; - } - } else if (byteOrderInfo == kCGBitmapByteOrderDefault || byteOrderInfo == kCGBitmapByteOrder32Big) { - /* Big endian, for alpha-last we can use this bitmap directly in GL */ - CGImageAlphaInfo alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask; - if (alphaInfo != kCGImageAlphaPremultipliedLast && alphaInfo != kCGImageAlphaLast && - alphaInfo != kCGImageAlphaNoneSkipLast) { - shouldRedrawUsingCoreGraphics = YES; - } else { - /* Can access directly using GL_RGBA pixel format */ - format = GL_RGBA; - } - } - } - } - } - - // CFAbsoluteTime elapsedTime, startTime = CFAbsoluteTimeGetCurrent(); - - if (shouldRedrawUsingCoreGraphics) - { - // For resized or incompatible image: redraw - imageData = (GLubyte *) calloc(1, (int)pixelSizeToUseForTexture.width * (int)pixelSizeToUseForTexture.height * 4); - - CGColorSpaceRef genericRGBColorspace = CGColorSpaceCreateDeviceRGB(); - - CGContextRef imageContext = CGBitmapContextCreate(imageData, (size_t)pixelSizeToUseForTexture.width, (size_t)pixelSizeToUseForTexture.height, 8, (size_t)pixelSizeToUseForTexture.width * 4, genericRGBColorspace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); - // CGContextSetBlendMode(imageContext, kCGBlendModeCopy); // From Technical Q&A QA1708: http://developer.apple.com/library/ios/#qa/qa1708/_index.html - CGContextDrawImage(imageContext, CGRectMake(0.0, 0.0, pixelSizeToUseForTexture.width, pixelSizeToUseForTexture.height), newImageSource); - CGContextRelease(imageContext); - CGColorSpaceRelease(genericRGBColorspace); - } - else - { - // Access the raw image bytes directly - dataFromImageDataProvider = CGDataProviderCopyData(CGImageGetDataProvider(newImageSource)); - imageData = (GLubyte *)CFDataGetBytePtr(dataFromImageDataProvider); - } - - // elapsedTime = (CFAbsoluteTimeGetCurrent() - startTime) * 1000.0; - // NSLog(@"Core Graphics drawing time: %f", elapsedTime); - - // CGFloat currentRedTotal = 0.0f, currentGreenTotal = 0.0f, currentBlueTotal = 0.0f, currentAlphaTotal = 0.0f; - // NSUInteger totalNumberOfPixels = round(pixelSizeToUseForTexture.width * pixelSizeToUseForTexture.height); - // - // for (NSUInteger currentPixel = 0; currentPixel < totalNumberOfPixels; currentPixel++) - // { - // currentBlueTotal += (CGFloat)imageData[(currentPixel * 4)] / 255.0f; - // currentGreenTotal += (CGFloat)imageData[(currentPixel * 4) + 1] / 255.0f; - // currentRedTotal += (CGFloat)imageData[(currentPixel * 4 + 2)] / 255.0f; - // currentAlphaTotal += (CGFloat)imageData[(currentPixel * 4) + 3] / 255.0f; - // } - // - // NSLog(@"Debug, average input image red: %f, green: %f, blue: %f, alpha: %f", currentRedTotal / (CGFloat)totalNumberOfPixels, currentGreenTotal / (CGFloat)totalNumberOfPixels, currentBlueTotal / (CGFloat)totalNumberOfPixels, currentAlphaTotal / (CGFloat)totalNumberOfPixels); - - runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext useImageProcessingContext]; - - outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:pixelSizeToUseForTexture onlyTexture:YES]; - [outputFramebuffer disableReferenceCounting]; - - glBindTexture(GL_TEXTURE_2D, [outputFramebuffer texture]); - if (self.shouldSmoothlyScaleOutput) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - } - // no need to use self.outputTextureOptions here since pictures need this texture formats and type - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)pixelSizeToUseForTexture.width, (int)pixelSizeToUseForTexture.height, 0, format, GL_UNSIGNED_BYTE, imageData); - - if (self.shouldSmoothlyScaleOutput) - { - glGenerateMipmap(GL_TEXTURE_2D); - } - glBindTexture(GL_TEXTURE_2D, 0); - }); - - if (shouldRedrawUsingCoreGraphics) - { - free(imageData); - } - else - { - CFRelease(dataFromImageDataProvider); - } - - return self; -} - -// ARC forbids explicit message send of 'release' on Mountain Lion, but needs this on Lion and older -#if ( (MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8) || (!defined(__MAC_10_8)) ) -- (void)dealloc; -{ - [outputFramebuffer enableReferenceCounting]; - [outputFramebuffer unlock]; - - if (imageUpdateSemaphore != NULL) - { - dispatch_release(imageUpdateSemaphore); - } -} -#endif - -#pragma mark - -#pragma mark Image rendering - -- (void)removeAllTargets; -{ - [super removeAllTargets]; - hasProcessedImage = NO; -} - -- (void)processImage; -{ - [self processImageWithCompletionHandler:nil]; -} - -- (BOOL)processImageWithCompletionHandler:(void (^)(void))completion; -{ - hasProcessedImage = YES; - - // dispatch_semaphore_wait(imageUpdateSemaphore, DISPATCH_TIME_FOREVER); - - if (dispatch_semaphore_wait(imageUpdateSemaphore, DISPATCH_TIME_NOW) != 0) - { - return NO; - } - - runAsynchronouslyOnVideoProcessingQueue(^{ - for (id currentTarget in targets) - { - NSInteger indexOfObject = [targets indexOfObject:currentTarget]; - NSInteger textureIndexOfTarget = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue]; - - [currentTarget setCurrentlyReceivingMonochromeInput:NO]; - [currentTarget setInputSize:pixelSizeOfImage atIndex:textureIndexOfTarget]; - [currentTarget setInputFramebuffer:outputFramebuffer atIndex:textureIndexOfTarget]; - [currentTarget newFrameReadyAtTime:kCMTimeIndefinite atIndex:textureIndexOfTarget]; - } - - dispatch_semaphore_signal(imageUpdateSemaphore); - - if (completion != nil) { - completion(); - } - }); - - return YES; -} - -- (void)processImageUpToFilter:(GPUImageOutput *)finalFilterInChain withCompletionHandler:(void (^)(NSImage *processedImage))block; -{ - [finalFilterInChain useNextFrameForImageCapture]; - [self processImageWithCompletionHandler:^{ - NSImage *imageFromFilter = [finalFilterInChain imageFromCurrentFramebuffer]; - block(imageFromFilter); - }]; -} - -- (CGSize)outputImageSize; -{ - return pixelSizeOfImage; -} - -- (void)addTarget:(id)newTarget atTextureLocation:(NSInteger)textureLocation; -{ - [super addTarget:newTarget atTextureLocation:textureLocation]; - - if (hasProcessedImage) - { - [newTarget setInputSize:pixelSizeOfImage atIndex:textureLocation]; - [newTarget newFrameReadyAtTime:kCMTimeIndefinite atIndex:textureLocation]; - } -} - -@end \ No newline at end of file diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageView.h b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageView.h deleted file mode 100755 index 029883a..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageView.h +++ /dev/null @@ -1,39 +0,0 @@ -#import -#import "GPUImageContext.h" - -typedef enum { - kGPUImageFillModeStretch, // Stretch to fill the full view, which may distort the image outside of its normal aspect ratio - kGPUImageFillModePreserveAspectRatio, // Maintains the aspect ratio of the source image, adding bars of the specified background color - kGPUImageFillModePreserveAspectRatioAndFill // Maintains the aspect ratio of the source image, zooming in on its center to fill the view -} GPUImageFillModeType; - -/** - UIView subclass to use as an endpoint for displaying GPUImage outputs - */ -@interface GPUImageView : NSOpenGLView -{ - GPUImageRotationMode inputRotation; -} - -/** The fill mode dictates how images are fit in the view, with the default being kGPUImageFillModePreserveAspectRatio - */ -@property(readwrite, nonatomic) GPUImageFillModeType fillMode; - -/** This calculates the current display size, in pixels, taking into account Retina scaling factors - */ -@property(readonly, nonatomic) CGSize sizeInPixels; - -@property(nonatomic) BOOL enabled; - -/** Handling fill mode - - @param redComponent Red component for background color - @param greenComponent Green component for background color - @param blueComponent Blue component for background color - @param alphaComponent Alpha component for background color - */ -- (void)setBackgroundColorRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent alpha:(GLfloat)alphaComponent; - -- (void)setCurrentlyReceivingMonochromeInput:(BOOL)newValue; - -@end diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageView.m b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageView.m deleted file mode 100755 index 9e277ac..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/GPUImageView.m +++ /dev/null @@ -1,458 +0,0 @@ -#import "GPUImageView.h" -#import -#import "GPUImageContext.h" -#import "GPUImageFilter.h" -#import - -#pragma mark - -#pragma mark Private methods and instance variables - -@interface GPUImageView () -{ - GPUImageFramebuffer *inputFramebufferForDisplay; - - GLProgram *displayProgram; - GLint displayPositionAttribute, displayTextureCoordinateAttribute; - GLint displayInputTextureUniform; - - CGSize inputImageSize; - GLfloat imageVertices[8]; - GLfloat backgroundColorRed, backgroundColorGreen, backgroundColorBlue, backgroundColorAlpha; -} - -// Initialization and teardown -- (void)commonInit; - -// Managing the display FBOs -- (void)createDisplayFramebuffer; -- (void)destroyDisplayFramebuffer; - -// Handling fill mode -- (void)recalculateViewGeometry; - -@end - -@implementation GPUImageView - -@synthesize sizeInPixels = _sizeInPixels; -@synthesize fillMode = _fillMode; -@synthesize enabled; - -#pragma mark - -#pragma mark Initialization and teardown - -- (id)initWithFrame:(CGRect)frame -{ - if (!(self = [super initWithFrame:frame])) - { - return nil; - } - - [self commonInit]; - - return self; -} - --(id)initWithCoder:(NSCoder *)coder -{ - if (!(self = [super initWithCoder:coder])) - { - return nil; - } - - [self commonInit]; - - return self; -} - -- (void)commonInit; -{ - [self setOpenGLContext:[[GPUImageContext sharedImageProcessingContext] context]]; - - if ([self respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) - { - [self setWantsBestResolutionOpenGLSurface:YES]; - } - - inputRotation = kGPUImageNoRotation; - self.hidden = NO; - - self.enabled = YES; - - runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext useImageProcessingContext]; - displayProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImagePassthroughFragmentShaderString]; - - if (!displayProgram.initialized) - { - [displayProgram addAttribute:@"position"]; - [displayProgram addAttribute:@"inputTextureCoordinate"]; - - if (![displayProgram link]) - { - NSString *progLog = [displayProgram programLog]; - NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [displayProgram fragmentShaderLog]; - NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [displayProgram vertexShaderLog]; - NSLog(@"Vertex shader compile log: %@", vertLog); - displayProgram = nil; - NSAssert(NO, @"Filter shader link failed"); - } - } - - displayPositionAttribute = [displayProgram attributeIndex:@"position"]; - displayTextureCoordinateAttribute = [displayProgram attributeIndex:@"inputTextureCoordinate"]; - displayInputTextureUniform = [displayProgram uniformIndex:@"inputImageTexture"]; - - [GPUImageContext setActiveShaderProgram:displayProgram]; - - glEnableVertexAttribArray(displayPositionAttribute); - glEnableVertexAttribArray(displayTextureCoordinateAttribute); - - [self setBackgroundColorRed:0.0 green:0.0 blue:0.0 alpha:1.0]; - _fillMode = kGPUImageFillModePreserveAspectRatio; - [self createDisplayFramebuffer]; - }); - -} - -- (void)dealloc -{ -} - -#pragma mark - -#pragma mark Managing the display FBOs - -- (void)createDisplayFramebuffer; -{ - // Perhaps I'll use an FBO at some time later, but for now will render directly to the screen - if ([self respondsToSelector:@selector(convertSizeToBacking:)]) - { - _sizeInPixels = [self convertSizeToBacking:self.bounds.size]; - } - else - { - _sizeInPixels = self.bounds.size; - } -} - -- (void)destroyDisplayFramebuffer; -{ - [self.openGLContext makeCurrentContext]; -} - -- (void)setDisplayFramebuffer; -{ - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - - glViewport(0, 0, (GLint)_sizeInPixels.width, (GLint)_sizeInPixels.height); -} - -- (void)presentFramebuffer; -{ - [self.openGLContext flushBuffer]; -} - -- (void)reshape; -{ - CGSize viewSize = self.bounds.size; - if ([self respondsToSelector:@selector(convertSizeToBacking:)]) - { - viewSize = [self convertSizeToBacking:self.bounds.size]; - } - - if ( (_sizeInPixels.width == viewSize.width) && (_sizeInPixels.height == viewSize.height) ) - { - return; - } - - _sizeInPixels = viewSize; - - [self recalculateViewGeometry]; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [self newFrameReadyAtTime:kCMTimeInvalid atIndex:0]; - }); -} - -#pragma mark - -#pragma mark Handling fill mode - -- (void)recalculateViewGeometry; -{ - CGFloat heightScaling, widthScaling; - - CGSize currentViewSize = self.sizeInPixels; - - if ((inputImageSize.width < 1.0) || (inputImageSize.height < 1.0)) - { - return; - } - - CGRect insetRect = AVMakeRectWithAspectRatioInsideRect(inputImageSize, CGRectMake(0.0,0.0,currentViewSize.width,currentViewSize.height)); - if ((insetRect.size.width < 1.0) || (insetRect.size.width < 1.0)) - { - insetRect = CGRectMake(0.0,0.0,currentViewSize.width,currentViewSize.height); - } - - switch(_fillMode) - { - case kGPUImageFillModeStretch: - { - widthScaling = 1.0; - heightScaling = 1.0; - }; break; - case kGPUImageFillModePreserveAspectRatio: - { - widthScaling = insetRect.size.width / currentViewSize.width; - heightScaling = insetRect.size.height / currentViewSize.height; - }; break; - case kGPUImageFillModePreserveAspectRatioAndFill: - { - widthScaling = currentViewSize.height / insetRect.size.height; - heightScaling = currentViewSize.width / insetRect.size.width; - }; break; - } - - imageVertices[0] = -widthScaling; - imageVertices[1] = -heightScaling; - imageVertices[2] = widthScaling; - imageVertices[3] = -heightScaling; - imageVertices[4] = -widthScaling; - imageVertices[5] = heightScaling; - imageVertices[6] = widthScaling; - imageVertices[7] = heightScaling; -} - -- (void)setBackgroundColorRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent alpha:(GLfloat)alphaComponent; -{ - backgroundColorRed = redComponent; - backgroundColorGreen = greenComponent; - backgroundColorBlue = blueComponent; - backgroundColorAlpha = alphaComponent; -} - -+ (const GLfloat *)textureCoordinatesForRotation:(GPUImageRotationMode)rotationMode; -{ -// static const GLfloat noRotationTextureCoordinates[] = { -// 0.0f, 0.0f, -// 1.0f, 0.0f, -// 0.0f, 1.0f, -// 1.0f, 1.0f, -// }; - - static const GLfloat noRotationTextureCoordinates[] = { - 0.0f, 1.0f, - 1.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 0.0f, - }; - - static const GLfloat rotateRightTextureCoordinates[] = { - 1.0f, 1.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, - }; - - static const GLfloat rotateLeftTextureCoordinates[] = { - 0.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, - }; - - static const GLfloat verticalFlipTextureCoordinates[] = { - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - }; - - static const GLfloat horizontalFlipTextureCoordinates[] = { - 1.0f, 1.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 0.0f, 0.0f, - }; - - static const GLfloat rotateRightVerticalFlipTextureCoordinates[] = { - 1.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 0.0f, - 0.0f, 1.0f, - }; - - static const GLfloat rotateRightHorizontalFlipTextureCoordinates[] = { - 1.0f, 1.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, - }; - - static const GLfloat rotate180TextureCoordinates[] = { - 1.0f, 0.0f, - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - }; - - switch(rotationMode) - { - case kGPUImageNoRotation: return noRotationTextureCoordinates; - case kGPUImageRotateLeft: return rotateLeftTextureCoordinates; - case kGPUImageRotateRight: return rotateRightTextureCoordinates; - case kGPUImageFlipVertical: return verticalFlipTextureCoordinates; - case kGPUImageFlipHorizonal: return horizontalFlipTextureCoordinates; - case kGPUImageRotateRightFlipVertical: return rotateRightVerticalFlipTextureCoordinates; - case kGPUImageRotateRightFlipHorizontal: return rotateRightHorizontalFlipTextureCoordinates; - case kGPUImageRotate180: return rotate180TextureCoordinates; - } -} - -#pragma mark - -#pragma mark GPUInput protocol - -- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex; -{ - runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext setActiveShaderProgram:displayProgram]; - [self setDisplayFramebuffer]; - - glClearColor(backgroundColorRed, backgroundColorGreen, backgroundColorBlue, backgroundColorAlpha); - glClear(GL_COLOR_BUFFER_BIT); - - // Re-render onscreen, flipped to a normal orientation - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, [inputFramebufferForDisplay texture]); - glUniform1i(displayInputTextureUniform, 4); - - glVertexAttribPointer(displayPositionAttribute, 2, GL_FLOAT, 0, 0, imageVertices); - glVertexAttribPointer(displayTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, [GPUImageView textureCoordinatesForRotation:inputRotation]); - - BOOL canLockFocus = YES; - if ([self respondsToSelector:@selector(lockFocusIfCanDraw)]) - { - canLockFocus = [self lockFocusIfCanDraw]; - } - else - { - [self lockFocus]; - } - - if (canLockFocus) - { - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - [self presentFramebuffer]; - glBindTexture(GL_TEXTURE_2D, 0); - [self unlockFocus]; - } - - [inputFramebufferForDisplay unlock]; - inputFramebufferForDisplay = nil; - }); -} - -- (NSInteger)nextAvailableTextureIndex; -{ - return 0; -} - -- (void)setInputFramebuffer:(GPUImageFramebuffer *)newInputFramebuffer atIndex:(NSInteger)textureIndex; -{ - inputFramebufferForDisplay = newInputFramebuffer; - [inputFramebufferForDisplay lock]; -} - -- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex; -{ - inputRotation = newInputRotation; -} - -- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex; -{ - if ((newSize.width < 1.0) || (newSize.height < 1.0)) - { - return; - } - - runSynchronouslyOnVideoProcessingQueue(^{ - CGSize rotatedSize = newSize; - - if (GPUImageRotationSwapsWidthAndHeight(inputRotation)) - { - rotatedSize.width = newSize.height; - rotatedSize.height = newSize.width; - } - - if (!CGSizeEqualToSize(inputImageSize, rotatedSize)) - { - inputImageSize = rotatedSize; - [self recalculateViewGeometry]; - } - }); -} - -- (CGSize)maximumOutputSize; -{ - if ([self respondsToSelector:@selector(convertSizeToBacking:)]) - { - return [self convertSizeToBacking:self.bounds.size]; - } - else - { - return self.bounds.size; - } -} - -- (void)endProcessing -{ -} - -- (BOOL)shouldIgnoreUpdatesToThisTarget; -{ - return NO; -} - -- (void)conserveMemoryForNextFrame; -{ - -} - -- (BOOL)wantsMonochromeInput; -{ - return NO; -} - -- (void)setCurrentlyReceivingMonochromeInput:(BOOL)newValue; -{ - -} - -#pragma mark - -#pragma mark Accessors - -- (CGSize)sizeInPixels; -{ - if (CGSizeEqualToSize(_sizeInPixels, CGSizeZero)) - { - return [self maximumOutputSize]; - } - else - { - return _sizeInPixels; - } -} - -- (void)setFillMode:(GPUImageFillModeType)newValue; -{ - _fillMode = newValue; - [self recalculateViewGeometry]; -} - -@end diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/en.lproj/InfoPlist.strings b/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/en.lproj/InfoPlist.strings deleted file mode 100644 index 477b28f..0000000 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/Mac/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImageMovieWriter.m b/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImageMovieWriter.m index addc0a7..1974d61 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImageMovieWriter.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImageMovieWriter.m @@ -101,43 +101,43 @@ - (id)initWithMovieURL:(NSURL *)newMovieURL size:(CGSize)newSize fileType:(NSStr [_movieWriterContext useSharegroup:[[[GPUImageContext sharedImageProcessingContext] context] sharegroup]]; runSynchronouslyOnContextQueue(_movieWriterContext, ^{ - [_movieWriterContext useAsCurrentContext]; + [self->_movieWriterContext useAsCurrentContext]; if ([GPUImageContext supportsFastTextureUpload]) { - colorSwizzlingProgram = [_movieWriterContext programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImagePassthroughFragmentShaderString]; + self->colorSwizzlingProgram = [self->_movieWriterContext programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImagePassthroughFragmentShaderString]; } else { - colorSwizzlingProgram = [_movieWriterContext programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageColorSwizzlingFragmentShaderString]; + self->colorSwizzlingProgram = [self->_movieWriterContext programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImageColorSwizzlingFragmentShaderString]; } - if (!colorSwizzlingProgram.initialized) + if (!self->colorSwizzlingProgram.initialized) { - [colorSwizzlingProgram addAttribute:@"position"]; - [colorSwizzlingProgram addAttribute:@"inputTextureCoordinate"]; + [self->colorSwizzlingProgram addAttribute:@"position"]; + [self->colorSwizzlingProgram addAttribute:@"inputTextureCoordinate"]; - if (![colorSwizzlingProgram link]) + if (![self->colorSwizzlingProgram link]) { - NSString *progLog = [colorSwizzlingProgram programLog]; + NSString *progLog = [self->colorSwizzlingProgram programLog]; NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [colorSwizzlingProgram fragmentShaderLog]; + NSString *fragLog = [self->colorSwizzlingProgram fragmentShaderLog]; NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [colorSwizzlingProgram vertexShaderLog]; + NSString *vertLog = [self->colorSwizzlingProgram vertexShaderLog]; NSLog(@"Vertex shader compile log: %@", vertLog); - colorSwizzlingProgram = nil; + self->colorSwizzlingProgram = nil; NSAssert(NO, @"Filter shader link failed"); } } - colorSwizzlingPositionAttribute = [colorSwizzlingProgram attributeIndex:@"position"]; - colorSwizzlingTextureCoordinateAttribute = [colorSwizzlingProgram attributeIndex:@"inputTextureCoordinate"]; - colorSwizzlingInputTextureUniform = [colorSwizzlingProgram uniformIndex:@"inputImageTexture"]; + self->colorSwizzlingPositionAttribute = [self->colorSwizzlingProgram attributeIndex:@"position"]; + self->colorSwizzlingTextureCoordinateAttribute = [self->colorSwizzlingProgram attributeIndex:@"inputTextureCoordinate"]; + self->colorSwizzlingInputTextureUniform = [self->colorSwizzlingProgram uniformIndex:@"inputImageTexture"]; - [_movieWriterContext setContextShaderProgram:colorSwizzlingProgram]; + [self->_movieWriterContext setContextShaderProgram:self->colorSwizzlingProgram]; - glEnableVertexAttribArray(colorSwizzlingPositionAttribute); - glEnableVertexAttribArray(colorSwizzlingTextureCoordinateAttribute); + glEnableVertexAttribArray(self->colorSwizzlingPositionAttribute); + glEnableVertexAttribArray(self->colorSwizzlingTextureCoordinateAttribute); }); [self initializeMovieWithOutputSettings:outputSettings]; @@ -272,9 +272,9 @@ - (void)startRecording; alreadyFinishedRecording = NO; startTime = kCMTimeInvalid; runSynchronouslyOnContextQueue(_movieWriterContext, ^{ - if (audioInputReadyCallback == NULL) + if (self->audioInputReadyCallback == NULL) { - [assetWriter startWriting]; + [self->assetWriter startWriting]; } }); isRecording = YES; @@ -297,19 +297,19 @@ - (void)cancelRecording; isRecording = NO; runSynchronouslyOnContextQueue(_movieWriterContext, ^{ - alreadyFinishedRecording = YES; + self->alreadyFinishedRecording = YES; - if( assetWriter.status == AVAssetWriterStatusWriting && ! videoEncodingIsFinished ) + if( self->assetWriter.status == AVAssetWriterStatusWriting && ! self->videoEncodingIsFinished ) { - videoEncodingIsFinished = YES; - [assetWriterVideoInput markAsFinished]; + self->videoEncodingIsFinished = YES; + [self->assetWriterVideoInput markAsFinished]; } - if( assetWriter.status == AVAssetWriterStatusWriting && ! audioEncodingIsFinished ) + if( self->assetWriter.status == AVAssetWriterStatusWriting && ! self->audioEncodingIsFinished ) { - audioEncodingIsFinished = YES; - [assetWriterAudioInput markAsFinished]; + self->audioEncodingIsFinished = YES; + [self->assetWriterAudioInput markAsFinished]; } - [assetWriter cancelWriting]; + [self->assetWriter cancelWriting]; }); } @@ -321,23 +321,23 @@ - (void)finishRecording; - (void)finishRecordingWithCompletionHandler:(void (^)(void))handler; { runSynchronouslyOnContextQueue(_movieWriterContext, ^{ - isRecording = NO; + self->isRecording = NO; - if (assetWriter.status == AVAssetWriterStatusCompleted || assetWriter.status == AVAssetWriterStatusCancelled || assetWriter.status == AVAssetWriterStatusUnknown) + if (self->assetWriter.status == AVAssetWriterStatusCompleted || self->assetWriter.status == AVAssetWriterStatusCancelled || self->assetWriter.status == AVAssetWriterStatusUnknown) { if (handler) - runAsynchronouslyOnContextQueue(_movieWriterContext, handler); + runAsynchronouslyOnContextQueue(self->_movieWriterContext, handler); return; } - if( assetWriter.status == AVAssetWriterStatusWriting && ! videoEncodingIsFinished ) + if( self->assetWriter.status == AVAssetWriterStatusWriting && ! self->videoEncodingIsFinished ) { - videoEncodingIsFinished = YES; - [assetWriterVideoInput markAsFinished]; + self->videoEncodingIsFinished = YES; + [self->assetWriterVideoInput markAsFinished]; } - if( assetWriter.status == AVAssetWriterStatusWriting && ! audioEncodingIsFinished ) + if( self->assetWriter.status == AVAssetWriterStatusWriting && ! self->audioEncodingIsFinished ) { - audioEncodingIsFinished = YES; - [assetWriterAudioInput markAsFinished]; + self->audioEncodingIsFinished = YES; + [self->assetWriterAudioInput markAsFinished]; } #if (!defined(__IPHONE_6_0) || (__IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)) // Not iOS 6 SDK @@ -346,18 +346,18 @@ - (void)finishRecordingWithCompletionHandler:(void (^)(void))handler; runAsynchronouslyOnContextQueue(_movieWriterContext,handler); #else // iOS 6 SDK - if ([assetWriter respondsToSelector:@selector(finishWritingWithCompletionHandler:)]) { + if ([self->assetWriter respondsToSelector:@selector(finishWritingWithCompletionHandler:)]) { // Running iOS 6 - [assetWriter finishWritingWithCompletionHandler:(handler ?: ^{ })]; + [self->assetWriter finishWritingWithCompletionHandler:(handler ?: ^{ })]; } else { // Not running iOS 6 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - [assetWriter finishWriting]; + [self->assetWriter finishWriting]; #pragma clang diagnostic pop if (handler) - runAsynchronouslyOnContextQueue(_movieWriterContext, handler); + runAsynchronouslyOnContextQueue(self->_movieWriterContext, handler); } #endif }); @@ -380,12 +380,12 @@ - (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer; if (CMTIME_IS_INVALID(startTime)) { runSynchronouslyOnContextQueue(_movieWriterContext, ^{ - if ((audioInputReadyCallback == NULL) && (assetWriter.status != AVAssetWriterStatusWriting)) + if ((self->audioInputReadyCallback == NULL) && (self->assetWriter.status != AVAssetWriterStatusWriting)) { - [assetWriter startWriting]; + [self->assetWriter startWriting]; } - [assetWriter startSessionAtSourceTime:currentSampleTime]; - startTime = currentSampleTime; + [self->assetWriter startSessionAtSourceTime:currentSampleTime]; + self->startTime = currentSampleTime; }); } @@ -454,19 +454,19 @@ - (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer; } // NSLog(@"Recorded audio sample time: %lld, %d, %lld", currentSampleTime.value, currentSampleTime.timescale, currentSampleTime.epoch); - void(^write)() = ^() { - while( ! assetWriterAudioInput.readyForMoreMediaData && ! _encodingLiveVideo && ! audioEncodingIsFinished ) { + void(^write)(void) = ^() { + while( ! self->assetWriterAudioInput.readyForMoreMediaData && ! self->_encodingLiveVideo && ! self->audioEncodingIsFinished ) { NSDate *maxDate = [NSDate dateWithTimeIntervalSinceNow:0.5]; //NSLog(@"audio waiting..."); [[NSRunLoop currentRunLoop] runUntilDate:maxDate]; } - if (!assetWriterAudioInput.readyForMoreMediaData) + if (!self->assetWriterAudioInput.readyForMoreMediaData) { NSLog(@"2: Had to drop an audio frame %@", CFBridgingRelease(CMTimeCopyDescription(kCFAllocatorDefault, currentSampleTime))); } - else if(assetWriter.status == AVAssetWriterStatusWriting) + else if(self->assetWriter.status == AVAssetWriterStatusWriting) { - if (![assetWriterAudioInput appendSampleBuffer:audioBuffer]) + if (![self->assetWriterAudioInput appendSampleBuffer:audioBuffer]) NSLog(@"Problem appending audio buffer at time: %@", CFBridgingRelease(CMTimeCopyDescription(kCFAllocatorDefault, currentSampleTime))); } else @@ -474,7 +474,7 @@ - (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer; //NSLog(@"Wrote an audio frame %@", CFBridgingRelease(CMTimeCopyDescription(kCFAllocatorDefault, currentSampleTime))); } - if (_shouldInvalidateAudioSampleWhenDone) + if (self->_shouldInvalidateAudioSampleWhenDone) { CMSampleBufferInvalidate(audioBuffer); } @@ -503,7 +503,7 @@ - (void)enableSynchronizationCallbacks; } videoQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.videoReadingQueue", GPUImageDefaultQueueAttribute()); [assetWriterVideoInput requestMediaDataWhenReadyOnQueue:videoQueue usingBlock:^{ - if( _paused ) + if( self->_paused ) { //NSLog(@"video requestMediaDataWhenReadyOnQueue paused"); // if we don't sleep, we'll get called back almost immediately, chewing up CPU @@ -511,15 +511,15 @@ - (void)enableSynchronizationCallbacks; return; } //NSLog(@"video requestMediaDataWhenReadyOnQueue begin"); - while( assetWriterVideoInput.readyForMoreMediaData && ! _paused ) + while( self->assetWriterVideoInput.readyForMoreMediaData && ! self->_paused ) { - if( videoInputReadyCallback && ! videoInputReadyCallback() && ! videoEncodingIsFinished ) + if( self->videoInputReadyCallback && ! self->videoInputReadyCallback() && ! self->videoEncodingIsFinished ) { - runAsynchronouslyOnContextQueue(_movieWriterContext, ^{ - if( assetWriter.status == AVAssetWriterStatusWriting && ! videoEncodingIsFinished ) + runAsynchronouslyOnContextQueue(self->_movieWriterContext, ^{ + if( self->assetWriter.status == AVAssetWriterStatusWriting && ! self->videoEncodingIsFinished ) { - videoEncodingIsFinished = YES; - [assetWriterVideoInput markAsFinished]; + self->videoEncodingIsFinished = YES; + [self->assetWriterVideoInput markAsFinished]; } }); } @@ -532,7 +532,7 @@ - (void)enableSynchronizationCallbacks; { audioQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.audioReadingQueue", GPUImageDefaultQueueAttribute()); [assetWriterAudioInput requestMediaDataWhenReadyOnQueue:audioQueue usingBlock:^{ - if( _paused ) + if( self->_paused ) { //NSLog(@"audio requestMediaDataWhenReadyOnQueue paused"); // if we don't sleep, we'll get called back almost immediately, chewing up CPU @@ -540,15 +540,15 @@ - (void)enableSynchronizationCallbacks; return; } //NSLog(@"audio requestMediaDataWhenReadyOnQueue begin"); - while( assetWriterAudioInput.readyForMoreMediaData && ! _paused ) + while( self->assetWriterAudioInput.readyForMoreMediaData && ! self->_paused ) { - if( audioInputReadyCallback && ! audioInputReadyCallback() && ! audioEncodingIsFinished ) + if( self->audioInputReadyCallback && ! self->audioInputReadyCallback() && ! self->audioEncodingIsFinished ) { - runAsynchronouslyOnContextQueue(_movieWriterContext, ^{ - if( assetWriter.status == AVAssetWriterStatusWriting && ! audioEncodingIsFinished ) + runAsynchronouslyOnContextQueue(self->_movieWriterContext, ^{ + if( self->assetWriter.status == AVAssetWriterStatusWriting && ! self->audioEncodingIsFinished ) { - audioEncodingIsFinished = YES; - [assetWriterAudioInput markAsFinished]; + self->audioEncodingIsFinished = YES; + [self->assetWriterAudioInput markAsFinished]; } }); } @@ -618,29 +618,29 @@ - (void)createDataFBO; - (void)destroyDataFBO; { runSynchronouslyOnContextQueue(_movieWriterContext, ^{ - [_movieWriterContext useAsCurrentContext]; + [self->_movieWriterContext useAsCurrentContext]; - if (movieFramebuffer) + if (self->movieFramebuffer) { - glDeleteFramebuffers(1, &movieFramebuffer); - movieFramebuffer = 0; + glDeleteFramebuffers(1, &self->movieFramebuffer); + self->movieFramebuffer = 0; } - if (movieRenderbuffer) + if (self->movieRenderbuffer) { - glDeleteRenderbuffers(1, &movieRenderbuffer); - movieRenderbuffer = 0; + glDeleteRenderbuffers(1, &self->movieRenderbuffer); + self->movieRenderbuffer = 0; } if ([GPUImageContext supportsFastTextureUpload]) { - if (renderTexture) + if (self->renderTexture) { - CFRelease(renderTexture); + CFRelease(self->renderTexture); } - if (renderTarget) + if (self->renderTarget) { - CVPixelBufferRelease(renderTarget); + CVPixelBufferRelease(self->renderTarget); } } @@ -737,13 +737,13 @@ - (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex; if (CMTIME_IS_INVALID(startTime)) { runSynchronouslyOnContextQueue(_movieWriterContext, ^{ - if ((videoInputReadyCallback == NULL) && (assetWriter.status != AVAssetWriterStatusWriting)) + if ((self->videoInputReadyCallback == NULL) && (self->assetWriter.status != AVAssetWriterStatusWriting)) { - [assetWriter startWriting]; + [self->assetWriter startWriting]; } - [assetWriter startSessionAtSourceTime:frameTime]; - startTime = frameTime; + [self->assetWriter startSessionAtSourceTime:frameTime]; + self->startTime = frameTime; }); } @@ -751,7 +751,7 @@ - (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex; glFinish(); runAsynchronouslyOnContextQueue(_movieWriterContext, ^{ - if (!assetWriterVideoInput.readyForMoreMediaData && _encodingLiveVideo) + if (!self->assetWriterVideoInput.readyForMoreMediaData && self->_encodingLiveVideo) { [inputFramebufferForBlock unlock]; NSLog(@"1: Had to drop a video frame: %@", CFBridgingRelease(CMTimeCopyDescription(kCFAllocatorDefault, frameTime))); @@ -759,19 +759,19 @@ - (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex; } // Render the frame with swizzled colors, so that they can be uploaded quickly as BGRA frames - [_movieWriterContext useAsCurrentContext]; + [self->_movieWriterContext useAsCurrentContext]; [self renderAtInternalSizeUsingFramebuffer:inputFramebufferForBlock]; CVPixelBufferRef pixel_buffer = NULL; if ([GPUImageContext supportsFastTextureUpload]) { - pixel_buffer = renderTarget; + pixel_buffer = self->renderTarget; CVPixelBufferLockBaseAddress(pixel_buffer, 0); } else { - CVReturn status = CVPixelBufferPoolCreatePixelBuffer (NULL, [assetWriterPixelBufferInput pixelBufferPool], &pixel_buffer); + CVReturn status = CVPixelBufferPoolCreatePixelBuffer (NULL, [self->assetWriterPixelBufferInput pixelBufferPool], &pixel_buffer); if ((pixel_buffer == NULL) || (status != kCVReturnSuccess)) { CVPixelBufferRelease(pixel_buffer); @@ -782,23 +782,23 @@ - (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex; CVPixelBufferLockBaseAddress(pixel_buffer, 0); GLubyte *pixelBufferData = (GLubyte *)CVPixelBufferGetBaseAddress(pixel_buffer); - glReadPixels(0, 0, videoSize.width, videoSize.height, GL_RGBA, GL_UNSIGNED_BYTE, pixelBufferData); + glReadPixels(0, 0, self->videoSize.width, self->videoSize.height, GL_RGBA, GL_UNSIGNED_BYTE, pixelBufferData); } } - void(^write)() = ^() { - while( ! assetWriterVideoInput.readyForMoreMediaData && ! _encodingLiveVideo && ! videoEncodingIsFinished ) { + void(^write)(void) = ^() { + while( ! self->assetWriterVideoInput.readyForMoreMediaData && ! self->_encodingLiveVideo && ! self->videoEncodingIsFinished ) { NSDate *maxDate = [NSDate dateWithTimeIntervalSinceNow:0.1]; // NSLog(@"video waiting..."); [[NSRunLoop currentRunLoop] runUntilDate:maxDate]; } - if (!assetWriterVideoInput.readyForMoreMediaData) + if (!self->assetWriterVideoInput.readyForMoreMediaData) { NSLog(@"2: Had to drop a video frame: %@", CFBridgingRelease(CMTimeCopyDescription(kCFAllocatorDefault, frameTime))); } else if(self.assetWriter.status == AVAssetWriterStatusWriting) { - if (![assetWriterPixelBufferInput appendPixelBuffer:pixel_buffer withPresentationTime:frameTime]) + if (![self->assetWriterPixelBufferInput appendPixelBuffer:pixel_buffer withPresentationTime:frameTime]) NSLog(@"Problem appending pixel buffer at time: %@", CFBridgingRelease(CMTimeCopyDescription(kCFAllocatorDefault, frameTime))); } else @@ -808,7 +808,7 @@ - (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex; } CVPixelBufferUnlockBaseAddress(pixel_buffer, 0); - previousFrameTime = frameTime; + self->previousFrameTime = frameTime; if (![GPUImageContext supportsFastTextureUpload]) { diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImagePicture+TextureSubimage.m b/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImagePicture+TextureSubimage.m index 71ef8f9..aa45b66 100644 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImagePicture+TextureSubimage.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImagePicture+TextureSubimage.m @@ -77,9 +77,9 @@ - (void)replaceTextureWithSubCGImage:(CGImageRef)subimageSource inRect:(CGRect)s runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - [outputFramebuffer disableReferenceCounting]; + [self->outputFramebuffer disableReferenceCounting]; - glBindTexture(GL_TEXTURE_2D, [outputFramebuffer texture]); + glBindTexture(GL_TEXTURE_2D, [self->outputFramebuffer texture]); // no need to use self.outputTextureOptions here since pictures need this texture formats and type glTexSubImage2D(GL_TEXTURE_2D, 0, subRect.origin.x, subRect.origin.y, (GLint)subRect.size.width, subRect.size.height, GL_RGBA, GL_UNSIGNED_BYTE, imageData); diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImagePicture.m b/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImagePicture.m index c525f4d..184e851 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImagePicture.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImagePicture.m @@ -249,10 +249,10 @@ - (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoot runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:pixelSizeToUseForTexture onlyTexture:YES]; - [outputFramebuffer disableReferenceCounting]; + self->outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:pixelSizeToUseForTexture onlyTexture:YES]; + [self->outputFramebuffer disableReferenceCounting]; - glBindTexture(GL_TEXTURE_2D, [outputFramebuffer texture]); + glBindTexture(GL_TEXTURE_2D, [self->outputFramebuffer texture]); if (self.shouldSmoothlyScaleOutput) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); @@ -322,18 +322,18 @@ - (BOOL)processImageWithCompletionHandler:(void (^)(void))completion; } runAsynchronouslyOnVideoProcessingQueue(^{ - for (id currentTarget in targets) + for (id currentTarget in self->targets) { - NSInteger indexOfObject = [targets indexOfObject:currentTarget]; - NSInteger textureIndexOfTarget = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue]; + NSInteger indexOfObject = [self->targets indexOfObject:currentTarget]; + NSInteger textureIndexOfTarget = [[self->targetTextureIndices objectAtIndex:indexOfObject] integerValue]; [currentTarget setCurrentlyReceivingMonochromeInput:NO]; - [currentTarget setInputSize:pixelSizeOfImage atIndex:textureIndexOfTarget]; - [currentTarget setInputFramebuffer:outputFramebuffer atIndex:textureIndexOfTarget]; + [currentTarget setInputSize:self->pixelSizeOfImage atIndex:textureIndexOfTarget]; + [currentTarget setInputFramebuffer:self->outputFramebuffer atIndex:textureIndexOfTarget]; [currentTarget newFrameReadyAtTime:kCMTimeIndefinite atIndex:textureIndexOfTarget]; } - dispatch_semaphore_signal(imageUpdateSemaphore); + dispatch_semaphore_signal(self->imageUpdateSemaphore); if (completion != nil) { completion(); diff --git a/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImageView.m b/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImageView.m index e092b80..0871066 100755 --- a/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImageView.m +++ b/ScannerApp/Frameworks/GPUImage/framework/Source/iOS/GPUImageView.m @@ -97,35 +97,35 @@ - (void)commonInit; runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext useImageProcessingContext]; - displayProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImagePassthroughFragmentShaderString]; - if (!displayProgram.initialized) + self->displayProgram = [[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:kGPUImagePassthroughFragmentShaderString]; + if (!self->displayProgram.initialized) { - [displayProgram addAttribute:@"position"]; - [displayProgram addAttribute:@"inputTextureCoordinate"]; + [self->displayProgram addAttribute:@"position"]; + [self->displayProgram addAttribute:@"inputTextureCoordinate"]; - if (![displayProgram link]) + if (![self->displayProgram link]) { - NSString *progLog = [displayProgram programLog]; + NSString *progLog = [self->displayProgram programLog]; NSLog(@"Program link log: %@", progLog); - NSString *fragLog = [displayProgram fragmentShaderLog]; + NSString *fragLog = [self->displayProgram fragmentShaderLog]; NSLog(@"Fragment shader compile log: %@", fragLog); - NSString *vertLog = [displayProgram vertexShaderLog]; + NSString *vertLog = [self->displayProgram vertexShaderLog]; NSLog(@"Vertex shader compile log: %@", vertLog); - displayProgram = nil; + self->displayProgram = nil; NSAssert(NO, @"Filter shader link failed"); } } - displayPositionAttribute = [displayProgram attributeIndex:@"position"]; - displayTextureCoordinateAttribute = [displayProgram attributeIndex:@"inputTextureCoordinate"]; - displayInputTextureUniform = [displayProgram uniformIndex:@"inputImageTexture"]; // This does assume a name of "inputTexture" for the fragment shader + self->displayPositionAttribute = [self->displayProgram attributeIndex:@"position"]; + self->displayTextureCoordinateAttribute = [self->displayProgram attributeIndex:@"inputTextureCoordinate"]; + self->displayInputTextureUniform = [self->displayProgram uniformIndex:@"inputImageTexture"]; // This does assume a name of "inputTexture" for the fragment shader - [GPUImageContext setActiveShaderProgram:displayProgram]; - glEnableVertexAttribArray(displayPositionAttribute); - glEnableVertexAttribArray(displayTextureCoordinateAttribute); + [GPUImageContext setActiveShaderProgram:self->displayProgram]; + glEnableVertexAttribArray(self->displayPositionAttribute); + glEnableVertexAttribArray(self->displayTextureCoordinateAttribute); [self setBackgroundColorRed:0.0 green:0.0 blue:0.0 alpha:1.0]; - _fillMode = kGPUImageFillModePreserveAspectRatio; + self->_fillMode = kGPUImageFillModePreserveAspectRatio; [self createDisplayFramebuffer]; }); } @@ -240,9 +240,9 @@ - (void)recalculateViewGeometry; // CGFloat imageAspectRatio = inputImageSize.width / inputImageSize.height; // CGFloat viewAspectRatio = currentViewSize.width / currentViewSize.height; - CGRect insetRect = AVMakeRectWithAspectRatioInsideRect(inputImageSize, self.bounds); + CGRect insetRect = AVMakeRectWithAspectRatioInsideRect(self->inputImageSize, self.bounds); - switch(_fillMode) + switch(self->_fillMode) { case kGPUImageFillModeStretch: { @@ -262,14 +262,14 @@ - (void)recalculateViewGeometry; }; break; } - imageVertices[0] = -widthScaling; - imageVertices[1] = -heightScaling; - imageVertices[2] = widthScaling; - imageVertices[3] = -heightScaling; - imageVertices[4] = -widthScaling; - imageVertices[5] = heightScaling; - imageVertices[6] = widthScaling; - imageVertices[7] = heightScaling; + self->imageVertices[0] = -widthScaling; + self->imageVertices[1] = -heightScaling; + self->imageVertices[2] = widthScaling; + self->imageVertices[3] = -heightScaling; + self->imageVertices[4] = -widthScaling; + self->imageVertices[5] = heightScaling; + self->imageVertices[6] = widthScaling; + self->imageVertices[7] = heightScaling; }); // static const GLfloat imageVertices[] = { @@ -372,24 +372,24 @@ + (const GLfloat *)textureCoordinatesForRotation:(GPUImageRotationMode)rotationM - (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex; { runSynchronouslyOnVideoProcessingQueue(^{ - [GPUImageContext setActiveShaderProgram:displayProgram]; + [GPUImageContext setActiveShaderProgram:self->displayProgram]; [self setDisplayFramebuffer]; - glClearColor(backgroundColorRed, backgroundColorGreen, backgroundColorBlue, backgroundColorAlpha); + glClearColor(self->backgroundColorRed, self->backgroundColorGreen, self->backgroundColorBlue, self->backgroundColorAlpha); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, [inputFramebufferForDisplay texture]); - glUniform1i(displayInputTextureUniform, 4); + glBindTexture(GL_TEXTURE_2D, [self->inputFramebufferForDisplay texture]); + glUniform1i(self->displayInputTextureUniform, 4); - glVertexAttribPointer(displayPositionAttribute, 2, GL_FLOAT, 0, 0, imageVertices); - glVertexAttribPointer(displayTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, [GPUImageView textureCoordinatesForRotation:inputRotation]); + glVertexAttribPointer(self->displayPositionAttribute, 2, GL_FLOAT, 0, 0, self->imageVertices); + glVertexAttribPointer(self->displayTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, [GPUImageView textureCoordinatesForRotation:self->inputRotation]); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); [self presentFramebuffer]; - [inputFramebufferForDisplay unlock]; - inputFramebufferForDisplay = nil; + [self->inputFramebufferForDisplay unlock]; + self->inputFramebufferForDisplay = nil; }); } @@ -414,15 +414,15 @@ - (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex; runSynchronouslyOnVideoProcessingQueue(^{ CGSize rotatedSize = newSize; - if (GPUImageRotationSwapsWidthAndHeight(inputRotation)) + if (GPUImageRotationSwapsWidthAndHeight(self->inputRotation)) { rotatedSize.width = newSize.height; rotatedSize.height = newSize.width; } - if (!CGSizeEqualToSize(inputImageSize, rotatedSize)) + if (!CGSizeEqualToSize(self->inputImageSize, rotatedSize)) { - inputImageSize = rotatedSize; + self->inputImageSize = rotatedSize; [self recalculateViewGeometry]; } }); diff --git a/ScannerApp/README.md b/ScannerApp/README.md index 03e6005..45dd7c9 100644 --- a/ScannerApp/README.md +++ b/ScannerApp/README.md @@ -8,7 +8,7 @@ The scanner app acquires RGB-D scans using a [structure.io sensor](https://struc ## Build - Open Scanner.xcodeproj with Xcode -- Set the URL to the data upload server at the top of `Scanner/ViewController.h` +- Set the URL to the data upload server at the top of `Scanner/Config.h` - Attach your iOS device and authorize the development machine to build to the device - Build the Scanner target for your device (select "Scanner" and your attached device name at the top left next to the "play" icon, and click the "play" icon) - Detach the device from the development machine, attach the structure sensor to the device, and run the Scanner app @@ -40,7 +40,7 @@ numIMUmeasurements = 4185 ``` **Depth data (`*.depth`)**: -Compressed stream of depth frames from Structure.io sensor. Please refer to the [Converter](../Converter) code for parsing. +Compressed stream of depth frames from Structure.io sensor. Please refer to the [depth2pgm](depth2pgm) code for an example of how to parse the data. **Color data (`*.h264`)**: An H.264 encoded stream of color frames from the iPad camera. Can be converted to sequences of images using ffmpeg through commands such as: `ffmpeg -i id.h264 %6d.color.png`. @@ -51,24 +51,23 @@ Stream of iPad camera settings containing exposure information. TODO: Format de **IMU data (`*.imu`)**: IMU data is a raw binary format consisting of: ``` -[8-byte Start time since 1970 in MS represented in double precision IEEE 754 little-endian] ---- Repeats 53 times per second --- -[8-byte capture time since 1970 in MS represented in double precision IEEE 754 little-endian] -[8-byte roll (Radians, double)] -[8-byte pitch (Radians, double)] -[8-byte yaw (Radians, double)] -[8-byte x rotation (Radians/s, double, RHR)] -[8-byte y rotation (Radians/s, double, RHR)] -[8-byte z rotation (Radians/s, double, RHR)] -[8-byte x gravity vector (G, double, device's reference frame)] -[8-byte y gravity vector (G, double, device's reference frame)] -[8-byte z gravity vector (G, double, device's reference frame)] +--- Repeats approx. 53 times per second --- +[8-byte capture device up-time sec. represented in double precision IEEE 754 little-endian] +[8-byte x rotation rate (Radians/s, double, RHR)] +[8-byte y rotation rate (Radians/s, double, RHR)] +[8-byte z rotation rate (Radians/s, double, RHR)] [8-byte x user-caused acceleration vector (G, double, device's reference frame)] [8-byte y user-caused acceleration vector (G, double, device's reference frame)] [8-byte z user-caused acceleration vector (G, double, device's reference frame)] [8-byte x magnetic field (microtesla, double)] [8-byte y magnetic field (microtesla, double)] [8-byte z magnetic field (microtesla, double)] +[8-byte roll (Radians, double)] +[8-byte pitch (Radians, double)] +[8-byte yaw (Radians, double)] +[8-byte x gravity vector (G, double, device's reference frame)] +[8-byte y gravity vector (G, double, device's reference frame)] +[8-byte z gravity vector (G, double, device's reference frame)] ----- REPEAT ------ ``` For more information about the IMU data refer to the iOS (CMDeviceMotion API)[https://developer.apple.com/library/prerelease/ios/documentation/CoreMotion/Reference/CMDeviceMotion_Class/index.html]. diff --git a/ScannerApp/Scanner.xcodeproj/project.pbxproj b/ScannerApp/Scanner.xcodeproj/project.pbxproj index c283a73..54d36f6 100644 --- a/ScannerApp/Scanner.xcodeproj/project.pbxproj +++ b/ScannerApp/Scanner.xcodeproj/project.pbxproj @@ -136,7 +136,6 @@ 435307C41872825B00B04481 /* Default-Landscape@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape@2x~ipad.png"; sourceTree = ""; }; 435307C51872825B00B04481 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 435307C61872825B00B04481 /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = ""; }; - 438C049918723EB10062E958 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPad.xib; sourceTree = ""; }; 43BB38C8199D2A51009D7AB2 /* calibration.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = calibration.png; sourceTree = ""; }; 6F03CB581862823000518C22 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = InfoPlist.strings; sourceTree = ""; }; 6F03CB5E1862832600518C22 /* EAGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAGLView.h; sourceTree = ""; }; @@ -151,6 +150,8 @@ 953997C11DAAE32500B43366 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 9591B5211E888E80005863DD /* Structure.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Structure.framework; path = Frameworks/Structure.framework; sourceTree = ""; }; 9591B5231E888EA6005863DD /* GPUImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GPUImage.xcodeproj; path = Frameworks/GPUImage/framework/GPUImage.xcodeproj; sourceTree = ""; }; + 95F123031F44E60700265C89 /* Config.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = ""; }; + A8426E672257C5A90024FEFE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ViewController_iPad.xib; sourceTree = ""; }; B60CC1BC1CFD5BB500EA51F4 /* toggleDepth.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = toggleDepth.png; sourceTree = ""; }; B60CC1BE1CFE2FCD00EA51F4 /* toggleAWB.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = toggleAWB.png; sourceTree = ""; }; B631B4521D6637F10064FB0D /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; @@ -259,6 +260,7 @@ 6F03CB5F1862832600518C22 /* EAGLView.mm */, 1F300614186E3B8F00405D34 /* Images.xcassets */, 433C3B9D186CBEA900552A10 /* Supporting Files */, + 95F123031F44E60700265C89 /* Config.h */, ); path = Scanner; sourceTree = SOURCE_ROOT; @@ -365,7 +367,7 @@ 2AFC8D6C176F966000F7F3B5 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0800; + LastUpgradeCheck = 1000; ORGANIZATIONNAME = Occipital; TargetAttributes = { 2AFC8D73176F966000F7F3B5 = { @@ -378,8 +380,10 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, global, + Base, ); mainGroup = 2AFC8D6B176F966000F7F3B5; productRefGroup = 2AFC8D75176F966000F7F3B5 /* Products */; @@ -489,7 +493,7 @@ 438C049818723EB10062E958 /* ViewController_iPad.xib */ = { isa = PBXVariantGroup; children = ( - 438C049918723EB10062E958 /* en */, + A8426E672257C5A90024FEFE /* Base */, ); name = ViewController_iPad.xib; sourceTree = ""; @@ -513,12 +517,20 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -537,7 +549,7 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, ); - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.Scanner.*\n"; PROVISIONING_PROFILE = ""; @@ -560,7 +572,7 @@ GCC_PREFIX_HEADER = "Scanner/Scanner-Prefix.pch"; HEADER_SEARCH_PATHS = "./Frameworks/GPUImage/framework/**"; INFOPLIST_FILE = "Scanner/Scanner-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_CFLAGS = "-DWRITE_LOCAL"; "OTHER_LDFLAGS[arch=*]" = "-ObjC"; @@ -578,12 +590,20 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -605,7 +625,7 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, ); - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.Scanner.*\n"; PROVISIONING_PROFILE = ""; @@ -627,7 +647,7 @@ GCC_PREFIX_HEADER = "Scanner/Scanner-Prefix.pch"; HEADER_SEARCH_PATHS = "./Frameworks/GPUImage/framework/**"; INFOPLIST_FILE = "Scanner/Scanner-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_CFLAGS = "-DWRITE_LOCAL"; "OTHER_LDFLAGS[arch=*]" = "-ObjC"; diff --git a/ScannerApp/Scanner/en.lproj/ViewController_iPad.xib b/ScannerApp/Scanner/Base.lproj/ViewController_iPad.xib similarity index 100% rename from ScannerApp/Scanner/en.lproj/ViewController_iPad.xib rename to ScannerApp/Scanner/Base.lproj/ViewController_iPad.xib diff --git a/ScannerApp/Scanner/Config.h b/ScannerApp/Scanner/Config.h new file mode 100644 index 0000000..fad652d --- /dev/null +++ b/ScannerApp/Scanner/Config.h @@ -0,0 +1,16 @@ +#ifndef Config_h +#define Config_h + + +// Upload server configuration +#define SERVER "http://dovahkiin.stanford.edu" +#define UPLOAD ":8000/upload" +#define VERIFY ":8000/verify" + +// Upload stream checksum chunking size in bytes +#define READ_CHUNK_SIZE 4096 + +#define DEBUG_MODE + + +#endif /* Config_h */ diff --git a/ScannerApp/Scanner/Scanner-Info.plist b/ScannerApp/Scanner/Scanner-Info.plist index 5eb2ac0..17ccb29 100644 --- a/ScannerApp/Scanner/Scanner-Info.plist +++ b/ScannerApp/Scanner/Scanner-Info.plist @@ -21,11 +21,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.4.2 + 1.4.3 CFBundleSignature ???? CFBundleVersion - 20170326203813 + 20190409143822 LSRequiresIPhoneOS NSAppTransportSecurity diff --git a/ScannerApp/Scanner/ViewController+Sensor.mm b/ScannerApp/Scanner/ViewController+Sensor.mm index bfe323a..f031c0a 100644 --- a/ScannerApp/Scanner/ViewController+Sensor.mm +++ b/ScannerApp/Scanner/ViewController+Sensor.mm @@ -712,6 +712,8 @@ - (void)stopScanningAndWrite [self cleanUpFileWriting]; g_frameCount = 0; g_encodedFrameCount = 0; + _colorTimestamps.clear(); + _depthTimestamps.clear(); } } @@ -829,7 +831,7 @@ - (void) verifyFiles NSString *absH264File = [NSString stringWithUTF8String:(curFilePrefix + ".h264").c_str()]; NSString *h264FileSize = [NSString stringWithFormat:@"%llu", [[[NSFileManager defaultManager] attributesOfItemAtPath:absH264File error:&error] fileSize]]; - if (!(h264FileSize > 0) || error) + if (!h264FileSize || error) { NSLog(@"H264 file %@, size %@, error: %@", absH264File, h264FileSize, error); remove = true; @@ -839,7 +841,7 @@ - (void) verifyFiles NSString *absDepthFile = [NSString stringWithUTF8String:(curFilePrefix + ".h264").c_str()]; NSString *depthFileSize = [NSString stringWithFormat:@"%llu", [[[NSFileManager defaultManager] attributesOfItemAtPath:absDepthFile error:&error] fileSize]]; - if (!(depthFileSize > 0) || error) + if (!depthFileSize || error) { NSLog(@"Depth file %@, size %@, error: %@", absDepthFile, depthFileSize, error); remove = true; @@ -849,7 +851,7 @@ - (void) verifyFiles NSString *absMetaFile = [NSString stringWithUTF8String:(curFilePrefix + ".h264").c_str()]; NSString *metaFileSize = [NSString stringWithFormat:@"%llu", [[[NSFileManager defaultManager] attributesOfItemAtPath:absMetaFile error:&error] fileSize]]; - if (!(metaFileSize > 0) || error) + if (!metaFileSize || error) { NSLog(@"Meta file %@, size %@, error: %@", absMetaFile, metaFileSize, error); remove = true; @@ -859,7 +861,7 @@ - (void) verifyFiles NSString *absImuFile = [NSString stringWithUTF8String:(curFilePrefix + ".h264").c_str()]; NSString *imuFileSize = [NSString stringWithFormat:@"%llu", [[[NSFileManager defaultManager] attributesOfItemAtPath:absImuFile error:&error] fileSize]]; - if (!(imuFileSize > 0) || error) + if (!imuFileSize || error) { NSLog(@"imu file %@, size %@, error: %@", absImuFile, imuFileSize, error); remove = true; diff --git a/ScannerApp/Scanner/ViewController.h b/ScannerApp/Scanner/ViewController.h index 7013d92..a393cac 100644 --- a/ScannerApp/Scanner/ViewController.h +++ b/ScannerApp/Scanner/ViewController.h @@ -14,9 +14,8 @@ #include #include -#define DEBUG_MODE +#import "Config.h" -#define SERVER "http://dovahkiin.stanford.edu" struct Options //TODO get rid of mesh view/tracking params { diff --git a/ScannerApp/Scanner/ViewController.mm b/ScannerApp/Scanner/ViewController.mm index b57afb0..328728c 100644 --- a/ScannerApp/Scanner/ViewController.mm +++ b/ScannerApp/Scanner/ViewController.mm @@ -22,10 +22,6 @@ #include #include -#define UPLOAD ":8000/upload" -#define VERIFY ":8000/verify" - -#define READ_CHUNK_SIZE 4096 NSUInteger g_uploadedCount = 0; NSUInteger g_fileCount = 0; diff --git a/ScannerApp/depth2pgm/.gitignore b/ScannerApp/depth2pgm/.gitignore new file mode 100644 index 0000000..56ce66b --- /dev/null +++ b/ScannerApp/depth2pgm/.gitignore @@ -0,0 +1,2 @@ +depth2pgm +*.o diff --git a/ScannerApp/depth2pgm/Makefile b/ScannerApp/depth2pgm/Makefile new file mode 100644 index 0000000..7ed60f4 --- /dev/null +++ b/ScannerApp/depth2pgm/Makefile @@ -0,0 +1,8 @@ +CXX = g++ +FLAGS=-std=c++11 + +main: + $(CXX) $(FLAGS) -o depth2pgm depth2pgm.cpp + +clean: + rm -f *~ *.o depth2pgm diff --git a/ScannerApp/depth2pgm/README.md b/ScannerApp/depth2pgm/README.md new file mode 100644 index 0000000..ad03e4e --- /dev/null +++ b/ScannerApp/depth2pgm/README.md @@ -0,0 +1,9 @@ +# depth2pgm + +This example code extracts depth frame data from a `*.depth` file produced by the ScannerApp. + +Code compiles by running `make`. + +Usage: `depth2pgm input.depth output_basename numDepthFramesToExtract` + +Output depth frames are saved in binary PGM format encoding per-pixel depth in mm. diff --git a/ScannerApp/depth2pgm/depth2pgm.cpp b/ScannerApp/depth2pgm/depth2pgm.cpp new file mode 100755 index 0000000..d4765a8 --- /dev/null +++ b/ScannerApp/depth2pgm/depth2pgm.cpp @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include + +#include "uplinksimple_image-codecs.h" +#include "uplinksimple_shift2depth.h" + +void saveAsPGM(const std::string& outFile, unsigned int width, unsigned int height, unsigned short* data, bool binary = true) { + if (binary) { + std::ofstream of(outFile, std::ios::binary); + std::stringstream ss; + ss << "P5\n"; + ss << "# data values are 16-bit each" << "\n"; + ss << width << " " << height << "\n"; + ss << std::numeric_limits::max() << "\n"; + of << ss.str(); + unsigned char* data_c = (unsigned char*)data; + for (unsigned int i = 0; i < width*height; i++) { + std::swap(data_c[2 * i + 0], data_c[2 * i + 1]); + } + of.write((const char*)data, width*height*sizeof(unsigned short)); + } else { + std::stringstream ss; + ss << "P2\n"; + ss << width << " " << height << "\n"; + ss << std::numeric_limits::max() << "\n"; + for (unsigned int y = 0; y < height; y++) { + for (unsigned int x = 0; x < width; x++) { + unsigned int idx = y*width + x; + ss << data[idx] << " "; + } + ss << "\n"; + } + std::ofstream of(outFile); + of << ss.str(); + } +} + +void process(const std::string& depthFile, const std::string& outBasename, + size_t numDepthFrames, size_t depthWidth = 640, size_t depthHeight = 480) { + std::ifstream inDepth(depthFile, std::ios::binary); + int frame = 0; + + while (frame < numDepthFrames) { + assert(inDepth.good()); + + // read depth frame + uint32_t byteSize; + inDepth.read((char*)&byteSize, sizeof(uint32_t)); + char* depthCompressed = new char[byteSize]; + inDepth.read((char*)depthCompressed, byteSize); + + // decode and convert from shift to depth + unsigned short* depth = (unsigned short*) std::malloc(depthWidth*depthHeight * 2); + uplinksimple::decode((unsigned char*)depthCompressed, byteSize, depthWidth*depthHeight, depth); + uplinksimple::shift2depth(depth, depthWidth*depthHeight); + + //check for invalid values and set to 0 + for (int i = 0; i < depthWidth*depthHeight; i++) { + if (depth[i] >= uplinksimple::shift2depth(0xffff)) { + depth[i] = 0; + } + } + + // save to PGM + const std::string filename = outBasename + "_" + std::to_string(frame) + ".pgm"; + saveAsPGM(filename, depthWidth, depthHeight, depth); + + delete[] depthCompressed; + std::free(depth); + std::cout << "frame " << frame << ": read " << byteSize << " [bytes] " << std::endl; + frame++; + } + + // read timestamps + for (int i = 0; i < numDepthFrames; i++) { + double timeStampDouble; + inDepth.read((char*)&timeStampDouble, sizeof(double)); + uint64_t timeStamp = (uint64_t)(timeStampDouble*1000*1000); // seconds to microseconds + // TODO do something with timestamps + } +} + + +int main(int argc, char* argv[]) { + if (argc >= 3) { + std::string depthFile(argv[1]); + std::string outBasename(argv[2]); + int numDepthFrames = 1; + if (argc >= 4) { + numDepthFrames = std::atoi(argv[3]); + } + process(depthFile, outBasename, numDepthFrames); + } else { + std::cerr << "Usage: depth2pgm path/to/file.depth pgm_seq_basename [numDepthFrames]" << std::endl; + } + return 0; +} diff --git a/ScannerApp/depth2pgm/uplinksimple_image-codecs.h b/ScannerApp/depth2pgm/uplinksimple_image-codecs.h new file mode 100755 index 0000000..b05e77d --- /dev/null +++ b/ScannerApp/depth2pgm/uplinksimple_image-codecs.h @@ -0,0 +1,398 @@ +// +// image/image-codecs.h +// Uplink +// +// Copyright (c) 2013 Occipital, Inc. All rights reserved. +// + +# pragma once + +#include "memory.h" + +#include +# include +# include +# include +# include +# include +# include + +# define BITSTREAM_SUCCESS 1 +# define BITSTREAM_FAILURE 0 + +namespace uplinksimple { + + //------------------------------------------------------------------------------ + + typedef struct s_bitstream { + uint8_t *buf; /* head of bitstream */ + uint8_t *pos; /* current byte in bitstream */ + unsigned int remain; /* bits remaining */ + unsigned int len; /* length of bitstream in bytes */ + uint8_t cur_bits; + } bitstream_t; + + int bs_init(bitstream_t *bp); + int bs_destroy(bitstream_t **ppb); + int bs_attach(bitstream_t *b, uint8_t *buf, int blen); + uint8_t bs_get(bitstream_t * b, uint8_t nbits); + int bs_bytes_used(bitstream_t *b); + + static inline int + bs_put(bitstream_t * b, + uint8_t bits, + uint8_t nbits) + { + assert(nbits != 0 && nbits <= 8); + + if (nbits > b->remain) { + unsigned int over = nbits - b->remain; + *(b->pos++) = b->cur_bits | (bits >> over); + b->remain = 8 - over; + b->cur_bits = bits << b->remain; + } + else { + b->cur_bits |= bits << (b->remain - nbits); + b->remain -= nbits; + + // we've exhausted the byte. move to the next byte. + if (b->remain == 0) { + *(b->pos++) = b->cur_bits; + b->remain = 8; + b->cur_bits = 0; + } + } + + assert((unsigned int)(b->pos - b->buf) <= b->len); + return BITSTREAM_SUCCESS; + } + + static inline int + bs_flush(bitstream_t * b) + { + *(b->pos) = b->cur_bits; + return BITSTREAM_SUCCESS; + } + + //------------------------------------------------------------------------------ + +} + + +namespace uplinksimple { + + //------------------------------------------------------------------------------ + + inline int + bs_init(bitstream_t *bp) + { + if (bp) { + memset(bp, 0, sizeof(bitstream_t)); + return BITSTREAM_SUCCESS; + } + return BITSTREAM_FAILURE; + } + + inline int + bs_destroy(bitstream_t * b) + { + free(b); + return BITSTREAM_SUCCESS; + } + + inline int + bs_attach(bitstream_t *b, + uint8_t *buf, + int blen) + { + b->buf = b->pos = buf; + b->remain = 8; + b->len = blen; + return BITSTREAM_SUCCESS; + } + + inline int + bs_bytes_used(bitstream_t *b) + { + unsigned int used = (unsigned int)(b->pos - b->buf); + return b->remain != 8 ? used + 1 : used; + } + + inline uint8_t + bs_get(bitstream_t * b, + uint8_t nbits) + { + uint8_t out; + + if (b->remain == 0) { + b->pos++; + b->remain = 8; + } + + if (nbits > b->remain) { + /* Get high bits */ + out = *b->pos; + out <<= (8 - b->remain); + out >>= (8 - nbits); + b->pos++; + b->remain += 8 - nbits; + out |= (*b->pos) >> b->remain; + } + else { + out = *b->pos; + out <<= (8 - b->remain); + out >>= (8 - nbits); + b->remain -= nbits; + } + + assert((unsigned int)(b->pos - b->buf) <= b->len); + return out; + } + + //------------------------------------------------------------------------------ + +} + + + +namespace uplinksimple { + +//------------------------------------------------------------------------------ + +// ----------------------------------------------- +// OCCIPITAL DEPTH FRAME COMPRESSION ALGORITHM 0.1 +// ----------------------------------------------- + +// TYPICAL COMPRESSION RATIO ON 640x480 test image: 0.17 + +// DECODE: +// Step 0. Last value is initialized to 0. Frame size is known in advance. +// Step 1. Proceed by decoding following bitstream until all pixels are decoded. + +// 00 - Next value is same as last value. +// 11 - Next value is last value + 1. +// 10 - Next value is last value - 1. +// 010 - bbbbb - Next N values are same as last value. (N encoded w/ 5 bits) +// 0111 - bbbbbbbbbbb - Next value is X. (X encoded w/ 11 bits) +// 01101 - Next value is last value + 2. +// 01100 - Next value is last value - 2. + + inline uint16_t * decode(const uint8_t * bitstream_data, unsigned int bitstream_length_bytes, int numelements, uint16_t* output) +{ + + uint16_t lastVal = 0; + uint16_t curVal = 0; + + bitstream_t bs; + bs_init(&bs); + bs_attach(&bs, const_cast(bitstream_data), bitstream_length_bytes); + + uint16_t * depthimage = 0 == output + ? (uint16_t*)malloc(numelements * sizeof(uint16_t)) + : output + ; + + uint16_t * depth_ptr = depthimage; + + while(numelements > 0) + { + uint8_t bit0 = bs_get(&bs, 1); + uint8_t bit1 = bs_get(&bs, 1); + + if(bit0 == 0 && bit1 == 0) // 00 + { + curVal = lastVal; + + *(depth_ptr++) = curVal; lastVal = curVal; + + numelements-=1; + } + else if(bit0 == 1) // 1 prefix + { + + if(bit1 == 0) { + curVal = lastVal - 1; + } + else { + curVal = lastVal + 1; + } + + *(depth_ptr++) = curVal; lastVal = curVal; + + numelements-=1; + + } + else // must be 01 prefix + { + uint8_t bit2 = bs_get(&bs, 1); + + if(bit2 == 0) // 010 --> multiple zeros! + { + uint16_t numZeros = bs_get(&bs, 5); + + numZeros += 5; // We never encode less than 5. + + for(int i = 0; i < numZeros; i++) { + *(depth_ptr++) = curVal; + } + + numelements-=numZeros; + } + else + { + uint8_t bit3 = bs_get(&bs, 1); + + if(bit3 == 0) // 0110 -- DELTA! + { + uint8_t delta_bit = bs_get(&bs, 1); + + if(delta_bit == 0) { + curVal = lastVal - 2; + } + else { + curVal = lastVal + 2; + } + + *(depth_ptr++) = curVal; lastVal = curVal; + + numelements-=1; + + } + else // 0111 -- RESET! + { + uint16_t value = (bs_get(&bs, 3) << 8) | bs_get(&bs, 8); // 11 bits total. + + curVal = value; + + *(depth_ptr++) = curVal; lastVal = curVal; + numelements-=1; + } + + } + + } + + } + + return depthimage; + +} + +//------------------------------------------------------------------------------ + +inline uint32_t encode(const uint16_t * data_in, int numelements, + uint8_t* out_buffer, uint32_t out_buffer_size) +{ + int numZeros = 0; + int lastVal = 0; + + bitstream_t bs; + bs_init(&bs); + bs_attach(&bs, out_buffer, out_buffer_size); + + // Loop over pixels. + while (numelements > 0) { + + int curVal = *(data_in++); + int delta = curVal - lastVal; + + if(delta == 0) + { + numZeros++; + } + else + { + if(numZeros > 0) + { + // MUST BURN ZEROS! + while( numZeros > 0 ) + { + if(numZeros <= 4) + { + // Ternary is fastest way of deciding how many zeros to encode (2 * numZeros) + bs_put(&bs, 0x0000, numZeros == 1 ? 2 : numZeros == 2 ? 4 : numZeros == 3 ? 6 : 8); + numZeros = 0; + } + else + { + bs_put(&bs, 0x2, 3); // 010bbbbb + + // We never encode less than 5 because in that case + // we'll just use multiple 2-bit single zeros. + unsigned int numberToEncode = numZeros - 5; + + // We're only using 5 bits, so we can't encode greater than 31. + if(numberToEncode > 31) numberToEncode = 31; + + bs_put(&bs, numberToEncode, 5); // 0b 010 + + numZeros -= (numberToEncode+5); + } + } + + // numZeros is now zero. + } + + if(delta == 1 || delta == -1) + { + bs_put(&bs, delta == 1 ? 0x3 : 0x2, 2); // 0b 11 + } + else if (delta >= -2 && delta <= 2) + { + bs_put(&bs, delta == 2 ? 0xD : 0xC, 5); + } + else // Reset == 1111 bbbbbbbbbbb + { + bs_put(&bs, 0x7, 4); // 0111 + bs_put(&bs, curVal >> 8, 3); + bs_put(&bs, curVal , 8); + } + + } // end else block of if (delta == 0) + + lastVal = curVal; + + numelements--; + } + + // FINISH Up -- repeat zeros check. + + if(numZeros > 0) + { + // MUST BURN ZEROS! + while(numZeros > 0) + { + if(numZeros <= 4) + { + // Ternary is fastest way of deciding how many zeros to encode (2 * numZeros) + bs_put(&bs, 0x0000, numZeros == 1 ? 2 : numZeros == 2 ? 4 : numZeros == 3 ? 6 : 8); + numZeros = 0; + } + else + { + bs_put(&bs, 0x2, 3); // 010bbbbb + + // We never encode less than 5 because in that case + // we'll just use multiple 2-bit single zeros. + unsigned int numberToEncode = numZeros - 5; + + // We're only using 5 bits, so we can't encode greater than 31. + if(numberToEncode > 31) numberToEncode = 31; + + bs_put(&bs, numberToEncode, 5); // 0b 010 + + numZeros -= (numberToEncode+5); + } + } + } + + // numZeros is now zero. + + // END FINISH UP + + + bs_flush(&bs); + return bs_bytes_used(&bs); +} + +} // uplink namespace diff --git a/ScannerApp/depth2pgm/uplinksimple_shift2depth.h b/ScannerApp/depth2pgm/uplinksimple_shift2depth.h new file mode 100755 index 0000000..315e610 --- /dev/null +++ b/ScannerApp/depth2pgm/uplinksimple_shift2depth.h @@ -0,0 +1,92 @@ +# pragma once + +# define sizeof_array(Array) sizeof(Array) / sizeof(Array[0]) + +// FIXME: Dynamically compute the table with the camera info data, instead of using this fixed one. + +namespace uplinksimple { + + inline uint16_t + shift2depth(uint16_t shift) + { + static const uint16_t table[] = { 0, + 264, 264, 265, 265, 265, 265, 265, 266, 266, 266, 266, 267, 267, 267, 267, 268, 268, 268, + 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272, 273, + 273, 273, 273, 274, 274, 274, 274, 275, 275, 275, 275, 276, 276, 276, 276, 277, 277, 277, + 277, 278, 278, 278, 278, 279, 279, 279, 279, 280, 280, 280, 280, 281, 281, 281, 281, 282, + 282, 282, 283, 283, 283, 283, 284, 284, 284, 284, 285, 285, 285, 286, 286, 286, 286, 287, + 287, 287, 287, 288, 288, 288, 289, 289, 289, 289, 290, 290, 290, 291, 291, 291, 291, 292, + 292, 292, 293, 293, 293, 293, 294, 294, 294, 295, 295, 295, 295, 296, 296, 296, 297, 297, + 297, 297, 298, 298, 298, 299, 299, 299, 300, 300, 300, 300, 301, 301, 301, 302, 302, 302, + 303, 303, 303, 304, 304, 304, 304, 305, 305, 305, 306, 306, 306, 307, 307, 307, 308, 308, + 308, 309, 309, 309, 309, 310, 310, 310, 311, 311, 311, 312, 312, 312, 313, 313, 313, 314, + 314, 314, 315, 315, 315, 316, 316, 316, 317, 317, 317, 318, 318, 318, 319, 319, 319, 320, + 320, 320, 321, 321, 321, 322, 322, 322, 323, 323, 324, 324, 324, 325, 325, 325, 326, 326, + 326, 327, 327, 327, 328, 328, 329, 329, 329, 330, 330, 330, 331, 331, 331, 332, 332, 333, + 333, 333, 334, 334, 334, 335, 335, 336, 336, 336, 337, 337, 337, 338, 338, 339, 339, 339, + 340, 340, 340, 341, 341, 342, 342, 342, 343, 343, 344, 344, 344, 345, 345, 346, 346, 346, + 347, 347, 348, 348, 348, 349, 349, 350, 350, 350, 351, 351, 352, 352, 353, 353, 353, 354, + 354, 355, 355, 355, 356, 356, 357, 357, 358, 358, 358, 359, 359, 360, 360, 361, 361, 361, + 362, 362, 363, 363, 364, 364, 365, 365, 365, 366, 366, 367, 367, 368, 368, 369, 369, 369, + 370, 370, 371, 371, 372, 372, 373, 373, 374, 374, 375, 375, 376, 376, 376, 377, 377, 378, + 378, 379, 379, 380, 380, 381, 381, 382, 382, 383, 383, 384, 384, 385, 385, 386, 386, 387, + 387, 388, 388, 389, 389, 390, 390, 391, 391, 392, 392, 393, 393, 394, 394, 395, 395, 396, + 396, 397, 397, 398, 399, 399, 400, 400, 401, 401, 402, 402, 403, 403, 404, 404, 405, 406, + 406, 407, 407, 408, 408, 409, 409, 410, 411, 411, 412, 412, 413, 413, 414, 415, 415, 416, + 416, 417, 417, 418, 419, 419, 420, 420, 421, 422, 422, 423, 423, 424, 425, 425, 426, 426, + 427, 428, 428, 429, 429, 430, 431, 431, 432, 433, 433, 434, 434, 435, 436, 436, 437, 438, + 438, 439, 439, 440, 441, 441, 442, 443, 443, 444, 445, 445, 446, 447, 447, 448, 449, 449, + 450, 451, 451, 452, 453, 453, 454, 455, 456, 456, 457, 458, 458, 459, 460, 460, 461, 462, + 463, 463, 464, 465, 465, 466, 467, 468, 468, 469, 470, 471, 471, 472, 473, 474, 474, 475, + 476, 477, 477, 478, 479, 480, 480, 481, 482, 483, 484, 484, 485, 486, 487, 487, 488, 489, + 490, 491, 491, 492, 493, 494, 495, 496, 496, 497, 498, 499, 500, 500, 501, 502, 503, 504, + 505, 506, 506, 507, 508, 509, 510, 511, 512, 512, 513, 514, 515, 516, 517, 518, 519, 520, + 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 533, 534, 535, 536, + 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, + 555, 556, 557, 558, 559, 560, 561, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, + 574, 575, 577, 578, 579, 580, 581, 582, 583, 584, 586, 587, 588, 589, 590, 591, 593, 594, + 595, 596, 597, 599, 600, 601, 602, 603, 605, 606, 607, 608, 609, 611, 612, 613, 614, 616, + 617, 618, 620, 621, 622, 623, 625, 626, 627, 629, 630, 631, 633, 634, 635, 637, 638, 639, + 641, 642, 644, 645, 646, 648, 649, 650, 652, 653, 655, 656, 658, 659, 661, 662, 663, 665, + 666, 668, 669, 671, 672, 674, 675, 677, 678, 680, 682, 683, 685, 686, 688, 689, 691, 693, + 694, 696, 697, 699, 701, 702, 704, 706, 707, 709, 711, 712, 714, 716, 717, 719, 721, 723, + 724, 726, 728, 730, 732, 733, 735, 737, 739, 741, 742, 744, 746, 748, 750, 752, 754, 755, + 757, 759, 761, 763, 765, 767, 769, 771, 773, 775, 777, 779, 781, 783, 785, 787, 789, 791, + 794, 796, 798, 800, 802, 804, 806, 808, 811, 813, 815, 817, 820, 822, 824, 826, 829, 831, + 833, 836, 838, 840, 843, 845, 847, 850, 852, 855, 857, 860, 862, 864, 867, 869, 872, 875, + 877, 880, 882, 885, 888, 890, 893, 895, 898, 901, 904, 906, 909, 912, 915, 917, 920, 923, + 926, 929, 932, 935, 937, 940, 943, 946, 949, 952, 955, 958, 962, 965, 968, 971, 974, 977, + 980, 984, 987, 990, 993, 997, 1000, 1003, 1007, 1010, 1014, 1017, 1020, 1024, 1027, 1031, + 1035, 1038, 1042, 1045, 1049, 1053, 1056, 1060, 1064, 1068, 1072, 1075, 1079, 1083, 1087, + 1091, 1095, 1099, 1103, 1107, 1111, 1115, 1120, 1124, 1128, 1132, 1137, 1141, 1145, 1150, + 1154, 1159, 1163, 1168, 1172, 1177, 1181, 1186, 1191, 1196, 1200, 1205, 1210, 1215, 1220, + 1225, 1230, 1235, 1240, 1245, 1250, 1256, 1261, 1266, 1272, 1277, 1282, 1288, 1294, 1299, + 1305, 1310, 1316, 1322, 1328, 1334, 1340, 1346, 1352, 1358, 1364, 1370, 1377, 1383, 1389, + 1396, 1402, 1409, 1416, 1422, 1429, 1436, 1443, 1450, 1457, 1464, 1471, 1479, 1486, 1493, + 1501, 1508, 1516, 1524, 1531, 1539, 1547, 1555, 1563, 1572, 1580, 1588, 1597, 1605, 1614, + 1623, 1631, 1640, 1649, 1658, 1668, 1677, 1686, 1696, 1706, 1715, 1725, 1735, 1745, 1756, + 1766, 1776, 1787, 1798, 1809, 1820, 1831, 1842, 1853, 1865, 1876, 1888, 1900, 1912, 1925, + 1937, 1950, 1962, 1975, 1988, 2002, 2015, 2029, 2043, 2057, 2071, 2085, 2100, 2115, 2130, + 2145, 2160, 2176, 2192, 2208, 2224, 2241, 2258, 2275, 2292, 2310, 2328, 2346, 2365, 2384, + 2403, 2422, 2442, 2462, 2482, 2503, 2524, 2545, 2567, 2589, 2612, 2635, 2658, 2682, 2706, + 2731, 2756, 2782, 2808, 2834, 2861, 2889, 2917, 2945, 2975, 3005, 3035, 3066, 3098, 3130, + 3163, 3197, 3231, 3266, 3302, 3339, 3377, 3415, 3454, 3495, 3536, 3578, 3621, 3665, 3711, + 3757, 3805, 3854, 3904, 3956, 4008, 4063, 4118, 4176, 4235, 4295, 4358, 4422, 4488, 4556, + 4627, 4699, 4774, 4851, 4931, 5013, 5099, 5187, 5278, 5373, 5471, 5572, 5678, 5787, 5901, + 6020, 6143, 6271, 6405, 6545, 6691, 6844, 7003, 7171, 7346, 7531, 7725, 7929, 8144, 8372, + 8612, 8866, 9137, 9424, 9729 + }; + + return shift < sizeof_array(table) ? table[shift] : table[sizeof_array(table) - 1]; + } + + inline void + shift2depth(uint16_t* buffer, size_t size) + { + for (size_t n = 0; n < size; ++n) + buffer[n] = shift2depth(buffer[n]); + } + + //------------------------------------------------------------------------------ + +} \ No newline at end of file diff --git a/Segmentator/.gitignore b/Segmentator/.gitignore new file mode 100644 index 0000000..6d22b0e --- /dev/null +++ b/Segmentator/.gitignore @@ -0,0 +1,2 @@ +segmentator +*.o diff --git a/Segmentator/CMakeLists.txt b/Segmentator/CMakeLists.txt new file mode 100644 index 0000000..8350dee --- /dev/null +++ b/Segmentator/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) +set(CMAKE_CXX_STANDARD 11) +project(Segmentator) +set(SOURCES segmentator.cpp tinyply.cpp) +add_executable(segmentator ${SOURCES}) diff --git a/Segmentator/Makefile b/Segmentator/Makefile new file mode 100644 index 0000000..26cb877 --- /dev/null +++ b/Segmentator/Makefile @@ -0,0 +1,8 @@ +CXX = g++ +FLAGS=-std=c++11 + +main: + $(CXX) $(FLAGS) -o segmentator segmentator.cpp tinyply.cpp + +clean: + rm -f *~ *.o segmentator diff --git a/Segmentator/README.md b/Segmentator/README.md new file mode 100644 index 0000000..77a2dab --- /dev/null +++ b/Segmentator/README.md @@ -0,0 +1,12 @@ +Mesh Segmentation +================= + +Mesh segmentation code using Felzenswalb and Huttenlocher's [*Graph Based Image Segmentation*](https://cs.brown.edu/~pff/segment/index.html) algorithm on computed mesh normals. + +Build by running `make` (or create makefiles for your system using `cmake`). This will create a `segmentator` binary that can be run by: + +`./segmentator input.ply [kThresh=0.01] [segMinVerts=20]` + +The first argument is a path to an input mesh in PLY format. +The second (optional) argument is the segmentation cluster threshold parameter (larger values lead to larger segments). +The third (optional) argument is the minimum number of vertices per-segment, enforced by merging small clusters into larger segments. \ No newline at end of file diff --git a/Segmentator/segmentator.cpp b/Segmentator/segmentator.cpp new file mode 100644 index 0000000..233776a --- /dev/null +++ b/Segmentator/segmentator.cpp @@ -0,0 +1,289 @@ +#include +#include +#include +#include +#include +#include + +#define TINYOBJLOADER_IMPLEMENTATION +#include "tiny_obj_loader.h" +#include "tinyply.h" + +using std::vector; +using std::string; + +// felzenswalb segmentation (https://cs.brown.edu/~pff/segment/index.html) + +// disjoint-set forests using union-by-rank and path compression (sort of). +typedef struct { + int rank; + int p; + int size; +} uni_elt; + +class universe { + public: + universe(int elements) { + elts = new uni_elt[elements]; + num = elements; + for (int i = 0; i < elements; i++) { + elts[i].rank = 0; + elts[i].size = 1; + elts[i].p = i; + } + } + ~universe() { delete [] elts; } + int find(int x) { + int y = x; + while (y != elts[y].p) + y = elts[y].p; + elts[x].p = y; + return y; + } + void join(int x, int y) { + if (elts[x].rank > elts[y].rank) { + elts[y].p = x; + elts[x].size += elts[y].size; + } else { + elts[x].p = y; + elts[y].size += elts[x].size; + if (elts[x].rank == elts[y].rank) + elts[y].rank++; + } + num--; + } + int size(int x) const { return elts[x].size; } + int num_sets() const { return num; } + private: + uni_elt *elts; + int num; +}; + +typedef struct { + float w; + int a, b; +} edge; + +bool operator<(const edge &a, const edge &b) { + return a.w < b.w; +} + +universe *segment_graph(int num_vertices, int num_edges, edge *edges, float c) { + std::sort(edges, edges + num_edges); // sort edges by weight + universe *u = new universe(num_vertices); // make a disjoint-set forest + float *threshold = new float[num_vertices]; + for (int i = 0; i < num_vertices; i++) { threshold[i] = c; } + // for each edge, in non-decreasing weight order + for (int i = 0; i < num_edges; i++) { + edge *pedge = &edges[i]; + // components conected by this edge + int a = u->find(pedge->a); + int b = u->find(pedge->b); + if (a != b) { + if ((pedge->w <= threshold[a]) && (pedge->w <= threshold[b])) { + u->join(a, b); + a = u->find(a); + threshold[a] = pedge->w + (c / u->size(a)); + } + } + } + delete [] threshold; + return u; +} + +// simple vec3f class +class vec3f { + public: + float x, y, z; + vec3f() { x = 0; y = 0; z = 0; } + vec3f(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } + vec3f operator+(const vec3f& o) { + return vec3f{x+o.x, y+o.y, z+o.z}; + } + vec3f operator-(const vec3f& o) { + return vec3f{x-o.x, y-o.y, z-o.z}; + } +}; +vec3f cross(const vec3f& u, const vec3f& v) { + vec3f c = {u.y*v.z - u.z*v.y, u.z*v.x - u.x*v.z, u.x*v.y - u.y*v.x}; + float n = sqrtf(c.x*c.x + c.y*c.y + c.z*c.z); + c.x /= n; c.y /= n; c.z /= n; + return c; +} +vec3f lerp(const vec3f& a, const vec3f& b, const float v) { + const float u = 1.0f-v; + return vec3f(v*b.x + u*a.x, v*b.y + u*a.y, v*b.z + u*a.z); +} + +inline bool ends_with(const std::string & value, const std::string& ending) { + if (ending.size() > value.size()) { return false; } + return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); +} + +vector segment(const string& meshFile, const float kthr, const int segMinVerts) { + //std::cout << "Loading mesh " << meshFile << std::endl; + vector verts; + vector faces; + size_t vertexCount = 0; + size_t faceCount = 0; + + if (ends_with(meshFile, ".ply") || ends_with(meshFile, ".PLY")) { + // Load the geometry from .ply + std::ifstream ss(meshFile, std::ios::binary); + tinyply::PlyFile file(ss); + vertexCount = file.request_properties_from_element("vertex", { "x", "y", "z" }, verts); + // Try getting vertex_indices or vertex_index + faceCount = file.request_properties_from_element("face", { "vertex_indices" }, faces, 3); + if (faceCount == 0) { + faceCount = file.request_properties_from_element("face", { "vertex_index" }, faces, 3); + } + file.read(ss); + } else if (ends_with(meshFile, ".obj") || ends_with(meshFile, ".OBJ")) { + // Load the geometry from .obj + tinyobj::attrib_t attrib; + vector shapes; + vector materials; + string err; + bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, meshFile.c_str(), NULL, false); + if (!err.empty()) { // `err` may contain warning message. + std::cerr << err << std::endl; + } + if (!ret) { + exit(1); + } + if (shapes.size() > 1) { + std::cerr << "Warning: only single mesh OBJ supported, segmenting first mesh" << std::endl; + } + + // Keep with original vertices (we don't want them duplicated) + vertexCount = attrib.vertices.size() / 3; + for (size_t v = 0; v < attrib.vertices.size(); v++) { + verts.push_back(attrib.vertices[v]); + } + + const auto& mesh = shapes[0].mesh; + faceCount = mesh.num_face_vertices.size(); + for (size_t f = 0; f < faceCount; f++) { + for (size_t v = 0; v < 3; v++) { + const size_t idx = mesh.indices[3 * f + v].vertex_index; + faces.push_back(idx); + } + } + } + + printf("Read mesh with vertexCount %lu %lu, faceCount %lu %lu\n", + vertexCount, verts.size(), faceCount, faces.size()); + + // create points, normals, edges, counts vectors + vector points(vertexCount); + vector normals(vertexCount); + vector counts(verts.size(), 0); + const size_t edgesCount = faceCount*3; + edge* edges = new edge[edgesCount]; + + // Compute face normals and smooth into vertex normals + for (int i = 0; i < faceCount; i++) { + const int fbase = 3*i; + const uint32_t i1 = faces[fbase]; + const uint32_t i2 = faces[fbase+1]; + const uint32_t i3 = faces[fbase+2]; + int vbase = 3*i1; + vec3f p1(verts[vbase], verts[vbase+1], verts[vbase+2]); + vbase = 3*i2; + vec3f p2(verts[vbase], verts[vbase+1], verts[vbase+2]); + vbase = 3*i3; + vec3f p3(verts[vbase], verts[vbase+1], verts[vbase+2]); + points[i1] = p1; points[i2] = p2; points[i3] = p3; + const int ebase = 3*i; + edges[ebase ].a = i1; edges[ebase ].b = i2; + edges[ebase+1].a = i1; edges[ebase+1].b = i3; + edges[ebase+2].a = i3; edges[ebase+2].b = i2; + + // smoothly blend face normals into vertex normals + vec3f normal = cross(p2 - p1, p3 - p1); + normals[i1] = lerp(normals[i1], normal, 1.0f / (counts[i1] + 1.0f)); + normals[i2] = lerp(normals[i2], normal, 1.0f / (counts[i2] + 1.0f)); + normals[i3] = lerp(normals[i3], normal, 1.0f / (counts[i3] + 1.0f)); + counts[i1]++; counts[i2]++; counts[i3]++; + } + + //std::cout << "Constructing edge graph based on mesh connectivity..." << std::endl; + for (int i = 0; i < edgesCount; i++) { + int a = edges[i].a; + int b = edges[i].b; + + vec3f& n1 = normals[a]; + vec3f& n2 = normals[b]; + vec3f& p1 = points[a]; + vec3f& p2 = points[b]; + + float dx = p2.x - p1.x; + float dy = p2.y - p1.y; + float dz = p2.z - p1.z; + float dd = sqrtf(dx * dx + dy * dy + dz * dz); dx /= dd; dy /= dd; dz /= dd; + float dot = n1.x * n2.x + n1.y * n2.y + n1.z * n2.z; + float dot2 = n2.x * dx + n2.y * dy + n2.z * dz; + float ww = 1.0f - dot; + if (dot2 > 0) { ww = ww * ww; } // make it much less of a problem if convex regions have normal difference + edges[i].w = ww; + } + //std::cout << "Constructed graph" << std::endl; + + // Segment! + universe* u = segment_graph(vertexCount, edgesCount, edges, kthr); + //std::cout << "Segmented" << std::endl; + + // Joining small segments + for (int j = 0; j < edgesCount; j++) { + int a = u->find(edges[j].a); + int b = u->find(edges[j].b); + if ((a != b) && ((u->size(a) < segMinVerts) || (u->size(b) < segMinVerts))) { + u->join(a, b); + } + } + + // Return segment indices as vector + vector outComps(vertexCount); + for (int q = 0; q < vertexCount; q++) { + outComps[q] = u->find(q); + } + return outComps; +} + +void writeToJSON(const string& filename, const string& scanId, + const float kthr, const int segMinVerts, const vector& segIndices) { + std::ofstream ofs(filename); + ofs << "{"; + ofs << "\"params\":{\"kThresh\":" << kthr << ",\"segMinVerts\":" << segMinVerts << "},"; + ofs << "\"sceneId\":\"" << scanId << "\","; + ofs << "\"segIndices\":["; + for (int i = 0; i < segIndices.size(); i++) { + if (i > 0) { ofs << ","; } + ofs << segIndices[i]; + } + ofs << "]}"; + ofs.close(); +} + +int main(int argc, const char** argv) { + if (argc < 2) { + printf("Usage: ./segmentator input.ply [kThresh] [segMinVerts] (defaults: kThresh=0.01 segMinVerts=20)\n"); + exit(-1); + } else { + const string plyFile = argv[1]; + const float kthr = argc > 2 ? (float)atof(argv[2]) : 0.01f; + const int segMinVerts = argc > 3 ? atoi(argv[3]) : 20; + printf("Segmenting %s with kThresh=%f, segMinVerts=%d ...\n", plyFile.c_str(), kthr, segMinVerts); + const vector comps = segment(plyFile, kthr, segMinVerts); + std::unordered_set comp_indices; + for (int i = 0; i < comps.size(); i++) { + comp_indices.insert(comps[i]); + } + const string baseName = plyFile.substr(0, plyFile.find_last_of(".")); + const int lastslash = plyFile.find_last_of("/"); + const string scanId = lastslash > 0 ? baseName.substr(lastslash) : baseName; + string segFile = baseName + "." + std::to_string(kthr) + ".segs.json"; + writeToJSON(segFile, scanId, kthr, segMinVerts, comps); + printf("Segmentation written to %s with %lu segments\n", segFile.c_str(), comp_indices.size()); + } +} diff --git a/Segmentator/tiny_obj_loader.h b/Segmentator/tiny_obj_loader.h new file mode 100644 index 0000000..f72493f --- /dev/null +++ b/Segmentator/tiny_obj_loader.h @@ -0,0 +1,2253 @@ +/* +The MIT License (MIT) + +Copyright (c) 2012-2017 Syoyo Fujita and many contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// +// version 1.1.0 : Support parsing vertex color(#144) +// version 1.0.8 : Fix parsing `g` tag just after `usemtl`(#138) +// version 1.0.7 : Support multiple tex options(#126) +// version 1.0.6 : Add TINYOBJLOADER_USE_DOUBLE option(#124) +// version 1.0.5 : Ignore `Tr` when `d` exists in MTL(#43) +// version 1.0.4 : Support multiple filenames for 'mtllib'(#112) +// version 1.0.3 : Support parsing texture options(#85) +// version 1.0.2 : Improve parsing speed by about a factor of 2 for large +// files(#105) +// version 1.0.1 : Fixes a shape is lost if obj ends with a 'usemtl'(#104) +// version 1.0.0 : Change data structure. Change license from BSD to MIT. +// + +// +// Use this in *one* .cc +// #define TINYOBJLOADER_IMPLEMENTATION +// #include "tiny_obj_loader.h" +// + +#ifndef TINY_OBJ_LOADER_H_ +#define TINY_OBJ_LOADER_H_ + +#include +#include +#include + +namespace tinyobj { + +#ifdef __clang__ +#pragma clang diagnostic push +#if __has_warning("-Wzero-as-null-pointer-constant") +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif +#endif + +// https://en.wikipedia.org/wiki/Wavefront_.obj_file says ... +// +// -blendu on | off # set horizontal texture blending +// (default on) +// -blendv on | off # set vertical texture blending +// (default on) +// -boost real_value # boost mip-map sharpness +// -mm base_value gain_value # modify texture map values (default +// 0 1) +// # base_value = brightness, +// gain_value = contrast +// -o u [v [w]] # Origin offset (default +// 0 0 0) +// -s u [v [w]] # Scale (default +// 1 1 1) +// -t u [v [w]] # Turbulence (default +// 0 0 0) +// -texres resolution # texture resolution to create +// -clamp on | off # only render texels in the clamped +// 0-1 range (default off) +// # When unclamped, textures are +// repeated across a surface, +// # when clamped, only texels which +// fall within the 0-1 +// # range are rendered. +// -bm mult_value # bump multiplier (for bump maps +// only) +// +// -imfchan r | g | b | m | l | z # specifies which channel of the file +// is used to +// # create a scalar or bump texture. +// r:red, g:green, +// # b:blue, m:matte, l:luminance, +// z:z-depth.. +// # (the default for bump is 'l' and +// for decal is 'm') +// bump -imfchan r bumpmap.tga # says to use the red channel of +// bumpmap.tga as the bumpmap +// +// For reflection maps... +// +// -type sphere # specifies a sphere for a "refl" +// reflection map +// -type cube_top | cube_bottom | # when using a cube map, the texture +// file for each +// cube_front | cube_back | # side of the cube is specified +// separately +// cube_left | cube_right + +#ifdef TINYOBJLOADER_USE_DOUBLE +//#pragma message "using double" +typedef double real_t; +#else +//#pragma message "using float" +typedef float real_t; +#endif + +typedef enum { + TEXTURE_TYPE_NONE, // default + TEXTURE_TYPE_SPHERE, + TEXTURE_TYPE_CUBE_TOP, + TEXTURE_TYPE_CUBE_BOTTOM, + TEXTURE_TYPE_CUBE_FRONT, + TEXTURE_TYPE_CUBE_BACK, + TEXTURE_TYPE_CUBE_LEFT, + TEXTURE_TYPE_CUBE_RIGHT +} texture_type_t; + +typedef struct { + texture_type_t type; // -type (default TEXTURE_TYPE_NONE) + real_t sharpness; // -boost (default 1.0?) + real_t brightness; // base_value in -mm option (default 0) + real_t contrast; // gain_value in -mm option (default 1) + real_t origin_offset[3]; // -o u [v [w]] (default 0 0 0) + real_t scale[3]; // -s u [v [w]] (default 1 1 1) + real_t turbulence[3]; // -t u [v [w]] (default 0 0 0) + // int texture_resolution; // -texres resolution (default = ?) TODO + bool clamp; // -clamp (default false) + char imfchan; // -imfchan (the default for bump is 'l' and for decal is 'm') + bool blendu; // -blendu (default on) + bool blendv; // -blendv (default on) + real_t bump_multiplier; // -bm (for bump maps only, default 1.0) +} texture_option_t; + +typedef struct { + std::string name; + + real_t ambient[3]; + real_t diffuse[3]; + real_t specular[3]; + real_t transmittance[3]; + real_t emission[3]; + real_t shininess; + real_t ior; // index of refraction + real_t dissolve; // 1 == opaque; 0 == fully transparent + // illumination model (see http://www.fileformat.info/format/material/) + int illum; + + int dummy; // Suppress padding warning. + + std::string ambient_texname; // map_Ka + std::string diffuse_texname; // map_Kd + std::string specular_texname; // map_Ks + std::string specular_highlight_texname; // map_Ns + std::string bump_texname; // map_bump, map_Bump, bump + std::string displacement_texname; // disp + std::string alpha_texname; // map_d + std::string reflection_texname; // refl + + texture_option_t ambient_texopt; + texture_option_t diffuse_texopt; + texture_option_t specular_texopt; + texture_option_t specular_highlight_texopt; + texture_option_t bump_texopt; + texture_option_t displacement_texopt; + texture_option_t alpha_texopt; + texture_option_t reflection_texopt; + + // PBR extension + // http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr + real_t roughness; // [0, 1] default 0 + real_t metallic; // [0, 1] default 0 + real_t sheen; // [0, 1] default 0 + real_t clearcoat_thickness; // [0, 1] default 0 + real_t clearcoat_roughness; // [0, 1] default 0 + real_t anisotropy; // aniso. [0, 1] default 0 + real_t anisotropy_rotation; // anisor. [0, 1] default 0 + real_t pad0; + std::string roughness_texname; // map_Pr + std::string metallic_texname; // map_Pm + std::string sheen_texname; // map_Ps + std::string emissive_texname; // map_Ke + std::string normal_texname; // norm. For normal mapping. + + texture_option_t roughness_texopt; + texture_option_t metallic_texopt; + texture_option_t sheen_texopt; + texture_option_t emissive_texopt; + texture_option_t normal_texopt; + + int pad2; + + std::map unknown_parameter; +} material_t; + +typedef struct { + std::string name; + + std::vector intValues; + std::vector floatValues; + std::vector stringValues; +} tag_t; + +// Index struct to support different indices for vtx/normal/texcoord. +// -1 means not used. +typedef struct { + int vertex_index; + int normal_index; + int texcoord_index; +} index_t; + +typedef struct { + std::vector indices; + std::vector num_face_vertices; // The number of vertices per + // face. 3 = polygon, 4 = quad, + // ... Up to 255. + std::vector material_ids; // per-face material ID + std::vector tags; // SubD tag +} mesh_t; + +typedef struct { + std::string name; + mesh_t mesh; +} shape_t; + +// Vertex attributes +typedef struct { + std::vector vertices; // 'v' + std::vector normals; // 'vn' + std::vector texcoords; // 'vt' + std::vector colors; // extension: vertex colors +} attrib_t; + +typedef struct callback_t_ { + // W is optional and set to 1 if there is no `w` item in `v` line + void (*vertex_cb)(void *user_data, real_t x, real_t y, real_t z, real_t w); + void (*normal_cb)(void *user_data, real_t x, real_t y, real_t z); + + // y and z are optional and set to 0 if there is no `y` and/or `z` item(s) in + // `vt` line. + void (*texcoord_cb)(void *user_data, real_t x, real_t y, real_t z); + + // called per 'f' line. num_indices is the number of face indices(e.g. 3 for + // triangle, 4 for quad) + // 0 will be passed for undefined index in index_t members. + void (*index_cb)(void *user_data, index_t *indices, int num_indices); + // `name` material name, `material_id` = the array index of material_t[]. -1 + // if + // a material not found in .mtl + void (*usemtl_cb)(void *user_data, const char *name, int material_id); + // `materials` = parsed material data. + void (*mtllib_cb)(void *user_data, const material_t *materials, + int num_materials); + // There may be multiple group names + void (*group_cb)(void *user_data, const char **names, int num_names); + void (*object_cb)(void *user_data, const char *name); + + callback_t_() + : vertex_cb(NULL), + normal_cb(NULL), + texcoord_cb(NULL), + index_cb(NULL), + usemtl_cb(NULL), + mtllib_cb(NULL), + group_cb(NULL), + object_cb(NULL) {} +} callback_t; + +class MaterialReader { + public: + MaterialReader() {} + virtual ~MaterialReader(); + + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *err) = 0; +}; + +class MaterialFileReader : public MaterialReader { + public: + explicit MaterialFileReader(const std::string &mtl_basedir) + : m_mtlBaseDir(mtl_basedir) {} + virtual ~MaterialFileReader() {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *err); + + private: + std::string m_mtlBaseDir; +}; + +class MaterialStreamReader : public MaterialReader { + public: + explicit MaterialStreamReader(std::istream &inStream) + : m_inStream(inStream) {} + virtual ~MaterialStreamReader() {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *err); + + private: + std::istream &m_inStream; +}; + +/// Loads .obj from a file. +/// 'attrib', 'shapes' and 'materials' will be filled with parsed shape data +/// 'shapes' will be filled with parsed shape data +/// Returns true when loading .obj become success. +/// Returns warning and error message into `err` +/// 'mtl_basedir' is optional, and used for base directory for .mtl file. +/// In default(`NULL'), .mtl file is searched from an application's working +/// directory. +/// 'triangulate' is optional, and used whether triangulate polygon face in .obj +/// or not. +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + const char *filename, const char *mtl_basedir = NULL, + bool triangulate = true); + +/// Loads .obj from a file with custom user callback. +/// .mtl is loaded as usual and parsed material_t data will be passed to +/// `callback.mtllib_cb`. +/// Returns true when loading .obj/.mtl become success. +/// Returns warning and error message into `err` +/// See `examples/callback_api/` for how to use this function. +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data = NULL, + MaterialReader *readMatFn = NULL, + std::string *err = NULL); + +/// Loads object from a std::istream, uses GetMtlIStreamFn to retrieve +/// std::istream for materials. +/// Returns true when loading .obj become success. +/// Returns warning and error message into `err` +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + std::istream *inStream, MaterialReader *readMatFn = NULL, + bool triangulate = true); + +/// Loads materials into std::map +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream, + std::string *warning); + +} // namespace tinyobj + +#endif // TINY_OBJ_LOADER_H_ + +#ifdef TINYOBJLOADER_IMPLEMENTATION +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace tinyobj { + +MaterialReader::~MaterialReader() {} + +struct vertex_index { + int v_idx, vt_idx, vn_idx; + vertex_index() : v_idx(-1), vt_idx(-1), vn_idx(-1) {} + explicit vertex_index(int idx) : v_idx(idx), vt_idx(idx), vn_idx(idx) {} + vertex_index(int vidx, int vtidx, int vnidx) + : v_idx(vidx), vt_idx(vtidx), vn_idx(vnidx) {} +}; + +struct tag_sizes { + tag_sizes() : num_ints(0), num_reals(0), num_strings(0) {} + int num_ints; + int num_reals; + int num_strings; +}; + +struct obj_shape { + std::vector v; + std::vector vn; + std::vector vt; +}; + +// See +// http://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf +static std::istream &safeGetline(std::istream &is, std::string &t) { + t.clear(); + + // The characters in the stream are read one-by-one using a std::streambuf. + // That is faster than reading them one-by-one using the std::istream. + // Code that uses streambuf this way must be guarded by a sentry object. + // The sentry object performs various tasks, + // such as thread synchronization and updating the stream state. + + std::istream::sentry se(is, true); + std::streambuf *sb = is.rdbuf(); + + if (se) { + for (;;) { + int c = sb->sbumpc(); + switch (c) { + case '\n': + return is; + case '\r': + if (sb->sgetc() == '\n') sb->sbumpc(); + return is; + case EOF: + // Also handle the case when the last line has no line ending + if (t.empty()) is.setstate(std::ios::eofbit); + return is; + default: + t += static_cast(c); + } + } + } + + return is; +} + +#define IS_SPACE(x) (((x) == ' ') || ((x) == '\t')) +#define IS_DIGIT(x) \ + (static_cast((x) - '0') < static_cast(10)) +#define IS_NEW_LINE(x) (((x) == '\r') || ((x) == '\n') || ((x) == '\0')) + +// Make index zero-base, and also support relative index. +static inline bool fixIndex(int idx, int n, int *ret) { + if (!ret) { + return false; + } + + if (idx > 0) { + (*ret) = idx - 1; + return true; + } + + if (idx == 0) { + // zero is not allowed according to the spec. + return false; + } + + if (idx < 0) { + (*ret) = n + idx; // negative value = relative + return true; + } + + return false; // never reach here. +} + +static inline std::string parseString(const char **token) { + std::string s; + (*token) += strspn((*token), " \t"); + size_t e = strcspn((*token), " \t\r"); + s = std::string((*token), &(*token)[e]); + (*token) += e; + return s; +} + +static inline int parseInt(const char **token) { + (*token) += strspn((*token), " \t"); + int i = atoi((*token)); + (*token) += strcspn((*token), " \t\r"); + return i; +} + +// Tries to parse a floating point number located at s. +// +// s_end should be a location in the string where reading should absolutely +// stop. For example at the end of the string, to prevent buffer overflows. +// +// Parses the following EBNF grammar: +// sign = "+" | "-" ; +// END = ? anything not in digit ? +// digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; +// integer = [sign] , digit , {digit} ; +// decimal = integer , ["." , integer] ; +// float = ( decimal , END ) | ( decimal , ("E" | "e") , integer , END ) ; +// +// Valid strings are for example: +// -0 +3.1417e+2 -0.0E-3 1.0324 -1.41 11e2 +// +// If the parsing is a success, result is set to the parsed value and true +// is returned. +// +// The function is greedy and will parse until any of the following happens: +// - a non-conforming character is encountered. +// - s_end is reached. +// +// The following situations triggers a failure: +// - s >= s_end. +// - parse failure. +// +static bool tryParseDouble(const char *s, const char *s_end, double *result) { + if (s >= s_end) { + return false; + } + + double mantissa = 0.0; + // This exponent is base 2 rather than 10. + // However the exponent we parse is supposed to be one of ten, + // thus we must take care to convert the exponent/and or the + // mantissa to a * 2^E, where a is the mantissa and E is the + // exponent. + // To get the final double we will use ldexp, it requires the + // exponent to be in base 2. + int exponent = 0; + + // NOTE: THESE MUST BE DECLARED HERE SINCE WE ARE NOT ALLOWED + // TO JUMP OVER DEFINITIONS. + char sign = '+'; + char exp_sign = '+'; + char const *curr = s; + + // How many characters were read in a loop. + int read = 0; + // Tells whether a loop terminated due to reaching s_end. + bool end_not_reached = false; + + /* + BEGIN PARSING. + */ + + // Find out what sign we've got. + if (*curr == '+' || *curr == '-') { + sign = *curr; + curr++; + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else { + goto fail; + } + + // Read the integer part. + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + mantissa *= 10; + mantissa += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + + // We must make sure we actually got something. + if (read == 0) goto fail; + // We allow numbers of form "#", "###" etc. + if (!end_not_reached) goto assemble; + + // Read the decimal part. + if (*curr == '.') { + curr++; + read = 1; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + static const double pow_lut[] = { + 1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, + }; + const int lut_entries = sizeof pow_lut / sizeof pow_lut[0]; + + // NOTE: Don't use powf here, it will absolutely murder precision. + mantissa += static_cast(*curr - 0x30) * + (read < lut_entries ? pow_lut[read] : std::pow(10.0, -read)); + read++; + curr++; + end_not_reached = (curr != s_end); + } + } else if (*curr == 'e' || *curr == 'E') { + } else { + goto assemble; + } + + if (!end_not_reached) goto assemble; + + // Read the exponent part. + if (*curr == 'e' || *curr == 'E') { + curr++; + // Figure out if a sign is present and if it is. + end_not_reached = (curr != s_end); + if (end_not_reached && (*curr == '+' || *curr == '-')) { + exp_sign = *curr; + curr++; + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else { + // Empty E is not allowed. + goto fail; + } + + read = 0; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + exponent *= 10; + exponent += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + exponent *= (exp_sign == '+' ? 1 : -1); + if (read == 0) goto fail; + } + +assemble: + *result = (sign == '+' ? 1 : -1) * + (exponent ? std::ldexp(mantissa * std::pow(5.0, exponent), exponent) + : mantissa); + return true; +fail: + return false; +} + +static inline real_t parseReal(const char **token, double default_value = 0.0) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val = default_value; + tryParseDouble((*token), end, &val); + real_t f = static_cast(val); + (*token) = end; + return f; +} + +static inline bool parseReal(const char **token, real_t *out) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val; + bool ret = tryParseDouble((*token), end, &val); + if (ret) { + real_t f = static_cast(val); + (*out) = f; + } + (*token) = end; + return ret; +} + +static inline void parseReal2(real_t *x, real_t *y, const char **token, + const double default_x = 0.0, + const double default_y = 0.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); +} + +static inline void parseReal3(real_t *x, real_t *y, real_t *z, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); +} + +static inline void parseV(real_t *x, real_t *y, real_t *z, real_t *w, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0, + const double default_w = 1.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); + (*w) = parseReal(token, default_w); +} + +// Extension: parse vertex with colors(6 items) +static inline bool parseVertexWithColor(real_t *x, real_t *y, real_t *z, real_t *r, + real_t *g, real_t *b, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); + + (*r) = parseReal(token, 1.0); + (*g) = parseReal(token, 1.0); + (*b) = parseReal(token, 1.0); + + return true; +} + +static inline bool parseOnOff(const char **token, bool default_value = true) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + + bool ret = default_value; + if ((0 == strncmp((*token), "on", 2))) { + ret = true; + } else if ((0 == strncmp((*token), "off", 3))) { + ret = false; + } + + (*token) = end; + return ret; +} + +static inline texture_type_t parseTextureType( + const char **token, texture_type_t default_value = TEXTURE_TYPE_NONE) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + texture_type_t ty = default_value; + + if ((0 == strncmp((*token), "cube_top", strlen("cube_top")))) { + ty = TEXTURE_TYPE_CUBE_TOP; + } else if ((0 == strncmp((*token), "cube_bottom", strlen("cube_bottom")))) { + ty = TEXTURE_TYPE_CUBE_BOTTOM; + } else if ((0 == strncmp((*token), "cube_left", strlen("cube_left")))) { + ty = TEXTURE_TYPE_CUBE_LEFT; + } else if ((0 == strncmp((*token), "cube_right", strlen("cube_right")))) { + ty = TEXTURE_TYPE_CUBE_RIGHT; + } else if ((0 == strncmp((*token), "cube_front", strlen("cube_front")))) { + ty = TEXTURE_TYPE_CUBE_FRONT; + } else if ((0 == strncmp((*token), "cube_back", strlen("cube_back")))) { + ty = TEXTURE_TYPE_CUBE_BACK; + } else if ((0 == strncmp((*token), "sphere", strlen("sphere")))) { + ty = TEXTURE_TYPE_SPHERE; + } + + (*token) = end; + return ty; +} + +static tag_sizes parseTagTriple(const char **token) { + tag_sizes ts; + + (*token) += strspn((*token), " \t"); + ts.num_ints = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + + (*token)++; // Skip '/' + + (*token) += strspn((*token), " \t"); + ts.num_reals = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + (*token)++; // Skip '/' + + ts.num_strings = parseInt(token); + + return ts; +} + +// Parse triples with index offsets: i, i/j/k, i//k, i/j +static bool parseTriple(const char **token, int vsize, int vnsize, int vtsize, + vertex_index *ret) { + if (!ret) { + return false; + } + + vertex_index vi(-1); + + if (!fixIndex(atoi((*token)), vsize, &(vi.v_idx))) { + return false; + } + + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + (*ret) = vi; + return true; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + if (!fixIndex(atoi((*token)), vnsize, &(vi.vn_idx))) { + return false; + } + (*token) += strcspn((*token), "/ \t\r"); + (*ret) = vi; + return true; + } + + // i/j/k or i/j + if (!fixIndex(atoi((*token)), vtsize, &(vi.vt_idx))) { + return false; + } + + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + (*ret) = vi; + return true; + } + + // i/j/k + (*token)++; // skip '/' + if (!fixIndex(atoi((*token)), vnsize, &(vi.vn_idx))) { + return false; + } + (*token) += strcspn((*token), "/ \t\r"); + + (*ret) = vi; + + return true; +} + +// Parse raw triples: i, i/j/k, i//k, i/j +static vertex_index parseRawTriple(const char **token) { + vertex_index vi(static_cast(0)); // 0 is an invalid index in OBJ + + vi.v_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; + } + + // i/j/k or i/j + vi.vt_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + + // i/j/k + (*token)++; // skip '/' + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; +} + +static bool ParseTextureNameAndOption(std::string *texname, + texture_option_t *texopt, + const char *linebuf, const bool is_bump) { + // @todo { write more robust lexer and parser. } + bool found_texname = false; + std::string texture_name; + + // Fill with default value for texopt. + if (is_bump) { + texopt->imfchan = 'l'; + } else { + texopt->imfchan = 'm'; + } + texopt->bump_multiplier = 1.0f; + texopt->clamp = false; + texopt->blendu = true; + texopt->blendv = true; + texopt->sharpness = 1.0f; + texopt->brightness = 0.0f; + texopt->contrast = 1.0f; + texopt->origin_offset[0] = 0.0f; + texopt->origin_offset[1] = 0.0f; + texopt->origin_offset[2] = 0.0f; + texopt->scale[0] = 1.0f; + texopt->scale[1] = 1.0f; + texopt->scale[2] = 1.0f; + texopt->turbulence[0] = 0.0f; + texopt->turbulence[1] = 0.0f; + texopt->turbulence[2] = 0.0f; + texopt->type = TEXTURE_TYPE_NONE; + + const char *token = linebuf; // Assume line ends with NULL + + while (!IS_NEW_LINE((*token))) { + token += strspn(token, " \t"); // skip space + if ((0 == strncmp(token, "-blendu", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendu = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-blendv", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendv = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-clamp", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->clamp = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-boost", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->sharpness = parseReal(&token, 1.0); + } else if ((0 == strncmp(token, "-bm", 3)) && IS_SPACE((token[3]))) { + token += 4; + texopt->bump_multiplier = parseReal(&token, 1.0); + } else if ((0 == strncmp(token, "-o", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->origin_offset[0]), &(texopt->origin_offset[1]), + &(texopt->origin_offset[2]), &token); + } else if ((0 == strncmp(token, "-s", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->scale[0]), &(texopt->scale[1]), &(texopt->scale[2]), + &token, 1.0, 1.0, 1.0); + } else if ((0 == strncmp(token, "-t", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->turbulence[0]), &(texopt->turbulence[1]), + &(texopt->turbulence[2]), &token); + } else if ((0 == strncmp(token, "-type", 5)) && IS_SPACE((token[5]))) { + token += 5; + texopt->type = parseTextureType((&token), TEXTURE_TYPE_NONE); + } else if ((0 == strncmp(token, "-imfchan", 8)) && IS_SPACE((token[8]))) { + token += 9; + token += strspn(token, " \t"); + const char *end = token + strcspn(token, " \t\r"); + if ((end - token) == 1) { // Assume one char for -imfchan + texopt->imfchan = (*token); + } + token = end; + } else if ((0 == strncmp(token, "-mm", 3)) && IS_SPACE((token[3]))) { + token += 4; + parseReal2(&(texopt->brightness), &(texopt->contrast), &token, 0.0, 1.0); + } else { + // Assume texture filename +#if 0 + size_t len = strcspn(token, " \t\r"); // untile next space + texture_name = std::string(token, token + len); + token += len; + + token += strspn(token, " \t"); // skip space +#else + // Read filename until line end to parse filename containing whitespace + // TODO(syoyo): Support parsing texture option flag after the filename. + texture_name = std::string(token); + token += texture_name.length(); +#endif + + found_texname = true; + } + } + + if (found_texname) { + (*texname) = texture_name; + return true; + } else { + return false; + } +} + +static void InitMaterial(material_t *material) { + material->name = ""; + material->ambient_texname = ""; + material->diffuse_texname = ""; + material->specular_texname = ""; + material->specular_highlight_texname = ""; + material->bump_texname = ""; + material->displacement_texname = ""; + material->reflection_texname = ""; + material->alpha_texname = ""; + for (int i = 0; i < 3; i++) { + material->ambient[i] = 0.f; + material->diffuse[i] = 0.f; + material->specular[i] = 0.f; + material->transmittance[i] = 0.f; + material->emission[i] = 0.f; + } + material->illum = 0; + material->dissolve = 1.f; + material->shininess = 1.f; + material->ior = 1.f; + + material->roughness = 0.f; + material->metallic = 0.f; + material->sheen = 0.f; + material->clearcoat_thickness = 0.f; + material->clearcoat_roughness = 0.f; + material->anisotropy_rotation = 0.f; + material->anisotropy = 0.f; + material->roughness_texname = ""; + material->metallic_texname = ""; + material->sheen_texname = ""; + material->emissive_texname = ""; + material->normal_texname = ""; + + material->unknown_parameter.clear(); +} + +// code from https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html +static int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy) +{ + int i, j, c = 0; + for (i = 0, j = nvert-1; i < nvert; j = i++) { + if ( ((verty[i]>testy) != (verty[j]>testy)) && + (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) ) + c = !c; + } + return c; +} + +static bool exportFaceGroupToShape( + shape_t *shape, const std::vector > &faceGroup, + const std::vector &tags, const int material_id, + const std::string &name, bool triangulate, const std::vector &v) { + if (faceGroup.empty()) { + return false; + } + + // Flatten vertices and indices + for (size_t i = 0; i < faceGroup.size(); i++) { + const std::vector &face = faceGroup[i]; + + vertex_index i0 = face[0]; + vertex_index i1(-1); + vertex_index i2 = face[1]; + + size_t npolys = face.size(); + + if (triangulate) { + // find the two axes to work in + size_t axes[2] = { 1, 2 }; + for(size_t k = 0; k < npolys; ++k) { + i0 = face[(k+0)%npolys]; + i1 = face[(k+1)%npolys]; + i2 = face[(k+2)%npolys]; + size_t vi0 = size_t(i0.v_idx); + size_t vi1 = size_t(i1.v_idx); + size_t vi2 = size_t(i2.v_idx); + real_t v0x = v[vi0*3+0]; + real_t v0y = v[vi0*3+1]; + real_t v0z = v[vi0*3+2]; + real_t v1x = v[vi1*3+0]; + real_t v1y = v[vi1*3+1]; + real_t v1z = v[vi1*3+2]; + real_t v2x = v[vi2*3+0]; + real_t v2y = v[vi2*3+1]; + real_t v2z = v[vi2*3+2]; + real_t e0x = v1x - v0x; + real_t e0y = v1y - v0y; + real_t e0z = v1z - v0z; + real_t e1x = v2x - v1x; + real_t e1y = v2y - v1y; + real_t e1z = v2z - v1z; + float cx = std::fabs(e0y*e1z - e0z*e1y); + float cy = std::fabs(e0z*e1x - e0x*e1z); + float cz = std::fabs(e0x*e1y - e0y*e1x); + const float epsilon = 0.0001f; + if( cx > epsilon || cy > epsilon || cz > epsilon ) { + // found a corner + if( cx > cy && cx > cz ) { + } else { + axes[0] = 0; + if( cz > cx && cz > cy ) + axes[1] = 1; + } + break; + } + } + + real_t area = 0; + for(size_t k = 0; k < npolys; ++k) { + i0 = face[(k+0)%npolys]; + i1 = face[(k+1)%npolys]; + size_t vi0 = size_t(i0.v_idx); + size_t vi1 = size_t(i1.v_idx); + real_t v0x = v[vi0*3+axes[0]]; + real_t v0y = v[vi0*3+axes[1]]; + real_t v1x = v[vi1*3+axes[0]]; + real_t v1y = v[vi1*3+axes[1]]; + area += (v0x*v1y - v0y*v1x)*0.5f; + } + + int maxRounds = 10; // arbitrary max loop count to protect against unexpected errors + + std::vector remainingFace = face; + size_t guess_vert = 0; + vertex_index ind[3]; + real_t vx[3]; + real_t vy[3]; + while( remainingFace.size() > 3 && maxRounds > 0 ) { + npolys = remainingFace.size(); + if( guess_vert >= npolys ) { + maxRounds -= 1; + guess_vert -= npolys; + } + for( size_t k = 0; k < 3; k++ ) { + ind[k] = remainingFace[(guess_vert+k)%npolys]; + size_t vi = size_t(ind[k].v_idx); + vx[k] = v[vi*3+axes[0]]; + vy[k] = v[vi*3+axes[1]]; + } + real_t e0x = vx[1] - vx[0]; + real_t e0y = vy[1] - vy[0]; + real_t e1x = vx[2] - vx[1]; + real_t e1y = vy[2] - vy[1]; + real_t cross = e0x*e1y - e0y*e1x; + // if an internal angle + if( cross * area < 0.0f ) { guess_vert += 1; continue; } + + // check all other verts in case they are inside this triangle + bool overlap = false; + for( size_t otherVert = 3; otherVert < npolys; ++otherVert ) { + size_t ovi = size_t(remainingFace[(guess_vert+otherVert)%npolys].v_idx); + real_t tx = v[ovi*3+axes[0]]; + real_t ty = v[ovi*3+axes[1]]; + if( pnpoly( 3, vx, vy, tx, ty ) ) { + overlap = true; + break; + } + } + + if( overlap ) { guess_vert += 1; continue; } + + // this triangle is an ear + { + index_t idx0, idx1, idx2; + idx0.vertex_index = ind[0].v_idx; + idx0.normal_index = ind[0].vn_idx; + idx0.texcoord_index = ind[0].vt_idx; + idx1.vertex_index = ind[1].v_idx; + idx1.normal_index = ind[1].vn_idx; + idx1.texcoord_index = ind[1].vt_idx; + idx2.vertex_index = ind[2].v_idx; + idx2.normal_index = ind[2].vn_idx; + idx2.texcoord_index = ind[2].vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + } + + // remove v1 from the list + size_t removed_vert_index = (guess_vert+1)%npolys; + while( removed_vert_index + 1 < npolys ) { + remainingFace[removed_vert_index] = remainingFace[removed_vert_index+1]; + removed_vert_index += 1; + } + remainingFace.pop_back(); + } + + if( remainingFace.size() == 3 ) { + i0 = remainingFace[0]; + i1 = remainingFace[1]; + i2 = remainingFace[2]; + { + index_t idx0, idx1, idx2; + idx0.vertex_index = i0.v_idx; + idx0.normal_index = i0.vn_idx; + idx0.texcoord_index = i0.vt_idx; + idx1.vertex_index = i1.v_idx; + idx1.normal_index = i1.vn_idx; + idx1.texcoord_index = i1.vt_idx; + idx2.vertex_index = i2.v_idx; + idx2.normal_index = i2.vn_idx; + idx2.texcoord_index = i2.vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + } + } + } else { + for (size_t k = 0; k < npolys; k++) { + index_t idx; + idx.vertex_index = face[k].v_idx; + idx.normal_index = face[k].vn_idx; + idx.texcoord_index = face[k].vt_idx; + shape->mesh.indices.push_back(idx); + } + + shape->mesh.num_face_vertices.push_back( + static_cast(npolys)); + shape->mesh.material_ids.push_back(material_id); // per face + } + } + + shape->name = name; + shape->mesh.tags = tags; + + return true; +} + +// Split a string with specified delimiter character. +// http://stackoverflow.com/questions/236129/split-a-string-in-c +static void SplitString(const std::string &s, char delim, + std::vector &elems) { + std::stringstream ss; + ss.str(s); + std::string item; + while (std::getline(ss, item, delim)) { + elems.push_back(item); + } +} + +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream, + std::string *warning) { + // Create a default material anyway. + material_t material; + InitMaterial(&material); + + // Issue 43. `d` wins against `Tr` since `Tr` is not in the MTL specification. + bool has_d = false; + bool has_tr = false; + + std::stringstream ss; + + std::string linebuf; + while (inStream->peek() != -1) { + safeGetline(*inStream, linebuf); + + // Trim trailing whitespace. + if (linebuf.size() > 0) { + linebuf = linebuf.substr(0, linebuf.find_last_not_of(" \t") + 1); + } + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // new mtl + if ((0 == strncmp(token, "newmtl", 6)) && IS_SPACE((token[6]))) { + // flush previous material. + if (!material.name.empty()) { + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); + } + + // initial temporary material + InitMaterial(&material); + + has_d = false; + has_tr = false; + + // set new mtl name + token += 7; + { + std::stringstream sstr; + sstr << token; + material.name = sstr.str(); + } + continue; + } + + // ambient + if (token[0] == 'K' && token[1] == 'a' && IS_SPACE((token[2]))) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.ambient[0] = r; + material.ambient[1] = g; + material.ambient[2] = b; + continue; + } + + // diffuse + if (token[0] == 'K' && token[1] == 'd' && IS_SPACE((token[2]))) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.diffuse[0] = r; + material.diffuse[1] = g; + material.diffuse[2] = b; + continue; + } + + // specular + if (token[0] == 'K' && token[1] == 's' && IS_SPACE((token[2]))) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.specular[0] = r; + material.specular[1] = g; + material.specular[2] = b; + continue; + } + + // transmittance + if ((token[0] == 'K' && token[1] == 't' && IS_SPACE((token[2]))) || + (token[0] == 'T' && token[1] == 'f' && IS_SPACE((token[2])))) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.transmittance[0] = r; + material.transmittance[1] = g; + material.transmittance[2] = b; + continue; + } + + // ior(index of refraction) + if (token[0] == 'N' && token[1] == 'i' && IS_SPACE((token[2]))) { + token += 2; + material.ior = parseReal(&token); + continue; + } + + // emission + if (token[0] == 'K' && token[1] == 'e' && IS_SPACE(token[2])) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.emission[0] = r; + material.emission[1] = g; + material.emission[2] = b; + continue; + } + + // shininess + if (token[0] == 'N' && token[1] == 's' && IS_SPACE(token[2])) { + token += 2; + material.shininess = parseReal(&token); + continue; + } + + // illum model + if (0 == strncmp(token, "illum", 5) && IS_SPACE(token[5])) { + token += 6; + material.illum = parseInt(&token); + continue; + } + + // dissolve + if ((token[0] == 'd' && IS_SPACE(token[1]))) { + token += 1; + material.dissolve = parseReal(&token); + + if (has_tr) { + ss << "WARN: Both `d` and `Tr` parameters defined for \"" + << material.name << "\". Use the value of `d` for dissolve." + << std::endl; + } + has_d = true; + continue; + } + if (token[0] == 'T' && token[1] == 'r' && IS_SPACE(token[2])) { + token += 2; + if (has_d) { + // `d` wins. Ignore `Tr` value. + ss << "WARN: Both `d` and `Tr` parameters defined for \"" + << material.name << "\". Use the value of `d` for dissolve." + << std::endl; + } else { + // We invert value of Tr(assume Tr is in range [0, 1]) + // NOTE: Interpretation of Tr is application(exporter) dependent. For + // some application(e.g. 3ds max obj exporter), Tr = d(Issue 43) + material.dissolve = 1.0f - parseReal(&token); + } + has_tr = true; + continue; + } + + // PBR: roughness + if (token[0] == 'P' && token[1] == 'r' && IS_SPACE(token[2])) { + token += 2; + material.roughness = parseReal(&token); + continue; + } + + // PBR: metallic + if (token[0] == 'P' && token[1] == 'm' && IS_SPACE(token[2])) { + token += 2; + material.metallic = parseReal(&token); + continue; + } + + // PBR: sheen + if (token[0] == 'P' && token[1] == 's' && IS_SPACE(token[2])) { + token += 2; + material.sheen = parseReal(&token); + continue; + } + + // PBR: clearcoat thickness + if (token[0] == 'P' && token[1] == 'c' && IS_SPACE(token[2])) { + token += 2; + material.clearcoat_thickness = parseReal(&token); + continue; + } + + // PBR: clearcoat roughness + if ((0 == strncmp(token, "Pcr", 3)) && IS_SPACE(token[3])) { + token += 4; + material.clearcoat_roughness = parseReal(&token); + continue; + } + + // PBR: anisotropy + if ((0 == strncmp(token, "aniso", 5)) && IS_SPACE(token[5])) { + token += 6; + material.anisotropy = parseReal(&token); + continue; + } + + // PBR: anisotropy rotation + if ((0 == strncmp(token, "anisor", 6)) && IS_SPACE(token[6])) { + token += 7; + material.anisotropy_rotation = parseReal(&token); + continue; + } + + // ambient texture + if ((0 == strncmp(token, "map_Ka", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.ambient_texname), + &(material.ambient_texopt), token, + /* is_bump */ false); + continue; + } + + // diffuse texture + if ((0 == strncmp(token, "map_Kd", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.diffuse_texname), + &(material.diffuse_texopt), token, + /* is_bump */ false); + continue; + } + + // specular texture + if ((0 == strncmp(token, "map_Ks", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.specular_texname), + &(material.specular_texopt), token, + /* is_bump */ false); + continue; + } + + // specular highlight texture + if ((0 == strncmp(token, "map_Ns", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.specular_highlight_texname), + &(material.specular_highlight_texopt), token, + /* is_bump */ false); + continue; + } + + // bump texture + if ((0 == strncmp(token, "map_bump", 8)) && IS_SPACE(token[8])) { + token += 9; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token, + /* is_bump */ true); + continue; + } + + // bump texture + if ((0 == strncmp(token, "map_Bump", 8)) && IS_SPACE(token[8])) { + token += 9; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token, + /* is_bump */ true); + continue; + } + + // bump texture + if ((0 == strncmp(token, "bump", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token, + /* is_bump */ true); + continue; + } + + // alpha texture + if ((0 == strncmp(token, "map_d", 5)) && IS_SPACE(token[5])) { + token += 6; + material.alpha_texname = token; + ParseTextureNameAndOption(&(material.alpha_texname), + &(material.alpha_texopt), token, + /* is_bump */ false); + continue; + } + + // displacement texture + if ((0 == strncmp(token, "disp", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.displacement_texname), + &(material.displacement_texopt), token, + /* is_bump */ false); + continue; + } + + // reflection map + if ((0 == strncmp(token, "refl", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.reflection_texname), + &(material.reflection_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: roughness texture + if ((0 == strncmp(token, "map_Pr", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.roughness_texname), + &(material.roughness_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: metallic texture + if ((0 == strncmp(token, "map_Pm", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.metallic_texname), + &(material.metallic_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: sheen texture + if ((0 == strncmp(token, "map_Ps", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.sheen_texname), + &(material.sheen_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: emissive texture + if ((0 == strncmp(token, "map_Ke", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.emissive_texname), + &(material.emissive_texopt), token, + /* is_bump */ false); + continue; + } + + // PBR: normal map texture + if ((0 == strncmp(token, "norm", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption( + &(material.normal_texname), &(material.normal_texopt), token, + /* is_bump */ false); // @fixme { is_bump will be true? } + continue; + } + + // unknown parameter + const char *_space = strchr(token, ' '); + if (!_space) { + _space = strchr(token, '\t'); + } + if (_space) { + std::ptrdiff_t len = _space - token; + std::string key(token, static_cast(len)); + std::string value = _space + 1; + material.unknown_parameter.insert( + std::pair(key, value)); + } + } + // flush last material. + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); + + if (warning) { + (*warning) = ss.str(); + } +} + +bool MaterialFileReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *err) { + std::string filepath; + + if (!m_mtlBaseDir.empty()) { + filepath = std::string(m_mtlBaseDir) + matId; + } else { + filepath = matId; + } + + std::ifstream matIStream(filepath.c_str()); + if (!matIStream) { + std::stringstream ss; + ss << "WARN: Material file [ " << filepath << " ] not found." << std::endl; + if (err) { + (*err) += ss.str(); + } + return false; + } + + std::string warning; + LoadMtl(matMap, materials, &matIStream, &warning); + + if (!warning.empty()) { + if (err) { + (*err) += warning; + } + } + + return true; +} + +bool MaterialStreamReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *err) { + (void)matId; + if (!m_inStream) { + std::stringstream ss; + ss << "WARN: Material stream in error state. " << std::endl; + if (err) { + (*err) += ss.str(); + } + return false; + } + + std::string warning; + LoadMtl(matMap, materials, &m_inStream, &warning); + + if (!warning.empty()) { + if (err) { + (*err) += warning; + } + } + + return true; +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + const char *filename, const char *mtl_basedir, bool trianglulate) { + attrib->vertices.clear(); + attrib->normals.clear(); + attrib->texcoords.clear(); + attrib->colors.clear(); + shapes->clear(); + + std::stringstream errss; + + std::ifstream ifs(filename); + if (!ifs) { + errss << "Cannot open file [" << filename << "]" << std::endl; + if (err) { + (*err) = errss.str(); + } + return false; + } + + std::string baseDir; + if (mtl_basedir) { + baseDir = mtl_basedir; + } + MaterialFileReader matFileReader(baseDir); + + return LoadObj(attrib, shapes, materials, err, &ifs, &matFileReader, + trianglulate); +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *err, + std::istream *inStream, MaterialReader *readMatFn /*= NULL*/, + bool triangulate) { + std::stringstream errss; + + std::vector v; + std::vector vn; + std::vector vt; + std::vector vc; + std::vector tags; + std::vector > faceGroup; + std::string name; + + // material + std::map material_map; + int material = -1; + + shape_t shape; + + std::string linebuf; + while (inStream->peek() != -1) { + safeGetline(*inStream, linebuf); + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // vertex + if (token[0] == 'v' && IS_SPACE((token[1]))) { + token += 2; + real_t x, y, z; + real_t r, g, b; + parseVertexWithColor(&x, &y, &z, &r, &g, &b, &token); + v.push_back(x); + v.push_back(y); + v.push_back(z); + + vc.push_back(r); + vc.push_back(g); + vc.push_back(b); + continue; + } + + // normal + if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) { + token += 3; + real_t x, y, z; + parseReal3(&x, &y, &z, &token); + vn.push_back(x); + vn.push_back(y); + vn.push_back(z); + continue; + } + + // texcoord + if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { + token += 3; + real_t x, y; + parseReal2(&x, &y, &token); + vt.push_back(x); + vt.push_back(y); + continue; + } + + // face + if (token[0] == 'f' && IS_SPACE((token[1]))) { + token += 2; + token += strspn(token, " \t"); + + std::vector face; + face.reserve(3); + + while (!IS_NEW_LINE(token[0])) { + vertex_index vi; + if (!parseTriple(&token, static_cast(v.size() / 3), + static_cast(vn.size() / 3), + static_cast(vt.size() / 2), &vi)) { + if (err) { + (*err) = "Failed parse `f' line(e.g. zero value for face index).\n"; + } + return false; + } + + face.push_back(vi); + size_t n = strspn(token, " \t\r"); + token += n; + } + + // replace with emplace_back + std::move on C++11 + faceGroup.push_back(std::vector()); + faceGroup[faceGroup.size() - 1].swap(face); + + continue; + } + + // use mtl + if ((0 == strncmp(token, "usemtl", 6)) && IS_SPACE((token[6]))) { + token += 7; + std::stringstream ss; + ss << token; + std::string namebuf = ss.str(); + + int newMaterialId = -1; + if (material_map.find(namebuf) != material_map.end()) { + newMaterialId = material_map[namebuf]; + } else { + // { error!! material not found } + } + + if (newMaterialId != material) { + // Create per-face material. Thus we don't add `shape` to `shapes` at + // this time. + // just clear `faceGroup` after `exportFaceGroupToShape()` call. + exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate, v); + faceGroup.clear(); + material = newMaterialId; + } + + continue; + } + + // load mtl + if ((0 == strncmp(token, "mtllib", 6)) && IS_SPACE((token[6]))) { + if (readMatFn) { + token += 7; + + std::vector filenames; + SplitString(std::string(token), ' ', filenames); + + if (filenames.empty()) { + if (err) { + (*err) += + "WARN: Looks like empty filename for mtllib. Use default " + "material. \n"; + } + } else { + bool found = false; + for (size_t s = 0; s < filenames.size(); s++) { + std::string err_mtl; + bool ok = (*readMatFn)(filenames[s].c_str(), materials, + &material_map, &err_mtl); + if (err && (!err_mtl.empty())) { + (*err) += err_mtl; // This should be warn message. + } + + if (ok) { + found = true; + break; + } + } + + if (!found) { + if (err) { + (*err) += + "WARN: Failed to load material file(s). Use default " + "material.\n"; + } + } + } + } + + continue; + } + + // group name + if (token[0] == 'g' && IS_SPACE((token[1]))) { + // flush previous face group. + bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate, v); + (void)ret; // return value not used. + + if (shape.mesh.indices.size() > 0) { + shapes->push_back(shape); + } + + shape = shape_t(); + + // material = -1; + faceGroup.clear(); + + std::vector names; + names.reserve(2); + + while (!IS_NEW_LINE(token[0])) { + std::string str = parseString(&token); + names.push_back(str); + token += strspn(token, " \t\r"); // skip tag + } + + assert(names.size() > 0); + + // names[0] must be 'g', so skip the 0th element. + if (names.size() > 1) { + name = names[1]; + } else { + name = ""; + } + + continue; + } + + // object name + if (token[0] == 'o' && IS_SPACE((token[1]))) { + // flush previous face group. + bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate, v); + if (ret) { + shapes->push_back(shape); + } + + // material = -1; + faceGroup.clear(); + shape = shape_t(); + + // @todo { multiple object name? } + token += 2; + std::stringstream ss; + ss << token; + name = ss.str(); + + continue; + } + + if (token[0] == 't' && IS_SPACE(token[1])) { + tag_t tag; + + token += 2; + + tag.name = parseString(&token); + + tag_sizes ts = parseTagTriple(&token); + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = parseInt(&token); + } + + tag.floatValues.resize(static_cast(ts.num_reals)); + for (size_t i = 0; i < static_cast(ts.num_reals); ++i) { + tag.floatValues[i] = parseReal(&token); + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + tag.stringValues[i] = parseString(&token); + } + + tags.push_back(tag); + } + + // Ignore unknown command. + } + + bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, + triangulate, v); + // exportFaceGroupToShape return false when `usemtl` is called in the last + // line. + // we also add `shape` to `shapes` when `shape.mesh` has already some + // faces(indices) + if (ret || shape.mesh.indices.size()) { + shapes->push_back(shape); + } + faceGroup.clear(); // for safety + + if (err) { + (*err) += errss.str(); + } + + attrib->vertices.swap(v); + attrib->normals.swap(vn); + attrib->texcoords.swap(vt); + attrib->colors.swap(vc); + + return true; +} + +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data /*= NULL*/, + MaterialReader *readMatFn /*= NULL*/, + std::string *err /*= NULL*/) { + std::stringstream errss; + + // material + std::map material_map; + int material_id = -1; // -1 = invalid + + std::vector indices; + std::vector materials; + std::vector names; + names.reserve(2); + std::string name; + std::vector names_out; + + std::string linebuf; + while (inStream.peek() != -1) { + safeGetline(inStream, linebuf); + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // vertex + if (token[0] == 'v' && IS_SPACE((token[1]))) { + token += 2; + // TODO(syoyo): Support parsing vertex color extension. + real_t x, y, z, w; // w is optional. default = 1.0 + parseV(&x, &y, &z, &w, &token); + if (callback.vertex_cb) { + callback.vertex_cb(user_data, x, y, z, w); + } + continue; + } + + // normal + if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) { + token += 3; + real_t x, y, z; + parseReal3(&x, &y, &z, &token); + if (callback.normal_cb) { + callback.normal_cb(user_data, x, y, z); + } + continue; + } + + // texcoord + if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { + token += 3; + real_t x, y, z; // y and z are optional. default = 0.0 + parseReal3(&x, &y, &z, &token); + if (callback.texcoord_cb) { + callback.texcoord_cb(user_data, x, y, z); + } + continue; + } + + // face + if (token[0] == 'f' && IS_SPACE((token[1]))) { + token += 2; + token += strspn(token, " \t"); + + indices.clear(); + while (!IS_NEW_LINE(token[0])) { + vertex_index vi = parseRawTriple(&token); + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + indices.push_back(idx); + size_t n = strspn(token, " \t\r"); + token += n; + } + + if (callback.index_cb && indices.size() > 0) { + callback.index_cb(user_data, &indices.at(0), + static_cast(indices.size())); + } + + continue; + } + + // use mtl + if ((0 == strncmp(token, "usemtl", 6)) && IS_SPACE((token[6]))) { + token += 7; + std::stringstream ss; + ss << token; + std::string namebuf = ss.str(); + + int newMaterialId = -1; + if (material_map.find(namebuf) != material_map.end()) { + newMaterialId = material_map[namebuf]; + } else { + // { error!! material not found } + } + + if (newMaterialId != material_id) { + material_id = newMaterialId; + } + + if (callback.usemtl_cb) { + callback.usemtl_cb(user_data, namebuf.c_str(), material_id); + } + + continue; + } + + // load mtl + if ((0 == strncmp(token, "mtllib", 6)) && IS_SPACE((token[6]))) { + if (readMatFn) { + token += 7; + + std::vector filenames; + SplitString(std::string(token), ' ', filenames); + + if (filenames.empty()) { + if (err) { + (*err) += + "WARN: Looks like empty filename for mtllib. Use default " + "material. \n"; + } + } else { + bool found = false; + for (size_t s = 0; s < filenames.size(); s++) { + std::string err_mtl; + bool ok = (*readMatFn)(filenames[s].c_str(), &materials, + &material_map, &err_mtl); + if (err && (!err_mtl.empty())) { + (*err) += err_mtl; // This should be warn message. + } + + if (ok) { + found = true; + break; + } + } + + if (!found) { + if (err) { + (*err) += + "WARN: Failed to load material file(s). Use default " + "material.\n"; + } + } else { + if (callback.mtllib_cb) { + callback.mtllib_cb(user_data, &materials.at(0), + static_cast(materials.size())); + } + } + } + } + + continue; + } + + // group name + if (token[0] == 'g' && IS_SPACE((token[1]))) { + names.clear(); + + while (!IS_NEW_LINE(token[0])) { + std::string str = parseString(&token); + names.push_back(str); + token += strspn(token, " \t\r"); // skip tag + } + + assert(names.size() > 0); + + // names[0] must be 'g', so skip the 0th element. + if (names.size() > 1) { + name = names[1]; + } else { + name.clear(); + } + + if (callback.group_cb) { + if (names.size() > 1) { + // create const char* array. + names_out.resize(names.size() - 1); + for (size_t j = 0; j < names_out.size(); j++) { + names_out[j] = names[j + 1].c_str(); + } + callback.group_cb(user_data, &names_out.at(0), + static_cast(names_out.size())); + + } else { + callback.group_cb(user_data, NULL, 0); + } + } + + continue; + } + + // object name + if (token[0] == 'o' && IS_SPACE((token[1]))) { + // @todo { multiple object name? } + token += 2; + + std::stringstream ss; + ss << token; + std::string object_name = ss.str(); + + if (callback.object_cb) { + callback.object_cb(user_data, object_name.c_str()); + } + + continue; + } + +#if 0 // @todo + if (token[0] == 't' && IS_SPACE(token[1])) { + tag_t tag; + + token += 2; + std::stringstream ss; + ss << token; + tag.name = ss.str(); + + token += tag.name.size() + 1; + + tag_sizes ts = parseTagTriple(&token); + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = atoi(token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.floatValues.resize(static_cast(ts.num_reals)); + for (size_t i = 0; i < static_cast(ts.num_reals); ++i) { + tag.floatValues[i] = parseReal(&token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + std::stringstream ss; + ss << token; + tag.stringValues[i] = ss.str(); + token += tag.stringValues[i].size() + 1; + } + + tags.push_back(tag); + } +#endif + + // Ignore unknown command. + } + + if (err) { + (*err) += errss.str(); + } + + return true; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +} // namespace tinyobj + +#endif \ No newline at end of file diff --git a/Segmentator/tinyply.cpp b/Segmentator/tinyply.cpp new file mode 100644 index 0000000..bc63a8a --- /dev/null +++ b/Segmentator/tinyply.cpp @@ -0,0 +1,360 @@ +// This software is in the public domain. Where that dedication is not +// recognized, you are granted a perpetual, irrevocable license to copy, +// distribute, and modify this file as you see fit. +// Authored in 2015 by Dimitri Diakopoulos (http://www.dimitridiakopoulos.com) +// https://github.com/ddiakopoulos/tinyply + +#include "tinyply.h" + +using namespace tinyply; +using namespace std; + +////////////////// +// PLY Property // +////////////////// + +PlyProperty::PlyProperty(std::istream & is) : isList(false) +{ + parse_internal(is); +} + +void PlyProperty::parse_internal(std::istream & is) +{ + string type; + is >> type; + if (type == "list") + { + string countType; + is >> countType >> type; + listType = property_type_from_string(countType); + isList = true; + } + propertyType = property_type_from_string(type); + is >> name; +} + +///////////////// +// PLY Element // +///////////////// + +PlyElement::PlyElement(std::istream & is) +{ + parse_internal(is); +} + +void PlyElement::parse_internal(std::istream & is) +{ + is >> name >> size; +} + +////////////// +// PLY File // +////////////// + +PlyFile::PlyFile(std::istream & is) +{ + if (!parse_header(is)) + { + throw std::runtime_error("file is not ply or encounted junk in header"); + } +} + +bool PlyFile::parse_header(std::istream & is) +{ + std::string line; + bool gotMagic = false; + while (std::getline(is, line)) + { + std::istringstream ls(line); + std::string token; + ls >> token; + if (token == "ply" || token == "PLY" || token == "") + { + gotMagic = true; + continue; + } + else if (token == "comment") read_header_text(line, ls, comments, 8); + else if (token == "format") read_header_format(ls); + else if (token == "element") read_header_element(ls); + else if (token == "property") read_header_property(ls); + else if (token == "obj_info") read_header_text(line, ls, objInfo, 9); + else if (token == "end_header") break; + else return false; + } + return true; +} + +void PlyFile::read_header_text(std::string line, std::istream & is, std::vector& place, int erase) +{ + place.push_back((erase > 0) ? line.erase(0, erase) : line); +} + +void PlyFile::read_header_format(std::istream & is) +{ + std::string s; + (is >> s); + if (s == "binary_little_endian") isBinary = true; + else if (s == "binary_big_endian") isBinary = isBigEndian = true; +} + +void PlyFile::read_header_element(std::istream & is) +{ + get_elements().emplace_back(is); +} + +void PlyFile::read_header_property(std::istream & is) +{ + get_elements().back().properties.emplace_back(is); +} + +size_t PlyFile::skip_property_binary(const PlyProperty & property, std::istream & is) +{ + static std::vector skip(PropertyTable[property.propertyType].stride); + if (property.isList) + { + size_t listSize = 0; + size_t dummyCount = 0; + read_property_binary(property.listType, &listSize, dummyCount, is); + for (size_t i = 0; i < listSize; ++i) is.read(skip.data(), PropertyTable[property.propertyType].stride); + return listSize; + } + else + { + is.read(skip.data(), PropertyTable[property.propertyType].stride); + return 0; + } +} + +void PlyFile::skip_property_ascii(const PlyProperty & property, std::istream & is) +{ + std::string skip; + if (property.isList) + { + int listSize; + is >> listSize; + for (int i = 0; i < listSize; ++i) is >> skip; + } + else is >> skip; +} + +void PlyFile::read_property_binary(PlyProperty::Type t, void * dest, size_t & destOffset, std::istream & is) +{ + static std::vector src(PropertyTable[t].stride); + is.read(src.data(), PropertyTable[t].stride); + + switch (t) + { + case PlyProperty::Type::INT8: ply_cast(dest, src.data(), isBigEndian); break; + case PlyProperty::Type::UINT8: ply_cast(dest, src.data(), isBigEndian); break; + case PlyProperty::Type::INT16: ply_cast(dest, src.data(), isBigEndian); break; + case PlyProperty::Type::UINT16: ply_cast(dest, src.data(), isBigEndian); break; + case PlyProperty::Type::INT32: ply_cast(dest, src.data(), isBigEndian); break; + case PlyProperty::Type::UINT32: ply_cast(dest, src.data(), isBigEndian); break; + case PlyProperty::Type::FLOAT32: ply_cast_float(dest, src.data(), isBigEndian); break; + case PlyProperty::Type::FLOAT64: ply_cast_double(dest, src.data(), isBigEndian); break; + case PlyProperty::Type::INVALID: throw std::invalid_argument("invalid ply property"); + } + destOffset += PropertyTable[t].stride; +} + +void PlyFile::read_property_ascii(PlyProperty::Type t, void * dest, size_t & destOffset, std::istream & is) +{ + switch (t) + { + case PlyProperty::Type::INT8: *((int8_t *)dest) = ply_read_ascii(is); break; + case PlyProperty::Type::UINT8: *((uint8_t *)dest) = ply_read_ascii(is); break; + case PlyProperty::Type::INT16: ply_cast_ascii(dest, is); break; + case PlyProperty::Type::UINT16: ply_cast_ascii(dest, is); break; + case PlyProperty::Type::INT32: ply_cast_ascii(dest, is); break; + case PlyProperty::Type::UINT32: ply_cast_ascii(dest, is); break; + case PlyProperty::Type::FLOAT32: ply_cast_ascii(dest, is); break; + case PlyProperty::Type::FLOAT64: ply_cast_ascii(dest, is); break; + case PlyProperty::Type::INVALID: throw std::invalid_argument("invalid ply property"); + } + destOffset += PropertyTable[t].stride; +} + +void PlyFile::write_property_ascii(PlyProperty::Type t, std::ostream & os, uint8_t * src, size_t & srcOffset) +{ + switch (t) + { + case PlyProperty::Type::INT8: os << static_cast(*reinterpret_cast(src)); break; + case PlyProperty::Type::UINT8: os << static_cast(*reinterpret_cast(src)); break; + case PlyProperty::Type::INT16: os << *reinterpret_cast(src); break; + case PlyProperty::Type::UINT16: os << *reinterpret_cast(src); break; + case PlyProperty::Type::INT32: os << *reinterpret_cast(src); break; + case PlyProperty::Type::UINT32: os << *reinterpret_cast(src); break; + case PlyProperty::Type::FLOAT32: os << *reinterpret_cast(src); break; + case PlyProperty::Type::FLOAT64: os << *reinterpret_cast(src); break; + case PlyProperty::Type::INVALID: throw std::invalid_argument("invalid ply property"); + } + os << " "; + srcOffset += PropertyTable[t].stride; +} + +void PlyFile::write_property_binary(PlyProperty::Type t, std::ostream & os, uint8_t * src, size_t & srcOffset) +{ + os.write((char *)src, PropertyTable[t].stride); + srcOffset += PropertyTable[t].stride; +} + +void PlyFile::read(std::istream & is) +{ + read_internal(is); +} + +void PlyFile::write(std::ostream & os, bool isBinary) +{ + if (isBinary) write_binary_internal(os); + else write_ascii_internal(os); +} + +void PlyFile::write_binary_internal(std::ostream & os) +{ + isBinary = true; + write_header(os); + + for (auto & e : elements) + { + for (size_t i = 0; i < e.size; ++i) + { + for (auto & p : e.properties) + { + auto & cursor = userDataTable[make_key(e.name, p.name)]; + if (p.isList) + { + uint8_t listSize[4] = {0, 0, 0, 0}; + memcpy(listSize, &p.listCount, sizeof(uint32_t)); + size_t dummyCount = 0; + write_property_binary(p.listType, os, listSize, dummyCount); + for (int j = 0; j < p.listCount; ++j) + { + write_property_binary(p.propertyType, os, (cursor->data + cursor->offset), cursor->offset); + } + } + else + { + write_property_binary(p.propertyType, os, (cursor->data + cursor->offset), cursor->offset); + } + } + } + } +} + +void PlyFile::write_ascii_internal(std::ostream & os) +{ + write_header(os); + + for (auto & e : elements) + { + for (size_t i = 0; i < e.size; ++i) + { + for (auto & p : e.properties) + { + auto & cursor = userDataTable[make_key(e.name, p.name)]; + if (p.isList) + { + os << p.listCount << " "; + for (int j = 0; j < p.listCount; ++j) + { + write_property_ascii(p.propertyType, os, (cursor->data + cursor->offset), cursor->offset); + } + } + else + { + write_property_ascii(p.propertyType, os, (cursor->data + cursor->offset), cursor->offset); + } + } + os << std::endl; + } + } +} + +void PlyFile::write_header(std::ostream & os) +{ + const std::locale & fixLoc = std::locale("C"); + os.imbue(fixLoc); + + os << "ply" << std::endl; + if (isBinary) + os << ((isBigEndian) ? "format binary_big_endian 1.0" : "format binary_little_endian 1.0") << std::endl; + else + os << "format ascii 1.0" << std::endl; + + for (const auto & comment : comments) + os << "comment " << comment << std::endl; + + for (auto & e : elements) + { + os << "element " << e.name << " " << e.size << std::endl; + for (const auto & p : e.properties) + { + if (p.isList) + { + os << "property list " << PropertyTable[p.listType].str << " " + << PropertyTable[p.propertyType].str << " " << p.name << std::endl; + } + else + { + os << "property " << PropertyTable[p.propertyType].str << " " << p.name << std::endl; + } + } + } + os << "end_header" << std::endl; +} + +void PlyFile::read_internal(std::istream & is) +{ + std::function read; + std::function skip; + if (isBinary) + { + read = [&](PlyProperty::Type t, void * dest, size_t & destOffset, std::istream & is) { read_property_binary(t, dest, destOffset, is); }; + skip = [&](const PlyProperty & property, std::istream & is) { skip_property_binary(property, is); }; + } + else + { + read = [&](PlyProperty::Type t, void * dest, size_t & destOffset, std::istream & is) { read_property_ascii(t, dest, destOffset, is); }; + skip = [&](const PlyProperty & property, std::istream & is) { skip_property_ascii(property, is); }; + } + + for (auto & element : get_elements()) + { + if (std::find(requestedElements.begin(), requestedElements.end(), element.name) != requestedElements.end()) + { + for (size_t count = 0; count < element.size; ++count) + { + for (auto & property : element.properties) + { + if (auto & cursor = userDataTable[make_key(element.name, property.name)]) + { + if (property.isList) + { + size_t listSize = 0; + size_t dummyCount = 0; + read(property.listType, &listSize, dummyCount, is); + if (cursor->realloc == false) + { + cursor->realloc = true; + resize_vector(property.propertyType, cursor->vector, listSize * element.size, cursor->data); + } + for (size_t i = 0; i < listSize; ++i) + { + read(property.propertyType, (cursor->data + cursor->offset), cursor->offset, is); + } + } + else + { + read(property.propertyType, (cursor->data + cursor->offset), cursor->offset, is); + } + } + else + { + skip(property, is); + } + } + } + } + else continue; + } +} diff --git a/Segmentator/tinyply.h b/Segmentator/tinyply.h new file mode 100644 index 0000000..4dbd436 --- /dev/null +++ b/Segmentator/tinyply.h @@ -0,0 +1,382 @@ +// This software is in the public domain. Where that dedication is not +// recognized, you are granted a perpetual, irrevocable license to copy, +// distribute, and modify this file as you see fit. +// Authored in 2015 by Dimitri Diakopoulos (http://www.dimitridiakopoulos.com) +// https://github.com/ddiakopoulos/tinyply + +#ifndef tinyply_h +#define tinyply_h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace tinyply +{ + + template T endian_swap(const T & v) { return v; } + template<> inline uint16_t endian_swap(const uint16_t & v) { return (v << 8) | (v >> 8); } + template<> inline uint32_t endian_swap(const uint32_t & v) { return (v << 24) | ((v << 8) & 0x00ff0000) | ((v >> 8) & 0x0000ff00) | (v >> 24); } + template<> inline uint64_t endian_swap(const uint64_t & v) + { + return (((v & 0x00000000000000ffLL) << 56) | + ((v & 0x000000000000ff00LL) << 40) | + ((v & 0x0000000000ff0000LL) << 24) | + ((v & 0x00000000ff000000LL) << 8) | + ((v & 0x000000ff00000000LL) >> 8) | + ((v & 0x0000ff0000000000LL) >> 24) | + ((v & 0x00ff000000000000LL) >> 40) | + ((v & 0xff00000000000000LL) >> 56)); + } + template<> inline int16_t endian_swap(const int16_t & v) { uint16_t r = endian_swap(*(uint16_t*)&v); return *(int16_t*)&r; } + template<> inline int32_t endian_swap(const int32_t & v) { uint32_t r = endian_swap(*(uint32_t*)&v); return *(int32_t*)&r; } + template<> inline int64_t endian_swap(const int64_t & v) { uint64_t r = endian_swap(*(uint64_t*)&v); return *(int64_t*)&r; } + inline float endian_swap_float(const uint32_t & v) { uint32_t r = endian_swap(v); return *(float*)&r; } + inline double endian_swap_double(const uint64_t & v) { uint64_t r = endian_swap(v); return *(double*)&r; } + + struct DataCursor + { + void * vector; + uint8_t * data; + size_t offset; + bool realloc = false; + }; + + class PlyProperty + { + void parse_internal(std::istream & is); + public: + + enum class Type : uint8_t + { + INVALID, + INT8, + UINT8, + INT16, + UINT16, + INT32, + UINT32, + FLOAT32, + FLOAT64 + }; + + PlyProperty(std::istream & is); + PlyProperty(Type type, const std::string & name) : propertyType(type), isList(false), name(name) {} + PlyProperty(Type list_type, Type prop_type, const std::string & name, int listCount) : listType(list_type), propertyType(prop_type), isList(true), name(name), listCount(listCount) {} + + Type listType, propertyType; + bool isList; + int listCount = 0; + std::string name; + }; + + inline std::string make_key(const std::string & a, const std::string & b) + { + return (a + "-" + b); + } + + template + void ply_cast(void * dest, const char * src, bool be) + { + *(static_cast(dest)) = (be) ? endian_swap(*(reinterpret_cast(src))) : *(reinterpret_cast(src)); + } + + template + void ply_cast_float(void * dest, const char * src, bool be) + { + *(static_cast(dest)) = (be) ? endian_swap_float(*(reinterpret_cast(src))) : *(reinterpret_cast(src)); + } + + template + void ply_cast_double(void * dest, const char * src, bool be) + { + *(static_cast(dest)) = (be) ? endian_swap_double(*(reinterpret_cast(src))) : *(reinterpret_cast(src)); + } + + template + T ply_read_ascii(std::istream & is) + { + T data; + is >> data; + return data; + } + + template + void ply_cast_ascii(void * dest, std::istream & is) + { + *(static_cast(dest)) = ply_read_ascii(is); + } + + struct PropertyInfo { int stride; std::string str; }; + static std::map PropertyTable + { + { PlyProperty::Type::INT8,{ 1, "char" } }, + { PlyProperty::Type::UINT8,{ 1, "uchar" } }, + { PlyProperty::Type::INT16,{ 2, "short" } }, + { PlyProperty::Type::UINT16,{ 2, "ushort" } }, + { PlyProperty::Type::INT32,{ 4, "int" } }, + { PlyProperty::Type::UINT32,{ 4, "uint" } }, + { PlyProperty::Type::FLOAT32,{ 4, "float" } }, + { PlyProperty::Type::FLOAT64,{ 8, "double" } }, + { PlyProperty::Type::INVALID,{ 0, "INVALID" } } + }; + + inline PlyProperty::Type property_type_from_string(const std::string & t) + { + if (t == "int8" || t == "char") return PlyProperty::Type::INT8; + else if (t == "uint8" || t == "uchar") return PlyProperty::Type::UINT8; + else if (t == "int16" || t == "short") return PlyProperty::Type::INT16; + else if (t == "uint16" || t == "ushort") return PlyProperty::Type::UINT16; + else if (t == "int32" || t == "int") return PlyProperty::Type::INT32; + else if (t == "uint32" || t == "uint") return PlyProperty::Type::UINT32; + else if (t == "float32" || t == "float") return PlyProperty::Type::FLOAT32; + else if (t == "float64" || t == "double") return PlyProperty::Type::FLOAT64; + return PlyProperty::Type::INVALID; + } + + template + inline uint8_t * resize(void * v, size_t newSize) + { + auto vec = static_cast *>(v); + vec->resize(newSize); + return reinterpret_cast(vec->data()); + } + + inline void resize_vector(const PlyProperty::Type t, void * v, size_t newSize, uint8_t *& ptr) + { + switch (t) + { + case PlyProperty::Type::INT8: ptr = resize(v, newSize); break; + case PlyProperty::Type::UINT8: ptr = resize(v, newSize); break; + case PlyProperty::Type::INT16: ptr = resize(v, newSize); break; + case PlyProperty::Type::UINT16: ptr = resize(v, newSize); break; + case PlyProperty::Type::INT32: ptr = resize(v, newSize); break; + case PlyProperty::Type::UINT32: ptr = resize(v, newSize); break; + case PlyProperty::Type::FLOAT32: ptr = resize(v, newSize); break; + case PlyProperty::Type::FLOAT64: ptr = resize(v, newSize); break; + case PlyProperty::Type::INVALID: throw std::invalid_argument("invalid ply property"); + } + } + + template + inline PlyProperty::Type property_type_for_type(std::vector & theType) + { + if (std::is_same::value) return PlyProperty::Type::INT8; + else if (std::is_same::value) return PlyProperty::Type::UINT8; + else if (std::is_same::value) return PlyProperty::Type::INT16; + else if (std::is_same::value) return PlyProperty::Type::UINT16; + else if (std::is_same::value) return PlyProperty::Type::INT32; + else if (std::is_same::value) return PlyProperty::Type::UINT32; + else if (std::is_same::value) return PlyProperty::Type::FLOAT32; + else if (std::is_same::value) return PlyProperty::Type::FLOAT64; + else return PlyProperty::Type::INVALID; + } + + class PlyElement + { + void parse_internal(std::istream & is); + public: + PlyElement(std::istream & istream); + PlyElement(const std::string & name, size_t count) : name(name), size(count) {} + std::string name; + size_t size; + std::vector properties; + }; + + inline int find_element(const std::string key, std::vector & list) + { + for (size_t i = 0; i < list.size(); ++i) + { + if (list[i].name == key) + { + return i; + } + } + return -1; + } + + class PlyFile + { + + public: + + PlyFile() {} + PlyFile(std::istream & is); + + void read(std::istream & is); + void write(std::ostream & os, bool isBinary); + + std::vector & get_elements() { return elements; } + + std::vector comments; + std::vector objInfo; + + template + size_t request_properties_from_element(const std::string & elementKey, std::vector propertyKeys, std::vector & source, const int listCount = 1) + { + if (get_elements().size() == 0) + return 0; + + if (find_element(elementKey, get_elements()) >= 0) + { + if (std::find(requestedElements.begin(), requestedElements.end(), elementKey) == requestedElements.end()) + requestedElements.push_back(elementKey); + } + else return 0; + + // count and verify large enough + auto instance_counter = [&](const std::string & elementKey, const std::string & propertyKey) + { + for (auto e : get_elements()) + { + if (e.name != elementKey) continue; + for (auto p : e.properties) + { + if (p.name == propertyKey) + { + if (PropertyTable[property_type_for_type(source)].stride != PropertyTable[p.propertyType].stride) + throw std::runtime_error("destination vector is wrongly typed to hold this property"); + return e.size; + + } + } + } + return size_t(0); + }; + + // Check if requested key is in the parsed header + std::vector unusedKeys; + for (auto key : propertyKeys) + { + for (auto e : get_elements()) + { + if (e.name != elementKey) continue; + std::vector headerKeys; + for (auto p : e.properties) + { + headerKeys.push_back(p.name); + } + + if (std::find(headerKeys.begin(), headerKeys.end(), key) == headerKeys.end()) + { + unusedKeys.push_back(key); + } + + } + } + + // Not using them? Don't let them affect the propertyKeys count used for calculating array sizes + for (auto k : unusedKeys) + { + propertyKeys.erase(std::remove(propertyKeys.begin(), propertyKeys.end(), k), propertyKeys.end()); + } + if (!propertyKeys.size()) return 0; + + // All requested properties in the userDataTable share the same cursor (thrown into the same flat array) + auto cursor = std::make_shared(); + + std::vector instanceCounts; + + for (auto key : propertyKeys) + { + if (int instanceCount = instance_counter(elementKey, key)) + { + instanceCounts.push_back(instanceCount); + auto result = userDataTable.insert(std::pair>(make_key(elementKey, key), cursor)); + if (result.second == false) + throw std::invalid_argument("property has already been requested: " + key); + } + else continue; + } + + size_t totalInstanceSize = [&]() { size_t t = 0; for (auto c : instanceCounts) { t += c; } return t; }() * listCount; + source.resize(totalInstanceSize); // this satisfies regular properties; `cursor->realloc` is for list types since tinyply uses single-pass parsing + cursor->offset = 0; + cursor->vector = &source; + cursor->data = reinterpret_cast(source.data()); + + if (listCount > 1) + { + cursor->realloc = true; + return (totalInstanceSize / propertyKeys.size()) / listCount; + } + + return totalInstanceSize / propertyKeys.size(); + } + + template + void add_properties_to_element(const std::string & elementKey, const std::vector & propertyKeys, std::vector & source, const int listCount = 1, const PlyProperty::Type listType = PlyProperty::Type::INVALID) + { + auto cursor = std::make_shared(); + cursor->offset = 0; + cursor->vector = &source; + cursor->data = reinterpret_cast(source.data()); + + auto create_property_on_element = [&](PlyElement & e) + { + for (auto key : propertyKeys) + { + PlyProperty::Type t = property_type_for_type(source); + PlyProperty newProp = (listType == PlyProperty::Type::INVALID) ? PlyProperty(t, key) : PlyProperty(listType, t, key, listCount); + userDataTable.insert(std::pair>(make_key(e.name, key), cursor)); + e.properties.push_back(newProp); + } + }; + + int idx = find_element(elementKey, elements); + if (idx >= 0) + { + PlyElement & e = elements[idx]; + create_property_on_element(e); + } + else + { + PlyElement newElement = (listCount == 1) ? PlyElement(elementKey, source.size() / propertyKeys.size()) : PlyElement(elementKey, source.size() / listCount); + create_property_on_element(newElement); + elements.push_back(newElement); + } + } + + private: + + size_t skip_property_binary(const PlyProperty & property, std::istream & is); + void skip_property_ascii(const PlyProperty & property, std::istream & is); + + void read_property_binary(PlyProperty::Type t, void * dest, size_t & destOffset, std::istream & is); + void read_property_ascii(PlyProperty::Type t, void * dest, size_t & destOffset, std::istream & is); + void write_property_ascii(PlyProperty::Type t, std::ostream & os, uint8_t * src, size_t & srcOffset); + void write_property_binary(PlyProperty::Type t, std::ostream & os, uint8_t * src, size_t & srcOffset); + + bool parse_header(std::istream & is); + void write_header(std::ostream & os); + + void read_header_format(std::istream & is); + void read_header_element(std::istream & is); + void read_header_property(std::istream & is); + void read_header_text(std::string line, std::istream & is, std::vector & place, int erase = 0); + + void read_internal(std::istream & is); + + void write_ascii_internal(std::ostream & os); + void write_binary_internal(std::ostream & os); + + bool isBinary = false; + bool isBigEndian = false; + + std::map> userDataTable; + + std::vector elements; + std::vector requestedElements; + }; + +} // namesapce tinyply + +#endif // tinyply_h diff --git a/SensReader/README.md b/SensReader/README.md new file mode 100644 index 0000000..b6835b1 --- /dev/null +++ b/SensReader/README.md @@ -0,0 +1,39 @@ +# Sens File Format (see [sensorData.h](c++/src/sensorData.h)): +``` +struct SensorData { + unsigned int m_versionNumber; + std::string m_sensorName; + + CalibrationData m_calibrationColor; //4x4 intrinsic matrix + CalibrationData m_calibrationDepth; //4x4 intrinsic matrix + + COMPRESSION_TYPE_COLOR m_colorCompressionType; //scannet color frames are typically jpeg encoded + COMPRESSION_TYPE_DEPTH m_depthCompressionType; //scannet depth frames are typically zLib encoded + + unsigned int m_colorWidth; + unsigned int m_colorHeight; + unsigned int m_depthWidth; + unsigned int m_depthHeight; + float m_depthShift; //conversion from float[m] to ushort (typically 1000.0f) + + std::vector m_frames; // <= Main data (contains timestamps and rigid transforms) + std::vector m_IMUFrames; +} + +// example get color frame, depth frame, pose (camera to world) +SensorData sd("sensfile.sens"); +unsigned int frame = 0; +vec3uc* color = sd.decompressColorAlloc(frame); // note: must be freed after use +unsigned short* depth = sd.decompressDepthAlloc(frame); // note: must be freed after use +const mat4f cameraToWorld = sd.m_frames[frame].getCameraToWorld(); +std::free(color); +std::free(depth); +// if using mlib, can save a frame to a point cloud with: +sd.saveToPointCloud("frame" + std::to_string(frame) + ".ply", frame); +``` + +## C++ ToolKit +See [c++/](c++) + +## Simple Python Data Exporter +See [python/](python) diff --git a/SensReader/Makefile b/SensReader/c++/Makefile similarity index 100% rename from SensReader/Makefile rename to SensReader/c++/Makefile diff --git a/SensReader/README.txt b/SensReader/c++/README.txt similarity index 77% rename from SensReader/README.txt rename to SensReader/c++/README.txt index 0a82e54..906db83 100644 --- a/SensReader/README.txt +++ b/SensReader/c++/README.txt @@ -6,10 +6,13 @@ Example to decode .sens files: - metadata output in _info.txt (includes intrinsics, etc.) - IMU data is not saved out (it's stored in m_IMUFrames) -run ./sens +Run: +./sens Hint: keep the sens files as they are a nice represention see processFrame(..) to decode independent frames + +For additional functionality (vector/matrix/point cloud classes, etc), include the mLib library: https://github.com/niessner/mLib. - tested under Windows10 VS2013 - tested 14.04.1-Ubuntu: g++ and clang @@ -46,4 +49,9 @@ Useful functions in sensorData.h: unsigned short* d = sd.decompressDepthAlloc(frameIdx); IMUFrame f = sd.findClosestIMUFrame(frameIdx); mat4f pose = sd.m_frames[frameIdx].getCameraToWorld(); - \ No newline at end of file + +================================================================ +Notes: + The invalid poses are marked with -inf values. They are result of lost tracking. + Subsequen poses can be trusted, as they are result of global alignment in + BundleFusion[Dai et al.] algorithm. diff --git a/SensReader/sens.sln b/SensReader/c++/sens.sln similarity index 100% rename from SensReader/sens.sln rename to SensReader/c++/sens.sln diff --git a/SensReader/sens.vcxproj b/SensReader/c++/sens.vcxproj similarity index 100% rename from SensReader/sens.vcxproj rename to SensReader/c++/sens.vcxproj diff --git a/SensReader/sens.vcxproj.filters b/SensReader/c++/sens.vcxproj.filters similarity index 100% rename from SensReader/sens.vcxproj.filters rename to SensReader/c++/sens.vcxproj.filters diff --git a/SensReader/src/main.cpp b/SensReader/c++/src/main.cpp similarity index 100% rename from SensReader/src/main.cpp rename to SensReader/c++/src/main.cpp diff --git a/SensReader/src/sensorData.h b/SensReader/c++/src/sensorData.h similarity index 100% rename from SensReader/src/sensorData.h rename to SensReader/c++/src/sensorData.h diff --git a/SensReader/src/sensorData/stb_image.h b/SensReader/c++/src/sensorData/stb_image.h similarity index 100% rename from SensReader/src/sensorData/stb_image.h rename to SensReader/c++/src/sensorData/stb_image.h diff --git a/SensReader/src/sensorData/stb_image_write.h b/SensReader/c++/src/sensorData/stb_image_write.h similarity index 100% rename from SensReader/src/sensorData/stb_image_write.h rename to SensReader/c++/src/sensorData/stb_image_write.h diff --git a/SensReader/python/README.md b/SensReader/python/README.md new file mode 100644 index 0000000..60da5a8 --- /dev/null +++ b/SensReader/python/README.md @@ -0,0 +1,13 @@ +# Data Exporter + +Developed and tested with python 2.7. + +Usage: +``` +python reader.py --filename [.sens file to export data from] --output_path [output directory to export data to] +Options: +--export_depth_images: export all depth frames as 16-bit pngs (depth shift 1000) +--export_color_images: export all color frames as 8-bit rgb jpgs +--export_poses: export all camera poses (4x4 matrix, camera to world) +--export_intrinsics: export camera intrinsics (4x4 matrix) +``` diff --git a/SensReader/python/SensorData.py b/SensReader/python/SensorData.py new file mode 100644 index 0000000..16215ca --- /dev/null +++ b/SensReader/python/SensorData.py @@ -0,0 +1,125 @@ + +import os, struct +import numpy as np +import zlib +import imageio +import cv2 +import png + +COMPRESSION_TYPE_COLOR = {-1:'unknown', 0:'raw', 1:'png', 2:'jpeg'} +COMPRESSION_TYPE_DEPTH = {-1:'unknown', 0:'raw_ushort', 1:'zlib_ushort', 2:'occi_ushort'} + +class RGBDFrame(): + + def load(self, file_handle): + self.camera_to_world = np.asarray(struct.unpack('f'*16, file_handle.read(16*4)), dtype=np.float32).reshape(4, 4) + self.timestamp_color = struct.unpack('Q', file_handle.read(8))[0] + self.timestamp_depth = struct.unpack('Q', file_handle.read(8))[0] + self.color_size_bytes = struct.unpack('Q', file_handle.read(8))[0] + self.depth_size_bytes = struct.unpack('Q', file_handle.read(8))[0] + self.color_data = ''.join(struct.unpack('c'*self.color_size_bytes, file_handle.read(self.color_size_bytes))) + self.depth_data = ''.join(struct.unpack('c'*self.depth_size_bytes, file_handle.read(self.depth_size_bytes))) + + + def decompress_depth(self, compression_type): + if compression_type == 'zlib_ushort': + return self.decompress_depth_zlib() + else: + raise + + + def decompress_depth_zlib(self): + return zlib.decompress(self.depth_data) + + + def decompress_color(self, compression_type): + if compression_type == 'jpeg': + return self.decompress_color_jpeg() + else: + raise + + + def decompress_color_jpeg(self): + return imageio.imread(self.color_data) + + +class SensorData: + + def __init__(self, filename): + self.version = 4 + self.load(filename) + + + def load(self, filename): + with open(filename, 'rb') as f: + version = struct.unpack('I', f.read(4))[0] + assert self.version == version + strlen = struct.unpack('Q', f.read(8))[0] + self.sensor_name = ''.join(struct.unpack('c'*strlen, f.read(strlen))) + self.intrinsic_color = np.asarray(struct.unpack('f'*16, f.read(16*4)), dtype=np.float32).reshape(4, 4) + self.extrinsic_color = np.asarray(struct.unpack('f'*16, f.read(16*4)), dtype=np.float32).reshape(4, 4) + self.intrinsic_depth = np.asarray(struct.unpack('f'*16, f.read(16*4)), dtype=np.float32).reshape(4, 4) + self.extrinsic_depth = np.asarray(struct.unpack('f'*16, f.read(16*4)), dtype=np.float32).reshape(4, 4) + self.color_compression_type = COMPRESSION_TYPE_COLOR[struct.unpack('i', f.read(4))[0]] + self.depth_compression_type = COMPRESSION_TYPE_DEPTH[struct.unpack('i', f.read(4))[0]] + self.color_width = struct.unpack('I', f.read(4))[0] + self.color_height = struct.unpack('I', f.read(4))[0] + self.depth_width = struct.unpack('I', f.read(4))[0] + self.depth_height = struct.unpack('I', f.read(4))[0] + self.depth_shift = struct.unpack('f', f.read(4))[0] + num_frames = struct.unpack('Q', f.read(8))[0] + self.frames = [] + for i in range(num_frames): + frame = RGBDFrame() + frame.load(f) + self.frames.append(frame) + + + def export_depth_images(self, output_path, image_size=None, frame_skip=1): + if not os.path.exists(output_path): + os.makedirs(output_path) + print 'exporting', len(self.frames)//frame_skip, ' depth frames to', output_path + for f in range(0, len(self.frames), frame_skip): + depth_data = self.frames[f].decompress_depth(self.depth_compression_type) + depth = np.fromstring(depth_data, dtype=np.uint16).reshape(self.depth_height, self.depth_width) + if image_size is not None: + depth = cv2.resize(depth, (image_size[1], image_size[0]), interpolation=cv2.INTER_NEAREST) + #imageio.imwrite(os.path.join(output_path, str(f) + '.png'), depth) + with open(os.path.join(output_path, str(f) + '.png'), 'wb') as f: # write 16-bit + writer = png.Writer(width=depth.shape[1], height=depth.shape[0], bitdepth=16) + depth = depth.reshape(-1, depth.shape[1]).tolist() + writer.write(f, depth) + + def export_color_images(self, output_path, image_size=None, frame_skip=1): + if not os.path.exists(output_path): + os.makedirs(output_path) + print 'exporting', len(self.frames)//frame_skip, 'color frames to', output_path + for f in range(0, len(self.frames), frame_skip): + color = self.frames[f].decompress_color(self.color_compression_type) + if image_size is not None: + color = cv2.resize(color, (image_size[1], image_size[0]), interpolation=cv2.INTER_NEAREST) + imageio.imwrite(os.path.join(output_path, str(f) + '.jpg'), color) + + + def save_mat_to_file(self, matrix, filename): + with open(filename, 'w') as f: + for line in matrix: + np.savetxt(f, line[np.newaxis], fmt='%f') + + + def export_poses(self, output_path, frame_skip=1): + if not os.path.exists(output_path): + os.makedirs(output_path) + print 'exporting', len(self.frames)//frame_skip, 'camera poses to', output_path + for f in range(0, len(self.frames), frame_skip): + self.save_mat_to_file(self.frames[f].camera_to_world, os.path.join(output_path, str(f) + '.txt')) + + + def export_intrinsics(self, output_path): + if not os.path.exists(output_path): + os.makedirs(output_path) + print 'exporting camera intrinsics to', output_path + self.save_mat_to_file(self.intrinsic_color, os.path.join(output_path, 'intrinsic_color.txt')) + self.save_mat_to_file(self.extrinsic_color, os.path.join(output_path, 'extrinsic_color.txt')) + self.save_mat_to_file(self.intrinsic_depth, os.path.join(output_path, 'intrinsic_depth.txt')) + self.save_mat_to_file(self.extrinsic_depth, os.path.join(output_path, 'extrinsic_depth.txt')) diff --git a/SensReader/python/reader.py b/SensReader/python/reader.py new file mode 100644 index 0000000..f419fba --- /dev/null +++ b/SensReader/python/reader.py @@ -0,0 +1,39 @@ +import argparse +import os, sys + +from SensorData import SensorData + +# params +parser = argparse.ArgumentParser() +# data paths +parser.add_argument('--filename', required=True, help='path to sens file to read') +parser.add_argument('--output_path', required=True, help='path to output folder') +parser.add_argument('--export_depth_images', dest='export_depth_images', action='store_true') +parser.add_argument('--export_color_images', dest='export_color_images', action='store_true') +parser.add_argument('--export_poses', dest='export_poses', action='store_true') +parser.add_argument('--export_intrinsics', dest='export_intrinsics', action='store_true') +parser.set_defaults(export_depth_images=False, export_color_images=False, export_poses=False, export_intrinsics=False) + +opt = parser.parse_args() +print(opt) + + +def main(): + if not os.path.exists(opt.output_path): + os.makedirs(opt.output_path) + # load the data + sys.stdout.write('loading %s...' % opt.filename) + sd = SensorData(opt.filename) + sys.stdout.write('loaded!\n') + if opt.export_depth_images: + sd.export_depth_images(os.path.join(opt.output_path, 'depth')) + if opt.export_color_images: + sd.export_color_images(os.path.join(opt.output_path, 'color')) + if opt.export_poses: + sd.export_poses(os.path.join(opt.output_path, 'pose')) + if opt.export_intrinsics: + sd.export_intrinsics(os.path.join(opt.output_path, 'intrinsic')) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/Server/.gitignore b/Server/.gitignore new file mode 100644 index 0000000..6e9ec1f --- /dev/null +++ b/Server/.gitignore @@ -0,0 +1,11 @@ +*.iml + +# virtualenv +bin/ +include/ +lib/ +local/ +.Python + +# python +*.pyc diff --git a/Server/README.md b/Server/README.md new file mode 100644 index 0000000..32f6723 --- /dev/null +++ b/Server/README.md @@ -0,0 +1,49 @@ +# ScanNet Data Server + +The ScanNet server is broken down into the following components: + +1. Upload process used by the iPad to upload the scan and trigger scan processing. To ensure that scans can be automatically processed, the scans should be placed in a directory with lots of space and accessible to the scanning processor. Tested on Ubuntu 14.04 Linux machine. +2. Scan processing scripts. Require a Windows machine with high-end GPU (tested on Windows 10 with GTX Titan X with 12GB of VRAM). +3. Indexing scripts. Go through scan folders and collate information about the scans. + +## Upload scripts + +The upload script receives scan files (`.h264`, `.depth`, `.imu`, `.txt`, `.camera`) from the iPad and stores them in a staging area for scan processing. The files are first placed in the `tmp` directory before being moved into the staging directory. Uses [flask](http://flask.pocoo.org/) with [gunicorn](http://gunicorn.org/) with 10 worker threads on port 8000. + +- `install_deps.sh` - Run this to install python dependencies required for the upload server +- `start_upload_server.sh` - Run this to start the upload server. The main entry point is at `upload.py` (started automatically by this `.sh` script) +- `wsgi.py` - Web service wrapper for `upload.py` + +## Scan processing scripts + +The scan processing requires a Windows machine with high-end GPU (tested on Titan X 12GB). It also relies on these third party tools: +- [MeshLab](http://meshlab.sourceforge.net/) for mesh simplification and processing +- [Mitsuba renderer](http://www.mitsuba-renderer.org) for generating preview images for each scan +- [ImageMagick](http://www.imagemagick.org/), [pngquant](https://pngquant.org), and [optipng](http://optipng.sourceforge.net) for thumbnail generation + +TODO: Also have a brief list of our binaries that are needed and pointers to their repository locations + +- `start_process_server.py` - Starts the scan processing server. The main entry point is at `process.py`. Running this starts the upload server on port 5000, simple flask server that only handles one request at a time (will block until scan is processed). +- `scan_processor.py` - Main scan processing script. Edit to see/change path for tools/applications. +- `mts_render.py` - Script to render preview images of scans (ply -> png). Depends on a Mitsuba renderer installation. +- `thumbnail.sh` - Script for generating thumbnails from rendered views + +## Indexing scripts + +Indexing scripts are used to collate information about the scans and index them. +- `monitor.py` - Web service entry point for monitoring and triggering of indexing of scans. Run `python monitor.py` to start the monitor server on port 5001 (simple flask server). +- `index.py` - Creates index of scans in a directory and outputs a csv file +- `scripts/index_scannet.sh` - Index both staging and checked scans and updates WebUI db + +## Statistics computation scripts + +- `compute_annotation_stats.py` - Compute aggregated annotation statistics +- `compute_timings.py` - Compute processing times for scans +- `scripts/combine_stats.py` - Combines statistics with index + + +## Configuration files + +- `scannet.json` - Metadata for ScanNet assets for use with the Scene Toolkit viewer +- `scan_stages.json` - The stages of the scan pipeline (so we can track progress) +- `upload.ini` - Configuration file for upload server diff --git a/Server/compute_annotation_stats.py b/Server/compute_annotation_stats.py new file mode 100755 index 0000000..d9579a8 --- /dev/null +++ b/Server/compute_annotation_stats.py @@ -0,0 +1,271 @@ +#!/usr/bin/env python +# +# Compute aggregated annotation statistics + +import argparse +import collections +import copy +import csv +import json +import sys +import os +import logging +import traceback + +import util + +# logger +FORMAT = '%(asctime)-15s [%(levelname)s] %(message)s' +logging.basicConfig(format=FORMAT) +log = logging.getLogger('compute_annotation_stats') +log.setLevel(logging.INFO) + + +SEGS_FILE = "${name}_vh_clean_2.0.010000.segs.json" +ANNS_FILE = "${name}.aggregation.json" + + +def computeStatistics(json, allLabels=None, allCategories=None): + # 'annotatedVertices': 0, + # 'unannotatedVertices': 0, + # 'annotatedSegments': 0, + # 'unannotatedSegments': 0, + # 'totalSegments': 0, + # 'totalVertices': 0, + # 'percentComplete': 0 + # 'objects': 0 + # 'labels': 0 + vertToSeg = json.get('segIndices') # Mapping of vertex to segment index + segToVerts = {} + for vert, seg in enumerate(vertToSeg): + if seg in segToVerts: + segToVerts[seg].append(vert) + else: + segToVerts[seg] = [vert] + segGroups = json.get('segGroups') # Array of segment groups + stats = collections.Counter({ + 'totalVertices': len(vertToSeg), + 'totalSegments': len(segToVerts), + 'annotatedVertices': 0, + 'annotatedSegments': 0, + 'segmentGroups': len(segGroups) + }) + labels = collections.Counter() + categories = collections.Counter() + objectIds = collections.Counter() + labeledObjectIds = collections.Counter() + annSegs = collections.Counter() + for segGroup in segGroups: + segments = segGroup.get('segments') + label = segGroup.get('label') + if label != 'unknown' and label != '': + annSegs.update(segments) + labels.update({segGroup.get('label'): 1}) + labeledObjectIds.update({segGroup.get('objectId'): 1}) + lparts = label.split(':') + category = lparts[0] + categories.update({category: 1}) + objectIds.update({segGroup.get('objectId'): 1}) + if allLabels is not None: + allLabels.update(labels) + if allCategories is not None: + allCategories.update(categories) + stats.update({'annotatedSegments': len(annSegs)}) + for seg in list(annSegs): + if seg in segToVerts: + stats.update({'annotatedVertices': len(segToVerts[seg])}) + stats.update({ + 'unannotatedVertices': len(vertToSeg) - stats.get('annotatedVertices'), + 'unannotatedSegments': len(segToVerts) - stats.get('annotatedSegments'), + 'objects': len(objectIds), + 'labeledObjects': len(labeledObjectIds), + 'labels': len(labels), + 'categories': len(categories), + 'percentObjectLabeled': 100*len(labeledObjectIds)/len(objectIds) if len(objectIds) > 0 else 0, + 'percentComplete': 100*stats.get('annotatedVertices')/stats.get('totalVertices') if stats.get('totalVertices') > 0 else 0 + }) + return stats + + +def loadAnnotations(segmentsFilename, annotationFilename): + with open(segmentsFilename) as segmentsFile: + segments = json.load(segmentsFile) + segmentGroups = {'segGroups': []} + if util.is_non_zero_file(annotationFilename): + try: + with open(annotationFilename) as annotationFile: + segmentGroups = json.load(annotationFile) + except: + log.error('Error loading annotation file ' + annotationFilename) + traceback.print_exc() + # merge the two + merged = segments.copy() + merged.update(segmentGroups) + return merged + + +def loadAllAnnotations(annotationFilename): + with open(annotationFilename) as annotationFile: + annotations = json.load(annotationFile) + annotationsByModel = {} + for ann in annotations: + modelId = ann.get('modelId') + if modelId in annotationsByModel: + annotationsByModel[modelId].append(ann) + else: + annotationsByModel[modelId] = [ann] + return annotationsByModel + + +def convertAnnotations(annsByModel): + m = {} + copyFields = ['workerId', 'annId', 'objectId', 'label', 'id'] + for modelId,anns in annsByModel.iteritems(): + segGroups = [] + for ann in anns: + sg = copy.copy(ann.get('segments')) + for f in copyFields: + sg[f] = ann.get(f) + segGroups.append(sg) + parts = modelId.split('.') + m[parts[1]] = { + 'sceneId': modelId, + 'segGroups': segGroups + } + return m + + +def loadSegmentsAndCombineAnnotations(segmentsFilename, segmentGroups=None): + with open(segmentsFilename) as segmentsFile: + #print 'Reading ' + segmentsFilename + segments = json.load(segmentsFile) + if segmentGroups is None: + segmentGroups = {'segGroups': []} + # merge the two + merged = segments.copy() + merged.update(segmentGroups) + return merged + + +def saveCsv(data, csvfile): + # Index and output + keys = data[0].keys() + keys.sort() + keys.remove('id') + fieldnames = ['id'] + fieldnames.extend(keys) + writer = csv.DictWriter(csvfile, fieldnames=fieldnames, extrasaction='ignore') + writer.writeheader() + for v in data: + writer.writerow(v) + + +def saveJson(data, file): + json.dump(data, file, indent=1, separators=(',', ': ')) + + +def saveOutput(format, data, file): + if format == 'json': + saveJson(data, file) + else: + saveCsv(data, file) + + +def saveCounts(data, file): + writer = csv.writer(file) + writer.writerow(['label','count']) + for label,count in data.most_common(): + writer.writerow([label,str(count)]) + + +# Process directory with annotations +def processDir(args): + dirname = args.get('input') + allLabels = collections.Counter() + allCategories = collections.Counter() + allStats = [] + for root, dirs, files in os.walk(dirname): + for name in dirs: + dir = os.path.join(root, name) + segsFile = os.path.join(dir, SEGS_FILE.replace("${name}", name)) + annsFile = os.path.join(dir, ANNS_FILE.replace("${name}", name)) + # log.info('segsFile=%s,annsFile=%s', segsFile, annsFile) + if util.is_non_zero_file(segsFile): + anns = loadAnnotations(segsFile, annsFile) + stats = computeStatistics(anns, allLabels, allCategories) + entry = {'id': name} + entry.update(stats) + allStats.append(entry) + #print json.dumps(entry) + labelsFile = args.get('labels') + if labelsFile is not None: + with open(labelsFile, 'wb') as labelsOut: + saveCounts(allLabels, labelsOut) + categoriesFile = args.get('categories') + if categoriesFile is not None: + with open(categoriesFile, 'wb') as categoriesOut: + saveCounts(allCategories, categoriesOut) + if len(allStats) > 0: + if args.get('output'): + with open(args.get('output'), 'wb') as outfile: + saveOutput(args.get('format'), allStats, outfile) + else: + saveOutput(args.get('format'), allStats, sys.stdout) + sys.stdout.flush() + + +def processFile(args): + # File of annotations + annsFilename = args.get('annotations') + # Directory of segmentations + dirname = args.get('input') + + rawAnnsByModel = loadAllAnnotations(annsFilename) + annsByModel = convertAnnotations(rawAnnsByModel) + allStats = [] + # Compute percentage of annotations + for root, dirs, files in os.walk(dirname): + for name in dirs: + dir = os.path.join(root, name) + segsFile = os.path.join(dir, SEGS_FILE.replace("${name}", name)) + if util.is_non_zero_file(segsFile): + try: + anns = loadSegmentsAndCombineAnnotations(segsFile, annsByModel.get(name)) + stats = computeStatistics(anns) + entry = {'id': name} + entry.update(stats) + allStats.append(entry) + # print json.dumps(entry) + except: + log.error('Invalid segmentation file for ' + name) + traceback.print_exc() + else: + log.warn('No segmentation file for ' + name) + if len(allStats) > 0: + if args.get('output'): + with open(args.get('output'), 'wb') as outfile: + saveOutput(args.get('format'), allStats, outfile) + else: + saveOutput(args.get('format'), allStats, sys.stdout) + sys.stdout.flush() + + +def main(): + parser = argparse.ArgumentParser(description='Compute annotation statistics!') + parser.add_argument('input', help='Directory with annotation json') + parser.add_argument('-a', '--annotations', dest='annotations', + help='Json file with all annotations', action='store') + parser.add_argument('--labels', dest='labels', help='Output labels', action='store') + parser.add_argument('--categories', dest='categories', help='Output categories', action='store') + parser.add_argument('-f', '--format', dest='format', default='csv', + help='Output format', choices=['json', 'csv'], action='store') + parser.add_argument('output', nargs='?') + args = parser.parse_args() + if args.annotations is not None: + processFile(vars(args)) + else: + processDir(vars(args)) + + +if __name__ == "__main__": + main() diff --git a/Server/compute_timings.py b/Server/compute_timings.py new file mode 100755 index 0000000..aa024c5 --- /dev/null +++ b/Server/compute_timings.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# +# Compute times from process.log +# May need pip install pytimeparse + +import argparse +import collections +import csv +import os +import logging +import re +import subprocess +import sys +import traceback + +from datetime import timedelta +import pytimeparse + +FORMAT = '%(asctime)-15s [%(levelname)s] %(message)s' +logging.basicConfig(format=FORMAT) +log = logging.getLogger('computeTimings') +log.setLevel(logging.INFO) + + +def getTotal(times): + secs = 0 + for k, r in times.iteritems(): + secs += r.get('secs') + return {'name': 'total', 'time': str(timedelta(seconds=secs)), 'secs': secs} + + +def getRecord(times, name, n=None): + if n is not None: + secs = 0 + for i in range(1, n+1): + r = times.get('%s%d' % (name, i)) + if r is not None: + secs += r.get('secs') + return {'name': name, 'time': str(timedelta(seconds=secs)), 'secs': secs} + else: + return times.get(name) + + +def computeTimings(input): + try: + timings = subprocess.check_output("grep 'Time' \"%s\"" % input, shell=True) + timings = [t.strip() for t in timings.splitlines() if len(t.strip()) > 0] + except subprocess.CalledProcessError as e: + if e.returncode != 1: + log.warning('Error extracting timings from %s', input) + traceback.print_exc() + return None + except: + log.warning('Error extracting timings from %s', input) + traceback.print_exc() + return None + + timePattern = re.compile('.*Time=([0-9.:]+)\s+for\s+(.*)') + times = collections.OrderedDict() + for timing in timings: + # print timing + m = timePattern.match(timing) + if m is not None: + time = m.group(1) + cmd = m.group(2) + if cmd.startswith('cmd'): + cmdname = None + else: + pieces = cmd.split(', ') + cmdname = pieces[0] + cmd = pieces[1] + if cmdname is not None: + times[cmdname] = {'name': cmdname, 'time': time, 'secs': pytimeparse.parse(time)} + else: + log.warn('Error extracting time from %s', timing) + return times + + +def saveCsv(fieldnames, data, csvfile): + writer = csv.DictWriter(csvfile, fieldnames=fieldnames, extrasaction='ignore') + writer.writeheader() + for k, v in data.iteritems(): + writer.writerow(v) + + +def computeAndOutputTimings(args): + input = args.get('inputfile') + times = computeTimings(input) + if times is not None: + fieldnames = ['name', 'time', 'secs'] + if args.get('output'): + with open(args.get('output'), 'wb') as outfile: + saveCsv(fieldnames, times, outfile) + else: + saveCsv(fieldnames, times, sys.stdout) + sys.stdout.flush() + + +def main(): + scriptpath = os.path.dirname(os.path.realpath(__file__)) + # Argument processing + parser = argparse.ArgumentParser(description='Compute timings for processing of a scan') + parser.add_argument('input', help='Input directory or log') + parser.add_argument('output', nargs='?') + + args = parser.parse_args() + if os.path.isdir(args.input): + args.inputfile = os.path.join(args.input, 'process.log') + elif os.path.isfile(args.input): + args.inputfile = args.input + else: + log.error('Not a directory or file: %s', args.input) + computeAndOutputTimings(vars(args)) + + +if __name__ == "__main__": main() diff --git a/Server/config.py b/Server/config.py new file mode 100644 index 0000000..9686f70 --- /dev/null +++ b/Server/config.py @@ -0,0 +1,24 @@ +import os +import util + +# Server configuration +DATA_SERVER = 'http://localhost:3030' +TEMP_FOLDER = 'tmp' +STAGING_FOLDER = 'staging' +AUTOPROCESS = False + +# General paths to binaries +SCRIPT_DIR = util.getScriptPath() +SOURCE_DIR = os.path.join(SCRIPT_DIR, '..') + +# System specific paths for processing server binaries +# TODO these need to be abstracted or refactored +GIT_BASH = 'C:\\Program Files\\Git\\bin\\bash.exe' +TOOLS_DIR = 'C:\\tools' +DATA_DIR = 'E:\\share\\data\\scan-net\\' +MESHLAB_BIN = 'C:\\Program Files\\VCG\\MeshLab\\meshlabserver.exe' +FREESPACE_BIN = 'C:\\code\\scanner-ipad\\FreeSpace\\x64\\Release\\FreeSpace.exe' # exe to call for computing occupancy grids +IMG_MAGIC_DIR = 'C:\\Program Files\\ImageMagick-7.0.2-Q16' + +# where scan data is stored under as subdirs with unique ids +STAGING_FOLDER_LOCAL = os.path.join(DATA_DIR, 'scans', 'staging') diff --git a/Server/config/scan_stages.json b/Server/config/scan_stages.json new file mode 100644 index 0000000..d3dcec9 --- /dev/null +++ b/Server/config/scan_stages.json @@ -0,0 +1,70 @@ +{ + "stages": [ + { + "name": "upload", + "output": [ "${id}.h264", "${id}.txt", "${id}.depth", "${id}.imu" ], + "optional": true + }, + { + "name": "convert", + "input": [ "${id}.h264", "${id}.txt", "${id}.depth", "${id}.imu" ], + "output": [ "${id}.uncalibrated.sens", "${id}.sens" ], + "outputCheck": "any" + }, + { + "name": "calibrate", + "input": [ "${id}.uncalibrated.sens" ], + "output": [ "${id}.sens" ] + }, + { + "name": "recons", + "input": [ "${id}.sens" ], + "output": [ "${id}.ply" ], + "checks": { "valid": "true" } + }, + { + "name": "clean", + "substeps": 2, + "input": [ "${id}.ply" ], + "output": [ "${id}.ply" ], + "checks": { "aligned": "true" } + }, + { + "name": "improve", + "input": [ "${id}.sens" ], + "output": [ "${id}_vh.ply" ] + }, + { + "name": "decimate", + "substeps": 3, + "input": [ "${id}_vh.ply" ], + "output": [ "${id}_vh_clean.ply", "${id}_vh_clean_1.ply", "${id}_vh_clean_2.ply" ] + }, + { + "name": "freespace", + "input": [ "${id}.sens" ], + "output": [ "${id}.grid" ] + }, + { + "name": "segment", + "input": [ "${id}_vh_clean_2.ply" ], + "output": [ "${id}_vh_clean_2.0.000100.segs.json", "${id}_vh_clean_2.0.001000.segs.json", "${id}_vh_clean_2.0.010000.segs.json" ] + }, + { + "name": "render", + "input": [ "${id}_vh_clean_2.ply" ], + "output": [ "${id}_vh_clean_2.png" ] + }, + { + "name": "thumbnail", + "input": [ "${id}_vh_clean_2.png" ], + "output": [ "${id}_vh_clean_2_thumb.png" ] + }, + { + "name": "annotation", + "input": [ "${id}_vh_clean_2.0.010000.segs.json" ], + "output": [ "${id}.aggregation.json" ], + "optional": true + } + ] +} diff --git a/Server/config/scannet.json b/Server/config/scannet.json new file mode 100644 index 0000000..6d43ffe --- /dev/null +++ b/Server/config/scannet.json @@ -0,0 +1,26 @@ +{ + "source": "scan-staging", + "assetType": "model", + "rootPath": "/scans/staging", + "screenShotPath": "${rootPath}/${path}/${id}_vh_clean_2.png", + "hasThumbnails": true, + "video": "${rootPath}/${path}/${id}.mp4", + "trajectory": "${rootPath}/${path}/${id}.traj.json", + "voxels-labeled": "/voxelizations/vox/${id}.vox", + "formats": [ + { + "format": "ply", + "path": "${rootPath}/${path}/${id}_vh_clean_2.ply", + "defaultUp": [ 0, 0, 1 ], "defaultFront": [ 0, -1, 0], "defaultUnit": 1, + "useVertexColors": true, + "computeNormals": true + } + ], + "surfaces": { + "format": "segmentGroups", + "files": { + "segmentGroups": "${rootPath}/${path}/${id}.aggregation.json", + "segments": "${rootPath}/${path}/${id}_vh_clean_2.0.010000.segs.json" + } + } +} diff --git a/Server/config/upload.ini b/Server/config/upload.ini new file mode 100644 index 0000000..7be05c2 --- /dev/null +++ b/Server/config/upload.ini @@ -0,0 +1,43 @@ +[server:main] +use = egg:gunicorn#main +daemon = False +#daemon = True +host = 0.0.0.0 +port = 8000 +workers = 10 +backlog = 1024 +loglevel = debug +# 6 hours +timeout = 21600 +worker_class = gevent + +[app:main] +use = call:upload:get_app + +[loggers] +keys = root, gunicorn + +[handlers] +keys = logfile + +[formatters] +keys = generic + +[handler_logfile] +class = logging.FileHandler +level = NOTSET +args = ('logs/upload.log', 'a') +formatter = generic + +[formatter_generic] +format = %(asctime)-15s [%(levelname)-5.5s] %(process)d:%(thread)s [%(name)s.%(funcName)s:%(lineno)d] -- %(message)s + +[logger_root] +level = INFO +handlers = logfile + +[logger_gunicorn] +level = DEBUG +handlers = logfile +propagate = 0 +qualname = gunicorn diff --git a/Server/index.py b/Server/index.py new file mode 100755 index 0000000..6d034aa --- /dev/null +++ b/Server/index.py @@ -0,0 +1,411 @@ +#!/usr/bin/env python +# +# Indexes scans into csv file +# Run with ./index.py (or python index.py on Windows) + +import argparse +import csv +import json +import re +import os +import sys +import logging + +import util +import compute_timings as timings + +from glob import glob + +FORMAT = '%(asctime)-15s [%(levelname)s] %(message)s' +logging.basicConfig(format=FORMAT) +log = logging.getLogger('index') +log.setLevel(logging.INFO) + +# For matching 2016-07-01_04-29-28 +DATE_RE = re.compile(r"\d\d\d\d-\d\d-\d\d_\d\d-\d\d-\d\d") +# For matching sceneLabel with end digit (and stripping it to get a sceneName) +SCENELABEL_RE = re.compile(r'^(.*?)[_-]?\d\s*$') + + +def index_all_recursive(dirname, writer, args): + indexed = 0 + for root, dirs, files in os.walk(dirname): + for name in dirs: + dir = os.path.join(root, name) + if has_scan(dir): + subdir = os.path.relpath(dir, dirname) + indexed += index_single(dir, subdir, writer, args) + else: + log.warning('Skipping directory without scan: ' + dir) + log.info('Indexed ' + str(indexed) + ' scans') + + +def index_all(dirname, writer, args): + entries = glob(dirname + '/*/') + indexed = 0 + for dir in entries: + indexed += index_single(dir, dir, writer, args) + log.info('Indexed ' + str(indexed) + ' scans') + + +def index_single(dirname, subdir, writer, args): + # Indexes a single scannet entry (stored in one directory) + # by extract the metadata and appending it to the writer + meta = extract_meta(dirname, subdir, args) + if meta: + writer(meta) + return 1 + else: + log.warning('Skipping directory without good scan: ' + dirname) + return 0 + + +def convert_data(data, meta): + output = None + if isinstance(data, dict): + output = {} + for key, value in data.iteritems(): + output[key] = convert_data(value, meta) + elif isinstance(data, list): + output = [] + for value in data: + output.append(convert_data(value, meta)) + elif isinstance(data, basestring): + output = data.replace('${id}', meta['id']) + else: + output = data + return output + + +def has_scan(dirname): + dirname = strip_dirname(dirname) + id = os.path.basename(dirname) + # If any of these files exists, this directory is likely to be a scan + files = [id + '.imu', id + '.depth', id + '.h264', id + '.sens', id + '.ply'] + for file in files: + if util.is_non_zero_file(os.path.join(dirname, file)): + return True + return False + + +def check_files(filesByName, files, checkAny=False): + nFilesOk = 0 + for file in files: + f = filesByName.get(file) + if f and f.get('size') > 0: + nFilesOk += 1 # OK + if checkAny: + return nFilesOk > 0 + else: + return nFilesOk == len(files) + + +def check_stages(stages_data, meta, times=None): + converted = convert_data(stages_data, meta) + stages = converted.get('stages') + if meta.get('files'): + filesByName = dict((f.get('name'), f) for f in meta.get('files')) + stageStatuses = [] + lastAllOk = '' + failed = False + for stage in stages: + if times is not None: + timeRec = timings.getRecord(times, stage.get('name'), stage.get('substeps')) + else: + timeRec = None + + ok = None # Don't know if okay + if stage.get('output'): + outputOk = check_files(filesByName, stage.get('output'), stage.get('outputCheck') == 'any') + if outputOk: + ok = True + if ok and stage.get('checks'): + for k, v in stage.get('checks').iteritems(): + if meta.get(k) != v: + ok = False + break + + # Check input + if stage.get('input'): + inputOk = check_files(filesByName, stage.get('input')) + else: + inputOk = None + + outdated = False + if ok is None: + if inputOk and not stage.get('optional'): + ok = False + else: + if inputOk: + # Check if output is out of date + inputs = [filesByName.get(name) for name in stage.get('input')] + inputs = [f for f in inputs if f is not None] + lastModifiedInput = util.lastModified(inputs) + lastModifiedMillis = lastModifiedInput.get('modifiedAtMillis') + outputs = [filesByName.get(name) for name in stage.get('output')] + outputs = [f for f in outputs if f is not None] + outdated = any(f.get('modifiedAtMillis') < lastModifiedMillis for f in outputs) + + status = {'name': stage.get('name')} + if timeRec is not None: + status['secs'] = timeRec['secs'] + status['time'] = timeRec['time'] + if outdated: + status['outdated'] = True + if ok is not None: + status['ok'] = ok + stageStatuses.append(status) + if not failed: + if ok: + lastAllOk = stage.get('name') + elif not stage.get('optional'): + failed = True + meta['stages'] = stageStatuses + meta['lastOkStage'] = lastAllOk + + +def strip_dirname(dirname): + # Make sure dirname don't end in '/', otherwise our poor basename is not going to work well + return dirname.rstrip('/').rstrip('\\') + + +def extract_meta(dirname, subdir, args): + source = args.get('source') + datasets = args.get('datasets') + + # Make sure dirname don't end in '/', otherwise our poor basename is not going to work well + dirname = strip_dirname(dirname) + + # Extract metadata from csv and create a record + + # First check if okay by looking into processed.txt + processedFile = dirname + '/processed.txt' + processed = None + if util.is_non_zero_file(processedFile): + processed = util.read_properties(processedFile, log) + if not processed: + if not args.get('includeAll'): + return False # NOT ACCEPTABLE + else: + if not args.get('includeAll'): + return False # NOT ACCEPTABLE + + # Process log + times = None + processLog = dirname + '/process.log' + if os.path.isfile(processLog): + times = timings.computeTimings(processLog) + + + # Take dirname and extract the final string as the id + id = os.path.basename(dirname) + if subdir is None: + subdir = id + + meta1 = { + 'fullId': source + '.' + id, + 'id': id, + 'source': source, + 'datasets': datasets, + 'path': subdir + } + if times is not None: + total = timings.getTotal(times) + meta1['totalProcessingSecs'] = total.get('secs') + meta1['totalProcessingTime'] = total.get('time') + # Extract create time from id matching: 2016-07-01_04-29-28 + date_match = DATE_RE.search(id) + if date_match: + createdAt = date_match.group(0) + # Reformat to be in ISO8601 format + meta1['createdAt'] = createdAt[0:10] + 'T' + createdAt[11:13] + ':' + createdAt[14:16] + ':' + createdAt[17:19] + + # Look for dirname/id.txt and extract fields into our meta + # if there is txt file, read it and append to metadata record + metafile = dirname + '/' + id + '.txt' + if util.is_non_zero_file(metafile): + # Read in txt as dictionary + meta = util.read_properties(metafile, log) + else: + meta = {} + # go through files and find last time as updatedAt time for scan + + # Take our basic info and merge it into meta (overwriting what maybe there) + if processed: + meta.update(processed) + meta.update(meta1) + + # Check what files we have + meta['files'] = util.list_files(dirname) + lastModified = util.lastModified(meta['files']) + if lastModified: + meta['updatedAt'] = util.millisToIso(lastModified.get('modifiedAtMillis')) + + # Check what stage we are in + # NOTE: This requires meta to be filled in with id and files!!! + if args.get('stages'): + check_stages(args.get('stages'), meta, times) + + # Check if we have a ply file and how big it is + filebase = id + '_vh_clean_2' if args.get('checkCleaned') else id + plyfile = dirname + '/' + filebase + '.ply' + plyfileSize = util.filesize(plyfile) + meta['hasCleaned'] = args.get('checkCleaned') and plyfileSize > 0 + if plyfileSize > 0: + meta['fileType'] = 'ply' + meta['fileSize'] = plyfileSize + + # Check if we have a png file + pngfile = dirname + '/' + filebase + '.png' + pngfileSize = util.filesize(pngfile) + meta['hasScreenshot'] = pngfileSize > 0 + + # Check if we have a thumbnail file + pngfile = dirname + '/' + filebase + '_thumb.png' + pngfileSize = util.filesize(pngfile) + meta['hasThumbnail'] = pngfileSize > 0 + + if source == 'nyuv2' and not meta.get('sceneType'): + idParts = meta.get('id').split('_') + meta['sceneType'] = '_'.join(idParts[0:len(idParts-1)]) + + if meta.get('sceneLabel'): + # Derive sceneName from sceneLabel + sceneLabel = meta.get('sceneLabel') + match = SCENELABEL_RE.match(sceneLabel) + meta['sceneName'] = match.group(1) if match else sceneLabel + + return meta + + +def loadJson(infile): + return json.load(infile) + + +def saveJson(data, out): + json.dump(data, out, indent=1, separators=(',', ': ')) + + +def loadCsv(infile): + reader = csv.DictReader(infile) + rows = {} + for row in reader: + rows[row['id']] = row + return rows + + +def saveCsv(data, csvfile): + # Index and output + fieldnames = ['fullId', 'source', 'id', 'datasets', + 'valid', 'aligned', 'hasScreenshot', 'hasThumbnail', 'hasCleaned', + 'fileType', 'fileSize', + 'sceneLabel', 'sceneName', 'sceneType', + 'deviceId', 'deviceName', 'userName', + 'numDepthFrames', 'numColorFrames', 'numIMUmeasurements', + 'lastOkStage', 'createdAt', 'updatedAt', 'path'] + writer = csv.DictWriter(csvfile, fieldnames=fieldnames, extrasaction='ignore') + writer.writeheader() + for k,v in data.iteritems(): + writer.writerow(v) + + +def index(args): + if args.get('stagesFile'): + with open(args.get('stagesFile')) as json_data: + args['stages'] = json.load(json_data) + if args.get('format') == 'json': + return indexAndSave(args, loadJson, saveJson) + else: + return indexAndSave(args, loadCsv, saveCsv) + + +def assignItem(m, id, entry): + m[id] = entry + + +def indexAndSave(args, loadFn, saveFn): + if args.get('output'): + print('Indexing ' + args.get('input') + ' to ' + args.get('output')) + + # index into memory + rows = {} + if args.get('single'): + subdir = None + if args.get('root'): + subdir = os.path.relpath(args.get('input'), args.get('root')) + index_single(args.get('input'), subdir, lambda r: assignItem(rows, r['id'], r), args) + elif args.get('recursive'): + index_all_recursive(args.get('input'), lambda r: assignItem(rows, r['id'], r), args) + else: + index_all(args.get('input'), lambda r: assignItem(rows, r['id'], r), args) + + # output + allRows = rows + if args.get('output'): + # read existing if there + isNonEmpty = util.is_non_zero_file(args.get('output')) + if args.get('append') and isNonEmpty: + with open(args.get('output')) as data: + existing = loadFn(data) + # combine old with new + allRows = existing.copy() + allRows.update(rows) + output = open(args.get('output'), 'wb') + else: + output = sys.stdout + + # dump output + saveFn(allRows, output) + + output.flush() + if args.get('output'): + output.close() + return rows + + +def main(): + scriptpath = os.path.dirname(os.path.realpath(__file__)) + # Argument processing + parser = argparse.ArgumentParser(description='Index scans!!!') + parser.add_argument('-i', '--input', dest='input', action='store', + #default='/scan-net/scans/staging', + help='Input directory') + parser.add_argument('-o', '--output', dest='output', action='store', + help='Output CSV filename') + parser.add_argument('-s', '--single', dest='single', action='store_true', + default=False, + help='Input directory points to a single entry') + parser.add_argument('-a', '--append', dest='append', action='store_true', + default=False, + help='Append to output') + parser.add_argument('--all', dest='includeAll', action='store_true', + default=False, + help='Include all scans (including unprocessed scans)') + # TODO: Remove this option at some point + parser.add_argument('--nonrecursive', dest='recursive', action='store_false', + default=True, + help='Non-recursive processing of directory') + parser.add_argument('--solr', dest='solr', action='store', + default='https:///models3d/solr/', + help='Solr url for updating the solr index') + parser.add_argument('--datasets', dest='datasets', action='store', + default='ScanNet', + help='Name of dataset') + parser.add_argument('--stages', dest='stagesFile', action='store', + default=os.path.join(scriptpath, 'config/scan_stages.json'), + help='File specifying scan stages') + parser.add_argument('--source', dest='source', action='store', + default='scan', + help='Source to use for fullId') + parser.add_argument('--format', dest='format', action='store', + default='csv', choices=['csv', 'json'], + help='Format to use for output') + parser.add_argument('--checkBasic', dest='checkCleaned', action='store_false', + default=True, + help='Check for basic ply or the cleaned ply') + + args = parser.parse_args() + index(vars(args)) + + +if __name__ == "__main__": main() diff --git a/Server/install_deps.sh b/Server/install_deps.sh new file mode 100755 index 0000000..c4f97d5 --- /dev/null +++ b/Server/install_deps.sh @@ -0,0 +1,9 @@ +#!/bin/sh +pip install --upgrade pip +pip install flask +pip install gunicorn +pip install paste +pip install pastedeploy +pip install gevent +pip install requests +pip install pytimeparse diff --git a/Server/logs/.gitignore b/Server/logs/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/Server/logs/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/Server/monitor.py b/Server/monitor.py new file mode 100755 index 0000000..aeae348 --- /dev/null +++ b/Server/monitor.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python +# +# Recommended: +# Install virtualenv +# Create virtualenv +# pip install flask +# Run with ./monitor.py (or python monitor.py on Windows) + +import argparse +import json +import os +import logging +import traceback +import requests +from threading import Lock +from flask import Flask, request, jsonify +from werkzeug import secure_filename + +import util +import index + +SCRIPT_DIR = util.getScriptPath() +INDEX_ALL_BIN = os.path.join(SCRIPT_DIR, 'index_scannet.sh') +CONVERT_H264_TO_MP4_BIN = os.path.join(SCRIPT_DIR, 'scripts', 'h264_to_mp4.sh') +CONVERT_H264_TO_THUMBNAIL_BIN = os.path.join(SCRIPT_DIR, 'scripts', 'h264_thumbnail.sh') + +CMD_ARGS = [] +if os.name == 'nt': + GIT_BASH = 'C:\\Program Files\\Git\\bin\\bash.exe' + CMD_ARGS = [GIT_BASH] + +# where scan data is stored under as subdirs with unique ids +STAGING_FOLDER = os.path.join(SCRIPT_DIR, 'staging') + +# informing our management UI of our updated state +WEBUI = 'http://localhost:3030' + +# for locking indexing resources +INDEX_LOCK = Lock() + +# for locking convert video lock +CONVERT_VIDEO_LOCK = Lock() + +app = Flask(__name__) +app.config['STAGING_FOLDER'] = STAGING_FOLDER +app.config['indexfile'] = 'scan-net.csv' +app.config['source'] = 'scan' +app.config['datasets'] = 'ScanNet' + +FORMAT = '%(asctime)-15s [%(levelname)s] %(message)s' +logging.basicConfig(format=FORMAT) +log = logging.getLogger('monitor') +log.setLevel(logging.INFO) + + +def post(url, data, log): + log.info('Connecting to ' + url + ' ...') + try: + resp = requests.post(url, json=data) + log.info('Connected to ' + url + ' successfully.') + return {'status': 'ok', 'response': resp.text} + except requests.exceptions.RequestException as e: + log.warning('Error connecting to ' + url + ': ' + e.reason) + return {'status': 'error', 'message': e.reason} + + +@app.before_request +def log_request(): + log.info('Got request: %s', request.path) + + +# Indexes scan +@app.route('/index/') +def index_scan(dirname): + dirname = secure_filename(dirname) + path = os.path.join(app.config['STAGING_FOLDER'], dirname) + + # Indexing + with INDEX_LOCK: + indexfile = os.path.join(app.config['STAGING_FOLDER'], app.config['indexfile']) + indexed = index.index({ + 'input': path, 'output': indexfile, 'root': app.config['STAGING_FOLDER'], + 'single': True, 'append': True, 'checkCleaned': True, + 'source': app.config['source'], 'datasets': app.config['datasets'], + 'stages': app.config['stages'], + 'includeAll': True + }) + if indexed: + res = post(WEBUI + '/scans/populate?group=staging&replace=true', indexed.values(), log) + if res.get('status') == 'ok': + return res.get('response') + else: + resp = jsonify({"message": res.message}) + resp.status_code = 500 + return resp + else: + return 'Nothing to index' + + +@app.route('/index') +def index_all(): + with INDEX_LOCK: + ret = util.call(CMD_ARGS + [INDEX_ALL_BIN], log, desc='index_all') + if ret < 0: + resp = jsonify({"message": 'Error indexing all scans'}) + resp.status_code = 500 + return resp + else: + return 'done' + + +# Converts the h264 to mp4 and thumbnails +@app.route('/convert-video/') +def convert_video(dirname): + dirname = secure_filename(dirname) + path = os.path.join(app.config['STAGING_FOLDER'], dirname) + + # Convert + with CONVERT_VIDEO_LOCK: + ret1 = util.call(CMD_ARGS + [CONVERT_H264_TO_MP4_BIN, '--skip-done', path], log, desc='h264-to-mp4') + ret2 = util.call(CMD_ARGS + [CONVERT_H264_TO_THUMBNAIL_BIN, '--skip-done', path], log, desc='h264-thumbnail') + if ret1 < 0 or ret2 < 0: + resp = jsonify({"message": 'Error converting h264 to mp4/thumbnail'}) + resp.status_code = 500 + return resp + else: + return 'done' + + +@app.route('/health') +def health(): + return 'ok' + + +def main(): + scriptpath = os.path.dirname(os.path.realpath(__file__)) + # Argument processing + parser = argparse.ArgumentParser(description='Start monitor web service') + parser.add_argument('--stages', dest='stagesFile', action='store', + default=os.path.join(scriptpath, 'config/scan_stages.json'), + help='File specifying scan stages') + parser.add_argument('--port', dest='port', action='store', + default=5001, + help='Port number') + args = parser.parse_args() + + if args.stagesFile: + with open(args.stagesFile) as json_data: + app.config['stages'] = json.load(json_data) + + app.run(host='0.0.0.0', port=args.port, debug=True) + + +if __name__ == "__main__": main() diff --git a/Server/mts_render.py b/Server/mts_render.py new file mode 100755 index 0000000..d6ee7c1 --- /dev/null +++ b/Server/mts_render.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python +# NOTE: remember to source setpath.sh in mitsuba dir or specify MITSUBA_DIR env variable +import argparse +import logging +import multiprocessing +import os +import sys +# add path for the Python extension module +MITSUBA_DIR = os.path.join(os.environ['MITSUBA_DIR'], '') +sys.path.append(MITSUBA_DIR + os.sep + 'python' + os.sep + '2.7') +# Ensure python can find Mitsuba core libraries +os.environ['PATH'] = MITSUBA_DIR + os.pathsep + os.environ['PATH'] +import mitsuba +from mitsuba.core import * +from mitsuba.render import Scene, RenderQueue, RenderJob + +# set up logger +FORMAT = '%(asctime)-15s [%(levelname)s] %(message)s' +logging.basicConfig(format=FORMAT) +log = logging.getLogger('mts-render') +log.setLevel(logging.INFO) + + +def render(args): + # Start up the scheduling system + scheduler = Scheduler.getInstance() + queue = RenderQueue() + for i in range(0, multiprocessing.cpu_count()): + scheduler.registerWorker(LocalWorker(i, 'wrk%i' % i)) + scheduler.start() + + # create globals + pmgr = PluginManager.getInstance() + integrator = pmgr.create({'type': args.get('integrator')}) + emitter = pmgr.create({'type': 'constant'}) + sensor = pmgr.create({ + 'type': 'perspective', + 'film': { + 'type': 'ldrfilm', + 'width': args.get('width'), + 'height':args.get('height'), + 'pixelFormat': 'rgba', + 'exposure': args.get('exposure'), + 'banner': False + }, + 'sampler': { + 'type': 'ldsampler', + 'sampleCount': args.get('samples') + }, + 'fov': 45.0#, + #'toWorld': Transform.lookAt(Point(0, 0, 1), Point(0, 0, 0), Vector(0, 1, 0)) + }) + + # add mesh to scene + meshfile = args.get('mesh') + mesh = pmgr.create({ + 'type': 'ply', + 'filename': meshfile, + 'bsdf': {'type' : 'diffuse', 'reflectance' : {'type': 'vertexcolors'}} + }) + scene = Scene() + scene.addChild(integrator) + scene.addChild(emitter) + scene.addChild(sensor) + scene.addChild(mesh) + scene.configure() + scene.initialize() # needed to force build of kd-tree + + # compute camera position + aabb = mesh.getAABB() + log.info(aabb) + bsphere = aabb.getBSphere() + camTarget = bsphere.center + camTranslate = Transform.translate(Vector(camTarget)) + camUnTranslate = Transform.translate(-Vector(camTarget)) + UP = args.get('world_up') + bsphere_mult = args.get('bsphere_mult') + camOff_vec = args.get('camera_offset') + camOffset = bsphere_mult * bsphere.radius * normalize(camOff_vec + UP) + camOrigin = camTarget + camOffset + camUp = args.get('camera_up') + + if args.get('render_turntable'): # render turntable sequence + angleDelta = args.get('frames_per_degree') + stepSize = 1 + for i in range(0, 360 / angleDelta, stepSize): + rotationCur = camTranslate * Transform.rotate(UP, i*angleDelta) * camUnTranslate; + trafoCur = Transform.lookAt(rotationCur * camOrigin, camTarget, rotationCur * camUp) + sensor.setWorldTransform(trafoCur) + scene.setDestinationFile('{0}_%03i.png'.format(meshfile) % i) + job = RenderJob('job_%i' % i, scene, queue) + job.start() + queue.waitLeft(0) + # convert to video + os.system('ffmpeg -y -pix_fmt yuv420p -r 30 -i {0}_%03d.png -vcodec libx264 {0}.mp4'.format(meshfile)) + else: # render single view + rotationCurr = Transform.rotate(UP, args.get('theta')) + transformCurr = Transform.lookAt(rotationCurr * camOrigin, camTarget, rotationCurr * camUp) + sensor.setWorldTransform(transformCurr) + if args.get('outfile') is None: + scene.setDestinationFile(os.path.splitext(meshfile)[0] + '.png') + else: + scene.setDestinationFile(args.get('outfile')) + job = RenderJob('job', scene, queue) + job.start() + queue.waitLeft(0) + + queue.join() + + +def vec3(str): + if str == 'x': + return Vector(1, 0, 0) + elif str == 'y': + return Vector(0, 1, 0) + elif str == 'z': + return Vector(0, 0, 1) + else: + v = str.split(',') + return Vector(float(v[0]), float(v[1]), float(v[2])) + + +def nvec3(str): + return normalize(vec3(str)) + + +def main(): + scriptpath = os.path.dirname(os.path.realpath(__file__)) + parser = argparse.ArgumentParser(description='Render PLY file using Mitsuba') + parser.add_argument('-o', dest='outfile', action='store', + help='Output file') + parser.add_argument('--cameras', dest='cameras', action='store', + help='Cameras file to render') + parser.add_argument('--integrator', dest='integrator', action='store', + default='path', choices=['path','mlt','vpl','ao'], + help='Exposure value e, scales radiance by 2^e') + parser.add_argument('--samples', dest='samples', action='store', + default=16, type=int, + help='Number of integrator samples per pixel') + parser.add_argument('--width', dest='width', action='store', + default=640, type=int, + help='Image width') + parser.add_argument('--height', dest='height', action='store', + default=480, type=int, + help='Image height') + parser.add_argument('--frames_per_degree', dest='frames_per_degree', action='store', + default=5, type=int, + help='Image height') + parser.add_argument('--theta', dest='theta', action='store', + default=0, type=float, + help='Azimuth angle to render from') + parser.add_argument('--exposure', dest='exposure', action='store', + default=1.0, type=float, + help='Exposure value e, scales radiance by 2^e') + parser.add_argument('--world_up', dest='world_up', action='store', + default=Vector(0, 0, 1), type=nvec3, + help='World up vector') + parser.add_argument('--camera_up', dest='camera_up', action='store', + default=Vector(0, 1, 0), type=nvec3, + help='Camera image plane up vector') + parser.add_argument('--camera_offset', dest='camera_offset', action='store', + default=Vector(0, 0, 0), type=nvec3, + help='Camera position offset vector to be added with one unit of world_up') + parser.add_argument('--bsphere_mult', dest='bsphere_mult', action='store', + default=2.5, type=float, + help='Camera image plane up vector') + parser.add_argument('--render_turntable', dest='render_turntable', action='store_true', + default=False, + help='Whether to render a turntable animation') + parser.add_argument('mesh') + args = parser.parse_args() + render(vars(args)) + + +if __name__ == "__main__": + main() diff --git a/Server/process.py b/Server/process.py new file mode 100755 index 0000000..5eeee09 --- /dev/null +++ b/Server/process.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# +# Recommended: +# Install virtualenv +# Create virtualenv +# pip install flask +# Run with ./process.py (or python process.py on Windows) + +import os +import logging +import urllib2 + +import util +import index +import scan_processor as sp + +from threading import Lock +from flask import Flask, request, jsonify +from werkzeug import secure_filename +import config as cfg + +# for locking GPU resources +GPU_LOCK = Lock() + +app = Flask(__name__) + +INDEX_URL = os.path.join(cfg.DATA_SERVER, '/scans/index/') # indexing endpoint + +FORMAT = '%(asctime)-15s [%(levelname)s] %(message)s' +logging.basicConfig(format=FORMAT) +log = logging.getLogger('processor') +log.setLevel(logging.INFO) + + +def trigger_indexing(basename, log): + index_url = INDEX_URL + basename + log.info('Indexing ' + basename + ' at ' + index_url + ' ...') + try: + response = urllib2.urlopen(index_url) + html = response.read() + log.info('Index ' + basename + ' successfully.') + except urllib2.URLError as e: + log.warning('Error indexing ' + index_url + ': ' + e.reason) + + +@app.route('/process/') +def process_scan_dir(dirname): + dirname = secure_filename(dirname) + path = os.path.join(cfg.STAGING_FOLDER_LOCAL, dirname) + args = request.args + if 'from' not in args and 'actions' not in args: + config = {'all': True} + else: + config = {'from': args.get('from'), 'actions': args.get('actions')} + config['overwrite'] = args.get('overwrite').lower() in ['true', '1', 'yes'] if 'overwrite' in args else False + # print config + sp.update_config(config) + + if config.get('overwrite'): + # Check timestamp of request (only trigger if the last update timestamp before overwrite) + # Prevents duplicates request + timestamp = args.get('timestamp') + if timestamp is None: + resp = jsonify({'message': 'Please provide timestamp with request'}) + resp.status_code = 400 + return resp + # Request timestamp should be in milliseconds UTC + timestamp = long(timestamp) + newer = util.checkLastModifiedNewer(path, timestamp) + if newer: + resp = jsonify({'message': 'Scan '+ dirname + ' modified after request issued, please resubmit request'}) + resp.status_code = 400 + return resp + + with GPU_LOCK: + processed = sp.process_scan_dir(path, dirname, config) + + trigger_indexing(dirname, log) + + return processed + + +app.run(host='0.0.0.0', port=5000, debug=True) diff --git a/Server/scan_processor.py b/Server/scan_processor.py new file mode 100755 index 0000000..8dab166 --- /dev/null +++ b/Server/scan_processor.py @@ -0,0 +1,240 @@ +#!/usr/bin/env python +# +# Process scans from ipad and runs recons pipeline +# Run with ./scan_processor.py (or python scan_processor.py on Windows) + +import argparse +import os +import logging + +import util + +from glob import glob +import config as cfg + +PROCESSES = ['convert', 'calibrate', 'recons', 'clean', 'improve', 'decimate', 'freespace', 'segment', 'render', 'thumbnail'] + + +# where devices information is stored +DEVICES_DIR = os.path.join(cfg.DATA_DIR, 'devices') +DEVICES_CSV = os.path.join(DEVICES_DIR, 'devices.csv') +# exe to call for converting iPad raw files to .sens files +CONVERTER_DIR = os.path.join(cfg.TOOLS_DIR, 'converter') +CONVERTER_BIN = os.path.join(CONVERTER_DIR, 'converter.exe') +# exe to call for calibration +CALIBRATE_DIR = os.path.join(cfg.TOOLS_DIR, 'calibrate') +CALIBRATE_BIN = os.path.join(CALIBRATE_DIR, 'calibrate.exe') +# exe to call for reconstructing .sens to .ply etc +RECONS_DIR = os.path.join(cfg.TOOLS_DIR, 'FriedLiver') +RECONS_BIN = os.path.join(RECONS_DIR, 'FriedLiver.exe zParametersScanNet.txt zParametersBundlingScanNet.txt') +# exe to call for aligning .sens to up,x,y directions +ALIGN_DIR = os.path.join(cfg.TOOLS_DIR, 'alignment') +ALIGN_BIN = os.path.join(ALIGN_DIR, 'alignment.exe') +# exe to call for hi-res mesh gen +VOXELHASHING_DIR = os.path.join(cfg.TOOLS_DIR, 'VoxelHashing') +VOXELHASHING_BIN = os.path.join(VOXELHASHING_DIR, 'DepthSensing.exe zParametersScanNet.txt zParametersTrackingDefault.txt') +# for mesh cleaning/simplification +MESHPROC_DIR = os.path.join(cfg.TOOLS_DIR, 'meshclean') +# exe for segmentation +SEGMENT_DIR = os.path.join(cfg.TOOLS_DIR, 'segmentor') +SEGMENT_BIN = os.path.join(SEGMENT_DIR, 'Segmentator.exe') +# exe for rendering +RENDER_DIR = cfg.SCRIPT_DIR +RENDER_BIN = 'python ' + os.path.join(RENDER_DIR, 'mts_render.py') +# exe for thumbnailing +THUMBNAIL_BIN = cfg.GIT_BASH + ' ' + os.path.join(cfg.SCRIPT_DIR, 'scripts', 'thumbnail.sh -v') +IMG_CONVERT_BIN = os.path.join(cfg.IMG_MAGIC_DIR, 'convert') +OPTIPNG_BIN = os.path.join(cfg.TOOLS_DIR, 'optipng', 'optipng') +PNGQUANT_BIN = os.path.join(cfg.TOOLS_DIR, 'pngquant', 'pngquant') + + +FORMAT = '%(asctime)-15s [%(levelname)s] %(message)s' +formatter = logging.Formatter(FORMAT) +logging.basicConfig(format=FORMAT) +log = logging.getLogger('scan_processor') +log.setLevel(logging.INFO) + +TEST_MODE = False + + +def update_config(config): + if config.get('all'): + for name in PROCESSES: + config[name] = True + elif config.get('from'): + fromSeen = False + for name in PROCESSES: + fromSeen = fromSeen or name == config['from'] + config[name] = fromSeen + return config + +def process_scan_dir(path, name, config): + # Check if valid scan dir + namebase = os.path.join(path, name) + validNovh = os.path.isfile(namebase + ".ply") and config.get('novh') + if not (validNovh or os.path.isfile(namebase + ".depth") or os.path.isfile(name + ".sens")): + msg = 'path %s not a valid scan dir' % path + log.info(msg) + return msg + + # Wrapper around process_scan_dir_basic but with logging to file + fh = logging.FileHandler(os.path.join(path, 'process.log')) + fh.setLevel(logging.INFO) + fh.setFormatter(formatter) + log.addHandler(fh) + msg = '' + try: + msg = process_scan_dir_basic(path, name, config) + log.info(msg) + finally: + log.removeHandler(fh) + fh.close() + return msg + + +def process_scan_dir_basic(path, name, config): + # Check if already processed + if not config.get('overwrite'): + processedFile = os.path.join(path, 'processed.txt') + if os.path.isfile(processedFile): + return 'Scan at %s already processed' % path + + # Convert to sens file + path = os.path.abspath(path) + outbase = os.path.join(path, name) + uncalibrated_sensfile = outbase + '.uncalibrated.sens' + sensfile = outbase + '.sens' + + if config.get('overwrite') or not os.path.isfile(sensfile): + if config.get('convert'): + ret = util.call([CONVERTER_BIN, path, uncalibrated_sensfile], log, CONVERTER_DIR, desc='convert') + if not os.path.isfile(uncalibrated_sensfile) and not TEST_MODE: + return 'Scan at %s aborted: no uncalibrated sens file (convert failed)' % path + + # Calibrate + if config.get('calibrate'): + if not os.path.isfile(uncalibrated_sensfile) and not TEST_MODE: + return 'Scan at %s aborted: no uncalibrated sens file for calibrate' % path + ret = util.call([CALIBRATE_BIN, uncalibrated_sensfile, sensfile, DEVICES_CSV, DEVICES_DIR], log, CALIBRATE_DIR, desc='calibrate') + else: + log.info(sensfile + ' already exists, skipping convert/calibrate') + + # Reconstruction to produce ply + if config.get('recons'): + if not os.path.isfile(sensfile) and not TEST_MODE: + return 'Scan at %s aborted: no calibrated sens file (calibrate failed)' % path + ret = util.call(RECONS_BIN + ' ' + sensfile, log, RECONS_DIR, desc='recons') + + # Clean and align ply + plyfile = outbase + '.ply' + if not os.path.isfile(plyfile) and not TEST_MODE: + return 'Scan at %s aborted: no ply (recons failed)' % path + if config.get('clean'): + # TODO check: overwrite orig ply file? + ret = util.call(cfg.MESHLAB_BIN + ' -i ' + plyfile + ' -o ' + plyfile + ' -m vc -s ' + MESHPROC_DIR + 'cleanLoRes.mlx', log, desc='clean1') + ret = util.call(ALIGN_BIN + ' ' + path, log, ALIGN_DIR, desc='clean2') + + if config.get('improve'): + ret = util.call(VOXELHASHING_BIN + ' ' + sensfile, log, VOXELHASHING_DIR, desc='improve') + + # Mesh processing + plybase = outbase if config.get('novh') else outbase + '_vh' + if config.get('decimate'): + ret = util.call(cfg.MESHLAB_BIN + ' -i ' + plybase + '.ply -o ' + plybase + '_clean.ply -m vc -s ' + MESHPROC_DIR + 'clean.mlx', log, desc='decimate1') + ret = util.call(cfg.MESHLAB_BIN + ' -i ' + plybase + '_clean.ply -o ' + plybase + '_clean_1.ply -m vc -s ' + MESHPROC_DIR + 'simplify.mlx', log, desc='decimate2') + ret = util.call(cfg.MESHLAB_BIN + ' -i ' + plybase + '_clean_1.ply -o ' + plybase + '_clean_2.ply -m vc -s ' + MESHPROC_DIR + 'simplify.mlx', log, desc='decimate3') + decimated_mesh = plybase + '_clean_2.ply' + if not os.path.isfile(decimated_mesh) and not TEST_MODE: + return 'Scan at %s has no downsampled mesh' % path + + # Freespace + if config.get('freespace'): + ret = util.call(cfg.FREESPACE_BIN + ' ' + sensfile, log, desc='freespace') + + # Segment + if config.get('segment'): + ret = util.call(SEGMENT_BIN + ' ' + decimated_mesh, log, SEGMENT_DIR, desc='segment') + + # Generate images + if config.get('render'): + ret = util.call(RENDER_BIN + ' ' + decimated_mesh, log, RENDER_DIR, desc='render') + + # Generate thumbnails + if config.get('thumbnail'): + ret = util.call(THUMBNAIL_BIN + ' ' + path.replace('\\', '/'), log, + env=dict(os.environ, CONVERT=IMG_CONVERT_BIN, PNGQUANT=PNGQUANT_BIN, OPTIPNG=OPTIPNG_BIN), desc='thumbnail') + + return 'Scan at %s processed' % path + + +def process_scan_dir_batch(dirname, config): + # For now, assume one directory deep (can use os.walk() to recursively descend + entries = glob(dirname + '/*/') + for dir in entries: + name = os.path.relpath(dir, dirname) + log.info('Processing ' + dir + ' ' + name) + process_scan_dir(dir, name, config) + + +def process_scan_dirs(dirs, config): + # For now, assume one directory deep (can use os.walk() to recursively descend + for dir in dirs: + name = os.path.relpath(dir, dir + '/..') + log.info('Processing ' + dir + ' ' + name) + process_scan_dir(dir, name, config) + + +def main(): + # Argument processing + parser = argparse.ArgumentParser(description='Process scans!!!') + parser.add_argument('-i', '--input', dest='input', action='store', + required=True, + help='Input directory or list of directories (if file)') + parser.add_argument('-b', '--batch', dest='batch', action='store_true', + default=False, + help='Batch processing of input directory') + parser.add_argument('--from', dest='from', action='store', + default='convert', + choices=PROCESSES, + help='Which command to start from') + parser.add_argument('--action', dest='actions', action='append', + choices=PROCESSES, + help='What actions to do') + parser.add_argument('--overwrite', dest='overwrite', action='store_true', default=False, + help='Overwrite existing files') + parser.add_argument('--novh', dest='novh', action='store_true', default=False, + help='Remove _vh suffixes') + parser.add_argument('--test', dest='test', action='store_true', default=False, + help='Test pipeline commands without executing them') + + args = parser.parse_args() + config = {} + if args.overwrite: + config['overwrite'] = True + if args.novh: + config['novh'] = True + if args.actions: + for action in args.actions: + config[action] = True + else: + config = update_config(vars(args)) + + global TEST_MODE + TEST_MODE = args.test + util.setCallTestMode(args.test) + + if os.path.isdir(args.input): + if args.batch: + process_scan_dir_batch(args.input, config) + else: + name = os.path.relpath(args.input, args.input + '/..') + process_scan_dir(args.input, name, config) + elif os.path.isfile(args.input): + dirs = util.readlines(args.input) + process_scan_dirs(dirs, config) + else: + print('Please specify directory or file as input') + + +if __name__ == "__main__": + main() diff --git a/Server/scripts/combine_stats.py b/Server/scripts/combine_stats.py new file mode 100755 index 0000000..5ae4e95 --- /dev/null +++ b/Server/scripts/combine_stats.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python +# +# Merges stats with index + +import argparse +import collections +import csv +import json +import os +import logging +import sys + + +FORMAT = '%(asctime)-15s [%(levelname)s] %(message)s' +logging.basicConfig(format=FORMAT) +log = logging.getLogger('mergeStats') +log.setLevel(logging.INFO) + +def loadJson(infile): + rows = json.load(infile) + if type(rows) is list: + byId = {} + for row in rows: + byId[row['id']] = row + rows = byId + fieldnames = set() + for id, row in rows.iteritems(): + fieldnames.update(row.keys()) + return {'fieldnames': list(fieldnames), 'rows': rows} + + +def saveJson(data, out): + json.dump(data, out, indent=1, separators=(',', ': ')) + + +def loadCsv(infile): + reader = csv.DictReader(infile) + rows = {} + for row in reader: + rows[row['id']] = row + return {'fieldnames': list(reader.fieldnames), 'rows': rows} + + +def saveCsv(fieldnames, data, csvfile): + writer = csv.DictWriter(csvfile, fieldnames=fieldnames, extrasaction='ignore') + writer.writeheader() + for k,v in data.iteritems(): + writer.writerow(v) + + +def loadFile(filename): + with open(filename, 'r') as infile: + if filename.endswith('.csv'): + return loadCsv(infile) + elif filename.endswith('.json'): + return loadJson(infile) + else: + log.warning('Unknown file type ' + filename) + + +def saveFile(format, fieldnames, entries, outfile): + if format == 'csv': + saveCsv(fieldnames, entries, outfile) + elif format == 'json': + saveJson(entries, outfile) + else: + log.warning('Unknown file format ' + format) + + +def combine(args): + inputs = args.get('input') + if len(inputs) == 0: + log.error('No inputs specified!!!') + return + data = loadFile(inputs[0]) + fieldnames = data.get('fieldnames') + entries = data.get('rows') + + # Read read of the data and merge in by id + ignored = collections.Counter() + for filename in inputs[1:]: + data = loadFile(filename) + newfieldnames = [f for f in data.get('fieldnames') if f not in fieldnames] + fieldnames.extend(newfieldnames) + for id, datum in data.get('rows').iteritems(): + if id in entries: + # merge in + entries[id].update(datum) + else: + ignored.update([id]) + + if args.get('output'): + with open(args.get('output'), 'wb') as outfile: + saveFile(args.get('format'), fieldnames, entries, outfile) + else: + saveFile(args.get('format'), fieldnames, entries, sys.stdout) + sys.stdout.flush() + + +def main(): + scriptpath = os.path.dirname(os.path.realpath(__file__)) + # Argument processing + parser = argparse.ArgumentParser(description='Merge index file with stats!') + parser.add_argument('-i','--input', dest='input', action='append', + help='Input files') + parser.add_argument('--format', dest='format', action='store', + default='csv', choices=['csv', 'json'], + help='Format to use for output') + parser.add_argument('output', nargs='?') + + args = parser.parse_args() + combine(vars(args)) + + +if __name__ == "__main__": main() \ No newline at end of file diff --git a/Server/scripts/h264_thumbnail.sh b/Server/scripts/h264_thumbnail.sh new file mode 100755 index 0000000..8af6558 --- /dev/null +++ b/Server/scripts/h264_thumbnail.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +# +# Generates thumbnails for h264 raw video streams + +OUT_WIDTH=200 +VERBOSE=false +SKIPDONE=false +FFMPEG=${FFMPEG:-ffmpeg} +INPUT_PATTERN="*.h264" + +function run { + for file in `find "${DIR}" -name "$INPUT_PATTERN"`; do + thumb=${file%.*}_thumb\.jpg + if [[ ("$SKIPDONE" = true) && (-s ${thumb}) ]]; then + # Skip this + continue + fi + if [ "$VERBOSE" = true ]; then + echo "Create thumbnail: ${file} to ${thumb}" + fi + "${FFMPEG}" -y -i "${file}" -vf "scale=${OUT_WIDTH}:-1" -frames:v 1 "${thumb}" + done + echo "Done." +} + +while true; do + case "$1" in + -h) + echo "Usage: $0 [-h] [-i pattern] [-v] [--skip-done] [width]" + echo "Creates thumbnail images for .h264 raw streams" + echo "[-h] prints this help message and quits" + echo "[-i] specified input file pattern" + echo "[-v] verbose mode" + echo "[--skip-done] skips images with existing thumbnails" + echo "[width] is optional and must be width in pixels" + echo "All parameters are positional" + exit 1 + ;; + -v) + VERBOSE=true + shift + ;; + -i) + shift + INPUT_PATTERN=$1 + shift + ;; + --skip-done) + SKIPDONE=true + shift + ;; + *) + DIR="$1" + shift + break + esac +done + +if [ -z $DIR ] +then + echo "Please specify input directory" + exit 1 +fi + +if [ -n "$1" ]; then + OUT_WIDTH="$1" +fi + +run diff --git a/Server/scripts/h264_to_mp4.sh b/Server/scripts/h264_to_mp4.sh new file mode 100755 index 0000000..5f1b9f3 --- /dev/null +++ b/Server/scripts/h264_to_mp4.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +# +# Converts h264 raw video streams to compressed mp4 + +OUT_WIDTH=324 +VERBOSE=false +SKIPDONE=false +FFMPEG=${FFMPEG:-ffmpeg} + +function run { + for h264 in `find "${DIR}" -name "*.h264"`; do + mp4=${h264/\.h264/\.mp4} + if [[ ("$SKIPDONE" = true) && (-s ${mp4}) ]]; then + # Skip this + continue + fi + if [ "$VERBOSE" = true ]; then + echo "Create mp4: ${h264} to ${mp4}" + fi + "${FFMPEG}" -y -i "${h264}" -vf "scale=${OUT_WIDTH}:-1" -pix_fmt yuv420p -r 25 -movflags faststart "${mp4}" + done + echo "Done." +} + +while true; do + case "$1" in + -h) + echo "Usage: $0 [-h] [-v] [--skip-done] [width]" + echo "Converts.h264 raw stream to lower bitrate .mp4" + echo "[-h] prints this help message and quits" + echo "[-v] verbose mode" + echo "[--skip-done] skips images with existing thumbnails" + echo "[width] is optional and must be width in pixels" + echo "All parameters are positional" + exit 1 + ;; + -v) + VERBOSE=true + shift + ;; + --skip-done) + SKIPDONE=true + shift + ;; + *) + DIR="$1" + shift + break + esac +done + +if [ -z $DIR ] +then + echo "Please specify input directory" + exit 1 +fi + +if [ -n "$1" ]; then + OUT_WIDTH="$1" +fi + +run diff --git a/Server/scripts/index_scannet.sh b/Server/scripts/index_scannet.sh new file mode 100755 index 0000000..c7878e1 --- /dev/null +++ b/Server/scripts/index_scannet.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# +# Simple script to index scannet staged and checked + +BIN=`dirname $0` +SCANNET_DIR=${1:-E:/share/data/scan-net/} +WEBUI=http://localhost:3030 + +SCANS_DIR=${SCANNET_DIR}/scans +ANNS_DIR=${SCANNET_DIR}/annotations + +# Index +$BIN/../index.py -i $SCANS_DIR/staging -o $SCANS_DIR/staging/scan-net.csv +$BIN/../index.py --all --format json -i $SCANS_DIR/staging -o $SCANS_DIR/staging/scan-net.all.json +$BIN/../index.py -i $SCANS_DIR/checked -o $SCANS_DIR/checked/scan-net.csv +$BIN/../index.py --format json -i $SCANS_DIR/checked -o $SCANS_DIR/checked/scan-net.all.json + +# If there is annotation stats, merge them in +ANN_STATS=${ANNS_DIR}/scannet.anns.stats.csv +if [ -f ${ANN_STATS} ]; then + echo "Combining stats from ${ANN_STATS}" + cp $SCANS_DIR/checked/scan-net.csv $SCANS_DIR/checked/scan-net.nostats.csv + $BIN/combine_stats.py --format csv -i $SCANS_DIR/checked/scan-net.nostats.csv -i ${ANN_STATS} $SCANS_DIR/checked/scan-net.csv + cp $SCANS_DIR/checked/scan-net.all.json $SCANS_DIR/checked/scan-net.all.nostats.json + $BIN/combine_stats.py --format json -i $SCANS_DIR/checked/scan-net.all.nostats.json -i ${ANN_STATS} $SCANS_DIR/checked/scan-net.all.json +fi + + +# Tell our webui about it +curl "$WEBUI/scans/populate?group=staging&replace=group" -H 'Content-Type: application/json' --data-binary "@$SCANS_DIR/staging/scan-net.all.json" +curl "$WEBUI/scans/populate?group=checked&replace=group" -H 'Content-Type: application/json' --data-binary "@$SCANS_DIR/checked/scan-net.all.json" diff --git a/Server/staging/.gitignore b/Server/staging/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/Server/staging/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/Server/start_process_server.sh b/Server/start_process_server.sh new file mode 100755 index 0000000..bba6e82 --- /dev/null +++ b/Server/start_process_server.sh @@ -0,0 +1,2 @@ +#!/bin/sh +python process.py diff --git a/Server/start_upload_server.sh b/Server/start_upload_server.sh new file mode 100755 index 0000000..ff0935e --- /dev/null +++ b/Server/start_upload_server.sh @@ -0,0 +1,7 @@ +#!/bin/sh +OLD_PATH="`pwd`" +MY_PATH="`dirname \"$0\"`" +cd ${MY_PATH} +#gunicorn -b 0.0.0.0:8000 -t 0 wsgi:app -w 2 +gunicorn --paste config/upload.ini +cd ${OLD_PATH} diff --git a/Server/thumbnail.sh b/Server/thumbnail.sh new file mode 100755 index 0000000..0938338 --- /dev/null +++ b/Server/thumbnail.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +# +# Reduces image sizes as well as optimizes PNGs +# Prerequisites for resize: +# http://imagemagick.org/ +# +# Prerequisites for optimization: +# https://pngquant.org/ +# http://optipng.sourceforge.net/ +# +# Both pngquant and optipng must be on the PATH + +OUT_SIZE=128x128 +OPTIMIZE=true +VERBOSE=false +SKIPDONE=false +CONVERT=${CONVERT:-convert} +PNGQUANT=${PNGQUANT:-pngquant} +OPTIPNG=${OPTIPNG:-optipng} + +function run { + echo "Resizing to ${OUT_SIZE}..." + for img in `find "${DIR}" -name "*.png" -not -name "*_thumb.png"`; do + thumb=${img/\.png/_thumb\.png} + if [[ ("$SKIPDONE" = true) && (-s ${thumb}) ]]; then + # Skip this + continue + fi + if [ "$VERBOSE" = true ]; then + echo "Create thumbnail: ${img} to ${thumb}" + fi + "${CONVERT}" "${img}" -resize ${OUT_SIZE} "${thumb}" + if [ "$OPTIMIZE" = true ]; then + "${PNGQUANT}" 256 --ext .png --force "${thumb}" && "${OPTIPNG}" -clobber "${thumb}" + fi + done + echo "Done." +} + +while true; do + case "$1" in + -h) + echo "Usage: $0 [-h] [-v] [--skip-done] [-d] [size]" + echo "Resizes images and optionally reduces image size in a lossy manner" + echo "[-h] prints this help message and quits" + echo "[-v] verbose mode" + echo "[--skip-done] skips images with existing thumbnails" + echo "[-d] is optional and disables optimization. pngquant and optipng must be on the PATH" + echo "[size] is optional and must be in XxY format: 128x128" + echo "All parameters are positional" + exit 1 + ;; + -d) + OPTIMIZE=false + shift + DIR="$1" + shift + break + ;; + -v) + VERBOSE=true + shift + ;; + --skip-done) + SKIPDONE=true + shift + ;; + *) + DIR="$1" + shift + break + esac +done + +if [ -z $DIR ] +then + echo "Please specify input directory" + exit 1 +fi + +if [ -n "$1" ]; then + OUT_SIZE="$1" +fi + +run diff --git a/Server/tmp/.gitignore b/Server/tmp/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/Server/tmp/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/Server/tools/meshclean/clean.mlx b/Server/tools/meshclean/clean.mlx new file mode 100644 index 0000000..55f9fe2 --- /dev/null +++ b/Server/tools/meshclean/clean.mlx @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/Server/tools/meshclean/cleanLoRes.mlx b/Server/tools/meshclean/cleanLoRes.mlx new file mode 100644 index 0000000..e5c177a --- /dev/null +++ b/Server/tools/meshclean/cleanLoRes.mlx @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/Server/tools/meshclean/simplify.mlx b/Server/tools/meshclean/simplify.mlx new file mode 100644 index 0000000..f48fe2c --- /dev/null +++ b/Server/tools/meshclean/simplify.mlx @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Server/tools/recons/zParametersBundlingScanNet.txt b/Server/tools/recons/zParametersBundlingScanNet.txt new file mode 100644 index 0000000..e4d5625 --- /dev/null +++ b/Server/tools/recons/zParametersBundlingScanNet.txt @@ -0,0 +1,76 @@ + + +s_verbose = true; // output debug statements (invalid frames etc) + +s_erodeSIFTdepth = true; +s_sendUplinkFeedbackImage = true; + +s_recordSolverConvergence = false; + +s_enablePerFrameTimings = true; +s_enableGlobalTimings = false; + +s_widthSIFT = 640; +s_heightSIFT = 480; + +s_minKeyScale = 3.0f;//5.0f; +s_siftMatchThresh = 0.7f;//0.5f; +s_siftMatchRatioMaxLocal = 0.8f; +s_siftMatchRatioMaxGlobal = 0.8f; + +s_optMaxResThresh = 0.12f; //not squared (per axis component) +s_denseDistThresh = 0.15f; +s_denseNormalThresh = 0.95f; +s_denseColorThresh = 0.1f; +s_denseColorGradientMin = 0.005f; +s_denseDepthMin = 0.5f; +s_denseDepthMax = 4.0f;//4.5f; +s_denseOverlapCheckSubsampleFactor = 4; + +s_maxNumImages = 2000; +s_submapSize = 10; +s_maxNumKeysPerImage = 512; +s_maxNumCorrPerImage = 2000; // over-conservative +s_maxNumResidualsRemoved = 10; + +s_useLocalDense = true; +s_numOptPerResidualRemoval = 1; + +s_numLocalNonLinIterations = 2; +s_numLocalLinIterations = 100; +s_numGlobalNonLinIterations = 3; +s_numGlobalLinIterations = 150; + +s_downsampledWidth = 80; +s_downsampledHeight = 60; + + +//dense term filtering +s_colorDownSigma = 2.5f; +s_depthDownSigmaD = 1.0f; +s_depthDownSigmaR = 0.05f; + +s_maxKabschResidual2 = 0.0006f; + +s_projCorrDistThres = 0.15f; +s_projCorrNormalThres = 0.95f; +s_projCorrColorThresh = 0.1f; + +s_verifySiftErrThresh = 0.12f; +s_verifySiftCorrThresh = 0.02f; + +s_useLocalVerify = true; +s_verifyOptErrThresh = 0.05f; +s_verifyOptCorrThresh = 0.001f; + +s_surfAreaPcaThresh = 0.032f; + +s_minNumMatchesLocal = 4; +s_minNumMatchesGlobal = 4; + +// filtering +s_depthSigmaD = 2.0f; //bilateral filter sigma domain +s_depthSigmaR = 0.05f; //bilateral filter sigma range +s_depthFilter = true; //bilateral filter enabled depth + +s_useComprehensiveFrameInvalidation = true; \ No newline at end of file diff --git a/Server/tools/recons/zParametersScanNet.txt b/Server/tools/recons/zParametersScanNet.txt new file mode 100644 index 0000000..45a8649 --- /dev/null +++ b/Server/tools/recons/zParametersScanNet.txt @@ -0,0 +1,126 @@ +// 0=Kinect; 1=PrimeSense; 2=KinectOne; 3=BinaryDumpReader; 4=NetworkSensor; 5=IntelSensor; 6=RealSense; 7=StructureSensor; 8=SensorDataReader +s_sensorIdx = 8; + +s_numSolveFramesBeforeExit = 60; //#frames to run after scan is done before saving ply and exiting; -1 to keep running +s_overwriteOrigSensTrajectory = true; + +s_generateVideo = false; +s_generateVideoDir = "output/"; +s_printTimingsDirectory = ""; +s_printConvergenceFile = ""; +s_topVideoTransformWorld = 1.0f 0.0f 0.0f 0.0f 0.0f 1.0f 0.0f 0.0f 0.0f 0.0f 1.0f 0.0f 0.0f 0.0f 0.0f 1.0f; +s_topVideoCameraPose = 0.0f 0.0f 0.0f 0.0f; //rotation (deg around z axis), translation (m) +s_topVideoMinMax = 0.0f 0.0f; + +s_windowWidth = 640; //render window width +s_windowHeight = 480; //render window height +//s_windowWidth = 1600; //render window width +//s_windowHeight = 1200; //render window height + +s_integrationWidth = 320; //input depth gets re-sampled to this width (decrease to improve perf.) +s_integrationHeight = 240; //input depth gets re-sampled to this height (decrease to improve perf.) +s_rayCastWidth = 320; //should be same as integration except if rendering video +s_rayCastHeight = 240; + +//trajectory manager/reintegration +s_maxFrameFixes = 30; //max number of frames reintegrated per frame +s_topNActive = 30; //max number of active elements to be reintegrated (sorted list) +s_minPoseDistSqrt = 0.0f; //reintegrate everything above that pose distance (squared dist) + +//////////////////////////////////// +// **** DEPTH SENSING BELOW ***** // +//////////////////////////////////// + +s_sensorDepthMax = 6.0f; //maximum sensor depth in meter +s_sensorDepthMin = 0.1f; //minimum sensor depth in meter +s_renderDepthMax = 6.0f; //maximum render depth in meter +s_renderDepthMin = 0.1f; //minimum render depth in meter + +// cropping options for PrimeSense & Asus Xtion Pro +s_enableColorCropping = false; +s_colorCropX = 320; +s_colorCropY = 272; +s_colorCropWidth = 640; +s_colorCropHeight = 480; + +// sdf and hash settings +s_SDFVoxelSize = 0.010f; //voxel size in meter (IMPORTANT: reduces to improve perf.) +s_SDFMarchingCubeThreshFactor = 10.0f; //marching cube thresh: s_SDFMarchingCubeThresh = s_SDFMarchingCubeThreshFactor*s_SDFVoxelSize +s_SDFTruncation = 0.06f; //truncation in meter +s_SDFTruncationScale = 0.02f; //truncation scale in meter per meter +s_SDFMaxIntegrationDistance = 4.0f; //maximum integration in meter +s_SDFIntegrationWeightSample = 1; //weight for an integrated depth value +s_SDFIntegrationWeightMax = 99999999; //maximum integration weight for a voxel +// s_SDFBlockSize is pound defined (SDF_BLOCK_SIZE) +// s_hashBucketSize is pound defined (HASH_BUCKET_SIZE) +s_hashNumBuckets = 800000; //smaller voxels require more space +s_hashNumSDFBlocks = 600000;//100000; //smaller voxels require more space +s_hashMaxCollisionLinkedListSize = 7; + +// raycast +s_SDFRayIncrementFactor = 0.8f; //(don't touch) s_SDFRayIncrement = s_SDFRayIncrementFactor*s_SDFTrunaction; +s_SDFRayThresSampleDistFactor = 50.5f; //(don't touch) s_SDFRayThresSampleDist = s_SDFRayThresSampleDistFactor*s_rayIncrement; +s_SDFRayThresDistFactor = 50.0f; //(don't touch) s_SDFRayThresDist = s_SDFRayThresSampleDistFactor*s_rayIncrement; +s_SDFUseGradients = false; //analytic gradients for rendering + + +s_binaryDumpSensorFile = ""; +s_binaryDumpSensorUseTrajectory = false; + +// filtering (unused in FriedLiver) +s_depthSigmaD = 2.0f; //bilateral filter sigma domain +s_depthSigmaR = 0.1f; //bilateral filter sigma range +s_depthFilter = false; //bilateral filter enabled depth + +s_colorSigmaD = 2.0f; //bilateral filter sigma domain +s_colorSigmaR = 0.1f; //bilateral filter sigma range +s_colorFilter = false; //bilateral filter enabled depth + +s_integrationEnabled = true; +s_trackingEnabled = true; +s_timingsDetailledEnabled = true; //enable timing output +s_timingsTotalEnabled = false; //enable timing output +s_garbageCollectionEnabled = true; +s_garbageCollectionStarve = 0; //decrement the voxel weight every n'th frame + +// rendering +s_materialShininess = 16.0f; +s_materialAmbient = 0.75f 0.65f 0.5f 1.0f; +s_materialDiffuse = 1.0f 0.9f 0.7f 1.0f; +s_materialSpecular = 1.0f 1.0f 1.0f 1.0f; +s_lightAmbient = 0.4f 0.4f 0.4f 1.0f; +s_lightDiffuse = 0.6f 0.52944f 0.4566f 0.6f; +s_lightSpecular = 0.3f 0.3f 0.3f 1.0f; +s_lightDirection = 0.0f -1.0f 2.0f; + +s_RenderMode = 1; +s_playData = true; + +s_renderingDepthDiscontinuityThresOffset = 0.012f; // discontinuity offset in meter +s_renderingDepthDiscontinuityThresLin = 0.001f; // additional discontinuity threshold per meter +s_remappingDepthDiscontinuityThresOffset = 0.012f; // discontinuity offset in meter +s_remappingDepthDiscontinuityThresLin = 0.01f; + +s_bUseCameraCalibration = false; + +s_marchingCubesMaxNumTriangles = 5000000; // max buffer size for marching cube + +//streaming parameters +s_streamingEnabled = false; +s_streamingVoxelExtents = 1.0f 1.0f 1.0f; +s_streamingGridDimensions = 257 257 257; // dimensions have to be odd (number of samples) +s_streamingMinGridPos = -128 -128 -128; +s_streamingInitialChunkListSize = 2000; +s_streamingRadius = 5.0f; // Depends on DepthMin and DepthMax +s_streamingPos = 0.0f 0.0f 3.0f 1.0f; // Depends on DepthMin and DepthMax +s_streamingOutParts = 80; // number of frames required to sweep through the entire hash + +//recording of the input data +s_recordData = false; // master flag for data recording: enables or disables data recording +s_recordCompression = true; //if recoding is enabled; then compression is used (.sens instead of .sensor) +s_recordDataWidth = 640; //only applies to the non compressed version (see RGBDSensor.cpp) +s_recordDataHeight = 480; //only applies to the non compressed version (see RGBDSensor.cpp) +s_recordDataFile = "dump/recording.sens"; +s_reconstructionEnabled = true; + + diff --git a/Server/upload.py b/Server/upload.py new file mode 100755 index 0000000..9a0ec65 --- /dev/null +++ b/Server/upload.py @@ -0,0 +1,266 @@ +#!/usr/bin/env python +# +# Install dependencies using install_deps.sh +# Run using start_upload_server.sh +# +# To mimic an upload from the iPad app use this curl command: +# curl -v -X PUT -H "FILE_NAME: test.h264" --data-binary "@" -H "Content-Type: application/ipad_scanner_data" "http://localhost:8000/upload" +# curl -v "localhost:8000/verify?filename=&checksum=" + +import os +import shutil +import traceback +import logging +import urllib2 +import threading +import util + +from flask import Flask, request, render_template_string, send_from_directory +from util import Error +from werkzeug import secure_filename +import config as cfg + +app = Flask(__name__) + +INDEX_URL = cfg.DATA_SERVER + '/scans/index/' +CONVERT_VIDEO_URL = cfg.DATA_SERVER + '/scans/monitor/convert-video/' +ALLOWED_EXTENSIONS = set(['h264', 'depth', 'imu', 'txt', 'camera']) +SCAN_PROCESS_TRIGGER_URL = cfg.DATA_SERVER + '/scans/process/' # WebUI process url is nonblocking (it places it on a queue) +SCAN_PROCESS_COMPLETE_STATUS = 'Queued' + + +log = logging.getLogger('scanner-ipad-server') + + +@app.errorhandler(util.Error) +def handle_error(error): + response = error.to_json() + response.status_code = error.status_code + return response + + +@app.before_request +def log_request_headers(): + log.info('Got request: %s', request.headers) + + +@app.after_request +def log_request_response(response): + log.info('Got response: %s', response) + return response + + +def allowed_file(filename): + return '.' in filename and \ + filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS + + +# returns whether scan completely uploaded to dir (assumes only scan files are being received) +def scan_done_uploading(dir): + return len(os.listdir(dir)) >= len(ALLOWED_EXTENSIONS) # TODO: improve check + + +# trigger indexing of scan +def trigger_indexing(basename, log): + index_url = INDEX_URL + basename + log.info('Indexing ' + basename + ' at ' + index_url + ' ...') + try: + response = urllib2.urlopen(index_url) + html = response.read() + log.info('Index ' + basename + ' successfully.') + except urllib2.URLError as e: + log.warning('Error indexing ' + index_url + ': ' + str(e.reason)) + + +# trigger video conversion of scan +def trigger_video_conversion(basename, log): + convert_video_url = CONVERT_VIDEO_URL + basename + log.info('Converting video ' + basename + ' at ' + convert_video_url + ' ...') + try: + response = urllib2.urlopen(convert_video_url) + html = response.read() + log.info('Convert video' + basename + ' successfully.') + except urllib2.URLError as e: + log.warning('Error converting video ' + convert_video_url + ': ' + str(e.reason)) + + +# scan uploaed do some basic stuff with it +def preprocess(basename, log): + trigger_video_conversion(basename, log) + trigger_indexing(basename, log) + + +# calls processor server on given scan basename +def trigger_processing(basename, log): + process_url = SCAN_PROCESS_TRIGGER_URL + basename + log.info('Calling scan process script for ' + basename + ' at ' + process_url + ' ...') + try: + response = urllib2.urlopen(process_url) + html = response.read() + log.info(SCAN_PROCESS_COMPLETE_STATUS + ' ' + basename + ' successfully.') + except urllib2.URLError as e: + log.warning('Error calling scan process for ' + process_url + ': ' + e.reason) + + +# Receives file from request (consuming input) +# Writes file to output if specifed (otherwise, discards it) +def receive_file(request, filename, output=None): + content_length = request.environ.get('CONTENT_LENGTH', 0) + #TODO DEBUG STARTS HERE + if 'Content-Range' in request.headers: + # extract starting byte from Content-Range header string + range_str = request.headers['Content-Range'] + start_bytes = int(range_str.split(' ')[1].split('-')[0]) + log.exception('Receiving %s: PARTIAL FILE RECEIVED: %s', filename, range_str) + if not content_length: + content_length = 0 + else: + content_length = int(content_length) + content_read = 0 + chunk_size = 4096*4 + stream = request.environ['wsgi.input'] + while True: + if(content_read % (chunk_size * 1000) == 0): + log.info("Receiving %s: Uploaded count: %d, \t Percent: %.2f", + filename, content_read, 100 * float(content_read) / content_length ) + try: + chunk = stream.read(chunk_size) + except Exception as e: + log.exception('Receiving %s: Exception: %s while reading input. Aborting...', + filename, str(e)) + raise Error(message='Unexpected error while receiving', status_code=500) + if len(chunk) == 0: + break + content_read += len(chunk) + if output is not None: + output.write(chunk) + + log.info("Receiving %s: Uploaded count: %d, \t Percent: %.2f", + filename, content_read, 100 * float(content_read) / content_length) + if output is None: + log.info('Discarding received file ' + filename) + + if content_read != content_length: + log.error('Receiving %s: Expected length %d, received length %d. Aborting...', + filename, content_length, content_read) + raise Error(message='Unexpected error while receiving', status_code=400) + + +# Temporarily accept both PUT and POST. +# TODO: Remove POST. PUT is more appropriate +@app.route('/upload', methods=['PUT', 'POST']) +def upload_file(): + try: + filename = request.headers.get('FILE_NAME') + if 'process' in request.args: + auto_process_scan = request.args.get('process').lower() in ['true', '1'] + else: + auto_process_scan = cfg.AUTOPROCESS + log.info('Receiving %s, autoprocess=%s', filename, auto_process_scan) + + if allowed_file(filename): + filename = secure_filename(filename) + # determine final staging path for file and check if the file already exists + basename = os.path.splitext(filename)[0] + stagingdir = os.path.join(cfg.STAGING_FOLDER, basename) + stagingpath = os.path.join(stagingdir, filename) + if os.path.exists(stagingpath): + log.info('File already exists on server: %s', stagingpath) + receive_file(request, filename) + return util.ret_ok('File already exists on server') + # temp location to receive stream + tmppath = os.path.join(cfg.TEMP_FOLDER, filename) + with open(tmppath, 'wb') as f: + receive_file(request, filename, f) + + # move to staging area dir and return + util.ensure_dir_exists(stagingdir) + shutil.move(tmppath, stagingpath) # TODO: check if move succeeded and log error if not + log.info('Staged ' + filename + ' to ' + stagingdir) + # If uploading is complete try to trigger processing + if scan_done_uploading(stagingdir): + log.info('Scan done uploading to ' + stagingdir) + if auto_process_scan: + #NOTE: Comment out lines below to disable automated scan processing trigger + indexThread = threading.Thread(target=preprocess, args=(basename, log)) + indexThread.start() + processThread = threading.Thread(target=trigger_processing, args=(basename, log)) + processThread.start() + return util.ret_ok() + else: + log.error('File type not allowed: ' + filename) + log.error(request) + raise Error(message=('File type not allowed: ' + filename), status_code=415) + except Exception as e: + log.error(traceback.format_exc()) + #raise Error(message=('Unknown exception encountered %s' % str(e)), status_code=500) + raise e + + +@app.route('/received', methods=['GET']) +@app.route('/received/', methods=['GET']) +def get_file(filename=None): + base_dir = cfg.STAGING_FOLDER + path = base_dir + if filename: + full_path = os.path.join(path, filename) + if not os.path.isdir(full_path): + return send_from_directory(path, filename) + else: + path = full_path + + tmpl = ''' + +Path: {{ tree.name }} +

{{ tree.name }}

+ + +{%- for item in tree.children recursive %} + + + + + +{%- endfor %} +
NameLast ModifiedSize
{{ item.name }}{{ item.modifiedAt }}{{ item.fileSize }}
+ ''' + return render_template_string(tmpl, tree=util.make_tree(base_dir, path)) + + +@app.route('/verify', methods=['GET']) +def verify_file(): + filename = request.args.get('filename') + checksum = request.args.get('checksum') + filename = secure_filename(filename) + basename = os.path.splitext(filename)[0] + stagingdir = os.path.join(cfg.STAGING_FOLDER, basename) + stagingpath = os.path.join(stagingdir, filename) + + if not os.path.exists(stagingpath): + log.error('File %s does not exist', stagingpath) + raise Error(message=('File %s does not exist' % stagingpath), status_code=404) + + calculated_checksum = util.md5(stagingpath) + + valid = calculated_checksum == checksum + if valid: + log.info('File %s successfully verified', filename) + return util.ret_ok() + else: + log.error('File %s: hash mismatch. Given: %s, calculated: %s', + filename, + checksum, + calculated_checksum) + raise Error(message=('File hash mismatch. Given: %s, calculated: %s' % (checksum, calculated_checksum)), + status_code=400) + + +@app.route('/process/', methods=['GET']) +def process_scan(scanid=None): + processThread = threading.Thread(target=trigger_processing, args=(scanid, log)) + processThread.start() + return util.ret_ok() + + +def get_app(*args, **kwargs): + return app diff --git a/Server/util.py b/Server/util.py new file mode 100755 index 0000000..026a8ff --- /dev/null +++ b/Server/util.py @@ -0,0 +1,214 @@ +import hashlib +import os +import subprocess as subp +import re +import sys +import traceback +import datetime + +from flask import jsonify +from timeit import default_timer as timer + + +DEFAULT_CALL_TEST_MODE = False + + +def setCallTestMode(v): + global DEFAULT_CALL_TEST_MODE + DEFAULT_CALL_TEST_MODE = v + + +def call(cmd, log, rundir='', env=None, desc=None, testMode=None): + if testMode is None: + testMode = DEFAULT_CALL_TEST_MODE + if not cmd: + log.warning('No command given') + return 0 + if testMode: + log.info('Running ' + str(cmd)) + return -1 + cwd = os.getcwd() + res = -1 + try: + start_time = timer() + if rundir: + os.chdir(rundir) + log.info('Currently in ' + os.getcwd()) + log.info('Running ' + str(cmd)) + prog = subp.Popen(cmd, stdout=subp.PIPE, stderr=subp.PIPE, env=env) + out, err = prog.communicate() + if out: + log.info(out) + if err: + log.error('Errors reported running ' + str(cmd)) + log.error(err) + end_time = timer() + delta_time = end_time - start_time + desc_str = desc + ', ' if desc else '' + desc_str = desc_str + 'cmd="' + str(cmd) + '"' + log.info('Time=' + str(datetime.timedelta(seconds=delta_time)) + ' for ' + desc_str) + res = prog.returncode + except Exception as e: + log.error(traceback.format_exc()) + os.chdir(cwd) + return res + + +def is_non_zero_file(fpath): + return True if os.path.isfile(fpath) and os.path.getsize(fpath) > 0 else False + + +def ensure_dir_exists(path): + try: + if not os.path.isdir(path): + os.makedirs(path) + except OSError: + if not os.path.isdir(path): + raise + + +def filesize(fpath): + if os.path.isfile(fpath): + return os.path.getsize(fpath) + else: + return 0 + + +def getScriptPath(): + return os.path.dirname(os.path.realpath(sys.argv[0])) + + +def read_properties(fpath, log): + # Read in txt as dictionary + try: + lines = filter(None, (line.rstrip() for line in open(fpath))) + props = dict(line.strip().split('=', 2) for line in lines) + # Strip whitespace (can also do so by using regex (re) to split) + props = {k.strip(): v.strip() for k, v in props.iteritems()} + return props + except Exception as e: + log.error('Error reading properties from ' + fpath) + log.error(traceback.format_exc()) + return False + + +def list_files(dirname): + # Get list of files in directory and their name, size, date + files = os.listdir(dirname) + fileinfos = [] + for file in files: + st = os.stat(os.path.join(dirname, file)) + mtimestr = datetime.datetime.fromtimestamp(st.st_mtime).strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] + name = re.sub(r'^' + dirname + '/+', '', file) + fileinfos.append({ + 'name': name, + 'size': st.st_size, + 'modifiedAt': mtimestr, + 'modifiedAtMillis': long(round(st.st_mtime*1000)) + }) + return fileinfos + + +def lastModified(fileinfos): + # Get the last modifiedAt string + last = None + for fileinfo in fileinfos: + if last == None or fileinfo.get('modifiedAtMillis') > last.get('modifiedAtMillis'): + last = fileinfo + return last + + +def millisToIso(millis): + # Return timestamp in ISO 8601 + mtimestr = datetime.datetime.fromtimestamp(millis/1000.0).strftime('%Y-%m-%dT%H:%M:%S') + return mtimestr + + +def secsToIso(secs): + # Return timestamp in ISO 8601 + mtimestr = datetime.datetime.fromtimestamp(secs).strftime('%Y-%m-%dT%H:%M:%S') + return mtimestr + + +def checkLastModifiedNewer(dirname, timestamp): + fileinfos = list_files(dirname) + last = lastModified(fileinfos) + if last is not None: + lastMs = last.get('modifiedAtMillis') + # print('last modified is ' + str(lastMs) + ', request timestamp is ' + str(timestamp)) + return lastMs > timestamp + else: + return None + + +# https://stackoverflow.com/questions/3431825/generating-a-md5-checksum-of-a-file +def md5(filename, blocksize=65536): + hash = hashlib.md5() + with open(filename, 'rb') as f: + for chunk in iter(lambda: f.read(blocksize), b''): + hash.update(chunk) + return hash.hexdigest() + + +# http://stackoverflow.com/questions/1094841/reusable-library-to-get-human-readable-version-of-file-size +def naturalsize(num, suffix='B'): + for unit in ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']: + if abs(num) < 1024.0: + return "%3.1f%s%s" % (num, unit, suffix) + num /= 1024.0 + return "%.1f%s%s" % (num, 'Yi', suffix) + + +# Read lines and returns as list (ignores empty lines) +def readlines(input): + lines = [] + with open(input) as x: + for line in x: + line = line.strip() + if len(line): + lines.append(line) + return lines + + +# Returns a recursive directory tree for path (relative to base_dir) +def make_tree(base_dir, path): + tree = dict(name=os.path.basename(path), relative_name=path.replace(base_dir, 'received') , children=[]) + try: lst = os.listdir(path) + except OSError: + pass #ignore errors + else: + for name in lst: + fn = os.path.join(path, name) + if os.path.isdir(fn): + tree['children'].append(make_tree(base_dir, fn)) + else: + st = os.stat(fn) + mtimestr = datetime.datetime.fromtimestamp(st.st_mtime).strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] + tree['children'].append(dict(name=name, fileSize=naturalsize(st.st_size), modifiedAt=mtimestr, + relative_name=os.path.join(path.replace(base_dir, 'received'), name))) + return tree + + +# Return 200 OK message +def ret_ok(message = 'ok'): + rv = {} + rv['message'] = message + ok_resp = jsonify(rv) + ok_resp.status_code = 200 + return ok_resp + + +# Simple error class +class Error(Exception): + def __init__(self, message='', status_code=500): + Exception.__init__(self) + self.message = message + self.status_code = status_code + + def to_dict(self): + rv = {} + rv['message'] = self.message + return rv + + def to_json(self): + return jsonify(self.to_dict()) diff --git a/Server/wsgi.py b/Server/wsgi.py new file mode 100755 index 0000000..f96fd10 --- /dev/null +++ b/Server/wsgi.py @@ -0,0 +1,4 @@ +from upload import app + +if __name__ == '__main__': + app.run() diff --git a/Tasks/Benchmark/classes_ObjClassification-ShapeNetCore55.txt b/Tasks/Benchmark/classes_ObjClassification-ShapeNetCore55.txt new file mode 100644 index 0000000..e53f5bc --- /dev/null +++ b/Tasks/Benchmark/classes_ObjClassification-ShapeNetCore55.txt @@ -0,0 +1,17 @@ +1 trash +3 basket +4 bathtub +5 bed +9 shelf +13 cabinet +18 chair +20 keyboard +22 tv +30 lamp +31 laptop +35 microwave +39 pillow +42 printer +47 sofa +48 stove +49 table diff --git a/Tasks/Benchmark/classes_SemVoxLabel-nyu40id.txt b/Tasks/Benchmark/classes_SemVoxLabel-nyu40id.txt new file mode 100644 index 0000000..48e2287 --- /dev/null +++ b/Tasks/Benchmark/classes_SemVoxLabel-nyu40id.txt @@ -0,0 +1,20 @@ +1 wall +2 floor +3 cabinet +4 bed +5 chair +6 sofa +7 table +8 door +9 window +10 bookshelf +11 picture +12 counter +14 desk +16 curtain +24 refridgerator +28 shower curtain +33 toilet +34 sink +36 bathtub +39 otherfurniture \ No newline at end of file diff --git a/Tasks/Benchmark/scannet_test.txt b/Tasks/Benchmark/scannetv1_test.txt similarity index 100% rename from Tasks/Benchmark/scannet_test.txt rename to Tasks/Benchmark/scannetv1_test.txt diff --git a/Tasks/Benchmark/scannet_train.txt b/Tasks/Benchmark/scannetv1_train.txt similarity index 100% rename from Tasks/Benchmark/scannet_train.txt rename to Tasks/Benchmark/scannetv1_train.txt diff --git a/Tasks/Benchmark/scannet_val.txt b/Tasks/Benchmark/scannetv1_val.txt similarity index 100% rename from Tasks/Benchmark/scannet_val.txt rename to Tasks/Benchmark/scannetv1_val.txt diff --git a/Tasks/Benchmark/scannetv2_test.txt b/Tasks/Benchmark/scannetv2_test.txt new file mode 100644 index 0000000..79d15b0 --- /dev/null +++ b/Tasks/Benchmark/scannetv2_test.txt @@ -0,0 +1,100 @@ +scene0707_00 +scene0708_00 +scene0709_00 +scene0710_00 +scene0711_00 +scene0712_00 +scene0713_00 +scene0714_00 +scene0715_00 +scene0716_00 +scene0717_00 +scene0718_00 +scene0719_00 +scene0720_00 +scene0721_00 +scene0722_00 +scene0723_00 +scene0724_00 +scene0725_00 +scene0726_00 +scene0727_00 +scene0728_00 +scene0729_00 +scene0730_00 +scene0731_00 +scene0732_00 +scene0733_00 +scene0734_00 +scene0735_00 +scene0736_00 +scene0737_00 +scene0738_00 +scene0739_00 +scene0740_00 +scene0741_00 +scene0742_00 +scene0743_00 +scene0744_00 +scene0745_00 +scene0746_00 +scene0747_00 +scene0748_00 +scene0749_00 +scene0750_00 +scene0751_00 +scene0752_00 +scene0753_00 +scene0754_00 +scene0755_00 +scene0756_00 +scene0757_00 +scene0758_00 +scene0759_00 +scene0760_00 +scene0761_00 +scene0762_00 +scene0763_00 +scene0764_00 +scene0765_00 +scene0766_00 +scene0767_00 +scene0768_00 +scene0769_00 +scene0770_00 +scene0771_00 +scene0772_00 +scene0773_00 +scene0774_00 +scene0775_00 +scene0776_00 +scene0777_00 +scene0778_00 +scene0779_00 +scene0780_00 +scene0781_00 +scene0782_00 +scene0783_00 +scene0784_00 +scene0785_00 +scene0786_00 +scene0787_00 +scene0788_00 +scene0789_00 +scene0790_00 +scene0791_00 +scene0792_00 +scene0793_00 +scene0794_00 +scene0795_00 +scene0796_00 +scene0797_00 +scene0798_00 +scene0799_00 +scene0800_00 +scene0801_00 +scene0802_00 +scene0803_00 +scene0804_00 +scene0805_00 +scene0806_00 diff --git a/Tasks/Benchmark/scannet_trainval.txt b/Tasks/Benchmark/scannetv2_train.txt similarity index 100% rename from Tasks/Benchmark/scannet_trainval.txt rename to Tasks/Benchmark/scannetv2_train.txt diff --git a/Tasks/Benchmark/scannetv2_val.txt b/Tasks/Benchmark/scannetv2_val.txt new file mode 100644 index 0000000..b9e7d92 --- /dev/null +++ b/Tasks/Benchmark/scannetv2_val.txt @@ -0,0 +1,312 @@ +scene0568_00 +scene0568_01 +scene0568_02 +scene0304_00 +scene0488_00 +scene0488_01 +scene0412_00 +scene0412_01 +scene0217_00 +scene0019_00 +scene0019_01 +scene0414_00 +scene0575_00 +scene0575_01 +scene0575_02 +scene0426_00 +scene0426_01 +scene0426_02 +scene0426_03 +scene0549_00 +scene0549_01 +scene0578_00 +scene0578_01 +scene0578_02 +scene0665_00 +scene0665_01 +scene0050_00 +scene0050_01 +scene0050_02 +scene0257_00 +scene0025_00 +scene0025_01 +scene0025_02 +scene0583_00 +scene0583_01 +scene0583_02 +scene0701_00 +scene0701_01 +scene0701_02 +scene0580_00 +scene0580_01 +scene0565_00 +scene0169_00 +scene0169_01 +scene0655_00 +scene0655_01 +scene0655_02 +scene0063_00 +scene0221_00 +scene0221_01 +scene0591_00 +scene0591_01 +scene0591_02 +scene0678_00 +scene0678_01 +scene0678_02 +scene0462_00 +scene0427_00 +scene0595_00 +scene0193_00 +scene0193_01 +scene0164_00 +scene0164_01 +scene0164_02 +scene0164_03 +scene0598_00 +scene0598_01 +scene0598_02 +scene0599_00 +scene0599_01 +scene0599_02 +scene0328_00 +scene0300_00 +scene0300_01 +scene0354_00 +scene0458_00 +scene0458_01 +scene0423_00 +scene0423_01 +scene0423_02 +scene0307_00 +scene0307_01 +scene0307_02 +scene0606_00 +scene0606_01 +scene0606_02 +scene0432_00 +scene0432_01 +scene0608_00 +scene0608_01 +scene0608_02 +scene0651_00 +scene0651_01 +scene0651_02 +scene0430_00 +scene0430_01 +scene0689_00 +scene0357_00 +scene0357_01 +scene0574_00 +scene0574_01 +scene0574_02 +scene0329_00 +scene0329_01 +scene0329_02 +scene0153_00 +scene0153_01 +scene0616_00 +scene0616_01 +scene0671_00 +scene0671_01 +scene0618_00 +scene0382_00 +scene0382_01 +scene0490_00 +scene0621_00 +scene0607_00 +scene0607_01 +scene0149_00 +scene0695_00 +scene0695_01 +scene0695_02 +scene0695_03 +scene0389_00 +scene0377_00 +scene0377_01 +scene0377_02 +scene0342_00 +scene0139_00 +scene0629_00 +scene0629_01 +scene0629_02 +scene0496_00 +scene0633_00 +scene0633_01 +scene0518_00 +scene0652_00 +scene0406_00 +scene0406_01 +scene0406_02 +scene0144_00 +scene0144_01 +scene0494_00 +scene0278_00 +scene0278_01 +scene0316_00 +scene0609_00 +scene0609_01 +scene0609_02 +scene0609_03 +scene0084_00 +scene0084_01 +scene0084_02 +scene0696_00 +scene0696_01 +scene0696_02 +scene0351_00 +scene0351_01 +scene0643_00 +scene0644_00 +scene0645_00 +scene0645_01 +scene0645_02 +scene0081_00 +scene0081_01 +scene0081_02 +scene0647_00 +scene0647_01 +scene0535_00 +scene0353_00 +scene0353_01 +scene0353_02 +scene0559_00 +scene0559_01 +scene0559_02 +scene0593_00 +scene0593_01 +scene0246_00 +scene0653_00 +scene0653_01 +scene0064_00 +scene0064_01 +scene0356_00 +scene0356_01 +scene0356_02 +scene0030_00 +scene0030_01 +scene0030_02 +scene0222_00 +scene0222_01 +scene0338_00 +scene0338_01 +scene0338_02 +scene0378_00 +scene0378_01 +scene0378_02 +scene0660_00 +scene0553_00 +scene0553_01 +scene0553_02 +scene0527_00 +scene0663_00 +scene0663_01 +scene0663_02 +scene0664_00 +scene0664_01 +scene0664_02 +scene0334_00 +scene0334_01 +scene0334_02 +scene0046_00 +scene0046_01 +scene0046_02 +scene0203_00 +scene0203_01 +scene0203_02 +scene0088_00 +scene0088_01 +scene0088_02 +scene0088_03 +scene0086_00 +scene0086_01 +scene0086_02 +scene0670_00 +scene0670_01 +scene0256_00 +scene0256_01 +scene0256_02 +scene0249_00 +scene0441_00 +scene0658_00 +scene0704_00 +scene0704_01 +scene0187_00 +scene0187_01 +scene0131_00 +scene0131_01 +scene0131_02 +scene0207_00 +scene0207_01 +scene0207_02 +scene0461_00 +scene0011_00 +scene0011_01 +scene0343_00 +scene0251_00 +scene0077_00 +scene0077_01 +scene0684_00 +scene0684_01 +scene0550_00 +scene0686_00 +scene0686_01 +scene0686_02 +scene0208_00 +scene0500_00 +scene0500_01 +scene0552_00 +scene0552_01 +scene0648_00 +scene0648_01 +scene0435_00 +scene0435_01 +scene0435_02 +scene0435_03 +scene0690_00 +scene0690_01 +scene0693_00 +scene0693_01 +scene0693_02 +scene0700_00 +scene0700_01 +scene0700_02 +scene0699_00 +scene0231_00 +scene0231_01 +scene0231_02 +scene0697_00 +scene0697_01 +scene0697_02 +scene0697_03 +scene0474_00 +scene0474_01 +scene0474_02 +scene0474_03 +scene0474_04 +scene0474_05 +scene0355_00 +scene0355_01 +scene0146_00 +scene0146_01 +scene0146_02 +scene0196_00 +scene0702_00 +scene0702_01 +scene0702_02 +scene0314_00 +scene0277_00 +scene0277_01 +scene0277_02 +scene0095_00 +scene0095_01 +scene0015_00 +scene0100_00 +scene0100_01 +scene0100_02 +scene0558_00 +scene0558_01 +scene0558_02 +scene0685_00 +scene0685_01 +scene0685_02 diff --git a/Tasks/ObjectClassification/torch/provider.lua b/Tasks/ObjectClassification/torch/provider.lua index 2d3cda0..ee80226 100644 --- a/Tasks/ObjectClassification/torch/provider.lua +++ b/Tasks/ObjectClassification/torch/provider.lua @@ -23,11 +23,15 @@ function jitter_chunk(src,jitter) return dst end +function trim(s) + return (s:gsub("^%s*(.-)%s*$", "%1")) +end + -- read h5 filename list function getDataFiles(input_file) local train_files = {} for line in io.lines(input_file) do - train_files[#train_files+1] = line + train_files[#train_files+1] = trim(line) end return train_files end diff --git a/Tasks/README.md b/Tasks/README.md index d1a963b..f6d9174 100644 --- a/Tasks/README.md +++ b/Tasks/README.md @@ -1,6 +1,7 @@ # ScanNet Benchmark Tasks Train/val/test split for ScanNet is given in [Benchmark](Benchmark). +Label mappings (`scannet-labels.combined.tsv`) can be downloaded with the ScanNet task data release. Download with along with the task data (`--task_data`) or by itself (`--label_map`). ScanNet label ids listed under `id`. Trained models can be downloaded with the ScanNet data release. @@ -16,7 +17,7 @@ Code to generate the training data from ScanNet data to come soon. ### 3D Object Classification -Classification of partially-scanned objects, voxelized to 30x30x30. We use the [3D CNN framework](https://github.com/charlesq34/3dcnn.torch) of [Qi et. al.](https://arxiv.org/abs/1604.03265) with an additional data channel encoding known/unknown voxels according to the camera scanning trajectory. +Classification of partially-scanned objects, voxelized to 30x30x30. We use the [3D CNN framework](https://github.com/charlesq34/3dcnn.torch) of [Qi et. al.](https://arxiv.org/abs/1604.03265) with an additional data channel encoding known/unknown voxels according to the camera scanning trajectory. The object classes used are given in [classes_ObjClassification-ShapeNetCore55.txt](Benchmark/classes_ObjClassification-ShapeNetCore55.txt), using ShapeNetCore55 label ids. * Training: run @@ -50,7 +51,7 @@ then compute the nearest neighbors with: ### Semantic Voxel Labeling -Prediction of class labels per voxel for voxels on the surface of a scan. Voxels of a scan are labeled column by column using the surrounding neighborhood information (31x31x62 neighborhood for labeling the 1x1x62 center column). Note that the class labels embedded in the h5 train/test data are nyu40 labels. +Prediction of class labels per voxel for voxels on the surface of a scan. Voxels of a scan are labeled column by column using the surrounding neighborhood information (31x31x62 neighborhood for labeling the 1x1x62 center column). The object classes used for ScanNet are given in [classes_SemVoxLabel-nyu40id.txt](Benchmark/classes_SemVoxLabel-nyu40id.txt), using nyu40 label ids. * Training: ``` diff --git a/Tasks/SemanticVoxelLabeling/torch/example_class_hist_scannet-20.txt b/Tasks/SemanticVoxelLabeling/torch/example_class_hist_scannet-20.txt new file mode 100644 index 0000000..b716d07 --- /dev/null +++ b/Tasks/SemanticVoxelLabeling/torch/example_class_hist_scannet-20.txt @@ -0,0 +1,43 @@ +1 0 +2 1862392 +3 1345760 +4 787024 +5 499600 +6 747160 +7 521072 +8 422168 +9 895960 +10 133576 +11 321824 +12 90128 +13 179384 +14 0 +15 292552 +16 0 +17 264384 +18 0 +19 0 +20 0 +21 0 +22 0 +23 0 +24 0 +25 152456 +26 0 +27 0 +28 0 +29 68432 +30 0 +31 0 +32 0 +33 0 +34 115368 +35 122216 +36 0 +37 202608 +38 0 +39 0 +40 543200 +41 0 +42 0 + diff --git a/Tasks/SemanticVoxelLabeling/torch/model.lua b/Tasks/SemanticVoxelLabeling/torch/model.lua index 2060c52..3e2de99 100644 --- a/Tasks/SemanticVoxelLabeling/torch/model.lua +++ b/Tasks/SemanticVoxelLabeling/torch/model.lua @@ -22,7 +22,7 @@ end -- create net if (opt.retrain == '' or opt.retrain == nil) then - local nf0 = 8 + local nf0 = 32 net:add(cudnn.VolumetricConvolution(2, nf0, 4, 3, 3, 2, 2, 2)) -- output nf0 x 30x15x15 net:add(cudnn.VolumetricBatchNormalization(nf0)) net:add(cudnn.ReLU()) @@ -34,7 +34,7 @@ if (opt.retrain == '' or opt.retrain == nil) then net:add(cudnn.ReLU()) net:add(nn.VolumetricDropout(0.2)) - local nf1 = 16 + local nf1 = 64 net:add(cudnn.VolumetricConvolution(nf0, nf1, 4, 3, 3, 2, 2, 2)) -- output nf1 x 14x7x7 net:add(cudnn.VolumetricBatchNormalization(nf1)) net:add(cudnn.ReLU()) @@ -46,7 +46,7 @@ if (opt.retrain == '' or opt.retrain == nil) then net:add(cudnn.ReLU()) net:add(nn.VolumetricDropout(0.2)) - local nf2 = 32 + local nf2 = 128 net:add(cudnn.VolumetricConvolution(nf1, nf2, 4, 3, 3, 2, 2, 2)) -- output nf x 6x3x3 net:add(cudnn.VolumetricBatchNormalization(nf2)) net:add(cudnn.ReLU()) diff --git a/Tasks/SemanticVoxelLabeling/torch/provider.lua b/Tasks/SemanticVoxelLabeling/torch/provider.lua index 44ba499..49ecbee 100644 --- a/Tasks/SemanticVoxelLabeling/torch/provider.lua +++ b/Tasks/SemanticVoxelLabeling/torch/provider.lua @@ -2,6 +2,10 @@ require 'torch' require 'hdf5' +function trim(s) + return (s:gsub("^%s*(.-)%s*$", "%1")) +end + function readClassesHist(file, num_classes) assert(paths.filep(file)) counts = torch.zeros(num_classes) @@ -43,7 +47,7 @@ end function getDataFiles(input_file) local train_files = {} for line in io.lines(input_file) do - train_files[#train_files+1] = line + train_files[#train_files+1] = trim(line) end return train_files end diff --git a/Tasks/SemanticVoxelLabeling/torch/train.lua b/Tasks/SemanticVoxelLabeling/torch/train.lua index 2b1a763..5cf8234 100644 --- a/Tasks/SemanticVoxelLabeling/torch/train.lua +++ b/Tasks/SemanticVoxelLabeling/torch/train.lua @@ -13,7 +13,7 @@ opt_string = [[ -b,--batchSize (default 64) batch size -r,--learningRate (default 0.01) learning rate --learningRateDecay (default 1e-7) learning rate decay - --weigthDecay (default 0.0005) weight decay + --weigthDecay (default 0.001) weight decay -m,--momentum (default 0.9) mementum --epoch_step (default 20) epoch step -g,--gpu_index (default 0) GPU index (start from 0) diff --git a/WebUI/.editorconfig b/WebUI/.editorconfig new file mode 100644 index 0000000..e717f5e --- /dev/null +++ b/WebUI/.editorconfig @@ -0,0 +1,13 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/WebUI/.gitignore b/WebUI/.gitignore new file mode 100644 index 0000000..3cd787d --- /dev/null +++ b/WebUI/.gitignore @@ -0,0 +1,31 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# Commenting this out is preferred by some people, see +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- +node_modules + +# Users Environment Variables +.lock-wscript + +lib/ +data/ diff --git a/WebUI/.jshintrc b/WebUI/.jshintrc new file mode 100644 index 0000000..1c271e2 --- /dev/null +++ b/WebUI/.jshintrc @@ -0,0 +1,29 @@ +{ + "node": true, + "esnext": true, + "bitwise": true, + "camelcase": true, + "curly": true, + "eqeqeq": true, + "immed": true, + "indent": 2, + "latedef": "nofunc", + "newcap": false, + "noarg": true, + "quotmark": "single", + "regexp": true, + "undef": true, + "unused": false, + "strict": false, + "trailing": true, + "smarttabs": true, + "white": false, + "globals": { + "it": true, + "describe": true, + "before": true, + "beforeEach": true, + "after": true, + "afterEach": true + } +} diff --git a/WebUI/.npmignore b/WebUI/.npmignore new file mode 100644 index 0000000..40e14ef --- /dev/null +++ b/WebUI/.npmignore @@ -0,0 +1,30 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# Commenting this out is preferred by some people, see +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- +node_modules + +# Users Environment Variables +.lock-wscript + +data/ diff --git a/WebUI/README.md b/WebUI/README.md new file mode 100644 index 0000000..e3a09c8 --- /dev/null +++ b/WebUI/README.md @@ -0,0 +1,84 @@ +# ScanNet WebUI + +> Web interface for ScanNet + +## About + +This project uses [Feathers](http://feathersjs.com). An open source web framework for building modern real-time applications. + +## Getting Started + +Getting up and running is as easy as 1, 2, 3. + +1. Make sure you have [NodeJS](https://nodejs.org/) and [npm](https://www.npmjs.com/) installed. +2. Install your dependencies + + ``` + cd WebUI; npm install + ``` + +3. Start your app + + ``` + npm start + ``` + +## Endpoints + +Web pages +``` +/scans/manage # Main manage view (supports feather style querying) +/scans/annotations # IFrame of annotations +/scans/devices/id # Devices by id +/scans/devices/name # Devices by name +/scans/scenes # Scenes by name +/scans/scenes/type # Scenes by type +/scans/users # Users +/scans/tags # Tags +/scans/browse # Browse view +/scans/browse/nyu # NYU scans +/scans/browse/nyu/frames # NYU frames +/scans/process # Process queue view +``` + +Web services +``` +/scans/list +/api/scans # Returns json of all the scans (supports feather style querying) + +/scans/index # Reindex everything +/scans/index/ # Reindex specified scan +/scans/monitor/convert_video/ # Converts h264 to mp4 and thumbnails + +/scans/process/ # Adds scan to process queue +/scans/edit # Edits metadata associated with a scan (follows DataTables editor client-server protocol) +/scans/populate # Updates scans +``` + +## Testing + +Simply run `npm test` and all your tests in the `test/` directory will be run. + +## Scaffolding + +Feathers has a powerful command line interface. Here are a few things it can do: + +``` +$ npm install -g feathers-cli # Install Feathers CLI + +$ feathers generate service # Generate a new Service +$ feathers generate hook # Generate a new Hook +$ feathers generate model # Generate a new Model +$ feathers help # Show all commands +``` + +## Help + +For more information on all the things you can do with Feathers visit [docs.feathersjs.com](http://docs.feathersjs.com). + +## Changelog + +__0.0.0__ + +- Initial release + diff --git a/WebUI/config/default.json b/WebUI/config/default.json new file mode 100644 index 0000000..5ef1b9e --- /dev/null +++ b/WebUI/config/default.json @@ -0,0 +1,29 @@ +{ + "host": "localhost", + "port": 3030, + "nedb": "../data/", + "public": "../public/", + "settings": { + "segmentAnnotatorUrl": "http://localhost/scans/segment-annotator-single", + "segmentAnnotationsUrl": "http://localhost/scans/segment-annotations", + "segmentAnnotationViewerUrl": "http://localhost/scans/segment-annotations/view", + "scanFilesPath": "http://localhost/data/scannet/scans", + "scansPaths": { + "nyuv2": "/data/nyuv2", + "default": "/data/scannet/scans" + } + }, + "auth": { + "token": { + "secret": "" + }, + "local": {}, + "github": { + "clientID": "your github client id", + "clientSecret": "your github client secret", + "permissions": { + "scope": [] + } + } + } +} diff --git a/WebUI/config/production.json b/WebUI/config/production.json new file mode 100644 index 0000000..0a6c6c3 --- /dev/null +++ b/WebUI/config/production.json @@ -0,0 +1,19 @@ +{ + "host": "ScanNet-app.feathersjs.com", + "port": 80, + "nedb": "NEDB_BASE_PATH", + "public": "../public/", + "auth": { + "token": { + "secret": "FEATHERS_AUTH_SECRET" + }, + "local": {}, + "github": { + "clientID": "your github client id", + "clientSecret": "your github client secret", + "permissions": { + "scope": [] + } + } + } +} diff --git a/WebUI/package.json b/WebUI/package.json new file mode 100644 index 0000000..c9371e3 --- /dev/null +++ b/WebUI/package.json @@ -0,0 +1,61 @@ +{ + "name": "ScanNet WebUI", + "description": "Web interface for ScanNet", + "version": "0.0.0", + "homepage": "", + "main": "src/", + "keywords": [ + "feathers" + ], + "license": "MIT", + "repository": {}, + "author": {}, + "contributors": [], + "bugs": {}, + "engines": { + "node": ">= 0.12.0" + }, + "scripts": { + "test": "npm run jshint && npm run mocha", + "jshint": "jshint src/. test/. --config", + "start": "node src/", + "mocha": "mocha test/ --recursive" + }, + "dependencies": { + "better-queue": "^3.7.21", + "better-queue-memory": "^1.0.1", + "better-queue-sql": "^1.0.0", + "body-parser": "^1.15.2", + "compression": "^1.6.2", + "cors": "^2.8.0", + "csv": "^1.1.0", + "express-http-proxy": "^0.10.0", + "express-winston": "^2.0.x", + "feathers": "^2.0.1", + "feathers-authentication": "^0.7.9", + "feathers-configuration": "^0.2.3", + "feathers-errors": "^2.4.0", + "feathers-hooks": "^1.5.7", + "feathers-nedb": "^2.5.1", + "feathers-rest": "^1.4.4", + "feathers-sequelize": "^1.3.2", + "feathers-socketio": "^1.4.1", + "jade": "^1.11.0", + "lodash": "^4.15.0", + "nedb": "^1.8.0", + "node-uuid": "^1.4.7", + "passport": "^0.3.2", + "passport-github": "^1.1.0", + "passport-github-token": "^2.1.0", + "request-promise-native": "^1.0.3", + "serve-favicon": "^2.3.0", + "sqlite3": "^3.1.10", + "winston": "^2.2.0", + "winston-context": "^0.0.7" + }, + "devDependencies": { + "jshint": "^2.9.3", + "mocha": "^3.0.2", + "request": "^2.74.0" + } +} diff --git a/WebUI/public/css/basic.css b/WebUI/public/css/basic.css new file mode 100644 index 0000000..c19066b --- /dev/null +++ b/WebUI/public/css/basic.css @@ -0,0 +1,94 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html, body { + font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif'; + font-weight: 400; + font-size: 16px; + color: #333; +} + +.center-text { + text-align: center; +} + +main { + margin-top: 20px; + padding: 20px; +} + +img.logo { + display: block; + margin: 0 auto; + max-width: 100%; + margin-bottom: 30px; +} + +h2 { + font-size: 2em; + font-weight: 100; +} + +footer { + position: absolute; + bottom: 0; + left: 0; + right: 0; + padding: 20px; +} + +footer p { + font-weight: 300; + font-size: 1.0em; +} + +a { + color: green; + text-decoration: none; +} + +a:hover, +a:focus { + color: green; +} + +tfoot input { + width: 100%; +} + +.ui-autocomplete { + max-height: 100px; + overflow-y: auto; + /* prevent horizontal scrollbar */ + overflow-x: hidden; +} + +.progress-strip { + border-radius: 10px; + padding: 5px; + width: 10px; + height: 20px; +} + +.progress-strip:hover { + opacity:0.6; +} + +.progress-ok { + background: green; +} + +.progress-none { + background: gray; +} + +.progress-failed { + background: red; +} + +.videoPreview { + cursor: pointer; +} diff --git a/WebUI/public/css/common.css b/WebUI/public/css/common.css new file mode 100644 index 0000000..a974ded --- /dev/null +++ b/WebUI/public/css/common.css @@ -0,0 +1,129 @@ +/* MAIN UI */ + +html * { + font-family: 'Open Sans', sans-serif; +} + +body { + background-color: transparent; + margin: 0; + overflow: hidden; +} + +#sidebar { + position: absolute; + top: 0; + right: 0; + width: 23%; + height: 100%; + min-height: 100%; +} + +#main { + position: absolute; + left: 0; + top: 0; + width: 75%; + height: 100%; +} + +#canvas { + position: absolute; + overflow: hidden; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: transparent; +} + +#canvas:focus { + outline: none; +} + +.grayBackground { + background-color: gainsboro; +} + +.roundBorder { + -moz-border-radius: 8px; + -webkit-border-radius: 8px; + -ms-border-radius: 8px; + -o-border-radius: 8px; + border-radius: 8px; +} + +#instructionsPanel { + position: absolute; + top: 30px; + left: 20px; + padding: 5px; + cursor: pointer; + opacity: 0.8; + z-index: 1; + border: thin solid #A5A5A5; +} + +/* Pagination stuff */ + +.pagination a { + text-decoration: none; + border: solid 1px #AAE; +} + +.pagination a, .pagination span { + display: block; + float: left; + padding: 0.1em 0.2em; + margin-right: 5px; + margin-bottom: 5px; + min-width: 0.5em; + text-align: center; +} + +.pagination .current { + background: #26B; + color: #fff; + border: solid 1px #AAE; +} + +.pagination .current.prev, .pagination .current.next { + color: #999; + border-color: #999; + background: #fff; +} + +.highlight { + background-color: #FFFF88; +} + +.btn-file { + position: relative; + overflow: hidden; +} +.btn-file input[type=file] { + position: absolute; + top: 0; + right: 0; + min-width: 100%; + min-height: 100%; + font-size: 100px; + text-align: right; + filter: alpha(opacity=0); + opacity: 0; + outline: none; + background: white; + cursor: inherit; + display: block; +} + +.helpicon { + cursor: default; + float: right; + color: silver; +} + +input[readonly] { + background-color: white !important; + cursor: text !important; +} \ No newline at end of file diff --git a/WebUI/public/css/datgui-light.css b/WebUI/public/css/datgui-light.css new file mode 100644 index 0000000..9acc4f4 --- /dev/null +++ b/WebUI/public/css/datgui-light.css @@ -0,0 +1,62 @@ +.dg.main.taller-than-window .close-button { + border-top: 1px solid #ddd; +} + +.dg.main .close-button { + background-color: #ccc; +} + +.dg.main .close-button:hover { + background-color: #ddd; +} + +.dg { + color: #555; + text-shadow: none !important; +} + +.dg.main::-webkit-scrollbar { + background: #fafafa; +} + +.dg.main::-webkit-scrollbar-thumb { + background: #bbb; +} + +.dg li:not(.folder) { + background: #fafafa; + border-bottom: 1px solid #ddd; +} + +.dg li.save-row .button { + text-shadow: none !important; +} + +.dg li.title { + background: #e8e8e8 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat; +} + +.dg .cr.function:hover,.dg .cr.boolean:hover { + background: #fff; +} + +.dg .c input[type=text] { + background: #e9e9e9; +} + +.dg .c input[type=text]:hover { + background: #eee; +} + +.dg .c input[type=text]:focus { + background: #eee; + color: #555; +} + +.dg .c .slider { + background: #e9e9e9; +} + +.dg .c .slider:hover { + background: #eee; +} \ No newline at end of file diff --git a/WebUI/public/css/model-viewer.css b/WebUI/public/css/model-viewer.css new file mode 100644 index 0000000..b35c78a --- /dev/null +++ b/WebUI/public/css/model-viewer.css @@ -0,0 +1,355 @@ + +.input-group-btn { + width: auto; +} + +.search { + width: 100%; +} + +.ui-tabs-panel { + padding: 0 !important; +} + +#textureSearchPanel { + position: relative; + height: 100%; +} + +#modelTexturesPanel { + position: relative; + height: 50%; +} + +#colorsPanel { + position: relative; + height: 100%; +} + +#imagesPanel { + position: relative; + height: 100%; +} + +.imageResults { + position: absolute; + width: 100%; + top: 0; + overflow: auto; + border: #00aadd solid 1px; +} + +img.enlarged { + opacity:0.2; + filter:alpha(opacity=20); +} + +.large img { + position:absolute; + max-width: 250px; + max-height: 250px; + border-width: 1px; + border-style:solid; + border-color:lightgray; +} +.large img:hover { + z-index: 50; +} + +#scaleLine { + position: absolute; + left: 0; + bottom: 5px; + width: 100%; + overflow: auto; + white-space: nowrap; +} + +#scaleLine .spacer +{ + width: 5px; + display: inline-block; + visibility: hidden; +} + +#scaleLine .bar +{ + width: 5px; + display: inline-block; + background-color: #aaaaaa; +} + +#scaleLine .bar:hover +{ + background-color: #00aadd; +} + +#scaleLine .refObject { + display: inline-block; + position: relative; + cursor: default; + text-align:center; +} + +#scaleLine .refObject > * { + font: 18px bold sans-serif; + color: white; + padding: 5px; +} + +#scaleLine .refObject:hover { + background-color: #00aadd; +} + +.scaleLineArrowDiv { + position: absolute; + height: 100%; + background-color: #EF9F56; + opacity: 0.8; +} + +#materialsPanel { + position: absolute; + top: 30px; + right: 20px; + padding: 5px; + cursor: pointer; + opacity: 0.8; + z-index: 1; + border: thin solid #A5A5A5; +} + +#materialsPanel .modelMaterial:hover { + background-color: rgba(0, 170, 221, 0.75); +} + +#materialsPanel .modelMaterialSelected { + background-color: #EF9F56; +} + +#modelTexturesPanel img { + max-height:100%; + max-width:100%; +} + +#tabs { + height: 90%; +} + +#tabs-1, #tabs-2, #tabs-3, #tabs-4, #tabs-5 #tabs-6 { + height: 90%; +} + +#loadFixedModel { + display: none; +} + +#annotateTextures div.formPart { + padding: 5px; +} + +#categorizerPanel { + padding: 15px; + width: 100%; + height: 85%; +} + +#sizeTextbox +{ + position: absolute; + left: 35%; + z-index: 100; + width: 50px; + font: 14pt sans-serif; + padding: 6px; + text-align: center; +} + +.scrollableDiv { + position: relative; + overflow: auto; +} + +#previewPane { + position: relative; + width: 100%; + height: 92%; + overflow: hidden; +} + +#previewPane .scrollableDiv { + border: #00aadd solid 1px; +} + +#previewPane .previewImage { + max-height:100%; + max-width:100%; +} + +#previewPane .previewImage:hover { + outline: #00aadd solid thick; +} + +#numCheckedMsg { + position: absolute; + right: 0; +} + +#selectedPane { + position: relative; + width: 100%; + height: 92%; + overflow: hidden; +} + +#selectedPane .scrollableDiv { + border: #00aadd solid 1px; +} + +#selectedPane .previewImage { + max-height:100%; + max-width:100%; +} + +#selectedPane .previewImage:hover { + outline: #00aadd solid thick; +} + +.selectedCategory { + background-color: #00aadd; + color: #ffffff; +} + +.selectedCatNum { + text-align: right; +} + +#categoriesPanel { + max-height: 100%; + overflow: auto; +} + +#categoriesPanel .categoryName { + color: #00aadd; + cursor: pointer; +} + +#categoriesPanel .categoryName:hover { + background-color: #EF9F56; +} + +.materialNode { + width: 12px; + height: 8px; + display: inline-block; + background-repeat: no-repeat; + background-size: 8px 8px; +} + +.materialNodeExpanded { + background-image: url("../resources/images/arrowDown.svg"); +} + +.materialNodeClosed { + background-image: url("../resources/images/arrowRight.svg"); +} + +.tabsToolbar { + position: absolute; + right: 10px; + z-index: 10; +} + +.tabsToolbar > img { + opacity:0.6; + filter:alpha(opacity=60); +} + +.tabsToolbar > img:hover { + opacity:1.0; + filter:alpha(opacity=100); +} + +.imageButton { + opacity:0.6; + filter:alpha(opacity=60); +} + +.imageButton:hover { + opacity:1.0; + filter:alpha(opacity=100); +} + +.grayRadialBackground { + background: #7d7e7d; /* Old browsers */ + /* IE9 SVG, needs conditional override of 'filter' to 'none' */ + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPHJhZGlhbEdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IjUwJSIgcj0iNzUlIj4KICAgIDxzdG9wIG9mZnNldD0iMCUiIHN0b3AtY29sb3I9IiM3ZDdlN2QiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjMGUwZTBlIiBzdG9wLW9wYWNpdHk9IjEiLz4KICA8L3JhZGlhbEdyYWRpZW50PgogIDxyZWN0IHg9Ii01MCIgeT0iLTUwIiB3aWR0aD0iMTAxIiBoZWlnaHQ9IjEwMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); + background: -moz-radial-gradient(center, ellipse cover, #7d7e7d 0%, #0e0e0e 100%); /* FF3.6+ */ + background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#7d7e7d), color-stop(100%,#0e0e0e)); /* Chrome,Safari4+ */ + background: -webkit-radial-gradient(center, ellipse cover, #7d7e7d 0%,#0e0e0e 100%); /* Chrome10+,Safari5.1+ */ + background: -o-radial-gradient(center, ellipse cover, #7d7e7d 0%,#0e0e0e 100%); /* Opera 12+ */ + background: -ms-radial-gradient(center, ellipse cover, #7d7e7d 0%,#0e0e0e 100%); /* IE10+ */ + background: radial-gradient(ellipse at center, #7d7e7d 0%,#0e0e0e 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7d7e7d', endColorstr='#0e0e0e',GradientType=1 ); /* IE6-8 fallback on horizontal gradient */ +} + +div.annotation { + margin: 5px; +} + +#customLoadingPanel { + position: absolute; + bottom: 30px; + left: 20px; + padding: 5px; + cursor: pointer; + opacity: 0.8; + z-index: 1; + border: thin solid #A5A5A5; +} + +div.pagination { + margin: 0px; +} + +.searchResults td, .searchResults th { + padding: 4px; +} + +/* Labels panel */ +.overlay { + position: absolute; + cursor: pointer; + opacity: 0.9; + z-index: 1; +} + +.btn-space { + margin-bottom: 15px; +} + +#namesPanel { + top: 20px; + right: 20px; +} + +label div { + display: inline-block; + width: 40px; + color: white; + text-align: center; + margin-right: 10px; +} + +.label-left { + text-align: left; +} + +.mouse-tooltip { + display: inline-block; + position: absolute; + pointer-events: none; + z-index: 100; +} + + diff --git a/WebUI/public/css/search-panel.css b/WebUI/public/css/search-panel.css new file mode 100644 index 0000000..b9f522d --- /dev/null +++ b/WebUI/public/css/search-panel.css @@ -0,0 +1,97 @@ +#searchPanel { + position: relative; + height: 100%; +} + +.searchPanel { + position: relative; + height: 100%; +} + +.searchResults { + position: absolute; + width: 100%; + height: 90%; + bottom: 0; + overflow: auto; + border: #aaaaaa solid 1px; +} + +.searchResult { + outline: none; +} + +.searchResult img { + outline: none; +} + +.searchResultSelected { + background-color: #ffff88; +} + +.searchResultSelected img { + opacity: 0.6; + filter: alpha(opacity=60); +} + +.searchResultNoModel img { + opacity: 0.6; + filter: alpha(opacity=60); +} + +.searchResultClicked { + background-color: #ffff00; +} + +.searchResultClicked img { + opacity: 0.6; + filter: alpha(opacity=60); +} + +.searchResult:hover { + outline: #00aadd solid thick; +} + +.searchResultLabel { + background-color: #fbec88; + border: 1px solid #aaaaaa; + display: inline-block; + padding: 2px 4px; + cursor: pointer; +} + +.searchResultLabel:hover { + border: 3px solid #EF9F56; +} + +.searchResultLabel_noedit { + cursor: default; +} + +.searchResultLabel_noedit:hover { + border: 1px solid #aaaaaa; +} + +.searchResultLabel_add { + background-color: #94F2A7; +} + +.searchResultLabel_del { + background-color: #F2B1CE; + text-decoration: line-through; +} + +.searchResultLabel img { + vertical-align: text-top; + opacity: 0.6; + filter: alpha(opacity=60); +} + +.searchResultLabel img:hover { + opacity: 1.0; + filter: alpha(opacity=100); +} + +.searchResults td, .searchResults th { + padding: 4px; +} \ No newline at end of file diff --git a/WebUI/public/favicon.ico b/WebUI/public/favicon.ico new file mode 100644 index 0000000..7ed25a6 Binary files /dev/null and b/WebUI/public/favicon.ico differ diff --git a/WebUI/public/index.html b/WebUI/public/index.html new file mode 100644 index 0000000..5ccaea9 --- /dev/null +++ b/WebUI/public/index.html @@ -0,0 +1,20 @@ + + + Welcome to ScanNet + + + + +
+

ScanNet - a dataset of 3D reconstructed scenes

+
+ + Manage + NYU +
+
+

ScanNet is great.

+
+
+ + diff --git a/WebUI/public/js/auth.js b/WebUI/public/js/auth.js new file mode 100644 index 0000000..7c26277 --- /dev/null +++ b/WebUI/public/js/auth.js @@ -0,0 +1,46 @@ +// Simplistic auth (just want to get a username) +// TODO: replace with JWT auth + +function Auth() { +} + +Auth.prototype.authenticate = function(onSuccess) { + var user = window.localStorage.getItem('user'); + if (user) { + onSuccess(JSON.parse(user)); + } else { + bootbox.prompt({ + title: "Please enter your username", + inputType: 'text', + callback: function (result) { + if (result) { + var user = { username: result }; + window.localStorage.setItem('user', JSON.stringify(user)); + onSuccess(user); + } + } + }); + } +}; + +Auth.prototype.addCheck = function(element) { + var scope = this; + var toCheck = element.find('[data-check-auth=true]'); + toCheck.each(function(index) { + var el = $(this); + el.off('click'); + el.click(function() { + scope.authenticate(function(user) { + if (el.attr('href')) { + var url = el.attr('href'); + url = url.replace('[username]', user.username); + var win = window.open(url, el.attr('target')); + win.focus(); + } + }) + return false; + }); + }); +}; + + diff --git a/WebUI/public/js/browse.js b/WebUI/public/js/browse.js new file mode 100644 index 0000000..c0e3f2f --- /dev/null +++ b/WebUI/public/js/browse.js @@ -0,0 +1,45 @@ + var ModelViewer = STK.ModelViewer; + var tabsDiv = $('#tabs'); + tabsDiv.tabs().css({ 'min-height': '400px', 'overflow': 'auto' }); + var canvas = document.getElementById('canvas'); + var modelViewer = new ModelViewer({ + container: canvas, + sources: ['vf'], + useNewImages: true, + tooltipIncludeExtraFields: ['sceneLabel', 'sceneType'], + partsPanel: { + partTypes: ['none', 'surfaces', 'voxels-solid', 'voxels-surface', 'voxels-labeled'], + defaultPartType: 'none', + defaultLabelType: 'Raw' + } + }); + var modelId = getUrlParam('modelId'); + var scanNetStagingIndexPath = '/data/scannet/scans/staging/scannet'; + var scanNetCheckedIndexPath = '/data/scannet/scans/checked/scannet'; + var nyuv2IndexPath = '/data/external/nyuv2/nyuv2'; + modelViewer.launch(); + modelViewer.registerCustomModelAssetGroup(scanNetStagingIndexPath + '.csv', scanNetStagingIndexPath + '.json', + (modelId && modelId.startsWith('scan-staging')) ? 'fullId:' + modelId : undefined); + modelViewer.registerCustomModelAssetGroup(scanNetCheckedIndexPath + '.csv', scanNetCheckedIndexPath + '.json', + (modelId && modelId.startsWith('scan-checked')) ? 'fullId:' + modelId : (!(modelId)? 'hasCleaned:True' : undefined) ); + modelViewer.registerCustomModelAssetGroup(nyuv2IndexPath + '.csv', nyuv2IndexPath + '.json', + (modelId && modelId.startsWith('nyuv2')) ? 'fullId:' + modelId : undefined); + tabsDiv.bind('tabsactivate', function (event, ui) { + switch (ui.newPanel.attr('id')) { + case 'tabs-1': + modelViewer.modelSearchController.onResize(); + break; + case 'tabs-7': + modelViewer.modelImagesPanel.onResize(); + break; + } + }); + $('#instructions').hide(); + $('#instructionsPanel').click(function () { + $('#instructions').toggle(); + }); + // Make various components draggable + $('#namesPanel').draggable(); + $('#customLoadingPanel').draggable(); + $('#instructionsPanel').draggable(); + window.app = modelViewer; // For console debugging diff --git a/WebUI/public/js/datatables.js b/WebUI/public/js/datatables.js new file mode 100644 index 0000000..90ac5f0 --- /dev/null +++ b/WebUI/public/js/datatables.js @@ -0,0 +1,454 @@ +// Utility functions for working with datatables +// See https://datatables.net + +// Utility functions for creating html for datatables +function getValues(data, field, includeValues) { + var values = _.map(data, function(d) { return d[field]; }); + values = _.flatten(values); + values = _.filter(values, function(x) { return (x != undefined) && x.length > 0; }); + if (includeValues) { + values = _.concat(values, includeValues); + } + values = _.uniq(values); // uniquify + values = values.sort(); + return values; +} + +function createLink(element, url, target) { + var link = $('').attr('href', url); + if (typeof element === 'string') { + link.text(element); + } else { + link.append(element); + } + if (target) { + link.attr('target', target); + } + return link; +} + +function createFilterLinks(url, data, field, opts) { + opts = opts || {}; + var queryField = opts.queryField || field; + var value = data[field]; + if (_.isArray(value)) { + var div = $('
'); + for (var i = 0; i < value.length; i++) { + var params = {}; + params[queryField] = value[i]; + div.append(createLink(value[i], url + '?' + $.param(params))); + if (i < value.length-1) { + div.append(',').append($('
')); + } + } + return div; + } else { + var params = {}; + params[queryField] = value; + var label = value; + if (opts.indicateSpecialValues) { + if (value == null) { + label = $('').append('NULL'); + } else if (value === '') { + label = $('').append('EMPTY'); + } + } + return createLink(label, url + '?' + $.param(params)); + } +} + +function createButton(label, url, desc) { + var button = $('') + .attr('class', 'btn btn-primary') + .attr('role', 'button') + .attr('href', url) + .attr('title', desc); + button.append(label); + return button; +} + +function createDropDown(label, buttons) { + var btnGroup = $('
'); + btnGroup.append(mainButton); + var menu = $('
    ').attr('class', 'dropdown-menu').attr('role', 'menu'); + for (var i = 0; i < buttons.length; i++) { + menu.append($('
  • ').attr('role', 'presentation') + .append(buttons[i].attr('role', 'menuitem').attr('tabindex', '-1'))); + } + btnGroup.append(menu); + return btnGroup; +} + +function getHtml(element) { + if (typeof element === 'string') { return element; } + else { + return element.get(0).outerHTML; + } +} + +// +// Pipelining function for DataTables. To be used to the `ajax` option of DataTables +// See https://datatables.net/examples/server_side/pipeline.html +// +$.fn.dataTable.pipeline = function ( opts ) { + //console.log(opts) + // Configuration options + var conf = $.extend( { + pages: 5, // number of pages to cache + url: '', // script url + data: null, // function or object with parameters to send to the server + // matching how `ajax.data` works in DataTables + method: 'GET' // Ajax HTTP method + }, opts ); + + // Private variables for storing the cache + var cacheLower = -1; + var cacheUpper = null; + var cacheLastRequest = null; + var cacheLastJson = null; + + return function ( request, drawCallback, settings ) { + var ajax = false; + var requestStart = request.start; + var drawStart = request.start; + var requestLength = request.length; + var requestEnd = requestStart + requestLength; + + if ( settings.clearCache ) { + // API requested that the cache be cleared + ajax = true; + settings.clearCache = false; + } + else if ( cacheLower < 0 || requestStart < cacheLower || requestEnd > cacheUpper ) { + // outside cached data - need to make a request + ajax = true; + } + else if ( JSON.stringify( request.order ) !== JSON.stringify( cacheLastRequest.order ) || + JSON.stringify( request.columns ) !== JSON.stringify( cacheLastRequest.columns ) || + JSON.stringify( request.search ) !== JSON.stringify( cacheLastRequest.search ) + ) { + // properties changed (ordering, columns, searching) + ajax = true; + } + + // Store the request for checking next time around + cacheLastRequest = $.extend( true, {}, request ); + + if ( ajax ) { + // Need data from the server + if ( requestStart < cacheLower ) { + requestStart = requestStart - (requestLength*(conf.pages-1)); + + if ( requestStart < 0 ) { + requestStart = 0; + } + } + + cacheLower = requestStart; + cacheUpper = requestStart + (requestLength * conf.pages); + + request.start = requestStart; + request.length = requestLength*conf.pages; + + // Provide the same `data` options as DataTables. + if ( $.isFunction ( conf.data ) ) { + // As a function it is executed with the data object as an arg + // for manipulation. If an object is returned, it is used as the + // data object to submit + var d = conf.data( request ); + if ( d ) { + $.extend( request, d ); + } + } + else if ( $.isPlainObject( conf.data ) ) { + // As an object, the data given extends the default + $.extend( request, conf.data ); + } + + // Reinterpret parameters + var requestData = { + '$limit': request.length, + '$skip': request.start + }; + if (request.order && request.order.length) { + var sort = {}; + for (var i = 0; i < request.order.length; i++) { + var s = request.order[i]; + var colname = request.columns[s.column].data; + if (colname) { + sort[colname] = (s.dir === 'asc')? +1 : -1; + } + } + requestData['$sort'] = sort; + } + // Not yet supported (see https://github.com/feathersjs/feathers/issues/334) + //if (request.search && request.search.value) { + // requestData['$search'] = [request.search.value]; + //} + console.log('requesting data from ' + conf.url, request, requestData); + settings.jqXHR = $.ajax( { + 'type': conf.method, + 'url': conf.url, + 'data': requestData, + 'dataType': 'json', + 'cache': false, + 'success': function ( json ) { + console.log(json); + json.recordsFiltered = json.total; + json.recordsTotal = json.totalAll; + + cacheLastJson = $.extend(true, {}, json); + + if ( cacheLower != drawStart ) { + json.data.splice( 0, drawStart-cacheLower ); + } + if ( requestLength >= -1 ) { + json.data.splice( requestLength, json.data.length ); + } + + drawCallback( json ); + } + } ); + } + else { + var json = $.extend( true, {}, cacheLastJson ); + json.draw = request.draw; // Update the echo for each response + json.data.splice( 0, requestStart-cacheLower ); + json.data.splice( requestLength, json.data.length ); + + drawCallback(json); + } + }; +}; + +// Define custom buttons (see https://datatables.net/extensions/buttons/custom) +$.fn.dataTable.ext.buttons.orderNeutral = { + text: 'Default order', + action: function ( e, dt, node, config ) { + dt.order.neutral().draw(); + } +}; + +$.fn.dataTable.addFooters = function(opts) { + var table = opts.table; + var columns = opts.columns; + var tfoot = table.find('tfoot'); + if (!tfoot.length) { + tfoot = $(''); + table.append(tfoot); + } + var tfr = tfoot.find('tr'); + if (!tfr.length) { + tfr = $(''); + tfoot.append(tfr); + } + for (var i = 0; i < columns.length; i++) { + var title = columns[i].title; + tfr.append($('').text(title)); + } +}; + +$.fn.dataTable.addColumnFilters = function(opts) { + var table = opts.table; + // // Setup - add a text input to each footer cell + // table.find('tfoot th').each( function () { + // var title = $(this).text(); + // $(this).html( '' ); + // }); + + var state = table.DataTable().state(); + // Apply the search + var columns = table.DataTable().settings().init().columns; + table.DataTable().columns().every( function (index) { + var searchable = columns[index].searchable !== false; + var searchText = state? state.columns[index].search.search : ''; + if (searchable) { + var that = this; + var data = this.data(); + // Build up values + var values = data + .flatten() + .map( function(x) { return (x != undefined)? x.toString() : null; }) + .filter( function(x) { return (x != undefined) && x.length > 0; }) + .sort() // Sort data alphabetically + .unique() + .toArray(); + var title = $(this.footer()).text(); + var maxTextLength = values.length > 0? + Math.max.apply(null, values.map( function(x) { return x.length; })) : 0; + + var input = $('"') + .val(searchText) + .attr('size', Math.min(20,maxTextLength+2)) + .appendTo( $(this.footer()).empty() ) + .on('keyup change', function () { + if (that.search() !== this.value) { + that.search( this.value ).draw(); + } + }) // Trigger search + .autocomplete({ + minLength: 0, + source: values, + position: { + my: 'left bottom', at: 'left top' + }, + select: function (event, ui) { + var value = ui.item.value; + if (that.search() !== value) { + that.search( value ).draw(); + } + } + }); // Set up autocomplete + } + }); +}; + +$.fn.dataTable.addColumnAggregations = function(opts) { + var table = opts.table; + // // Setup - add a text input to each footer cell + // table.find('tfoot th').each( function () { + // var title = $(this).text(); + // $(this).html( '' ); + // }); + + var state = table.DataTable().state(); + // Apply the search + var columns = table.DataTable().settings().init().columns; + table.DataTable().columns().every( function (index) { + var aggregation = columns[index].aggregation; + if (aggregation === 'sum' || aggregation === 'avg' || aggregation === 'average') { + var that = this; + var data = this.data(); + + // Remove the formatting to get integer data for summation + var numVal = function ( i ) { + return (typeof i === 'string') ? i.replace(/[\$,]/g, '')*1 : + (typeof i === 'number') ? + i : 0; + }; + // Total over all pages + count = data.length; + total = data + .reduce( function (a, b) { + return numVal(a) + numVal(b); + }, 0 ); + + // Total over this page + // pageTotal = table.DataTable() + // .column( iCol, { page: 'current'} ) + // .data() + // .reduce( function (a, b) { + // return numVal(a) + numVal(b); + // }, 0 ); + + if (aggregation === 'avg' || aggregation === 'average') { + aggregate = total / data.count(); + } else { + aggregate = total; + } + + // Update footer + $( this.footer() ).html( + aggregate +// pageTotal +' ( '+ total +' total)' + ); + } + }); +}; + + +$.fn.dataTable.getLazyImgLoadCallback = function() { + var loadedCount = 0; + return function( row, aData, iDisplayIndex ) { + //console.log(row, aData, iDisplayIndex); + var imgs = $(row).find('img.lazy'); + imgs.each(function( index ) { + var img = $(this); + if (img.attr('src') !== img.attr('data-src')) { + loadedCount += 1; + console.log('setting src ' + img.attr('data-src') + ' for ' + loadedCount); + img.attr('src', img.attr('data-src')); + } + }); + }; +}; + + +// Register an API method that will empty the pipelined data, forcing an Ajax +// fetch on the next draw (i.e. `table.clearPipeline().draw()`) +$.fn.dataTable.Api.register( 'clearPipeline()', function () { + return this.iterator( 'table', function ( settings ) { + settings.clearCache = true; + } ); +} ); + +// Order neutral from https://datatables.net/plug-ins/api/order.neutral() +// //cdn.datatables.net/plug-ins/1.10.12/api/order.neutral().js +$.fn.dataTable.Api.register( 'order.neutral()', function () { + return this.iterator( 'table', function ( s ) { + s.aaSorting.length = 0; + s.aiDisplay.sort( function (a,b) { + return a-b; + } ); + s.aiDisplayMaster.sort( function (a,b) { + return a-b; + } ); + } ); +} ); + + +// Plugin for jquery ui autocomplete +// https://editor.datatables.net/plug-ins/field-type/editor.autoComplete +(function ($, DataTable) { + + + if ( ! DataTable.ext.editorFields ) { + DataTable.ext.editorFields = {}; + } + + var _fieldTypes = DataTable.Editor ? + DataTable.Editor.fieldTypes : + DataTable.ext.editorFields; + + _fieldTypes.autoComplete = { + create: function ( conf ) { + conf._input = $('') + .autocomplete( conf.opts || {} ); + + return conf._input[0]; + }, + + get: function ( conf ) { + return conf._input.val(); + }, + + set: function ( conf, val ) { + conf._input.val( val ); + }, + + enable: function ( conf ) { + conf._input.autocomplete( 'enable' ); + }, + + disable: function ( conf ) { + conf._input.autocomplete( 'disable' ); + }, + + // Non-standard Editor method - custom to this plug-in + node: function ( conf ) { + return conf._input; + }, + + update: function ( conf, options ) { + conf._input.autocomplete( 'option', 'source', options ); + } + }; + + +})(jQuery, jQuery.fn.dataTable); diff --git a/WebUI/public/js/devicesById.js b/WebUI/public/js/devicesById.js new file mode 100644 index 0000000..56c4486 --- /dev/null +++ b/WebUI/public/js/devicesById.js @@ -0,0 +1,58 @@ +function createActionButtons(device) { + var div = $('
    '); + div.append(createButton('Scans', '/scans/manage?deviceId=' + device.id, 'View scans')); + return div; +} + +function initResultTable(params) { + params = params || {}; + var data = params.data; + + var lazyImgLoadCallback = $.fn.dataTable.getLazyImgLoadCallback(); + var resultTable = $("#resultTable"); + resultTable.dataTable({ + "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]], + "order": [], + "deferRender": false, + "stateSave": true, + "data": data, + "dom": 'BlfripFtip', + "buttons": [ + 'csv', 'colvis', 'orderNeutral', 'selectAll', 'selectNone' + ], + "select": { + style: 'multi' + }, + "columns": [ + { "data": "id", + "defaultContent": "" }, + { "data": "names", + "type": "array", + "defaultContent": "", + "render": function ( data, type, full, meta ) { + return getHtml(createFilterLinks('/scans/manage', full, 'names', { queryField: 'deviceName' })); + } + }, + { "data": "scans.length", + "defaultContent": "" }, + { // Action buttons + "data": null, + "orderable": false, + "searchable": false, + "render": function ( data, type, full, meta ) { + return getHtml(createActionButtons(full)); + } + } + ], + "rowCallback": function( row, aData, iDisplayIndex ) { + //console.log(row, aData, iDisplayIndex); + lazyImgLoadCallback(row, aData, iDisplayIndex); + return row; + }, + "initComplete": function() { + $.fn.dataTable.addColumnFilters({ table: resultTable }); + resultTable.css('visibility', 'visible'); + $('#loadingMessage').hide(); + } + }); +} diff --git a/WebUI/public/js/devicesByName.js b/WebUI/public/js/devicesByName.js new file mode 100644 index 0000000..7160870 --- /dev/null +++ b/WebUI/public/js/devicesByName.js @@ -0,0 +1,60 @@ +function createActionButtons(device) { + var div = $('
    '); + div.append(createButton('Scans', '/scans/manage?deviceName=' + device.name, 'View scans')); + return div; +} + +function initResultTable(params) { + params = params || {}; + var data = params.data; + + var lazyImgLoadCallback = $.fn.dataTable.getLazyImgLoadCallback(); + var resultTable = $("#resultTable"); + resultTable.dataTable({ + "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]], + "order": [], + "deferRender": false, + "stateSave": true, + "data": data, + "dom": 'BlfripFtip', + "buttons": [ + 'csv', 'colvis', 'orderNeutral', 'selectAll', 'selectNone' + ], + "select": { + style: 'multi' + }, + "columns": [ + { "data": "ids", + "type": "array", + "defaultContent": "", + "render": function ( data, type, full, meta ) { + return getHtml(createFilterLinks('/scans/manage', full, 'ids', { queryField: 'deviceId' })); + } + }, + { "data": "name", + "defaultContent": "" + }, + { "data": "scans.length", + "defaultContent": "" }, + { // Action buttons + "data": null, + "orderable": false, + "searchable": false, + "render": function ( data, type, full, meta ) { + return getHtml(createActionButtons(full)); + } + } + ], + "rowCallback": function( row, aData, iDisplayIndex ) { + //console.log(row, aData, iDisplayIndex); + //console.log(row, aData, iDisplayIndex); + lazyImgLoadCallback(row, aData, iDisplayIndex); + return row; + }, + "initComplete": function() { + $.fn.dataTable.addColumnFilters({ table: resultTable }); + resultTable.css('visibility', 'visible'); + $('#loadingMessage').hide(); + } + }); +} diff --git a/WebUI/public/js/download.js b/WebUI/public/js/download.js new file mode 100644 index 0000000..0130eee --- /dev/null +++ b/WebUI/public/js/download.js @@ -0,0 +1,75 @@ +// Multidownload from https://github.com/sindresorhus/multi-download + +'use strict'; + +function Downloader() { +} + +Downloader.prototype.__fallback = function(urls) { + var i = 0; + + (function createIframe() { + var frame = document.createElement('iframe'); + frame.style.display = 'none'; + frame.src = urls[i++]; + document.documentElement.appendChild(frame); + + // the download init has to be sequential otherwise IE only use the first + var interval = setInterval(function () { + if (frame.contentWindow.document.readyState === 'complete') { + clearInterval(interval); + + // Safari needs a timeout + setTimeout(function () { + frame.parentNode.removeChild(frame); + }, 1000); + + if (i < urls.length) { + createIframe(); + } + } + }, 100); + })(); +}; + +Downloader.prototype.__isFirefox = function() { + // sad panda :( + return /Firefox\//i.test(navigator.userAgent); +}; + +Downloader.prototype.__sameDomain = function(url) { + var a = document.createElement('a'); + a.href = url; + + return location.hostname === a.hostname && location.protocol === a.protocol; +}; + +Downloader.prototype.__download = function(url) { + var a = document.createElement('a'); + a.download = ''; + a.href = url; + // firefox doesn't support `a.click()`... + a.dispatchEvent(new MouseEvent('click')); +}; + +Downloader.prototype.download = function (urls) { + var self = this; + if (!urls) { + throw new Error('`urls` required'); + } + + if (typeof document.createElement('a').download === 'undefined') { + return self.__fallback(urls); + } + + var delay = 0; + + urls.forEach(function (url) { + // the download init has to be sequential for firefox if the urls are not on the same domain + if (self.__isFirefox() && !self.__sameDomain(url)) { + return setTimeout(self.__download.bind(null, url), 100 * ++delay); + } + + self.__download(url); + }); +}; diff --git a/WebUI/public/js/manage-ajax.js b/WebUI/public/js/manage-ajax.js new file mode 100644 index 0000000..d9db15f --- /dev/null +++ b/WebUI/public/js/manage-ajax.js @@ -0,0 +1,403 @@ +// Simple version of _.omit +function omit(obj, fields) { + var result = {}; + for (var x in obj) { + if (obj.hasOwnProperty(x)) { + var fi = fields.indexOf(x); + if (fi < 0) { + result[x] = obj[x]; + } + } + } + return result; +} + +function createFilterLink(data, field) { + return createFilterLinks('/scans/manage', data, field); +} + +function createActionButtons(scan) { + var div = $('
    '); + // Annotate buttons + if (scan.group === 'checked' || scan.group === 'nyuv2') { + var condition = (scan.group === 'nyuv2')? 'nyu-manual' : 'scannet-checked-manual'; + div.append(createButton('Annotate', settings.segmentAnnotatorUrl + + '?condition=' + condition + '&userId=[username]&taskMode=fixup&modelId=' + scan.modelId, 'Annotate scan') + .attr('data-check-auth', 'true') + .attr('target', '_blank')); + div.append(createButton('Annotations', settings.segmentAnnotationViewerUrl + '?modelId=' + scan.modelId, 'View raw annotations') + .attr('target', '_blank')); + } + + if (scan.queueState && scan.queueState.queued) { + div.append(createButton('Cancel', null, 'Remove from process queue') + .attr('class', scan.queueState.running? 'btn btn-danger cancelBtn' : 'btn btn-warning cancelBtn') + .attr('data-id', scan.id) + .attr('data-path', scan.path)); + } else { + if (scan.group === 'staging' && scan.path === scan.id) { + div.append(createButton('Process', null, 'Adds to process queue') + .attr('class', 'btn btn-primary processBtn') + .attr('data-id', scan.id) + .attr('data-path', scan.path)); + } + } + if (processView) { + div.append(createDropDown('Move', [ + createButton('to Top', '#', 'Move to top').attr('data-id', scan.id) + .attr('class', 'moveTopBtn'), + createButton('to End', '#', 'Move to end').attr('data-id', scan.id) + .attr('class', 'moveBottomBtn') + ])); + } + + // Details and download buttons + div.append(createButton('Details', '/api/scans/' + scan.id, 'View details')); + if (scan.group === 'staging' || scan.group === 'checked') { + div.append(createButton('Files', settings.scanFilesPath + '/' + + scan.group + '/' + scan.path, 'List files') + .attr('target', '_blank')); + div.append(createDropDown('Download', [ + createButton('Raw', '#', 'Download scan files') + .attr('data-id', scan.id) + .attr('data-path', scan.group + '/' + scan.path) + .attr('class', 'downloadRawBtn'), + createButton('All', '#', 'Download all files') + .attr('data-id', scan.id) + .attr('data-path', scan.group + '/' + scan.path) + .attr('class', 'downloadAllBtn') + ])); + } + + return div; +} + +function createPreviewImage(scan, imgurl) { + var url = '/scans/browse?modelId=' + scan.modelId; + var title = JSON.stringify(omit(scan, ['files', 'stages']), undefined, 2); + var elem = $('').attr('href', url).attr('target', '_blank') + .append($('').attr('class', 'lazy').attr('data-src', imgurl) + .attr('title', title).attr('alt', scan.id).css('max-width', '128px')); + return elem; +} + + +function createVideoElement(videoUrl) { + var video = $('').attr('src', videoUrl); + return video; +} + +function createVideoPreview(scan, imgurl) { + var url = scan.videoMp4Url; + var img = $('').attr('class', 'lazy').attr('data-src', imgurl) + .attr('alt', scan.id).css('max-width', '128px'); + if (url) { + img.addClass('videoPreview'); + img.attr('data-video', url); + return img; + } else { + return img; + } +} + +function createProgressStatusBars(scan) { + var stages = scan.stages; + if (scan.lastOkStage && stages && stages.length) { + var div = $('
    ').attr('class', 'progressBars'); + for (var i = 0; i < stages.length; i++) { + var stage = stages[i]; + var progressClass = (stage.ok == undefined)? 'progress-none' : + ((stage.ok)? 'progress-ok' : 'progress-failed'); + div.append($('').attr('class', 'progress-strip ' + progressClass).attr('title', stage.name)); + } + return div; + } +} + +function initResultTable(params) { + params = params || {}; + var serverSide = params.serverSide; + var lazyImgLoadCallback = $.fn.dataTable.getLazyImgLoadCallback(); + var resultTable = $("#resultTable"); + var ajaxUrl = params.ajax || '/scans/list'; + var data = params.data; + var auth = params.auth; + + if (params.allowEdit) { + var tagValues = getValues(data, 'tags'); + var ignoreSceneTypes = ['Please Select A Scene Type']; + // TODO: Move to a separate file + // 'Apartment', 'Closet', 'Hallway', 'Lobby' not in ipad app + var basicSceneTypes = + ['Apartment', 'Bathroom', 'Bedroom / Hotel', 'Bookstore / Library', + 'Classroom', 'Closet', 'Conference Room', 'Dining Room', 'Hallway', + 'Kitchen', 'Living room / Lounge', 'Lobby', 'Office', 'Misc.']; + var sceneTypes = getValues(data, 'sceneType', basicSceneTypes) + .filter(function(x) { return x && ignoreSceneTypes.indexOf(x) < 0; }); + var editor = new $.fn.dataTable.Editor( { + ajax: { + url: "/scans/edit", + data: function(d) { return JSON.stringify(d); }, + contentType: "application/json; charset=utf-8" + }, + table: "#resultTable", + idSrc: 'id', + fields: + [ { + label: "User", + name: "userName" + }, + { + label: "Scene Type", + name: "sceneType", + type: "autoComplete", + opts: { + 'minLength': 0, + 'source': sceneTypes + } + }, + { + label: "Scene Name", + name: "sceneName" + }, + { + label: "Tags", + name: "tags", + type: "selectize", + options: tagValues.map(function(x) { return { label: x, value: x }; }), + opts: { + //plugins: ['remove_button'], + maxItems: null, + create: true + } + } + ] + } ); + + // Activate an inline edit on click of a table cell + resultTable.on( 'click', 'tbody td.bubble', function (e) { + editor.bubble( this ); + } ); + resultTable.on( 'click', 'tbody td.inline', function (e) { + editor.inline( this ); + } ); + resultTable.on( 'click', 'tbody td.inline-selectize', function (e) { + editor.inline( this, { + onReturn: 'none', + buttons: { label: '>', fn: function () { this.submit(); } } + }); + } ); + } + resultTable.dataTable({ + "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]], + "order": [], + "deferRender": true, + "processing": serverSide, + "serverSide": serverSide, + "stateSave": true, + "data": data, + "ajax": data? undefined : (serverSide? + $.fn.dataTable.pipeline( { + url: ajaxUrl, + pages: 5 // number of pages to cache + } ) : ajaxUrl), + "dom": 'BlfripFtip', + "buttons": [ + 'csv', 'colvis', 'orderNeutral',// 'selectAll', 'selectNone' + ], + // "select": { + // style: 'multi' + // }, + "columns": [ + { // Preview image of video + "orderable": false, + "searchable": false, + "data": null, + "defaultContent": "", + "render": function ( data, type, full, meta ) { + if (full.videoThumbnailUrl) { + return getHtml(createVideoPreview(full, full.videoThumbnailUrl)); + } + } + }, + { // Preview image + "orderable": false, + "searchable": false, + "data": null, + "defaultContent": "", + "render": function ( data, type, full, meta ) { + if (full.previewUrl) { + return getHtml(createPreviewImage(full, full.previewUrl)); + } + } + }, + { "data": "id", + "visible": isNYU + }, + { "data": "createdAt", + "visible": !isNYU, + "defaultContent": "" }, + { "data": "updatedAt", + "defaultContent": "" }, + { "data": "numColorFrames", + "searchable": false, + "aggregation": "sum", + "defaultContent": "" + }, + { "data": "scanSecs", + "visible": false, + "searchable": false, + "aggregation": "sum", + "defaultContent": "" + }, + { "data": "totalProcessingSecs", + "visible": false, + "searchable": false, + "aggregation": "sum", + "defaultContent": "", + render: function ( data, type, full, meta ) { + return full.totalProcessingTime; + } + }, + { "data": "objects", + "visible": false, + "searchable": false, + "aggregation": "sum", + "defaultContent": "" + }, + { "data": "labels", + "visible": false, + "searchable": false, + "aggregation": "sum", + "defaultContent": "" + }, + { "data": "floorArea", + "visible": false, + "searchable": false, + "aggregation": "sum", + "defaultContent": "" + }, + { "data": "floorAreaFilled", + "visible": false, + "searchable": false, + "aggregation": "sum", + "defaultContent": "" + }, + { "data": "floorAreaRatio", + "visible": false, + "searchable": false, + "aggregation": "average", + "defaultContent": "" + }, + { "data": "deviceName", + "visible": !isNYU, + "defaultContent": "", + render: function ( data, type, full, meta ) { + return getHtml(createFilterLink(full, "deviceName")); + } + }, + { "data": "userName", + "visible": !isNYU, + "className": "inline", + "defaultContent": "" }, + { "data": "sceneName", + "visible": !isNYU, + "className": "inline", + "defaultContent": "", + "render": function ( data, type, full, meta ) { + if (full.sceneLabel !== full.sceneName) { + var span = $('
    ').append( + $('').text(full.sceneLabel)); + var div = $('
    '); + div.append(data).append(span); + return getHtml(div); + } else { + return data; + } + } + }, + { "data": "sceneType", + "className": "inline", + "defaultContent": "" }, + { "data": "group", + "visible": !isNYU, + "defaultContent": "", + render: function ( data, type, full, meta ) { + return getHtml(createFilterLink(full, "group")); + } + }, + { "data": "subgroup", + "visible": false, + "defaultContent": "" }, + { "data": "lastOkStage", + "defaultContent": "", + "render": function ( data, type, full, meta ) { + var progressDiv = createProgressStatusBars(full); + if (progressDiv) { + var div = $('
    '); + div.append(createFilterLink(full, "lastOkStage")).append(progressDiv); + return getHtml(div); + } else { + return data? getHtml(createFilterLink(full, "lastOkStage")) : data; + } + } + }, + { "data": "tags", + "type": "array", + "className": "inline-selectize", + "defaultContent": "" }, + { "data": "totalVertices", + "searchable": false, + "aggregation": "sum", + "defaultContent": "" + }, + { "data": "percentComplete", + "searchable": false, + "aggregation": "average", + "defaultContent": "" + }, + { // Action buttons + "orderable": false, + "searchable": false, + "data": null, + "defaultContent": "", + "render": function ( data, type, full, meta ) { + return getHtml(createActionButtons(full)); + } + } + ], + "rowCallback": function( row, aData, iDisplayIndex ) { + //console.log(row, aData, iDisplayIndex); + lazyImgLoadCallback(row, aData, iDisplayIndex); + var imgs = $(row).find('img.videoPreview'); + imgs.each(function( index ) { + var img = $(this); + if (!img.attr('data-video-bound')) { + img.click(function(event) { + var videoUrl = img.attr('data-video'); + video = createVideoElement(videoUrl); + video.click(function(event) { + video.hide(); + img.show(); + }); + img.parent().append(video); + img.hide(); + }); + img.attr('data-video-bound', true); + } + }); + processQueue.initProcessButtons(row); + if (auth) { + auth.addCheck($(row)); + } + return row; + }, + "initComplete": function() { + $.fn.dataTable.addColumnFilters({ table: resultTable }); + $.fn.dataTable.addColumnAggregations({ table: resultTable }); + resultTable.css('visibility', 'visible'); + $('#loadingMessage').hide(); + } + }); +} + diff --git a/WebUI/public/js/manage.js b/WebUI/public/js/manage.js new file mode 100644 index 0000000..4afdd46 --- /dev/null +++ b/WebUI/public/js/manage.js @@ -0,0 +1,51 @@ +function initResultTable(params) { + var lazyImgLoadCallback = $.fn.dataTable.getLazyImgLoadCallback(); + var resultTable = $("#resultTable"); + resultTable.dataTable({ + "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]], + "order": [], + "deferRender": false, + "stateSave": true, + "dom": 'BlfripFtip', + "buttons": [ + 'csv', 'colvis', 'orderNeutral', 'selectAll', 'selectNone' + ], + "select": { + style: 'multi' + }, + "columns": [ + { // Preview image + "orderable": false, + "searchable": false + }, + { "data": "id" }, + { "data": "createdAt" }, + { "data": "updatedAt" }, + { "data": "deviceName" }, + { "data": "sceneLabel" }, + { "data": "sceneType" }, + { "data": "group" }, + { "data": "lastOkStage", + "defaultContent": "" + }, + { "data": "tags", + "defaultContent": "" + }, + { // Action buttons + "orderable": false, + "searchable": false + } + ], + "rowCallback": function( row, aData, iDisplayIndex ) { + //console.log(row, aData, iDisplayIndex); + lazyImgLoadCallback(row, aData, iDisplayIndex); + processQueue.initProcessButtons(row); + return row; + }, + "initComplete": function() { + $.fn.dataTable.addColumnFilters({ table: resultTable }); + resultTable.css('visibility', 'visible'); + $('#loadingMessage').hide(); + } + }); +} diff --git a/WebUI/public/js/nyuframes.js b/WebUI/public/js/nyuframes.js new file mode 100644 index 0000000..563d350 --- /dev/null +++ b/WebUI/public/js/nyuframes.js @@ -0,0 +1,142 @@ +function createImage(imgUrl, linkUrl) { + var img = $('').attr('class', 'lazy').attr('data-src', imgUrl) + .css('max-width', '100px'); + if (linkUrl) { + var elem = $('').attr('href', linkUrl).attr('target', '_blank') + .append(img); + return elem; + } else { + return img; + } +} + +function createActionButtons(rec) { + var div = $('
    '); + div.append(createButton('Annotate', settings.segmentAnnotatorUrl + + '?condition=nyu-manual&userId=[username]&taskMode=fixup&modelId=nyuv2.' + + rec.sceneName, + 'Annotate scan') + .attr('data-check-auth', 'true') + .attr('target', '_blank')); + div.append(createButton('Annotations', settings.segmentAnnotationViewerUrl + '?modelId=nyuv2.' + rec.sceneName, 'View raw annotations') + .attr('target', '_blank')); + return div; +} + +function getImageUrl(root, rec, type) { + //513__bedroom_0132__frame27.annNYU.png + var url = root + 'rendered-annotations/' + (rec.nyuAnnotatedIdx-1) + '__' + + rec.sceneName + '__frame' + rec.frameIdx + (type? '.' + type : '') + '.png'; + return url; +} + +function initResultTable(params) { + params = params || {}; + var auth = params.auth; + var nyuAnnRoot = '/data/nyuv2/'; + + var lazyImgLoadCallback = $.fn.dataTable.getLazyImgLoadCallback(); + var resultTable = $("#resultTable"); + var ajaxUrl = nyuAnnRoot + 'nyuFrameAnnotation.csv'; + resultTable.dataTable({ + "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]], + "order": [], + "deferRender": true, + "stateSave": true, + "ajax": { + url: ajaxUrl, + dataType: "text", + dataSrc: function(data) { + var results = Papa.parse(data, {header: true, dynamicTyping: true, skipEmptyLines: true}); + return results.data; + }, + complete: function(jqXhr) { + var lastModified = jqXhr.getResponseHeader('last-modified'); + $('#lastModified').text('Modified: ' + lastModified); + } + }, + "dom": 'BlfripFtip', + "buttons": [ + 'csv', 'colvis', 'orderNeutral', 'selectAll', 'selectNone' + ], + "select": { + style: 'multi' + }, + "columns": [ + { "data": "nyuAnnotatedIdx" }, + { "data": "sceneName", + "defaultContent": "", + "render": function ( data, type, full, meta ) { + var url = '/scans/browse?modelId=nyuv2.' + full.sceneName; + var imgUrl = '/data/nyuv2/' + full.sceneName + + '/' + full.sceneName + '_vh_clean_2_thumb.png'; + return data + '
    ' + getHtml(createImage(imgUrl, url)); + } + }, + { "data": "frameIdx" }, + { "data": "frameReconCoverage", + "searchable": false, + "aggregation": "avg", + "defaultContent": 0 }, + { "data": "frameLabelCoverage", + "searchable": false, + "aggregation": "avg", + "defaultContent": 0 }, + { // Preview image + "orderable": false, + "searchable": false, + "data": null, + "defaultContent": "", + "render": function ( data, type, full, meta ) { + var imgUrl = getImageUrl(nyuAnnRoot, full); + return getHtml(createImage(imgUrl, imgUrl)); + } + }, + { // Preview image + "orderable": false, + "searchable": false, + "data": null, + "defaultContent": "", + "render": function ( data, type, full, meta ) { + var imgUrl = getImageUrl(nyuAnnRoot, full, 'annNYU'); + return getHtml(createImage(imgUrl, imgUrl)); + } + }, + { // Preview image + "orderable": false, + "searchable": false, + "data": null, + "defaultContent": "", + "render": function ( data, type, full, meta ) { + var imgUrl = getImageUrl(nyuAnnRoot, full, 'ann'); + return getHtml(createImage(imgUrl, imgUrl)); + } + }, + { // Action buttons + "orderable": false, + "searchable": false, + "data": null, + "defaultContent": "", + "render": function ( data, type, full, meta ) { + var actionButtons = createActionButtons(full); + return getHtml(actionButtons); + } + } + ], + "rowCallback": function( row, aData, iDisplayIndex ) { + //console.log(row, aData, iDisplayIndex); + lazyImgLoadCallback(row, aData, iDisplayIndex); + if (auth) { + auth.addCheck($(row)); + } + return row; + }, + "initComplete": function() { + $.fn.dataTable.addColumnFilters({ table: resultTable }); + $.fn.dataTable.addColumnAggregations({ table: resultTable }); + resultTable.css('visibility', 'visible'); + $('#loadingMessage').hide(); + } + }); +} + diff --git a/WebUI/public/js/process.js b/WebUI/public/js/process.js new file mode 100644 index 0000000..1f5cdaa --- /dev/null +++ b/WebUI/public/js/process.js @@ -0,0 +1,186 @@ +function ProcessQueue(url) { + this.url = url; + this.__downloader = new Downloader(); +} + +ProcessQueue.prototype.__submitAndRun = function(name, path, data, onSuccess) { + path = path || name; + $.ajax({ url: path[0] === '/'? path : this.url + path, data: data }) + .done(function(resp) { + console.log('%s(%s) success', name, data? JSON.stringify(data) : ''); + onSuccess(resp); + }) + .fail(function() { + console.log('%s(%s) error', name, data? JSON.stringify(data) : ''); + }); +}; + +ProcessQueue.prototype.__submitAndReload = function(name, path, data) { + this.__submitAndRun(name, path, data, function() { + location.reload(); + }); +}; + +ProcessQueue.prototype.__downloadFiles = function(scanId, scanPath, exts) { + var self = this; + this.__submitAndRun('download', '/api/scans/' + scanId, + null, function(scan) { + if (scan.files && scan.files.length > 0) { + var files = scan.files; + if (exts) { + var fexts = exts.map( function(ext) { return scanId + ext; }); + files = files.filter( function(file) { + return fexts.indexOf(file.name) >= 0; + }); + } + var base = settings.scanFilesPath + '/'; + var urls = files.map( function(file) { + return base + scanPath + '/' + file.name; + }); + self.__downloader.download(urls); + } else { + bootbox.alert("No files to download for scan " + scanId); + } + }); +}; + + +ProcessQueue.prototype.initCancelButton = function(button, running) { + var self = this; + if (button) { + button.off('click'); + if (running) { + button.attr('class', 'btn btn-danger cancelBtn'); + } else { + button.attr('class', 'btn btn-warning cancelBtn'); + } + button.text('Cancel'); + button.attr('title', 'Remove from process queue'); + button.click( function() { + self.remove($(this).attr('data-id'), $(this)); + }); + } +}; + +ProcessQueue.prototype.initAddButton = function(button) { + var self = this; + if (button) { + button.off('click'); + button.attr('class', 'btn btn-primary cancelBtn'); + button.text('Process'); + button.attr('title', 'Add to process queue'); + button.click( function() { + self.add($(this).attr('data-id'), $(this)); + }); + } +}; + +ProcessQueue.prototype.add = function(scanId, button) { + var self = this; + $.ajax({ url: this.url + 'add', data: { scanId: scanId } }) + .done(function(resp) { + console.log('add %s success', scanId, resp); + self.initCancelButton(button, resp.ticket.isStarted); + }) + .fail(function() { + console.log('add %s error', scanId); + }); +}; + +ProcessQueue.prototype.remove = function(scanId, button) { + var self = this; + $.ajax({ url: this.url + 'remove', data: { scanId: scanId } }) + .done(function(resp) { + console.log('remove %s success', scanId); + self.initAddButton(button); + }) + .fail(function() { + console.log('remove %s error', scanId); + }); +}; + +ProcessQueue.prototype.initProcessButtons = function(div) { + var self = this; + // $(div).find('.processBars').clear(); + // $(div).find('.processBars').each( function() { + + // }); + + $(div).find('.processBtn').off('click'); + $(div).find('.processBtn').click( function() { + self.add($(this).attr('data-id'), $(this)); + }); + + $(div).find('.cancelBtn').off('click'); + $(div).find('.cancelBtn').click( function() { + self.remove($(this).attr('data-id'), $(this)); + }); + + $(div).find('.moveTopBtn').off('click'); + $(div).find('.moveTopBtn').click( function() { + self.__submitAndReload('move top', 'add', + { scanId: $(this).attr('data-id'), priority: 'max'} ); + }); + + $(div).find('.moveBottomBtn').off('click'); + $(div).find('.moveBottomBtn').click( function() { + self.__submitAndReload('move bottom', 'add', + { scanId: $(this).attr('data-id'), priority: 'min'} ); + }); + + if (self.__downloader) { + $(div).find('.downloadAllBtn').off('click'); + $(div).find('.downloadAllBtn').click( function() { + var scanId = $(this).attr('data-id'); + var scanPath = $(this).attr('data-path'); + self.__downloadFiles(scanId, scanPath); + }); + + $(div).find('.downloadRawBtn').off('click'); + $(div).find('.downloadRawBtn').click( function() { + var scanId = $(this).attr('data-id'); + var scanPath = $(this).attr('data-path'); + self.__downloadFiles(scanId, scanPath, ['.txt', '.depth', '.imu', '.h264', '.camera']); + }); + } +}; + + +ProcessQueue.prototype.initBasicButtons = function() { + var self = this; + $('#clearProgressQueueBtn').click( function() { + bootbox.confirm("Are you sure you want to clear the process queue?", function(result) { + if (result) { + self.__submitAndReload('clear'); + } + }); + }); + $('#pauseResumeBtn').click( function() { + var btn = $(this); + var action = btn.data('action'); + if (action === 'pause' || action === 'resume') { + self.__submitAndRun(action, action, undefined, function(resp) { + console.log(resp); + if (resp.isPaused) { + btn.data('action', 'resume').removeClass('btn-warning').addClass('btn-success').text('Resume'); + } else { + btn.data('action', 'pause').removeClass('btn-success').addClass('btn-warning').text('Pause'); + } + }); + } else { + console.warning('Unsupported action: ' + action); + } + }); + $('#reindexBtn').click( function() { + bootbox.confirm("Are you sure you want to reindex?", function(result) { + if (result) { + self.__submitAndReload('reindex', '/scans/index'); + } + }); + }); +}; + +var queueUrl = '/queues/process/'; +var processQueue = new ProcessQueue(queueUrl); +//processQueue.init(); +processQueue.initBasicButtons(); diff --git a/WebUI/public/js/scenes.js b/WebUI/public/js/scenes.js new file mode 100644 index 0000000..7cba288 --- /dev/null +++ b/WebUI/public/js/scenes.js @@ -0,0 +1,41 @@ +function initResultTable(params) { + var lazyImgLoadCallback = $.fn.dataTable.getLazyImgLoadCallback(); + var resultTable = $("#resultTable"); + resultTable.dataTable({ + "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]], + "order": [], + "deferRender": false, + "stateSave": true, + "dom": 'BlfripFtip', + "buttons": [ + 'csv', 'colvis', 'orderNeutral', 'selectAll', 'selectNone' + ], + "select": { + style: 'multi' + }, + "columns": [ + { "data": "name" }, + { "data": "type" }, + { "data": "scans" }, + { // Scans + "orderable": false, + "searchable": false + }, + { // Action buttons + "orderable": false, + "searchable": false + } + ], + "rowCallback": function( row, aData, iDisplayIndex ) { + //console.log(row, aData, iDisplayIndex); + lazyImgLoadCallback(row, aData, iDisplayIndex); + return row; + }, + "initComplete": function() { + $.fn.dataTable.addColumnFilters({ table: resultTable }); + resultTable.css('visibility', 'visible'); + $('#loadingMessage').hide(); + } + }); + +} diff --git a/WebUI/public/js/scenesByType.js b/WebUI/public/js/scenesByType.js new file mode 100644 index 0000000..d8f4a4e --- /dev/null +++ b/WebUI/public/js/scenesByType.js @@ -0,0 +1,36 @@ +function initResultTable(params) { + var lazyImgLoadCallback = $.fn.dataTable.getLazyImgLoadCallback(); + var resultTable = $("#resultTable"); + resultTable.dataTable({ + "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]], + "order": [], + "deferRender": false, + "stateSave": true, + "dom": 'BlfripFtip', + "buttons": [ + 'csv', 'colvis', 'orderNeutral', 'selectAll', 'selectNone' + ], + "select": { + style: 'multi' + }, + "columns": [ + { "data": "type" }, + { "data": "scans" }, + { "data": "scenes" }, + { // Action buttons + "orderable": false, + "searchable": false + } + ], + "rowCallback": function( row, aData, iDisplayIndex ) { + //console.log(row, aData, iDisplayIndex); + lazyImgLoadCallback(row, aData, iDisplayIndex); + return row; + }, + "initComplete": function() { + $.fn.dataTable.addColumnFilters({ table: resultTable }); + resultTable.css('visibility', 'visible'); + $('#loadingMessage').hide(); + } + }); +} diff --git a/WebUI/public/js/tags.js b/WebUI/public/js/tags.js new file mode 100644 index 0000000..6e79bca --- /dev/null +++ b/WebUI/public/js/tags.js @@ -0,0 +1,35 @@ +function initResultTable(params) { + var lazyImgLoadCallback = $.fn.dataTable.getLazyImgLoadCallback(); + var resultTable = $("#resultTable"); + resultTable.dataTable({ + "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]], + "order": [], + "deferRender": false, + "stateSave": true, + "dom": 'BlfripFtip', + "buttons": [ + 'csv', 'colvis', 'orderNeutral', 'selectAll', 'selectNone' + ], + "select": { + style: 'multi' + }, + "columns": [ + { "data": "name" }, + { "data": "scans" }, + { // Action buttons + "orderable": false, + "searchable": false + } + ], + "rowCallback": function( row, aData, iDisplayIndex ) { + //console.log(row, aData, iDisplayIndex); + lazyImgLoadCallback(row, aData, iDisplayIndex); + return row; + }, + "initComplete": function() { + $.fn.dataTable.addColumnFilters({ table: resultTable }); + resultTable.css('visibility', 'visible'); + $('#loadingMessage').hide(); + } + }); +} diff --git a/WebUI/public/js/users.js b/WebUI/public/js/users.js new file mode 100644 index 0000000..6e79bca --- /dev/null +++ b/WebUI/public/js/users.js @@ -0,0 +1,35 @@ +function initResultTable(params) { + var lazyImgLoadCallback = $.fn.dataTable.getLazyImgLoadCallback(); + var resultTable = $("#resultTable"); + resultTable.dataTable({ + "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]], + "order": [], + "deferRender": false, + "stateSave": true, + "dom": 'BlfripFtip', + "buttons": [ + 'csv', 'colvis', 'orderNeutral', 'selectAll', 'selectNone' + ], + "select": { + style: 'multi' + }, + "columns": [ + { "data": "name" }, + { "data": "scans" }, + { // Action buttons + "orderable": false, + "searchable": false + } + ], + "rowCallback": function( row, aData, iDisplayIndex ) { + //console.log(row, aData, iDisplayIndex); + lazyImgLoadCallback(row, aData, iDisplayIndex); + return row; + }, + "initComplete": function() { + $.fn.dataTable.addColumnFilters({ table: resultTable }); + resultTable.css('visibility', 'visible'); + $('#loadingMessage').hide(); + } + }); +} diff --git a/WebUI/public/login.html b/WebUI/public/login.html new file mode 100644 index 0000000..063c3f7 --- /dev/null +++ b/WebUI/public/login.html @@ -0,0 +1,35 @@ + + + + + ScanNet Login + + + + + +
    +
    +
    +

    Welcome Back

    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    + +
    +
    +
    +
    + + diff --git a/WebUI/public/resources/images/loading.gif b/WebUI/public/resources/images/loading.gif new file mode 100644 index 0000000..5442721 Binary files /dev/null and b/WebUI/public/resources/images/loading.gif differ diff --git a/WebUI/public/signup.html b/WebUI/public/signup.html new file mode 100644 index 0000000..88e2997 --- /dev/null +++ b/WebUI/public/signup.html @@ -0,0 +1,37 @@ + + + + + ScanNet Signup + + + + + +
    +
    +
    +

    Create an Account

    +
    +
    +
    +
    +
    +
    + + +
    +
    + + +
    + +
    +
    +
    +
    + + diff --git a/WebUI/src/app.js b/WebUI/src/app.js new file mode 100644 index 0000000..69bf7ae --- /dev/null +++ b/WebUI/src/app.js @@ -0,0 +1,46 @@ +'use strict'; + +const path = require('path'); +const serveStatic = require('feathers').static; +const favicon = require('serve-favicon'); +const compress = require('compression'); +const cors = require('cors'); +const feathers = require('feathers'); +const configuration = require('feathers-configuration'); +const hooks = require('feathers-hooks'); +const rest = require('feathers-rest'); +const bodyParser = require('body-parser'); +const socketio = require('feathers-socketio'); +const middleware = require('./middleware'); +const services = require('./services'); +const proxy = require('./proxy'); +const routes = require('./routes'); +const process_queue = require('./process_queue'); + +const app = feathers(); +app.locals._ = require('lodash'); + +// View template configuration +app.set('views', path.join(__dirname, '../views')); +app.set('view engine', 'jade'); + +app.configure(configuration(path.join(__dirname, '..'))); + +app.use(compress()) + .options('*', cors()) + .use(cors()) + .use(favicon( path.join(app.get('public'), 'favicon.ico') )) + .use('/', serveStatic( app.get('public') )) + .configure(proxy) // proxy routes (need to go before bodyParser + .use(bodyParser.json({ limit: '50mb' })) + .use(bodyParser.text({ type: 'text/*', limit: '10mb' })) + .use(bodyParser.urlencoded({ extended: true })) + .configure(hooks()) + .configure(rest()) + .configure(socketio()) + .configure(services) + .configure(process_queue) // Scan process queue (goes after bodyParser, before our routes) + .configure(routes) // Our custom routes (goes after bodyParser) + .configure(middleware); // Middleware comes last + +module.exports = app; diff --git a/WebUI/src/hooks/index.js b/WebUI/src/hooks/index.js new file mode 100644 index 0000000..e72a8ce --- /dev/null +++ b/WebUI/src/hooks/index.js @@ -0,0 +1,55 @@ +'use strict'; + +// Add any common hooks you want to share across services in here. +// +// Below is an example of how a hook is written and exported. Please +// see http://docs.feathersjs.com/hooks/readme.html for more details +// on hooks. + +function normalizeValue(v) { + if (typeof v === 'string') { + var vl = v.toLowerCase(); + if (vl === 'true') { + return true; + } else if (vl === 'false') { + return false; + } + } + return v; +} + +exports.rewriteQuery = function(options) { + const rewriteQueries = data => { + for (let k in data) { + var value = data[k]; + if (value['$exists'] != undefined) { + value['$exists'] = normalizeValue(value['$exists']); + } + if (value['$regex'] != undefined) { + if (typeof value['$regex'] === 'string') { + value['$regex'] = new RegExp(value['$regex']); + } + } + } + }; + + const callback = () => true; + + return function (hook) { + if (hook.type === 'after') { + throw new errors.GeneralError(`Provider '${hook.params.provider}' can not rewrite query params on after hook.`); + } + const result = hook.params.query; + const next = condition => { + if (result && condition) { + rewriteQueries(result); + } + return hook; + }; + + const check = callback(hook); + + return check && typeof check.then === 'function' + ? check.then(next) : next(check); + }; +}; diff --git a/WebUI/src/index.js b/WebUI/src/index.js new file mode 100644 index 0000000..bd307ee --- /dev/null +++ b/WebUI/src/index.js @@ -0,0 +1,17 @@ +'use strict'; + +const app = require('./app'); +const port = app.get('port'); +const server = app.listen(port); + +app.use(app.logger.expressLogger); + +app.logger.info('Logging...'); + +process.on('unhandledRejection', (reason, p) => { + console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason); +}); + +server.on('listening', () => + console.log(`Feathers application started on ${app.get('host')}:${port}`) +); diff --git a/WebUI/src/logger.js b/WebUI/src/logger.js new file mode 100644 index 0000000..bde88fe --- /dev/null +++ b/WebUI/src/logger.js @@ -0,0 +1,39 @@ +var winston = require('winston'); +var expressWinston = require('express-winston'); +var WinstonContext = require('winston-context'); + +var expressLogger = expressWinston.logger({ + transports: [ + new (winston.transports.File)({ filename: 'logs/express.log' }) + ], + meta: true, // optional: control whether you want to log the meta data about the request (default to true) + msg: 'HTTP {{res.statusCode}} {{req.method}} {{res.responseTime}}ms {{req.url}}', // optional: customize the default logging message. + //expressFormat: true, // Use the default Express/morgan request formatting, with the same colors. Enabling this will override any msg and colorStatus if true. Will only output colors on transports with colorize set to true + //colorStatus: true, // Color the status code, using the Express/morgan color palette (default green, 3XX cyan, 4XX yellow, 5XX red). Will not be recognized if expressFormat is true + //ignoreRoute: function (req, res) { return false; } // optional: allows to skip some log messages based on request and/or response +}); + +var defaultLogger = new winston.Logger({ + level: 'info', + transports: [ + new (winston.transports.Console)({handleExceptions: true}), + new (winston.transports.File)({ filename: 'logs/server.log', handleExceptions: true }) + ], + exitOnError: false +}); +// winston.add(winston.transports.File, { +// filename: 'logs/server.log', +// handleExceptions: true +// }); +// winston.exitOnError = false; + +var Logger = function(name, meta) { + var logger = winston.loggers.get(name) || defaultLogger; + meta = meta || {}; + if (logger === winston && !meta.name) { meta.name = name; } + var ctx = new WinstonContext(logger, '', meta); + ctx.expressLogger = expressLogger; + return ctx; +}; + +module.exports = Logger; diff --git a/WebUI/src/middleware/index.js b/WebUI/src/middleware/index.js new file mode 100644 index 0000000..bb5a5eb --- /dev/null +++ b/WebUI/src/middleware/index.js @@ -0,0 +1,19 @@ +'use strict'; + +const signup = require('./signup'); + +const handler = require('feathers-errors/handler'); +const notFound = require('./not-found-handler'); +const logger = require('./logger'); + +module.exports = function() { + // Add your custom middleware here. Remember, that + // just like Express the order matters, so error + // handling middleware should go last. + const app = this; + + app.post('/signup', signup(app)); + app.use(notFound()); + app.use(logger(app)); + app.use(handler()); +}; diff --git a/WebUI/src/middleware/logger.js b/WebUI/src/middleware/logger.js new file mode 100644 index 0000000..11e564f --- /dev/null +++ b/WebUI/src/middleware/logger.js @@ -0,0 +1,25 @@ +'use strict'; + +const logger = require('../logger')(); + +module.exports = function(app) { + // Add a logger to our app object for convenience + app.logger = logger; + + return function(error, req, res, next) { + if (error) { + const message = `${error.code ? `(${error.code}) ` : '' }Route: ${req.url} - ${error.message}`; + + if (error.code === 404) { + logger.info(message); + } + else { + logger.error(message); + logger.info(error.stack); + } + } + + next(error); + }; +}; + diff --git a/WebUI/src/middleware/not-found-handler.js b/WebUI/src/middleware/not-found-handler.js new file mode 100644 index 0000000..cb0ee51 --- /dev/null +++ b/WebUI/src/middleware/not-found-handler.js @@ -0,0 +1,9 @@ +'use strict'; + +const errors = require('feathers-errors'); + +module.exports = function() { + return function(req, res, next) { + next(new errors.NotFound('Page not found')); + }; +}; diff --git a/WebUI/src/middleware/signup.js b/WebUI/src/middleware/signup.js new file mode 100644 index 0000000..1a8ca03 --- /dev/null +++ b/WebUI/src/middleware/signup.js @@ -0,0 +1,17 @@ +'use strict'; + +module.exports = function(app) { + return function(req, res, next) { + const body = req.body; + + // Get the user service and `create` a new user + app.service('users').create({ + email: body.email, + password: body.password + }) + // Then redirect to the login page + .then(user => res.redirect('/login.html')) + // On errors, just call our error middleware + .catch(next); + }; +}; diff --git a/WebUI/src/process_queue.js b/WebUI/src/process_queue.js new file mode 100644 index 0000000..851fc79 --- /dev/null +++ b/WebUI/src/process_queue.js @@ -0,0 +1,120 @@ +const rp = require('request-promise-native'); +const Queue = require('./taskqueue'); +const _ = require('lodash'); + +const processUrl = 'http://localhost:5000/process/'; +const processBasicFields = ['overwrite', 'from', 'actions']; +const processFields = ['timestamp'].concat(processBasicFields); +const debug = false; + +// Queue of scans to be processed +// Persistent storage using sqlite +const store = Queue.getCachedSqlStore({ + type: 'sql', + dialect: 'sqlite', + path: './data/process-queue.db' +}); +const queue = new Queue(function (task, cb) { + var url = processUrl + task.id; + if (!debug) { + var options = { + uri: url, + qs: _.pick(task, processFields) + }; + console.log('Processing %s, connecting to url %s', task.id, url); + rp(options) + .then(function (resp) { + // TODO: Process response... + console.log('Response to %s: ', task.id, resp); + cb(null, resp); + }) + .catch(function (err) { + // Processing failed... + console.log('Processing %s FAILED: ', task.id, err); + cb(err, null); + }); + } else { + console.log('Processing %s - debug mode', task.id); + } +}, { + stateFile: './data/process-queue.state.json', + store: store, + priority: function (task, cb) { + cb(null, task.priority || 1); + } + } +); + +module.exports = function() { + const app = this; + + app.process_queue = queue; + + // custom population of scans from csv + app.get('/queues/process/add', (req, res, next) => { + // Add scan to process queue + //var logger = app.logger.getContext('', { path: '/queues/process/add'}); + var opts = { id: req.query.scanId, timestamp: Date.now() }; + _.defaults(opts, _.pick(req.query, processBasicFields)); + if (req.query.priority != undefined) { + var priority = req.query.priority; + if (priority == 'max') { + var p = queue.maxPriority(); + priority = p? p+1 : undefined; + } else if (priority == 'min') { + var p = queue.minPriority(); + priority = p? p-1 : undefined; + } + opts.priority = priority; + } + console.log(opts); + var ticket = queue.push(opts); + res.json({ status: 'ok', size: queue.size(), ticket: ticket }); + }); + + app.get('/queues/process/remove', (req, res, next) => { + // Remove scan from process queue + //var logger = app.logger.getContext('', { path: '/queues/process/remove'}); + queue.cancel(req.query.scanId); + res.json({ status: 'ok', size: queue.size() }); + }); + + app.get('/queues/process/list', (req, res, next) => { + // List scans in process queue + //var logger = app.logger.getContext('', { path: '/queues/process/list'}); + var queued = queue.list(); + res.json({ status: 'ok', queue: queued }); + }); + + app.get('/queues/process/clear', (req, res, next) => { + // List scans in process queue + //var logger = app.logger.getContext('', { path: '/queues/process/clear'}); + queue.clear(); + res.json({ status: 'ok', size: queue.size() }); + }); + + app.get('/queues/process/status', (req, res, next) => { + // Returns basic queue status + res.json({ status: 'ok', status: queue.status() }); + }); + + app.get('/queues/process/stats', (req, res, next) => { + // Returns basic queue stats + res.json({ status: 'ok', stats: queue.getStats(), size: queue.size(), isPaused: queue.isPaused() }); + }); + + app.get('/queues/process/pause', (req, res, next) => { + // Pauses process queue + queue.pause(); + queue.saveState(); + res.json({ status: 'ok', size: queue.size(), isPaused: queue.isPaused() }); + }); + + app.get('/queues/process/resume', (req, res, next) => { + // Resumes process queue + queue.resume(); + queue.saveState(); + res.json({ status: 'ok', size: queue.size(), isPaused: queue.isPaused() }); + }); + +}; diff --git a/WebUI/src/proxy.js b/WebUI/src/proxy.js new file mode 100644 index 0000000..fffefc4 --- /dev/null +++ b/WebUI/src/proxy.js @@ -0,0 +1,40 @@ +// Using the simplest possible proxying for proxying data located on servers +// can also try express-http-proxy or http-proxy-middleware +//const proxy = require('proxy-middleware'); +const proxy = require('express-http-proxy'); +const url = require('url'); + +var proxyRules = [ + { path: '/scans/index', targetUrl: 'http://localhost:5001/index' }, + { path: '/scans/monitor', targetUrl: 'http://localhost:5001' }, +// { path: '/scans/index', targetUrl: 'http://localhost:5001/index' }, + { path: '/solr', targetUrl: 'http://localhost/solr' }, +]; + +module.exports = function() { + const app = this; + + // Simple proxy rules + for (var i = 0; i < proxyRules.length; i++) { + var proxyRule = proxyRules[i]; +// Simple but sometimes add trailing slash due to req.url being enforced to have '/' +// Problematic for redirecting /scans/index +// app.use(proxyRule.path, proxy(proxyRule.targetUrl)); + + proxyRule.target = url.parse(proxyRule.targetUrl); + proxyRule.targetRoot = url.resolve(proxyRule.targetUrl, '/'); + proxyRule.targetPath = proxyRule.target.pathname; + console.log('Proxying: ' + proxyRule.path + ' to ' + proxyRule.targetUrl + ' with ' + + 'host=' + proxyRule.targetRoot + ', path=' + proxyRule.targetPath); + app.use(proxyRule.path, proxy(proxyRule.targetRoot, { + forwardPath: function(pr, req, res) { + var prefix = pr.targetPath; + var path = prefix + (req.originalUrl === req.baseUrl? '':url.parse(req.url).path); + path = path.replace('//', '/'); + //console.log('Proxying ' + req.originalUrl + ' to ' + path); + return path; + }.bind(this, proxyRule) + })); + } +}; + diff --git a/WebUI/src/routes.js b/WebUI/src/routes.js new file mode 100644 index 0000000..729754a --- /dev/null +++ b/WebUI/src/routes.js @@ -0,0 +1,441 @@ +// Using the simplest possible proxying for proxying data located on servers +const csv = require('csv'); +const errors = require('feathers-errors'); +const _ = require('lodash'); + +module.exports = function() { + const app = this; + const scanService = app.service('/api/scans'); + const scanmetaService = app.service('/api/scanmeta'); + + function groupByArrayField(data, field) { + groupedByField = {}; + for (var i = 0; i < data.length; i++) { + var d = data[i]; + var values = d[field]; + if (values) { + for (var j = 0; j < values.length; j++) { + var v = values[j]; + if (v != undefined) { + if (groupedByField[v]) { + groupedByField[v].push(d); + } else { + groupedByField[v] = [d]; + } + } + } + } + } + return groupedByField; + } + + // render home page + //app.get('/', (req, res) => res.render('index')); + + // render annotations + app.get('/scans/annotations', (req, res, next) => { + res.render('annotations', { + settings: app.get('settings') + }); + }); + + // render scans by devices + app.get('/scans/devices/id', (req, res, next) => { + scanService.find({query: req.query}).then(result => { + // This handles paginated and non-paginated services + var scans = result.data ? result.data : result; + if (scans && scans.length) { + scansByDeviceId = _.groupBy(scans.filter( (x) => {return x.deviceId;}), 'deviceId'); + } else { + scansByDeviceId = {}; + } + var devices = _.map(scansByDeviceId, (deviceScans, deviceId) => { + var deviceNames = _.map(deviceScans, (scan) => { return scan.deviceName; }); + deviceNames = _.uniq(_.filter(deviceNames, (name) => { return name; })); + return { id: deviceId, names: deviceNames, scans: deviceScans }; + }); + res.render('devicesById', { + devices: devices, + settings: app.get('settings') + }); + }).catch(next); + }); + + app.get('/scans/devices/name', (req, res, next) => { + scanService.find({query: req.query}).then(result => { + // This handles paginated and non-paginated services + var scans = result.data ? result.data : result; + if (scans && scans.length) { + scansByDeviceName = _.groupBy(scans.filter( (x) => {return x.deviceName;}), 'deviceName'); + } else { + scansByDeviceName = {}; + } + var devices = _.map(scansByDeviceName, (deviceScans, deviceName) => { + var deviceIds = _.map(deviceScans, (scan) => { return scan.deviceId; }); + deviceIds = _.uniq(_.filter(deviceIds, (id) => { return id; })); + return { name: deviceName, ids: deviceIds, scans: deviceScans }; + }); + res.render('devicesByName', { + devices: devices, + settings: app.get('settings') + }); + }).catch(next); + }); + + // render scans by sceneName + app.get('/scans/scenes', (req, res, next) => { + //res.render('manage'); + scanService.find({ sceneName: { '$ne': null }, query: req.query}).then(result => { + // This handles paginated and non-paginated services + var scans = result.data ? result.data : result; + if (scans && scans.length) { + scansByScene = _.groupBy(scans.filter( (x) => {return x.sceneName;}), 'sceneName'); + } else { + scansByScene = {}; + } + var scenes = _.map(scansByScene, (groupedScans, name) => { + var sceneTypes = _.map(groupedScans, (scan) => { return scan.sceneType; }); + sceneTypes = _.uniq(_.filter(sceneTypes, (sceneType) => { return sceneType; })); + return { name: name, type: sceneTypes, scans: groupedScans }; + }); + res.render('scenes', { + scenes: scenes, + settings: app.get('settings') + }); + }).catch(next); + }); + + // render scans by sceneType + app.get('/scans/scenes/type', (req, res, next) => { + if (!req.query['group']) { + req.query['group'] = { '$ne': 'nyuv2' }; + } + scanService.find({query: req.query}).then(result => { + // This handles paginated and non-paginated services + var scans = result.data ? result.data : result; + if (scans && scans.length) { + scansByScene = _.groupBy(scans.filter( (x) => {return x.sceneType;}), 'sceneType'); + } else { + scansByScene = {}; + } + var scenes = _.map(scansByScene, (groupedScans, type) => { + var byName = _.groupBy(groupedScans.filter( (x) => {return x.sceneName;}), 'sceneName'); + return { type: type, scans: groupedScans, numScenes: _.size(byName) }; + }); + res.render('scenesByType', { + scenes: scenes, + settings: app.get('settings') + }); + }).catch(next); + }); + + // render scans by user + app.get('/scans/users', (req, res, next) => { + scanService.find({ userName: { '$ne': null }, query: req.query}).then(result => { + // This handles paginated and non-paginated services + var scans = result.data ? result.data : result; + if (scans && scans.length) { + scansByUser = _.groupBy(scans.filter( (x) => {return x.userName;}), 'userName'); + } else { + scansByUser = {}; + } + var users = _.map(scansByUser, (groupedScans, name) => { + return { name: name, scans: groupedScans }; + }); + res.render('users', { + users: users, + settings: app.get('settings') + }); + }).catch(next); + }); + + // render scans by tag + app.get('/scans/tags', (req, res, next) => { + scanService.find({ tag: { '$ne': null }, query: req.query}).then(result => { + // This handles paginated and non-paginated services + var scans = result.data ? result.data : result; + if (scans && scans.length) { + scansByTag = groupByArrayField(scans, 'tags'); + } else { + scansByTag = {}; + } + var tags = _.map(scansByTag, (groupedScans, name) => { + return { name: name, scans: groupedScans }; + }); + res.render('tags', { + tags: tags, + settings: app.get('settings') + }); + }).catch(next); + }); + + // render our list of messages retrieving them from our service + app.get('/scans/browse', (req, res, next) => { + res.render('browse'); + }); + + app.get('/scans/list', (req, res, next) => { + var queued = app.process_queue.list(); + var queuedById = _.keyBy(queued, 'id'); + scanService.find({query: req.query}).then(result => { + // This handles paginated and non-paginated services + var scans = result.data ? result.data : result; + if (scans && scans.length) { + for (var i = 0; i < scans.length; i++) { + var scan = scans[i]; + var queueState = queuedById[scan['id']]; + if (queueState) { + scan.queueState = { queued: true, running: !!queueState.lock }; + } + } + } + // Hacky way to get count of total total + result.data = scans; + scanService.find({query: {'$limit': 1}}).then( all => { + result.totalAll = all.total; + res.json(result); + }).catch(next); + }).catch(next); + }); + + app.get('/scans/browse/nyu', (req, res, next) => { + req.query['group'] = 'nyuv2'; + scanService.find({query: req.query}).then(result => { + var scans = result.data ? result.data : result; + res.render('manage', { scans: scans, total: result.total, + settings: app.get('settings'), + nyu: true + }); + }).catch(next); + }); + + app.get('/scans/browse/nyu/frames', (req, res, next) => { + res.render('nyuframes', { + settings: app.get('settings') + }); + }); + + app.get('/scans/manage', (req, res, next) => { + //res.render('manage'); + if (!req.query['$sort']) { + req.query['$sort'] = { 'createdAt': -1 }; + } + if (!req.query['group']) { + req.query['group'] = { '$ne': 'nyuv2' }; + } + //console.log(req.query); + var queued = app.process_queue.list(); + var queuedById = _.keyBy(queued, 'id'); + scanService.find({query: req.query}).then(result => { + // This handles paginated and non-paginated services + var scans = result.data ? result.data : result; + if (scans && scans.length) { + for (var i = 0; i < scans.length; i++) { + var scan = scans[i]; + var queueState = queuedById[scan['id']]; + if (queueState) { + scan.queueState = { queued: true, running: !!queueState.lock }; + } + } + } + res.render('manage', { scans: scans, total: result.total, + processQueue: app.process_queue.status(), + manageView: true, + settings: app.get('settings') + }); + }).catch(next); + }); + + app.get('/scans/process/:scanId', (req, res, next) => { + app.process_queue.push( { id: req.params.scanId }); + res.json({ status: 'ok', size: app.process_queue.size() }); + }); + + app.get('/scans/process', (req, res, next) => { + var queued = app.process_queue.list(); + scanService.find({}).then(result => { + // TODO: Filter by the ones that are on the process queue + var scans = result.data ? result.data : result; + var scansById = _.keyBy(scans, 'id'); + var queuedScans = queued.map( queueState => { + var scanId = queueState.id; + var scan = scansById[scanId]; + if (!scan) { + scan = { + id: scanId + }; + } + scan.queueState = { queued: true, running: !!queueState.lock }; + return scan; + }); + res.render('manage', { scans: queuedScans, + total: queued.length, + processQueue: app.process_queue.status(), + processView: true, + settings: app.get('settings') + }); + }).catch(next); + }); + + + app.post('/scans/edit', (req, res, next) => { + var logger = app.logger.getContext('', { path: '/scans/edit'}); + var params = req.body; + logger.info('Processing ' + JSON.stringify(params)); + if (params.action === 'edit') { + if (!params.data) { + throw new errors.GeneralError( + { message: 'No data for /scans/edit: ' + params.action }); + } + // Editing + //var patchData = _.map(params.data, function(v,k) { v._id = k; return v; }); + //console.log(patchData); + // TODO: Handle multple rows being editted + _.each(params.data, function(v,k) { + scanmetaService.patch(k, v, { nedb: { upsert: true } }).then(result => { + scanService.patch(k, v).then(scanResult => { + if (!_.isArray(scanResult)) { + scanResult = [scanResult]; + } + _.each(result, function(f) { + f.id = f._id; + delete f.files; + delete f._id; + }); + res.json({ status: 'ok', data: scanResult }); + }).catch(next); + }).catch(next); + }); + } else { + throw new errors.GeneralError( + { message: 'Unsupported action for /scans/edit: ' + params.action }); + } + }); + + + // TODO: Move logic into service + // custom population of scans from csv + app.post('/scans/populate', (req, res, next) => { + var logger = app.logger.getContext('', { path: '/scans/populate'}); + var preserveKeys = ['sceneName', 'sceneType']; + function error(e) { + console.log(e); + logger.error(e); + res.json(new errors.GeneralError( + { message: 'Error processing /scans/populate', error: e })); + } + + function populate(data) { + logger.info('Populating ' + data.length + ' scans'); + scanService.create(data).then( result => { + scanService.find().then( found => { + //console.log(found); + res.json({ status: 'ok', processed: result.length, total: found.total }); + }).catch(error); + }).catch(error); + } + + function normalizeValue(v) { + if (typeof v === 'string') { + var vl = v.toLowerCase(); + if (vl === 'true') { + return true; + } else if (vl === 'false') { + return false; + } + } + return v; + } + + function normalizeObject(obj) { + for (k in obj) { + if (obj.hasOwnProperty(k)) { + obj[k] = normalizeValue(obj[k]); + } + } + } + + function populateAll(err, data) { + //console.log(data); + if (data) { + if (!_.isArray(data)) { + data = _.values(data); + } + logger.info('Processing /scans/populate for ' + data.length + ' scans'); + for (var i = 0; i < data.length; i++) { + normalizeObject[data[i]]; + if (data[i].path) { + var subgroup = data[i].path.replace(data[i].id, ''); + subgroup = _.trim(subgroup, '/\\'); + if (subgroup) { + data[i].subgroup = subgroup; + } + } + data[i]._orig = _.pick(data, preserveKeys); + data[i]._id = data[i].id; + } + if (req.query.group) { + for (var i = 0; i < data.length; i++) { + data[i].group = req.query.group; + } + } + + function replaceAndPopulate() { + if (req.query.replace) { + // Replace all + if (req.query.replace == 'group' && req.query.group) { + logger.info('Remove group ' + req.query.group); + scanService.remove(null, {query: {group: req.query.group}} ).then( result => { + populate(data); + }).catch(error); + } else if (req.query.replace == 'all') { + logger.info('Remove all'); + scanService.remove(null, {}).then( result => { + populate(data); + }).catch(error); + } else { + logger.info('Remove individual scans'); + var ids = data.map( x => x.id ); + scanService.remove(null, {query: {id: { $in: ids }} }).then( result => { + populate(data); + }).catch(error); + } + } else { + populate(data); + } + } + + scanmetaService.find({}).then( metaResults => { + // combine data and metaResults + if (metaResults.data) { + var metaById = _.keyBy(metaResults.data, '_id'); + for (var i = 0; i < data.length; i++) { + var meta = metaById[data[i].id]; + if (meta) { + _.assign(data[i], meta); + } + } + } + + replaceAndPopulate(); + }).catch(error); + } else { + if (err) { + logger.error(err); + } else { + logger.error('No data'); + } + res.json(new errors.GeneralError( + { message: 'Error processing /scans/populate: ' + err })); + } + } + + if (typeof req.body === 'string') { + // Convert from csv to json + csv.parse(req.body, { skip_empty_lines: true, columns: true }, populateAll); + } else { + populateAll(null, req.body); + } + }); + +}; diff --git a/WebUI/src/services/authentication/index.js b/WebUI/src/services/authentication/index.js new file mode 100644 index 0000000..28ac44d --- /dev/null +++ b/WebUI/src/services/authentication/index.js @@ -0,0 +1,18 @@ +'use strict'; + +const authentication = require('feathers-authentication'); + +const GithubStrategy = require('passport-github').Strategy; +const GithubTokenStrategy = require('passport-github-token'); + +module.exports = function() { + const app = this; + + let config = app.get('auth'); + + config.github.strategy = GithubStrategy; + config.github.tokenStrategy = GithubTokenStrategy; + + app.set('auth', config); + app.configure(authentication(config)); +}; diff --git a/WebUI/src/services/index.js b/WebUI/src/services/index.js new file mode 100644 index 0000000..ea98251 --- /dev/null +++ b/WebUI/src/services/index.js @@ -0,0 +1,15 @@ +'use strict'; +const scanmeta = require('./scanmeta'); +const scan = require('./scan'); +const authentication = require('./authentication'); +const user = require('./user'); + +module.exports = function() { + const app = this; + + + app.configure(authentication); + app.configure(user); + app.configure(scan); + app.configure(scanmeta); +}; diff --git a/WebUI/src/services/scan/hooks/index.js b/WebUI/src/services/scan/hooks/index.js new file mode 100644 index 0000000..08b489f --- /dev/null +++ b/WebUI/src/services/scan/hooks/index.js @@ -0,0 +1,26 @@ +'use strict'; + +const updateScan = require('./updateScan'); + +const globalHooks = require('../../../hooks'); +const hooks = require('feathers-hooks'); + +exports.before = { + all: [], + find: [hooks.removeQuery('_'), globalHooks.rewriteQuery()], + get: [], + create: [], + update: [], + patch: [], + remove: [] +}; + +exports.after = { + all: [], + find: [hooks.remove('files', '_id', '_orig'), updateScan()], + get: [hooks.remove('_id', '_orig'), updateScan()], + create: [], + update: [], + patch: [hooks.remove('_id'), updateScan()], + remove: [] +}; diff --git a/WebUI/src/services/scan/hooks/updateScan.js b/WebUI/src/services/scan/hooks/updateScan.js new file mode 100644 index 0000000..cee871a --- /dev/null +++ b/WebUI/src/services/scan/hooks/updateScan.js @@ -0,0 +1,60 @@ +'use strict'; + +// src/services/scan/hooks/updateScan.js +// +// Use this hook to manipulate incoming or outgoing data. +// For more information on hooks see: http://docs.feathersjs.com/hooks/readme.html + +const defaults = {}; + +module.exports = function(options) { + options = Object.assign({}, defaults, options); + + return function(hook) { + var settings = hook.app.get('settings'); + + function updateScan(scan) { + if (scan.group === 'nyuv2') { + scan.modelId = scan.group + '.' + scan.id; + } else { + scan.modelId = 'scan-' + scan.group + '.' + scan.id; + } + if (scan.numColorFrames == undefined) { + scan.numColorFrames = scan.numTransforms; + } + if (scan.numColorFrames > 0) { + scan.scanSecs = scan.numColorFrames / 30; + } + if (scan.floorAreaFilled > 0 && scan.floorArea > 0) { + scan.floorAreaRatio = scan.floorArea / scan.floorAreaFilled; + } + + var rootPath = settings.scansPaths[scan.group] || settings.scansPaths['default'] + '/' + scan.group; + var scanPath = rootPath + '/' + scan.path + '/'; + if (scan.files) { + for (var i = 0; i < scan.files.length; i++) { + var f = scan.files[i]; + if (f.name === scan.id + '_thumb.jpg') { + scan.videoThumbnailUrl = scanPath + f.name; + } else if (f.name === scan.id + '.mp4') { + scan.videoMp4Url = scanPath + f.name; + } + } + } + + if (scan.hasThumbnail) { + scan.previewUrl = scanPath + scan.id + '_vh_clean_2_thumb.png'; + } + } + + const isPaginated = (hook.method === 'find' && hook.result.data); + const data = isPaginated ? hook.result.data : hook.result; + + if (Array.isArray(data)) { + data.forEach( scan => updateScan(scan) ); + } else { + updateScan(data); + } + hook.updateScan = true; + }; +}; diff --git a/WebUI/src/services/scan/index.js b/WebUI/src/services/scan/index.js new file mode 100644 index 0000000..d4db431 --- /dev/null +++ b/WebUI/src/services/scan/index.js @@ -0,0 +1,35 @@ +'use strict'; + +const path = require('path'); +const NeDB = require('nedb'); +const service = require('feathers-nedb'); +const hooks = require('./hooks'); + +module.exports = function(){ + const app = this; + + const db = new NeDB({ + filename: path.join(app.get('nedb'), 'scans.db'), + autoload: true + }); + + let options = { + Model: db, + paginate: { + default: 5000, + max: 10000 + } + }; + + // Initialize our service with any options it requires + app.use('/api/scans', service(options)); + + // Get our initialize service to that we can bind hooks + const scanService = app.service('/api/scans'); + + // Set up our before hooks + scanService.before(hooks.before); + + // Set up our after hooks + scanService.after(hooks.after); +}; diff --git a/WebUI/src/services/scanmeta/hooks/index.js b/WebUI/src/services/scanmeta/hooks/index.js new file mode 100644 index 0000000..8b47865 --- /dev/null +++ b/WebUI/src/services/scanmeta/hooks/index.js @@ -0,0 +1,25 @@ +'use strict'; + +const globalHooks = require('../../../hooks'); +const hooks = require('feathers-hooks'); + + +exports.before = { + all: [], + find: [hooks.removeQuery('_'), globalHooks.rewriteQuery()], + get: [], + create: [], + update: [], + patch: [], + remove: [] +}; + +exports.after = { + all: [], + find: [], + get: [], + create: [], + update: [], + patch: [], + remove: [] +}; diff --git a/WebUI/src/services/scanmeta/index.js b/WebUI/src/services/scanmeta/index.js new file mode 100644 index 0000000..518c556 --- /dev/null +++ b/WebUI/src/services/scanmeta/index.js @@ -0,0 +1,36 @@ +'use strict'; + +const path = require('path'); +const NeDB = require('nedb'); +const service = require('feathers-nedb'); +const hooks = require('./hooks'); + +// Metadata associated with scans that outlive reindexing attempts +module.exports = function(){ + const app = this; + + const db = new NeDB({ + filename: path.join(app.get('nedb'), 'scanmeta.db'), + autoload: true + }); + + let options = { + Model: db, + paginate: { + default: 5000, + max: 10000 + } + }; + + // Initialize our service with any options it requires + app.use('/api/scanmeta', service(options)); + + // Get our initialize service to that we can bind hooks + const scanmetaService = app.service('/api/scanmeta'); + + // Set up our before hooks + scanmetaService.before(hooks.before); + + // Set up our after hooks + scanmetaService.after(hooks.after); +}; diff --git a/WebUI/src/services/user/hooks/index.js b/WebUI/src/services/user/hooks/index.js new file mode 100644 index 0000000..1cbed8a --- /dev/null +++ b/WebUI/src/services/user/hooks/index.js @@ -0,0 +1,51 @@ +'use strict'; + +const globalHooks = require('../../../hooks'); +const hooks = require('feathers-hooks'); +const auth = require('feathers-authentication').hooks; + +exports.before = { + all: [], + find: [ + auth.verifyToken(), + auth.populateUser(), + auth.restrictToAuthenticated() + ], + get: [ + auth.verifyToken(), + auth.populateUser(), + auth.restrictToAuthenticated(), + auth.restrictToOwner({ ownerField: '_id' }) + ], + create: [ + auth.hashPassword() + ], + update: [ + auth.verifyToken(), + auth.populateUser(), + auth.restrictToAuthenticated(), + auth.restrictToOwner({ ownerField: '_id' }) + ], + patch: [ + auth.verifyToken(), + auth.populateUser(), + auth.restrictToAuthenticated(), + auth.restrictToOwner({ ownerField: '_id' }) + ], + remove: [ + auth.verifyToken(), + auth.populateUser(), + auth.restrictToAuthenticated(), + auth.restrictToOwner({ ownerField: '_id' }) + ] +}; + +exports.after = { + all: [hooks.remove('password')], + find: [], + get: [], + create: [], + update: [], + patch: [], + remove: [] +}; diff --git a/WebUI/src/services/user/index.js b/WebUI/src/services/user/index.js new file mode 100644 index 0000000..b3c4e89 --- /dev/null +++ b/WebUI/src/services/user/index.js @@ -0,0 +1,35 @@ +'use strict'; + +const path = require('path'); +const NeDB = require('nedb'); +const service = require('feathers-nedb'); +const hooks = require('./hooks'); + +module.exports = function(){ + const app = this; + + const db = new NeDB({ + filename: path.join(app.get('nedb'), 'users.db'), + autoload: true + }); + + let options = { + Model: db, + paginate: { + default: 5, + max: 25 + } + }; + + // Initialize our service with any options it requires + app.use('/users', service(options)); + + // Get our initialize service to that we can bind hooks + const userService = app.service('/users'); + + // Set up our before hooks + userService.before(hooks.before); + + // Set up our after hooks + userService.after(hooks.after); +}; diff --git a/WebUI/src/taskqueue.js b/WebUI/src/taskqueue.js new file mode 100644 index 0000000..3f91a43 --- /dev/null +++ b/WebUI/src/taskqueue.js @@ -0,0 +1,223 @@ +const fs = require('fs'); +var BasicQueue = require('better-queue'); +var MemoryStore = require('better-queue-memory'); +var SqlStore = require('better-queue-sql'); +var _ = require('lodash'); + +// Improvements to SqlStore +SqlStore.prototype.getTaskStates = function(n, fields, cb) { + var self = this; + var first = true; + var q = self.adapter.knex(self.tableName).orderBy('lock', 'desc').orderBy('priority', 'DESC').orderBy('added', first ? 'ASC' : 'DESC'); + q = (fields)? q.select(fields) : q.select(); + q = (n > 0)? q.limit(n) : q; + q.then(function(rows) { + cb(null, rows); + }).catch(function(error) { + cb(error, null); + }); +}; + +// Improvements to MemoryStore +MemoryStore.prototype.getTaskStates = function(n, fields, cb) { + var self = this; + var running = _.flatMap( self._running, (tasks, lockId) => { + return _.map( tasks, (task, taskId) => { + return { + id: taskId, + task: task, + lock: lockId, + priority: self._priorities[taskId] + }; + }); + }); + var queued = this._queue.map( taskId => { + return { + id: taskId, + task: self._tasks[taskId], + priority: self._priorities[taskId] + }; + }); + + var all = _.concat([], running, queued); + all = (n > 0)? _.take(all, n) : all; + if (cb) { + cb(null, all); + } + return all; +}; + + +// MemoryStored that is backed by a sqlstore +// Always pushes changes to backend store +// But keeps a cache of queue tasks +function CachedStore(store) { + this._store = store; + this._taskIds = []; // Array of taskIds + this._taskStates = []; // Array of task states + this._taskStatesById = {}; // TaskId to task state +} + +CachedStore.prototype.connect = function (cb) { + var self = this; + this._store.connect( self.__wrapWithUpdateQueue(cb) ); +}; + +CachedStore.prototype.__wrapWithUpdateQueue = function(cb) { + var self = this; + return function(err, res) { + if (!err) { + self._store.getTaskStates(0, null, function(err, rows) { + self._taskStates = rows || []; + self._taskIds = _.map(self._taskStates, 'id'); + self._taskStatesById = _.keyBy(self._taskStates, 'id'); + console.log('In queue: ' + self._taskStates.length); + cb(null, res); + }); + } else { + cb(err, res); + } + }; +}; + +CachedStore.prototype.getTask = function (taskId, cb) { + return this._store.getTask(taskId, cb); +}; + +CachedStore.prototype.deleteTask = function (taskId, cb) { + return this._store.deleteTask(taskId, this.__wrapWithUpdateQueue(cb)); +}; + +CachedStore.prototype.putTask = function (taskId, task, priority, cb) { + return this._store.putTask(taskId, task, priority, this.__wrapWithUpdateQueue(cb)); +}; + +CachedStore.prototype.takeFirstN = function (n, cb) { + return this._store.takeFirstN(n, this.__wrapWithUpdateQueue(cb)); +}; + +CachedStore.prototype.takeLastN = function (n, cb) { + return this._store.takeLastN(n, this.__wrapWithUpdateQueue(cb)); +}; + +CachedStore.prototype.getLock = function (lockId, cb) { + return this._store.getLock(lockId, cb); +}; + +CachedStore.prototype.getRunningTasks = function (cb) { + return this._store.getRunningTasks(cb); +}; + +CachedStore.prototype.releaseLock = function (lockId, cb) { + return this._store.releaseLock(lockId, this.__wrapWithUpdateQueue(cb)); +}; + +function Queue(process, opts) { + opts = opts || {}; + BasicQueue.call(this, process, opts); + this._stateFile = opts.stateFile; + this.loadState(); +} + +Queue.prototype = Object.create(BasicQueue.prototype); +Queue.prototype.constructor = Queue; + +// Improvements to the queue +Queue.prototype.size = function() { + var taskIds = this.taskIds(); + if (this.length !== taskIds.length) { + console.log('Got taskIds length=%d, cached length=%d', taskIds.length, this.length); + } + return taskIds.length; +}; + +Queue.prototype.taskIds = function() { + var tasks = this.list(); + if (tasks) { + return _.map(tasks, 'id'); + } +}; + +Queue.prototype.list = function() { + var store = this._store; + if (store._taskStates) { + return store._taskStates; + } else if (store._queue && store._tasks) { + var tasks = store.getTaskStates(); + return tasks; + } +}; + +Queue.prototype.firstTask = function() { + var tasks = this.list(); + if (tasks && tasks.length > 0) { + return tasks[0]; + } +}; + +Queue.prototype.lastTask = function() { + var tasks = this.list(); + if (tasks && tasks.length > 0) { + return tasks[tasks.length-1]; + } +}; + +Queue.prototype.maxPriority = function() { + var tasks = this.list(); + return _.maxBy(tasks, 'priority').priority; +}; + +Queue.prototype.minPriority = function() { + var tasks = this.list(); + return _.minBy(tasks, 'priority').priority; +}; + +Queue.prototype.clear = function() { + // Clears the queue + this.pause(); + var taskIds = this.taskIds(); + for (var i = 0; i < taskIds.length; i++) { + console.log('cancel %s', taskIds[i]); + this.cancel(taskIds[i]); + } + this.resume(); +}; + +Queue.prototype.isPaused = function() { + return this._stopped; +}; + +Queue.prototype.status = function() { + return { isPaused: this.isPaused(), size: this.size() }; +}; + +Queue.prototype.saveState = function() { + if (this._stateFile) { + var state = { + isPaused: this.isPaused() + }; + fs.writeFileSync(this._stateFile, JSON.stringify(state), 'utf-8'); + } + +}; + + +Queue.prototype.loadState = function() { + if (this._stateFile && fs.existsSync(this._stateFile)) { + var state = fs.readFileSync(this._stateFile, 'utf-8'); + if (state) { + state = JSON.parse(state); + if (state.isPaused) { + this.pause(); + } + } + } +}; + +Queue.getCachedSqlStore = function(opts) { + var store = new SqlStore(opts); + var cached = new CachedStore(store); + return cached; +}; + +module.exports = Queue; diff --git a/WebUI/test/app.test.js b/WebUI/test/app.test.js new file mode 100644 index 0000000..a16c396 --- /dev/null +++ b/WebUI/test/app.test.js @@ -0,0 +1,51 @@ +'use strict'; + +const assert = require('assert'); +const request = require('request'); +const app = require('../src/app'); + +describe('Feathers application tests', function() { + before(function(done) { + this.server = app.listen(3030); + this.server.once('listening', () => done()); + }); + + after(function(done) { + this.server.close(done); + }); + + it('starts and shows the index page', function(done) { + request('http://localhost:3030', function(err, res, body) { + assert.ok(body.indexOf('') !== -1); + done(err); + }); + }); + + describe('404', function() { + it('shows a 404 HTML page', function(done) { + request({ + url: 'http://localhost:3030/path/to/nowhere', + headers: { + 'Accept': 'text/html' + } + }, function(err, res, body) { + assert.equal(res.statusCode, 404); + assert.ok(body.indexOf('') !== -1); + done(err); + }); + }); + + it('shows a 404 JSON error without stack trace', function(done) { + request({ + url: 'http://localhost:3030/path/to/nowhere', + json: true + }, function(err, res, body) { + assert.equal(res.statusCode, 404); + assert.equal(body.code, 404); + assert.equal(body.message, 'Page not found'); + assert.equal(body.name, 'NotFound'); + done(err); + }); + }); + }); +}); diff --git a/WebUI/test/services/scan/hooks/updateScan.test.js b/WebUI/test/services/scan/hooks/updateScan.test.js new file mode 100644 index 0000000..72a9fc5 --- /dev/null +++ b/WebUI/test/services/scan/hooks/updateScan.test.js @@ -0,0 +1,20 @@ +'use strict'; + +const assert = require('assert'); +const updateScan = require('../../../../src/services/scan/hooks/updateScan.js'); + +describe('scan updateScan hook', function() { + it('hook can be used', function() { + const mockHook = { + type: 'after', + app: {}, + params: {}, + result: {}, + data: {} + }; + + updateScan()(mockHook); + + assert.ok(mockHook.updateScan); + }); +}); diff --git a/WebUI/test/services/scan/index.test.js b/WebUI/test/services/scan/index.test.js new file mode 100644 index 0000000..fae2037 --- /dev/null +++ b/WebUI/test/services/scan/index.test.js @@ -0,0 +1,10 @@ +'use strict'; + +const assert = require('assert'); +const app = require('../../../src/app'); + +describe('scan service', function() { + it('registered the scans service', () => { + assert.ok(app.service('scans')); + }); +}); diff --git a/WebUI/test/services/scanmeta/index.test.js b/WebUI/test/services/scanmeta/index.test.js new file mode 100644 index 0000000..e73d84d --- /dev/null +++ b/WebUI/test/services/scanmeta/index.test.js @@ -0,0 +1,10 @@ +'use strict'; + +const assert = require('assert'); +const app = require('../../../src/app'); + +describe('scanmeta service', function() { + it('registered the scanmeta service', () => { + assert.ok(app.service('scanmeta')); + }); +}); diff --git a/WebUI/test/services/user/index.test.js b/WebUI/test/services/user/index.test.js new file mode 100644 index 0000000..a43dcae --- /dev/null +++ b/WebUI/test/services/user/index.test.js @@ -0,0 +1,10 @@ +'use strict'; + +const assert = require('assert'); +const app = require('../../../src/app'); + +describe('user service', function() { + it('registered the users service', () => { + assert.ok(app.service('users')); + }); +}); diff --git a/WebUI/views/annotations.jade b/WebUI/views/annotations.jade new file mode 100644 index 0000000..1eb7d06 --- /dev/null +++ b/WebUI/views/annotations.jade @@ -0,0 +1,18 @@ +doctype html +html(lang="en") + head + title= "ScanNet Annotations" + meta(charset= "UTF-8") + link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css') + link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css') + link(rel='stylesheet', href='/css/basic.css') + + body + include includes/navbar.jade + + main + iframe(src="#{settings.segmentAnnotationsUrl}" frameborder="0" style="position:absolute;width:95%; height:95%;") + + script(src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js") + script(src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js") + script(src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js") diff --git a/WebUI/views/devicesById.jade b/WebUI/views/devicesById.jade new file mode 100644 index 0000000..75b67ec --- /dev/null +++ b/WebUI/views/devicesById.jade @@ -0,0 +1,42 @@ +extends layouts/datatable + +block title + title= "ScanNet Devices" + +block body + div + h1 Devices + div.btn-group + button.btn.btn-default.dropdown-toggle(type='button', data-toggle='dropdown') + | Show + span.caret + ul.dropdown-menu(role='menu') + li + a(href='/scans/devices/id') All + li + a(href='/scans/devices/id?group=checked') Checked + li + a(href='/scans/devices/id?group=staging') Staging + hr + div#loadingMessage Loading... + table#resultTable(style='visibility: hidden') + thead + tr + th id + th name + th scans + th actions + tfoot + tr + th id + th name + th scans + th actions + tbody + +block footer + script(type="text/javascript"). + var devices = !{JSON.stringify(devices)}; + script(src="/js/devicesById.js") + script(type="text/javascript"). + initResultTable({ data: devices }); diff --git a/WebUI/views/devicesByName.jade b/WebUI/views/devicesByName.jade new file mode 100644 index 0000000..d0e9898 --- /dev/null +++ b/WebUI/views/devicesByName.jade @@ -0,0 +1,42 @@ +extends layouts/datatable + +block title + title= "ScanNet Devices" + +block body + div + h1 Devices + div.btn-group + button.btn.btn-default.dropdown-toggle(type='button', data-toggle='dropdown') + | Show + span.caret + ul.dropdown-menu(role='menu') + li + a(href='/scans/devices/name') All + li + a(href='/scans/devices/name?group=checked') Checked + li + a(href='/scans/devices/name?group=staging') Staging + hr + div#loadingMessage Loading... + table#resultTable(style='visibility: hidden') + thead + tr + th id + th name + th scans + th actions + tfoot + tr + th id + th name + th scans + th actions + tbody + +block footer + script(type="text/javascript"). + var devices = !{JSON.stringify(devices)}; + script(src="/js/devicesByName.js") + script(type="text/javascript"). + initResultTable({ data: devices }); diff --git a/WebUI/views/includes/navbar.jade b/WebUI/views/includes/navbar.jade new file mode 100644 index 0000000..96c07b2 --- /dev/null +++ b/WebUI/views/includes/navbar.jade @@ -0,0 +1,50 @@ +nav.navbar.navbar-default(role='navigation') + .container-fluid + // Brand and toggle get grouped for better mobile display + .navbar-header + button.navbar-toggle(type='button', data-toggle='collapse', data-target='#bs-example-navbar-collapse-1') + span.sr-only Toggle navigation + span.icon-bar + span.icon-bar + span.icon-bar + a.navbar-brand(href='/') ScanNet + // Collect the nav links, forms, and other content for toggling + #bs-example-navbar-collapse-1.collapse.navbar-collapse + ul.nav.navbar-nav + li.dropdown + a.dropdown-toggle(href='#', data-toggle='dropdown') + | Scans + span.caret + ul.dropdown-menu(role='menu') + li + a(href='/scans/manage') All + li + a(href='/scans/process') Queued + li + a(href='/scans/scenes') Scenes by id + li + a(href='/scans/scenes/type') Scenes by type + li + a(href='/scans/devices/id') Devices by id + li + a(href='/scans/devices/name') Devices by name + li + a(href='/scans/tags') Tags + li + a(href='/scans/users') Users + li.dropdown + a.dropdown-toggle(href='#', data-toggle='dropdown') + | Annotations + span.caret + ul.dropdown-menu(role='menu') + li + a(href='/scans/annotations') All + li.dropdown + a.dropdown-toggle(href='#', data-toggle='dropdown') + | NYU + span.caret + ul.dropdown-menu(role='menu') + li + a(href='/scans/browse/nyu') Scans + li + a(href='/scans/browse/nyu/frames') Frames diff --git a/WebUI/views/layouts/datatable.jade b/WebUI/views/layouts/datatable.jade new file mode 100644 index 0000000..bd6bcd2 --- /dev/null +++ b/WebUI/views/layouts/datatable.jade @@ -0,0 +1,36 @@ +doctype html +html(lang="en") + head + block title + title= "ScanNet" + meta(charset= "UTF-8") + link(rel='stylesheet', href='//cdn.datatables.net/1.10.12/css/jquery.dataTables.min.css') + link(rel='stylesheet', href='//cdn.datatables.net/buttons/1.2.2/css/buttons.dataTables.min.css') + link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css') + link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css') + link(rel='stylesheet', href='//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.min.css') + link(rel='stylesheet', href='/css/basic.css') + block head + + body + block navbar + include ../includes/navbar.jade + + main.container + block body + + script(src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js") + script(src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js") + script(src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js") + script(src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js") + script(src="//cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js") + script(src="//cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js") + script(src="//cdn.datatables.net/select/1.2.0/js/dataTables.select.min.js") + script(src="//cdn.datatables.net/buttons/1.2.2/js/dataTables.buttons.min.js") + script(src="//cdn.datatables.net/buttons/1.2.2/js/buttons.colVis.min.js") + script(src="//cdn.datatables.net/buttons/1.2.2/js/buttons.html5.min.js") + script(src="/js/datatables.js") + script(src="/js/auth.js") + script(type="text/javascript"). + var settings = !{JSON.stringify(settings)}; + block footer diff --git a/WebUI/views/manage.jade b/WebUI/views/manage.jade new file mode 100644 index 0000000..42dbebd --- /dev/null +++ b/WebUI/views/manage.jade @@ -0,0 +1,116 @@ +extends layouts/datatable + +block head + link(rel='stylesheet', href='//cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.4/css/selectize.css') + link(rel='stylesheet', href='/vendor/datatables.editor/css/editor.dataTables.min.css') + link(rel='stylesheet', href='/vendor/datatables.editor/css/editor.selectize.css') + +block body + div + if processView || manageView + a.btn.btn-primary.btn-lg(href='#', role='button', id='reindexBtn') Reindex + if processView + a.btn.btn-primary.btn-lg(href='/scans/manage', role='button', title='Show all scans') All + a.btn.btn-primary.btn-lg.pull-right(href='#', role='button', id='clearProgressQueueBtn') Clear + if processQueue.isPaused + a.btn.btn-success.btn-lg.pull-right(href='#', role='button', id='pauseResumeBtn', data-action='resume', title='Resume processing') Resume + else + a.btn.btn-warning.btn-lg.pull-right(href='#', role='button', id='pauseResumeBtn', data-action='pause', title='Pause processing') Pause + else if manageView + a.btn.btn-primary.btn-lg(href='/scans/process', role='button', title='Show scans queued for processing') Queued + + if nyu + a.btn.btn-primary.btn-lg(href='/scans/browse/nyu/frames', role='button', title='Show scans by device') Frames + + if manageView + div.btn-group.pull-right + button.btn.btn-default.dropdown-toggle(type='button', data-toggle='dropdown') + | Show + span.caret + ul.dropdown-menu(role='menu') + li + a(href='/scans/manage') All + li + a(href='/scans/manage?group=checked') Checked + li + a(href='/scans/manage?group=staging') Staging + li + a(href='/scans/manage?group=staging&subgroup[$exists]=false') Staging - No subgroup + li + a(href='/scans/manage?group=staging&subgroup[$exists]=true') Staging - Subgrouped + hr + div#loadingMessage Loading... + table#resultTable(style='visibility: hidden') + thead + tr + th video + th preview + th id + th createdAt + th updatedAt + th frames + th scanSecs + th processSecs + th objects + th labels + th floorArea + th floorAreaFilled + th floorAreaRatio + th device + th user + th name + th type + th group + th subgroup + th progress + th tags + th vertices + th % annotated + th actions + tfoot + tr + th video + th preview + th id + th createdAt + th updatedAt + th frames + th scanSecs + th processSecs + th objects + th labels + th device + th floorArea + th floorAreaFilled + th floorAreaRatio + th user + th name + th type + th group + th subgroup + th progress + th tags + th vertices + th % annotated + th actions + tbody + +block footer + script(src="//cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.4/js/standalone/selectize.js") + script(src="/vendor/datatables.editor/js/dataTables.editor.min.js") + script(src="/vendor/datatables.editor/js/editor.selectize.js") + script(type="text/javascript"). + var processView = !{JSON.stringify(processView || false)}; + var allowEdit = !{JSON.stringify(manageView || false)}; + var isNYU = !{JSON.stringify(nyu || false)}; + var scans = !{JSON.stringify(scans.map( function(x) { return _.omit(x, ['files']); }))}; + script(src="/js/download.js") + script(src="/js/process.js") + if scans.length === total + script(src="/js/manage-ajax.js") + script(type="text/javascript"). + initResultTable({ serverSide: false, data: scans, allowEdit: allowEdit, auth: new Auth() }); + else + script(src="/js/manage-ajax.js") + script(type="text/javascript"). + initResultTable({ serverSide: true, allowEdit: allowEdit, auth: new Auth() }); diff --git a/WebUI/views/nyuframes.jade b/WebUI/views/nyuframes.jade new file mode 100644 index 0000000..b607c42 --- /dev/null +++ b/WebUI/views/nyuframes.jade @@ -0,0 +1,42 @@ +extends layouts/datatable + +block title + title= "ScanNet NYU Frames" + +block body + div + h1 NYU Frames + a.btn.btn-primary.btn-lg(href='/scans/browse/nyu', role='button', title='Show all scans') Scans + hr + div + span#lastModified + table#resultTable(style='visibility: hidden') + thead + tr + th id + th scene + th frame + th reconCoverage + th labelCoverage + th image + th nyu + th ours + th actions + tfoot + tr + th id + th scene + th frame + th reconCoverage + th labelCoverage + th image + th nyu + th ours + th actions + tbody + +block footer + script(src="//cdnjs.cloudflare.com/ajax/libs/PapaParse/4.1.2/papaparse.min.js") + script(src="/js/nyuframes.js") + script(type="text/javascript"). + initResultTable({ auth: new Auth() }); diff --git a/WebUI/views/scenes.jade b/WebUI/views/scenes.jade new file mode 100644 index 0000000..cf48d68 --- /dev/null +++ b/WebUI/views/scenes.jade @@ -0,0 +1,53 @@ +extends layouts/datatable + +block title + title= "ScanNet Scenes" + +block body + div + h1 Scenes + div.btn-group + button.btn.btn-default.dropdown-toggle(type='button', data-toggle='dropdown') + | Show + span.caret + ul.dropdown-menu(role='menu') + li + a(href='/scans/scenes') All + li + a(href='/scans/scenes?group=checked') Checked + li + a(href='/scans/scenes?group=staging') Staging + hr + div#loadingMessage Loading... + table#resultTable(style='visibility: hidden') + thead + tr + th name + th type + th scans + th examples + th actions + tfoot + tr + th name + th type + th scans + th examples + th actions + tbody + each scene in scenes + tr + td #{scene.name} + td #{scene.type} + td #{scene.scans.length} + td(style='white-space: nowrap;') + each scan in _.take(_.filter(scene.scans, function(x) { return x.previewUrl; }), 4) + a(href='/scans/browse?modelId=#{scan.modelId}', target='_blank') + img.lazy(data-src='#{scan.previewUrl}', style='max-height: 50px;') + td + a.btn.btn-primary(href='/scans/manage?sceneName=#{scene.name}', role='button', title="View scans") Scans + +block footer + script(src="/js/scenes.js") + script(type="text/javascript"). + initResultTable({}); diff --git a/WebUI/views/scenesByType.jade b/WebUI/views/scenesByType.jade new file mode 100644 index 0000000..ff0e588 --- /dev/null +++ b/WebUI/views/scenesByType.jade @@ -0,0 +1,47 @@ +extends layouts/datatable + +block title + title= "ScanNet Scenes" + +block body + div + h1 Scenes + div.btn-group + button.btn.btn-default.dropdown-toggle(type='button', data-toggle='dropdown') + | Show + span.caret + ul.dropdown-menu(role='menu') + li + a(href='/scans/scenes/type') All + li + a(href='/scans/scenes/type?group=checked') Checked + li + a(href='/scans/scenes/type?group=staging') Staging + hr + div#loadingMessage Loading... + table#resultTable(style='visibility: hidden') + thead + tr + th type + th scans + th scenes + th actions + tfoot + tr + th type + th scans + th scenes + th actions + tbody + each scene in scenes + tr + td #{scene.type} + td #{scene.scans.length} + td #{scene.numScenes} + td + a.btn.btn-primary(href='/scans/manage?sceneType=#{scene.type}', role='button', title="View scans") Scans + +block footer + script(src="/js/scenesByType.js") + script(type="text/javascript"). + initResultTable({}); diff --git a/WebUI/views/tags.jade b/WebUI/views/tags.jade new file mode 100644 index 0000000..a54cc42 --- /dev/null +++ b/WebUI/views/tags.jade @@ -0,0 +1,44 @@ +extends layouts/datatable + +block title + title= "ScanNet scans by tags" + +block body + div + h1 Tags + div.btn-group + button.btn.btn-default.dropdown-toggle(type='button', data-toggle='dropdown') + | Show + span.caret + ul.dropdown-menu(role='menu') + li + a(href='/scans/tags') All + li + a(href='/scans/tags?group=checked') Checked + li + a(href='/scans/tags?group=staging') Staging + hr + div#loadingMessage Loading... + table#resultTable(style='visibility: hidden') + thead + tr + th name + th scans + th actions + tfoot + tr + th name + th scans + th actions + tbody + each tag in tags + tr + td #{tag.name} + td #{tag.scans.length} + td + a.btn.btn-primary(href='/scans/manage?tags=#{tag.name}', role='button', title="View scans") Scans + +block footer + script(src="/js/tags.js") + script(type="text/javascript"). + initResultTable({}); diff --git a/WebUI/views/users.jade b/WebUI/views/users.jade new file mode 100644 index 0000000..5a03083 --- /dev/null +++ b/WebUI/views/users.jade @@ -0,0 +1,44 @@ +extends layouts/datatable + +block title + title= "ScanNet Users" + +block body + div + h1 Users + div.btn-group + button.btn.btn-default.dropdown-toggle(type='button', data-toggle='dropdown') + | Show + span.caret + ul.dropdown-menu(role='menu') + li + a(href='/scans/users') All + li + a(href='/scans/users?group=checked') Checked + li + a(href='/scans/users?group=staging') Staging + hr + div#loadingMessage Loading... + table#resultTable(style='visibility: hidden') + thead + tr + th name + th scans + th actions + tfoot + tr + th name + th scans + th actions + tbody + each user in users + tr + td #{user.name} + td #{user.scans.length} + td + a.btn.btn-primary(href='/scans/manage?userName=#{user.name}', role='button', title="View scans") Scans + +block footer + script(src="/js/users.js") + script(type="text/javascript"). + initResultTable({}); diff --git a/external/cutil/inc/GL/freeglut.h b/external/cutil/inc/GL/freeglut.h new file mode 100644 index 0000000..0e6f8c6 --- /dev/null +++ b/external/cutil/inc/GL/freeglut.h @@ -0,0 +1,22 @@ +#ifndef __FREEGLUT_H__ +#define __FREEGLUT_H__ + +/* + * freeglut.h + * + * The freeglut library include file + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "freeglut_std.h" +#include "freeglut_ext.h" + +/*** END OF FILE ***/ + +#endif /* __FREEGLUT_H__ */ diff --git a/external/cutil/inc/GL/freeglut_ext.h b/external/cutil/inc/GL/freeglut_ext.h new file mode 100644 index 0000000..0f5ff00 --- /dev/null +++ b/external/cutil/inc/GL/freeglut_ext.h @@ -0,0 +1,115 @@ +#ifndef __FREEGLUT_EXT_H__ +#define __FREEGLUT_EXT_H__ + +/* + * freeglut_ext.h + * + * The non-GLUT-compatible extensions to the freeglut library include file + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 2 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * GLUT API Extension macro definitions -- behaviour when the user clicks on an "x" to close a window + */ +#define GLUT_ACTION_EXIT 0 +#define GLUT_ACTION_GLUTMAINLOOP_RETURNS 1 +#define GLUT_ACTION_CONTINUE_EXECUTION 2 + +/* + * Create a new rendering context when the user opens a new window? + */ +#define GLUT_CREATE_NEW_CONTEXT 0 +#define GLUT_USE_CURRENT_CONTEXT 1 + +/* + * GLUT API Extension macro definitions -- the glutGet parameters + */ +#define GLUT_ACTION_ON_WINDOW_CLOSE 0x01F9 + +#define GLUT_WINDOW_BORDER_WIDTH 0x01FA +#define GLUT_WINDOW_HEADER_HEIGHT 0x01FB + +#define GLUT_VERSION 0x01FC + +#define GLUT_RENDERING_CONTEXT 0x01FD + +/* + * Process loop function, see freeglut_main.c + */ +FGAPI void FGAPIENTRY glutMainLoopEvent( void ); +FGAPI void FGAPIENTRY glutLeaveMainLoop( void ); + +/* + * Window-specific callback functions, see freeglut_callbacks.c + */ +FGAPI void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) ); +FGAPI void FGAPIENTRY glutCloseFunc( void (* callback)( void ) ); +FGAPI void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) ); +/* A. Donev: Also a destruction callback for menus */ +FGAPI void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) ); + +/* + * State setting and retrieval functions, see freeglut_state.c + */ +FGAPI void FGAPIENTRY glutSetOption ( GLenum option_flag, int value ) ; +/* A.Donev: User-data manipulation */ +FGAPI void* FGAPIENTRY glutGetWindowData( void ); +FGAPI void FGAPIENTRY glutSetWindowData(void* data); +FGAPI void* FGAPIENTRY glutGetMenuData( void ); +FGAPI void FGAPIENTRY glutSetMenuData(void* data); + +/* + * Font stuff, see freeglut_font.c + */ +FGAPI int FGAPIENTRY glutBitmapHeight( void* font ); +FGAPI GLfloat FGAPIENTRY glutStrokeHeight( void* font ); +FGAPI void FGAPIENTRY glutBitmapString( void* font, const unsigned char *string ); +FGAPI void FGAPIENTRY glutStrokeString( void* font, const unsigned char *string ); + +/* + * Geometry functions, see freeglut_geometry.c + */ +FGAPI void FGAPIENTRY glutWireRhombicDodecahedron( void ); +FGAPI void FGAPIENTRY glutSolidRhombicDodecahedron( void ); +FGAPI void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale ) ; +FGAPI void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale ) ; +FGAPI void FGAPIENTRY glutWireCylinder( GLdouble radius, GLdouble height, GLint slices, GLint stacks); +FGAPI void FGAPIENTRY glutSolidCylinder( GLdouble radius, GLdouble height, GLint slices, GLint stacks); + +/* + * Extension functions, see freeglut_ext.c + */ +FGAPI void * FGAPIENTRY glutGetProcAddress( const char *procName ); + + +#ifdef __cplusplus + } +#endif + +/*** END OF FILE ***/ + +#endif /* __FREEGLUT_EXT_H__ */ diff --git a/external/cutil/inc/GL/freeglut_std.h b/external/cutil/inc/GL/freeglut_std.h new file mode 100644 index 0000000..d7bdec0 --- /dev/null +++ b/external/cutil/inc/GL/freeglut_std.h @@ -0,0 +1,547 @@ +#ifndef __FREEGLUT_STD_H__ +#define __FREEGLUT_STD_H__ + +/* + * freeglut_std.h + * + * The GLUT-compatible part of the freeglut library include file + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 2 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Under windows, we have to differentiate between static and dynamic libraries + */ +#if defined(WIN32) +# include +# include +# include +# define WINDOWS +#ifdef FREEGLUT_STATIC +# define FGAPI +# define FGAPIENTRY + +# pragma comment (lib, "freeglut_static.lib") /* link with Win32 static freeglut lib */ + +#else + +# if defined(FREEGLUT_EXPORTS) +# define FGAPI __declspec(dllexport) +/* # define FGAPI */ +# else +# define FGAPI __declspec(dllimport) +# pragma comment (lib, "freeglut.lib") /* link with Win32 freeglut lib */ +# endif +# define FGAPIENTRY __stdcall + +#endif + +#pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */ +#pragma comment (lib, "user32.lib") /* link with Windows user lib */ +#pragma comment (lib, "gdi32.lib") /* link with Windows GDI lib */ +#pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */ +#pragma comment (lib, "glu32.lib") /* link with OpenGL Utility lib */ + + +#else +# define FGAPI +# define FGAPIENTRY +#endif + +/* + * The freeglut and GLUT API versions + */ +#define FREEGLUT 1 +#define GLUT_API_VERSION 4 +#define FREEGLUT_VERSION_2_0 1 + +/* + * Always include OpenGL and GLU headers + */ +#include +#include + +/* + * GLUT API macro definitions -- the special key codes: + */ +#define GLUT_KEY_F1 0x0001 +#define GLUT_KEY_F2 0x0002 +#define GLUT_KEY_F3 0x0003 +#define GLUT_KEY_F4 0x0004 +#define GLUT_KEY_F5 0x0005 +#define GLUT_KEY_F6 0x0006 +#define GLUT_KEY_F7 0x0007 +#define GLUT_KEY_F8 0x0008 +#define GLUT_KEY_F9 0x0009 +#define GLUT_KEY_F10 0x000A +#define GLUT_KEY_F11 0x000B +#define GLUT_KEY_F12 0x000C +#define GLUT_KEY_LEFT 0x0064 +#define GLUT_KEY_UP 0x0065 +#define GLUT_KEY_RIGHT 0x0066 +#define GLUT_KEY_DOWN 0x0067 +#define GLUT_KEY_PAGE_UP 0x0068 +#define GLUT_KEY_PAGE_DOWN 0x0069 +#define GLUT_KEY_HOME 0x006A +#define GLUT_KEY_END 0x006B +#define GLUT_KEY_INSERT 0x006C + +/* + * GLUT API macro definitions -- mouse state definitions + */ +#define GLUT_LEFT_BUTTON 0x0000 +#define GLUT_MIDDLE_BUTTON 0x0001 +#define GLUT_RIGHT_BUTTON 0x0002 +#define GLUT_DOWN 0x0000 +#define GLUT_UP 0x0001 +#define GLUT_LEFT 0x0000 +#define GLUT_ENTERED 0x0001 + +/* + * GLUT API macro definitions -- the display mode definitions + */ +#define GLUT_RGB 0x0000 +#define GLUT_RGBA 0x0000 +#define GLUT_INDEX 0x0001 +#define GLUT_SINGLE 0x0000 +#define GLUT_DOUBLE 0x0002 +#define GLUT_ACCUM 0x0004 +#define GLUT_ALPHA 0x0008 +#define GLUT_DEPTH 0x0010 +#define GLUT_STENCIL 0x0020 +#define GLUT_MULTISAMPLE 0x0080 +#define GLUT_STEREO 0x0100 +#define GLUT_LUMINANCE 0x0200 + +/* + * GLUT API macro definitions -- windows and menu related definitions + */ +#define GLUT_MENU_NOT_IN_USE 0x0000 +#define GLUT_MENU_IN_USE 0x0001 +#define GLUT_NOT_VISIBLE 0x0000 +#define GLUT_VISIBLE 0x0001 +#define GLUT_HIDDEN 0x0000 +#define GLUT_FULLY_RETAINED 0x0001 +#define GLUT_PARTIALLY_RETAINED 0x0002 +#define GLUT_FULLY_COVERED 0x0003 + +/* + * GLUT API macro definitions -- fonts definitions + * + * Steve Baker suggested to make it binary compatible with GLUT: + */ +#if defined(WIN32) +# define GLUT_STROKE_ROMAN ((void *)0x0000) +# define GLUT_STROKE_MONO_ROMAN ((void *)0x0001) +# define GLUT_BITMAP_9_BY_15 ((void *)0x0002) +# define GLUT_BITMAP_8_BY_13 ((void *)0x0003) +# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *)0x0004) +# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *)0x0005) +# define GLUT_BITMAP_HELVETICA_10 ((void *)0x0006) +# define GLUT_BITMAP_HELVETICA_12 ((void *)0x0007) +# define GLUT_BITMAP_HELVETICA_18 ((void *)0x0008) +#else + /* + * I don't really know if it's a good idea... But here it goes: + */ + extern void* glutStrokeRoman; + extern void* glutStrokeMonoRoman; + extern void* glutBitmap9By15; + extern void* glutBitmap8By13; + extern void* glutBitmapTimesRoman10; + extern void* glutBitmapTimesRoman24; + extern void* glutBitmapHelvetica10; + extern void* glutBitmapHelvetica12; + extern void* glutBitmapHelvetica18; + + /* + * Those pointers will be used by following definitions: + */ +# define GLUT_STROKE_ROMAN ((void *) &glutStrokeRoman) +# define GLUT_STROKE_MONO_ROMAN ((void *) &glutStrokeMonoRoman) +# define GLUT_BITMAP_9_BY_15 ((void *) &glutBitmap9By15) +# define GLUT_BITMAP_8_BY_13 ((void *) &glutBitmap8By13) +# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *) &glutBitmapTimesRoman10) +# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *) &glutBitmapTimesRoman24) +# define GLUT_BITMAP_HELVETICA_10 ((void *) &glutBitmapHelvetica10) +# define GLUT_BITMAP_HELVETICA_12 ((void *) &glutBitmapHelvetica12) +# define GLUT_BITMAP_HELVETICA_18 ((void *) &glutBitmapHelvetica18) +#endif + +/* + * GLUT API macro definitions -- the glutGet parameters + */ +#define GLUT_WINDOW_X 0x0064 +#define GLUT_WINDOW_Y 0x0065 +#define GLUT_WINDOW_WIDTH 0x0066 +#define GLUT_WINDOW_HEIGHT 0x0067 +#define GLUT_WINDOW_BUFFER_SIZE 0x0068 +#define GLUT_WINDOW_STENCIL_SIZE 0x0069 +#define GLUT_WINDOW_DEPTH_SIZE 0x006A +#define GLUT_WINDOW_RED_SIZE 0x006B +#define GLUT_WINDOW_GREEN_SIZE 0x006C +#define GLUT_WINDOW_BLUE_SIZE 0x006D +#define GLUT_WINDOW_ALPHA_SIZE 0x006E +#define GLUT_WINDOW_ACCUM_RED_SIZE 0x006F +#define GLUT_WINDOW_ACCUM_GREEN_SIZE 0x0070 +#define GLUT_WINDOW_ACCUM_BLUE_SIZE 0x0071 +#define GLUT_WINDOW_ACCUM_ALPHA_SIZE 0x0072 +#define GLUT_WINDOW_DOUBLEBUFFER 0x0073 +#define GLUT_WINDOW_RGBA 0x0074 +#define GLUT_WINDOW_PARENT 0x0075 +#define GLUT_WINDOW_NUM_CHILDREN 0x0076 +#define GLUT_WINDOW_COLORMAP_SIZE 0x0077 +#define GLUT_WINDOW_NUM_SAMPLES 0x0078 +#define GLUT_WINDOW_STEREO 0x0079 +#define GLUT_WINDOW_CURSOR 0x007A + +#define GLUT_SCREEN_WIDTH 0x00C8 +#define GLUT_SCREEN_HEIGHT 0x00C9 +#define GLUT_SCREEN_WIDTH_MM 0x00CA +#define GLUT_SCREEN_HEIGHT_MM 0x00CB +#define GLUT_MENU_NUM_ITEMS 0x012C +#define GLUT_DISPLAY_MODE_POSSIBLE 0x0190 +#define GLUT_INIT_WINDOW_X 0x01F4 +#define GLUT_INIT_WINDOW_Y 0x01F5 +#define GLUT_INIT_WINDOW_WIDTH 0x01F6 +#define GLUT_INIT_WINDOW_HEIGHT 0x01F7 +#define GLUT_INIT_DISPLAY_MODE 0x01F8 +#define GLUT_ELAPSED_TIME 0x02BC +#define GLUT_WINDOW_FORMAT_ID 0x007B +#define GLUT_INIT_STATE 0x007C + +/* + * GLUT API macro definitions -- the glutDeviceGet parameters + */ +#define GLUT_HAS_KEYBOARD 0x0258 +#define GLUT_HAS_MOUSE 0x0259 +#define GLUT_HAS_SPACEBALL 0x025A +#define GLUT_HAS_DIAL_AND_BUTTON_BOX 0x025B +#define GLUT_HAS_TABLET 0x025C +#define GLUT_NUM_MOUSE_BUTTONS 0x025D +#define GLUT_NUM_SPACEBALL_BUTTONS 0x025E +#define GLUT_NUM_BUTTON_BOX_BUTTONS 0x025F +#define GLUT_NUM_DIALS 0x0260 +#define GLUT_NUM_TABLET_BUTTONS 0x0261 +#define GLUT_DEVICE_IGNORE_KEY_REPEAT 0x0262 +#define GLUT_DEVICE_KEY_REPEAT 0x0263 +#define GLUT_HAS_JOYSTICK 0x0264 +#define GLUT_OWNS_JOYSTICK 0x0265 +#define GLUT_JOYSTICK_BUTTONS 0x0266 +#define GLUT_JOYSTICK_AXES 0x0267 +#define GLUT_JOYSTICK_POLL_RATE 0x0268 + +/* + * GLUT API macro definitions -- the glutLayerGet parameters + */ +#define GLUT_OVERLAY_POSSIBLE 0x0320 +#define GLUT_LAYER_IN_USE 0x0321 +#define GLUT_HAS_OVERLAY 0x0322 +#define GLUT_TRANSPARENT_INDEX 0x0323 +#define GLUT_NORMAL_DAMAGED 0x0324 +#define GLUT_OVERLAY_DAMAGED 0x0325 + +/* + * GLUT API macro definitions -- the glutVideoResizeGet parameters + */ +#define GLUT_VIDEO_RESIZE_POSSIBLE 0x0384 +#define GLUT_VIDEO_RESIZE_IN_USE 0x0385 +#define GLUT_VIDEO_RESIZE_X_DELTA 0x0386 +#define GLUT_VIDEO_RESIZE_Y_DELTA 0x0387 +#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 0x0388 +#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 0x0389 +#define GLUT_VIDEO_RESIZE_X 0x038A +#define GLUT_VIDEO_RESIZE_Y 0x038B +#define GLUT_VIDEO_RESIZE_WIDTH 0x038C +#define GLUT_VIDEO_RESIZE_HEIGHT 0x038D + +/* + * GLUT API macro definitions -- the glutUseLayer parameters + */ +#define GLUT_NORMAL 0x0000 +#define GLUT_OVERLAY 0x0001 + +/* + * GLUT API macro definitions -- the glutGetModifiers parameters + */ +#define GLUT_ACTIVE_SHIFT 0x0001 +#define GLUT_ACTIVE_CTRL 0x0002 +#define GLUT_ACTIVE_ALT 0x0004 + +/* + * GLUT API macro definitions -- the glutSetCursor parameters + */ +#define GLUT_CURSOR_RIGHT_ARROW 0x0000 +#define GLUT_CURSOR_LEFT_ARROW 0x0001 +#define GLUT_CURSOR_INFO 0x0002 +#define GLUT_CURSOR_DESTROY 0x0003 +#define GLUT_CURSOR_HELP 0x0004 +#define GLUT_CURSOR_CYCLE 0x0005 +#define GLUT_CURSOR_SPRAY 0x0006 +#define GLUT_CURSOR_WAIT 0x0007 +#define GLUT_CURSOR_TEXT 0x0008 +#define GLUT_CURSOR_CROSSHAIR 0x0009 +#define GLUT_CURSOR_UP_DOWN 0x000A +#define GLUT_CURSOR_LEFT_RIGHT 0x000B +#define GLUT_CURSOR_TOP_SIDE 0x000C +#define GLUT_CURSOR_BOTTOM_SIDE 0x000D +#define GLUT_CURSOR_LEFT_SIDE 0x000E +#define GLUT_CURSOR_RIGHT_SIDE 0x000F +#define GLUT_CURSOR_TOP_LEFT_CORNER 0x0010 +#define GLUT_CURSOR_TOP_RIGHT_CORNER 0x0011 +#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 0x0012 +#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 0x0013 +#define GLUT_CURSOR_INHERIT 0x0064 +#define GLUT_CURSOR_NONE 0x0065 +#define GLUT_CURSOR_FULL_CROSSHAIR 0x0066 + +/* + * GLUT API macro definitions -- RGB color component specification definitions + */ +#define GLUT_RED 0x0000 +#define GLUT_GREEN 0x0001 +#define GLUT_BLUE 0x0002 + +/* + * GLUT API macro definitions -- additional keyboard and joystick definitions + */ +#define GLUT_KEY_REPEAT_OFF 0x0000 +#define GLUT_KEY_REPEAT_ON 0x0001 +#define GLUT_KEY_REPEAT_DEFAULT 0x0002 + +#define GLUT_JOYSTICK_BUTTON_A 0x0001 +#define GLUT_JOYSTICK_BUTTON_B 0x0002 +#define GLUT_JOYSTICK_BUTTON_C 0x0004 +#define GLUT_JOYSTICK_BUTTON_D 0x0008 + +/* + * GLUT API macro definitions -- game mode definitions + */ +#define GLUT_GAME_MODE_ACTIVE 0x0000 +#define GLUT_GAME_MODE_POSSIBLE 0x0001 +#define GLUT_GAME_MODE_WIDTH 0x0002 +#define GLUT_GAME_MODE_HEIGHT 0x0003 +#define GLUT_GAME_MODE_PIXEL_DEPTH 0x0004 +#define GLUT_GAME_MODE_REFRESH_RATE 0x0005 +#define GLUT_GAME_MODE_DISPLAY_CHANGED 0x0006 + +/* + * Initialization functions, see fglut_init.c + */ +FGAPI void FGAPIENTRY glutInit( int* pargc, char** argv ); +FGAPI void FGAPIENTRY glutInitWindowPosition( int x, int y ); +FGAPI void FGAPIENTRY glutInitWindowSize( int width, int height ); +FGAPI void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode ); +FGAPI void FGAPIENTRY glutInitDisplayString( const char* displayMode ); + +/* + * Process loop function, see freeglut_main.c + */ +FGAPI void FGAPIENTRY glutMainLoop( void ); + +/* + * Window management functions, see freeglut_window.c + */ +FGAPI int FGAPIENTRY glutCreateWindow( const char* title ); +FGAPI int FGAPIENTRY glutCreateSubWindow( int window, int x, int y, int width, int height ); +FGAPI void FGAPIENTRY glutDestroyWindow( int window ); +FGAPI void FGAPIENTRY glutSetWindow( int window ); +FGAPI int FGAPIENTRY glutGetWindow( void ); +FGAPI void FGAPIENTRY glutSetWindowTitle( const char* title ); +FGAPI void FGAPIENTRY glutSetIconTitle( const char* title ); +FGAPI void FGAPIENTRY glutReshapeWindow( int width, int height ); +FGAPI void FGAPIENTRY glutPositionWindow( int x, int y ); +FGAPI void FGAPIENTRY glutShowWindow( void ); +FGAPI void FGAPIENTRY glutHideWindow( void ); +FGAPI void FGAPIENTRY glutIconifyWindow( void ); +FGAPI void FGAPIENTRY glutPushWindow( void ); +FGAPI void FGAPIENTRY glutPopWindow( void ); +FGAPI void FGAPIENTRY glutFullScreen( void ); + +/* + * Display-connected functions, see freeglut_display.c + */ +FGAPI void FGAPIENTRY glutPostWindowRedisplay( int window ); +FGAPI void FGAPIENTRY glutPostRedisplay( void ); +FGAPI void FGAPIENTRY glutSwapBuffers( void ); + +/* + * Mouse cursor functions, see freeglut_cursor.c + */ +FGAPI void FGAPIENTRY glutWarpPointer( int x, int y ); +FGAPI void FGAPIENTRY glutSetCursor( int cursor ); + +/* + * Overlay stuff, see freeglut_overlay.c + */ +FGAPI void FGAPIENTRY glutEstablishOverlay( void ); +FGAPI void FGAPIENTRY glutRemoveOverlay( void ); +FGAPI void FGAPIENTRY glutUseLayer( GLenum layer ); +FGAPI void FGAPIENTRY glutPostOverlayRedisplay( void ); +FGAPI void FGAPIENTRY glutPostWindowOverlayRedisplay( int window ); +FGAPI void FGAPIENTRY glutShowOverlay( void ); +FGAPI void FGAPIENTRY glutHideOverlay( void ); + +/* + * Menu stuff, see freeglut_menu.c + */ +FGAPI int FGAPIENTRY glutCreateMenu( void (* callback)( int menu ) ); +FGAPI void FGAPIENTRY glutDestroyMenu( int menu ); +FGAPI int FGAPIENTRY glutGetMenu( void ); +FGAPI void FGAPIENTRY glutSetMenu( int menu ); +FGAPI void FGAPIENTRY glutAddMenuEntry( const char* label, int value ); +FGAPI void FGAPIENTRY glutAddSubMenu( const char* label, int subMenu ); +FGAPI void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value ); +FGAPI void FGAPIENTRY glutChangeToSubMenu( int item, const char* label, int value ); +FGAPI void FGAPIENTRY glutRemoveMenuItem( int item ); +FGAPI void FGAPIENTRY glutAttachMenu( int button ); +FGAPI void FGAPIENTRY glutDetachMenu( int button ); + +/* + * Global callback functions, see freeglut_callbacks.c + */ +FGAPI void FGAPIENTRY glutTimerFunc( unsigned int time, void (* callback)( int ), int value ); +FGAPI void FGAPIENTRY glutIdleFunc( void (* callback)( void ) ); + +/* + * Window-specific callback functions, see freeglut_callbacks.c + */ +FGAPI void FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) ); +FGAPI void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) ); +FGAPI void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) ); +FGAPI void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) ); +FGAPI void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutEntryFunc( void (* callback)( int ) ); + +FGAPI void FGAPIENTRY glutKeyboardUpFunc( void (* callback)( unsigned char, int, int ) ); +FGAPI void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutJoystickFunc( void (* callback)( unsigned int, int, int, int ), int pollInterval ); +FGAPI void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) ); +FGAPI void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) ); +FGAPI void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) ); + +FGAPI void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) ); + +/* + * State setting and retrieval functions, see freeglut_state.c + */ +FGAPI int FGAPIENTRY glutGet( GLenum query ); +FGAPI int FGAPIENTRY glutDeviceGet( GLenum query ); +FGAPI int FGAPIENTRY glutGetModifiers( void ); +FGAPI int FGAPIENTRY glutLayerGet( GLenum query ); + +/* + * Font stuff, see freeglut_font.c + */ +FGAPI void FGAPIENTRY glutBitmapCharacter( void* font, int character ); +FGAPI int FGAPIENTRY glutBitmapWidth( void* font, int character ); +FGAPI void FGAPIENTRY glutStrokeCharacter( void* font, int character ); +FGAPI int FGAPIENTRY glutStrokeWidth( void* font, int character ); +FGAPI int FGAPIENTRY glutBitmapLength( void* font, const unsigned char* string ); +FGAPI int FGAPIENTRY glutStrokeLength( void* font, const unsigned char* string ); + +/* + * Geometry functions, see freeglut_geometry.c + */ +FGAPI void FGAPIENTRY glutWireCube( GLdouble size ); +FGAPI void FGAPIENTRY glutSolidCube( GLdouble size ); +FGAPI void FGAPIENTRY glutWireSphere( GLdouble radius, GLint slices, GLint stacks ); +FGAPI void FGAPIENTRY glutSolidSphere( GLdouble radius, GLint slices, GLint stacks ); +FGAPI void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLint stacks ); +FGAPI void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLint stacks ); + +FGAPI void FGAPIENTRY glutWireTorus( GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings ); +FGAPI void FGAPIENTRY glutSolidTorus( GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings ); +FGAPI void FGAPIENTRY glutWireDodecahedron( void ); +FGAPI void FGAPIENTRY glutSolidDodecahedron( void ); +FGAPI void FGAPIENTRY glutWireOctahedron( void ); +FGAPI void FGAPIENTRY glutSolidOctahedron( void ); +FGAPI void FGAPIENTRY glutWireTetrahedron( void ); +FGAPI void FGAPIENTRY glutSolidTetrahedron( void ); +FGAPI void FGAPIENTRY glutWireIcosahedron( void ); +FGAPI void FGAPIENTRY glutSolidIcosahedron( void ); + +/* + * Teapot rendering functions, found in freeglut_teapot.c + */ +FGAPI void FGAPIENTRY glutWireTeapot( GLdouble size ); +FGAPI void FGAPIENTRY glutSolidTeapot( GLdouble size ); + +/* + * Game mode functions, see freeglut_gamemode.c + */ +FGAPI void FGAPIENTRY glutGameModeString( const char* string ); +FGAPI int FGAPIENTRY glutEnterGameMode( void ); +FGAPI void FGAPIENTRY glutLeaveGameMode( void ); +FGAPI int FGAPIENTRY glutGameModeGet( GLenum query ); + +/* + * Video resize functions, see freeglut_videoresize.c + */ +FGAPI int FGAPIENTRY glutVideoResizeGet( GLenum query ); +FGAPI void FGAPIENTRY glutSetupVideoResizing( void ); +FGAPI void FGAPIENTRY glutStopVideoResizing( void ); +FGAPI void FGAPIENTRY glutVideoResize( int x, int y, int width, int height ); +FGAPI void FGAPIENTRY glutVideoPan( int x, int y, int width, int height ); + +/* + * Colormap functions, see freeglut_misc.c + */ +FGAPI void FGAPIENTRY glutSetColor( int color, GLfloat red, GLfloat green, GLfloat blue ); +FGAPI GLfloat FGAPIENTRY glutGetColor( int color, int component ); +FGAPI void FGAPIENTRY glutCopyColormap( int window ); + +/* + * Misc keyboard and joystick functions, see freeglut_misc.c + */ +FGAPI void FGAPIENTRY glutIgnoreKeyRepeat( int ignore ); +FGAPI void FGAPIENTRY glutSetKeyRepeat( int repeatMode ); /* DEPRECATED 11/4/02 - Do not use */ +FGAPI void FGAPIENTRY glutForceJoystickFunc( void ); + +/* + * Misc functions, see freeglut_misc.c + */ +FGAPI int FGAPIENTRY glutExtensionSupported( const char* extension ); +FGAPI void FGAPIENTRY glutReportErrors( void ); + +#ifdef __cplusplus + } +#endif + +/*** END OF FILE ***/ + +#endif /* __FREEGLUT_STD_H__ */ + diff --git a/external/cutil/inc/GL/glew.h b/external/cutil/inc/GL/glew.h new file mode 100644 index 0000000..4c13437 --- /dev/null +++ b/external/cutil/inc/GL/glew.h @@ -0,0 +1,14457 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + * Mesa 3-D graphics library + * Version: 7.0 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* +** Copyright (c) 2007 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#ifndef __glew_h__ +#define __glew_h__ +#define __GLEW_H__ + +#if defined(__gl_h_) || defined(__GL_H__) || defined(__X_GL_H) +#error gl.h included before glew.h +#endif +#if defined(__glext_h_) || defined(__GLEXT_H_) +#error glext.h included before glew.h +#endif +#if defined(__gl_ATI_h_) +#error glATI.h included before glew.h +#endif + +#define __gl_h_ +#define __GL_H__ +#define __X_GL_H +#define __glext_h_ +#define __GLEXT_H_ +#define __gl_ATI_h_ + +#if defined(_WIN32) + +/* + * GLEW does not include to avoid name space pollution. + * GL needs GLAPI and GLAPIENTRY, GLU needs APIENTRY, CALLBACK, and wchar_t + * defined properly. + */ +/* */ +#ifndef APIENTRY +#define GLEW_APIENTRY_DEFINED +# if defined(__MINGW32__) || defined(__CYGWIN__) +# define APIENTRY __stdcall +# elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +#endif +#ifndef GLAPI +# if defined(__MINGW32__) || defined(__CYGWIN__) +# define GLAPI extern +# endif +#endif +/* */ +#ifndef CALLBACK +#define GLEW_CALLBACK_DEFINED +# if defined(__MINGW32__) || defined(__CYGWIN__) +# define CALLBACK __attribute__ ((__stdcall__)) +# elif (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +#endif +/* and */ +#ifndef WINGDIAPI +#define GLEW_WINGDIAPI_DEFINED +#define WINGDIAPI __declspec(dllimport) +#endif +/* */ +#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(_WCHAR_T_DEFINED) +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +#endif +/* */ +#if !defined(_W64) +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && defined(_MSC_VER) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif +#if !defined(_PTRDIFF_T_DEFINED) && !defined(_PTRDIFF_T_) +# ifdef _WIN64 +typedef __int64 ptrdiff_t; +# else +typedef _W64 int ptrdiff_t; +# endif +# define _PTRDIFF_T_DEFINED +# define _PTRDIFF_T_ +#endif + +#ifndef GLAPI +# if defined(__MINGW32__) || defined(__CYGWIN__) +# define GLAPI extern +# else +# define GLAPI WINGDIAPI +# endif +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY APIENTRY +#endif + +/* + * GLEW_STATIC needs to be set when using the static version. + * GLEW_BUILD is set when building the DLL version. + */ +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# ifdef GLEW_BUILD +# define GLEWAPI extern __declspec(dllexport) +# else +# define GLEWAPI extern __declspec(dllimport) +# endif +#endif + +#else /* _UNIX */ + +/* + * Needed for ptrdiff_t in turn needed by VBO. This is defined by ISO + * C. On my system, this amounts to _3 lines_ of included code, all of + * them pretty much harmless. If you know of a way of detecting 32 vs + * 64 _targets_ at compile time you are free to replace this with + * something that's portable. For now, _this_ is the portable solution. + * (mem, 2004-01-04) + */ + +#include +#include + +#define GLEW_APIENTRY_DEFINED +#define APIENTRY +#define GLEWAPI extern + +/* */ +#ifndef GLAPI +#define GLAPI extern +#endif +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#endif /* _WIN32 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----------------------------- GL_VERSION_1_1 ---------------------------- */ + +#ifndef GL_VERSION_1_1 +#define GL_VERSION_1_1 1 + +typedef unsigned int GLenum; +typedef unsigned int GLbitfield; +typedef unsigned int GLuint; +typedef int GLint; +typedef int GLsizei; +typedef unsigned char GLboolean; +typedef signed char GLbyte; +typedef short GLshort; +typedef unsigned char GLubyte; +typedef unsigned short GLushort; +typedef unsigned long GLulong; +typedef float GLfloat; +typedef float GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void GLvoid; +#if defined(_MSC_VER) +# if _MSC_VER < 1400 +typedef __int64 GLint64EXT; +typedef unsigned __int64 GLuint64EXT; +# else +typedef signed long long GLint64EXT; +typedef unsigned long long GLuint64EXT; +# endif +#else +# if defined(__MINGW32__) || defined(__CYGWIN__) +#include +# endif +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +#endif +typedef GLint64EXT GLint64; +typedef GLuint64EXT GLuint64; +typedef struct __GLsync *GLsync; + +#define GL_ACCUM 0x0100 +#define GL_LOAD 0x0101 +#define GL_RETURN 0x0102 +#define GL_MULT 0x0103 +#define GL_ADD 0x0104 +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_CURRENT_BIT 0x00000001 +#define GL_POINT_BIT 0x00000002 +#define GL_LINE_BIT 0x00000004 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_HINT_BIT 0x00008000 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0x000fffff +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON 0x0009 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_TRUE 1 +#define GL_FALSE 0 +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_DOUBLE 0x140A +#define GL_NONE 0 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LIST_MODE 0x0B30 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_SHADE_MODEL 0x0B54 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_FOG 0x0B60 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_COLOR 0x0B66 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_MATRIX_MODE 0x0BA0 +#define GL_NORMALIZE 0x0BA1 +#define GL_VIEWPORT 0x0BA2 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_DITHER 0x0BD0 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND 0x0BE2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_READ_BUFFER 0x0C02 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_INDEX_MODE 0x0C30 +#define GL_RGBA_MODE 0x0C31 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_RENDER_MODE 0x0C40 +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_FOG_HINT 0x0C54 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_INDEX_BITS 0x0D51 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_CLEAR 0x1500 +#define GL_AND 0x1501 +#define GL_AND_REVERSE 0x1502 +#define GL_COPY 0x1503 +#define GL_AND_INVERTED 0x1504 +#define GL_NOOP 0x1505 +#define GL_XOR 0x1506 +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_EQUIV 0x1509 +#define GL_INVERT 0x150A +#define GL_OR_REVERSE 0x150B +#define GL_COPY_INVERTED 0x150C +#define GL_OR_INVERTED 0x150D +#define GL_NAND 0x150E +#define GL_SET 0x150F +#define GL_EMISSION 0x1600 +#define GL_SHININESS 0x1601 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_COLOR_INDEX 0x1900 +#define GL_STENCIL_INDEX 0x1901 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_BITMAP 0x1A00 +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_RENDER 0x1C00 +#define GL_FEEDBACK 0x1C01 +#define GL_SELECT 0x1C02 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 +#define GL_MODULATE 0x2100 +#define GL_DECAL 0x2101 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV 0x2300 +#define GL_EYE_LINEAR 0x2400 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_SPHERE_MAP 0x2402 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_PLANE 0x2502 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_CLAMP 0x2900 +#define GL_REPEAT 0x2901 +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D +#define GL_LOGIC_OP GL_INDEX_LOGIC_OP +#define GL_TEXTURE_COMPONENTS GL_TEXTURE_INTERNAL_FORMAT +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 + +GLAPI void GLAPIENTRY glAccum (GLenum op, GLfloat value); +GLAPI void GLAPIENTRY glAlphaFunc (GLenum func, GLclampf ref); +GLAPI GLboolean GLAPIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences); +GLAPI void GLAPIENTRY glArrayElement (GLint i); +GLAPI void GLAPIENTRY glBegin (GLenum mode); +GLAPI void GLAPIENTRY glBindTexture (GLenum target, GLuint texture); +GLAPI void GLAPIENTRY glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +GLAPI void GLAPIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GLAPI void GLAPIENTRY glCallList (GLuint list); +GLAPI void GLAPIENTRY glCallLists (GLsizei n, GLenum type, const GLvoid *lists); +GLAPI void GLAPIENTRY glClear (GLbitfield mask); +GLAPI void GLAPIENTRY glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GLAPI void GLAPIENTRY glClearDepth (GLclampd depth); +GLAPI void GLAPIENTRY glClearIndex (GLfloat c); +GLAPI void GLAPIENTRY glClearStencil (GLint s); +GLAPI void GLAPIENTRY glClipPlane (GLenum plane, const GLdouble *equation); +GLAPI void GLAPIENTRY glColor3b (GLbyte red, GLbyte green, GLbyte blue); +GLAPI void GLAPIENTRY glColor3bv (const GLbyte *v); +GLAPI void GLAPIENTRY glColor3d (GLdouble red, GLdouble green, GLdouble blue); +GLAPI void GLAPIENTRY glColor3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue); +GLAPI void GLAPIENTRY glColor3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glColor3i (GLint red, GLint green, GLint blue); +GLAPI void GLAPIENTRY glColor3iv (const GLint *v); +GLAPI void GLAPIENTRY glColor3s (GLshort red, GLshort green, GLshort blue); +GLAPI void GLAPIENTRY glColor3sv (const GLshort *v); +GLAPI void GLAPIENTRY glColor3ub (GLubyte red, GLubyte green, GLubyte blue); +GLAPI void GLAPIENTRY glColor3ubv (const GLubyte *v); +GLAPI void GLAPIENTRY glColor3ui (GLuint red, GLuint green, GLuint blue); +GLAPI void GLAPIENTRY glColor3uiv (const GLuint *v); +GLAPI void GLAPIENTRY glColor3us (GLushort red, GLushort green, GLushort blue); +GLAPI void GLAPIENTRY glColor3usv (const GLushort *v); +GLAPI void GLAPIENTRY glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +GLAPI void GLAPIENTRY glColor4bv (const GLbyte *v); +GLAPI void GLAPIENTRY glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +GLAPI void GLAPIENTRY glColor4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glColor4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glColor4i (GLint red, GLint green, GLint blue, GLint alpha); +GLAPI void GLAPIENTRY glColor4iv (const GLint *v); +GLAPI void GLAPIENTRY glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha); +GLAPI void GLAPIENTRY glColor4sv (const GLshort *v); +GLAPI void GLAPIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +GLAPI void GLAPIENTRY glColor4ubv (const GLubyte *v); +GLAPI void GLAPIENTRY glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha); +GLAPI void GLAPIENTRY glColor4uiv (const GLuint *v); +GLAPI void GLAPIENTRY glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha); +GLAPI void GLAPIENTRY glColor4usv (const GLushort *v); +GLAPI void GLAPIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GLAPI void GLAPIENTRY glColorMaterial (GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +GLAPI void GLAPIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void GLAPIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void GLAPIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void GLAPIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void GLAPIENTRY glCullFace (GLenum mode); +GLAPI void GLAPIENTRY glDeleteLists (GLuint list, GLsizei range); +GLAPI void GLAPIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GLAPI void GLAPIENTRY glDepthFunc (GLenum func); +GLAPI void GLAPIENTRY glDepthMask (GLboolean flag); +GLAPI void GLAPIENTRY glDepthRange (GLclampd zNear, GLclampd zFar); +GLAPI void GLAPIENTRY glDisable (GLenum cap); +GLAPI void GLAPIENTRY glDisableClientState (GLenum array); +GLAPI void GLAPIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GLAPI void GLAPIENTRY glDrawBuffer (GLenum mode); +GLAPI void GLAPIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +GLAPI void GLAPIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glEdgeFlag (GLboolean flag); +GLAPI void GLAPIENTRY glEdgeFlagPointer (GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glEdgeFlagv (const GLboolean *flag); +GLAPI void GLAPIENTRY glEnable (GLenum cap); +GLAPI void GLAPIENTRY glEnableClientState (GLenum array); +GLAPI void GLAPIENTRY glEnd (void); +GLAPI void GLAPIENTRY glEndList (void); +GLAPI void GLAPIENTRY glEvalCoord1d (GLdouble u); +GLAPI void GLAPIENTRY glEvalCoord1dv (const GLdouble *u); +GLAPI void GLAPIENTRY glEvalCoord1f (GLfloat u); +GLAPI void GLAPIENTRY glEvalCoord1fv (const GLfloat *u); +GLAPI void GLAPIENTRY glEvalCoord2d (GLdouble u, GLdouble v); +GLAPI void GLAPIENTRY glEvalCoord2dv (const GLdouble *u); +GLAPI void GLAPIENTRY glEvalCoord2f (GLfloat u, GLfloat v); +GLAPI void GLAPIENTRY glEvalCoord2fv (const GLfloat *u); +GLAPI void GLAPIENTRY glEvalMesh1 (GLenum mode, GLint i1, GLint i2); +GLAPI void GLAPIENTRY glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +GLAPI void GLAPIENTRY glEvalPoint1 (GLint i); +GLAPI void GLAPIENTRY glEvalPoint2 (GLint i, GLint j); +GLAPI void GLAPIENTRY glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer); +GLAPI void GLAPIENTRY glFinish (void); +GLAPI void GLAPIENTRY glFlush (void); +GLAPI void GLAPIENTRY glFogf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glFogfv (GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glFogi (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glFogiv (GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glFrontFace (GLenum mode); +GLAPI void GLAPIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI GLuint GLAPIENTRY glGenLists (GLsizei range); +GLAPI void GLAPIENTRY glGenTextures (GLsizei n, GLuint *textures); +GLAPI void GLAPIENTRY glGetBooleanv (GLenum pname, GLboolean *params); +GLAPI void GLAPIENTRY glGetClipPlane (GLenum plane, GLdouble *equation); +GLAPI void GLAPIENTRY glGetDoublev (GLenum pname, GLdouble *params); +GLAPI GLenum GLAPIENTRY glGetError (void); +GLAPI void GLAPIENTRY glGetFloatv (GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetIntegerv (GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetLightiv (GLenum light, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetMapdv (GLenum target, GLenum query, GLdouble *v); +GLAPI void GLAPIENTRY glGetMapfv (GLenum target, GLenum query, GLfloat *v); +GLAPI void GLAPIENTRY glGetMapiv (GLenum target, GLenum query, GLint *v); +GLAPI void GLAPIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetMaterialiv (GLenum face, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetPixelMapfv (GLenum map, GLfloat *values); +GLAPI void GLAPIENTRY glGetPixelMapuiv (GLenum map, GLuint *values); +GLAPI void GLAPIENTRY glGetPixelMapusv (GLenum map, GLushort *values); +GLAPI void GLAPIENTRY glGetPointerv (GLenum pname, GLvoid* *params); +GLAPI void GLAPIENTRY glGetPolygonStipple (GLubyte *mask); +GLAPI const GLubyte * GLAPIENTRY glGetString (GLenum name); +GLAPI void GLAPIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params); +GLAPI void GLAPIENTRY glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexGeniv (GLenum coord, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +GLAPI void GLAPIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glHint (GLenum target, GLenum mode); +GLAPI void GLAPIENTRY glIndexMask (GLuint mask); +GLAPI void GLAPIENTRY glIndexPointer (GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glIndexd (GLdouble c); +GLAPI void GLAPIENTRY glIndexdv (const GLdouble *c); +GLAPI void GLAPIENTRY glIndexf (GLfloat c); +GLAPI void GLAPIENTRY glIndexfv (const GLfloat *c); +GLAPI void GLAPIENTRY glIndexi (GLint c); +GLAPI void GLAPIENTRY glIndexiv (const GLint *c); +GLAPI void GLAPIENTRY glIndexs (GLshort c); +GLAPI void GLAPIENTRY glIndexsv (const GLshort *c); +GLAPI void GLAPIENTRY glIndexub (GLubyte c); +GLAPI void GLAPIENTRY glIndexubv (const GLubyte *c); +GLAPI void GLAPIENTRY glInitNames (void); +GLAPI void GLAPIENTRY glInterleavedArrays (GLenum format, GLsizei stride, const GLvoid *pointer); +GLAPI GLboolean GLAPIENTRY glIsEnabled (GLenum cap); +GLAPI GLboolean GLAPIENTRY glIsList (GLuint list); +GLAPI GLboolean GLAPIENTRY glIsTexture (GLuint texture); +GLAPI void GLAPIENTRY glLightModelf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightModelfv (GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glLightModeli (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightModeliv (GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glLightf (GLenum light, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glLighti (GLenum light, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightiv (GLenum light, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glLineStipple (GLint factor, GLushort pattern); +GLAPI void GLAPIENTRY glLineWidth (GLfloat width); +GLAPI void GLAPIENTRY glListBase (GLuint base); +GLAPI void GLAPIENTRY glLoadIdentity (void); +GLAPI void GLAPIENTRY glLoadMatrixd (const GLdouble *m); +GLAPI void GLAPIENTRY glLoadMatrixf (const GLfloat *m); +GLAPI void GLAPIENTRY glLoadName (GLuint name); +GLAPI void GLAPIENTRY glLogicOp (GLenum opcode); +GLAPI void GLAPIENTRY glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +GLAPI void GLAPIENTRY glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +GLAPI void GLAPIENTRY glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +GLAPI void GLAPIENTRY glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +GLAPI void GLAPIENTRY glMapGrid1d (GLint un, GLdouble u1, GLdouble u2); +GLAPI void GLAPIENTRY glMapGrid1f (GLint un, GLfloat u1, GLfloat u2); +GLAPI void GLAPIENTRY glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +GLAPI void GLAPIENTRY glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +GLAPI void GLAPIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glMateriali (GLenum face, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glMaterialiv (GLenum face, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glMatrixMode (GLenum mode); +GLAPI void GLAPIENTRY glMultMatrixd (const GLdouble *m); +GLAPI void GLAPIENTRY glMultMatrixf (const GLfloat *m); +GLAPI void GLAPIENTRY glNewList (GLuint list, GLenum mode); +GLAPI void GLAPIENTRY glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz); +GLAPI void GLAPIENTRY glNormal3bv (const GLbyte *v); +GLAPI void GLAPIENTRY glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz); +GLAPI void GLAPIENTRY glNormal3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz); +GLAPI void GLAPIENTRY glNormal3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glNormal3i (GLint nx, GLint ny, GLint nz); +GLAPI void GLAPIENTRY glNormal3iv (const GLint *v); +GLAPI void GLAPIENTRY glNormal3s (GLshort nx, GLshort ny, GLshort nz); +GLAPI void GLAPIENTRY glNormal3sv (const GLshort *v); +GLAPI void GLAPIENTRY glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI void GLAPIENTRY glPassThrough (GLfloat token); +GLAPI void GLAPIENTRY glPixelMapfv (GLenum map, GLsizei mapsize, const GLfloat *values); +GLAPI void GLAPIENTRY glPixelMapuiv (GLenum map, GLsizei mapsize, const GLuint *values); +GLAPI void GLAPIENTRY glPixelMapusv (GLenum map, GLsizei mapsize, const GLushort *values); +GLAPI void GLAPIENTRY glPixelStoref (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelStorei (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelTransferf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelTransferi (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelZoom (GLfloat xfactor, GLfloat yfactor); +GLAPI void GLAPIENTRY glPointSize (GLfloat size); +GLAPI void GLAPIENTRY glPolygonMode (GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GLAPI void GLAPIENTRY glPolygonStipple (const GLubyte *mask); +GLAPI void GLAPIENTRY glPopAttrib (void); +GLAPI void GLAPIENTRY glPopClientAttrib (void); +GLAPI void GLAPIENTRY glPopMatrix (void); +GLAPI void GLAPIENTRY glPopName (void); +GLAPI void GLAPIENTRY glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities); +GLAPI void GLAPIENTRY glPushAttrib (GLbitfield mask); +GLAPI void GLAPIENTRY glPushClientAttrib (GLbitfield mask); +GLAPI void GLAPIENTRY glPushMatrix (void); +GLAPI void GLAPIENTRY glPushName (GLuint name); +GLAPI void GLAPIENTRY glRasterPos2d (GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glRasterPos2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos2f (GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glRasterPos2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos2i (GLint x, GLint y); +GLAPI void GLAPIENTRY glRasterPos2iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos2s (GLshort x, GLshort y); +GLAPI void GLAPIENTRY glRasterPos2sv (const GLshort *v); +GLAPI void GLAPIENTRY glRasterPos3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRasterPos3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glRasterPos3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos3i (GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glRasterPos3iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos3s (GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glRasterPos3sv (const GLshort *v); +GLAPI void GLAPIENTRY glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glRasterPos4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glRasterPos4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos4i (GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glRasterPos4iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glRasterPos4sv (const GLshort *v); +GLAPI void GLAPIENTRY glReadBuffer (GLenum mode); +GLAPI void GLAPIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +GLAPI void GLAPIENTRY glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +GLAPI void GLAPIENTRY glRectdv (const GLdouble *v1, const GLdouble *v2); +GLAPI void GLAPIENTRY glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +GLAPI void GLAPIENTRY glRectfv (const GLfloat *v1, const GLfloat *v2); +GLAPI void GLAPIENTRY glRecti (GLint x1, GLint y1, GLint x2, GLint y2); +GLAPI void GLAPIENTRY glRectiv (const GLint *v1, const GLint *v2); +GLAPI void GLAPIENTRY glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2); +GLAPI void GLAPIENTRY glRectsv (const GLshort *v1, const GLshort *v2); +GLAPI GLint GLAPIENTRY glRenderMode (GLenum mode); +GLAPI void GLAPIENTRY glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScaled (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void GLAPIENTRY glSelectBuffer (GLsizei size, GLuint *buffer); +GLAPI void GLAPIENTRY glShadeModel (GLenum mode); +GLAPI void GLAPIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GLAPI void GLAPIENTRY glStencilMask (GLuint mask); +GLAPI void GLAPIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GLAPI void GLAPIENTRY glTexCoord1d (GLdouble s); +GLAPI void GLAPIENTRY glTexCoord1dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord1f (GLfloat s); +GLAPI void GLAPIENTRY glTexCoord1fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord1i (GLint s); +GLAPI void GLAPIENTRY glTexCoord1iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord1s (GLshort s); +GLAPI void GLAPIENTRY glTexCoord1sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord2d (GLdouble s, GLdouble t); +GLAPI void GLAPIENTRY glTexCoord2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord2f (GLfloat s, GLfloat t); +GLAPI void GLAPIENTRY glTexCoord2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord2i (GLint s, GLint t); +GLAPI void GLAPIENTRY glTexCoord2iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord2s (GLshort s, GLshort t); +GLAPI void GLAPIENTRY glTexCoord2sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord3d (GLdouble s, GLdouble t, GLdouble r); +GLAPI void GLAPIENTRY glTexCoord3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord3f (GLfloat s, GLfloat t, GLfloat r); +GLAPI void GLAPIENTRY glTexCoord3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord3i (GLint s, GLint t, GLint r); +GLAPI void GLAPIENTRY glTexCoord3iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord3s (GLshort s, GLshort t, GLshort r); +GLAPI void GLAPIENTRY glTexCoord3sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void GLAPIENTRY glTexCoord4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void GLAPIENTRY glTexCoord4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord4i (GLint s, GLint t, GLint r, GLint q); +GLAPI void GLAPIENTRY glTexCoord4iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void GLAPIENTRY glTexCoord4sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexGend (GLenum coord, GLenum pname, GLdouble param); +GLAPI void GLAPIENTRY glTexGendv (GLenum coord, GLenum pname, const GLdouble *params); +GLAPI void GLAPIENTRY glTexGenf (GLenum coord, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexGeniv (GLenum coord, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTranslated (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex2d (GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glVertex2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex2f (GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glVertex2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex2i (GLint x, GLint y); +GLAPI void GLAPIENTRY glVertex2iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex2s (GLshort x, GLshort y); +GLAPI void GLAPIENTRY glVertex2sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glVertex3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex3i (GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glVertex3iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex3s (GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glVertex3sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glVertex4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glVertex4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glVertex4iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glVertex4sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#define GLEW_VERSION_1_1 GLEW_GET_VAR(__GLEW_VERSION_1_1) + +#endif /* GL_VERSION_1_1 */ + +/* ---------------------------------- GLU ---------------------------------- */ + +/* this is where we can safely include GLU */ +#if defined(__APPLE__) && defined(__MACH__) +#include +#else +#include +#endif + +/* ----------------------------- GL_VERSION_1_2 ---------------------------- */ + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 + +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E + +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); + +#define glCopyTexSubImage3D GLEW_GET_FUN(__glewCopyTexSubImage3D) +#define glDrawRangeElements GLEW_GET_FUN(__glewDrawRangeElements) +#define glTexImage3D GLEW_GET_FUN(__glewTexImage3D) +#define glTexSubImage3D GLEW_GET_FUN(__glewTexSubImage3D) + +#define GLEW_VERSION_1_2 GLEW_GET_VAR(__GLEW_VERSION_1_2) + +#endif /* GL_VERSION_1_2 */ + +/* ----------------------------- GL_VERSION_1_3 ---------------------------- */ + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 + +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_SUBTRACT 0x84E7 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#define GL_MULTISAMPLE_BIT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLvoid *img); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); + +#define glActiveTexture GLEW_GET_FUN(__glewActiveTexture) +#define glClientActiveTexture GLEW_GET_FUN(__glewClientActiveTexture) +#define glCompressedTexImage1D GLEW_GET_FUN(__glewCompressedTexImage1D) +#define glCompressedTexImage2D GLEW_GET_FUN(__glewCompressedTexImage2D) +#define glCompressedTexImage3D GLEW_GET_FUN(__glewCompressedTexImage3D) +#define glCompressedTexSubImage1D GLEW_GET_FUN(__glewCompressedTexSubImage1D) +#define glCompressedTexSubImage2D GLEW_GET_FUN(__glewCompressedTexSubImage2D) +#define glCompressedTexSubImage3D GLEW_GET_FUN(__glewCompressedTexSubImage3D) +#define glGetCompressedTexImage GLEW_GET_FUN(__glewGetCompressedTexImage) +#define glLoadTransposeMatrixd GLEW_GET_FUN(__glewLoadTransposeMatrixd) +#define glLoadTransposeMatrixf GLEW_GET_FUN(__glewLoadTransposeMatrixf) +#define glMultTransposeMatrixd GLEW_GET_FUN(__glewMultTransposeMatrixd) +#define glMultTransposeMatrixf GLEW_GET_FUN(__glewMultTransposeMatrixf) +#define glMultiTexCoord1d GLEW_GET_FUN(__glewMultiTexCoord1d) +#define glMultiTexCoord1dv GLEW_GET_FUN(__glewMultiTexCoord1dv) +#define glMultiTexCoord1f GLEW_GET_FUN(__glewMultiTexCoord1f) +#define glMultiTexCoord1fv GLEW_GET_FUN(__glewMultiTexCoord1fv) +#define glMultiTexCoord1i GLEW_GET_FUN(__glewMultiTexCoord1i) +#define glMultiTexCoord1iv GLEW_GET_FUN(__glewMultiTexCoord1iv) +#define glMultiTexCoord1s GLEW_GET_FUN(__glewMultiTexCoord1s) +#define glMultiTexCoord1sv GLEW_GET_FUN(__glewMultiTexCoord1sv) +#define glMultiTexCoord2d GLEW_GET_FUN(__glewMultiTexCoord2d) +#define glMultiTexCoord2dv GLEW_GET_FUN(__glewMultiTexCoord2dv) +#define glMultiTexCoord2f GLEW_GET_FUN(__glewMultiTexCoord2f) +#define glMultiTexCoord2fv GLEW_GET_FUN(__glewMultiTexCoord2fv) +#define glMultiTexCoord2i GLEW_GET_FUN(__glewMultiTexCoord2i) +#define glMultiTexCoord2iv GLEW_GET_FUN(__glewMultiTexCoord2iv) +#define glMultiTexCoord2s GLEW_GET_FUN(__glewMultiTexCoord2s) +#define glMultiTexCoord2sv GLEW_GET_FUN(__glewMultiTexCoord2sv) +#define glMultiTexCoord3d GLEW_GET_FUN(__glewMultiTexCoord3d) +#define glMultiTexCoord3dv GLEW_GET_FUN(__glewMultiTexCoord3dv) +#define glMultiTexCoord3f GLEW_GET_FUN(__glewMultiTexCoord3f) +#define glMultiTexCoord3fv GLEW_GET_FUN(__glewMultiTexCoord3fv) +#define glMultiTexCoord3i GLEW_GET_FUN(__glewMultiTexCoord3i) +#define glMultiTexCoord3iv GLEW_GET_FUN(__glewMultiTexCoord3iv) +#define glMultiTexCoord3s GLEW_GET_FUN(__glewMultiTexCoord3s) +#define glMultiTexCoord3sv GLEW_GET_FUN(__glewMultiTexCoord3sv) +#define glMultiTexCoord4d GLEW_GET_FUN(__glewMultiTexCoord4d) +#define glMultiTexCoord4dv GLEW_GET_FUN(__glewMultiTexCoord4dv) +#define glMultiTexCoord4f GLEW_GET_FUN(__glewMultiTexCoord4f) +#define glMultiTexCoord4fv GLEW_GET_FUN(__glewMultiTexCoord4fv) +#define glMultiTexCoord4i GLEW_GET_FUN(__glewMultiTexCoord4i) +#define glMultiTexCoord4iv GLEW_GET_FUN(__glewMultiTexCoord4iv) +#define glMultiTexCoord4s GLEW_GET_FUN(__glewMultiTexCoord4s) +#define glMultiTexCoord4sv GLEW_GET_FUN(__glewMultiTexCoord4sv) +#define glSampleCoverage GLEW_GET_FUN(__glewSampleCoverage) + +#define GLEW_VERSION_1_3 GLEW_GET_VAR(__GLEW_VERSION_1_3) + +#endif /* GL_VERSION_1_3 */ + +/* ----------------------------- GL_VERSION_1_4 ---------------------------- */ + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 + +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E + +typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVPROC) (const GLdouble *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVPROC) (const GLfloat *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVPROC) (const GLint *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVPROC) (const GLshort *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVPROC) (const GLdouble *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVPROC) (const GLfloat *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVPROC) (const GLint *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVPROC) (const GLshort *p); + +#define glBlendColor GLEW_GET_FUN(__glewBlendColor) +#define glBlendEquation GLEW_GET_FUN(__glewBlendEquation) +#define glBlendFuncSeparate GLEW_GET_FUN(__glewBlendFuncSeparate) +#define glFogCoordPointer GLEW_GET_FUN(__glewFogCoordPointer) +#define glFogCoordd GLEW_GET_FUN(__glewFogCoordd) +#define glFogCoorddv GLEW_GET_FUN(__glewFogCoorddv) +#define glFogCoordf GLEW_GET_FUN(__glewFogCoordf) +#define glFogCoordfv GLEW_GET_FUN(__glewFogCoordfv) +#define glMultiDrawArrays GLEW_GET_FUN(__glewMultiDrawArrays) +#define glMultiDrawElements GLEW_GET_FUN(__glewMultiDrawElements) +#define glPointParameterf GLEW_GET_FUN(__glewPointParameterf) +#define glPointParameterfv GLEW_GET_FUN(__glewPointParameterfv) +#define glPointParameteri GLEW_GET_FUN(__glewPointParameteri) +#define glPointParameteriv GLEW_GET_FUN(__glewPointParameteriv) +#define glSecondaryColor3b GLEW_GET_FUN(__glewSecondaryColor3b) +#define glSecondaryColor3bv GLEW_GET_FUN(__glewSecondaryColor3bv) +#define glSecondaryColor3d GLEW_GET_FUN(__glewSecondaryColor3d) +#define glSecondaryColor3dv GLEW_GET_FUN(__glewSecondaryColor3dv) +#define glSecondaryColor3f GLEW_GET_FUN(__glewSecondaryColor3f) +#define glSecondaryColor3fv GLEW_GET_FUN(__glewSecondaryColor3fv) +#define glSecondaryColor3i GLEW_GET_FUN(__glewSecondaryColor3i) +#define glSecondaryColor3iv GLEW_GET_FUN(__glewSecondaryColor3iv) +#define glSecondaryColor3s GLEW_GET_FUN(__glewSecondaryColor3s) +#define glSecondaryColor3sv GLEW_GET_FUN(__glewSecondaryColor3sv) +#define glSecondaryColor3ub GLEW_GET_FUN(__glewSecondaryColor3ub) +#define glSecondaryColor3ubv GLEW_GET_FUN(__glewSecondaryColor3ubv) +#define glSecondaryColor3ui GLEW_GET_FUN(__glewSecondaryColor3ui) +#define glSecondaryColor3uiv GLEW_GET_FUN(__glewSecondaryColor3uiv) +#define glSecondaryColor3us GLEW_GET_FUN(__glewSecondaryColor3us) +#define glSecondaryColor3usv GLEW_GET_FUN(__glewSecondaryColor3usv) +#define glSecondaryColorPointer GLEW_GET_FUN(__glewSecondaryColorPointer) +#define glWindowPos2d GLEW_GET_FUN(__glewWindowPos2d) +#define glWindowPos2dv GLEW_GET_FUN(__glewWindowPos2dv) +#define glWindowPos2f GLEW_GET_FUN(__glewWindowPos2f) +#define glWindowPos2fv GLEW_GET_FUN(__glewWindowPos2fv) +#define glWindowPos2i GLEW_GET_FUN(__glewWindowPos2i) +#define glWindowPos2iv GLEW_GET_FUN(__glewWindowPos2iv) +#define glWindowPos2s GLEW_GET_FUN(__glewWindowPos2s) +#define glWindowPos2sv GLEW_GET_FUN(__glewWindowPos2sv) +#define glWindowPos3d GLEW_GET_FUN(__glewWindowPos3d) +#define glWindowPos3dv GLEW_GET_FUN(__glewWindowPos3dv) +#define glWindowPos3f GLEW_GET_FUN(__glewWindowPos3f) +#define glWindowPos3fv GLEW_GET_FUN(__glewWindowPos3fv) +#define glWindowPos3i GLEW_GET_FUN(__glewWindowPos3i) +#define glWindowPos3iv GLEW_GET_FUN(__glewWindowPos3iv) +#define glWindowPos3s GLEW_GET_FUN(__glewWindowPos3s) +#define glWindowPos3sv GLEW_GET_FUN(__glewWindowPos3sv) + +#define GLEW_VERSION_1_4 GLEW_GET_VAR(__GLEW_VERSION_1_4) + +#endif /* GL_VERSION_1_4 */ + +/* ----------------------------- GL_VERSION_1_5 ---------------------------- */ + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 + +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +#define GL_SRC2_RGB GL_SOURCE2_RGB +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 + +typedef ptrdiff_t GLsizeiptr; +typedef ptrdiff_t GLintptr; + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id); +typedef GLvoid* (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERPROC) (GLenum target); + +#define glBeginQuery GLEW_GET_FUN(__glewBeginQuery) +#define glBindBuffer GLEW_GET_FUN(__glewBindBuffer) +#define glBufferData GLEW_GET_FUN(__glewBufferData) +#define glBufferSubData GLEW_GET_FUN(__glewBufferSubData) +#define glDeleteBuffers GLEW_GET_FUN(__glewDeleteBuffers) +#define glDeleteQueries GLEW_GET_FUN(__glewDeleteQueries) +#define glEndQuery GLEW_GET_FUN(__glewEndQuery) +#define glGenBuffers GLEW_GET_FUN(__glewGenBuffers) +#define glGenQueries GLEW_GET_FUN(__glewGenQueries) +#define glGetBufferParameteriv GLEW_GET_FUN(__glewGetBufferParameteriv) +#define glGetBufferPointerv GLEW_GET_FUN(__glewGetBufferPointerv) +#define glGetBufferSubData GLEW_GET_FUN(__glewGetBufferSubData) +#define glGetQueryObjectiv GLEW_GET_FUN(__glewGetQueryObjectiv) +#define glGetQueryObjectuiv GLEW_GET_FUN(__glewGetQueryObjectuiv) +#define glGetQueryiv GLEW_GET_FUN(__glewGetQueryiv) +#define glIsBuffer GLEW_GET_FUN(__glewIsBuffer) +#define glIsQuery GLEW_GET_FUN(__glewIsQuery) +#define glMapBuffer GLEW_GET_FUN(__glewMapBuffer) +#define glUnmapBuffer GLEW_GET_FUN(__glewUnmapBuffer) + +#define GLEW_VERSION_1_5 GLEW_GET_VAR(__GLEW_VERSION_1_5) + +#endif /* GL_VERSION_1_5 */ + +/* ----------------------------- GL_VERSION_2_0 ---------------------------- */ + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 + +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 + +typedef char GLchar; + +typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum, GLenum); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum* bufs); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source); +typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint, GLenum, GLvoid*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint, GLenum, GLdouble*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint, GLenum, GLfloat*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint, GLenum, GLint*); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths); +typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); + +#define glAttachShader GLEW_GET_FUN(__glewAttachShader) +#define glBindAttribLocation GLEW_GET_FUN(__glewBindAttribLocation) +#define glBlendEquationSeparate GLEW_GET_FUN(__glewBlendEquationSeparate) +#define glCompileShader GLEW_GET_FUN(__glewCompileShader) +#define glCreateProgram GLEW_GET_FUN(__glewCreateProgram) +#define glCreateShader GLEW_GET_FUN(__glewCreateShader) +#define glDeleteProgram GLEW_GET_FUN(__glewDeleteProgram) +#define glDeleteShader GLEW_GET_FUN(__glewDeleteShader) +#define glDetachShader GLEW_GET_FUN(__glewDetachShader) +#define glDisableVertexAttribArray GLEW_GET_FUN(__glewDisableVertexAttribArray) +#define glDrawBuffers GLEW_GET_FUN(__glewDrawBuffers) +#define glEnableVertexAttribArray GLEW_GET_FUN(__glewEnableVertexAttribArray) +#define glGetActiveAttrib GLEW_GET_FUN(__glewGetActiveAttrib) +#define glGetActiveUniform GLEW_GET_FUN(__glewGetActiveUniform) +#define glGetAttachedShaders GLEW_GET_FUN(__glewGetAttachedShaders) +#define glGetAttribLocation GLEW_GET_FUN(__glewGetAttribLocation) +#define glGetProgramInfoLog GLEW_GET_FUN(__glewGetProgramInfoLog) +#define glGetProgramiv GLEW_GET_FUN(__glewGetProgramiv) +#define glGetShaderInfoLog GLEW_GET_FUN(__glewGetShaderInfoLog) +#define glGetShaderSource GLEW_GET_FUN(__glewGetShaderSource) +#define glGetShaderiv GLEW_GET_FUN(__glewGetShaderiv) +#define glGetUniformLocation GLEW_GET_FUN(__glewGetUniformLocation) +#define glGetUniformfv GLEW_GET_FUN(__glewGetUniformfv) +#define glGetUniformiv GLEW_GET_FUN(__glewGetUniformiv) +#define glGetVertexAttribPointerv GLEW_GET_FUN(__glewGetVertexAttribPointerv) +#define glGetVertexAttribdv GLEW_GET_FUN(__glewGetVertexAttribdv) +#define glGetVertexAttribfv GLEW_GET_FUN(__glewGetVertexAttribfv) +#define glGetVertexAttribiv GLEW_GET_FUN(__glewGetVertexAttribiv) +#define glIsProgram GLEW_GET_FUN(__glewIsProgram) +#define glIsShader GLEW_GET_FUN(__glewIsShader) +#define glLinkProgram GLEW_GET_FUN(__glewLinkProgram) +#define glShaderSource GLEW_GET_FUN(__glewShaderSource) +#define glStencilFuncSeparate GLEW_GET_FUN(__glewStencilFuncSeparate) +#define glStencilMaskSeparate GLEW_GET_FUN(__glewStencilMaskSeparate) +#define glStencilOpSeparate GLEW_GET_FUN(__glewStencilOpSeparate) +#define glUniform1f GLEW_GET_FUN(__glewUniform1f) +#define glUniform1fv GLEW_GET_FUN(__glewUniform1fv) +#define glUniform1i GLEW_GET_FUN(__glewUniform1i) +#define glUniform1iv GLEW_GET_FUN(__glewUniform1iv) +#define glUniform2f GLEW_GET_FUN(__glewUniform2f) +#define glUniform2fv GLEW_GET_FUN(__glewUniform2fv) +#define glUniform2i GLEW_GET_FUN(__glewUniform2i) +#define glUniform2iv GLEW_GET_FUN(__glewUniform2iv) +#define glUniform3f GLEW_GET_FUN(__glewUniform3f) +#define glUniform3fv GLEW_GET_FUN(__glewUniform3fv) +#define glUniform3i GLEW_GET_FUN(__glewUniform3i) +#define glUniform3iv GLEW_GET_FUN(__glewUniform3iv) +#define glUniform4f GLEW_GET_FUN(__glewUniform4f) +#define glUniform4fv GLEW_GET_FUN(__glewUniform4fv) +#define glUniform4i GLEW_GET_FUN(__glewUniform4i) +#define glUniform4iv GLEW_GET_FUN(__glewUniform4iv) +#define glUniformMatrix2fv GLEW_GET_FUN(__glewUniformMatrix2fv) +#define glUniformMatrix3fv GLEW_GET_FUN(__glewUniformMatrix3fv) +#define glUniformMatrix4fv GLEW_GET_FUN(__glewUniformMatrix4fv) +#define glUseProgram GLEW_GET_FUN(__glewUseProgram) +#define glValidateProgram GLEW_GET_FUN(__glewValidateProgram) +#define glVertexAttrib1d GLEW_GET_FUN(__glewVertexAttrib1d) +#define glVertexAttrib1dv GLEW_GET_FUN(__glewVertexAttrib1dv) +#define glVertexAttrib1f GLEW_GET_FUN(__glewVertexAttrib1f) +#define glVertexAttrib1fv GLEW_GET_FUN(__glewVertexAttrib1fv) +#define glVertexAttrib1s GLEW_GET_FUN(__glewVertexAttrib1s) +#define glVertexAttrib1sv GLEW_GET_FUN(__glewVertexAttrib1sv) +#define glVertexAttrib2d GLEW_GET_FUN(__glewVertexAttrib2d) +#define glVertexAttrib2dv GLEW_GET_FUN(__glewVertexAttrib2dv) +#define glVertexAttrib2f GLEW_GET_FUN(__glewVertexAttrib2f) +#define glVertexAttrib2fv GLEW_GET_FUN(__glewVertexAttrib2fv) +#define glVertexAttrib2s GLEW_GET_FUN(__glewVertexAttrib2s) +#define glVertexAttrib2sv GLEW_GET_FUN(__glewVertexAttrib2sv) +#define glVertexAttrib3d GLEW_GET_FUN(__glewVertexAttrib3d) +#define glVertexAttrib3dv GLEW_GET_FUN(__glewVertexAttrib3dv) +#define glVertexAttrib3f GLEW_GET_FUN(__glewVertexAttrib3f) +#define glVertexAttrib3fv GLEW_GET_FUN(__glewVertexAttrib3fv) +#define glVertexAttrib3s GLEW_GET_FUN(__glewVertexAttrib3s) +#define glVertexAttrib3sv GLEW_GET_FUN(__glewVertexAttrib3sv) +#define glVertexAttrib4Nbv GLEW_GET_FUN(__glewVertexAttrib4Nbv) +#define glVertexAttrib4Niv GLEW_GET_FUN(__glewVertexAttrib4Niv) +#define glVertexAttrib4Nsv GLEW_GET_FUN(__glewVertexAttrib4Nsv) +#define glVertexAttrib4Nub GLEW_GET_FUN(__glewVertexAttrib4Nub) +#define glVertexAttrib4Nubv GLEW_GET_FUN(__glewVertexAttrib4Nubv) +#define glVertexAttrib4Nuiv GLEW_GET_FUN(__glewVertexAttrib4Nuiv) +#define glVertexAttrib4Nusv GLEW_GET_FUN(__glewVertexAttrib4Nusv) +#define glVertexAttrib4bv GLEW_GET_FUN(__glewVertexAttrib4bv) +#define glVertexAttrib4d GLEW_GET_FUN(__glewVertexAttrib4d) +#define glVertexAttrib4dv GLEW_GET_FUN(__glewVertexAttrib4dv) +#define glVertexAttrib4f GLEW_GET_FUN(__glewVertexAttrib4f) +#define glVertexAttrib4fv GLEW_GET_FUN(__glewVertexAttrib4fv) +#define glVertexAttrib4iv GLEW_GET_FUN(__glewVertexAttrib4iv) +#define glVertexAttrib4s GLEW_GET_FUN(__glewVertexAttrib4s) +#define glVertexAttrib4sv GLEW_GET_FUN(__glewVertexAttrib4sv) +#define glVertexAttrib4ubv GLEW_GET_FUN(__glewVertexAttrib4ubv) +#define glVertexAttrib4uiv GLEW_GET_FUN(__glewVertexAttrib4uiv) +#define glVertexAttrib4usv GLEW_GET_FUN(__glewVertexAttrib4usv) +#define glVertexAttribPointer GLEW_GET_FUN(__glewVertexAttribPointer) + +#define GLEW_VERSION_2_0 GLEW_GET_VAR(__GLEW_VERSION_2_0) + +#endif /* GL_VERSION_2_0 */ + +/* ----------------------------- GL_VERSION_2_1 ---------------------------- */ + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 + +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B + +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + +#define glUniformMatrix2x3fv GLEW_GET_FUN(__glewUniformMatrix2x3fv) +#define glUniformMatrix2x4fv GLEW_GET_FUN(__glewUniformMatrix2x4fv) +#define glUniformMatrix3x2fv GLEW_GET_FUN(__glewUniformMatrix3x2fv) +#define glUniformMatrix3x4fv GLEW_GET_FUN(__glewUniformMatrix3x4fv) +#define glUniformMatrix4x2fv GLEW_GET_FUN(__glewUniformMatrix4x2fv) +#define glUniformMatrix4x3fv GLEW_GET_FUN(__glewUniformMatrix4x3fv) + +#define GLEW_VERSION_2_1 GLEW_GET_VAR(__GLEW_VERSION_2_1) + +#endif /* GL_VERSION_2_1 */ + +/* ----------------------------- GL_VERSION_3_0 ---------------------------- */ + +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 + +#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES +#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 +#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 +#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 +#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB +#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 +#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 +#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 +#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_DEPTH_BUFFER 0x8223 +#define GL_STENCIL_BUFFER 0x8224 +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_ALPHA_INTEGER 0x8D97 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 + +typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERPROC) (GLuint, GLenum); +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum); +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint, GLuint, const GLchar*); +typedef void (GLAPIENTRY * PFNGLCLAMPCOLORPROC) (GLenum, GLenum); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum, GLint, GLfloat, GLint); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum, GLint, const GLfloat*); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum, GLint, const GLint*); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum, GLint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLCOLORMASKIPROC) (GLuint, GLboolean, GLboolean, GLboolean, GLboolean); +typedef void (GLAPIENTRY * PFNGLDISABLEIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLENABLEIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERPROC) (void); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETBOOLEANI_VPROC) (GLenum, GLuint, GLboolean*); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint, const GLchar*); +typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVPROC) (GLenum, GLenum, GLint*); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVPROC) (GLenum, GLenum, GLuint*); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint, GLuint, GLint*); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint, GLint, GLuint*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVPROC) (GLuint, GLenum, GLint*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint, GLenum, GLuint*); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVPROC) (GLenum, GLenum, const GLint*); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVPROC) (GLenum, GLenum, const GLuint*); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint, GLsizei, const GLchar **, GLenum); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIPROC) (GLint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIPROC) (GLint, GLuint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVPROC) (GLint, GLsizei, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IPROC) (GLuint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIPROC) (GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IPROC) (GLuint, GLint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIPROC) (GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IPROC) (GLuint, GLint, GLint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIPROC) (GLuint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVPROC) (GLuint, const GLbyte*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IPROC) (GLuint, GLint, GLint, GLint, GLint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVPROC) (GLuint, const GLint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVPROC) (GLuint, const GLshort*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVPROC) (GLuint, const GLubyte*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIPROC) (GLuint, GLuint, GLuint, GLuint, GLuint); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVPROC) (GLuint, const GLuint*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVPROC) (GLuint, const GLushort*); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint, GLint, GLenum, GLsizei, const GLvoid*); + +#define glBeginConditionalRender GLEW_GET_FUN(__glewBeginConditionalRender) +#define glBeginTransformFeedback GLEW_GET_FUN(__glewBeginTransformFeedback) +#define glBindFragDataLocation GLEW_GET_FUN(__glewBindFragDataLocation) +#define glClampColor GLEW_GET_FUN(__glewClampColor) +#define glClearBufferfi GLEW_GET_FUN(__glewClearBufferfi) +#define glClearBufferfv GLEW_GET_FUN(__glewClearBufferfv) +#define glClearBufferiv GLEW_GET_FUN(__glewClearBufferiv) +#define glClearBufferuiv GLEW_GET_FUN(__glewClearBufferuiv) +#define glColorMaski GLEW_GET_FUN(__glewColorMaski) +#define glDisablei GLEW_GET_FUN(__glewDisablei) +#define glEnablei GLEW_GET_FUN(__glewEnablei) +#define glEndConditionalRender GLEW_GET_FUN(__glewEndConditionalRender) +#define glEndTransformFeedback GLEW_GET_FUN(__glewEndTransformFeedback) +#define glGetBooleani_v GLEW_GET_FUN(__glewGetBooleani_v) +#define glGetFragDataLocation GLEW_GET_FUN(__glewGetFragDataLocation) +#define glGetStringi GLEW_GET_FUN(__glewGetStringi) +#define glGetTexParameterIiv GLEW_GET_FUN(__glewGetTexParameterIiv) +#define glGetTexParameterIuiv GLEW_GET_FUN(__glewGetTexParameterIuiv) +#define glGetTransformFeedbackVarying GLEW_GET_FUN(__glewGetTransformFeedbackVarying) +#define glGetUniformuiv GLEW_GET_FUN(__glewGetUniformuiv) +#define glGetVertexAttribIiv GLEW_GET_FUN(__glewGetVertexAttribIiv) +#define glGetVertexAttribIuiv GLEW_GET_FUN(__glewGetVertexAttribIuiv) +#define glIsEnabledi GLEW_GET_FUN(__glewIsEnabledi) +#define glTexParameterIiv GLEW_GET_FUN(__glewTexParameterIiv) +#define glTexParameterIuiv GLEW_GET_FUN(__glewTexParameterIuiv) +#define glTransformFeedbackVaryings GLEW_GET_FUN(__glewTransformFeedbackVaryings) +#define glUniform1ui GLEW_GET_FUN(__glewUniform1ui) +#define glUniform1uiv GLEW_GET_FUN(__glewUniform1uiv) +#define glUniform2ui GLEW_GET_FUN(__glewUniform2ui) +#define glUniform2uiv GLEW_GET_FUN(__glewUniform2uiv) +#define glUniform3ui GLEW_GET_FUN(__glewUniform3ui) +#define glUniform3uiv GLEW_GET_FUN(__glewUniform3uiv) +#define glUniform4ui GLEW_GET_FUN(__glewUniform4ui) +#define glUniform4uiv GLEW_GET_FUN(__glewUniform4uiv) +#define glVertexAttribI1i GLEW_GET_FUN(__glewVertexAttribI1i) +#define glVertexAttribI1iv GLEW_GET_FUN(__glewVertexAttribI1iv) +#define glVertexAttribI1ui GLEW_GET_FUN(__glewVertexAttribI1ui) +#define glVertexAttribI1uiv GLEW_GET_FUN(__glewVertexAttribI1uiv) +#define glVertexAttribI2i GLEW_GET_FUN(__glewVertexAttribI2i) +#define glVertexAttribI2iv GLEW_GET_FUN(__glewVertexAttribI2iv) +#define glVertexAttribI2ui GLEW_GET_FUN(__glewVertexAttribI2ui) +#define glVertexAttribI2uiv GLEW_GET_FUN(__glewVertexAttribI2uiv) +#define glVertexAttribI3i GLEW_GET_FUN(__glewVertexAttribI3i) +#define glVertexAttribI3iv GLEW_GET_FUN(__glewVertexAttribI3iv) +#define glVertexAttribI3ui GLEW_GET_FUN(__glewVertexAttribI3ui) +#define glVertexAttribI3uiv GLEW_GET_FUN(__glewVertexAttribI3uiv) +#define glVertexAttribI4bv GLEW_GET_FUN(__glewVertexAttribI4bv) +#define glVertexAttribI4i GLEW_GET_FUN(__glewVertexAttribI4i) +#define glVertexAttribI4iv GLEW_GET_FUN(__glewVertexAttribI4iv) +#define glVertexAttribI4sv GLEW_GET_FUN(__glewVertexAttribI4sv) +#define glVertexAttribI4ubv GLEW_GET_FUN(__glewVertexAttribI4ubv) +#define glVertexAttribI4ui GLEW_GET_FUN(__glewVertexAttribI4ui) +#define glVertexAttribI4uiv GLEW_GET_FUN(__glewVertexAttribI4uiv) +#define glVertexAttribI4usv GLEW_GET_FUN(__glewVertexAttribI4usv) +#define glVertexAttribIPointer GLEW_GET_FUN(__glewVertexAttribIPointer) + +#define GLEW_VERSION_3_0 GLEW_GET_VAR(__GLEW_VERSION_3_0) + +#endif /* GL_VERSION_3_0 */ + +/* ----------------------------- GL_VERSION_3_1 ---------------------------- */ + +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 1 + +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum, GLint, GLsizei, GLsizei); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum, GLsizei, GLenum, const GLvoid*, GLsizei); +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint); +typedef void (GLAPIENTRY * PFNGLTEXBUFFERPROC) (GLenum, GLenum, GLuint); + +#define glDrawArraysInstanced GLEW_GET_FUN(__glewDrawArraysInstanced) +#define glDrawElementsInstanced GLEW_GET_FUN(__glewDrawElementsInstanced) +#define glPrimitiveRestartIndex GLEW_GET_FUN(__glewPrimitiveRestartIndex) +#define glTexBuffer GLEW_GET_FUN(__glewTexBuffer) + +#define GLEW_VERSION_3_1 GLEW_GET_VAR(__GLEW_VERSION_3_1) + +#endif /* GL_VERSION_3_1 */ + +/* ----------------------------- GL_VERSION_3_2 ---------------------------- */ + +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 1 + +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_CONTEXT_PROFILE_MASK 0x9126 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum, GLenum, GLuint, GLint); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum, GLenum, GLint64 *); +typedef void (GLAPIENTRY * PFNGLGETINTEGER64I_VPROC) (GLenum, GLuint, GLint64 *); + +#define glFramebufferTexture GLEW_GET_FUN(__glewFramebufferTexture) +#define glGetBufferParameteri64v GLEW_GET_FUN(__glewGetBufferParameteri64v) +#define glGetInteger64i_v GLEW_GET_FUN(__glewGetInteger64i_v) + +#define GLEW_VERSION_3_2 GLEW_GET_VAR(__GLEW_VERSION_3_2) + +#endif /* GL_VERSION_3_2 */ + +/* ----------------------------- GL_VERSION_3_3 ---------------------------- */ + +#ifndef GL_VERSION_3_3 +#define GL_VERSION_3_3 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#define GL_RGB10_A2UI 0x906F + +#define GLEW_VERSION_3_3 GLEW_GET_VAR(__GLEW_VERSION_3_3) + +#endif /* GL_VERSION_3_3 */ + +/* ----------------------------- GL_VERSION_4_0 ---------------------------- */ + +#ifndef GL_VERSION_4_0 +#define GL_VERSION_4_0 1 + +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGPROC) (GLclampf value); + +#define glBlendEquationSeparatei GLEW_GET_FUN(__glewBlendEquationSeparatei) +#define glBlendEquationi GLEW_GET_FUN(__glewBlendEquationi) +#define glBlendFuncSeparatei GLEW_GET_FUN(__glewBlendFuncSeparatei) +#define glBlendFunci GLEW_GET_FUN(__glewBlendFunci) +#define glMinSampleShading GLEW_GET_FUN(__glewMinSampleShading) + +#define GLEW_VERSION_4_0 GLEW_GET_VAR(__GLEW_VERSION_4_0) + +#endif /* GL_VERSION_4_0 */ + +/* -------------------------- GL_3DFX_multisample -------------------------- */ + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 + +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 + +#define GLEW_3DFX_multisample GLEW_GET_VAR(__GLEW_3DFX_multisample) + +#endif /* GL_3DFX_multisample */ + +/* ---------------------------- GL_3DFX_tbuffer ---------------------------- */ + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 + +typedef void (GLAPIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); + +#define glTbufferMask3DFX GLEW_GET_FUN(__glewTbufferMask3DFX) + +#define GLEW_3DFX_tbuffer GLEW_GET_VAR(__GLEW_3DFX_tbuffer) + +#endif /* GL_3DFX_tbuffer */ + +/* -------------------- GL_3DFX_texture_compression_FXT1 ------------------- */ + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 + +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 + +#define GLEW_3DFX_texture_compression_FXT1 GLEW_GET_VAR(__GLEW_3DFX_texture_compression_FXT1) + +#endif /* GL_3DFX_texture_compression_FXT1 */ + +/* ----------------------- GL_AMD_draw_buffers_blend ----------------------- */ + +#ifndef GL_AMD_draw_buffers_blend +#define GL_AMD_draw_buffers_blend 1 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + +#define glBlendEquationIndexedAMD GLEW_GET_FUN(__glewBlendEquationIndexedAMD) +#define glBlendEquationSeparateIndexedAMD GLEW_GET_FUN(__glewBlendEquationSeparateIndexedAMD) +#define glBlendFuncIndexedAMD GLEW_GET_FUN(__glewBlendFuncIndexedAMD) +#define glBlendFuncSeparateIndexedAMD GLEW_GET_FUN(__glewBlendFuncSeparateIndexedAMD) + +#define GLEW_AMD_draw_buffers_blend GLEW_GET_VAR(__GLEW_AMD_draw_buffers_blend) + +#endif /* GL_AMD_draw_buffers_blend */ + +/* ----------------------- GL_AMD_performance_monitor ---------------------- */ + +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor 1 + +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 + +typedef void (GLAPIENTRY * PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GLAPIENTRY * PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); +typedef void (GLAPIENTRY * PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GLAPIENTRY * PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint *bytesWritten); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void* data); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, char *counterString); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint* numCounters, GLint *maxActiveCounters, GLsizei countersSize, GLuint *counters); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei* length, char *groupString); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint* numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (GLAPIENTRY * PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* counterList); + +#define glBeginPerfMonitorAMD GLEW_GET_FUN(__glewBeginPerfMonitorAMD) +#define glDeletePerfMonitorsAMD GLEW_GET_FUN(__glewDeletePerfMonitorsAMD) +#define glEndPerfMonitorAMD GLEW_GET_FUN(__glewEndPerfMonitorAMD) +#define glGenPerfMonitorsAMD GLEW_GET_FUN(__glewGenPerfMonitorsAMD) +#define glGetPerfMonitorCounterDataAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterDataAMD) +#define glGetPerfMonitorCounterInfoAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterInfoAMD) +#define glGetPerfMonitorCounterStringAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterStringAMD) +#define glGetPerfMonitorCountersAMD GLEW_GET_FUN(__glewGetPerfMonitorCountersAMD) +#define glGetPerfMonitorGroupStringAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupStringAMD) +#define glGetPerfMonitorGroupsAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupsAMD) +#define glSelectPerfMonitorCountersAMD GLEW_GET_FUN(__glewSelectPerfMonitorCountersAMD) + +#define GLEW_AMD_performance_monitor GLEW_GET_VAR(__GLEW_AMD_performance_monitor) + +#endif /* GL_AMD_performance_monitor */ + +/* ------------------ GL_AMD_seamless_cubemap_per_texture ------------------ */ + +#ifndef GL_AMD_seamless_cubemap_per_texture +#define GL_AMD_seamless_cubemap_per_texture 1 + +#define GL_TEXTURE_CUBE_MAP_SEAMLESS_ARB 0x884F + +#define GLEW_AMD_seamless_cubemap_per_texture GLEW_GET_VAR(__GLEW_AMD_seamless_cubemap_per_texture) + +#endif /* GL_AMD_seamless_cubemap_per_texture */ + +/* ---------------------- GL_AMD_shader_stencil_export --------------------- */ + +#ifndef GL_AMD_shader_stencil_export +#define GL_AMD_shader_stencil_export 1 + +#define GLEW_AMD_shader_stencil_export GLEW_GET_VAR(__GLEW_AMD_shader_stencil_export) + +#endif /* GL_AMD_shader_stencil_export */ + +/* ------------------------ GL_AMD_texture_texture4 ------------------------ */ + +#ifndef GL_AMD_texture_texture4 +#define GL_AMD_texture_texture4 1 + +#define GLEW_AMD_texture_texture4 GLEW_GET_VAR(__GLEW_AMD_texture_texture4) + +#endif /* GL_AMD_texture_texture4 */ + +/* -------------------- GL_AMD_vertex_shader_tessellator ------------------- */ + +#ifndef GL_AMD_vertex_shader_tessellator +#define GL_AMD_vertex_shader_tessellator 1 + +#define GL_SAMPLER_BUFFER_AMD 0x9001 +#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 +#define GL_TESSELLATION_MODE_AMD 0x9004 +#define GL_TESSELLATION_FACTOR_AMD 0x9005 +#define GL_DISCRETE_AMD 0x9006 +#define GL_CONTINUOUS_AMD 0x9007 + +typedef void (GLAPIENTRY * PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor); +typedef void (GLAPIENTRY * PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); + +#define glTessellationFactorAMD GLEW_GET_FUN(__glewTessellationFactorAMD) +#define glTessellationModeAMD GLEW_GET_FUN(__glewTessellationModeAMD) + +#define GLEW_AMD_vertex_shader_tessellator GLEW_GET_VAR(__GLEW_AMD_vertex_shader_tessellator) + +#endif /* GL_AMD_vertex_shader_tessellator */ + +/* ----------------------- GL_APPLE_aux_depth_stencil ---------------------- */ + +#ifndef GL_APPLE_aux_depth_stencil +#define GL_APPLE_aux_depth_stencil 1 + +#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 + +#define GLEW_APPLE_aux_depth_stencil GLEW_GET_VAR(__GLEW_APPLE_aux_depth_stencil) + +#endif /* GL_APPLE_aux_depth_stencil */ + +/* ------------------------ GL_APPLE_client_storage ------------------------ */ + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 + +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 + +#define GLEW_APPLE_client_storage GLEW_GET_VAR(__GLEW_APPLE_client_storage) + +#endif /* GL_APPLE_client_storage */ + +/* ------------------------- GL_APPLE_element_array ------------------------ */ + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 + +#define GL_ELEMENT_ARRAY_APPLE 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void* pointer); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint* first, const GLsizei *count, GLsizei primcount); + +#define glDrawElementArrayAPPLE GLEW_GET_FUN(__glewDrawElementArrayAPPLE) +#define glDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewDrawRangeElementArrayAPPLE) +#define glElementPointerAPPLE GLEW_GET_FUN(__glewElementPointerAPPLE) +#define glMultiDrawElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawElementArrayAPPLE) +#define glMultiDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawRangeElementArrayAPPLE) + +#define GLEW_APPLE_element_array GLEW_GET_VAR(__GLEW_APPLE_element_array) + +#endif /* GL_APPLE_element_array */ + +/* ----------------------------- GL_APPLE_fence ---------------------------- */ + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 + +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B + +typedef void (GLAPIENTRY * PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint* fences); +typedef void (GLAPIENTRY * PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +typedef void (GLAPIENTRY * PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint* fences); +typedef GLboolean (GLAPIENTRY * PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRY * PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); + +#define glDeleteFencesAPPLE GLEW_GET_FUN(__glewDeleteFencesAPPLE) +#define glFinishFenceAPPLE GLEW_GET_FUN(__glewFinishFenceAPPLE) +#define glFinishObjectAPPLE GLEW_GET_FUN(__glewFinishObjectAPPLE) +#define glGenFencesAPPLE GLEW_GET_FUN(__glewGenFencesAPPLE) +#define glIsFenceAPPLE GLEW_GET_FUN(__glewIsFenceAPPLE) +#define glSetFenceAPPLE GLEW_GET_FUN(__glewSetFenceAPPLE) +#define glTestFenceAPPLE GLEW_GET_FUN(__glewTestFenceAPPLE) +#define glTestObjectAPPLE GLEW_GET_FUN(__glewTestObjectAPPLE) + +#define GLEW_APPLE_fence GLEW_GET_VAR(__GLEW_APPLE_fence) + +#endif /* GL_APPLE_fence */ + +/* ------------------------- GL_APPLE_float_pixels ------------------------- */ + +#ifndef GL_APPLE_float_pixels +#define GL_APPLE_float_pixels 1 + +#define GL_HALF_APPLE 0x140B +#define GL_RGBA_FLOAT32_APPLE 0x8814 +#define GL_RGB_FLOAT32_APPLE 0x8815 +#define GL_ALPHA_FLOAT32_APPLE 0x8816 +#define GL_INTENSITY_FLOAT32_APPLE 0x8817 +#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 +#define GL_RGBA_FLOAT16_APPLE 0x881A +#define GL_RGB_FLOAT16_APPLE 0x881B +#define GL_ALPHA_FLOAT16_APPLE 0x881C +#define GL_INTENSITY_FLOAT16_APPLE 0x881D +#define GL_LUMINANCE_FLOAT16_APPLE 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F +#define GL_COLOR_FLOAT_APPLE 0x8A0F + +#define GLEW_APPLE_float_pixels GLEW_GET_VAR(__GLEW_APPLE_float_pixels) + +#endif /* GL_APPLE_float_pixels */ + +/* ---------------------- GL_APPLE_flush_buffer_range ---------------------- */ + +#ifndef GL_APPLE_flush_buffer_range +#define GL_APPLE_flush_buffer_range 1 + +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 + +typedef void (GLAPIENTRY * PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); + +#define glBufferParameteriAPPLE GLEW_GET_FUN(__glewBufferParameteriAPPLE) +#define glFlushMappedBufferRangeAPPLE GLEW_GET_FUN(__glewFlushMappedBufferRangeAPPLE) + +#define GLEW_APPLE_flush_buffer_range GLEW_GET_VAR(__GLEW_APPLE_flush_buffer_range) + +#endif /* GL_APPLE_flush_buffer_range */ + +/* ----------------------- GL_APPLE_object_purgeable ----------------------- */ + +#ifndef GL_APPLE_object_purgeable +#define GL_APPLE_object_purgeable 1 + +#define GL_BUFFER_OBJECT_APPLE 0x85B3 +#define GL_RELEASED_APPLE 0x8A19 +#define GL_VOLATILE_APPLE 0x8A1A +#define GL_RETAINED_APPLE 0x8A1B +#define GL_UNDEFINED_APPLE 0x8A1C +#define GL_PURGEABLE_APPLE 0x8A1D + +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint* params); +typedef GLenum (GLAPIENTRY * PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); +typedef GLenum (GLAPIENTRY * PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); + +#define glGetObjectParameterivAPPLE GLEW_GET_FUN(__glewGetObjectParameterivAPPLE) +#define glObjectPurgeableAPPLE GLEW_GET_FUN(__glewObjectPurgeableAPPLE) +#define glObjectUnpurgeableAPPLE GLEW_GET_FUN(__glewObjectUnpurgeableAPPLE) + +#define GLEW_APPLE_object_purgeable GLEW_GET_VAR(__GLEW_APPLE_object_purgeable) + +#endif /* GL_APPLE_object_purgeable */ + +/* ------------------------- GL_APPLE_pixel_buffer ------------------------- */ + +#ifndef GL_APPLE_pixel_buffer +#define GL_APPLE_pixel_buffer 1 + +#define GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE 0x8A10 + +#define GLEW_APPLE_pixel_buffer GLEW_GET_VAR(__GLEW_APPLE_pixel_buffer) + +#endif /* GL_APPLE_pixel_buffer */ + +/* ---------------------------- GL_APPLE_rgb_422 --------------------------- */ + +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 + +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#define GL_RGB_422_APPLE 0x8A1F + +#define GLEW_APPLE_rgb_422 GLEW_GET_VAR(__GLEW_APPLE_rgb_422) + +#endif /* GL_APPLE_rgb_422 */ + +/* --------------------------- GL_APPLE_row_bytes -------------------------- */ + +#ifndef GL_APPLE_row_bytes +#define GL_APPLE_row_bytes 1 + +#define GL_PACK_ROW_BYTES_APPLE 0x8A15 +#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 + +#define GLEW_APPLE_row_bytes GLEW_GET_VAR(__GLEW_APPLE_row_bytes) + +#endif /* GL_APPLE_row_bytes */ + +/* ------------------------ GL_APPLE_specular_vector ----------------------- */ + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 + +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 + +#define GLEW_APPLE_specular_vector GLEW_GET_VAR(__GLEW_APPLE_specular_vector) + +#endif /* GL_APPLE_specular_vector */ + +/* ------------------------- GL_APPLE_texture_range ------------------------ */ + +#ifndef GL_APPLE_texture_range +#define GL_APPLE_texture_range 1 + +#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 +#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_STORAGE_PRIVATE_APPLE 0x85BD +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF + +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid **params); +typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, GLvoid *pointer); + +#define glGetTexParameterPointervAPPLE GLEW_GET_FUN(__glewGetTexParameterPointervAPPLE) +#define glTextureRangeAPPLE GLEW_GET_FUN(__glewTextureRangeAPPLE) + +#define GLEW_APPLE_texture_range GLEW_GET_VAR(__GLEW_APPLE_texture_range) + +#endif /* GL_APPLE_texture_range */ + +/* ------------------------ GL_APPLE_transform_hint ------------------------ */ + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 + +#define GL_TRANSFORM_HINT_APPLE 0x85B1 + +#define GLEW_APPLE_transform_hint GLEW_GET_VAR(__GLEW_APPLE_transform_hint) + +#endif /* GL_APPLE_transform_hint */ + +/* ---------------------- GL_APPLE_vertex_array_object --------------------- */ + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 + +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 + +typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); +typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); + +#define glBindVertexArrayAPPLE GLEW_GET_FUN(__glewBindVertexArrayAPPLE) +#define glDeleteVertexArraysAPPLE GLEW_GET_FUN(__glewDeleteVertexArraysAPPLE) +#define glGenVertexArraysAPPLE GLEW_GET_FUN(__glewGenVertexArraysAPPLE) +#define glIsVertexArrayAPPLE GLEW_GET_FUN(__glewIsVertexArrayAPPLE) + +#define GLEW_APPLE_vertex_array_object GLEW_GET_VAR(__GLEW_APPLE_vertex_array_object) + +#endif /* GL_APPLE_vertex_array_object */ + +/* ---------------------- GL_APPLE_vertex_array_range ---------------------- */ + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 + +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF + +typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void* pointer); + +#define glFlushVertexArrayRangeAPPLE GLEW_GET_FUN(__glewFlushVertexArrayRangeAPPLE) +#define glVertexArrayParameteriAPPLE GLEW_GET_FUN(__glewVertexArrayParameteriAPPLE) +#define glVertexArrayRangeAPPLE GLEW_GET_FUN(__glewVertexArrayRangeAPPLE) + +#define GLEW_APPLE_vertex_array_range GLEW_GET_VAR(__GLEW_APPLE_vertex_array_range) + +#endif /* GL_APPLE_vertex_array_range */ + +/* ------------------- GL_APPLE_vertex_program_evaluators ------------------ */ + +#ifndef GL_APPLE_vertex_program_evaluators +#define GL_APPLE_vertex_program_evaluators 1 + +#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 +#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 +#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 +#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 +#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 +#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 +#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 +#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 +#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 +#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 + +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble* points); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat* points); + +#define glDisableVertexAttribAPPLE GLEW_GET_FUN(__glewDisableVertexAttribAPPLE) +#define glEnableVertexAttribAPPLE GLEW_GET_FUN(__glewEnableVertexAttribAPPLE) +#define glIsVertexAttribEnabledAPPLE GLEW_GET_FUN(__glewIsVertexAttribEnabledAPPLE) +#define glMapVertexAttrib1dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1dAPPLE) +#define glMapVertexAttrib1fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1fAPPLE) +#define glMapVertexAttrib2dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2dAPPLE) +#define glMapVertexAttrib2fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2fAPPLE) + +#define GLEW_APPLE_vertex_program_evaluators GLEW_GET_VAR(__GLEW_APPLE_vertex_program_evaluators) + +#endif /* GL_APPLE_vertex_program_evaluators */ + +/* --------------------------- GL_APPLE_ycbcr_422 -------------------------- */ + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 + +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB + +#define GLEW_APPLE_ycbcr_422 GLEW_GET_VAR(__GLEW_APPLE_ycbcr_422) + +#endif /* GL_APPLE_ycbcr_422 */ + +/* ----------------------- GL_ARB_blend_func_extended ---------------------- */ + +#ifndef GL_ARB_blend_func_extended +#define GL_ARB_blend_func_extended 1 + +#define GL_SRC1_COLOR 0x88F9 +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC + +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const char * name); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const char * name); + +#define glBindFragDataLocationIndexed GLEW_GET_FUN(__glewBindFragDataLocationIndexed) +#define glGetFragDataIndex GLEW_GET_FUN(__glewGetFragDataIndex) + +#define GLEW_ARB_blend_func_extended GLEW_GET_VAR(__GLEW_ARB_blend_func_extended) + +#endif /* GL_ARB_blend_func_extended */ + +/* ----------------------- GL_ARB_color_buffer_float ----------------------- */ + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float 1 + +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D + +typedef void (GLAPIENTRY * PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); + +#define glClampColorARB GLEW_GET_FUN(__glewClampColorARB) + +#define GLEW_ARB_color_buffer_float GLEW_GET_VAR(__GLEW_ARB_color_buffer_float) + +#endif /* GL_ARB_color_buffer_float */ + +/* -------------------------- GL_ARB_compatibility ------------------------- */ + +#ifndef GL_ARB_compatibility +#define GL_ARB_compatibility 1 + +#define GLEW_ARB_compatibility GLEW_GET_VAR(__GLEW_ARB_compatibility) + +#endif /* GL_ARB_compatibility */ + +/* --------------------------- GL_ARB_copy_buffer -------------------------- */ + +#ifndef GL_ARB_copy_buffer +#define GL_ARB_copy_buffer 1 + +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 + +typedef void (GLAPIENTRY * PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size); + +#define glCopyBufferSubData GLEW_GET_FUN(__glewCopyBufferSubData) + +#define GLEW_ARB_copy_buffer GLEW_GET_VAR(__GLEW_ARB_copy_buffer) + +#endif /* GL_ARB_copy_buffer */ + +/* ----------------------- GL_ARB_depth_buffer_float ----------------------- */ + +#ifndef GL_ARB_depth_buffer_float +#define GL_ARB_depth_buffer_float 1 + +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD + +#define GLEW_ARB_depth_buffer_float GLEW_GET_VAR(__GLEW_ARB_depth_buffer_float) + +#endif /* GL_ARB_depth_buffer_float */ + +/* --------------------------- GL_ARB_depth_clamp -------------------------- */ + +#ifndef GL_ARB_depth_clamp +#define GL_ARB_depth_clamp 1 + +#define GL_DEPTH_CLAMP 0x864F + +#define GLEW_ARB_depth_clamp GLEW_GET_VAR(__GLEW_ARB_depth_clamp) + +#endif /* GL_ARB_depth_clamp */ + +/* -------------------------- GL_ARB_depth_texture ------------------------- */ + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 + +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B + +#define GLEW_ARB_depth_texture GLEW_GET_VAR(__GLEW_ARB_depth_texture) + +#endif /* GL_ARB_depth_texture */ + +/* -------------------------- GL_ARB_draw_buffers -------------------------- */ + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers 1 + +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 + +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersARB GLEW_GET_FUN(__glewDrawBuffersARB) + +#define GLEW_ARB_draw_buffers GLEW_GET_VAR(__GLEW_ARB_draw_buffers) + +#endif /* GL_ARB_draw_buffers */ + +/* ----------------------- GL_ARB_draw_buffers_blend ----------------------- */ + +#ifndef GL_ARB_draw_buffers_blend +#define GL_ARB_draw_buffers_blend 1 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); + +#define glBlendEquationSeparateiARB GLEW_GET_FUN(__glewBlendEquationSeparateiARB) +#define glBlendEquationiARB GLEW_GET_FUN(__glewBlendEquationiARB) +#define glBlendFuncSeparateiARB GLEW_GET_FUN(__glewBlendFuncSeparateiARB) +#define glBlendFunciARB GLEW_GET_FUN(__glewBlendFunciARB) + +#define GLEW_ARB_draw_buffers_blend GLEW_GET_VAR(__GLEW_ARB_draw_buffers_blend) + +#endif /* GL_ARB_draw_buffers_blend */ + +/* -------------------- GL_ARB_draw_elements_base_vertex ------------------- */ + +#ifndef GL_ARB_draw_elements_base_vertex +#define GL_ARB_draw_elements_base_vertex 1 + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, void* indices, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, void* indices, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei* count, GLenum type, GLvoid**indices, GLsizei primcount, GLint *basevertex); + +#define glDrawElementsBaseVertex GLEW_GET_FUN(__glewDrawElementsBaseVertex) +#define glDrawElementsInstancedBaseVertex GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertex) +#define glDrawRangeElementsBaseVertex GLEW_GET_FUN(__glewDrawRangeElementsBaseVertex) +#define glMultiDrawElementsBaseVertex GLEW_GET_FUN(__glewMultiDrawElementsBaseVertex) + +#define GLEW_ARB_draw_elements_base_vertex GLEW_GET_VAR(__GLEW_ARB_draw_elements_base_vertex) + +#endif /* GL_ARB_draw_elements_base_vertex */ + +/* -------------------------- GL_ARB_draw_indirect ------------------------- */ + +#ifndef GL_ARB_draw_indirect +#define GL_ARB_draw_indirect 1 + +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void* indirect); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void* indirect); + +#define glDrawArraysIndirect GLEW_GET_FUN(__glewDrawArraysIndirect) +#define glDrawElementsIndirect GLEW_GET_FUN(__glewDrawElementsIndirect) + +#define GLEW_ARB_draw_indirect GLEW_GET_VAR(__GLEW_ARB_draw_indirect) + +#endif /* GL_ARB_draw_indirect */ + +/* ------------------------- GL_ARB_draw_instanced ------------------------- */ + +#ifndef GL_ARB_draw_instanced +#define GL_ARB_draw_instanced 1 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount); + +#define glDrawArraysInstancedARB GLEW_GET_FUN(__glewDrawArraysInstancedARB) +#define glDrawElementsInstancedARB GLEW_GET_FUN(__glewDrawElementsInstancedARB) + +#define GLEW_ARB_draw_instanced GLEW_GET_VAR(__GLEW_ARB_draw_instanced) + +#endif /* GL_ARB_draw_instanced */ + +/* -------------------- GL_ARB_explicit_attrib_location -------------------- */ + +#ifndef GL_ARB_explicit_attrib_location +#define GL_ARB_explicit_attrib_location 1 + +#define GLEW_ARB_explicit_attrib_location GLEW_GET_VAR(__GLEW_ARB_explicit_attrib_location) + +#endif /* GL_ARB_explicit_attrib_location */ + +/* ------------------- GL_ARB_fragment_coord_conventions ------------------- */ + +#ifndef GL_ARB_fragment_coord_conventions +#define GL_ARB_fragment_coord_conventions 1 + +#define GLEW_ARB_fragment_coord_conventions GLEW_GET_VAR(__GLEW_ARB_fragment_coord_conventions) + +#endif /* GL_ARB_fragment_coord_conventions */ + +/* ------------------------ GL_ARB_fragment_program ------------------------ */ + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 + +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 + +#define GLEW_ARB_fragment_program GLEW_GET_VAR(__GLEW_ARB_fragment_program) + +#endif /* GL_ARB_fragment_program */ + +/* --------------------- GL_ARB_fragment_program_shadow -------------------- */ + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 + +#define GLEW_ARB_fragment_program_shadow GLEW_GET_VAR(__GLEW_ARB_fragment_program_shadow) + +#endif /* GL_ARB_fragment_program_shadow */ + +/* ------------------------- GL_ARB_fragment_shader ------------------------ */ + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader 1 + +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B + +#define GLEW_ARB_fragment_shader GLEW_GET_VAR(__GLEW_ARB_fragment_shader) + +#endif /* GL_ARB_fragment_shader */ + +/* ----------------------- GL_ARB_framebuffer_object ----------------------- */ + +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object 1 + +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_INDEX 0x8222 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_SRGB 0x8C40 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 + +typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer); +typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glBindFramebuffer GLEW_GET_FUN(__glewBindFramebuffer) +#define glBindRenderbuffer GLEW_GET_FUN(__glewBindRenderbuffer) +#define glBlitFramebuffer GLEW_GET_FUN(__glewBlitFramebuffer) +#define glCheckFramebufferStatus GLEW_GET_FUN(__glewCheckFramebufferStatus) +#define glDeleteFramebuffers GLEW_GET_FUN(__glewDeleteFramebuffers) +#define glDeleteRenderbuffers GLEW_GET_FUN(__glewDeleteRenderbuffers) +#define glFramebufferRenderbuffer GLEW_GET_FUN(__glewFramebufferRenderbuffer) +#define glFramebufferTexture1D GLEW_GET_FUN(__glewFramebufferTexture1D) +#define glFramebufferTexture2D GLEW_GET_FUN(__glewFramebufferTexture2D) +#define glFramebufferTexture3D GLEW_GET_FUN(__glewFramebufferTexture3D) +#define glFramebufferTextureLayer GLEW_GET_FUN(__glewFramebufferTextureLayer) +#define glGenFramebuffers GLEW_GET_FUN(__glewGenFramebuffers) +#define glGenRenderbuffers GLEW_GET_FUN(__glewGenRenderbuffers) +#define glGenerateMipmap GLEW_GET_FUN(__glewGenerateMipmap) +#define glGetFramebufferAttachmentParameteriv GLEW_GET_FUN(__glewGetFramebufferAttachmentParameteriv) +#define glGetRenderbufferParameteriv GLEW_GET_FUN(__glewGetRenderbufferParameteriv) +#define glIsFramebuffer GLEW_GET_FUN(__glewIsFramebuffer) +#define glIsRenderbuffer GLEW_GET_FUN(__glewIsRenderbuffer) +#define glRenderbufferStorage GLEW_GET_FUN(__glewRenderbufferStorage) +#define glRenderbufferStorageMultisample GLEW_GET_FUN(__glewRenderbufferStorageMultisample) + +#define GLEW_ARB_framebuffer_object GLEW_GET_VAR(__GLEW_ARB_framebuffer_object) + +#endif /* GL_ARB_framebuffer_object */ + +/* ------------------------ GL_ARB_framebuffer_sRGB ------------------------ */ + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_ARB_framebuffer_sRGB 1 + +#define GL_FRAMEBUFFER_SRGB 0x8DB9 + +#define GLEW_ARB_framebuffer_sRGB GLEW_GET_VAR(__GLEW_ARB_framebuffer_sRGB) + +#endif /* GL_ARB_framebuffer_sRGB */ + +/* ------------------------ GL_ARB_geometry_shader4 ------------------------ */ + +#ifndef GL_ARB_geometry_shader4 +#define GL_ARB_geometry_shader4 1 + +#define GL_LINES_ADJACENCY_ARB 0xA +#define GL_LINE_STRIP_ADJACENCY_ARB 0xB +#define GL_TRIANGLES_ADJACENCY_ARB 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0xD +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 +#define GL_GEOMETRY_SHADER_ARB 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); + +#define glFramebufferTextureARB GLEW_GET_FUN(__glewFramebufferTextureARB) +#define glFramebufferTextureFaceARB GLEW_GET_FUN(__glewFramebufferTextureFaceARB) +#define glFramebufferTextureLayerARB GLEW_GET_FUN(__glewFramebufferTextureLayerARB) +#define glProgramParameteriARB GLEW_GET_FUN(__glewProgramParameteriARB) + +#define GLEW_ARB_geometry_shader4 GLEW_GET_VAR(__GLEW_ARB_geometry_shader4) + +#endif /* GL_ARB_geometry_shader4 */ + +/* --------------------------- GL_ARB_gpu_shader5 -------------------------- */ + +#ifndef GL_ARB_gpu_shader5 +#define GL_ARB_gpu_shader5 1 + +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_MAX_VERTEX_STREAMS 0x8E71 + +#define GLEW_ARB_gpu_shader5 GLEW_GET_VAR(__GLEW_ARB_gpu_shader5) + +#endif /* GL_ARB_gpu_shader5 */ + +/* ------------------------- GL_ARB_gpu_shader_fp64 ------------------------ */ + +#ifndef GL_ARB_gpu_shader_fp64 +#define GL_ARB_gpu_shader_fp64 1 + +#define GLEW_ARB_gpu_shader_fp64 GLEW_GET_VAR(__GLEW_ARB_gpu_shader_fp64) + +#endif /* GL_ARB_gpu_shader_fp64 */ + +/* ------------------------ GL_ARB_half_float_pixel ------------------------ */ + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 + +#define GL_HALF_FLOAT_ARB 0x140B + +#define GLEW_ARB_half_float_pixel GLEW_GET_VAR(__GLEW_ARB_half_float_pixel) + +#endif /* GL_ARB_half_float_pixel */ + +/* ------------------------ GL_ARB_half_float_vertex ----------------------- */ + +#ifndef GL_ARB_half_float_vertex +#define GL_ARB_half_float_vertex 1 + +#define GL_HALF_FLOAT 0x140B + +#define GLEW_ARB_half_float_vertex GLEW_GET_VAR(__GLEW_ARB_half_float_vertex) + +#endif /* GL_ARB_half_float_vertex */ + +/* ----------------------------- GL_ARB_imaging ---------------------------- */ + +#ifndef GL_ARB_imaging +#define GL_ARB_imaging 1 + +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_IGNORE_BORDER 0x8150 +#define GL_CONSTANT_BORDER 0x8151 +#define GL_WRAP_BORDER 0x8152 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 + +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum types, GLvoid *values); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (GLAPIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); + +#define glColorSubTable GLEW_GET_FUN(__glewColorSubTable) +#define glColorTable GLEW_GET_FUN(__glewColorTable) +#define glColorTableParameterfv GLEW_GET_FUN(__glewColorTableParameterfv) +#define glColorTableParameteriv GLEW_GET_FUN(__glewColorTableParameteriv) +#define glConvolutionFilter1D GLEW_GET_FUN(__glewConvolutionFilter1D) +#define glConvolutionFilter2D GLEW_GET_FUN(__glewConvolutionFilter2D) +#define glConvolutionParameterf GLEW_GET_FUN(__glewConvolutionParameterf) +#define glConvolutionParameterfv GLEW_GET_FUN(__glewConvolutionParameterfv) +#define glConvolutionParameteri GLEW_GET_FUN(__glewConvolutionParameteri) +#define glConvolutionParameteriv GLEW_GET_FUN(__glewConvolutionParameteriv) +#define glCopyColorSubTable GLEW_GET_FUN(__glewCopyColorSubTable) +#define glCopyColorTable GLEW_GET_FUN(__glewCopyColorTable) +#define glCopyConvolutionFilter1D GLEW_GET_FUN(__glewCopyConvolutionFilter1D) +#define glCopyConvolutionFilter2D GLEW_GET_FUN(__glewCopyConvolutionFilter2D) +#define glGetColorTable GLEW_GET_FUN(__glewGetColorTable) +#define glGetColorTableParameterfv GLEW_GET_FUN(__glewGetColorTableParameterfv) +#define glGetColorTableParameteriv GLEW_GET_FUN(__glewGetColorTableParameteriv) +#define glGetConvolutionFilter GLEW_GET_FUN(__glewGetConvolutionFilter) +#define glGetConvolutionParameterfv GLEW_GET_FUN(__glewGetConvolutionParameterfv) +#define glGetConvolutionParameteriv GLEW_GET_FUN(__glewGetConvolutionParameteriv) +#define glGetHistogram GLEW_GET_FUN(__glewGetHistogram) +#define glGetHistogramParameterfv GLEW_GET_FUN(__glewGetHistogramParameterfv) +#define glGetHistogramParameteriv GLEW_GET_FUN(__glewGetHistogramParameteriv) +#define glGetMinmax GLEW_GET_FUN(__glewGetMinmax) +#define glGetMinmaxParameterfv GLEW_GET_FUN(__glewGetMinmaxParameterfv) +#define glGetMinmaxParameteriv GLEW_GET_FUN(__glewGetMinmaxParameteriv) +#define glGetSeparableFilter GLEW_GET_FUN(__glewGetSeparableFilter) +#define glHistogram GLEW_GET_FUN(__glewHistogram) +#define glMinmax GLEW_GET_FUN(__glewMinmax) +#define glResetHistogram GLEW_GET_FUN(__glewResetHistogram) +#define glResetMinmax GLEW_GET_FUN(__glewResetMinmax) +#define glSeparableFilter2D GLEW_GET_FUN(__glewSeparableFilter2D) + +#define GLEW_ARB_imaging GLEW_GET_VAR(__GLEW_ARB_imaging) + +#endif /* GL_ARB_imaging */ + +/* ------------------------ GL_ARB_instanced_arrays ------------------------ */ + +#ifndef GL_ARB_instanced_arrays +#define GL_ARB_instanced_arrays 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE + +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); + +#define glVertexAttribDivisorARB GLEW_GET_FUN(__glewVertexAttribDivisorARB) + +#define GLEW_ARB_instanced_arrays GLEW_GET_VAR(__GLEW_ARB_instanced_arrays) + +#endif /* GL_ARB_instanced_arrays */ + +/* ------------------------ GL_ARB_map_buffer_range ------------------------ */ + +#ifndef GL_ARB_map_buffer_range +#define GL_ARB_map_buffer_range 1 + +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 + +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + +#define glFlushMappedBufferRange GLEW_GET_FUN(__glewFlushMappedBufferRange) +#define glMapBufferRange GLEW_GET_FUN(__glewMapBufferRange) + +#define GLEW_ARB_map_buffer_range GLEW_GET_VAR(__GLEW_ARB_map_buffer_range) + +#endif /* GL_ARB_map_buffer_range */ + +/* ------------------------- GL_ARB_matrix_palette ------------------------- */ + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 + +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 + +typedef void (GLAPIENTRY * PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUBVARBPROC) (GLint size, GLubyte *indices); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUIVARBPROC) (GLint size, GLuint *indices); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUSVARBPROC) (GLint size, GLushort *indices); + +#define glCurrentPaletteMatrixARB GLEW_GET_FUN(__glewCurrentPaletteMatrixARB) +#define glMatrixIndexPointerARB GLEW_GET_FUN(__glewMatrixIndexPointerARB) +#define glMatrixIndexubvARB GLEW_GET_FUN(__glewMatrixIndexubvARB) +#define glMatrixIndexuivARB GLEW_GET_FUN(__glewMatrixIndexuivARB) +#define glMatrixIndexusvARB GLEW_GET_FUN(__glewMatrixIndexusvARB) + +#define GLEW_ARB_matrix_palette GLEW_GET_VAR(__GLEW_ARB_matrix_palette) + +#endif /* GL_ARB_matrix_palette */ + +/* --------------------------- GL_ARB_multisample -------------------------- */ + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 + +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); + +#define glSampleCoverageARB GLEW_GET_FUN(__glewSampleCoverageARB) + +#define GLEW_ARB_multisample GLEW_GET_VAR(__GLEW_ARB_multisample) + +#endif /* GL_ARB_multisample */ + +/* -------------------------- GL_ARB_multitexture -------------------------- */ + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 + +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 + +typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); + +#define glActiveTextureARB GLEW_GET_FUN(__glewActiveTextureARB) +#define glClientActiveTextureARB GLEW_GET_FUN(__glewClientActiveTextureARB) +#define glMultiTexCoord1dARB GLEW_GET_FUN(__glewMultiTexCoord1dARB) +#define glMultiTexCoord1dvARB GLEW_GET_FUN(__glewMultiTexCoord1dvARB) +#define glMultiTexCoord1fARB GLEW_GET_FUN(__glewMultiTexCoord1fARB) +#define glMultiTexCoord1fvARB GLEW_GET_FUN(__glewMultiTexCoord1fvARB) +#define glMultiTexCoord1iARB GLEW_GET_FUN(__glewMultiTexCoord1iARB) +#define glMultiTexCoord1ivARB GLEW_GET_FUN(__glewMultiTexCoord1ivARB) +#define glMultiTexCoord1sARB GLEW_GET_FUN(__glewMultiTexCoord1sARB) +#define glMultiTexCoord1svARB GLEW_GET_FUN(__glewMultiTexCoord1svARB) +#define glMultiTexCoord2dARB GLEW_GET_FUN(__glewMultiTexCoord2dARB) +#define glMultiTexCoord2dvARB GLEW_GET_FUN(__glewMultiTexCoord2dvARB) +#define glMultiTexCoord2fARB GLEW_GET_FUN(__glewMultiTexCoord2fARB) +#define glMultiTexCoord2fvARB GLEW_GET_FUN(__glewMultiTexCoord2fvARB) +#define glMultiTexCoord2iARB GLEW_GET_FUN(__glewMultiTexCoord2iARB) +#define glMultiTexCoord2ivARB GLEW_GET_FUN(__glewMultiTexCoord2ivARB) +#define glMultiTexCoord2sARB GLEW_GET_FUN(__glewMultiTexCoord2sARB) +#define glMultiTexCoord2svARB GLEW_GET_FUN(__glewMultiTexCoord2svARB) +#define glMultiTexCoord3dARB GLEW_GET_FUN(__glewMultiTexCoord3dARB) +#define glMultiTexCoord3dvARB GLEW_GET_FUN(__glewMultiTexCoord3dvARB) +#define glMultiTexCoord3fARB GLEW_GET_FUN(__glewMultiTexCoord3fARB) +#define glMultiTexCoord3fvARB GLEW_GET_FUN(__glewMultiTexCoord3fvARB) +#define glMultiTexCoord3iARB GLEW_GET_FUN(__glewMultiTexCoord3iARB) +#define glMultiTexCoord3ivARB GLEW_GET_FUN(__glewMultiTexCoord3ivARB) +#define glMultiTexCoord3sARB GLEW_GET_FUN(__glewMultiTexCoord3sARB) +#define glMultiTexCoord3svARB GLEW_GET_FUN(__glewMultiTexCoord3svARB) +#define glMultiTexCoord4dARB GLEW_GET_FUN(__glewMultiTexCoord4dARB) +#define glMultiTexCoord4dvARB GLEW_GET_FUN(__glewMultiTexCoord4dvARB) +#define glMultiTexCoord4fARB GLEW_GET_FUN(__glewMultiTexCoord4fARB) +#define glMultiTexCoord4fvARB GLEW_GET_FUN(__glewMultiTexCoord4fvARB) +#define glMultiTexCoord4iARB GLEW_GET_FUN(__glewMultiTexCoord4iARB) +#define glMultiTexCoord4ivARB GLEW_GET_FUN(__glewMultiTexCoord4ivARB) +#define glMultiTexCoord4sARB GLEW_GET_FUN(__glewMultiTexCoord4sARB) +#define glMultiTexCoord4svARB GLEW_GET_FUN(__glewMultiTexCoord4svARB) + +#define GLEW_ARB_multitexture GLEW_GET_VAR(__GLEW_ARB_multitexture) + +#endif /* GL_ARB_multitexture */ + +/* ------------------------- GL_ARB_occlusion_query ------------------------ */ + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query 1 + +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_SAMPLES_PASSED_ARB 0x8914 + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYARBPROC) (GLuint id); + +#define glBeginQueryARB GLEW_GET_FUN(__glewBeginQueryARB) +#define glDeleteQueriesARB GLEW_GET_FUN(__glewDeleteQueriesARB) +#define glEndQueryARB GLEW_GET_FUN(__glewEndQueryARB) +#define glGenQueriesARB GLEW_GET_FUN(__glewGenQueriesARB) +#define glGetQueryObjectivARB GLEW_GET_FUN(__glewGetQueryObjectivARB) +#define glGetQueryObjectuivARB GLEW_GET_FUN(__glewGetQueryObjectuivARB) +#define glGetQueryivARB GLEW_GET_FUN(__glewGetQueryivARB) +#define glIsQueryARB GLEW_GET_FUN(__glewIsQueryARB) + +#define GLEW_ARB_occlusion_query GLEW_GET_VAR(__GLEW_ARB_occlusion_query) + +#endif /* GL_ARB_occlusion_query */ + +/* ------------------------ GL_ARB_occlusion_query2 ------------------------ */ + +#ifndef GL_ARB_occlusion_query2 +#define GL_ARB_occlusion_query2 1 + +#define GL_ANY_SAMPLES_PASSED 0x8C2F + +#define GLEW_ARB_occlusion_query2 GLEW_GET_VAR(__GLEW_ARB_occlusion_query2) + +#endif /* GL_ARB_occlusion_query2 */ + +/* ----------------------- GL_ARB_pixel_buffer_object ---------------------- */ + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 + +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF + +#define GLEW_ARB_pixel_buffer_object GLEW_GET_VAR(__GLEW_ARB_pixel_buffer_object) + +#endif /* GL_ARB_pixel_buffer_object */ + +/* ------------------------ GL_ARB_point_parameters ------------------------ */ + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 + +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, GLfloat* params); + +#define glPointParameterfARB GLEW_GET_FUN(__glewPointParameterfARB) +#define glPointParameterfvARB GLEW_GET_FUN(__glewPointParameterfvARB) + +#define GLEW_ARB_point_parameters GLEW_GET_VAR(__GLEW_ARB_point_parameters) + +#endif /* GL_ARB_point_parameters */ + +/* -------------------------- GL_ARB_point_sprite -------------------------- */ + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 + +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 + +#define GLEW_ARB_point_sprite GLEW_GET_VAR(__GLEW_ARB_point_sprite) + +#endif /* GL_ARB_point_sprite */ + +/* ------------------------ GL_ARB_provoking_vertex ------------------------ */ + +#ifndef GL_ARB_provoking_vertex +#define GL_ARB_provoking_vertex 1 + +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F + +typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXPROC) (GLenum mode); + +#define glProvokingVertex GLEW_GET_FUN(__glewProvokingVertex) + +#define GLEW_ARB_provoking_vertex GLEW_GET_VAR(__GLEW_ARB_provoking_vertex) + +#endif /* GL_ARB_provoking_vertex */ + +/* ------------------------- GL_ARB_sample_shading ------------------------- */ + +#ifndef GL_ARB_sample_shading +#define GL_ARB_sample_shading 1 + +#define GL_SAMPLE_SHADING_ARB 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 + +typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value); + +#define glMinSampleShadingARB GLEW_GET_FUN(__glewMinSampleShadingARB) + +#define GLEW_ARB_sample_shading GLEW_GET_VAR(__GLEW_ARB_sample_shading) + +#endif /* GL_ARB_sample_shading */ + +/* ------------------------- GL_ARB_sampler_objects ------------------------ */ + +#ifndef GL_ARB_sampler_objects +#define GL_ARB_sampler_objects 1 + +#define GL_SAMPLER_BINDING 0x8919 + +typedef void (GLAPIENTRY * PFNGLBINDSAMPLERPROC) (GLenum unit, GLuint sampler); +typedef void (GLAPIENTRY * PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint * samplers); +typedef void (GLAPIENTRY * PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint* samplers); +typedef GLboolean (GLAPIENTRY * PFNGLISSAMPLERPROC) (GLuint sampler); + +#define glBindSampler GLEW_GET_FUN(__glewBindSampler) +#define glDeleteSamplers GLEW_GET_FUN(__glewDeleteSamplers) +#define glGenSamplers GLEW_GET_FUN(__glewGenSamplers) +#define glIsSampler GLEW_GET_FUN(__glewIsSampler) + +#define GLEW_ARB_sampler_objects GLEW_GET_VAR(__GLEW_ARB_sampler_objects) + +#endif /* GL_ARB_sampler_objects */ + +/* ------------------------ GL_ARB_seamless_cube_map ----------------------- */ + +#ifndef GL_ARB_seamless_cube_map +#define GL_ARB_seamless_cube_map 1 + +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F + +#define GLEW_ARB_seamless_cube_map GLEW_GET_VAR(__GLEW_ARB_seamless_cube_map) + +#endif /* GL_ARB_seamless_cube_map */ + +/* ----------------------- GL_ARB_shader_bit_encoding ---------------------- */ + +#ifndef GL_ARB_shader_bit_encoding +#define GL_ARB_shader_bit_encoding 1 + +#define GLEW_ARB_shader_bit_encoding GLEW_GET_VAR(__GLEW_ARB_shader_bit_encoding) + +#endif /* GL_ARB_shader_bit_encoding */ + +/* ------------------------- GL_ARB_shader_objects ------------------------- */ + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 + +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 + +typedef char GLcharARB; +typedef unsigned int GLhandleARB; + +typedef void (GLAPIENTRY * PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATEPROGRAMOBJECTARBPROC) (void); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (GLAPIENTRY * PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei* count, GLhandleARB *obj); +typedef GLhandleARB (GLAPIENTRY * PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (GLAPIENTRY * PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *infoLog); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *source); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint* params); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB ** string, const GLint *length); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); + +#define glAttachObjectARB GLEW_GET_FUN(__glewAttachObjectARB) +#define glCompileShaderARB GLEW_GET_FUN(__glewCompileShaderARB) +#define glCreateProgramObjectARB GLEW_GET_FUN(__glewCreateProgramObjectARB) +#define glCreateShaderObjectARB GLEW_GET_FUN(__glewCreateShaderObjectARB) +#define glDeleteObjectARB GLEW_GET_FUN(__glewDeleteObjectARB) +#define glDetachObjectARB GLEW_GET_FUN(__glewDetachObjectARB) +#define glGetActiveUniformARB GLEW_GET_FUN(__glewGetActiveUniformARB) +#define glGetAttachedObjectsARB GLEW_GET_FUN(__glewGetAttachedObjectsARB) +#define glGetHandleARB GLEW_GET_FUN(__glewGetHandleARB) +#define glGetInfoLogARB GLEW_GET_FUN(__glewGetInfoLogARB) +#define glGetObjectParameterfvARB GLEW_GET_FUN(__glewGetObjectParameterfvARB) +#define glGetObjectParameterivARB GLEW_GET_FUN(__glewGetObjectParameterivARB) +#define glGetShaderSourceARB GLEW_GET_FUN(__glewGetShaderSourceARB) +#define glGetUniformLocationARB GLEW_GET_FUN(__glewGetUniformLocationARB) +#define glGetUniformfvARB GLEW_GET_FUN(__glewGetUniformfvARB) +#define glGetUniformivARB GLEW_GET_FUN(__glewGetUniformivARB) +#define glLinkProgramARB GLEW_GET_FUN(__glewLinkProgramARB) +#define glShaderSourceARB GLEW_GET_FUN(__glewShaderSourceARB) +#define glUniform1fARB GLEW_GET_FUN(__glewUniform1fARB) +#define glUniform1fvARB GLEW_GET_FUN(__glewUniform1fvARB) +#define glUniform1iARB GLEW_GET_FUN(__glewUniform1iARB) +#define glUniform1ivARB GLEW_GET_FUN(__glewUniform1ivARB) +#define glUniform2fARB GLEW_GET_FUN(__glewUniform2fARB) +#define glUniform2fvARB GLEW_GET_FUN(__glewUniform2fvARB) +#define glUniform2iARB GLEW_GET_FUN(__glewUniform2iARB) +#define glUniform2ivARB GLEW_GET_FUN(__glewUniform2ivARB) +#define glUniform3fARB GLEW_GET_FUN(__glewUniform3fARB) +#define glUniform3fvARB GLEW_GET_FUN(__glewUniform3fvARB) +#define glUniform3iARB GLEW_GET_FUN(__glewUniform3iARB) +#define glUniform3ivARB GLEW_GET_FUN(__glewUniform3ivARB) +#define glUniform4fARB GLEW_GET_FUN(__glewUniform4fARB) +#define glUniform4fvARB GLEW_GET_FUN(__glewUniform4fvARB) +#define glUniform4iARB GLEW_GET_FUN(__glewUniform4iARB) +#define glUniform4ivARB GLEW_GET_FUN(__glewUniform4ivARB) +#define glUniformMatrix2fvARB GLEW_GET_FUN(__glewUniformMatrix2fvARB) +#define glUniformMatrix3fvARB GLEW_GET_FUN(__glewUniformMatrix3fvARB) +#define glUniformMatrix4fvARB GLEW_GET_FUN(__glewUniformMatrix4fvARB) +#define glUseProgramObjectARB GLEW_GET_FUN(__glewUseProgramObjectARB) +#define glValidateProgramARB GLEW_GET_FUN(__glewValidateProgramARB) + +#define GLEW_ARB_shader_objects GLEW_GET_VAR(__GLEW_ARB_shader_objects) + +#endif /* GL_ARB_shader_objects */ + +/* ------------------------ GL_ARB_shader_subroutine ----------------------- */ + +#ifndef GL_ARB_shader_subroutine +#define GL_ARB_shader_subroutine 1 + +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B + +typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, char *name); +typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, char *name); +typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint* values); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint* values); +typedef GLuint (GLAPIENTRY * PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const char* name); +typedef GLint (GLAPIENTRY * PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const char* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint* params); +typedef void (GLAPIENTRY * PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint* indices); + +#define glGetActiveSubroutineName GLEW_GET_FUN(__glewGetActiveSubroutineName) +#define glGetActiveSubroutineUniformName GLEW_GET_FUN(__glewGetActiveSubroutineUniformName) +#define glGetActiveSubroutineUniformiv GLEW_GET_FUN(__glewGetActiveSubroutineUniformiv) +#define glGetProgramStageiv GLEW_GET_FUN(__glewGetProgramStageiv) +#define glGetSubroutineIndex GLEW_GET_FUN(__glewGetSubroutineIndex) +#define glGetSubroutineUniformLocation GLEW_GET_FUN(__glewGetSubroutineUniformLocation) +#define glGetUniformSubroutineuiv GLEW_GET_FUN(__glewGetUniformSubroutineuiv) +#define glUniformSubroutinesuiv GLEW_GET_FUN(__glewUniformSubroutinesuiv) + +#define GLEW_ARB_shader_subroutine GLEW_GET_VAR(__GLEW_ARB_shader_subroutine) + +#endif /* GL_ARB_shader_subroutine */ + +/* ----------------------- GL_ARB_shader_texture_lod ----------------------- */ + +#ifndef GL_ARB_shader_texture_lod +#define GL_ARB_shader_texture_lod 1 + +#define GLEW_ARB_shader_texture_lod GLEW_GET_VAR(__GLEW_ARB_shader_texture_lod) + +#endif /* GL_ARB_shader_texture_lod */ + +/* ---------------------- GL_ARB_shading_language_100 ---------------------- */ + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 + +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C + +#define GLEW_ARB_shading_language_100 GLEW_GET_VAR(__GLEW_ARB_shading_language_100) + +#endif /* GL_ARB_shading_language_100 */ + +/* -------------------- GL_ARB_shading_language_include -------------------- */ + +#ifndef GL_ARB_shading_language_include +#define GL_ARB_shading_language_include 1 + +#define GL_SHADER_INCLUDE_ARB 0x8DAE +#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 +#define GL_NAMED_STRING_TYPE_ARB 0x8DEA + +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const char ** path, const GLint *length); +typedef void (GLAPIENTRY * PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const char* name); +typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const char* name, GLsizei bufSize, GLint *stringlen, char *string); +typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const char* name, GLenum pname, GLint *params); +typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const char* name); +typedef void (GLAPIENTRY * PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const char* name, GLint stringlen, const char *string); + +#define glCompileShaderIncludeARB GLEW_GET_FUN(__glewCompileShaderIncludeARB) +#define glDeleteNamedStringARB GLEW_GET_FUN(__glewDeleteNamedStringARB) +#define glGetNamedStringARB GLEW_GET_FUN(__glewGetNamedStringARB) +#define glGetNamedStringivARB GLEW_GET_FUN(__glewGetNamedStringivARB) +#define glIsNamedStringARB GLEW_GET_FUN(__glewIsNamedStringARB) +#define glNamedStringARB GLEW_GET_FUN(__glewNamedStringARB) + +#define GLEW_ARB_shading_language_include GLEW_GET_VAR(__GLEW_ARB_shading_language_include) + +#endif /* GL_ARB_shading_language_include */ + +/* ----------------------------- GL_ARB_shadow ----------------------------- */ + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 + +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E + +#define GLEW_ARB_shadow GLEW_GET_VAR(__GLEW_ARB_shadow) + +#endif /* GL_ARB_shadow */ + +/* ------------------------- GL_ARB_shadow_ambient ------------------------- */ + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 + +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF + +#define GLEW_ARB_shadow_ambient GLEW_GET_VAR(__GLEW_ARB_shadow_ambient) + +#endif /* GL_ARB_shadow_ambient */ + +/* ------------------------------ GL_ARB_sync ------------------------------ */ + +#ifndef GL_ARB_sync +#define GL_ARB_sync 1 + +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF + +typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout); +typedef void (GLAPIENTRY * PFNGLDELETESYNCPROC) (GLsync GLsync); +typedef GLsync (GLAPIENTRY * PFNGLFENCESYNCPROC) (GLenum condition,GLbitfield flags); +typedef void (GLAPIENTRY * PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETSYNCIVPROC) (GLsync GLsync,GLenum pname,GLsizei bufSize,GLsizei* length, GLint *values); +typedef GLboolean (GLAPIENTRY * PFNGLISSYNCPROC) (GLsync GLsync); +typedef void (GLAPIENTRY * PFNGLWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout); + +#define glClientWaitSync GLEW_GET_FUN(__glewClientWaitSync) +#define glDeleteSync GLEW_GET_FUN(__glewDeleteSync) +#define glFenceSync GLEW_GET_FUN(__glewFenceSync) +#define glGetInteger64v GLEW_GET_FUN(__glewGetInteger64v) +#define glGetSynciv GLEW_GET_FUN(__glewGetSynciv) +#define glIsSync GLEW_GET_FUN(__glewIsSync) +#define glWaitSync GLEW_GET_FUN(__glewWaitSync) + +#define GLEW_ARB_sync GLEW_GET_VAR(__GLEW_ARB_sync) + +#endif /* GL_ARB_sync */ + +/* ----------------------- GL_ARB_tessellation_shader ---------------------- */ + +#ifndef GL_ARB_tessellation_shader +#define GL_ARB_tessellation_shader 1 + +#define GL_PATCHES 0xE +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_ISOLINES 0x8E7A +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A + +typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat* values); +typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); + +#define glPatchParameterfv GLEW_GET_FUN(__glewPatchParameterfv) +#define glPatchParameteri GLEW_GET_FUN(__glewPatchParameteri) + +#define GLEW_ARB_tessellation_shader GLEW_GET_VAR(__GLEW_ARB_tessellation_shader) + +#endif /* GL_ARB_tessellation_shader */ + +/* ---------------------- GL_ARB_texture_border_clamp ---------------------- */ + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 + +#define GL_CLAMP_TO_BORDER_ARB 0x812D + +#define GLEW_ARB_texture_border_clamp GLEW_GET_VAR(__GLEW_ARB_texture_border_clamp) + +#endif /* GL_ARB_texture_border_clamp */ + +/* ---------------------- GL_ARB_texture_buffer_object --------------------- */ + +#ifndef GL_ARB_texture_buffer_object +#define GL_ARB_texture_buffer_object 1 + +#define GL_TEXTURE_BUFFER_ARB 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E + +typedef void (GLAPIENTRY * PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); + +#define glTexBufferARB GLEW_GET_FUN(__glewTexBufferARB) + +#define GLEW_ARB_texture_buffer_object GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object) + +#endif /* GL_ARB_texture_buffer_object */ + +/* ------------------- GL_ARB_texture_buffer_object_rgb32 ------------------ */ + +#ifndef GL_ARB_texture_buffer_object_rgb32 +#define GL_ARB_texture_buffer_object_rgb32 1 + +#define GLEW_ARB_texture_buffer_object_rgb32 GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object_rgb32) + +#endif /* GL_ARB_texture_buffer_object_rgb32 */ + +/* ----------------------- GL_ARB_texture_compression ---------------------- */ + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 + +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 + +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, void* img); + +#define glCompressedTexImage1DARB GLEW_GET_FUN(__glewCompressedTexImage1DARB) +#define glCompressedTexImage2DARB GLEW_GET_FUN(__glewCompressedTexImage2DARB) +#define glCompressedTexImage3DARB GLEW_GET_FUN(__glewCompressedTexImage3DARB) +#define glCompressedTexSubImage1DARB GLEW_GET_FUN(__glewCompressedTexSubImage1DARB) +#define glCompressedTexSubImage2DARB GLEW_GET_FUN(__glewCompressedTexSubImage2DARB) +#define glCompressedTexSubImage3DARB GLEW_GET_FUN(__glewCompressedTexSubImage3DARB) +#define glGetCompressedTexImageARB GLEW_GET_FUN(__glewGetCompressedTexImageARB) + +#define GLEW_ARB_texture_compression GLEW_GET_VAR(__GLEW_ARB_texture_compression) + +#endif /* GL_ARB_texture_compression */ + +/* -------------------- GL_ARB_texture_compression_bptc -------------------- */ + +#ifndef GL_ARB_texture_compression_bptc +#define GL_ARB_texture_compression_bptc 1 + +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F + +#define GLEW_ARB_texture_compression_bptc GLEW_GET_VAR(__GLEW_ARB_texture_compression_bptc) + +#endif /* GL_ARB_texture_compression_bptc */ + +/* -------------------- GL_ARB_texture_compression_rgtc -------------------- */ + +#ifndef GL_ARB_texture_compression_rgtc +#define GL_ARB_texture_compression_rgtc 1 + +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE + +#define GLEW_ARB_texture_compression_rgtc GLEW_GET_VAR(__GLEW_ARB_texture_compression_rgtc) + +#endif /* GL_ARB_texture_compression_rgtc */ + +/* ------------------------ GL_ARB_texture_cube_map ------------------------ */ + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 + +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C + +#define GLEW_ARB_texture_cube_map GLEW_GET_VAR(__GLEW_ARB_texture_cube_map) + +#endif /* GL_ARB_texture_cube_map */ + +/* --------------------- GL_ARB_texture_cube_map_array --------------------- */ + +#ifndef GL_ARB_texture_cube_map_array +#define GL_ARB_texture_cube_map_array 1 + +#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F + +#define GLEW_ARB_texture_cube_map_array GLEW_GET_VAR(__GLEW_ARB_texture_cube_map_array) + +#endif /* GL_ARB_texture_cube_map_array */ + +/* ------------------------- GL_ARB_texture_env_add ------------------------ */ + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 + +#define GLEW_ARB_texture_env_add GLEW_GET_VAR(__GLEW_ARB_texture_env_add) + +#endif /* GL_ARB_texture_env_add */ + +/* ----------------------- GL_ARB_texture_env_combine ---------------------- */ + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 + +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A + +#define GLEW_ARB_texture_env_combine GLEW_GET_VAR(__GLEW_ARB_texture_env_combine) + +#endif /* GL_ARB_texture_env_combine */ + +/* ---------------------- GL_ARB_texture_env_crossbar ---------------------- */ + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 + +#define GLEW_ARB_texture_env_crossbar GLEW_GET_VAR(__GLEW_ARB_texture_env_crossbar) + +#endif /* GL_ARB_texture_env_crossbar */ + +/* ------------------------ GL_ARB_texture_env_dot3 ------------------------ */ + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 + +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF + +#define GLEW_ARB_texture_env_dot3 GLEW_GET_VAR(__GLEW_ARB_texture_env_dot3) + +#endif /* GL_ARB_texture_env_dot3 */ + +/* -------------------------- GL_ARB_texture_float ------------------------- */ + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 + +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 + +#define GLEW_ARB_texture_float GLEW_GET_VAR(__GLEW_ARB_texture_float) + +#endif /* GL_ARB_texture_float */ + +/* ------------------------- GL_ARB_texture_gather ------------------------- */ + +#ifndef GL_ARB_texture_gather +#define GL_ARB_texture_gather 1 + +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F + +#define GLEW_ARB_texture_gather GLEW_GET_VAR(__GLEW_ARB_texture_gather) + +#endif /* GL_ARB_texture_gather */ + +/* --------------------- GL_ARB_texture_mirrored_repeat -------------------- */ + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 + +#define GL_MIRRORED_REPEAT_ARB 0x8370 + +#define GLEW_ARB_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_ARB_texture_mirrored_repeat) + +#endif /* GL_ARB_texture_mirrored_repeat */ + +/* ----------------------- GL_ARB_texture_multisample ---------------------- */ + +#ifndef GL_ARB_texture_multisample +#define GL_ARB_texture_multisample 1 + +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 + +typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat* val); +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + +#define glGetMultisamplefv GLEW_GET_FUN(__glewGetMultisamplefv) +#define glSampleMaski GLEW_GET_FUN(__glewSampleMaski) +#define glTexImage2DMultisample GLEW_GET_FUN(__glewTexImage2DMultisample) +#define glTexImage3DMultisample GLEW_GET_FUN(__glewTexImage3DMultisample) + +#define GLEW_ARB_texture_multisample GLEW_GET_VAR(__GLEW_ARB_texture_multisample) + +#endif /* GL_ARB_texture_multisample */ + +/* -------------------- GL_ARB_texture_non_power_of_two -------------------- */ + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 + +#define GLEW_ARB_texture_non_power_of_two GLEW_GET_VAR(__GLEW_ARB_texture_non_power_of_two) + +#endif /* GL_ARB_texture_non_power_of_two */ + +/* ------------------------ GL_ARB_texture_query_lod ----------------------- */ + +#ifndef GL_ARB_texture_query_lod +#define GL_ARB_texture_query_lod 1 + +#define GLEW_ARB_texture_query_lod GLEW_GET_VAR(__GLEW_ARB_texture_query_lod) + +#endif /* GL_ARB_texture_query_lod */ + +/* ------------------------ GL_ARB_texture_rectangle ----------------------- */ + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 + +#define GLEW_ARB_texture_rectangle GLEW_GET_VAR(__GLEW_ARB_texture_rectangle) + +#endif /* GL_ARB_texture_rectangle */ + +/* --------------------------- GL_ARB_texture_rg --------------------------- */ + +#ifndef GL_ARB_texture_rg +#define GL_ARB_texture_rg 1 + +#define GL_RED 0x1903 +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C + +#define GLEW_ARB_texture_rg GLEW_GET_VAR(__GLEW_ARB_texture_rg) + +#endif /* GL_ARB_texture_rg */ + +/* ----------------------- GL_ARB_texture_rgb10_a2ui ----------------------- */ + +#ifndef GL_ARB_texture_rgb10_a2ui +#define GL_ARB_texture_rgb10_a2ui 1 + +#define GL_RGB10_A2UI 0x906F + +#define GLEW_ARB_texture_rgb10_a2ui GLEW_GET_VAR(__GLEW_ARB_texture_rgb10_a2ui) + +#endif /* GL_ARB_texture_rgb10_a2ui */ + +/* ------------------------- GL_ARB_texture_swizzle ------------------------ */ + +#ifndef GL_ARB_texture_swizzle +#define GL_ARB_texture_swizzle 1 + +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 + +#define GLEW_ARB_texture_swizzle GLEW_GET_VAR(__GLEW_ARB_texture_swizzle) + +#endif /* GL_ARB_texture_swizzle */ + +/* --------------------------- GL_ARB_timer_query -------------------------- */ + +#ifndef GL_ARB_timer_query +#define GL_ARB_timer_query 1 + +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIMESTAMP 0x8E28 + +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64* params); +typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); + +#define glGetQueryObjecti64v GLEW_GET_FUN(__glewGetQueryObjecti64v) +#define glGetQueryObjectui64v GLEW_GET_FUN(__glewGetQueryObjectui64v) +#define glQueryCounter GLEW_GET_FUN(__glewQueryCounter) + +#define GLEW_ARB_timer_query GLEW_GET_VAR(__GLEW_ARB_timer_query) + +#endif /* GL_ARB_timer_query */ + +/* ----------------------- GL_ARB_transform_feedback2 ---------------------- */ + +#ifndef GL_ARB_transform_feedback2 +#define GL_ARB_transform_feedback2 1 + +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 + +typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); +typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids); +typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); +typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); + +#define glBindTransformFeedback GLEW_GET_FUN(__glewBindTransformFeedback) +#define glDeleteTransformFeedbacks GLEW_GET_FUN(__glewDeleteTransformFeedbacks) +#define glDrawTransformFeedback GLEW_GET_FUN(__glewDrawTransformFeedback) +#define glGenTransformFeedbacks GLEW_GET_FUN(__glewGenTransformFeedbacks) +#define glIsTransformFeedback GLEW_GET_FUN(__glewIsTransformFeedback) +#define glPauseTransformFeedback GLEW_GET_FUN(__glewPauseTransformFeedback) +#define glResumeTransformFeedback GLEW_GET_FUN(__glewResumeTransformFeedback) + +#define GLEW_ARB_transform_feedback2 GLEW_GET_VAR(__GLEW_ARB_transform_feedback2) + +#endif /* GL_ARB_transform_feedback2 */ + +/* ----------------------- GL_ARB_transform_feedback3 ---------------------- */ + +#ifndef GL_ARB_transform_feedback3 +#define GL_ARB_transform_feedback3 1 + +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +#define GL_MAX_VERTEX_STREAMS 0x8E71 + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); +typedef void (GLAPIENTRY * PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params); + +#define glBeginQueryIndexed GLEW_GET_FUN(__glewBeginQueryIndexed) +#define glDrawTransformFeedbackStream GLEW_GET_FUN(__glewDrawTransformFeedbackStream) +#define glEndQueryIndexed GLEW_GET_FUN(__glewEndQueryIndexed) +#define glGetQueryIndexediv GLEW_GET_FUN(__glewGetQueryIndexediv) + +#define GLEW_ARB_transform_feedback3 GLEW_GET_VAR(__GLEW_ARB_transform_feedback3) + +#endif /* GL_ARB_transform_feedback3 */ + +/* ------------------------ GL_ARB_transpose_matrix ------------------------ */ + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 + +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 + +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); + +#define glLoadTransposeMatrixdARB GLEW_GET_FUN(__glewLoadTransposeMatrixdARB) +#define glLoadTransposeMatrixfARB GLEW_GET_FUN(__glewLoadTransposeMatrixfARB) +#define glMultTransposeMatrixdARB GLEW_GET_FUN(__glewMultTransposeMatrixdARB) +#define glMultTransposeMatrixfARB GLEW_GET_FUN(__glewMultTransposeMatrixfARB) + +#define GLEW_ARB_transpose_matrix GLEW_GET_VAR(__GLEW_ARB_transpose_matrix) + +#endif /* GL_ARB_transpose_matrix */ + +/* ---------------------- GL_ARB_uniform_buffer_object --------------------- */ + +#ifndef GL_ARB_uniform_buffer_object +#define GL_ARB_uniform_buffer_object 1 + +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, char* uniformBlockName); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, char* uniformName); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint* data); +typedef GLuint (GLAPIENTRY * PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const char* uniformBlockName); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const char** uniformNames, GLuint* uniformIndices); +typedef void (GLAPIENTRY * PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + +#define glBindBufferBase GLEW_GET_FUN(__glewBindBufferBase) +#define glBindBufferRange GLEW_GET_FUN(__glewBindBufferRange) +#define glGetActiveUniformBlockName GLEW_GET_FUN(__glewGetActiveUniformBlockName) +#define glGetActiveUniformBlockiv GLEW_GET_FUN(__glewGetActiveUniformBlockiv) +#define glGetActiveUniformName GLEW_GET_FUN(__glewGetActiveUniformName) +#define glGetActiveUniformsiv GLEW_GET_FUN(__glewGetActiveUniformsiv) +#define glGetIntegeri_v GLEW_GET_FUN(__glewGetIntegeri_v) +#define glGetUniformBlockIndex GLEW_GET_FUN(__glewGetUniformBlockIndex) +#define glGetUniformIndices GLEW_GET_FUN(__glewGetUniformIndices) +#define glUniformBlockBinding GLEW_GET_FUN(__glewUniformBlockBinding) + +#define GLEW_ARB_uniform_buffer_object GLEW_GET_VAR(__GLEW_ARB_uniform_buffer_object) + +#endif /* GL_ARB_uniform_buffer_object */ + +/* ------------------------ GL_ARB_vertex_array_bgra ----------------------- */ + +#ifndef GL_ARB_vertex_array_bgra +#define GL_ARB_vertex_array_bgra 1 + +#define GL_BGRA 0x80E1 + +#define GLEW_ARB_vertex_array_bgra GLEW_GET_VAR(__GLEW_ARB_vertex_array_bgra) + +#endif /* GL_ARB_vertex_array_bgra */ + +/* ----------------------- GL_ARB_vertex_array_object ---------------------- */ + +#ifndef GL_ARB_vertex_array_object +#define GL_ARB_vertex_array_object 1 + +#define GL_VERTEX_ARRAY_BINDING 0x85B5 + +typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays); +typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYPROC) (GLuint array); + +#define glBindVertexArray GLEW_GET_FUN(__glewBindVertexArray) +#define glDeleteVertexArrays GLEW_GET_FUN(__glewDeleteVertexArrays) +#define glGenVertexArrays GLEW_GET_FUN(__glewGenVertexArrays) +#define glIsVertexArray GLEW_GET_FUN(__glewIsVertexArray) + +#define GLEW_ARB_vertex_array_object GLEW_GET_VAR(__GLEW_ARB_vertex_array_object) + +#endif /* GL_ARB_vertex_array_object */ + +/* -------------------------- GL_ARB_vertex_blend -------------------------- */ + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 + +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F + +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDARBPROC) (GLint count); +typedef void (GLAPIENTRY * PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLWEIGHTBVARBPROC) (GLint size, GLbyte *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTDVARBPROC) (GLint size, GLdouble *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTFVARBPROC) (GLint size, GLfloat *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTIVARBPROC) (GLint size, GLint *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTSVARBPROC) (GLint size, GLshort *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUBVARBPROC) (GLint size, GLubyte *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUIVARBPROC) (GLint size, GLuint *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUSVARBPROC) (GLint size, GLushort *weights); + +#define glVertexBlendARB GLEW_GET_FUN(__glewVertexBlendARB) +#define glWeightPointerARB GLEW_GET_FUN(__glewWeightPointerARB) +#define glWeightbvARB GLEW_GET_FUN(__glewWeightbvARB) +#define glWeightdvARB GLEW_GET_FUN(__glewWeightdvARB) +#define glWeightfvARB GLEW_GET_FUN(__glewWeightfvARB) +#define glWeightivARB GLEW_GET_FUN(__glewWeightivARB) +#define glWeightsvARB GLEW_GET_FUN(__glewWeightsvARB) +#define glWeightubvARB GLEW_GET_FUN(__glewWeightubvARB) +#define glWeightuivARB GLEW_GET_FUN(__glewWeightuivARB) +#define glWeightusvARB GLEW_GET_FUN(__glewWeightusvARB) + +#define GLEW_ARB_vertex_blend GLEW_GET_VAR(__GLEW_ARB_vertex_blend) + +#endif /* GL_ARB_vertex_blend */ + +/* ---------------------- GL_ARB_vertex_buffer_object ---------------------- */ + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 + +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA + +typedef ptrdiff_t GLsizeiptrARB; +typedef ptrdiff_t GLintptrARB; + +typedef void (GLAPIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid* data); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid* data); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERARBPROC) (GLenum target); + +#define glBindBufferARB GLEW_GET_FUN(__glewBindBufferARB) +#define glBufferDataARB GLEW_GET_FUN(__glewBufferDataARB) +#define glBufferSubDataARB GLEW_GET_FUN(__glewBufferSubDataARB) +#define glDeleteBuffersARB GLEW_GET_FUN(__glewDeleteBuffersARB) +#define glGenBuffersARB GLEW_GET_FUN(__glewGenBuffersARB) +#define glGetBufferParameterivARB GLEW_GET_FUN(__glewGetBufferParameterivARB) +#define glGetBufferPointervARB GLEW_GET_FUN(__glewGetBufferPointervARB) +#define glGetBufferSubDataARB GLEW_GET_FUN(__glewGetBufferSubDataARB) +#define glIsBufferARB GLEW_GET_FUN(__glewIsBufferARB) +#define glMapBufferARB GLEW_GET_FUN(__glewMapBufferARB) +#define glUnmapBufferARB GLEW_GET_FUN(__glewUnmapBufferARB) + +#define GLEW_ARB_vertex_buffer_object GLEW_GET_VAR(__GLEW_ARB_vertex_buffer_object) + +#endif /* GL_ARB_vertex_buffer_object */ + +/* ------------------------- GL_ARB_vertex_program ------------------------- */ + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 + +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF + +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint* programs); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint* programs); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void* string); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMARBPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void* string); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); + +#define glBindProgramARB GLEW_GET_FUN(__glewBindProgramARB) +#define glDeleteProgramsARB GLEW_GET_FUN(__glewDeleteProgramsARB) +#define glDisableVertexAttribArrayARB GLEW_GET_FUN(__glewDisableVertexAttribArrayARB) +#define glEnableVertexAttribArrayARB GLEW_GET_FUN(__glewEnableVertexAttribArrayARB) +#define glGenProgramsARB GLEW_GET_FUN(__glewGenProgramsARB) +#define glGetProgramEnvParameterdvARB GLEW_GET_FUN(__glewGetProgramEnvParameterdvARB) +#define glGetProgramEnvParameterfvARB GLEW_GET_FUN(__glewGetProgramEnvParameterfvARB) +#define glGetProgramLocalParameterdvARB GLEW_GET_FUN(__glewGetProgramLocalParameterdvARB) +#define glGetProgramLocalParameterfvARB GLEW_GET_FUN(__glewGetProgramLocalParameterfvARB) +#define glGetProgramStringARB GLEW_GET_FUN(__glewGetProgramStringARB) +#define glGetProgramivARB GLEW_GET_FUN(__glewGetProgramivARB) +#define glGetVertexAttribPointervARB GLEW_GET_FUN(__glewGetVertexAttribPointervARB) +#define glGetVertexAttribdvARB GLEW_GET_FUN(__glewGetVertexAttribdvARB) +#define glGetVertexAttribfvARB GLEW_GET_FUN(__glewGetVertexAttribfvARB) +#define glGetVertexAttribivARB GLEW_GET_FUN(__glewGetVertexAttribivARB) +#define glIsProgramARB GLEW_GET_FUN(__glewIsProgramARB) +#define glProgramEnvParameter4dARB GLEW_GET_FUN(__glewProgramEnvParameter4dARB) +#define glProgramEnvParameter4dvARB GLEW_GET_FUN(__glewProgramEnvParameter4dvARB) +#define glProgramEnvParameter4fARB GLEW_GET_FUN(__glewProgramEnvParameter4fARB) +#define glProgramEnvParameter4fvARB GLEW_GET_FUN(__glewProgramEnvParameter4fvARB) +#define glProgramLocalParameter4dARB GLEW_GET_FUN(__glewProgramLocalParameter4dARB) +#define glProgramLocalParameter4dvARB GLEW_GET_FUN(__glewProgramLocalParameter4dvARB) +#define glProgramLocalParameter4fARB GLEW_GET_FUN(__glewProgramLocalParameter4fARB) +#define glProgramLocalParameter4fvARB GLEW_GET_FUN(__glewProgramLocalParameter4fvARB) +#define glProgramStringARB GLEW_GET_FUN(__glewProgramStringARB) +#define glVertexAttrib1dARB GLEW_GET_FUN(__glewVertexAttrib1dARB) +#define glVertexAttrib1dvARB GLEW_GET_FUN(__glewVertexAttrib1dvARB) +#define glVertexAttrib1fARB GLEW_GET_FUN(__glewVertexAttrib1fARB) +#define glVertexAttrib1fvARB GLEW_GET_FUN(__glewVertexAttrib1fvARB) +#define glVertexAttrib1sARB GLEW_GET_FUN(__glewVertexAttrib1sARB) +#define glVertexAttrib1svARB GLEW_GET_FUN(__glewVertexAttrib1svARB) +#define glVertexAttrib2dARB GLEW_GET_FUN(__glewVertexAttrib2dARB) +#define glVertexAttrib2dvARB GLEW_GET_FUN(__glewVertexAttrib2dvARB) +#define glVertexAttrib2fARB GLEW_GET_FUN(__glewVertexAttrib2fARB) +#define glVertexAttrib2fvARB GLEW_GET_FUN(__glewVertexAttrib2fvARB) +#define glVertexAttrib2sARB GLEW_GET_FUN(__glewVertexAttrib2sARB) +#define glVertexAttrib2svARB GLEW_GET_FUN(__glewVertexAttrib2svARB) +#define glVertexAttrib3dARB GLEW_GET_FUN(__glewVertexAttrib3dARB) +#define glVertexAttrib3dvARB GLEW_GET_FUN(__glewVertexAttrib3dvARB) +#define glVertexAttrib3fARB GLEW_GET_FUN(__glewVertexAttrib3fARB) +#define glVertexAttrib3fvARB GLEW_GET_FUN(__glewVertexAttrib3fvARB) +#define glVertexAttrib3sARB GLEW_GET_FUN(__glewVertexAttrib3sARB) +#define glVertexAttrib3svARB GLEW_GET_FUN(__glewVertexAttrib3svARB) +#define glVertexAttrib4NbvARB GLEW_GET_FUN(__glewVertexAttrib4NbvARB) +#define glVertexAttrib4NivARB GLEW_GET_FUN(__glewVertexAttrib4NivARB) +#define glVertexAttrib4NsvARB GLEW_GET_FUN(__glewVertexAttrib4NsvARB) +#define glVertexAttrib4NubARB GLEW_GET_FUN(__glewVertexAttrib4NubARB) +#define glVertexAttrib4NubvARB GLEW_GET_FUN(__glewVertexAttrib4NubvARB) +#define glVertexAttrib4NuivARB GLEW_GET_FUN(__glewVertexAttrib4NuivARB) +#define glVertexAttrib4NusvARB GLEW_GET_FUN(__glewVertexAttrib4NusvARB) +#define glVertexAttrib4bvARB GLEW_GET_FUN(__glewVertexAttrib4bvARB) +#define glVertexAttrib4dARB GLEW_GET_FUN(__glewVertexAttrib4dARB) +#define glVertexAttrib4dvARB GLEW_GET_FUN(__glewVertexAttrib4dvARB) +#define glVertexAttrib4fARB GLEW_GET_FUN(__glewVertexAttrib4fARB) +#define glVertexAttrib4fvARB GLEW_GET_FUN(__glewVertexAttrib4fvARB) +#define glVertexAttrib4ivARB GLEW_GET_FUN(__glewVertexAttrib4ivARB) +#define glVertexAttrib4sARB GLEW_GET_FUN(__glewVertexAttrib4sARB) +#define glVertexAttrib4svARB GLEW_GET_FUN(__glewVertexAttrib4svARB) +#define glVertexAttrib4ubvARB GLEW_GET_FUN(__glewVertexAttrib4ubvARB) +#define glVertexAttrib4uivARB GLEW_GET_FUN(__glewVertexAttrib4uivARB) +#define glVertexAttrib4usvARB GLEW_GET_FUN(__glewVertexAttrib4usvARB) +#define glVertexAttribPointerARB GLEW_GET_FUN(__glewVertexAttribPointerARB) + +#define GLEW_ARB_vertex_program GLEW_GET_VAR(__GLEW_ARB_vertex_program) + +#endif /* GL_ARB_vertex_program */ + +/* -------------------------- GL_ARB_vertex_shader ------------------------- */ + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 + +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A + +typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB* name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); + +#define glBindAttribLocationARB GLEW_GET_FUN(__glewBindAttribLocationARB) +#define glGetActiveAttribARB GLEW_GET_FUN(__glewGetActiveAttribARB) +#define glGetAttribLocationARB GLEW_GET_FUN(__glewGetAttribLocationARB) + +#define GLEW_ARB_vertex_shader GLEW_GET_VAR(__GLEW_ARB_vertex_shader) + +#endif /* GL_ARB_vertex_shader */ + +/* ------------------- GL_ARB_vertex_type_2_10_10_10_rev ------------------- */ + +#ifndef GL_ARB_vertex_type_2_10_10_10_rev +#define GL_ARB_vertex_type_2_10_10_10_rev 1 + +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_INT_2_10_10_10_REV 0x8D9F + +typedef void (GLAPIENTRY * PFNGLCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (GLAPIENTRY * PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint* color); +typedef void (GLAPIENTRY * PFNGLCOLORP4UIPROC) (GLenum type, GLuint color); +typedef void (GLAPIENTRY * PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint* color); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint* color); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint* value); + +#define glColorP3ui GLEW_GET_FUN(__glewColorP3ui) +#define glColorP3uiv GLEW_GET_FUN(__glewColorP3uiv) +#define glColorP4ui GLEW_GET_FUN(__glewColorP4ui) +#define glColorP4uiv GLEW_GET_FUN(__glewColorP4uiv) +#define glMultiTexCoordP1ui GLEW_GET_FUN(__glewMultiTexCoordP1ui) +#define glMultiTexCoordP1uiv GLEW_GET_FUN(__glewMultiTexCoordP1uiv) +#define glMultiTexCoordP2ui GLEW_GET_FUN(__glewMultiTexCoordP2ui) +#define glMultiTexCoordP2uiv GLEW_GET_FUN(__glewMultiTexCoordP2uiv) +#define glMultiTexCoordP3ui GLEW_GET_FUN(__glewMultiTexCoordP3ui) +#define glMultiTexCoordP3uiv GLEW_GET_FUN(__glewMultiTexCoordP3uiv) +#define glMultiTexCoordP4ui GLEW_GET_FUN(__glewMultiTexCoordP4ui) +#define glMultiTexCoordP4uiv GLEW_GET_FUN(__glewMultiTexCoordP4uiv) +#define glNormalP3ui GLEW_GET_FUN(__glewNormalP3ui) +#define glNormalP3uiv GLEW_GET_FUN(__glewNormalP3uiv) +#define glSecondaryColorP3ui GLEW_GET_FUN(__glewSecondaryColorP3ui) +#define glSecondaryColorP3uiv GLEW_GET_FUN(__glewSecondaryColorP3uiv) +#define glTexCoordP1ui GLEW_GET_FUN(__glewTexCoordP1ui) +#define glTexCoordP1uiv GLEW_GET_FUN(__glewTexCoordP1uiv) +#define glTexCoordP2ui GLEW_GET_FUN(__glewTexCoordP2ui) +#define glTexCoordP2uiv GLEW_GET_FUN(__glewTexCoordP2uiv) +#define glTexCoordP3ui GLEW_GET_FUN(__glewTexCoordP3ui) +#define glTexCoordP3uiv GLEW_GET_FUN(__glewTexCoordP3uiv) +#define glTexCoordP4ui GLEW_GET_FUN(__glewTexCoordP4ui) +#define glTexCoordP4uiv GLEW_GET_FUN(__glewTexCoordP4uiv) +#define glVertexAttribP1ui GLEW_GET_FUN(__glewVertexAttribP1ui) +#define glVertexAttribP1uiv GLEW_GET_FUN(__glewVertexAttribP1uiv) +#define glVertexAttribP2ui GLEW_GET_FUN(__glewVertexAttribP2ui) +#define glVertexAttribP2uiv GLEW_GET_FUN(__glewVertexAttribP2uiv) +#define glVertexAttribP3ui GLEW_GET_FUN(__glewVertexAttribP3ui) +#define glVertexAttribP3uiv GLEW_GET_FUN(__glewVertexAttribP3uiv) +#define glVertexAttribP4ui GLEW_GET_FUN(__glewVertexAttribP4ui) +#define glVertexAttribP4uiv GLEW_GET_FUN(__glewVertexAttribP4uiv) +#define glVertexP2ui GLEW_GET_FUN(__glewVertexP2ui) +#define glVertexP2uiv GLEW_GET_FUN(__glewVertexP2uiv) +#define glVertexP3ui GLEW_GET_FUN(__glewVertexP3ui) +#define glVertexP3uiv GLEW_GET_FUN(__glewVertexP3uiv) +#define glVertexP4ui GLEW_GET_FUN(__glewVertexP4ui) +#define glVertexP4uiv GLEW_GET_FUN(__glewVertexP4uiv) + +#define GLEW_ARB_vertex_type_2_10_10_10_rev GLEW_GET_VAR(__GLEW_ARB_vertex_type_2_10_10_10_rev) + +#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ + +/* --------------------------- GL_ARB_window_pos --------------------------- */ + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 + +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVARBPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVARBPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVARBPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVARBPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVARBPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVARBPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVARBPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVARBPROC) (const GLshort* p); + +#define glWindowPos2dARB GLEW_GET_FUN(__glewWindowPos2dARB) +#define glWindowPos2dvARB GLEW_GET_FUN(__glewWindowPos2dvARB) +#define glWindowPos2fARB GLEW_GET_FUN(__glewWindowPos2fARB) +#define glWindowPos2fvARB GLEW_GET_FUN(__glewWindowPos2fvARB) +#define glWindowPos2iARB GLEW_GET_FUN(__glewWindowPos2iARB) +#define glWindowPos2ivARB GLEW_GET_FUN(__glewWindowPos2ivARB) +#define glWindowPos2sARB GLEW_GET_FUN(__glewWindowPos2sARB) +#define glWindowPos2svARB GLEW_GET_FUN(__glewWindowPos2svARB) +#define glWindowPos3dARB GLEW_GET_FUN(__glewWindowPos3dARB) +#define glWindowPos3dvARB GLEW_GET_FUN(__glewWindowPos3dvARB) +#define glWindowPos3fARB GLEW_GET_FUN(__glewWindowPos3fARB) +#define glWindowPos3fvARB GLEW_GET_FUN(__glewWindowPos3fvARB) +#define glWindowPos3iARB GLEW_GET_FUN(__glewWindowPos3iARB) +#define glWindowPos3ivARB GLEW_GET_FUN(__glewWindowPos3ivARB) +#define glWindowPos3sARB GLEW_GET_FUN(__glewWindowPos3sARB) +#define glWindowPos3svARB GLEW_GET_FUN(__glewWindowPos3svARB) + +#define GLEW_ARB_window_pos GLEW_GET_VAR(__GLEW_ARB_window_pos) + +#endif /* GL_ARB_window_pos */ + +/* ------------------------- GL_ATIX_point_sprites ------------------------- */ + +#ifndef GL_ATIX_point_sprites +#define GL_ATIX_point_sprites 1 + +#define GL_TEXTURE_POINT_MODE_ATIX 0x60B0 +#define GL_TEXTURE_POINT_ONE_COORD_ATIX 0x60B1 +#define GL_TEXTURE_POINT_SPRITE_ATIX 0x60B2 +#define GL_POINT_SPRITE_CULL_MODE_ATIX 0x60B3 +#define GL_POINT_SPRITE_CULL_CENTER_ATIX 0x60B4 +#define GL_POINT_SPRITE_CULL_CLIP_ATIX 0x60B5 + +#define GLEW_ATIX_point_sprites GLEW_GET_VAR(__GLEW_ATIX_point_sprites) + +#endif /* GL_ATIX_point_sprites */ + +/* ---------------------- GL_ATIX_texture_env_combine3 --------------------- */ + +#ifndef GL_ATIX_texture_env_combine3 +#define GL_ATIX_texture_env_combine3 1 + +#define GL_MODULATE_ADD_ATIX 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATIX 0x8745 +#define GL_MODULATE_SUBTRACT_ATIX 0x8746 + +#define GLEW_ATIX_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATIX_texture_env_combine3) + +#endif /* GL_ATIX_texture_env_combine3 */ + +/* ----------------------- GL_ATIX_texture_env_route ----------------------- */ + +#ifndef GL_ATIX_texture_env_route +#define GL_ATIX_texture_env_route 1 + +#define GL_SECONDARY_COLOR_ATIX 0x8747 +#define GL_TEXTURE_OUTPUT_RGB_ATIX 0x8748 +#define GL_TEXTURE_OUTPUT_ALPHA_ATIX 0x8749 + +#define GLEW_ATIX_texture_env_route GLEW_GET_VAR(__GLEW_ATIX_texture_env_route) + +#endif /* GL_ATIX_texture_env_route */ + +/* ---------------- GL_ATIX_vertex_shader_output_point_size ---------------- */ + +#ifndef GL_ATIX_vertex_shader_output_point_size +#define GL_ATIX_vertex_shader_output_point_size 1 + +#define GL_OUTPUT_POINT_SIZE_ATIX 0x610E + +#define GLEW_ATIX_vertex_shader_output_point_size GLEW_GET_VAR(__GLEW_ATIX_vertex_shader_output_point_size) + +#endif /* GL_ATIX_vertex_shader_output_point_size */ + +/* -------------------------- GL_ATI_draw_buffers -------------------------- */ + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 + +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 + +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersATI GLEW_GET_FUN(__glewDrawBuffersATI) + +#define GLEW_ATI_draw_buffers GLEW_GET_VAR(__GLEW_ATI_draw_buffers) + +#endif /* GL_ATI_draw_buffers */ + +/* -------------------------- GL_ATI_element_array ------------------------- */ + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 + +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void* pointer); + +#define glDrawElementArrayATI GLEW_GET_FUN(__glewDrawElementArrayATI) +#define glDrawRangeElementArrayATI GLEW_GET_FUN(__glewDrawRangeElementArrayATI) +#define glElementPointerATI GLEW_GET_FUN(__glewElementPointerATI) + +#define GLEW_ATI_element_array GLEW_GET_VAR(__GLEW_ATI_element_array) + +#endif /* GL_ATI_element_array */ + +/* ------------------------- GL_ATI_envmap_bumpmap ------------------------- */ + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 + +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C + +typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); + +#define glGetTexBumpParameterfvATI GLEW_GET_FUN(__glewGetTexBumpParameterfvATI) +#define glGetTexBumpParameterivATI GLEW_GET_FUN(__glewGetTexBumpParameterivATI) +#define glTexBumpParameterfvATI GLEW_GET_FUN(__glewTexBumpParameterfvATI) +#define glTexBumpParameterivATI GLEW_GET_FUN(__glewTexBumpParameterivATI) + +#define GLEW_ATI_envmap_bumpmap GLEW_GET_VAR(__GLEW_ATI_envmap_bumpmap) + +#endif /* GL_ATI_envmap_bumpmap */ + +/* ------------------------- GL_ATI_fragment_shader ------------------------ */ + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 + +#define GL_RED_BIT_ATI 0x00000001 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B + +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAPIENTRY * PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (GLAPIENTRY * PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAPIENTRY * PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (GLAPIENTRY * PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (GLAPIENTRY * PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (GLAPIENTRY * PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat* value); + +#define glAlphaFragmentOp1ATI GLEW_GET_FUN(__glewAlphaFragmentOp1ATI) +#define glAlphaFragmentOp2ATI GLEW_GET_FUN(__glewAlphaFragmentOp2ATI) +#define glAlphaFragmentOp3ATI GLEW_GET_FUN(__glewAlphaFragmentOp3ATI) +#define glBeginFragmentShaderATI GLEW_GET_FUN(__glewBeginFragmentShaderATI) +#define glBindFragmentShaderATI GLEW_GET_FUN(__glewBindFragmentShaderATI) +#define glColorFragmentOp1ATI GLEW_GET_FUN(__glewColorFragmentOp1ATI) +#define glColorFragmentOp2ATI GLEW_GET_FUN(__glewColorFragmentOp2ATI) +#define glColorFragmentOp3ATI GLEW_GET_FUN(__glewColorFragmentOp3ATI) +#define glDeleteFragmentShaderATI GLEW_GET_FUN(__glewDeleteFragmentShaderATI) +#define glEndFragmentShaderATI GLEW_GET_FUN(__glewEndFragmentShaderATI) +#define glGenFragmentShadersATI GLEW_GET_FUN(__glewGenFragmentShadersATI) +#define glPassTexCoordATI GLEW_GET_FUN(__glewPassTexCoordATI) +#define glSampleMapATI GLEW_GET_FUN(__glewSampleMapATI) +#define glSetFragmentShaderConstantATI GLEW_GET_FUN(__glewSetFragmentShaderConstantATI) + +#define GLEW_ATI_fragment_shader GLEW_GET_VAR(__GLEW_ATI_fragment_shader) + +#endif /* GL_ATI_fragment_shader */ + +/* ------------------------ GL_ATI_map_object_buffer ----------------------- */ + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 + +typedef void* (GLAPIENTRY * PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); + +#define glMapObjectBufferATI GLEW_GET_FUN(__glewMapObjectBufferATI) +#define glUnmapObjectBufferATI GLEW_GET_FUN(__glewUnmapObjectBufferATI) + +#define GLEW_ATI_map_object_buffer GLEW_GET_VAR(__GLEW_ATI_map_object_buffer) + +#endif /* GL_ATI_map_object_buffer */ + +/* ----------------------------- GL_ATI_meminfo ---------------------------- */ + +#ifndef GL_ATI_meminfo +#define GL_ATI_meminfo 1 + +#define GL_VBO_FREE_MEMORY_ATI 0x87FB +#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC +#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD + +#define GLEW_ATI_meminfo GLEW_GET_VAR(__GLEW_ATI_meminfo) + +#endif /* GL_ATI_meminfo */ + +/* -------------------------- GL_ATI_pn_triangles -------------------------- */ + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 + +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 + +typedef void (GLAPIENTRY * PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); + +#define glPNTrianglesfATI GLEW_GET_FUN(__glPNTrianglewesfATI) +#define glPNTrianglesiATI GLEW_GET_FUN(__glPNTrianglewesiATI) + +#define GLEW_ATI_pn_triangles GLEW_GET_VAR(__GLEW_ATI_pn_triangles) + +#endif /* GL_ATI_pn_triangles */ + +/* ------------------------ GL_ATI_separate_stencil ------------------------ */ + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 + +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 + +typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + +#define glStencilFuncSeparateATI GLEW_GET_FUN(__glewStencilFuncSeparateATI) +#define glStencilOpSeparateATI GLEW_GET_FUN(__glewStencilOpSeparateATI) + +#define GLEW_ATI_separate_stencil GLEW_GET_VAR(__GLEW_ATI_separate_stencil) + +#endif /* GL_ATI_separate_stencil */ + +/* ----------------------- GL_ATI_shader_texture_lod ----------------------- */ + +#ifndef GL_ATI_shader_texture_lod +#define GL_ATI_shader_texture_lod 1 + +#define GLEW_ATI_shader_texture_lod GLEW_GET_VAR(__GLEW_ATI_shader_texture_lod) + +#endif /* GL_ATI_shader_texture_lod */ + +/* ---------------------- GL_ATI_text_fragment_shader ---------------------- */ + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 + +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 + +#define GLEW_ATI_text_fragment_shader GLEW_GET_VAR(__GLEW_ATI_text_fragment_shader) + +#endif /* GL_ATI_text_fragment_shader */ + +/* --------------------- GL_ATI_texture_compression_3dc -------------------- */ + +#ifndef GL_ATI_texture_compression_3dc +#define GL_ATI_texture_compression_3dc 1 + +#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 + +#define GLEW_ATI_texture_compression_3dc GLEW_GET_VAR(__GLEW_ATI_texture_compression_3dc) + +#endif /* GL_ATI_texture_compression_3dc */ + +/* ---------------------- GL_ATI_texture_env_combine3 ---------------------- */ + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 + +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 + +#define GLEW_ATI_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATI_texture_env_combine3) + +#endif /* GL_ATI_texture_env_combine3 */ + +/* -------------------------- GL_ATI_texture_float ------------------------- */ + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 + +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F + +#define GLEW_ATI_texture_float GLEW_GET_VAR(__GLEW_ATI_texture_float) + +#endif /* GL_ATI_texture_float */ + +/* ----------------------- GL_ATI_texture_mirror_once ---------------------- */ + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 + +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 + +#define GLEW_ATI_texture_mirror_once GLEW_GET_VAR(__GLEW_ATI_texture_mirror_once) + +#endif /* GL_ATI_texture_mirror_once */ + +/* ----------------------- GL_ATI_vertex_array_object ---------------------- */ + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 + +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 + +typedef void (GLAPIENTRY * PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (GLAPIENTRY * PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef GLuint (GLAPIENTRY * PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void* pointer, GLenum usage); +typedef void (GLAPIENTRY * PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void* pointer, GLenum preserve); +typedef void (GLAPIENTRY * PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); + +#define glArrayObjectATI GLEW_GET_FUN(__glewArrayObjectATI) +#define glFreeObjectBufferATI GLEW_GET_FUN(__glewFreeObjectBufferATI) +#define glGetArrayObjectfvATI GLEW_GET_FUN(__glewGetArrayObjectfvATI) +#define glGetArrayObjectivATI GLEW_GET_FUN(__glewGetArrayObjectivATI) +#define glGetObjectBufferfvATI GLEW_GET_FUN(__glewGetObjectBufferfvATI) +#define glGetObjectBufferivATI GLEW_GET_FUN(__glewGetObjectBufferivATI) +#define glGetVariantArrayObjectfvATI GLEW_GET_FUN(__glewGetVariantArrayObjectfvATI) +#define glGetVariantArrayObjectivATI GLEW_GET_FUN(__glewGetVariantArrayObjectivATI) +#define glIsObjectBufferATI GLEW_GET_FUN(__glewIsObjectBufferATI) +#define glNewObjectBufferATI GLEW_GET_FUN(__glewNewObjectBufferATI) +#define glUpdateObjectBufferATI GLEW_GET_FUN(__glewUpdateObjectBufferATI) +#define glVariantArrayObjectATI GLEW_GET_FUN(__glewVariantArrayObjectATI) + +#define GLEW_ATI_vertex_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_array_object) + +#endif /* GL_ATI_vertex_array_object */ + +/* ------------------- GL_ATI_vertex_attrib_array_object ------------------- */ + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); + +#define glGetVertexAttribArrayObjectfvATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectfvATI) +#define glGetVertexAttribArrayObjectivATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectivATI) +#define glVertexAttribArrayObjectATI GLEW_GET_FUN(__glewVertexAttribArrayObjectATI) + +#define GLEW_ATI_vertex_attrib_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_attrib_array_object) + +#endif /* GL_ATI_vertex_attrib_array_object */ + +/* ------------------------- GL_ATI_vertex_streams ------------------------- */ + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 + +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_SOURCE_ATI 0x876C +#define GL_VERTEX_STREAM0_ATI 0x876D +#define GL_VERTEX_STREAM1_ATI 0x876E +#define GL_VERTEX_STREAM2_ATI 0x876F +#define GL_VERTEX_STREAM3_ATI 0x8770 +#define GL_VERTEX_STREAM4_ATI 0x8771 +#define GL_VERTEX_STREAM5_ATI 0x8772 +#define GL_VERTEX_STREAM6_ATI 0x8773 +#define GL_VERTEX_STREAM7_ATI 0x8774 + +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte x, GLbyte y, GLbyte z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *v); + +#define glClientActiveVertexStreamATI GLEW_GET_FUN(__glewClientActiveVertexStreamATI) +#define glNormalStream3bATI GLEW_GET_FUN(__glewNormalStream3bATI) +#define glNormalStream3bvATI GLEW_GET_FUN(__glewNormalStream3bvATI) +#define glNormalStream3dATI GLEW_GET_FUN(__glewNormalStream3dATI) +#define glNormalStream3dvATI GLEW_GET_FUN(__glewNormalStream3dvATI) +#define glNormalStream3fATI GLEW_GET_FUN(__glewNormalStream3fATI) +#define glNormalStream3fvATI GLEW_GET_FUN(__glewNormalStream3fvATI) +#define glNormalStream3iATI GLEW_GET_FUN(__glewNormalStream3iATI) +#define glNormalStream3ivATI GLEW_GET_FUN(__glewNormalStream3ivATI) +#define glNormalStream3sATI GLEW_GET_FUN(__glewNormalStream3sATI) +#define glNormalStream3svATI GLEW_GET_FUN(__glewNormalStream3svATI) +#define glVertexBlendEnvfATI GLEW_GET_FUN(__glewVertexBlendEnvfATI) +#define glVertexBlendEnviATI GLEW_GET_FUN(__glewVertexBlendEnviATI) +#define glVertexStream2dATI GLEW_GET_FUN(__glewVertexStream2dATI) +#define glVertexStream2dvATI GLEW_GET_FUN(__glewVertexStream2dvATI) +#define glVertexStream2fATI GLEW_GET_FUN(__glewVertexStream2fATI) +#define glVertexStream2fvATI GLEW_GET_FUN(__glewVertexStream2fvATI) +#define glVertexStream2iATI GLEW_GET_FUN(__glewVertexStream2iATI) +#define glVertexStream2ivATI GLEW_GET_FUN(__glewVertexStream2ivATI) +#define glVertexStream2sATI GLEW_GET_FUN(__glewVertexStream2sATI) +#define glVertexStream2svATI GLEW_GET_FUN(__glewVertexStream2svATI) +#define glVertexStream3dATI GLEW_GET_FUN(__glewVertexStream3dATI) +#define glVertexStream3dvATI GLEW_GET_FUN(__glewVertexStream3dvATI) +#define glVertexStream3fATI GLEW_GET_FUN(__glewVertexStream3fATI) +#define glVertexStream3fvATI GLEW_GET_FUN(__glewVertexStream3fvATI) +#define glVertexStream3iATI GLEW_GET_FUN(__glewVertexStream3iATI) +#define glVertexStream3ivATI GLEW_GET_FUN(__glewVertexStream3ivATI) +#define glVertexStream3sATI GLEW_GET_FUN(__glewVertexStream3sATI) +#define glVertexStream3svATI GLEW_GET_FUN(__glewVertexStream3svATI) +#define glVertexStream4dATI GLEW_GET_FUN(__glewVertexStream4dATI) +#define glVertexStream4dvATI GLEW_GET_FUN(__glewVertexStream4dvATI) +#define glVertexStream4fATI GLEW_GET_FUN(__glewVertexStream4fATI) +#define glVertexStream4fvATI GLEW_GET_FUN(__glewVertexStream4fvATI) +#define glVertexStream4iATI GLEW_GET_FUN(__glewVertexStream4iATI) +#define glVertexStream4ivATI GLEW_GET_FUN(__glewVertexStream4ivATI) +#define glVertexStream4sATI GLEW_GET_FUN(__glewVertexStream4sATI) +#define glVertexStream4svATI GLEW_GET_FUN(__glewVertexStream4svATI) + +#define GLEW_ATI_vertex_streams GLEW_GET_VAR(__GLEW_ATI_vertex_streams) + +#endif /* GL_ATI_vertex_streams */ + +/* --------------------------- GL_EXT_422_pixels --------------------------- */ + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 + +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF + +#define GLEW_EXT_422_pixels GLEW_GET_VAR(__GLEW_EXT_422_pixels) + +#endif /* GL_EXT_422_pixels */ + +/* ---------------------------- GL_EXT_Cg_shader --------------------------- */ + +#ifndef GL_EXT_Cg_shader +#define GL_EXT_Cg_shader 1 + +#define GL_CG_VERTEX_SHADER_EXT 0x890E +#define GL_CG_FRAGMENT_SHADER_EXT 0x890F + +#define GLEW_EXT_Cg_shader GLEW_GET_VAR(__GLEW_EXT_Cg_shader) + +#endif /* GL_EXT_Cg_shader */ + +/* ------------------------------ GL_EXT_abgr ------------------------------ */ + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 + +#define GL_ABGR_EXT 0x8000 + +#define GLEW_EXT_abgr GLEW_GET_VAR(__GLEW_EXT_abgr) + +#endif /* GL_EXT_abgr */ + +/* ------------------------------ GL_EXT_bgra ------------------------------ */ + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 + +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 + +#define GLEW_EXT_bgra GLEW_GET_VAR(__GLEW_EXT_bgra) + +#endif /* GL_EXT_bgra */ + +/* ------------------------ GL_EXT_bindable_uniform ------------------------ */ + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform 1 + +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF + +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); +typedef GLintptr (GLAPIENTRY * PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); +typedef void (GLAPIENTRY * PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); + +#define glGetUniformBufferSizeEXT GLEW_GET_FUN(__glewGetUniformBufferSizeEXT) +#define glGetUniformOffsetEXT GLEW_GET_FUN(__glewGetUniformOffsetEXT) +#define glUniformBufferEXT GLEW_GET_FUN(__glewUniformBufferEXT) + +#define GLEW_EXT_bindable_uniform GLEW_GET_VAR(__GLEW_EXT_bindable_uniform) + +#endif /* GL_EXT_bindable_uniform */ + +/* --------------------------- GL_EXT_blend_color -------------------------- */ + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 + +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 + +typedef void (GLAPIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + +#define glBlendColorEXT GLEW_GET_FUN(__glewBlendColorEXT) + +#define GLEW_EXT_blend_color GLEW_GET_VAR(__GLEW_EXT_blend_color) + +#endif /* GL_EXT_blend_color */ + +/* --------------------- GL_EXT_blend_equation_separate -------------------- */ + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 1 + +#define GL_BLEND_EQUATION_RGB_EXT 0x8009 +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); + +#define glBlendEquationSeparateEXT GLEW_GET_FUN(__glewBlendEquationSeparateEXT) + +#define GLEW_EXT_blend_equation_separate GLEW_GET_VAR(__GLEW_EXT_blend_equation_separate) + +#endif /* GL_EXT_blend_equation_separate */ + +/* ----------------------- GL_EXT_blend_func_separate ---------------------- */ + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 + +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB + +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); + +#define glBlendFuncSeparateEXT GLEW_GET_FUN(__glewBlendFuncSeparateEXT) + +#define GLEW_EXT_blend_func_separate GLEW_GET_VAR(__GLEW_EXT_blend_func_separate) + +#endif /* GL_EXT_blend_func_separate */ + +/* ------------------------- GL_EXT_blend_logic_op ------------------------- */ + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 + +#define GLEW_EXT_blend_logic_op GLEW_GET_VAR(__GLEW_EXT_blend_logic_op) + +#endif /* GL_EXT_blend_logic_op */ + +/* -------------------------- GL_EXT_blend_minmax -------------------------- */ + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 + +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); + +#define glBlendEquationEXT GLEW_GET_FUN(__glewBlendEquationEXT) + +#define GLEW_EXT_blend_minmax GLEW_GET_VAR(__GLEW_EXT_blend_minmax) + +#endif /* GL_EXT_blend_minmax */ + +/* ------------------------- GL_EXT_blend_subtract ------------------------- */ + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 + +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B + +#define GLEW_EXT_blend_subtract GLEW_GET_VAR(__GLEW_EXT_blend_subtract) + +#endif /* GL_EXT_blend_subtract */ + +/* ------------------------ GL_EXT_clip_volume_hint ------------------------ */ + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 + +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 + +#define GLEW_EXT_clip_volume_hint GLEW_GET_VAR(__GLEW_EXT_clip_volume_hint) + +#endif /* GL_EXT_clip_volume_hint */ + +/* ------------------------------ GL_EXT_cmyka ----------------------------- */ + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 + +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F + +#define GLEW_EXT_cmyka GLEW_GET_VAR(__GLEW_EXT_cmyka) + +#endif /* GL_EXT_cmyka */ + +/* ------------------------- GL_EXT_color_subtable ------------------------- */ + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 + +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void* data); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); + +#define glColorSubTableEXT GLEW_GET_FUN(__glewColorSubTableEXT) +#define glCopyColorSubTableEXT GLEW_GET_FUN(__glewCopyColorSubTableEXT) + +#define GLEW_EXT_color_subtable GLEW_GET_VAR(__GLEW_EXT_color_subtable) + +#endif /* GL_EXT_color_subtable */ + +/* ---------------------- GL_EXT_compiled_vertex_array --------------------- */ + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 + +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 + +typedef void (GLAPIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void); + +#define glLockArraysEXT GLEW_GET_FUN(__glewLockArraysEXT) +#define glUnlockArraysEXT GLEW_GET_FUN(__glewUnlockArraysEXT) + +#define GLEW_EXT_compiled_vertex_array GLEW_GET_VAR(__GLEW_EXT_compiled_vertex_array) + +#endif /* GL_EXT_compiled_vertex_array */ + +/* --------------------------- GL_EXT_convolution -------------------------- */ + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 + +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 + +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void* image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void* image); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void* row, void* column, void* span); +typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* row, const void* column); + +#define glConvolutionFilter1DEXT GLEW_GET_FUN(__glewConvolutionFilter1DEXT) +#define glConvolutionFilter2DEXT GLEW_GET_FUN(__glewConvolutionFilter2DEXT) +#define glConvolutionParameterfEXT GLEW_GET_FUN(__glewConvolutionParameterfEXT) +#define glConvolutionParameterfvEXT GLEW_GET_FUN(__glewConvolutionParameterfvEXT) +#define glConvolutionParameteriEXT GLEW_GET_FUN(__glewConvolutionParameteriEXT) +#define glConvolutionParameterivEXT GLEW_GET_FUN(__glewConvolutionParameterivEXT) +#define glCopyConvolutionFilter1DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter1DEXT) +#define glCopyConvolutionFilter2DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter2DEXT) +#define glGetConvolutionFilterEXT GLEW_GET_FUN(__glewGetConvolutionFilterEXT) +#define glGetConvolutionParameterfvEXT GLEW_GET_FUN(__glewGetConvolutionParameterfvEXT) +#define glGetConvolutionParameterivEXT GLEW_GET_FUN(__glewGetConvolutionParameterivEXT) +#define glGetSeparableFilterEXT GLEW_GET_FUN(__glewGetSeparableFilterEXT) +#define glSeparableFilter2DEXT GLEW_GET_FUN(__glewSeparableFilter2DEXT) + +#define GLEW_EXT_convolution GLEW_GET_VAR(__GLEW_EXT_convolution) + +#endif /* GL_EXT_convolution */ + +/* ------------------------ GL_EXT_coordinate_frame ------------------------ */ + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 + +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 + +typedef void (GLAPIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, void* pointer); +typedef void (GLAPIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, void* pointer); + +#define glBinormalPointerEXT GLEW_GET_FUN(__glewBinormalPointerEXT) +#define glTangentPointerEXT GLEW_GET_FUN(__glewTangentPointerEXT) + +#define GLEW_EXT_coordinate_frame GLEW_GET_VAR(__GLEW_EXT_coordinate_frame) + +#endif /* GL_EXT_coordinate_frame */ + +/* -------------------------- GL_EXT_copy_texture -------------------------- */ + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 + +typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + +#define glCopyTexImage1DEXT GLEW_GET_FUN(__glewCopyTexImage1DEXT) +#define glCopyTexImage2DEXT GLEW_GET_FUN(__glewCopyTexImage2DEXT) +#define glCopyTexSubImage1DEXT GLEW_GET_FUN(__glewCopyTexSubImage1DEXT) +#define glCopyTexSubImage2DEXT GLEW_GET_FUN(__glewCopyTexSubImage2DEXT) +#define glCopyTexSubImage3DEXT GLEW_GET_FUN(__glewCopyTexSubImage3DEXT) + +#define GLEW_EXT_copy_texture GLEW_GET_VAR(__GLEW_EXT_copy_texture) + +#endif /* GL_EXT_copy_texture */ + +/* --------------------------- GL_EXT_cull_vertex -------------------------- */ + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 + +typedef void (GLAPIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params); + +#define glCullParameterdvEXT GLEW_GET_FUN(__glewCullParameterdvEXT) +#define glCullParameterfvEXT GLEW_GET_FUN(__glewCullParameterfvEXT) + +#define GLEW_EXT_cull_vertex GLEW_GET_VAR(__GLEW_EXT_cull_vertex) + +#endif /* GL_EXT_cull_vertex */ + +/* ------------------------ GL_EXT_depth_bounds_test ----------------------- */ + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 1 + +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 + +typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); + +#define glDepthBoundsEXT GLEW_GET_FUN(__glewDepthBoundsEXT) + +#define GLEW_EXT_depth_bounds_test GLEW_GET_VAR(__GLEW_EXT_depth_bounds_test) + +#endif /* GL_EXT_depth_bounds_test */ + +/* ----------------------- GL_EXT_direct_state_access ---------------------- */ + +#ifndef GL_EXT_direct_state_access +#define GL_EXT_direct_state_access 1 + +#define GL_PROGRAM_MATRIX_EXT 0x8E2D +#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E +#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F + +typedef void (GLAPIENTRY * PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); +typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); +typedef void (GLAPIENTRY * PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); +typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, void* img); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, void* img); +typedef void (GLAPIENTRY * PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void* pixels); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void** params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void* data); +typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void* string); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void* pixels); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLvoid** param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, GLvoid** param); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GLAPIENTRY * PFNGLMATRIXFRUSTUMEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXORTHOEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); +typedef void (GLAPIENTRY * PFNGLMATRIXPOPEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXPUSHEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXROTATEDEXTPROC) (GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXROTATEFEXTPROC) (GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMATRIXSCALEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXSCALEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* param); +typedef void (GLAPIENTRY * PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void* data); +typedef void (GLAPIENTRY * PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void* string); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat* param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* param); +typedef void (GLAPIENTRY * PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); + +#define glBindMultiTextureEXT GLEW_GET_FUN(__glewBindMultiTextureEXT) +#define glCheckNamedFramebufferStatusEXT GLEW_GET_FUN(__glewCheckNamedFramebufferStatusEXT) +#define glClientAttribDefaultEXT GLEW_GET_FUN(__glewClientAttribDefaultEXT) +#define glCompressedMultiTexImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage1DEXT) +#define glCompressedMultiTexImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage2DEXT) +#define glCompressedMultiTexImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage3DEXT) +#define glCompressedMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage1DEXT) +#define glCompressedMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage2DEXT) +#define glCompressedMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage3DEXT) +#define glCompressedTextureImage1DEXT GLEW_GET_FUN(__glewCompressedTextureImage1DEXT) +#define glCompressedTextureImage2DEXT GLEW_GET_FUN(__glewCompressedTextureImage2DEXT) +#define glCompressedTextureImage3DEXT GLEW_GET_FUN(__glewCompressedTextureImage3DEXT) +#define glCompressedTextureSubImage1DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage1DEXT) +#define glCompressedTextureSubImage2DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage2DEXT) +#define glCompressedTextureSubImage3DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage3DEXT) +#define glCopyMultiTexImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexImage1DEXT) +#define glCopyMultiTexImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexImage2DEXT) +#define glCopyMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage1DEXT) +#define glCopyMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage2DEXT) +#define glCopyMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage3DEXT) +#define glCopyTextureImage1DEXT GLEW_GET_FUN(__glewCopyTextureImage1DEXT) +#define glCopyTextureImage2DEXT GLEW_GET_FUN(__glewCopyTextureImage2DEXT) +#define glCopyTextureSubImage1DEXT GLEW_GET_FUN(__glewCopyTextureSubImage1DEXT) +#define glCopyTextureSubImage2DEXT GLEW_GET_FUN(__glewCopyTextureSubImage2DEXT) +#define glCopyTextureSubImage3DEXT GLEW_GET_FUN(__glewCopyTextureSubImage3DEXT) +#define glDisableClientStateIndexedEXT GLEW_GET_FUN(__glewDisableClientStateIndexedEXT) +#define glDisableClientStateiEXT GLEW_GET_FUN(__glewDisableClientStateiEXT) +#define glDisableVertexArrayAttribEXT GLEW_GET_FUN(__glewDisableVertexArrayAttribEXT) +#define glDisableVertexArrayEXT GLEW_GET_FUN(__glewDisableVertexArrayEXT) +#define glEnableClientStateIndexedEXT GLEW_GET_FUN(__glewEnableClientStateIndexedEXT) +#define glEnableClientStateiEXT GLEW_GET_FUN(__glewEnableClientStateiEXT) +#define glEnableVertexArrayAttribEXT GLEW_GET_FUN(__glewEnableVertexArrayAttribEXT) +#define glEnableVertexArrayEXT GLEW_GET_FUN(__glewEnableVertexArrayEXT) +#define glFlushMappedNamedBufferRangeEXT GLEW_GET_FUN(__glewFlushMappedNamedBufferRangeEXT) +#define glFramebufferDrawBufferEXT GLEW_GET_FUN(__glewFramebufferDrawBufferEXT) +#define glFramebufferDrawBuffersEXT GLEW_GET_FUN(__glewFramebufferDrawBuffersEXT) +#define glFramebufferReadBufferEXT GLEW_GET_FUN(__glewFramebufferReadBufferEXT) +#define glGenerateMultiTexMipmapEXT GLEW_GET_FUN(__glewGenerateMultiTexMipmapEXT) +#define glGenerateTextureMipmapEXT GLEW_GET_FUN(__glewGenerateTextureMipmapEXT) +#define glGetCompressedMultiTexImageEXT GLEW_GET_FUN(__glewGetCompressedMultiTexImageEXT) +#define glGetCompressedTextureImageEXT GLEW_GET_FUN(__glewGetCompressedTextureImageEXT) +#define glGetDoubleIndexedvEXT GLEW_GET_FUN(__glewGetDoubleIndexedvEXT) +#define glGetDoublei_vEXT GLEW_GET_FUN(__glewGetDoublei_vEXT) +#define glGetFloatIndexedvEXT GLEW_GET_FUN(__glewGetFloatIndexedvEXT) +#define glGetFloati_vEXT GLEW_GET_FUN(__glewGetFloati_vEXT) +#define glGetFramebufferParameterivEXT GLEW_GET_FUN(__glewGetFramebufferParameterivEXT) +#define glGetMultiTexEnvfvEXT GLEW_GET_FUN(__glewGetMultiTexEnvfvEXT) +#define glGetMultiTexEnvivEXT GLEW_GET_FUN(__glewGetMultiTexEnvivEXT) +#define glGetMultiTexGendvEXT GLEW_GET_FUN(__glewGetMultiTexGendvEXT) +#define glGetMultiTexGenfvEXT GLEW_GET_FUN(__glewGetMultiTexGenfvEXT) +#define glGetMultiTexGenivEXT GLEW_GET_FUN(__glewGetMultiTexGenivEXT) +#define glGetMultiTexImageEXT GLEW_GET_FUN(__glewGetMultiTexImageEXT) +#define glGetMultiTexLevelParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterfvEXT) +#define glGetMultiTexLevelParameterivEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterivEXT) +#define glGetMultiTexParameterIivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIivEXT) +#define glGetMultiTexParameterIuivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIuivEXT) +#define glGetMultiTexParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexParameterfvEXT) +#define glGetMultiTexParameterivEXT GLEW_GET_FUN(__glewGetMultiTexParameterivEXT) +#define glGetNamedBufferParameterivEXT GLEW_GET_FUN(__glewGetNamedBufferParameterivEXT) +#define glGetNamedBufferPointervEXT GLEW_GET_FUN(__glewGetNamedBufferPointervEXT) +#define glGetNamedBufferSubDataEXT GLEW_GET_FUN(__glewGetNamedBufferSubDataEXT) +#define glGetNamedFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferAttachmentParameterivEXT) +#define glGetNamedProgramLocalParameterIivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIivEXT) +#define glGetNamedProgramLocalParameterIuivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIuivEXT) +#define glGetNamedProgramLocalParameterdvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterdvEXT) +#define glGetNamedProgramLocalParameterfvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterfvEXT) +#define glGetNamedProgramStringEXT GLEW_GET_FUN(__glewGetNamedProgramStringEXT) +#define glGetNamedProgramivEXT GLEW_GET_FUN(__glewGetNamedProgramivEXT) +#define glGetNamedRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetNamedRenderbufferParameterivEXT) +#define glGetPointerIndexedvEXT GLEW_GET_FUN(__glewGetPointerIndexedvEXT) +#define glGetPointeri_vEXT GLEW_GET_FUN(__glewGetPointeri_vEXT) +#define glGetTextureImageEXT GLEW_GET_FUN(__glewGetTextureImageEXT) +#define glGetTextureLevelParameterfvEXT GLEW_GET_FUN(__glewGetTextureLevelParameterfvEXT) +#define glGetTextureLevelParameterivEXT GLEW_GET_FUN(__glewGetTextureLevelParameterivEXT) +#define glGetTextureParameterIivEXT GLEW_GET_FUN(__glewGetTextureParameterIivEXT) +#define glGetTextureParameterIuivEXT GLEW_GET_FUN(__glewGetTextureParameterIuivEXT) +#define glGetTextureParameterfvEXT GLEW_GET_FUN(__glewGetTextureParameterfvEXT) +#define glGetTextureParameterivEXT GLEW_GET_FUN(__glewGetTextureParameterivEXT) +#define glGetVertexArrayIntegeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayIntegeri_vEXT) +#define glGetVertexArrayIntegervEXT GLEW_GET_FUN(__glewGetVertexArrayIntegervEXT) +#define glGetVertexArrayPointeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayPointeri_vEXT) +#define glGetVertexArrayPointervEXT GLEW_GET_FUN(__glewGetVertexArrayPointervEXT) +#define glMapNamedBufferEXT GLEW_GET_FUN(__glewMapNamedBufferEXT) +#define glMapNamedBufferRangeEXT GLEW_GET_FUN(__glewMapNamedBufferRangeEXT) +#define glMatrixFrustumEXT GLEW_GET_FUN(__glewMatrixFrustumEXT) +#define glMatrixLoadIdentityEXT GLEW_GET_FUN(__glewMatrixLoadIdentityEXT) +#define glMatrixLoadTransposedEXT GLEW_GET_FUN(__glewMatrixLoadTransposedEXT) +#define glMatrixLoadTransposefEXT GLEW_GET_FUN(__glewMatrixLoadTransposefEXT) +#define glMatrixLoaddEXT GLEW_GET_FUN(__glewMatrixLoaddEXT) +#define glMatrixLoadfEXT GLEW_GET_FUN(__glewMatrixLoadfEXT) +#define glMatrixMultTransposedEXT GLEW_GET_FUN(__glewMatrixMultTransposedEXT) +#define glMatrixMultTransposefEXT GLEW_GET_FUN(__glewMatrixMultTransposefEXT) +#define glMatrixMultdEXT GLEW_GET_FUN(__glewMatrixMultdEXT) +#define glMatrixMultfEXT GLEW_GET_FUN(__glewMatrixMultfEXT) +#define glMatrixOrthoEXT GLEW_GET_FUN(__glewMatrixOrthoEXT) +#define glMatrixPopEXT GLEW_GET_FUN(__glewMatrixPopEXT) +#define glMatrixPushEXT GLEW_GET_FUN(__glewMatrixPushEXT) +#define glMatrixRotatedEXT GLEW_GET_FUN(__glewMatrixRotatedEXT) +#define glMatrixRotatefEXT GLEW_GET_FUN(__glewMatrixRotatefEXT) +#define glMatrixScaledEXT GLEW_GET_FUN(__glewMatrixScaledEXT) +#define glMatrixScalefEXT GLEW_GET_FUN(__glewMatrixScalefEXT) +#define glMatrixTranslatedEXT GLEW_GET_FUN(__glewMatrixTranslatedEXT) +#define glMatrixTranslatefEXT GLEW_GET_FUN(__glewMatrixTranslatefEXT) +#define glMultiTexBufferEXT GLEW_GET_FUN(__glewMultiTexBufferEXT) +#define glMultiTexCoordPointerEXT GLEW_GET_FUN(__glewMultiTexCoordPointerEXT) +#define glMultiTexEnvfEXT GLEW_GET_FUN(__glewMultiTexEnvfEXT) +#define glMultiTexEnvfvEXT GLEW_GET_FUN(__glewMultiTexEnvfvEXT) +#define glMultiTexEnviEXT GLEW_GET_FUN(__glewMultiTexEnviEXT) +#define glMultiTexEnvivEXT GLEW_GET_FUN(__glewMultiTexEnvivEXT) +#define glMultiTexGendEXT GLEW_GET_FUN(__glewMultiTexGendEXT) +#define glMultiTexGendvEXT GLEW_GET_FUN(__glewMultiTexGendvEXT) +#define glMultiTexGenfEXT GLEW_GET_FUN(__glewMultiTexGenfEXT) +#define glMultiTexGenfvEXT GLEW_GET_FUN(__glewMultiTexGenfvEXT) +#define glMultiTexGeniEXT GLEW_GET_FUN(__glewMultiTexGeniEXT) +#define glMultiTexGenivEXT GLEW_GET_FUN(__glewMultiTexGenivEXT) +#define glMultiTexImage1DEXT GLEW_GET_FUN(__glewMultiTexImage1DEXT) +#define glMultiTexImage2DEXT GLEW_GET_FUN(__glewMultiTexImage2DEXT) +#define glMultiTexImage3DEXT GLEW_GET_FUN(__glewMultiTexImage3DEXT) +#define glMultiTexParameterIivEXT GLEW_GET_FUN(__glewMultiTexParameterIivEXT) +#define glMultiTexParameterIuivEXT GLEW_GET_FUN(__glewMultiTexParameterIuivEXT) +#define glMultiTexParameterfEXT GLEW_GET_FUN(__glewMultiTexParameterfEXT) +#define glMultiTexParameterfvEXT GLEW_GET_FUN(__glewMultiTexParameterfvEXT) +#define glMultiTexParameteriEXT GLEW_GET_FUN(__glewMultiTexParameteriEXT) +#define glMultiTexParameterivEXT GLEW_GET_FUN(__glewMultiTexParameterivEXT) +#define glMultiTexRenderbufferEXT GLEW_GET_FUN(__glewMultiTexRenderbufferEXT) +#define glMultiTexSubImage1DEXT GLEW_GET_FUN(__glewMultiTexSubImage1DEXT) +#define glMultiTexSubImage2DEXT GLEW_GET_FUN(__glewMultiTexSubImage2DEXT) +#define glMultiTexSubImage3DEXT GLEW_GET_FUN(__glewMultiTexSubImage3DEXT) +#define glNamedBufferDataEXT GLEW_GET_FUN(__glewNamedBufferDataEXT) +#define glNamedBufferSubDataEXT GLEW_GET_FUN(__glewNamedBufferSubDataEXT) +#define glNamedCopyBufferSubDataEXT GLEW_GET_FUN(__glewNamedCopyBufferSubDataEXT) +#define glNamedFramebufferRenderbufferEXT GLEW_GET_FUN(__glewNamedFramebufferRenderbufferEXT) +#define glNamedFramebufferTexture1DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture1DEXT) +#define glNamedFramebufferTexture2DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture2DEXT) +#define glNamedFramebufferTexture3DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture3DEXT) +#define glNamedFramebufferTextureEXT GLEW_GET_FUN(__glewNamedFramebufferTextureEXT) +#define glNamedFramebufferTextureFaceEXT GLEW_GET_FUN(__glewNamedFramebufferTextureFaceEXT) +#define glNamedFramebufferTextureLayerEXT GLEW_GET_FUN(__glewNamedFramebufferTextureLayerEXT) +#define glNamedProgramLocalParameter4dEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dEXT) +#define glNamedProgramLocalParameter4dvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dvEXT) +#define glNamedProgramLocalParameter4fEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fEXT) +#define glNamedProgramLocalParameter4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fvEXT) +#define glNamedProgramLocalParameterI4iEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4iEXT) +#define glNamedProgramLocalParameterI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4ivEXT) +#define glNamedProgramLocalParameterI4uiEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uiEXT) +#define glNamedProgramLocalParameterI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uivEXT) +#define glNamedProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameters4fvEXT) +#define glNamedProgramLocalParametersI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4ivEXT) +#define glNamedProgramLocalParametersI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4uivEXT) +#define glNamedProgramStringEXT GLEW_GET_FUN(__glewNamedProgramStringEXT) +#define glNamedRenderbufferStorageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageEXT) +#define glNamedRenderbufferStorageMultisampleCoverageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleCoverageEXT) +#define glNamedRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleEXT) +#define glProgramUniform1fEXT GLEW_GET_FUN(__glewProgramUniform1fEXT) +#define glProgramUniform1fvEXT GLEW_GET_FUN(__glewProgramUniform1fvEXT) +#define glProgramUniform1iEXT GLEW_GET_FUN(__glewProgramUniform1iEXT) +#define glProgramUniform1ivEXT GLEW_GET_FUN(__glewProgramUniform1ivEXT) +#define glProgramUniform1uiEXT GLEW_GET_FUN(__glewProgramUniform1uiEXT) +#define glProgramUniform1uivEXT GLEW_GET_FUN(__glewProgramUniform1uivEXT) +#define glProgramUniform2fEXT GLEW_GET_FUN(__glewProgramUniform2fEXT) +#define glProgramUniform2fvEXT GLEW_GET_FUN(__glewProgramUniform2fvEXT) +#define glProgramUniform2iEXT GLEW_GET_FUN(__glewProgramUniform2iEXT) +#define glProgramUniform2ivEXT GLEW_GET_FUN(__glewProgramUniform2ivEXT) +#define glProgramUniform2uiEXT GLEW_GET_FUN(__glewProgramUniform2uiEXT) +#define glProgramUniform2uivEXT GLEW_GET_FUN(__glewProgramUniform2uivEXT) +#define glProgramUniform3fEXT GLEW_GET_FUN(__glewProgramUniform3fEXT) +#define glProgramUniform3fvEXT GLEW_GET_FUN(__glewProgramUniform3fvEXT) +#define glProgramUniform3iEXT GLEW_GET_FUN(__glewProgramUniform3iEXT) +#define glProgramUniform3ivEXT GLEW_GET_FUN(__glewProgramUniform3ivEXT) +#define glProgramUniform3uiEXT GLEW_GET_FUN(__glewProgramUniform3uiEXT) +#define glProgramUniform3uivEXT GLEW_GET_FUN(__glewProgramUniform3uivEXT) +#define glProgramUniform4fEXT GLEW_GET_FUN(__glewProgramUniform4fEXT) +#define glProgramUniform4fvEXT GLEW_GET_FUN(__glewProgramUniform4fvEXT) +#define glProgramUniform4iEXT GLEW_GET_FUN(__glewProgramUniform4iEXT) +#define glProgramUniform4ivEXT GLEW_GET_FUN(__glewProgramUniform4ivEXT) +#define glProgramUniform4uiEXT GLEW_GET_FUN(__glewProgramUniform4uiEXT) +#define glProgramUniform4uivEXT GLEW_GET_FUN(__glewProgramUniform4uivEXT) +#define glProgramUniformMatrix2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2fvEXT) +#define glProgramUniformMatrix2x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x3fvEXT) +#define glProgramUniformMatrix2x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x4fvEXT) +#define glProgramUniformMatrix3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3fvEXT) +#define glProgramUniformMatrix3x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x2fvEXT) +#define glProgramUniformMatrix3x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x4fvEXT) +#define glProgramUniformMatrix4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4fvEXT) +#define glProgramUniformMatrix4x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x2fvEXT) +#define glProgramUniformMatrix4x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x3fvEXT) +#define glPushClientAttribDefaultEXT GLEW_GET_FUN(__glewPushClientAttribDefaultEXT) +#define glTextureBufferEXT GLEW_GET_FUN(__glewTextureBufferEXT) +#define glTextureImage1DEXT GLEW_GET_FUN(__glewTextureImage1DEXT) +#define glTextureImage2DEXT GLEW_GET_FUN(__glewTextureImage2DEXT) +#define glTextureImage3DEXT GLEW_GET_FUN(__glewTextureImage3DEXT) +#define glTextureParameterIivEXT GLEW_GET_FUN(__glewTextureParameterIivEXT) +#define glTextureParameterIuivEXT GLEW_GET_FUN(__glewTextureParameterIuivEXT) +#define glTextureParameterfEXT GLEW_GET_FUN(__glewTextureParameterfEXT) +#define glTextureParameterfvEXT GLEW_GET_FUN(__glewTextureParameterfvEXT) +#define glTextureParameteriEXT GLEW_GET_FUN(__glewTextureParameteriEXT) +#define glTextureParameterivEXT GLEW_GET_FUN(__glewTextureParameterivEXT) +#define glTextureRenderbufferEXT GLEW_GET_FUN(__glewTextureRenderbufferEXT) +#define glTextureSubImage1DEXT GLEW_GET_FUN(__glewTextureSubImage1DEXT) +#define glTextureSubImage2DEXT GLEW_GET_FUN(__glewTextureSubImage2DEXT) +#define glTextureSubImage3DEXT GLEW_GET_FUN(__glewTextureSubImage3DEXT) +#define glUnmapNamedBufferEXT GLEW_GET_FUN(__glewUnmapNamedBufferEXT) +#define glVertexArrayColorOffsetEXT GLEW_GET_FUN(__glewVertexArrayColorOffsetEXT) +#define glVertexArrayEdgeFlagOffsetEXT GLEW_GET_FUN(__glewVertexArrayEdgeFlagOffsetEXT) +#define glVertexArrayFogCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayFogCoordOffsetEXT) +#define glVertexArrayIndexOffsetEXT GLEW_GET_FUN(__glewVertexArrayIndexOffsetEXT) +#define glVertexArrayMultiTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayMultiTexCoordOffsetEXT) +#define glVertexArrayNormalOffsetEXT GLEW_GET_FUN(__glewVertexArrayNormalOffsetEXT) +#define glVertexArraySecondaryColorOffsetEXT GLEW_GET_FUN(__glewVertexArraySecondaryColorOffsetEXT) +#define glVertexArrayTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayTexCoordOffsetEXT) +#define glVertexArrayVertexAttribIOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribIOffsetEXT) +#define glVertexArrayVertexAttribOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribOffsetEXT) +#define glVertexArrayVertexOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexOffsetEXT) + +#define GLEW_EXT_direct_state_access GLEW_GET_VAR(__GLEW_EXT_direct_state_access) + +#endif /* GL_EXT_direct_state_access */ + +/* -------------------------- GL_EXT_draw_buffers2 ------------------------- */ + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 + +typedef void (GLAPIENTRY * PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAPIENTRY * PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum value, GLuint index, GLboolean* data); +typedef void (GLAPIENTRY * PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum value, GLuint index, GLint* data); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); + +#define glColorMaskIndexedEXT GLEW_GET_FUN(__glewColorMaskIndexedEXT) +#define glDisableIndexedEXT GLEW_GET_FUN(__glewDisableIndexedEXT) +#define glEnableIndexedEXT GLEW_GET_FUN(__glewEnableIndexedEXT) +#define glGetBooleanIndexedvEXT GLEW_GET_FUN(__glewGetBooleanIndexedvEXT) +#define glGetIntegerIndexedvEXT GLEW_GET_FUN(__glewGetIntegerIndexedvEXT) +#define glIsEnabledIndexedEXT GLEW_GET_FUN(__glewIsEnabledIndexedEXT) + +#define GLEW_EXT_draw_buffers2 GLEW_GET_VAR(__GLEW_EXT_draw_buffers2) + +#endif /* GL_EXT_draw_buffers2 */ + +/* ------------------------- GL_EXT_draw_instanced ------------------------- */ + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); + +#define glDrawArraysInstancedEXT GLEW_GET_FUN(__glewDrawArraysInstancedEXT) +#define glDrawElementsInstancedEXT GLEW_GET_FUN(__glewDrawElementsInstancedEXT) + +#define GLEW_EXT_draw_instanced GLEW_GET_VAR(__GLEW_EXT_draw_instanced) + +#endif /* GL_EXT_draw_instanced */ + +/* ----------------------- GL_EXT_draw_range_elements ---------------------- */ + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 + +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 + +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); + +#define glDrawRangeElementsEXT GLEW_GET_FUN(__glewDrawRangeElementsEXT) + +#define GLEW_EXT_draw_range_elements GLEW_GET_VAR(__GLEW_EXT_draw_range_elements) + +#endif /* GL_EXT_draw_range_elements */ + +/* ---------------------------- GL_EXT_fog_coord --------------------------- */ + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 + +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 + +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); + +#define glFogCoordPointerEXT GLEW_GET_FUN(__glewFogCoordPointerEXT) +#define glFogCoorddEXT GLEW_GET_FUN(__glewFogCoorddEXT) +#define glFogCoorddvEXT GLEW_GET_FUN(__glewFogCoorddvEXT) +#define glFogCoordfEXT GLEW_GET_FUN(__glewFogCoordfEXT) +#define glFogCoordfvEXT GLEW_GET_FUN(__glewFogCoordfvEXT) + +#define GLEW_EXT_fog_coord GLEW_GET_VAR(__GLEW_EXT_fog_coord) + +#endif /* GL_EXT_fog_coord */ + +/* ------------------------ GL_EXT_fragment_lighting ----------------------- */ + +#ifndef GL_EXT_fragment_lighting +#define GL_EXT_fragment_lighting 1 + +#define GL_FRAGMENT_LIGHTING_EXT 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_EXT 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_EXT 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_EXT 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_EXT 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_EXT 0x8405 +#define GL_CURRENT_RASTER_NORMAL_EXT 0x8406 +#define GL_LIGHT_ENV_MODE_EXT 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_EXT 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_EXT 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_EXT 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_EXT 0x840B +#define GL_FRAGMENT_LIGHT0_EXT 0x840C +#define GL_FRAGMENT_LIGHT7_EXT 0x8413 + +typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALEXTPROC) (GLenum face, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVEXTPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIEXTPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVEXTPROC) (GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFEXTPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIEXTPROC) (GLenum light, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFEXTPROC) (GLenum face, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIEXTPROC) (GLenum face, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLLIGHTENVIEXTPROC) (GLenum pname, GLint param); + +#define glFragmentColorMaterialEXT GLEW_GET_FUN(__glewFragmentColorMaterialEXT) +#define glFragmentLightModelfEXT GLEW_GET_FUN(__glewFragmentLightModelfEXT) +#define glFragmentLightModelfvEXT GLEW_GET_FUN(__glewFragmentLightModelfvEXT) +#define glFragmentLightModeliEXT GLEW_GET_FUN(__glewFragmentLightModeliEXT) +#define glFragmentLightModelivEXT GLEW_GET_FUN(__glewFragmentLightModelivEXT) +#define glFragmentLightfEXT GLEW_GET_FUN(__glewFragmentLightfEXT) +#define glFragmentLightfvEXT GLEW_GET_FUN(__glewFragmentLightfvEXT) +#define glFragmentLightiEXT GLEW_GET_FUN(__glewFragmentLightiEXT) +#define glFragmentLightivEXT GLEW_GET_FUN(__glewFragmentLightivEXT) +#define glFragmentMaterialfEXT GLEW_GET_FUN(__glewFragmentMaterialfEXT) +#define glFragmentMaterialfvEXT GLEW_GET_FUN(__glewFragmentMaterialfvEXT) +#define glFragmentMaterialiEXT GLEW_GET_FUN(__glewFragmentMaterialiEXT) +#define glFragmentMaterialivEXT GLEW_GET_FUN(__glewFragmentMaterialivEXT) +#define glGetFragmentLightfvEXT GLEW_GET_FUN(__glewGetFragmentLightfvEXT) +#define glGetFragmentLightivEXT GLEW_GET_FUN(__glewGetFragmentLightivEXT) +#define glGetFragmentMaterialfvEXT GLEW_GET_FUN(__glewGetFragmentMaterialfvEXT) +#define glGetFragmentMaterialivEXT GLEW_GET_FUN(__glewGetFragmentMaterialivEXT) +#define glLightEnviEXT GLEW_GET_FUN(__glewLightEnviEXT) + +#define GLEW_EXT_fragment_lighting GLEW_GET_VAR(__GLEW_EXT_fragment_lighting) + +#endif /* GL_EXT_fragment_lighting */ + +/* ------------------------ GL_EXT_framebuffer_blit ------------------------ */ + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 + +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA + +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + +#define glBlitFramebufferEXT GLEW_GET_FUN(__glewBlitFramebufferEXT) + +#define GLEW_EXT_framebuffer_blit GLEW_GET_VAR(__GLEW_EXT_framebuffer_blit) + +#endif /* GL_EXT_framebuffer_blit */ + +/* --------------------- GL_EXT_framebuffer_multisample -------------------- */ + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 + +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 + +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewRenderbufferStorageMultisampleEXT) + +#define GLEW_EXT_framebuffer_multisample GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample) + +#endif /* GL_EXT_framebuffer_multisample */ + +/* ----------------------- GL_EXT_framebuffer_object ----------------------- */ + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 + +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 + +typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + +#define glBindFramebufferEXT GLEW_GET_FUN(__glewBindFramebufferEXT) +#define glBindRenderbufferEXT GLEW_GET_FUN(__glewBindRenderbufferEXT) +#define glCheckFramebufferStatusEXT GLEW_GET_FUN(__glewCheckFramebufferStatusEXT) +#define glDeleteFramebuffersEXT GLEW_GET_FUN(__glewDeleteFramebuffersEXT) +#define glDeleteRenderbuffersEXT GLEW_GET_FUN(__glewDeleteRenderbuffersEXT) +#define glFramebufferRenderbufferEXT GLEW_GET_FUN(__glewFramebufferRenderbufferEXT) +#define glFramebufferTexture1DEXT GLEW_GET_FUN(__glewFramebufferTexture1DEXT) +#define glFramebufferTexture2DEXT GLEW_GET_FUN(__glewFramebufferTexture2DEXT) +#define glFramebufferTexture3DEXT GLEW_GET_FUN(__glewFramebufferTexture3DEXT) +#define glGenFramebuffersEXT GLEW_GET_FUN(__glewGenFramebuffersEXT) +#define glGenRenderbuffersEXT GLEW_GET_FUN(__glewGenRenderbuffersEXT) +#define glGenerateMipmapEXT GLEW_GET_FUN(__glewGenerateMipmapEXT) +#define glGetFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetFramebufferAttachmentParameterivEXT) +#define glGetRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetRenderbufferParameterivEXT) +#define glIsFramebufferEXT GLEW_GET_FUN(__glewIsFramebufferEXT) +#define glIsRenderbufferEXT GLEW_GET_FUN(__glewIsRenderbufferEXT) +#define glRenderbufferStorageEXT GLEW_GET_FUN(__glewRenderbufferStorageEXT) + +#define GLEW_EXT_framebuffer_object GLEW_GET_VAR(__GLEW_EXT_framebuffer_object) + +#endif /* GL_EXT_framebuffer_object */ + +/* ------------------------ GL_EXT_framebuffer_sRGB ------------------------ */ + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB 1 + +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA + +#define GLEW_EXT_framebuffer_sRGB GLEW_GET_VAR(__GLEW_EXT_framebuffer_sRGB) + +#endif /* GL_EXT_framebuffer_sRGB */ + +/* ------------------------ GL_EXT_geometry_shader4 ------------------------ */ + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 1 + +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); + +#define glFramebufferTextureEXT GLEW_GET_FUN(__glewFramebufferTextureEXT) +#define glFramebufferTextureFaceEXT GLEW_GET_FUN(__glewFramebufferTextureFaceEXT) +#define glFramebufferTextureLayerEXT GLEW_GET_FUN(__glewFramebufferTextureLayerEXT) +#define glProgramParameteriEXT GLEW_GET_FUN(__glewProgramParameteriEXT) + +#define GLEW_EXT_geometry_shader4 GLEW_GET_VAR(__GLEW_EXT_geometry_shader4) + +#endif /* GL_EXT_geometry_shader4 */ + +/* --------------------- GL_EXT_gpu_program_parameters --------------------- */ + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters 1 + +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); + +#define glProgramEnvParameters4fvEXT GLEW_GET_FUN(__glewProgramEnvParameters4fvEXT) +#define glProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewProgramLocalParameters4fvEXT) + +#define GLEW_EXT_gpu_program_parameters GLEW_GET_VAR(__GLEW_EXT_gpu_program_parameters) + +#endif /* GL_EXT_gpu_program_parameters */ + +/* --------------------------- GL_EXT_gpu_shader4 -------------------------- */ + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 1 + +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 + +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + +#define glBindFragDataLocationEXT GLEW_GET_FUN(__glewBindFragDataLocationEXT) +#define glGetFragDataLocationEXT GLEW_GET_FUN(__glewGetFragDataLocationEXT) +#define glGetUniformuivEXT GLEW_GET_FUN(__glewGetUniformuivEXT) +#define glGetVertexAttribIivEXT GLEW_GET_FUN(__glewGetVertexAttribIivEXT) +#define glGetVertexAttribIuivEXT GLEW_GET_FUN(__glewGetVertexAttribIuivEXT) +#define glUniform1uiEXT GLEW_GET_FUN(__glewUniform1uiEXT) +#define glUniform1uivEXT GLEW_GET_FUN(__glewUniform1uivEXT) +#define glUniform2uiEXT GLEW_GET_FUN(__glewUniform2uiEXT) +#define glUniform2uivEXT GLEW_GET_FUN(__glewUniform2uivEXT) +#define glUniform3uiEXT GLEW_GET_FUN(__glewUniform3uiEXT) +#define glUniform3uivEXT GLEW_GET_FUN(__glewUniform3uivEXT) +#define glUniform4uiEXT GLEW_GET_FUN(__glewUniform4uiEXT) +#define glUniform4uivEXT GLEW_GET_FUN(__glewUniform4uivEXT) +#define glVertexAttribI1iEXT GLEW_GET_FUN(__glewVertexAttribI1iEXT) +#define glVertexAttribI1ivEXT GLEW_GET_FUN(__glewVertexAttribI1ivEXT) +#define glVertexAttribI1uiEXT GLEW_GET_FUN(__glewVertexAttribI1uiEXT) +#define glVertexAttribI1uivEXT GLEW_GET_FUN(__glewVertexAttribI1uivEXT) +#define glVertexAttribI2iEXT GLEW_GET_FUN(__glewVertexAttribI2iEXT) +#define glVertexAttribI2ivEXT GLEW_GET_FUN(__glewVertexAttribI2ivEXT) +#define glVertexAttribI2uiEXT GLEW_GET_FUN(__glewVertexAttribI2uiEXT) +#define glVertexAttribI2uivEXT GLEW_GET_FUN(__glewVertexAttribI2uivEXT) +#define glVertexAttribI3iEXT GLEW_GET_FUN(__glewVertexAttribI3iEXT) +#define glVertexAttribI3ivEXT GLEW_GET_FUN(__glewVertexAttribI3ivEXT) +#define glVertexAttribI3uiEXT GLEW_GET_FUN(__glewVertexAttribI3uiEXT) +#define glVertexAttribI3uivEXT GLEW_GET_FUN(__glewVertexAttribI3uivEXT) +#define glVertexAttribI4bvEXT GLEW_GET_FUN(__glewVertexAttribI4bvEXT) +#define glVertexAttribI4iEXT GLEW_GET_FUN(__glewVertexAttribI4iEXT) +#define glVertexAttribI4ivEXT GLEW_GET_FUN(__glewVertexAttribI4ivEXT) +#define glVertexAttribI4svEXT GLEW_GET_FUN(__glewVertexAttribI4svEXT) +#define glVertexAttribI4ubvEXT GLEW_GET_FUN(__glewVertexAttribI4ubvEXT) +#define glVertexAttribI4uiEXT GLEW_GET_FUN(__glewVertexAttribI4uiEXT) +#define glVertexAttribI4uivEXT GLEW_GET_FUN(__glewVertexAttribI4uivEXT) +#define glVertexAttribI4usvEXT GLEW_GET_FUN(__glewVertexAttribI4usvEXT) +#define glVertexAttribIPointerEXT GLEW_GET_FUN(__glewVertexAttribIPointerEXT) + +#define GLEW_EXT_gpu_shader4 GLEW_GET_VAR(__GLEW_EXT_gpu_shader4) + +#endif /* GL_EXT_gpu_shader4 */ + +/* ---------------------------- GL_EXT_histogram --------------------------- */ + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 + +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 + +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void* values); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void* values); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target); + +#define glGetHistogramEXT GLEW_GET_FUN(__glewGetHistogramEXT) +#define glGetHistogramParameterfvEXT GLEW_GET_FUN(__glewGetHistogramParameterfvEXT) +#define glGetHistogramParameterivEXT GLEW_GET_FUN(__glewGetHistogramParameterivEXT) +#define glGetMinmaxEXT GLEW_GET_FUN(__glewGetMinmaxEXT) +#define glGetMinmaxParameterfvEXT GLEW_GET_FUN(__glewGetMinmaxParameterfvEXT) +#define glGetMinmaxParameterivEXT GLEW_GET_FUN(__glewGetMinmaxParameterivEXT) +#define glHistogramEXT GLEW_GET_FUN(__glewHistogramEXT) +#define glMinmaxEXT GLEW_GET_FUN(__glewMinmaxEXT) +#define glResetHistogramEXT GLEW_GET_FUN(__glewResetHistogramEXT) +#define glResetMinmaxEXT GLEW_GET_FUN(__glewResetMinmaxEXT) + +#define GLEW_EXT_histogram GLEW_GET_VAR(__GLEW_EXT_histogram) + +#endif /* GL_EXT_histogram */ + +/* ----------------------- GL_EXT_index_array_formats ---------------------- */ + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 + +#define GLEW_EXT_index_array_formats GLEW_GET_VAR(__GLEW_EXT_index_array_formats) + +#endif /* GL_EXT_index_array_formats */ + +/* --------------------------- GL_EXT_index_func --------------------------- */ + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 + +typedef void (GLAPIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLfloat ref); + +#define glIndexFuncEXT GLEW_GET_FUN(__glewIndexFuncEXT) + +#define GLEW_EXT_index_func GLEW_GET_VAR(__GLEW_EXT_index_func) + +#endif /* GL_EXT_index_func */ + +/* ------------------------- GL_EXT_index_material ------------------------- */ + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 + +typedef void (GLAPIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); + +#define glIndexMaterialEXT GLEW_GET_FUN(__glewIndexMaterialEXT) + +#define GLEW_EXT_index_material GLEW_GET_VAR(__GLEW_EXT_index_material) + +#endif /* GL_EXT_index_material */ + +/* -------------------------- GL_EXT_index_texture ------------------------- */ + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 + +#define GLEW_EXT_index_texture GLEW_GET_VAR(__GLEW_EXT_index_texture) + +#endif /* GL_EXT_index_texture */ + +/* -------------------------- GL_EXT_light_texture ------------------------- */ + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 + +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 + +typedef void (GLAPIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (GLAPIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); + +#define glApplyTextureEXT GLEW_GET_FUN(__glewApplyTextureEXT) +#define glTextureLightEXT GLEW_GET_FUN(__glewTextureLightEXT) +#define glTextureMaterialEXT GLEW_GET_FUN(__glewTextureMaterialEXT) + +#define GLEW_EXT_light_texture GLEW_GET_VAR(__GLEW_EXT_light_texture) + +#endif /* GL_EXT_light_texture */ + +/* ------------------------- GL_EXT_misc_attribute ------------------------- */ + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 + +#define GLEW_EXT_misc_attribute GLEW_GET_VAR(__GLEW_EXT_misc_attribute) + +#endif /* GL_EXT_misc_attribute */ + +/* ------------------------ GL_EXT_multi_draw_arrays ----------------------- */ + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint* first, GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, GLsizei* count, GLenum type, const GLvoid **indices, GLsizei primcount); + +#define glMultiDrawArraysEXT GLEW_GET_FUN(__glewMultiDrawArraysEXT) +#define glMultiDrawElementsEXT GLEW_GET_FUN(__glewMultiDrawElementsEXT) + +#define GLEW_EXT_multi_draw_arrays GLEW_GET_VAR(__GLEW_EXT_multi_draw_arrays) + +#endif /* GL_EXT_multi_draw_arrays */ + +/* --------------------------- GL_EXT_multisample -------------------------- */ + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 + +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); + +#define glSampleMaskEXT GLEW_GET_FUN(__glewSampleMaskEXT) +#define glSamplePatternEXT GLEW_GET_FUN(__glewSamplePatternEXT) + +#define GLEW_EXT_multisample GLEW_GET_VAR(__GLEW_EXT_multisample) + +#endif /* GL_EXT_multisample */ + +/* ---------------------- GL_EXT_packed_depth_stencil ---------------------- */ + +#ifndef GL_EXT_packed_depth_stencil +#define GL_EXT_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 + +#define GLEW_EXT_packed_depth_stencil GLEW_GET_VAR(__GLEW_EXT_packed_depth_stencil) + +#endif /* GL_EXT_packed_depth_stencil */ + +/* -------------------------- GL_EXT_packed_float -------------------------- */ + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float 1 + +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C + +#define GLEW_EXT_packed_float GLEW_GET_VAR(__GLEW_EXT_packed_float) + +#endif /* GL_EXT_packed_float */ + +/* -------------------------- GL_EXT_packed_pixels ------------------------- */ + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 + +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 + +#define GLEW_EXT_packed_pixels GLEW_GET_VAR(__GLEW_EXT_packed_pixels) + +#endif /* GL_EXT_packed_pixels */ + +/* ------------------------ GL_EXT_paletted_texture ------------------------ */ + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 + +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_COLOR_TABLE_FORMAT_EXT 0x80D8 +#define GL_COLOR_TABLE_WIDTH_EXT 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_EXT 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_EXT 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_EXT 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_EXT 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_EXT 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_EXT 0x80DF +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B + +typedef void (GLAPIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void* data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void* data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); + +#define glColorTableEXT GLEW_GET_FUN(__glewColorTableEXT) +#define glGetColorTableEXT GLEW_GET_FUN(__glewGetColorTableEXT) +#define glGetColorTableParameterfvEXT GLEW_GET_FUN(__glewGetColorTableParameterfvEXT) +#define glGetColorTableParameterivEXT GLEW_GET_FUN(__glewGetColorTableParameterivEXT) + +#define GLEW_EXT_paletted_texture GLEW_GET_VAR(__GLEW_EXT_paletted_texture) + +#endif /* GL_EXT_paletted_texture */ + +/* ----------------------- GL_EXT_pixel_buffer_object ---------------------- */ + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object 1 + +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF + +#define GLEW_EXT_pixel_buffer_object GLEW_GET_VAR(__GLEW_EXT_pixel_buffer_object) + +#endif /* GL_EXT_pixel_buffer_object */ + +/* ------------------------- GL_EXT_pixel_transform ------------------------ */ + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 + +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 + +typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glGetPixelTransformParameterfvEXT GLEW_GET_FUN(__glewGetPixelTransformParameterfvEXT) +#define glGetPixelTransformParameterivEXT GLEW_GET_FUN(__glewGetPixelTransformParameterivEXT) +#define glPixelTransformParameterfEXT GLEW_GET_FUN(__glewPixelTransformParameterfEXT) +#define glPixelTransformParameterfvEXT GLEW_GET_FUN(__glewPixelTransformParameterfvEXT) +#define glPixelTransformParameteriEXT GLEW_GET_FUN(__glewPixelTransformParameteriEXT) +#define glPixelTransformParameterivEXT GLEW_GET_FUN(__glewPixelTransformParameterivEXT) + +#define GLEW_EXT_pixel_transform GLEW_GET_VAR(__GLEW_EXT_pixel_transform) + +#endif /* GL_EXT_pixel_transform */ + +/* ------------------- GL_EXT_pixel_transform_color_table ------------------ */ + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 + +#define GLEW_EXT_pixel_transform_color_table GLEW_GET_VAR(__GLEW_EXT_pixel_transform_color_table) + +#endif /* GL_EXT_pixel_transform_color_table */ + +/* ------------------------ GL_EXT_point_parameters ------------------------ */ + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 + +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params); + +#define glPointParameterfEXT GLEW_GET_FUN(__glewPointParameterfEXT) +#define glPointParameterfvEXT GLEW_GET_FUN(__glewPointParameterfvEXT) + +#define GLEW_EXT_point_parameters GLEW_GET_VAR(__GLEW_EXT_point_parameters) + +#endif /* GL_EXT_point_parameters */ + +/* ------------------------- GL_EXT_polygon_offset ------------------------- */ + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 + +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 + +typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); + +#define glPolygonOffsetEXT GLEW_GET_FUN(__glewPolygonOffsetEXT) + +#define GLEW_EXT_polygon_offset GLEW_GET_VAR(__GLEW_EXT_polygon_offset) + +#endif /* GL_EXT_polygon_offset */ + +/* ------------------------ GL_EXT_provoking_vertex ------------------------ */ + +#ifndef GL_EXT_provoking_vertex +#define GL_EXT_provoking_vertex 1 + +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_PROVOKING_VERTEX_EXT 0x8E4F + +typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode); + +#define glProvokingVertexEXT GLEW_GET_FUN(__glewProvokingVertexEXT) + +#define GLEW_EXT_provoking_vertex GLEW_GET_VAR(__GLEW_EXT_provoking_vertex) + +#endif /* GL_EXT_provoking_vertex */ + +/* ------------------------- GL_EXT_rescale_normal ------------------------- */ + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 + +#define GL_RESCALE_NORMAL_EXT 0x803A + +#define GLEW_EXT_rescale_normal GLEW_GET_VAR(__GLEW_EXT_rescale_normal) + +#endif /* GL_EXT_rescale_normal */ + +/* -------------------------- GL_EXT_scene_marker -------------------------- */ + +#ifndef GL_EXT_scene_marker +#define GL_EXT_scene_marker 1 + +typedef void (GLAPIENTRY * PFNGLBEGINSCENEEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLENDSCENEEXTPROC) (void); + +#define glBeginSceneEXT GLEW_GET_FUN(__glewBeginSceneEXT) +#define glEndSceneEXT GLEW_GET_FUN(__glewEndSceneEXT) + +#define GLEW_EXT_scene_marker GLEW_GET_VAR(__GLEW_EXT_scene_marker) + +#endif /* GL_EXT_scene_marker */ + +/* ------------------------- GL_EXT_secondary_color ------------------------ */ + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 + +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E + +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); + +#define glSecondaryColor3bEXT GLEW_GET_FUN(__glewSecondaryColor3bEXT) +#define glSecondaryColor3bvEXT GLEW_GET_FUN(__glewSecondaryColor3bvEXT) +#define glSecondaryColor3dEXT GLEW_GET_FUN(__glewSecondaryColor3dEXT) +#define glSecondaryColor3dvEXT GLEW_GET_FUN(__glewSecondaryColor3dvEXT) +#define glSecondaryColor3fEXT GLEW_GET_FUN(__glewSecondaryColor3fEXT) +#define glSecondaryColor3fvEXT GLEW_GET_FUN(__glewSecondaryColor3fvEXT) +#define glSecondaryColor3iEXT GLEW_GET_FUN(__glewSecondaryColor3iEXT) +#define glSecondaryColor3ivEXT GLEW_GET_FUN(__glewSecondaryColor3ivEXT) +#define glSecondaryColor3sEXT GLEW_GET_FUN(__glewSecondaryColor3sEXT) +#define glSecondaryColor3svEXT GLEW_GET_FUN(__glewSecondaryColor3svEXT) +#define glSecondaryColor3ubEXT GLEW_GET_FUN(__glewSecondaryColor3ubEXT) +#define glSecondaryColor3ubvEXT GLEW_GET_FUN(__glewSecondaryColor3ubvEXT) +#define glSecondaryColor3uiEXT GLEW_GET_FUN(__glewSecondaryColor3uiEXT) +#define glSecondaryColor3uivEXT GLEW_GET_FUN(__glewSecondaryColor3uivEXT) +#define glSecondaryColor3usEXT GLEW_GET_FUN(__glewSecondaryColor3usEXT) +#define glSecondaryColor3usvEXT GLEW_GET_FUN(__glewSecondaryColor3usvEXT) +#define glSecondaryColorPointerEXT GLEW_GET_FUN(__glewSecondaryColorPointerEXT) + +#define GLEW_EXT_secondary_color GLEW_GET_VAR(__GLEW_EXT_secondary_color) + +#endif /* GL_EXT_secondary_color */ + +/* --------------------- GL_EXT_separate_shader_objects -------------------- */ + +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 + +#define GL_ACTIVE_PROGRAM_EXT 0x8B8D + +typedef void (GLAPIENTRY * PFNGLACTIVEPROGRAMEXTPROC) (GLuint program); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const char* string); +typedef void (GLAPIENTRY * PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program); + +#define glActiveProgramEXT GLEW_GET_FUN(__glewActiveProgramEXT) +#define glCreateShaderProgramEXT GLEW_GET_FUN(__glewCreateShaderProgramEXT) +#define glUseShaderProgramEXT GLEW_GET_FUN(__glewUseShaderProgramEXT) + +#define GLEW_EXT_separate_shader_objects GLEW_GET_VAR(__GLEW_EXT_separate_shader_objects) + +#endif /* GL_EXT_separate_shader_objects */ + +/* --------------------- GL_EXT_separate_specular_color -------------------- */ + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 + +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA + +#define GLEW_EXT_separate_specular_color GLEW_GET_VAR(__GLEW_EXT_separate_specular_color) + +#endif /* GL_EXT_separate_specular_color */ + +/* --------------------- GL_EXT_shader_image_load_store -------------------- */ + +#ifndef GL_EXT_shader_image_load_store +#define GL_EXT_shader_image_load_store 1 + +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 +#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 +#define GL_MAX_IMAGE_UNITS_EXT 0x8F38 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 +#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A +#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B +#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C +#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D +#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E +#define GL_IMAGE_1D_EXT 0x904C +#define GL_IMAGE_2D_EXT 0x904D +#define GL_IMAGE_3D_EXT 0x904E +#define GL_IMAGE_2D_RECT_EXT 0x904F +#define GL_IMAGE_CUBE_EXT 0x9050 +#define GL_IMAGE_BUFFER_EXT 0x9051 +#define GL_IMAGE_1D_ARRAY_EXT 0x9052 +#define GL_IMAGE_2D_ARRAY_EXT 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 +#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 +#define GL_INT_IMAGE_1D_EXT 0x9057 +#define GL_INT_IMAGE_2D_EXT 0x9058 +#define GL_INT_IMAGE_3D_EXT 0x9059 +#define GL_INT_IMAGE_2D_RECT_EXT 0x905A +#define GL_INT_IMAGE_CUBE_EXT 0x905B +#define GL_INT_IMAGE_BUFFER_EXT 0x905C +#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D +#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F +#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C +#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D +#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E +#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); +typedef void (GLAPIENTRY * PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers); + +#define glBindImageTextureEXT GLEW_GET_FUN(__glewBindImageTextureEXT) +#define glMemoryBarrierEXT GLEW_GET_FUN(__glewMemoryBarrierEXT) + +#define GLEW_EXT_shader_image_load_store GLEW_GET_VAR(__GLEW_EXT_shader_image_load_store) + +#endif /* GL_EXT_shader_image_load_store */ + +/* -------------------------- GL_EXT_shadow_funcs -------------------------- */ + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 + +#define GLEW_EXT_shadow_funcs GLEW_GET_VAR(__GLEW_EXT_shadow_funcs) + +#endif /* GL_EXT_shadow_funcs */ + +/* --------------------- GL_EXT_shared_texture_palette --------------------- */ + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 + +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB + +#define GLEW_EXT_shared_texture_palette GLEW_GET_VAR(__GLEW_EXT_shared_texture_palette) + +#endif /* GL_EXT_shared_texture_palette */ + +/* ------------------------ GL_EXT_stencil_clear_tag ----------------------- */ + +#ifndef GL_EXT_stencil_clear_tag +#define GL_EXT_stencil_clear_tag 1 + +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 + +#define GLEW_EXT_stencil_clear_tag GLEW_GET_VAR(__GLEW_EXT_stencil_clear_tag) + +#endif /* GL_EXT_stencil_clear_tag */ + +/* ------------------------ GL_EXT_stencil_two_side ------------------------ */ + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 + +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 + +typedef void (GLAPIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); + +#define glActiveStencilFaceEXT GLEW_GET_FUN(__glewActiveStencilFaceEXT) + +#define GLEW_EXT_stencil_two_side GLEW_GET_VAR(__GLEW_EXT_stencil_two_side) + +#endif /* GL_EXT_stencil_two_side */ + +/* -------------------------- GL_EXT_stencil_wrap -------------------------- */ + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 + +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 + +#define GLEW_EXT_stencil_wrap GLEW_GET_VAR(__GLEW_EXT_stencil_wrap) + +#endif /* GL_EXT_stencil_wrap */ + +/* --------------------------- GL_EXT_subtexture --------------------------- */ + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 + +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); + +#define glTexSubImage1DEXT GLEW_GET_FUN(__glewTexSubImage1DEXT) +#define glTexSubImage2DEXT GLEW_GET_FUN(__glewTexSubImage2DEXT) +#define glTexSubImage3DEXT GLEW_GET_FUN(__glewTexSubImage3DEXT) + +#define GLEW_EXT_subtexture GLEW_GET_VAR(__GLEW_EXT_subtexture) + +#endif /* GL_EXT_subtexture */ + +/* ----------------------------- GL_EXT_texture ---------------------------- */ + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 + +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 + +#define GLEW_EXT_texture GLEW_GET_VAR(__GLEW_EXT_texture) + +#endif /* GL_EXT_texture */ + +/* ---------------------------- GL_EXT_texture3D --------------------------- */ + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 + +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); + +#define glTexImage3DEXT GLEW_GET_FUN(__glewTexImage3DEXT) + +#define GLEW_EXT_texture3D GLEW_GET_VAR(__GLEW_EXT_texture3D) + +#endif /* GL_EXT_texture3D */ + +/* -------------------------- GL_EXT_texture_array ------------------------- */ + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array 1 + +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D + +#define GLEW_EXT_texture_array GLEW_GET_VAR(__GLEW_EXT_texture_array) + +#endif /* GL_EXT_texture_array */ + +/* ---------------------- GL_EXT_texture_buffer_object --------------------- */ + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object 1 + +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E + +typedef void (GLAPIENTRY * PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); + +#define glTexBufferEXT GLEW_GET_FUN(__glewTexBufferEXT) + +#define GLEW_EXT_texture_buffer_object GLEW_GET_VAR(__GLEW_EXT_texture_buffer_object) + +#endif /* GL_EXT_texture_buffer_object */ + +/* -------------------- GL_EXT_texture_compression_dxt1 -------------------- */ + +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 + +#define GLEW_EXT_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_EXT_texture_compression_dxt1) + +#endif /* GL_EXT_texture_compression_dxt1 */ + +/* -------------------- GL_EXT_texture_compression_latc -------------------- */ + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc 1 + +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 + +#define GLEW_EXT_texture_compression_latc GLEW_GET_VAR(__GLEW_EXT_texture_compression_latc) + +#endif /* GL_EXT_texture_compression_latc */ + +/* -------------------- GL_EXT_texture_compression_rgtc -------------------- */ + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc 1 + +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE + +#define GLEW_EXT_texture_compression_rgtc GLEW_GET_VAR(__GLEW_EXT_texture_compression_rgtc) + +#endif /* GL_EXT_texture_compression_rgtc */ + +/* -------------------- GL_EXT_texture_compression_s3tc -------------------- */ + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 + +#define GLEW_EXT_texture_compression_s3tc GLEW_GET_VAR(__GLEW_EXT_texture_compression_s3tc) + +#endif /* GL_EXT_texture_compression_s3tc */ + +/* ------------------------ GL_EXT_texture_cube_map ------------------------ */ + +#ifndef GL_EXT_texture_cube_map +#define GL_EXT_texture_cube_map 1 + +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C + +#define GLEW_EXT_texture_cube_map GLEW_GET_VAR(__GLEW_EXT_texture_cube_map) + +#endif /* GL_EXT_texture_cube_map */ + +/* ----------------------- GL_EXT_texture_edge_clamp ----------------------- */ + +#ifndef GL_EXT_texture_edge_clamp +#define GL_EXT_texture_edge_clamp 1 + +#define GL_CLAMP_TO_EDGE_EXT 0x812F + +#define GLEW_EXT_texture_edge_clamp GLEW_GET_VAR(__GLEW_EXT_texture_edge_clamp) + +#endif /* GL_EXT_texture_edge_clamp */ + +/* --------------------------- GL_EXT_texture_env -------------------------- */ + +#ifndef GL_EXT_texture_env +#define GL_EXT_texture_env 1 + +#define GL_TEXTURE_ENV0_EXT 0 +#define GL_ENV_BLEND_EXT 0 +#define GL_TEXTURE_ENV_SHIFT_EXT 0 +#define GL_ENV_REPLACE_EXT 0 +#define GL_ENV_ADD_EXT 0 +#define GL_ENV_SUBTRACT_EXT 0 +#define GL_TEXTURE_ENV_MODE_ALPHA_EXT 0 +#define GL_ENV_REVERSE_SUBTRACT_EXT 0 +#define GL_ENV_REVERSE_BLEND_EXT 0 +#define GL_ENV_COPY_EXT 0 +#define GL_ENV_MODULATE_EXT 0 + +#define GLEW_EXT_texture_env GLEW_GET_VAR(__GLEW_EXT_texture_env) + +#endif /* GL_EXT_texture_env */ + +/* ------------------------- GL_EXT_texture_env_add ------------------------ */ + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 + +#define GLEW_EXT_texture_env_add GLEW_GET_VAR(__GLEW_EXT_texture_env_add) + +#endif /* GL_EXT_texture_env_add */ + +/* ----------------------- GL_EXT_texture_env_combine ---------------------- */ + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 + +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A + +#define GLEW_EXT_texture_env_combine GLEW_GET_VAR(__GLEW_EXT_texture_env_combine) + +#endif /* GL_EXT_texture_env_combine */ + +/* ------------------------ GL_EXT_texture_env_dot3 ------------------------ */ + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 + +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 + +#define GLEW_EXT_texture_env_dot3 GLEW_GET_VAR(__GLEW_EXT_texture_env_dot3) + +#endif /* GL_EXT_texture_env_dot3 */ + +/* ------------------- GL_EXT_texture_filter_anisotropic ------------------- */ + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 + +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF + +#define GLEW_EXT_texture_filter_anisotropic GLEW_GET_VAR(__GLEW_EXT_texture_filter_anisotropic) + +#endif /* GL_EXT_texture_filter_anisotropic */ + +/* ------------------------- GL_EXT_texture_integer ------------------------ */ + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer 1 + +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E + +typedef void (GLAPIENTRY * PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (GLAPIENTRY * PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); + +#define glClearColorIiEXT GLEW_GET_FUN(__glewClearColorIiEXT) +#define glClearColorIuiEXT GLEW_GET_FUN(__glewClearColorIuiEXT) +#define glGetTexParameterIivEXT GLEW_GET_FUN(__glewGetTexParameterIivEXT) +#define glGetTexParameterIuivEXT GLEW_GET_FUN(__glewGetTexParameterIuivEXT) +#define glTexParameterIivEXT GLEW_GET_FUN(__glewTexParameterIivEXT) +#define glTexParameterIuivEXT GLEW_GET_FUN(__glewTexParameterIuivEXT) + +#define GLEW_EXT_texture_integer GLEW_GET_VAR(__GLEW_EXT_texture_integer) + +#endif /* GL_EXT_texture_integer */ + +/* ------------------------ GL_EXT_texture_lod_bias ------------------------ */ + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 + +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 + +#define GLEW_EXT_texture_lod_bias GLEW_GET_VAR(__GLEW_EXT_texture_lod_bias) + +#endif /* GL_EXT_texture_lod_bias */ + +/* ---------------------- GL_EXT_texture_mirror_clamp ---------------------- */ + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp 1 + +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 + +#define GLEW_EXT_texture_mirror_clamp GLEW_GET_VAR(__GLEW_EXT_texture_mirror_clamp) + +#endif /* GL_EXT_texture_mirror_clamp */ + +/* ------------------------- GL_EXT_texture_object ------------------------- */ + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 + +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A + +typedef GLboolean (GLAPIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint* textures, GLboolean* residences); +typedef void (GLAPIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (GLAPIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint* textures); +typedef void (GLAPIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint* textures); +typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (GLAPIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint* textures, const GLclampf* priorities); + +#define glAreTexturesResidentEXT GLEW_GET_FUN(__glewAreTexturesResidentEXT) +#define glBindTextureEXT GLEW_GET_FUN(__glewBindTextureEXT) +#define glDeleteTexturesEXT GLEW_GET_FUN(__glewDeleteTexturesEXT) +#define glGenTexturesEXT GLEW_GET_FUN(__glewGenTexturesEXT) +#define glIsTextureEXT GLEW_GET_FUN(__glewIsTextureEXT) +#define glPrioritizeTexturesEXT GLEW_GET_FUN(__glewPrioritizeTexturesEXT) + +#define GLEW_EXT_texture_object GLEW_GET_VAR(__GLEW_EXT_texture_object) + +#endif /* GL_EXT_texture_object */ + +/* --------------------- GL_EXT_texture_perturb_normal --------------------- */ + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 + +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF + +typedef void (GLAPIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode); + +#define glTextureNormalEXT GLEW_GET_FUN(__glewTextureNormalEXT) + +#define GLEW_EXT_texture_perturb_normal GLEW_GET_VAR(__GLEW_EXT_texture_perturb_normal) + +#endif /* GL_EXT_texture_perturb_normal */ + +/* ------------------------ GL_EXT_texture_rectangle ----------------------- */ + +#ifndef GL_EXT_texture_rectangle +#define GL_EXT_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_EXT 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_EXT 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_EXT 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT 0x84F8 + +#define GLEW_EXT_texture_rectangle GLEW_GET_VAR(__GLEW_EXT_texture_rectangle) + +#endif /* GL_EXT_texture_rectangle */ + +/* -------------------------- GL_EXT_texture_sRGB -------------------------- */ + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB 1 + +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F + +#define GLEW_EXT_texture_sRGB GLEW_GET_VAR(__GLEW_EXT_texture_sRGB) + +#endif /* GL_EXT_texture_sRGB */ + +/* --------------------- GL_EXT_texture_shared_exponent -------------------- */ + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent 1 + +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F + +#define GLEW_EXT_texture_shared_exponent GLEW_GET_VAR(__GLEW_EXT_texture_shared_exponent) + +#endif /* GL_EXT_texture_shared_exponent */ + +/* -------------------------- GL_EXT_texture_snorm ------------------------- */ + +#ifndef GL_EXT_texture_snorm +#define GL_EXT_texture_snorm 1 + +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_ALPHA_SNORM 0x9010 +#define GL_LUMINANCE_SNORM 0x9011 +#define GL_LUMINANCE_ALPHA_SNORM 0x9012 +#define GL_INTENSITY_SNORM 0x9013 +#define GL_ALPHA8_SNORM 0x9014 +#define GL_LUMINANCE8_SNORM 0x9015 +#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 +#define GL_INTENSITY8_SNORM 0x9017 +#define GL_ALPHA16_SNORM 0x9018 +#define GL_LUMINANCE16_SNORM 0x9019 +#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A +#define GL_INTENSITY16_SNORM 0x901B + +#define GLEW_EXT_texture_snorm GLEW_GET_VAR(__GLEW_EXT_texture_snorm) + +#endif /* GL_EXT_texture_snorm */ + +/* ------------------------- GL_EXT_texture_swizzle ------------------------ */ + +#ifndef GL_EXT_texture_swizzle +#define GL_EXT_texture_swizzle 1 + +#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 +#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 +#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 +#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 + +#define GLEW_EXT_texture_swizzle GLEW_GET_VAR(__GLEW_EXT_texture_swizzle) + +#endif /* GL_EXT_texture_swizzle */ + +/* --------------------------- GL_EXT_timer_query -------------------------- */ + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query 1 + +#define GL_TIME_ELAPSED_EXT 0x88BF + +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); + +#define glGetQueryObjecti64vEXT GLEW_GET_FUN(__glewGetQueryObjecti64vEXT) +#define glGetQueryObjectui64vEXT GLEW_GET_FUN(__glewGetQueryObjectui64vEXT) + +#define GLEW_EXT_timer_query GLEW_GET_VAR(__GLEW_EXT_timer_query) + +#endif /* GL_EXT_timer_query */ + +/* ----------------------- GL_EXT_transform_feedback ----------------------- */ + +#ifndef GL_EXT_transform_feedback +#define GL_EXT_transform_feedback 1 + +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 +#define GL_RASTERIZER_DISCARD_EXT 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C +#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F + +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei *size, GLenum *type, char *name); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const char ** varyings, GLenum bufferMode); + +#define glBeginTransformFeedbackEXT GLEW_GET_FUN(__glewBeginTransformFeedbackEXT) +#define glBindBufferBaseEXT GLEW_GET_FUN(__glewBindBufferBaseEXT) +#define glBindBufferOffsetEXT GLEW_GET_FUN(__glewBindBufferOffsetEXT) +#define glBindBufferRangeEXT GLEW_GET_FUN(__glewBindBufferRangeEXT) +#define glEndTransformFeedbackEXT GLEW_GET_FUN(__glewEndTransformFeedbackEXT) +#define glGetTransformFeedbackVaryingEXT GLEW_GET_FUN(__glewGetTransformFeedbackVaryingEXT) +#define glTransformFeedbackVaryingsEXT GLEW_GET_FUN(__glewTransformFeedbackVaryingsEXT) + +#define GLEW_EXT_transform_feedback GLEW_GET_VAR(__GLEW_EXT_transform_feedback) + +#endif /* GL_EXT_transform_feedback */ + +/* -------------------------- GL_EXT_vertex_array -------------------------- */ + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 + +#define GL_DOUBLE_EXT 0x140A +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 + +typedef void (GLAPIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (GLAPIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean* pointer); +typedef void (GLAPIENTRY * PFNGLGETPOINTERVEXTPROC) (GLenum pname, void** params); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); + +#define glArrayElementEXT GLEW_GET_FUN(__glewArrayElementEXT) +#define glColorPointerEXT GLEW_GET_FUN(__glewColorPointerEXT) +#define glDrawArraysEXT GLEW_GET_FUN(__glewDrawArraysEXT) +#define glEdgeFlagPointerEXT GLEW_GET_FUN(__glewEdgeFlagPointerEXT) +#define glGetPointervEXT GLEW_GET_FUN(__glewGetPointervEXT) +#define glIndexPointerEXT GLEW_GET_FUN(__glewIndexPointerEXT) +#define glNormalPointerEXT GLEW_GET_FUN(__glewNormalPointerEXT) +#define glTexCoordPointerEXT GLEW_GET_FUN(__glewTexCoordPointerEXT) +#define glVertexPointerEXT GLEW_GET_FUN(__glewVertexPointerEXT) + +#define GLEW_EXT_vertex_array GLEW_GET_VAR(__GLEW_EXT_vertex_array) + +#endif /* GL_EXT_vertex_array */ + +/* ------------------------ GL_EXT_vertex_array_bgra ----------------------- */ + +#ifndef GL_EXT_vertex_array_bgra +#define GL_EXT_vertex_array_bgra 1 + +#define GL_BGRA 0x80E1 + +#define GLEW_EXT_vertex_array_bgra GLEW_GET_VAR(__GLEW_EXT_vertex_array_bgra) + +#endif /* GL_EXT_vertex_array_bgra */ + +/* ----------------------- GL_EXT_vertex_attrib_64bit ---------------------- */ + +#ifndef GL_EXT_vertex_attrib_64bit +#define GL_EXT_vertex_attrib_64bit 1 + +#define GL_DOUBLE_MAT2_EXT 0x8F46 +#define GL_DOUBLE_MAT3_EXT 0x8F47 +#define GL_DOUBLE_MAT4_EXT 0x8F48 +#define GL_DOUBLE_VEC2_EXT 0x8FFC +#define GL_DOUBLE_VEC3_EXT 0x8FFD +#define GL_DOUBLE_VEC4_EXT 0x8FFE + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); + +#define glGetVertexAttribLdvEXT GLEW_GET_FUN(__glewGetVertexAttribLdvEXT) +#define glVertexArrayVertexAttribLOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribLOffsetEXT) +#define glVertexAttribL1dEXT GLEW_GET_FUN(__glewVertexAttribL1dEXT) +#define glVertexAttribL1dvEXT GLEW_GET_FUN(__glewVertexAttribL1dvEXT) +#define glVertexAttribL2dEXT GLEW_GET_FUN(__glewVertexAttribL2dEXT) +#define glVertexAttribL2dvEXT GLEW_GET_FUN(__glewVertexAttribL2dvEXT) +#define glVertexAttribL3dEXT GLEW_GET_FUN(__glewVertexAttribL3dEXT) +#define glVertexAttribL3dvEXT GLEW_GET_FUN(__glewVertexAttribL3dvEXT) +#define glVertexAttribL4dEXT GLEW_GET_FUN(__glewVertexAttribL4dEXT) +#define glVertexAttribL4dvEXT GLEW_GET_FUN(__glewVertexAttribL4dvEXT) +#define glVertexAttribLPointerEXT GLEW_GET_FUN(__glewVertexAttribLPointerEXT) + +#define GLEW_EXT_vertex_attrib_64bit GLEW_GET_VAR(__GLEW_EXT_vertex_attrib_64bit) + +#endif /* GL_EXT_vertex_attrib_64bit */ + +/* -------------------------- GL_EXT_vertex_shader ------------------------- */ + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 + +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED + +typedef void (GLAPIENTRY * PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef void (GLAPIENTRY * PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (GLAPIENTRY * PFNGLGENSYMBOLSEXTPROC) (GLenum dataType, GLenum storageType, GLenum range, GLuint components); +typedef GLuint (GLAPIENTRY * PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid **data); +typedef void (GLAPIENTRY * PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLboolean (GLAPIENTRY * PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (GLAPIENTRY * PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (GLAPIENTRY * PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (GLAPIENTRY * PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (GLAPIENTRY * PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (GLAPIENTRY * PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTBVEXTPROC) (GLuint id, GLbyte *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTDVEXTPROC) (GLuint id, GLdouble *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTFVEXTPROC) (GLuint id, GLfloat *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTIVEXTPROC) (GLuint id, GLint *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTSVEXTPROC) (GLuint id, GLshort *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUBVEXTPROC) (GLuint id, GLubyte *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUIVEXTPROC) (GLuint id, GLuint *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUSVEXTPROC) (GLuint id, GLushort *addr); +typedef void (GLAPIENTRY * PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); + +#define glBeginVertexShaderEXT GLEW_GET_FUN(__glewBeginVertexShaderEXT) +#define glBindLightParameterEXT GLEW_GET_FUN(__glewBindLightParameterEXT) +#define glBindMaterialParameterEXT GLEW_GET_FUN(__glewBindMaterialParameterEXT) +#define glBindParameterEXT GLEW_GET_FUN(__glewBindParameterEXT) +#define glBindTexGenParameterEXT GLEW_GET_FUN(__glewBindTexGenParameterEXT) +#define glBindTextureUnitParameterEXT GLEW_GET_FUN(__glewBindTextureUnitParameterEXT) +#define glBindVertexShaderEXT GLEW_GET_FUN(__glewBindVertexShaderEXT) +#define glDeleteVertexShaderEXT GLEW_GET_FUN(__glewDeleteVertexShaderEXT) +#define glDisableVariantClientStateEXT GLEW_GET_FUN(__glewDisableVariantClientStateEXT) +#define glEnableVariantClientStateEXT GLEW_GET_FUN(__glewEnableVariantClientStateEXT) +#define glEndVertexShaderEXT GLEW_GET_FUN(__glewEndVertexShaderEXT) +#define glExtractComponentEXT GLEW_GET_FUN(__glewExtractComponentEXT) +#define glGenSymbolsEXT GLEW_GET_FUN(__glewGenSymbolsEXT) +#define glGenVertexShadersEXT GLEW_GET_FUN(__glewGenVertexShadersEXT) +#define glGetInvariantBooleanvEXT GLEW_GET_FUN(__glewGetInvariantBooleanvEXT) +#define glGetInvariantFloatvEXT GLEW_GET_FUN(__glewGetInvariantFloatvEXT) +#define glGetInvariantIntegervEXT GLEW_GET_FUN(__glewGetInvariantIntegervEXT) +#define glGetLocalConstantBooleanvEXT GLEW_GET_FUN(__glewGetLocalConstantBooleanvEXT) +#define glGetLocalConstantFloatvEXT GLEW_GET_FUN(__glewGetLocalConstantFloatvEXT) +#define glGetLocalConstantIntegervEXT GLEW_GET_FUN(__glewGetLocalConstantIntegervEXT) +#define glGetVariantBooleanvEXT GLEW_GET_FUN(__glewGetVariantBooleanvEXT) +#define glGetVariantFloatvEXT GLEW_GET_FUN(__glewGetVariantFloatvEXT) +#define glGetVariantIntegervEXT GLEW_GET_FUN(__glewGetVariantIntegervEXT) +#define glGetVariantPointervEXT GLEW_GET_FUN(__glewGetVariantPointervEXT) +#define glInsertComponentEXT GLEW_GET_FUN(__glewInsertComponentEXT) +#define glIsVariantEnabledEXT GLEW_GET_FUN(__glewIsVariantEnabledEXT) +#define glSetInvariantEXT GLEW_GET_FUN(__glewSetInvariantEXT) +#define glSetLocalConstantEXT GLEW_GET_FUN(__glewSetLocalConstantEXT) +#define glShaderOp1EXT GLEW_GET_FUN(__glewShaderOp1EXT) +#define glShaderOp2EXT GLEW_GET_FUN(__glewShaderOp2EXT) +#define glShaderOp3EXT GLEW_GET_FUN(__glewShaderOp3EXT) +#define glSwizzleEXT GLEW_GET_FUN(__glewSwizzleEXT) +#define glVariantPointerEXT GLEW_GET_FUN(__glewVariantPointerEXT) +#define glVariantbvEXT GLEW_GET_FUN(__glewVariantbvEXT) +#define glVariantdvEXT GLEW_GET_FUN(__glewVariantdvEXT) +#define glVariantfvEXT GLEW_GET_FUN(__glewVariantfvEXT) +#define glVariantivEXT GLEW_GET_FUN(__glewVariantivEXT) +#define glVariantsvEXT GLEW_GET_FUN(__glewVariantsvEXT) +#define glVariantubvEXT GLEW_GET_FUN(__glewVariantubvEXT) +#define glVariantuivEXT GLEW_GET_FUN(__glewVariantuivEXT) +#define glVariantusvEXT GLEW_GET_FUN(__glewVariantusvEXT) +#define glWriteMaskEXT GLEW_GET_FUN(__glewWriteMaskEXT) + +#define GLEW_EXT_vertex_shader GLEW_GET_VAR(__GLEW_EXT_vertex_shader) + +#endif /* GL_EXT_vertex_shader */ + +/* ------------------------ GL_EXT_vertex_weighting ------------------------ */ + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 + +#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 +#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 +#define GL_MODELVIEW0_EXT 0x1700 +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 + +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (GLfloat* weight); + +#define glVertexWeightPointerEXT GLEW_GET_FUN(__glewVertexWeightPointerEXT) +#define glVertexWeightfEXT GLEW_GET_FUN(__glewVertexWeightfEXT) +#define glVertexWeightfvEXT GLEW_GET_FUN(__glewVertexWeightfvEXT) + +#define GLEW_EXT_vertex_weighting GLEW_GET_VAR(__GLEW_EXT_vertex_weighting) + +#endif /* GL_EXT_vertex_weighting */ + +/* ---------------------- GL_GREMEDY_frame_terminator ---------------------- */ + +#ifndef GL_GREMEDY_frame_terminator +#define GL_GREMEDY_frame_terminator 1 + +typedef void (GLAPIENTRY * PFNGLFRAMETERMINATORGREMEDYPROC) (void); + +#define glFrameTerminatorGREMEDY GLEW_GET_FUN(__glewFrameTerminatorGREMEDY) + +#define GLEW_GREMEDY_frame_terminator GLEW_GET_VAR(__GLEW_GREMEDY_frame_terminator) + +#endif /* GL_GREMEDY_frame_terminator */ + +/* ------------------------ GL_GREMEDY_string_marker ----------------------- */ + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 + +typedef void (GLAPIENTRY * PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void* string); + +#define glStringMarkerGREMEDY GLEW_GET_FUN(__glewStringMarkerGREMEDY) + +#define GLEW_GREMEDY_string_marker GLEW_GET_VAR(__GLEW_GREMEDY_string_marker) + +#endif /* GL_GREMEDY_string_marker */ + +/* --------------------- GL_HP_convolution_border_modes -------------------- */ + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 + +#define GLEW_HP_convolution_border_modes GLEW_GET_VAR(__GLEW_HP_convolution_border_modes) + +#endif /* GL_HP_convolution_border_modes */ + +/* ------------------------- GL_HP_image_transform ------------------------- */ + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 + +typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glGetImageTransformParameterfvHP GLEW_GET_FUN(__glewGetImageTransformParameterfvHP) +#define glGetImageTransformParameterivHP GLEW_GET_FUN(__glewGetImageTransformParameterivHP) +#define glImageTransformParameterfHP GLEW_GET_FUN(__glewImageTransformParameterfHP) +#define glImageTransformParameterfvHP GLEW_GET_FUN(__glewImageTransformParameterfvHP) +#define glImageTransformParameteriHP GLEW_GET_FUN(__glewImageTransformParameteriHP) +#define glImageTransformParameterivHP GLEW_GET_FUN(__glewImageTransformParameterivHP) + +#define GLEW_HP_image_transform GLEW_GET_VAR(__GLEW_HP_image_transform) + +#endif /* GL_HP_image_transform */ + +/* -------------------------- GL_HP_occlusion_test ------------------------- */ + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 + +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 + +#define GLEW_HP_occlusion_test GLEW_GET_VAR(__GLEW_HP_occlusion_test) + +#endif /* GL_HP_occlusion_test */ + +/* ------------------------- GL_HP_texture_lighting ------------------------ */ + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 + +#define GLEW_HP_texture_lighting GLEW_GET_VAR(__GLEW_HP_texture_lighting) + +#endif /* GL_HP_texture_lighting */ + +/* --------------------------- GL_IBM_cull_vertex -------------------------- */ + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 + +#define GL_CULL_VERTEX_IBM 103050 + +#define GLEW_IBM_cull_vertex GLEW_GET_VAR(__GLEW_IBM_cull_vertex) + +#endif /* GL_IBM_cull_vertex */ + +/* ---------------------- GL_IBM_multimode_draw_arrays --------------------- */ + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 + +typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum* mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum* mode, const GLsizei *count, GLenum type, const GLvoid * const *indices, GLsizei primcount, GLint modestride); + +#define glMultiModeDrawArraysIBM GLEW_GET_FUN(__glewMultiModeDrawArraysIBM) +#define glMultiModeDrawElementsIBM GLEW_GET_FUN(__glewMultiModeDrawElementsIBM) + +#define GLEW_IBM_multimode_draw_arrays GLEW_GET_VAR(__GLEW_IBM_multimode_draw_arrays) + +#endif /* GL_IBM_multimode_draw_arrays */ + +/* ------------------------- GL_IBM_rasterpos_clip ------------------------- */ + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 + +#define GL_RASTER_POSITION_UNCLIPPED_IBM 103010 + +#define GLEW_IBM_rasterpos_clip GLEW_GET_VAR(__GLEW_IBM_rasterpos_clip) + +#endif /* GL_IBM_rasterpos_clip */ + +/* --------------------------- GL_IBM_static_data -------------------------- */ + +#ifndef GL_IBM_static_data +#define GL_IBM_static_data 1 + +#define GL_ALL_STATIC_DATA_IBM 103060 +#define GL_STATIC_VERTEX_ARRAY_IBM 103061 + +#define GLEW_IBM_static_data GLEW_GET_VAR(__GLEW_IBM_static_data) + +#endif /* GL_IBM_static_data */ + +/* --------------------- GL_IBM_texture_mirrored_repeat -------------------- */ + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_IBM_texture_mirrored_repeat 1 + +#define GL_MIRRORED_REPEAT_IBM 0x8370 + +#define GLEW_IBM_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_IBM_texture_mirrored_repeat) + +#endif /* GL_IBM_texture_mirrored_repeat */ + +/* ----------------------- GL_IBM_vertex_array_lists ----------------------- */ + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 + +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 + +typedef void (GLAPIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); + +#define glColorPointerListIBM GLEW_GET_FUN(__glewColorPointerListIBM) +#define glEdgeFlagPointerListIBM GLEW_GET_FUN(__glewEdgeFlagPointerListIBM) +#define glFogCoordPointerListIBM GLEW_GET_FUN(__glewFogCoordPointerListIBM) +#define glIndexPointerListIBM GLEW_GET_FUN(__glewIndexPointerListIBM) +#define glNormalPointerListIBM GLEW_GET_FUN(__glewNormalPointerListIBM) +#define glSecondaryColorPointerListIBM GLEW_GET_FUN(__glewSecondaryColorPointerListIBM) +#define glTexCoordPointerListIBM GLEW_GET_FUN(__glewTexCoordPointerListIBM) +#define glVertexPointerListIBM GLEW_GET_FUN(__glewVertexPointerListIBM) + +#define GLEW_IBM_vertex_array_lists GLEW_GET_VAR(__GLEW_IBM_vertex_array_lists) + +#endif /* GL_IBM_vertex_array_lists */ + +/* -------------------------- GL_INGR_color_clamp -------------------------- */ + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 + +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 + +#define GLEW_INGR_color_clamp GLEW_GET_VAR(__GLEW_INGR_color_clamp) + +#endif /* GL_INGR_color_clamp */ + +/* ------------------------- GL_INGR_interlace_read ------------------------ */ + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 + +#define GL_INTERLACE_READ_INGR 0x8568 + +#define GLEW_INGR_interlace_read GLEW_GET_VAR(__GLEW_INGR_interlace_read) + +#endif /* GL_INGR_interlace_read */ + +/* ------------------------ GL_INTEL_parallel_arrays ----------------------- */ + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 + +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 + +typedef void (GLAPIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); + +#define glColorPointervINTEL GLEW_GET_FUN(__glewColorPointervINTEL) +#define glNormalPointervINTEL GLEW_GET_FUN(__glewNormalPointervINTEL) +#define glTexCoordPointervINTEL GLEW_GET_FUN(__glewTexCoordPointervINTEL) +#define glVertexPointervINTEL GLEW_GET_FUN(__glewVertexPointervINTEL) + +#define GLEW_INTEL_parallel_arrays GLEW_GET_VAR(__GLEW_INTEL_parallel_arrays) + +#endif /* GL_INTEL_parallel_arrays */ + +/* ------------------------ GL_INTEL_texture_scissor ----------------------- */ + +#ifndef GL_INTEL_texture_scissor +#define GL_INTEL_texture_scissor 1 + +typedef void (GLAPIENTRY * PFNGLTEXSCISSORFUNCINTELPROC) (GLenum target, GLenum lfunc, GLenum hfunc); +typedef void (GLAPIENTRY * PFNGLTEXSCISSORINTELPROC) (GLenum target, GLclampf tlow, GLclampf thigh); + +#define glTexScissorFuncINTEL GLEW_GET_FUN(__glewTexScissorFuncINTEL) +#define glTexScissorINTEL GLEW_GET_FUN(__glewTexScissorINTEL) + +#define GLEW_INTEL_texture_scissor GLEW_GET_VAR(__GLEW_INTEL_texture_scissor) + +#endif /* GL_INTEL_texture_scissor */ + +/* -------------------------- GL_KTX_buffer_region ------------------------- */ + +#ifndef GL_KTX_buffer_region +#define GL_KTX_buffer_region 1 + +#define GL_KTX_FRONT_REGION 0x0 +#define GL_KTX_BACK_REGION 0x1 +#define GL_KTX_Z_REGION 0x2 +#define GL_KTX_STENCIL_REGION 0x3 + +typedef GLuint (GLAPIENTRY * PFNGLBUFFERREGIONENABLEDEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERREGIONEXTPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERREGIONEXTPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height, GLint xDest, GLint yDest); +typedef GLuint (GLAPIENTRY * PFNGLNEWBUFFERREGIONEXTPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLREADBUFFERREGIONEXTPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height); + +#define glBufferRegionEnabledEXT GLEW_GET_FUN(__glewBufferRegionEnabledEXT) +#define glDeleteBufferRegionEXT GLEW_GET_FUN(__glewDeleteBufferRegionEXT) +#define glDrawBufferRegionEXT GLEW_GET_FUN(__glewDrawBufferRegionEXT) +#define glNewBufferRegionEXT GLEW_GET_FUN(__glewNewBufferRegionEXT) +#define glReadBufferRegionEXT GLEW_GET_FUN(__glewReadBufferRegionEXT) + +#define GLEW_KTX_buffer_region GLEW_GET_VAR(__GLEW_KTX_buffer_region) + +#endif /* GL_KTX_buffer_region */ + +/* ------------------------- GL_MESAX_texture_stack ------------------------ */ + +#ifndef GL_MESAX_texture_stack +#define GL_MESAX_texture_stack 1 + +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E + +#define GLEW_MESAX_texture_stack GLEW_GET_VAR(__GLEW_MESAX_texture_stack) + +#endif /* GL_MESAX_texture_stack */ + +/* -------------------------- GL_MESA_pack_invert -------------------------- */ + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 + +#define GL_PACK_INVERT_MESA 0x8758 + +#define GLEW_MESA_pack_invert GLEW_GET_VAR(__GLEW_MESA_pack_invert) + +#endif /* GL_MESA_pack_invert */ + +/* ------------------------- GL_MESA_resize_buffers ------------------------ */ + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 + +typedef void (GLAPIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void); + +#define glResizeBuffersMESA GLEW_GET_FUN(__glewResizeBuffersMESA) + +#define GLEW_MESA_resize_buffers GLEW_GET_VAR(__GLEW_MESA_resize_buffers) + +#endif /* GL_MESA_resize_buffers */ + +/* --------------------------- GL_MESA_window_pos -------------------------- */ + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 + +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort* p); + +#define glWindowPos2dMESA GLEW_GET_FUN(__glewWindowPos2dMESA) +#define glWindowPos2dvMESA GLEW_GET_FUN(__glewWindowPos2dvMESA) +#define glWindowPos2fMESA GLEW_GET_FUN(__glewWindowPos2fMESA) +#define glWindowPos2fvMESA GLEW_GET_FUN(__glewWindowPos2fvMESA) +#define glWindowPos2iMESA GLEW_GET_FUN(__glewWindowPos2iMESA) +#define glWindowPos2ivMESA GLEW_GET_FUN(__glewWindowPos2ivMESA) +#define glWindowPos2sMESA GLEW_GET_FUN(__glewWindowPos2sMESA) +#define glWindowPos2svMESA GLEW_GET_FUN(__glewWindowPos2svMESA) +#define glWindowPos3dMESA GLEW_GET_FUN(__glewWindowPos3dMESA) +#define glWindowPos3dvMESA GLEW_GET_FUN(__glewWindowPos3dvMESA) +#define glWindowPos3fMESA GLEW_GET_FUN(__glewWindowPos3fMESA) +#define glWindowPos3fvMESA GLEW_GET_FUN(__glewWindowPos3fvMESA) +#define glWindowPos3iMESA GLEW_GET_FUN(__glewWindowPos3iMESA) +#define glWindowPos3ivMESA GLEW_GET_FUN(__glewWindowPos3ivMESA) +#define glWindowPos3sMESA GLEW_GET_FUN(__glewWindowPos3sMESA) +#define glWindowPos3svMESA GLEW_GET_FUN(__glewWindowPos3svMESA) +#define glWindowPos4dMESA GLEW_GET_FUN(__glewWindowPos4dMESA) +#define glWindowPos4dvMESA GLEW_GET_FUN(__glewWindowPos4dvMESA) +#define glWindowPos4fMESA GLEW_GET_FUN(__glewWindowPos4fMESA) +#define glWindowPos4fvMESA GLEW_GET_FUN(__glewWindowPos4fvMESA) +#define glWindowPos4iMESA GLEW_GET_FUN(__glewWindowPos4iMESA) +#define glWindowPos4ivMESA GLEW_GET_FUN(__glewWindowPos4ivMESA) +#define glWindowPos4sMESA GLEW_GET_FUN(__glewWindowPos4sMESA) +#define glWindowPos4svMESA GLEW_GET_FUN(__glewWindowPos4svMESA) + +#define GLEW_MESA_window_pos GLEW_GET_VAR(__GLEW_MESA_window_pos) + +#endif /* GL_MESA_window_pos */ + +/* ------------------------- GL_MESA_ycbcr_texture ------------------------- */ + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture 1 + +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_YCBCR_MESA 0x8757 + +#define GLEW_MESA_ycbcr_texture GLEW_GET_VAR(__GLEW_MESA_ycbcr_texture) + +#endif /* GL_MESA_ycbcr_texture */ + +/* --------------------------- GL_NV_blend_square -------------------------- */ + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 + +#define GLEW_NV_blend_square GLEW_GET_VAR(__GLEW_NV_blend_square) + +#endif /* GL_NV_blend_square */ + +/* ------------------------ GL_NV_conditional_render ----------------------- */ + +#ifndef GL_NV_conditional_render +#define GL_NV_conditional_render 1 + +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 + +typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVPROC) (void); + +#define glBeginConditionalRenderNV GLEW_GET_FUN(__glewBeginConditionalRenderNV) +#define glEndConditionalRenderNV GLEW_GET_FUN(__glewEndConditionalRenderNV) + +#define GLEW_NV_conditional_render GLEW_GET_VAR(__GLEW_NV_conditional_render) + +#endif /* GL_NV_conditional_render */ + +/* ----------------------- GL_NV_copy_depth_to_color ----------------------- */ + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 + +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F + +#define GLEW_NV_copy_depth_to_color GLEW_GET_VAR(__GLEW_NV_copy_depth_to_color) + +#endif /* GL_NV_copy_depth_to_color */ + +/* ---------------------------- GL_NV_copy_image --------------------------- */ + +#ifndef GL_NV_copy_image +#define GL_NV_copy_image 1 + +typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); + +#define glCopyImageSubDataNV GLEW_GET_FUN(__glewCopyImageSubDataNV) + +#define GLEW_NV_copy_image GLEW_GET_VAR(__GLEW_NV_copy_image) + +#endif /* GL_NV_copy_image */ + +/* ------------------------ GL_NV_depth_buffer_float ----------------------- */ + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float 1 + +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF + +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); +typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); + +#define glClearDepthdNV GLEW_GET_FUN(__glewClearDepthdNV) +#define glDepthBoundsdNV GLEW_GET_FUN(__glewDepthBoundsdNV) +#define glDepthRangedNV GLEW_GET_FUN(__glewDepthRangedNV) + +#define GLEW_NV_depth_buffer_float GLEW_GET_VAR(__GLEW_NV_depth_buffer_float) + +#endif /* GL_NV_depth_buffer_float */ + +/* --------------------------- GL_NV_depth_clamp --------------------------- */ + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 + +#define GL_DEPTH_CLAMP_NV 0x864F + +#define GLEW_NV_depth_clamp GLEW_GET_VAR(__GLEW_NV_depth_clamp) + +#endif /* GL_NV_depth_clamp */ + +/* ---------------------- GL_NV_depth_range_unclamped ---------------------- */ + +#ifndef GL_NV_depth_range_unclamped +#define GL_NV_depth_range_unclamped 1 + +#define GL_SAMPLE_COUNT_BITS_NV 0x8864 +#define GL_CURRENT_SAMPLE_COUNT_QUERY_NV 0x8865 +#define GL_QUERY_RESULT_NV 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_NV 0x8867 +#define GL_SAMPLE_COUNT_NV 0x8914 + +#define GLEW_NV_depth_range_unclamped GLEW_GET_VAR(__GLEW_NV_depth_range_unclamped) + +#endif /* GL_NV_depth_range_unclamped */ + +/* ---------------------------- GL_NV_evaluators --------------------------- */ + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 + +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 + +typedef void (GLAPIENTRY * PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void* points); +typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void* points); +typedef void (GLAPIENTRY * PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glEvalMapsNV GLEW_GET_FUN(__glewEvalMapsNV) +#define glGetMapAttribParameterfvNV GLEW_GET_FUN(__glewGetMapAttribParameterfvNV) +#define glGetMapAttribParameterivNV GLEW_GET_FUN(__glewGetMapAttribParameterivNV) +#define glGetMapControlPointsNV GLEW_GET_FUN(__glewGetMapControlPointsNV) +#define glGetMapParameterfvNV GLEW_GET_FUN(__glewGetMapParameterfvNV) +#define glGetMapParameterivNV GLEW_GET_FUN(__glewGetMapParameterivNV) +#define glMapControlPointsNV GLEW_GET_FUN(__glewMapControlPointsNV) +#define glMapParameterfvNV GLEW_GET_FUN(__glewMapParameterfvNV) +#define glMapParameterivNV GLEW_GET_FUN(__glewMapParameterivNV) + +#define GLEW_NV_evaluators GLEW_GET_VAR(__GLEW_NV_evaluators) + +#endif /* GL_NV_evaluators */ + +/* ----------------------- GL_NV_explicit_multisample ---------------------- */ + +#ifndef GL_NV_explicit_multisample +#define GL_NV_explicit_multisample 1 + +#define GL_SAMPLE_POSITION_NV 0x8E50 +#define GL_SAMPLE_MASK_NV 0x8E51 +#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 +#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 +#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 +#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 +#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 +#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 +#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 +#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 + +typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat* val); +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); + +#define glGetMultisamplefvNV GLEW_GET_FUN(__glewGetMultisamplefvNV) +#define glSampleMaskIndexedNV GLEW_GET_FUN(__glewSampleMaskIndexedNV) +#define glTexRenderbufferNV GLEW_GET_FUN(__glewTexRenderbufferNV) + +#define GLEW_NV_explicit_multisample GLEW_GET_VAR(__GLEW_NV_explicit_multisample) + +#endif /* GL_NV_explicit_multisample */ + +/* ------------------------------ GL_NV_fence ------------------------------ */ + +#ifndef GL_NV_fence +#define GL_NV_fence 1 + +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 + +typedef void (GLAPIENTRY * PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint* fences); +typedef void (GLAPIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint* fences); +typedef void (GLAPIENTRY * PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCENVPROC) (GLuint fence); + +#define glDeleteFencesNV GLEW_GET_FUN(__glewDeleteFencesNV) +#define glFinishFenceNV GLEW_GET_FUN(__glewFinishFenceNV) +#define glGenFencesNV GLEW_GET_FUN(__glewGenFencesNV) +#define glGetFenceivNV GLEW_GET_FUN(__glewGetFenceivNV) +#define glIsFenceNV GLEW_GET_FUN(__glewIsFenceNV) +#define glSetFenceNV GLEW_GET_FUN(__glewSetFenceNV) +#define glTestFenceNV GLEW_GET_FUN(__glewTestFenceNV) + +#define GLEW_NV_fence GLEW_GET_VAR(__GLEW_NV_fence) + +#endif /* GL_NV_fence */ + +/* --------------------------- GL_NV_float_buffer -------------------------- */ + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 + +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E + +#define GLEW_NV_float_buffer GLEW_GET_VAR(__GLEW_NV_float_buffer) + +#endif /* GL_NV_float_buffer */ + +/* --------------------------- GL_NV_fog_distance -------------------------- */ + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 + +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C + +#define GLEW_NV_fog_distance GLEW_GET_VAR(__GLEW_NV_fog_distance) + +#endif /* GL_NV_fog_distance */ + +/* ------------------------- GL_NV_fragment_program ------------------------ */ + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 + +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 + +typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble *params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLdouble v[]); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLfloat v[]); + +#define glGetProgramNamedParameterdvNV GLEW_GET_FUN(__glewGetProgramNamedParameterdvNV) +#define glGetProgramNamedParameterfvNV GLEW_GET_FUN(__glewGetProgramNamedParameterfvNV) +#define glProgramNamedParameter4dNV GLEW_GET_FUN(__glewProgramNamedParameter4dNV) +#define glProgramNamedParameter4dvNV GLEW_GET_FUN(__glewProgramNamedParameter4dvNV) +#define glProgramNamedParameter4fNV GLEW_GET_FUN(__glewProgramNamedParameter4fNV) +#define glProgramNamedParameter4fvNV GLEW_GET_FUN(__glewProgramNamedParameter4fvNV) + +#define GLEW_NV_fragment_program GLEW_GET_VAR(__GLEW_NV_fragment_program) + +#endif /* GL_NV_fragment_program */ + +/* ------------------------ GL_NV_fragment_program2 ------------------------ */ + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 1 + +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 + +#define GLEW_NV_fragment_program2 GLEW_GET_VAR(__GLEW_NV_fragment_program2) + +#endif /* GL_NV_fragment_program2 */ + +/* ------------------------ GL_NV_fragment_program4 ------------------------ */ + +#ifndef GL_NV_fragment_program4 +#define GL_NV_fragment_program4 1 + +#define GLEW_NV_fragment_program4 GLEW_GET_VAR(__GLEW_NV_fragment_program4) + +#endif /* GL_NV_fragment_program4 */ + +/* --------------------- GL_NV_fragment_program_option --------------------- */ + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 + +#define GLEW_NV_fragment_program_option GLEW_GET_VAR(__GLEW_NV_fragment_program_option) + +#endif /* GL_NV_fragment_program_option */ + +/* ----------------- GL_NV_framebuffer_multisample_coverage ---------------- */ + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage 1 + +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 + +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleCoverageNV GLEW_GET_FUN(__glewRenderbufferStorageMultisampleCoverageNV) + +#define GLEW_NV_framebuffer_multisample_coverage GLEW_GET_VAR(__GLEW_NV_framebuffer_multisample_coverage) + +#endif /* GL_NV_framebuffer_multisample_coverage */ + +/* ------------------------ GL_NV_geometry_program4 ------------------------ */ + +#ifndef GL_NV_geometry_program4 +#define GL_NV_geometry_program4 1 + +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 + +typedef void (GLAPIENTRY * PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); + +#define glProgramVertexLimitNV GLEW_GET_FUN(__glewProgramVertexLimitNV) + +#define GLEW_NV_geometry_program4 GLEW_GET_VAR(__GLEW_NV_geometry_program4) + +#endif /* GL_NV_geometry_program4 */ + +/* ------------------------- GL_NV_geometry_shader4 ------------------------ */ + +#ifndef GL_NV_geometry_shader4 +#define GL_NV_geometry_shader4 1 + +#define GLEW_NV_geometry_shader4 GLEW_GET_VAR(__GLEW_NV_geometry_shader4) + +#endif /* GL_NV_geometry_shader4 */ + +/* --------------------------- GL_NV_gpu_program4 -------------------------- */ + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 1 + +#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 + +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); + +#define glProgramEnvParameterI4iNV GLEW_GET_FUN(__glewProgramEnvParameterI4iNV) +#define glProgramEnvParameterI4ivNV GLEW_GET_FUN(__glewProgramEnvParameterI4ivNV) +#define glProgramEnvParameterI4uiNV GLEW_GET_FUN(__glewProgramEnvParameterI4uiNV) +#define glProgramEnvParameterI4uivNV GLEW_GET_FUN(__glewProgramEnvParameterI4uivNV) +#define glProgramEnvParametersI4ivNV GLEW_GET_FUN(__glewProgramEnvParametersI4ivNV) +#define glProgramEnvParametersI4uivNV GLEW_GET_FUN(__glewProgramEnvParametersI4uivNV) +#define glProgramLocalParameterI4iNV GLEW_GET_FUN(__glewProgramLocalParameterI4iNV) +#define glProgramLocalParameterI4ivNV GLEW_GET_FUN(__glewProgramLocalParameterI4ivNV) +#define glProgramLocalParameterI4uiNV GLEW_GET_FUN(__glewProgramLocalParameterI4uiNV) +#define glProgramLocalParameterI4uivNV GLEW_GET_FUN(__glewProgramLocalParameterI4uivNV) +#define glProgramLocalParametersI4ivNV GLEW_GET_FUN(__glewProgramLocalParametersI4ivNV) +#define glProgramLocalParametersI4uivNV GLEW_GET_FUN(__glewProgramLocalParametersI4uivNV) + +#define GLEW_NV_gpu_program4 GLEW_GET_VAR(__GLEW_NV_gpu_program4) + +#endif /* GL_NV_gpu_program4 */ + +/* -------------------------- GL_NV_gpu_program4_1 ------------------------- */ + +#ifndef GL_NV_gpu_program4_1 +#define GL_NV_gpu_program4_1 1 + +#define GLEW_NV_gpu_program4_1 GLEW_GET_VAR(__GLEW_NV_gpu_program4_1) + +#endif /* GL_NV_gpu_program4_1 */ + +/* --------------------------- GL_NV_gpu_program5 -------------------------- */ + +#ifndef GL_NV_gpu_program5 +#define GL_NV_gpu_program5 1 + +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_NV 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT_NV 0x00000002 +#define GL_UNIFORM_BARRIER_BIT_NV 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT_NV 0x00000008 +#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_NV 0x00000020 +#define GL_COMMAND_BARRIER_BIT_NV 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT_NV 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT_NV 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT_NV 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT_NV 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_NV 0x00000800 +#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C +#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D +#define GL_ALL_BARRIER_BITS_NV 0xFFFFFFFF + +#define GLEW_NV_gpu_program5 GLEW_GET_VAR(__GLEW_NV_gpu_program5) + +#endif /* GL_NV_gpu_program5 */ + +/* ------------------------- GL_NV_gpu_program_fp64 ------------------------ */ + +#ifndef GL_NV_gpu_program_fp64 +#define GL_NV_gpu_program_fp64 1 + +#define GLEW_NV_gpu_program_fp64 GLEW_GET_VAR(__GLEW_NV_gpu_program_fp64) + +#endif /* GL_NV_gpu_program_fp64 */ + +/* --------------------------- GL_NV_gpu_shader5 --------------------------- */ + +#ifndef GL_NV_gpu_shader5 +#define GL_NV_gpu_shader5 1 + +#define GL_INT64_NV 0x140E +#define GL_UNSIGNED_INT64_NV 0x140F +#define GL_INT8_NV 0x8FE0 +#define GL_INT8_VEC2_NV 0x8FE1 +#define GL_INT8_VEC3_NV 0x8FE2 +#define GL_INT8_VEC4_NV 0x8FE3 +#define GL_INT16_NV 0x8FE4 +#define GL_INT16_VEC2_NV 0x8FE5 +#define GL_INT16_VEC3_NV 0x8FE6 +#define GL_INT16_VEC4_NV 0x8FE7 +#define GL_INT64_VEC2_NV 0x8FE9 +#define GL_INT64_VEC3_NV 0x8FEA +#define GL_INT64_VEC4_NV 0x8FEB +#define GL_UNSIGNED_INT8_NV 0x8FEC +#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED +#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE +#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF +#define GL_UNSIGNED_INT16_NV 0x8FF0 +#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 +#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 +#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 +#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB + +typedef void (GLAPIENTRY * PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); +typedef void (GLAPIENTRY * PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GLAPIENTRY * PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAPIENTRY * PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAPIENTRY * PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); + +#define glGetUniformi64vNV GLEW_GET_FUN(__glewGetUniformi64vNV) +#define glGetUniformui64vNV GLEW_GET_FUN(__glewGetUniformui64vNV) +#define glProgramUniform1i64NV GLEW_GET_FUN(__glewProgramUniform1i64NV) +#define glProgramUniform1i64vNV GLEW_GET_FUN(__glewProgramUniform1i64vNV) +#define glProgramUniform1ui64NV GLEW_GET_FUN(__glewProgramUniform1ui64NV) +#define glProgramUniform1ui64vNV GLEW_GET_FUN(__glewProgramUniform1ui64vNV) +#define glProgramUniform2i64NV GLEW_GET_FUN(__glewProgramUniform2i64NV) +#define glProgramUniform2i64vNV GLEW_GET_FUN(__glewProgramUniform2i64vNV) +#define glProgramUniform2ui64NV GLEW_GET_FUN(__glewProgramUniform2ui64NV) +#define glProgramUniform2ui64vNV GLEW_GET_FUN(__glewProgramUniform2ui64vNV) +#define glProgramUniform3i64NV GLEW_GET_FUN(__glewProgramUniform3i64NV) +#define glProgramUniform3i64vNV GLEW_GET_FUN(__glewProgramUniform3i64vNV) +#define glProgramUniform3ui64NV GLEW_GET_FUN(__glewProgramUniform3ui64NV) +#define glProgramUniform3ui64vNV GLEW_GET_FUN(__glewProgramUniform3ui64vNV) +#define glProgramUniform4i64NV GLEW_GET_FUN(__glewProgramUniform4i64NV) +#define glProgramUniform4i64vNV GLEW_GET_FUN(__glewProgramUniform4i64vNV) +#define glProgramUniform4ui64NV GLEW_GET_FUN(__glewProgramUniform4ui64NV) +#define glProgramUniform4ui64vNV GLEW_GET_FUN(__glewProgramUniform4ui64vNV) +#define glUniform1i64NV GLEW_GET_FUN(__glewUniform1i64NV) +#define glUniform1i64vNV GLEW_GET_FUN(__glewUniform1i64vNV) +#define glUniform1ui64NV GLEW_GET_FUN(__glewUniform1ui64NV) +#define glUniform1ui64vNV GLEW_GET_FUN(__glewUniform1ui64vNV) +#define glUniform2i64NV GLEW_GET_FUN(__glewUniform2i64NV) +#define glUniform2i64vNV GLEW_GET_FUN(__glewUniform2i64vNV) +#define glUniform2ui64NV GLEW_GET_FUN(__glewUniform2ui64NV) +#define glUniform2ui64vNV GLEW_GET_FUN(__glewUniform2ui64vNV) +#define glUniform3i64NV GLEW_GET_FUN(__glewUniform3i64NV) +#define glUniform3i64vNV GLEW_GET_FUN(__glewUniform3i64vNV) +#define glUniform3ui64NV GLEW_GET_FUN(__glewUniform3ui64NV) +#define glUniform3ui64vNV GLEW_GET_FUN(__glewUniform3ui64vNV) +#define glUniform4i64NV GLEW_GET_FUN(__glewUniform4i64NV) +#define glUniform4i64vNV GLEW_GET_FUN(__glewUniform4i64vNV) +#define glUniform4ui64NV GLEW_GET_FUN(__glewUniform4ui64NV) +#define glUniform4ui64vNV GLEW_GET_FUN(__glewUniform4ui64vNV) + +#define GLEW_NV_gpu_shader5 GLEW_GET_VAR(__GLEW_NV_gpu_shader5) + +#endif /* GL_NV_gpu_shader5 */ + +/* ---------------------------- GL_NV_half_float --------------------------- */ + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 + +#define GL_HALF_FLOAT_NV 0x140B + +typedef unsigned short GLhalf; + +typedef void (GLAPIENTRY * PFNGLCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); +typedef void (GLAPIENTRY * PFNGLCOLOR3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLCOLOR4HNVPROC) (GLhalf red, GLhalf green, GLhalf blue, GLhalf alpha); +typedef void (GLAPIENTRY * PFNGLCOLOR4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHNVPROC) (GLhalf fog); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHVNVPROC) (const GLhalf* fog); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalf s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalf s, GLhalf t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r, GLhalf q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLNORMAL3HNVPROC) (GLhalf nx, GLhalf ny, GLhalf nz); +typedef void (GLAPIENTRY * PFNGLNORMAL3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HNVPROC) (GLhalf s); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HNVPROC) (GLhalf s, GLhalf t); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HNVPROC) (GLhalf s, GLhalf t, GLhalf r); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HNVPROC) (GLhalf s, GLhalf t, GLhalf r, GLhalf q); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX2HNVPROC) (GLhalf x, GLhalf y); +typedef void (GLAPIENTRY * PFNGLVERTEX2HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX3HNVPROC) (GLhalf x, GLhalf y, GLhalf z); +typedef void (GLAPIENTRY * PFNGLVERTEX3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX4HNVPROC) (GLhalf x, GLhalf y, GLhalf z, GLhalf w); +typedef void (GLAPIENTRY * PFNGLVERTEX4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalf x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalf x, GLhalf y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z, GLhalf w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHNVPROC) (GLhalf weight); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalf* weight); + +#define glColor3hNV GLEW_GET_FUN(__glewColor3hNV) +#define glColor3hvNV GLEW_GET_FUN(__glewColor3hvNV) +#define glColor4hNV GLEW_GET_FUN(__glewColor4hNV) +#define glColor4hvNV GLEW_GET_FUN(__glewColor4hvNV) +#define glFogCoordhNV GLEW_GET_FUN(__glewFogCoordhNV) +#define glFogCoordhvNV GLEW_GET_FUN(__glewFogCoordhvNV) +#define glMultiTexCoord1hNV GLEW_GET_FUN(__glewMultiTexCoord1hNV) +#define glMultiTexCoord1hvNV GLEW_GET_FUN(__glewMultiTexCoord1hvNV) +#define glMultiTexCoord2hNV GLEW_GET_FUN(__glewMultiTexCoord2hNV) +#define glMultiTexCoord2hvNV GLEW_GET_FUN(__glewMultiTexCoord2hvNV) +#define glMultiTexCoord3hNV GLEW_GET_FUN(__glewMultiTexCoord3hNV) +#define glMultiTexCoord3hvNV GLEW_GET_FUN(__glewMultiTexCoord3hvNV) +#define glMultiTexCoord4hNV GLEW_GET_FUN(__glewMultiTexCoord4hNV) +#define glMultiTexCoord4hvNV GLEW_GET_FUN(__glewMultiTexCoord4hvNV) +#define glNormal3hNV GLEW_GET_FUN(__glewNormal3hNV) +#define glNormal3hvNV GLEW_GET_FUN(__glewNormal3hvNV) +#define glSecondaryColor3hNV GLEW_GET_FUN(__glewSecondaryColor3hNV) +#define glSecondaryColor3hvNV GLEW_GET_FUN(__glewSecondaryColor3hvNV) +#define glTexCoord1hNV GLEW_GET_FUN(__glewTexCoord1hNV) +#define glTexCoord1hvNV GLEW_GET_FUN(__glewTexCoord1hvNV) +#define glTexCoord2hNV GLEW_GET_FUN(__glewTexCoord2hNV) +#define glTexCoord2hvNV GLEW_GET_FUN(__glewTexCoord2hvNV) +#define glTexCoord3hNV GLEW_GET_FUN(__glewTexCoord3hNV) +#define glTexCoord3hvNV GLEW_GET_FUN(__glewTexCoord3hvNV) +#define glTexCoord4hNV GLEW_GET_FUN(__glewTexCoord4hNV) +#define glTexCoord4hvNV GLEW_GET_FUN(__glewTexCoord4hvNV) +#define glVertex2hNV GLEW_GET_FUN(__glewVertex2hNV) +#define glVertex2hvNV GLEW_GET_FUN(__glewVertex2hvNV) +#define glVertex3hNV GLEW_GET_FUN(__glewVertex3hNV) +#define glVertex3hvNV GLEW_GET_FUN(__glewVertex3hvNV) +#define glVertex4hNV GLEW_GET_FUN(__glewVertex4hNV) +#define glVertex4hvNV GLEW_GET_FUN(__glewVertex4hvNV) +#define glVertexAttrib1hNV GLEW_GET_FUN(__glewVertexAttrib1hNV) +#define glVertexAttrib1hvNV GLEW_GET_FUN(__glewVertexAttrib1hvNV) +#define glVertexAttrib2hNV GLEW_GET_FUN(__glewVertexAttrib2hNV) +#define glVertexAttrib2hvNV GLEW_GET_FUN(__glewVertexAttrib2hvNV) +#define glVertexAttrib3hNV GLEW_GET_FUN(__glewVertexAttrib3hNV) +#define glVertexAttrib3hvNV GLEW_GET_FUN(__glewVertexAttrib3hvNV) +#define glVertexAttrib4hNV GLEW_GET_FUN(__glewVertexAttrib4hNV) +#define glVertexAttrib4hvNV GLEW_GET_FUN(__glewVertexAttrib4hvNV) +#define glVertexAttribs1hvNV GLEW_GET_FUN(__glewVertexAttribs1hvNV) +#define glVertexAttribs2hvNV GLEW_GET_FUN(__glewVertexAttribs2hvNV) +#define glVertexAttribs3hvNV GLEW_GET_FUN(__glewVertexAttribs3hvNV) +#define glVertexAttribs4hvNV GLEW_GET_FUN(__glewVertexAttribs4hvNV) +#define glVertexWeighthNV GLEW_GET_FUN(__glewVertexWeighthNV) +#define glVertexWeighthvNV GLEW_GET_FUN(__glewVertexWeighthvNV) + +#define GLEW_NV_half_float GLEW_GET_VAR(__GLEW_NV_half_float) + +#endif /* GL_NV_half_float */ + +/* ------------------------ GL_NV_light_max_exponent ----------------------- */ + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 + +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 + +#define GLEW_NV_light_max_exponent GLEW_GET_VAR(__GLEW_NV_light_max_exponent) + +#endif /* GL_NV_light_max_exponent */ + +/* --------------------- GL_NV_multisample_filter_hint --------------------- */ + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 + +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 + +#define GLEW_NV_multisample_filter_hint GLEW_GET_VAR(__GLEW_NV_multisample_filter_hint) + +#endif /* GL_NV_multisample_filter_hint */ + +/* ------------------------- GL_NV_occlusion_query ------------------------- */ + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 + +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 + +typedef void (GLAPIENTRY * PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); + +#define glBeginOcclusionQueryNV GLEW_GET_FUN(__glewBeginOcclusionQueryNV) +#define glDeleteOcclusionQueriesNV GLEW_GET_FUN(__glewDeleteOcclusionQueriesNV) +#define glEndOcclusionQueryNV GLEW_GET_FUN(__glewEndOcclusionQueryNV) +#define glGenOcclusionQueriesNV GLEW_GET_FUN(__glewGenOcclusionQueriesNV) +#define glGetOcclusionQueryivNV GLEW_GET_FUN(__glewGetOcclusionQueryivNV) +#define glGetOcclusionQueryuivNV GLEW_GET_FUN(__glewGetOcclusionQueryuivNV) +#define glIsOcclusionQueryNV GLEW_GET_FUN(__glewIsOcclusionQueryNV) + +#define GLEW_NV_occlusion_query GLEW_GET_VAR(__GLEW_NV_occlusion_query) + +#endif /* GL_NV_occlusion_query */ + +/* ----------------------- GL_NV_packed_depth_stencil ---------------------- */ + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA + +#define GLEW_NV_packed_depth_stencil GLEW_GET_VAR(__GLEW_NV_packed_depth_stencil) + +#endif /* GL_NV_packed_depth_stencil */ + +/* --------------------- GL_NV_parameter_buffer_object --------------------- */ + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object 1 + +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 + +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); + +#define glProgramBufferParametersIivNV GLEW_GET_FUN(__glewProgramBufferParametersIivNV) +#define glProgramBufferParametersIuivNV GLEW_GET_FUN(__glewProgramBufferParametersIuivNV) +#define glProgramBufferParametersfvNV GLEW_GET_FUN(__glewProgramBufferParametersfvNV) + +#define GLEW_NV_parameter_buffer_object GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object) + +#endif /* GL_NV_parameter_buffer_object */ + +/* --------------------- GL_NV_parameter_buffer_object2 -------------------- */ + +#ifndef GL_NV_parameter_buffer_object2 +#define GL_NV_parameter_buffer_object2 1 + +#define GLEW_NV_parameter_buffer_object2 GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object2) + +#endif /* GL_NV_parameter_buffer_object2 */ + +/* ------------------------- GL_NV_pixel_data_range ------------------------ */ + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 + +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D + +typedef void (GLAPIENTRY * PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, void* pointer); + +#define glFlushPixelDataRangeNV GLEW_GET_FUN(__glewFlushPixelDataRangeNV) +#define glPixelDataRangeNV GLEW_GET_FUN(__glewPixelDataRangeNV) + +#define GLEW_NV_pixel_data_range GLEW_GET_VAR(__GLEW_NV_pixel_data_range) + +#endif /* GL_NV_pixel_data_range */ + +/* --------------------------- GL_NV_point_sprite -------------------------- */ + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 + +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint* params); + +#define glPointParameteriNV GLEW_GET_FUN(__glewPointParameteriNV) +#define glPointParameterivNV GLEW_GET_FUN(__glewPointParameterivNV) + +#define GLEW_NV_point_sprite GLEW_GET_VAR(__GLEW_NV_point_sprite) + +#endif /* GL_NV_point_sprite */ + +/* -------------------------- GL_NV_present_video -------------------------- */ + +#ifndef GL_NV_present_video +#define GL_NV_present_video 1 + +#define GL_FRAME_NV 0x8E26 +#define GL_FIELDS_NV 0x8E27 +#define GL_CURRENT_TIME_NV 0x8E28 +#define GL_NUM_FILL_STREAMS_NV 0x8E29 +#define GL_PRESENT_TIME_NV 0x8E2A +#define GL_PRESENT_DURATION_NV 0x8E2B + +typedef void (GLAPIENTRY * PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); +typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); + +#define glGetVideoi64vNV GLEW_GET_FUN(__glewGetVideoi64vNV) +#define glGetVideoivNV GLEW_GET_FUN(__glewGetVideoivNV) +#define glGetVideoui64vNV GLEW_GET_FUN(__glewGetVideoui64vNV) +#define glGetVideouivNV GLEW_GET_FUN(__glewGetVideouivNV) +#define glPresentFrameDualFillNV GLEW_GET_FUN(__glewPresentFrameDualFillNV) +#define glPresentFrameKeyedNV GLEW_GET_FUN(__glewPresentFrameKeyedNV) + +#define GLEW_NV_present_video GLEW_GET_VAR(__GLEW_NV_present_video) + +#endif /* GL_NV_present_video */ + +/* ------------------------ GL_NV_primitive_restart ------------------------ */ + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 + +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 + +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTNVPROC) (void); + +#define glPrimitiveRestartIndexNV GLEW_GET_FUN(__glewPrimitiveRestartIndexNV) +#define glPrimitiveRestartNV GLEW_GET_FUN(__glewPrimitiveRestartNV) + +#define GLEW_NV_primitive_restart GLEW_GET_VAR(__GLEW_NV_primitive_restart) + +#endif /* GL_NV_primitive_restart */ + +/* ------------------------ GL_NV_register_combiners ----------------------- */ + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 + +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 + +typedef void (GLAPIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint* params); + +#define glCombinerInputNV GLEW_GET_FUN(__glewCombinerInputNV) +#define glCombinerOutputNV GLEW_GET_FUN(__glewCombinerOutputNV) +#define glCombinerParameterfNV GLEW_GET_FUN(__glewCombinerParameterfNV) +#define glCombinerParameterfvNV GLEW_GET_FUN(__glewCombinerParameterfvNV) +#define glCombinerParameteriNV GLEW_GET_FUN(__glewCombinerParameteriNV) +#define glCombinerParameterivNV GLEW_GET_FUN(__glewCombinerParameterivNV) +#define glFinalCombinerInputNV GLEW_GET_FUN(__glewFinalCombinerInputNV) +#define glGetCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetCombinerInputParameterfvNV) +#define glGetCombinerInputParameterivNV GLEW_GET_FUN(__glewGetCombinerInputParameterivNV) +#define glGetCombinerOutputParameterfvNV GLEW_GET_FUN(__glewGetCombinerOutputParameterfvNV) +#define glGetCombinerOutputParameterivNV GLEW_GET_FUN(__glewGetCombinerOutputParameterivNV) +#define glGetFinalCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterfvNV) +#define glGetFinalCombinerInputParameterivNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterivNV) + +#define GLEW_NV_register_combiners GLEW_GET_VAR(__GLEW_NV_register_combiners) + +#endif /* GL_NV_register_combiners */ + +/* ----------------------- GL_NV_register_combiners2 ----------------------- */ + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 + +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 + +typedef void (GLAPIENTRY * PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat* params); + +#define glCombinerStageParameterfvNV GLEW_GET_FUN(__glewCombinerStageParameterfvNV) +#define glGetCombinerStageParameterfvNV GLEW_GET_FUN(__glewGetCombinerStageParameterfvNV) + +#define GLEW_NV_register_combiners2 GLEW_GET_VAR(__GLEW_NV_register_combiners2) + +#endif /* GL_NV_register_combiners2 */ + +/* ------------------------ GL_NV_shader_buffer_load ----------------------- */ + +#ifndef GL_NV_shader_buffer_load +#define GL_NV_shader_buffer_load 1 + +#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D +#define GL_GPU_ADDRESS_NV 0x8F34 +#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 + +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT* result); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT* params); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERRESIDENTNVPROC) (GLenum target); +typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access); +typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value); +typedef void (GLAPIENTRY * PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); + +#define glGetBufferParameterui64vNV GLEW_GET_FUN(__glewGetBufferParameterui64vNV) +#define glGetIntegerui64vNV GLEW_GET_FUN(__glewGetIntegerui64vNV) +#define glGetNamedBufferParameterui64vNV GLEW_GET_FUN(__glewGetNamedBufferParameterui64vNV) +#define glIsBufferResidentNV GLEW_GET_FUN(__glewIsBufferResidentNV) +#define glIsNamedBufferResidentNV GLEW_GET_FUN(__glewIsNamedBufferResidentNV) +#define glMakeBufferNonResidentNV GLEW_GET_FUN(__glewMakeBufferNonResidentNV) +#define glMakeBufferResidentNV GLEW_GET_FUN(__glewMakeBufferResidentNV) +#define glMakeNamedBufferNonResidentNV GLEW_GET_FUN(__glewMakeNamedBufferNonResidentNV) +#define glMakeNamedBufferResidentNV GLEW_GET_FUN(__glewMakeNamedBufferResidentNV) +#define glProgramUniformui64NV GLEW_GET_FUN(__glewProgramUniformui64NV) +#define glProgramUniformui64vNV GLEW_GET_FUN(__glewProgramUniformui64vNV) +#define glUniformui64NV GLEW_GET_FUN(__glewUniformui64NV) +#define glUniformui64vNV GLEW_GET_FUN(__glewUniformui64vNV) + +#define GLEW_NV_shader_buffer_load GLEW_GET_VAR(__GLEW_NV_shader_buffer_load) + +#endif /* GL_NV_shader_buffer_load */ + +/* ---------------------- GL_NV_tessellation_program5 ---------------------- */ + +#ifndef GL_NV_tessellation_program5 +#define GL_NV_tessellation_program5 1 + +#define GL_PATCHES_NV 0xE +#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 +#define GL_TESS_CONTROL_PROGRAM_NV 0x891E +#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F +#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 +#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 +#define GL_PATCH_VERTICES_NV 0x8E72 +#define GL_PATCH_DEFAULT_INNER_LEVEL_NV 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL_NV 0x8E74 +#define GL_MAX_PATCH_VERTICES_NV 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL_NV 0x8E7E +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_NV 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_NV 0x8E82 + +typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERFVNVPROC) (GLenum pname, const GLfloat* values); +typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERINVPROC) (GLenum pname, GLint value); + +#define glPatchParameterfvNV GLEW_GET_FUN(__glewPatchParameterfvNV) +#define glPatchParameteriNV GLEW_GET_FUN(__glewPatchParameteriNV) + +#define GLEW_NV_tessellation_program5 GLEW_GET_VAR(__GLEW_NV_tessellation_program5) + +#endif /* GL_NV_tessellation_program5 */ + +/* -------------------------- GL_NV_texgen_emboss -------------------------- */ + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 + +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F + +#define GLEW_NV_texgen_emboss GLEW_GET_VAR(__GLEW_NV_texgen_emboss) + +#endif /* GL_NV_texgen_emboss */ + +/* ------------------------ GL_NV_texgen_reflection ------------------------ */ + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 + +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 + +#define GLEW_NV_texgen_reflection GLEW_GET_VAR(__GLEW_NV_texgen_reflection) + +#endif /* GL_NV_texgen_reflection */ + +/* ------------------------- GL_NV_texture_barrier ------------------------- */ + +#ifndef GL_NV_texture_barrier +#define GL_NV_texture_barrier 1 + +typedef void (GLAPIENTRY * PFNGLTEXTUREBARRIERNVPROC) (void); + +#define glTextureBarrierNV GLEW_GET_FUN(__glewTextureBarrierNV) + +#define GLEW_NV_texture_barrier GLEW_GET_VAR(__GLEW_NV_texture_barrier) + +#endif /* GL_NV_texture_barrier */ + +/* --------------------- GL_NV_texture_compression_vtc --------------------- */ + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 + +#define GLEW_NV_texture_compression_vtc GLEW_GET_VAR(__GLEW_NV_texture_compression_vtc) + +#endif /* GL_NV_texture_compression_vtc */ + +/* ----------------------- GL_NV_texture_env_combine4 ---------------------- */ + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 + +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B + +#define GLEW_NV_texture_env_combine4 GLEW_GET_VAR(__GLEW_NV_texture_env_combine4) + +#endif /* GL_NV_texture_env_combine4 */ + +/* ---------------------- GL_NV_texture_expand_normal ---------------------- */ + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 + +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F + +#define GLEW_NV_texture_expand_normal GLEW_GET_VAR(__GLEW_NV_texture_expand_normal) + +#endif /* GL_NV_texture_expand_normal */ + +/* ----------------------- GL_NV_texture_multisample ----------------------- */ + +#ifndef GL_NV_texture_multisample +#define GL_NV_texture_multisample 1 + +#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 +#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); + +#define glTexImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage2DMultisampleCoverageNV) +#define glTexImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage3DMultisampleCoverageNV) +#define glTextureImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage2DMultisampleCoverageNV) +#define glTextureImage2DMultisampleNV GLEW_GET_FUN(__glewTextureImage2DMultisampleNV) +#define glTextureImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage3DMultisampleCoverageNV) +#define glTextureImage3DMultisampleNV GLEW_GET_FUN(__glewTextureImage3DMultisampleNV) + +#define GLEW_NV_texture_multisample GLEW_GET_VAR(__GLEW_NV_texture_multisample) + +#endif /* GL_NV_texture_multisample */ + +/* ------------------------ GL_NV_texture_rectangle ------------------------ */ + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 + +#define GLEW_NV_texture_rectangle GLEW_GET_VAR(__GLEW_NV_texture_rectangle) + +#endif /* GL_NV_texture_rectangle */ + +/* -------------------------- GL_NV_texture_shader ------------------------- */ + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 + +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F + +#define GLEW_NV_texture_shader GLEW_GET_VAR(__GLEW_NV_texture_shader) + +#endif /* GL_NV_texture_shader */ + +/* ------------------------- GL_NV_texture_shader2 ------------------------- */ + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 + +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D + +#define GLEW_NV_texture_shader2 GLEW_GET_VAR(__GLEW_NV_texture_shader2) + +#endif /* GL_NV_texture_shader2 */ + +/* ------------------------- GL_NV_texture_shader3 ------------------------- */ + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 + +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 + +#define GLEW_NV_texture_shader3 GLEW_GET_VAR(__GLEW_NV_texture_shader3) + +#endif /* GL_NV_texture_shader3 */ + +/* ------------------------ GL_NV_transform_feedback ----------------------- */ + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback 1 + +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F + +typedef void (GLAPIENTRY * PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); +typedef GLint (GLAPIENTRY * PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); + +#define glActiveVaryingNV GLEW_GET_FUN(__glewActiveVaryingNV) +#define glBeginTransformFeedbackNV GLEW_GET_FUN(__glewBeginTransformFeedbackNV) +#define glBindBufferBaseNV GLEW_GET_FUN(__glewBindBufferBaseNV) +#define glBindBufferOffsetNV GLEW_GET_FUN(__glewBindBufferOffsetNV) +#define glBindBufferRangeNV GLEW_GET_FUN(__glewBindBufferRangeNV) +#define glEndTransformFeedbackNV GLEW_GET_FUN(__glewEndTransformFeedbackNV) +#define glGetActiveVaryingNV GLEW_GET_FUN(__glewGetActiveVaryingNV) +#define glGetTransformFeedbackVaryingNV GLEW_GET_FUN(__glewGetTransformFeedbackVaryingNV) +#define glGetVaryingLocationNV GLEW_GET_FUN(__glewGetVaryingLocationNV) +#define glTransformFeedbackAttribsNV GLEW_GET_FUN(__glewTransformFeedbackAttribsNV) +#define glTransformFeedbackVaryingsNV GLEW_GET_FUN(__glewTransformFeedbackVaryingsNV) + +#define GLEW_NV_transform_feedback GLEW_GET_VAR(__GLEW_NV_transform_feedback) + +#endif /* GL_NV_transform_feedback */ + +/* ----------------------- GL_NV_transform_feedback2 ----------------------- */ + +#ifndef GL_NV_transform_feedback2 +#define GL_NV_transform_feedback2 1 + +#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 + +typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); +typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint* ids); +typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); + +#define glBindTransformFeedbackNV GLEW_GET_FUN(__glewBindTransformFeedbackNV) +#define glDeleteTransformFeedbacksNV GLEW_GET_FUN(__glewDeleteTransformFeedbacksNV) +#define glDrawTransformFeedbackNV GLEW_GET_FUN(__glewDrawTransformFeedbackNV) +#define glGenTransformFeedbacksNV GLEW_GET_FUN(__glewGenTransformFeedbacksNV) +#define glIsTransformFeedbackNV GLEW_GET_FUN(__glewIsTransformFeedbackNV) +#define glPauseTransformFeedbackNV GLEW_GET_FUN(__glewPauseTransformFeedbackNV) +#define glResumeTransformFeedbackNV GLEW_GET_FUN(__glewResumeTransformFeedbackNV) + +#define GLEW_NV_transform_feedback2 GLEW_GET_VAR(__GLEW_NV_transform_feedback2) + +#endif /* GL_NV_transform_feedback2 */ + +/* ------------------------ GL_NV_vertex_array_range ----------------------- */ + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 + +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 + +typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, void* pointer); + +#define glFlushVertexArrayRangeNV GLEW_GET_FUN(__glewFlushVertexArrayRangeNV) +#define glVertexArrayRangeNV GLEW_GET_FUN(__glewVertexArrayRangeNV) + +#define GLEW_NV_vertex_array_range GLEW_GET_VAR(__GLEW_NV_vertex_array_range) + +#endif /* GL_NV_vertex_array_range */ + +/* ----------------------- GL_NV_vertex_array_range2 ----------------------- */ + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 + +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 + +#define GLEW_NV_vertex_array_range2 GLEW_GET_VAR(__GLEW_NV_vertex_array_range2) + +#endif /* GL_NV_vertex_array_range2 */ + +/* ------------------- GL_NV_vertex_attrib_integer_64bit ------------------- */ + +#ifndef GL_NV_vertex_attrib_integer_64bit +#define GL_NV_vertex_attrib_integer_64bit 1 + +#define GL_INT64_NV 0x140E +#define GL_UNSIGNED_INT64_NV 0x140F + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); + +#define glGetVertexAttribLi64vNV GLEW_GET_FUN(__glewGetVertexAttribLi64vNV) +#define glGetVertexAttribLui64vNV GLEW_GET_FUN(__glewGetVertexAttribLui64vNV) +#define glVertexAttribL1i64NV GLEW_GET_FUN(__glewVertexAttribL1i64NV) +#define glVertexAttribL1i64vNV GLEW_GET_FUN(__glewVertexAttribL1i64vNV) +#define glVertexAttribL1ui64NV GLEW_GET_FUN(__glewVertexAttribL1ui64NV) +#define glVertexAttribL1ui64vNV GLEW_GET_FUN(__glewVertexAttribL1ui64vNV) +#define glVertexAttribL2i64NV GLEW_GET_FUN(__glewVertexAttribL2i64NV) +#define glVertexAttribL2i64vNV GLEW_GET_FUN(__glewVertexAttribL2i64vNV) +#define glVertexAttribL2ui64NV GLEW_GET_FUN(__glewVertexAttribL2ui64NV) +#define glVertexAttribL2ui64vNV GLEW_GET_FUN(__glewVertexAttribL2ui64vNV) +#define glVertexAttribL3i64NV GLEW_GET_FUN(__glewVertexAttribL3i64NV) +#define glVertexAttribL3i64vNV GLEW_GET_FUN(__glewVertexAttribL3i64vNV) +#define glVertexAttribL3ui64NV GLEW_GET_FUN(__glewVertexAttribL3ui64NV) +#define glVertexAttribL3ui64vNV GLEW_GET_FUN(__glewVertexAttribL3ui64vNV) +#define glVertexAttribL4i64NV GLEW_GET_FUN(__glewVertexAttribL4i64NV) +#define glVertexAttribL4i64vNV GLEW_GET_FUN(__glewVertexAttribL4i64vNV) +#define glVertexAttribL4ui64NV GLEW_GET_FUN(__glewVertexAttribL4ui64NV) +#define glVertexAttribL4ui64vNV GLEW_GET_FUN(__glewVertexAttribL4ui64vNV) +#define glVertexAttribLFormatNV GLEW_GET_FUN(__glewVertexAttribLFormatNV) + +#define GLEW_NV_vertex_attrib_integer_64bit GLEW_GET_VAR(__GLEW_NV_vertex_attrib_integer_64bit) + +#endif /* GL_NV_vertex_attrib_integer_64bit */ + +/* ------------------- GL_NV_vertex_buffer_unified_memory ------------------ */ + +#ifndef GL_NV_vertex_buffer_unified_memory +#define GL_NV_vertex_buffer_unified_memory 1 + +#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E +#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F +#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 +#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 +#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 +#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 +#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 +#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 +#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 +#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 +#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 +#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 +#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A +#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B +#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C +#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D +#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E +#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F +#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 +#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 +#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 +#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 + +typedef void (GLAPIENTRY * PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); +typedef void (GLAPIENTRY * PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT result[]); +typedef void (GLAPIENTRY * PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); + +#define glBufferAddressRangeNV GLEW_GET_FUN(__glewBufferAddressRangeNV) +#define glColorFormatNV GLEW_GET_FUN(__glewColorFormatNV) +#define glEdgeFlagFormatNV GLEW_GET_FUN(__glewEdgeFlagFormatNV) +#define glFogCoordFormatNV GLEW_GET_FUN(__glewFogCoordFormatNV) +#define glGetIntegerui64i_vNV GLEW_GET_FUN(__glewGetIntegerui64i_vNV) +#define glIndexFormatNV GLEW_GET_FUN(__glewIndexFormatNV) +#define glNormalFormatNV GLEW_GET_FUN(__glewNormalFormatNV) +#define glSecondaryColorFormatNV GLEW_GET_FUN(__glewSecondaryColorFormatNV) +#define glTexCoordFormatNV GLEW_GET_FUN(__glewTexCoordFormatNV) +#define glVertexAttribFormatNV GLEW_GET_FUN(__glewVertexAttribFormatNV) +#define glVertexAttribIFormatNV GLEW_GET_FUN(__glewVertexAttribIFormatNV) +#define glVertexFormatNV GLEW_GET_FUN(__glewVertexFormatNV) + +#define GLEW_NV_vertex_buffer_unified_memory GLEW_GET_VAR(__GLEW_NV_vertex_buffer_unified_memory) + +#endif /* GL_NV_vertex_buffer_unified_memory */ + +/* -------------------------- GL_NV_vertex_program ------------------------- */ + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 + +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F + +typedef GLboolean (GLAPIENTRY * PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint* ids, GLboolean *residences); +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte* program); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte* program); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint num, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint num, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei n, const GLubyte* v); + +#define glAreProgramsResidentNV GLEW_GET_FUN(__glewAreProgramsResidentNV) +#define glBindProgramNV GLEW_GET_FUN(__glewBindProgramNV) +#define glDeleteProgramsNV GLEW_GET_FUN(__glewDeleteProgramsNV) +#define glExecuteProgramNV GLEW_GET_FUN(__glewExecuteProgramNV) +#define glGenProgramsNV GLEW_GET_FUN(__glewGenProgramsNV) +#define glGetProgramParameterdvNV GLEW_GET_FUN(__glewGetProgramParameterdvNV) +#define glGetProgramParameterfvNV GLEW_GET_FUN(__glewGetProgramParameterfvNV) +#define glGetProgramStringNV GLEW_GET_FUN(__glewGetProgramStringNV) +#define glGetProgramivNV GLEW_GET_FUN(__glewGetProgramivNV) +#define glGetTrackMatrixivNV GLEW_GET_FUN(__glewGetTrackMatrixivNV) +#define glGetVertexAttribPointervNV GLEW_GET_FUN(__glewGetVertexAttribPointervNV) +#define glGetVertexAttribdvNV GLEW_GET_FUN(__glewGetVertexAttribdvNV) +#define glGetVertexAttribfvNV GLEW_GET_FUN(__glewGetVertexAttribfvNV) +#define glGetVertexAttribivNV GLEW_GET_FUN(__glewGetVertexAttribivNV) +#define glIsProgramNV GLEW_GET_FUN(__glewIsProgramNV) +#define glLoadProgramNV GLEW_GET_FUN(__glewLoadProgramNV) +#define glProgramParameter4dNV GLEW_GET_FUN(__glewProgramParameter4dNV) +#define glProgramParameter4dvNV GLEW_GET_FUN(__glewProgramParameter4dvNV) +#define glProgramParameter4fNV GLEW_GET_FUN(__glewProgramParameter4fNV) +#define glProgramParameter4fvNV GLEW_GET_FUN(__glewProgramParameter4fvNV) +#define glProgramParameters4dvNV GLEW_GET_FUN(__glewProgramParameters4dvNV) +#define glProgramParameters4fvNV GLEW_GET_FUN(__glewProgramParameters4fvNV) +#define glRequestResidentProgramsNV GLEW_GET_FUN(__glewRequestResidentProgramsNV) +#define glTrackMatrixNV GLEW_GET_FUN(__glewTrackMatrixNV) +#define glVertexAttrib1dNV GLEW_GET_FUN(__glewVertexAttrib1dNV) +#define glVertexAttrib1dvNV GLEW_GET_FUN(__glewVertexAttrib1dvNV) +#define glVertexAttrib1fNV GLEW_GET_FUN(__glewVertexAttrib1fNV) +#define glVertexAttrib1fvNV GLEW_GET_FUN(__glewVertexAttrib1fvNV) +#define glVertexAttrib1sNV GLEW_GET_FUN(__glewVertexAttrib1sNV) +#define glVertexAttrib1svNV GLEW_GET_FUN(__glewVertexAttrib1svNV) +#define glVertexAttrib2dNV GLEW_GET_FUN(__glewVertexAttrib2dNV) +#define glVertexAttrib2dvNV GLEW_GET_FUN(__glewVertexAttrib2dvNV) +#define glVertexAttrib2fNV GLEW_GET_FUN(__glewVertexAttrib2fNV) +#define glVertexAttrib2fvNV GLEW_GET_FUN(__glewVertexAttrib2fvNV) +#define glVertexAttrib2sNV GLEW_GET_FUN(__glewVertexAttrib2sNV) +#define glVertexAttrib2svNV GLEW_GET_FUN(__glewVertexAttrib2svNV) +#define glVertexAttrib3dNV GLEW_GET_FUN(__glewVertexAttrib3dNV) +#define glVertexAttrib3dvNV GLEW_GET_FUN(__glewVertexAttrib3dvNV) +#define glVertexAttrib3fNV GLEW_GET_FUN(__glewVertexAttrib3fNV) +#define glVertexAttrib3fvNV GLEW_GET_FUN(__glewVertexAttrib3fvNV) +#define glVertexAttrib3sNV GLEW_GET_FUN(__glewVertexAttrib3sNV) +#define glVertexAttrib3svNV GLEW_GET_FUN(__glewVertexAttrib3svNV) +#define glVertexAttrib4dNV GLEW_GET_FUN(__glewVertexAttrib4dNV) +#define glVertexAttrib4dvNV GLEW_GET_FUN(__glewVertexAttrib4dvNV) +#define glVertexAttrib4fNV GLEW_GET_FUN(__glewVertexAttrib4fNV) +#define glVertexAttrib4fvNV GLEW_GET_FUN(__glewVertexAttrib4fvNV) +#define glVertexAttrib4sNV GLEW_GET_FUN(__glewVertexAttrib4sNV) +#define glVertexAttrib4svNV GLEW_GET_FUN(__glewVertexAttrib4svNV) +#define glVertexAttrib4ubNV GLEW_GET_FUN(__glewVertexAttrib4ubNV) +#define glVertexAttrib4ubvNV GLEW_GET_FUN(__glewVertexAttrib4ubvNV) +#define glVertexAttribPointerNV GLEW_GET_FUN(__glewVertexAttribPointerNV) +#define glVertexAttribs1dvNV GLEW_GET_FUN(__glewVertexAttribs1dvNV) +#define glVertexAttribs1fvNV GLEW_GET_FUN(__glewVertexAttribs1fvNV) +#define glVertexAttribs1svNV GLEW_GET_FUN(__glewVertexAttribs1svNV) +#define glVertexAttribs2dvNV GLEW_GET_FUN(__glewVertexAttribs2dvNV) +#define glVertexAttribs2fvNV GLEW_GET_FUN(__glewVertexAttribs2fvNV) +#define glVertexAttribs2svNV GLEW_GET_FUN(__glewVertexAttribs2svNV) +#define glVertexAttribs3dvNV GLEW_GET_FUN(__glewVertexAttribs3dvNV) +#define glVertexAttribs3fvNV GLEW_GET_FUN(__glewVertexAttribs3fvNV) +#define glVertexAttribs3svNV GLEW_GET_FUN(__glewVertexAttribs3svNV) +#define glVertexAttribs4dvNV GLEW_GET_FUN(__glewVertexAttribs4dvNV) +#define glVertexAttribs4fvNV GLEW_GET_FUN(__glewVertexAttribs4fvNV) +#define glVertexAttribs4svNV GLEW_GET_FUN(__glewVertexAttribs4svNV) +#define glVertexAttribs4ubvNV GLEW_GET_FUN(__glewVertexAttribs4ubvNV) + +#define GLEW_NV_vertex_program GLEW_GET_VAR(__GLEW_NV_vertex_program) + +#endif /* GL_NV_vertex_program */ + +/* ------------------------ GL_NV_vertex_program1_1 ------------------------ */ + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 + +#define GLEW_NV_vertex_program1_1 GLEW_GET_VAR(__GLEW_NV_vertex_program1_1) + +#endif /* GL_NV_vertex_program1_1 */ + +/* ------------------------- GL_NV_vertex_program2 ------------------------- */ + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 + +#define GLEW_NV_vertex_program2 GLEW_GET_VAR(__GLEW_NV_vertex_program2) + +#endif /* GL_NV_vertex_program2 */ + +/* ---------------------- GL_NV_vertex_program2_option --------------------- */ + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 + +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 + +#define GLEW_NV_vertex_program2_option GLEW_GET_VAR(__GLEW_NV_vertex_program2_option) + +#endif /* GL_NV_vertex_program2_option */ + +/* ------------------------- GL_NV_vertex_program3 ------------------------- */ + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 + +#define MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C + +#define GLEW_NV_vertex_program3 GLEW_GET_VAR(__GLEW_NV_vertex_program3) + +#endif /* GL_NV_vertex_program3 */ + +/* ------------------------- GL_NV_vertex_program4 ------------------------- */ + +#ifndef GL_NV_vertex_program4 +#define GL_NV_vertex_program4 1 + +#define GLEW_NV_vertex_program4 GLEW_GET_VAR(__GLEW_NV_vertex_program4) + +#endif /* GL_NV_vertex_program4 */ + +/* ------------------------ GL_OES_byte_coordinates ------------------------ */ + +#ifndef GL_OES_byte_coordinates +#define GL_OES_byte_coordinates 1 + +#define GL_BYTE 0x1400 + +#define GLEW_OES_byte_coordinates GLEW_GET_VAR(__GLEW_OES_byte_coordinates) + +#endif /* GL_OES_byte_coordinates */ + +/* ------------------- GL_OES_compressed_paletted_texture ------------------ */ + +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 + +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 + +#define GLEW_OES_compressed_paletted_texture GLEW_GET_VAR(__GLEW_OES_compressed_paletted_texture) + +#endif /* GL_OES_compressed_paletted_texture */ + +/* --------------------------- GL_OES_read_format -------------------------- */ + +#ifndef GL_OES_read_format +#define GL_OES_read_format 1 + +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B + +#define GLEW_OES_read_format GLEW_GET_VAR(__GLEW_OES_read_format) + +#endif /* GL_OES_read_format */ + +/* ------------------------ GL_OES_single_precision ------------------------ */ + +#ifndef GL_OES_single_precision +#define GL_OES_single_precision 1 + +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFOESPROC) (GLclampd depth); +typedef void (GLAPIENTRY * PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat* equation); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); +typedef void (GLAPIENTRY * PFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat* equation); +typedef void (GLAPIENTRY * PFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); + +#define glClearDepthfOES GLEW_GET_FUN(__glewClearDepthfOES) +#define glClipPlanefOES GLEW_GET_FUN(__glewClipPlanefOES) +#define glDepthRangefOES GLEW_GET_FUN(__glewDepthRangefOES) +#define glFrustumfOES GLEW_GET_FUN(__glewFrustumfOES) +#define glGetClipPlanefOES GLEW_GET_FUN(__glewGetClipPlanefOES) +#define glOrthofOES GLEW_GET_FUN(__glewOrthofOES) + +#define GLEW_OES_single_precision GLEW_GET_VAR(__GLEW_OES_single_precision) + +#endif /* GL_OES_single_precision */ + +/* ---------------------------- GL_OML_interlace --------------------------- */ + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 + +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 + +#define GLEW_OML_interlace GLEW_GET_VAR(__GLEW_OML_interlace) + +#endif /* GL_OML_interlace */ + +/* ---------------------------- GL_OML_resample ---------------------------- */ + +#ifndef GL_OML_resample +#define GL_OML_resample 1 + +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 + +#define GLEW_OML_resample GLEW_GET_VAR(__GLEW_OML_resample) + +#endif /* GL_OML_resample */ + +/* ---------------------------- GL_OML_subsample --------------------------- */ + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 + +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 + +#define GLEW_OML_subsample GLEW_GET_VAR(__GLEW_OML_subsample) + +#endif /* GL_OML_subsample */ + +/* --------------------------- GL_PGI_misc_hints --------------------------- */ + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 + +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 107000 +#define GL_CONSERVE_MEMORY_HINT_PGI 107005 +#define GL_RECLAIM_MEMORY_HINT_PGI 107006 +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 107010 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 107011 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 107012 +#define GL_ALWAYS_FAST_HINT_PGI 107020 +#define GL_ALWAYS_SOFT_HINT_PGI 107021 +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 107022 +#define GL_ALLOW_DRAW_WIN_HINT_PGI 107023 +#define GL_ALLOW_DRAW_FRG_HINT_PGI 107024 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 107025 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 107030 +#define GL_STRICT_LIGHTING_HINT_PGI 107031 +#define GL_STRICT_SCISSOR_HINT_PGI 107032 +#define GL_FULL_STIPPLE_HINT_PGI 107033 +#define GL_CLIP_NEAR_HINT_PGI 107040 +#define GL_CLIP_FAR_HINT_PGI 107041 +#define GL_WIDE_LINE_HINT_PGI 107042 +#define GL_BACK_NORMALS_HINT_PGI 107043 + +#define GLEW_PGI_misc_hints GLEW_GET_VAR(__GLEW_PGI_misc_hints) + +#endif /* GL_PGI_misc_hints */ + +/* -------------------------- GL_PGI_vertex_hints -------------------------- */ + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 + +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_VERTEX_DATA_HINT_PGI 107050 +#define GL_VERTEX_CONSISTENT_HINT_PGI 107051 +#define GL_MATERIAL_SIDE_HINT_PGI 107052 +#define GL_MAX_VERTEX_HINT_PGI 107053 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 + +#define GLEW_PGI_vertex_hints GLEW_GET_VAR(__GLEW_PGI_vertex_hints) + +#endif /* GL_PGI_vertex_hints */ + +/* ----------------------- GL_REND_screen_coordinates ---------------------- */ + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 + +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 + +#define GLEW_REND_screen_coordinates GLEW_GET_VAR(__GLEW_REND_screen_coordinates) + +#endif /* GL_REND_screen_coordinates */ + +/* ------------------------------- GL_S3_s3tc ------------------------------ */ + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 + +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#define GL_RGBA_DXT5_S3TC 0x83A4 +#define GL_RGBA4_DXT5_S3TC 0x83A5 + +#define GLEW_S3_s3tc GLEW_GET_VAR(__GLEW_S3_s3tc) + +#endif /* GL_S3_s3tc */ + +/* -------------------------- GL_SGIS_color_range -------------------------- */ + +#ifndef GL_SGIS_color_range +#define GL_SGIS_color_range 1 + +#define GL_EXTENDED_RANGE_SGIS 0x85A5 +#define GL_MIN_RED_SGIS 0x85A6 +#define GL_MAX_RED_SGIS 0x85A7 +#define GL_MIN_GREEN_SGIS 0x85A8 +#define GL_MAX_GREEN_SGIS 0x85A9 +#define GL_MIN_BLUE_SGIS 0x85AA +#define GL_MAX_BLUE_SGIS 0x85AB +#define GL_MIN_ALPHA_SGIS 0x85AC +#define GL_MAX_ALPHA_SGIS 0x85AD + +#define GLEW_SGIS_color_range GLEW_GET_VAR(__GLEW_SGIS_color_range) + +#endif /* GL_SGIS_color_range */ + +/* ------------------------- GL_SGIS_detail_texture ------------------------ */ + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 + +typedef void (GLAPIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat* points); + +#define glDetailTexFuncSGIS GLEW_GET_FUN(__glewDetailTexFuncSGIS) +#define glGetDetailTexFuncSGIS GLEW_GET_FUN(__glewGetDetailTexFuncSGIS) + +#define GLEW_SGIS_detail_texture GLEW_GET_VAR(__GLEW_SGIS_detail_texture) + +#endif /* GL_SGIS_detail_texture */ + +/* -------------------------- GL_SGIS_fog_function ------------------------- */ + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 + +typedef void (GLAPIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLGETFOGFUNCSGISPROC) (GLfloat* points); + +#define glFogFuncSGIS GLEW_GET_FUN(__glewFogFuncSGIS) +#define glGetFogFuncSGIS GLEW_GET_FUN(__glewGetFogFuncSGIS) + +#define GLEW_SGIS_fog_function GLEW_GET_VAR(__GLEW_SGIS_fog_function) + +#endif /* GL_SGIS_fog_function */ + +/* ------------------------ GL_SGIS_generate_mipmap ------------------------ */ + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 + +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 + +#define GLEW_SGIS_generate_mipmap GLEW_GET_VAR(__GLEW_SGIS_generate_mipmap) + +#endif /* GL_SGIS_generate_mipmap */ + +/* -------------------------- GL_SGIS_multisample -------------------------- */ + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 + +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); + +#define glSampleMaskSGIS GLEW_GET_FUN(__glewSampleMaskSGIS) +#define glSamplePatternSGIS GLEW_GET_FUN(__glewSamplePatternSGIS) + +#define GLEW_SGIS_multisample GLEW_GET_VAR(__GLEW_SGIS_multisample) + +#endif /* GL_SGIS_multisample */ + +/* ------------------------- GL_SGIS_pixel_texture ------------------------- */ + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 + +#define GLEW_SGIS_pixel_texture GLEW_GET_VAR(__GLEW_SGIS_pixel_texture) + +#endif /* GL_SGIS_pixel_texture */ + +/* ----------------------- GL_SGIS_point_line_texgen ----------------------- */ + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 + +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 + +#define GLEW_SGIS_point_line_texgen GLEW_GET_VAR(__GLEW_SGIS_point_line_texgen) + +#endif /* GL_SGIS_point_line_texgen */ + +/* ------------------------ GL_SGIS_sharpen_texture ------------------------ */ + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 + +typedef void (GLAPIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat* points); +typedef void (GLAPIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); + +#define glGetSharpenTexFuncSGIS GLEW_GET_FUN(__glewGetSharpenTexFuncSGIS) +#define glSharpenTexFuncSGIS GLEW_GET_FUN(__glewSharpenTexFuncSGIS) + +#define GLEW_SGIS_sharpen_texture GLEW_GET_VAR(__GLEW_SGIS_sharpen_texture) + +#endif /* GL_SGIS_sharpen_texture */ + +/* --------------------------- GL_SGIS_texture4D --------------------------- */ + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLenum format, GLenum type, const void* pixels); + +#define glTexImage4DSGIS GLEW_GET_FUN(__glewTexImage4DSGIS) +#define glTexSubImage4DSGIS GLEW_GET_FUN(__glewTexSubImage4DSGIS) + +#define GLEW_SGIS_texture4D GLEW_GET_VAR(__GLEW_SGIS_texture4D) + +#endif /* GL_SGIS_texture4D */ + +/* ---------------------- GL_SGIS_texture_border_clamp --------------------- */ + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 + +#define GL_CLAMP_TO_BORDER_SGIS 0x812D + +#define GLEW_SGIS_texture_border_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_border_clamp) + +#endif /* GL_SGIS_texture_border_clamp */ + +/* ----------------------- GL_SGIS_texture_edge_clamp ---------------------- */ + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 + +#define GL_CLAMP_TO_EDGE_SGIS 0x812F + +#define GLEW_SGIS_texture_edge_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_edge_clamp) + +#endif /* GL_SGIS_texture_edge_clamp */ + +/* ------------------------ GL_SGIS_texture_filter4 ------------------------ */ + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 + +typedef void (GLAPIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat* weights); +typedef void (GLAPIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat* weights); + +#define glGetTexFilterFuncSGIS GLEW_GET_FUN(__glewGetTexFilterFuncSGIS) +#define glTexFilterFuncSGIS GLEW_GET_FUN(__glewTexFilterFuncSGIS) + +#define GLEW_SGIS_texture_filter4 GLEW_GET_VAR(__GLEW_SGIS_texture_filter4) + +#endif /* GL_SGIS_texture_filter4 */ + +/* -------------------------- GL_SGIS_texture_lod -------------------------- */ + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 + +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D + +#define GLEW_SGIS_texture_lod GLEW_GET_VAR(__GLEW_SGIS_texture_lod) + +#endif /* GL_SGIS_texture_lod */ + +/* ------------------------- GL_SGIS_texture_select ------------------------ */ + +#ifndef GL_SGIS_texture_select +#define GL_SGIS_texture_select 1 + +#define GLEW_SGIS_texture_select GLEW_GET_VAR(__GLEW_SGIS_texture_select) + +#endif /* GL_SGIS_texture_select */ + +/* ----------------------------- GL_SGIX_async ----------------------------- */ + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 + +#define GL_ASYNC_MARKER_SGIX 0x8329 + +typedef void (GLAPIENTRY * PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef void (GLAPIENTRY * PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLint (GLAPIENTRY * PFNGLFINISHASYNCSGIXPROC) (GLuint* markerp); +typedef GLuint (GLAPIENTRY * PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef GLboolean (GLAPIENTRY * PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (GLAPIENTRY * PFNGLPOLLASYNCSGIXPROC) (GLuint* markerp); + +#define glAsyncMarkerSGIX GLEW_GET_FUN(__glewAsyncMarkerSGIX) +#define glDeleteAsyncMarkersSGIX GLEW_GET_FUN(__glewDeleteAsyncMarkersSGIX) +#define glFinishAsyncSGIX GLEW_GET_FUN(__glewFinishAsyncSGIX) +#define glGenAsyncMarkersSGIX GLEW_GET_FUN(__glewGenAsyncMarkersSGIX) +#define glIsAsyncMarkerSGIX GLEW_GET_FUN(__glewIsAsyncMarkerSGIX) +#define glPollAsyncSGIX GLEW_GET_FUN(__glewPollAsyncSGIX) + +#define GLEW_SGIX_async GLEW_GET_VAR(__GLEW_SGIX_async) + +#endif /* GL_SGIX_async */ + +/* ------------------------ GL_SGIX_async_histogram ------------------------ */ + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 + +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D + +#define GLEW_SGIX_async_histogram GLEW_GET_VAR(__GLEW_SGIX_async_histogram) + +#endif /* GL_SGIX_async_histogram */ + +/* -------------------------- GL_SGIX_async_pixel -------------------------- */ + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 + +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 + +#define GLEW_SGIX_async_pixel GLEW_GET_VAR(__GLEW_SGIX_async_pixel) + +#endif /* GL_SGIX_async_pixel */ + +/* ----------------------- GL_SGIX_blend_alpha_minmax ---------------------- */ + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 + +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 + +#define GLEW_SGIX_blend_alpha_minmax GLEW_GET_VAR(__GLEW_SGIX_blend_alpha_minmax) + +#endif /* GL_SGIX_blend_alpha_minmax */ + +/* ---------------------------- GL_SGIX_clipmap ---------------------------- */ + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 + +#define GLEW_SGIX_clipmap GLEW_GET_VAR(__GLEW_SGIX_clipmap) + +#endif /* GL_SGIX_clipmap */ + +/* ---------------------- GL_SGIX_convolution_accuracy --------------------- */ + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 + +#define GL_CONVOLUTION_HINT_SGIX 0x8316 + +#define GLEW_SGIX_convolution_accuracy GLEW_GET_VAR(__GLEW_SGIX_convolution_accuracy) + +#endif /* GL_SGIX_convolution_accuracy */ + +/* ------------------------- GL_SGIX_depth_texture ------------------------- */ + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 + +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 + +#define GLEW_SGIX_depth_texture GLEW_GET_VAR(__GLEW_SGIX_depth_texture) + +#endif /* GL_SGIX_depth_texture */ + +/* -------------------------- GL_SGIX_flush_raster ------------------------- */ + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 + +typedef void (GLAPIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void); + +#define glFlushRasterSGIX GLEW_GET_FUN(__glewFlushRasterSGIX) + +#define GLEW_SGIX_flush_raster GLEW_GET_VAR(__GLEW_SGIX_flush_raster) + +#endif /* GL_SGIX_flush_raster */ + +/* --------------------------- GL_SGIX_fog_offset -------------------------- */ + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 + +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 + +#define GLEW_SGIX_fog_offset GLEW_GET_VAR(__GLEW_SGIX_fog_offset) + +#endif /* GL_SGIX_fog_offset */ + +/* -------------------------- GL_SGIX_fog_texture -------------------------- */ + +#ifndef GL_SGIX_fog_texture +#define GL_SGIX_fog_texture 1 + +#define GL_TEXTURE_FOG_SGIX 0 +#define GL_FOG_PATCHY_FACTOR_SGIX 0 +#define GL_FRAGMENT_FOG_SGIX 0 + +typedef void (GLAPIENTRY * PFNGLTEXTUREFOGSGIXPROC) (GLenum pname); + +#define glTextureFogSGIX GLEW_GET_FUN(__glewTextureFogSGIX) + +#define GLEW_SGIX_fog_texture GLEW_GET_VAR(__GLEW_SGIX_fog_texture) + +#endif /* GL_SGIX_fog_texture */ + +/* ------------------- GL_SGIX_fragment_specular_lighting ------------------ */ + +#ifndef GL_SGIX_fragment_specular_lighting +#define GL_SGIX_fragment_specular_lighting 1 + +typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum value, GLfloat* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum value, GLint* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* data); + +#define glFragmentColorMaterialSGIX GLEW_GET_FUN(__glewFragmentColorMaterialSGIX) +#define glFragmentLightModelfSGIX GLEW_GET_FUN(__glewFragmentLightModelfSGIX) +#define glFragmentLightModelfvSGIX GLEW_GET_FUN(__glewFragmentLightModelfvSGIX) +#define glFragmentLightModeliSGIX GLEW_GET_FUN(__glewFragmentLightModeliSGIX) +#define glFragmentLightModelivSGIX GLEW_GET_FUN(__glewFragmentLightModelivSGIX) +#define glFragmentLightfSGIX GLEW_GET_FUN(__glewFragmentLightfSGIX) +#define glFragmentLightfvSGIX GLEW_GET_FUN(__glewFragmentLightfvSGIX) +#define glFragmentLightiSGIX GLEW_GET_FUN(__glewFragmentLightiSGIX) +#define glFragmentLightivSGIX GLEW_GET_FUN(__glewFragmentLightivSGIX) +#define glFragmentMaterialfSGIX GLEW_GET_FUN(__glewFragmentMaterialfSGIX) +#define glFragmentMaterialfvSGIX GLEW_GET_FUN(__glewFragmentMaterialfvSGIX) +#define glFragmentMaterialiSGIX GLEW_GET_FUN(__glewFragmentMaterialiSGIX) +#define glFragmentMaterialivSGIX GLEW_GET_FUN(__glewFragmentMaterialivSGIX) +#define glGetFragmentLightfvSGIX GLEW_GET_FUN(__glewGetFragmentLightfvSGIX) +#define glGetFragmentLightivSGIX GLEW_GET_FUN(__glewGetFragmentLightivSGIX) +#define glGetFragmentMaterialfvSGIX GLEW_GET_FUN(__glewGetFragmentMaterialfvSGIX) +#define glGetFragmentMaterialivSGIX GLEW_GET_FUN(__glewGetFragmentMaterialivSGIX) + +#define GLEW_SGIX_fragment_specular_lighting GLEW_GET_VAR(__GLEW_SGIX_fragment_specular_lighting) + +#endif /* GL_SGIX_fragment_specular_lighting */ + +/* --------------------------- GL_SGIX_framezoom --------------------------- */ + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 + +typedef void (GLAPIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor); + +#define glFrameZoomSGIX GLEW_GET_FUN(__glewFrameZoomSGIX) + +#define GLEW_SGIX_framezoom GLEW_GET_VAR(__GLEW_SGIX_framezoom) + +#endif /* GL_SGIX_framezoom */ + +/* --------------------------- GL_SGIX_interlace --------------------------- */ + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 + +#define GL_INTERLACE_SGIX 0x8094 + +#define GLEW_SGIX_interlace GLEW_GET_VAR(__GLEW_SGIX_interlace) + +#endif /* GL_SGIX_interlace */ + +/* ------------------------- GL_SGIX_ir_instrument1 ------------------------ */ + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 + +#define GLEW_SGIX_ir_instrument1 GLEW_GET_VAR(__GLEW_SGIX_ir_instrument1) + +#endif /* GL_SGIX_ir_instrument1 */ + +/* ------------------------- GL_SGIX_list_priority ------------------------- */ + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 + +#define GLEW_SGIX_list_priority GLEW_GET_VAR(__GLEW_SGIX_list_priority) + +#endif /* GL_SGIX_list_priority */ + +/* ------------------------- GL_SGIX_pixel_texture ------------------------- */ + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 + +typedef void (GLAPIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); + +#define glPixelTexGenSGIX GLEW_GET_FUN(__glewPixelTexGenSGIX) + +#define GLEW_SGIX_pixel_texture GLEW_GET_VAR(__GLEW_SGIX_pixel_texture) + +#endif /* GL_SGIX_pixel_texture */ + +/* ----------------------- GL_SGIX_pixel_texture_bits ---------------------- */ + +#ifndef GL_SGIX_pixel_texture_bits +#define GL_SGIX_pixel_texture_bits 1 + +#define GLEW_SGIX_pixel_texture_bits GLEW_GET_VAR(__GLEW_SGIX_pixel_texture_bits) + +#endif /* GL_SGIX_pixel_texture_bits */ + +/* ------------------------ GL_SGIX_reference_plane ------------------------ */ + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 + +typedef void (GLAPIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble* equation); + +#define glReferencePlaneSGIX GLEW_GET_FUN(__glewReferencePlaneSGIX) + +#define GLEW_SGIX_reference_plane GLEW_GET_VAR(__GLEW_SGIX_reference_plane) + +#endif /* GL_SGIX_reference_plane */ + +/* ---------------------------- GL_SGIX_resample --------------------------- */ + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 + +#define GL_PACK_RESAMPLE_SGIX 0x842E +#define GL_UNPACK_RESAMPLE_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 + +#define GLEW_SGIX_resample GLEW_GET_VAR(__GLEW_SGIX_resample) + +#endif /* GL_SGIX_resample */ + +/* ----------------------------- GL_SGIX_shadow ---------------------------- */ + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 + +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D + +#define GLEW_SGIX_shadow GLEW_GET_VAR(__GLEW_SGIX_shadow) + +#endif /* GL_SGIX_shadow */ + +/* ------------------------- GL_SGIX_shadow_ambient ------------------------ */ + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 + +#define GL_SHADOW_AMBIENT_SGIX 0x80BF + +#define GLEW_SGIX_shadow_ambient GLEW_GET_VAR(__GLEW_SGIX_shadow_ambient) + +#endif /* GL_SGIX_shadow_ambient */ + +/* ----------------------------- GL_SGIX_sprite ---------------------------- */ + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 + +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, GLint* params); + +#define glSpriteParameterfSGIX GLEW_GET_FUN(__glewSpriteParameterfSGIX) +#define glSpriteParameterfvSGIX GLEW_GET_FUN(__glewSpriteParameterfvSGIX) +#define glSpriteParameteriSGIX GLEW_GET_FUN(__glewSpriteParameteriSGIX) +#define glSpriteParameterivSGIX GLEW_GET_FUN(__glewSpriteParameterivSGIX) + +#define GLEW_SGIX_sprite GLEW_GET_VAR(__GLEW_SGIX_sprite) + +#endif /* GL_SGIX_sprite */ + +/* ----------------------- GL_SGIX_tag_sample_buffer ----------------------- */ + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 + +typedef void (GLAPIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); + +#define glTagSampleBufferSGIX GLEW_GET_FUN(__glewTagSampleBufferSGIX) + +#define GLEW_SGIX_tag_sample_buffer GLEW_GET_VAR(__GLEW_SGIX_tag_sample_buffer) + +#endif /* GL_SGIX_tag_sample_buffer */ + +/* ------------------------ GL_SGIX_texture_add_env ------------------------ */ + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 + +#define GLEW_SGIX_texture_add_env GLEW_GET_VAR(__GLEW_SGIX_texture_add_env) + +#endif /* GL_SGIX_texture_add_env */ + +/* -------------------- GL_SGIX_texture_coordinate_clamp ------------------- */ + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 + +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B + +#define GLEW_SGIX_texture_coordinate_clamp GLEW_GET_VAR(__GLEW_SGIX_texture_coordinate_clamp) + +#endif /* GL_SGIX_texture_coordinate_clamp */ + +/* ------------------------ GL_SGIX_texture_lod_bias ----------------------- */ + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 + +#define GLEW_SGIX_texture_lod_bias GLEW_GET_VAR(__GLEW_SGIX_texture_lod_bias) + +#endif /* GL_SGIX_texture_lod_bias */ + +/* ---------------------- GL_SGIX_texture_multi_buffer --------------------- */ + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 + +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E + +#define GLEW_SGIX_texture_multi_buffer GLEW_GET_VAR(__GLEW_SGIX_texture_multi_buffer) + +#endif /* GL_SGIX_texture_multi_buffer */ + +/* ------------------------- GL_SGIX_texture_range ------------------------- */ + +#ifndef GL_SGIX_texture_range +#define GL_SGIX_texture_range 1 + +#define GL_RGB_SIGNED_SGIX 0x85E0 +#define GL_RGBA_SIGNED_SGIX 0x85E1 +#define GL_ALPHA_SIGNED_SGIX 0x85E2 +#define GL_LUMINANCE_SIGNED_SGIX 0x85E3 +#define GL_INTENSITY_SIGNED_SGIX 0x85E4 +#define GL_LUMINANCE_ALPHA_SIGNED_SGIX 0x85E5 +#define GL_RGB16_SIGNED_SGIX 0x85E6 +#define GL_RGBA16_SIGNED_SGIX 0x85E7 +#define GL_ALPHA16_SIGNED_SGIX 0x85E8 +#define GL_LUMINANCE16_SIGNED_SGIX 0x85E9 +#define GL_INTENSITY16_SIGNED_SGIX 0x85EA +#define GL_LUMINANCE16_ALPHA16_SIGNED_SGIX 0x85EB +#define GL_RGB_EXTENDED_RANGE_SGIX 0x85EC +#define GL_RGBA_EXTENDED_RANGE_SGIX 0x85ED +#define GL_ALPHA_EXTENDED_RANGE_SGIX 0x85EE +#define GL_LUMINANCE_EXTENDED_RANGE_SGIX 0x85EF +#define GL_INTENSITY_EXTENDED_RANGE_SGIX 0x85F0 +#define GL_LUMINANCE_ALPHA_EXTENDED_RANGE_SGIX 0x85F1 +#define GL_RGB16_EXTENDED_RANGE_SGIX 0x85F2 +#define GL_RGBA16_EXTENDED_RANGE_SGIX 0x85F3 +#define GL_ALPHA16_EXTENDED_RANGE_SGIX 0x85F4 +#define GL_LUMINANCE16_EXTENDED_RANGE_SGIX 0x85F5 +#define GL_INTENSITY16_EXTENDED_RANGE_SGIX 0x85F6 +#define GL_LUMINANCE16_ALPHA16_EXTENDED_RANGE_SGIX 0x85F7 +#define GL_MIN_LUMINANCE_SGIS 0x85F8 +#define GL_MAX_LUMINANCE_SGIS 0x85F9 +#define GL_MIN_INTENSITY_SGIS 0x85FA +#define GL_MAX_INTENSITY_SGIS 0x85FB + +#define GLEW_SGIX_texture_range GLEW_GET_VAR(__GLEW_SGIX_texture_range) + +#endif /* GL_SGIX_texture_range */ + +/* ----------------------- GL_SGIX_texture_scale_bias ---------------------- */ + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 + +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C + +#define GLEW_SGIX_texture_scale_bias GLEW_GET_VAR(__GLEW_SGIX_texture_scale_bias) + +#endif /* GL_SGIX_texture_scale_bias */ + +/* ------------------------- GL_SGIX_vertex_preclip ------------------------ */ + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 + +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF + +#define GLEW_SGIX_vertex_preclip GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip) + +#endif /* GL_SGIX_vertex_preclip */ + +/* ---------------------- GL_SGIX_vertex_preclip_hint ---------------------- */ + +#ifndef GL_SGIX_vertex_preclip_hint +#define GL_SGIX_vertex_preclip_hint 1 + +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF + +#define GLEW_SGIX_vertex_preclip_hint GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip_hint) + +#endif /* GL_SGIX_vertex_preclip_hint */ + +/* ----------------------------- GL_SGIX_ycrcb ----------------------------- */ + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 + +#define GLEW_SGIX_ycrcb GLEW_GET_VAR(__GLEW_SGIX_ycrcb) + +#endif /* GL_SGIX_ycrcb */ + +/* -------------------------- GL_SGI_color_matrix -------------------------- */ + +#ifndef GL_SGI_color_matrix +#define GL_SGI_color_matrix 1 + +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB + +#define GLEW_SGI_color_matrix GLEW_GET_VAR(__GLEW_SGI_color_matrix) + +#endif /* GL_SGI_color_matrix */ + +/* --------------------------- GL_SGI_color_table -------------------------- */ + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 + +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF + +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void* table); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void* table); + +#define glColorTableParameterfvSGI GLEW_GET_FUN(__glewColorTableParameterfvSGI) +#define glColorTableParameterivSGI GLEW_GET_FUN(__glewColorTableParameterivSGI) +#define glColorTableSGI GLEW_GET_FUN(__glewColorTableSGI) +#define glCopyColorTableSGI GLEW_GET_FUN(__glewCopyColorTableSGI) +#define glGetColorTableParameterfvSGI GLEW_GET_FUN(__glewGetColorTableParameterfvSGI) +#define glGetColorTableParameterivSGI GLEW_GET_FUN(__glewGetColorTableParameterivSGI) +#define glGetColorTableSGI GLEW_GET_FUN(__glewGetColorTableSGI) + +#define GLEW_SGI_color_table GLEW_GET_VAR(__GLEW_SGI_color_table) + +#endif /* GL_SGI_color_table */ + +/* ----------------------- GL_SGI_texture_color_table ---------------------- */ + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 + +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD + +#define GLEW_SGI_texture_color_table GLEW_GET_VAR(__GLEW_SGI_texture_color_table) + +#endif /* GL_SGI_texture_color_table */ + +/* ------------------------- GL_SUNX_constant_data ------------------------- */ + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 + +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 + +typedef void (GLAPIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void); + +#define glFinishTextureSUNX GLEW_GET_FUN(__glewFinishTextureSUNX) + +#define GLEW_SUNX_constant_data GLEW_GET_VAR(__GLEW_SUNX_constant_data) + +#endif /* GL_SUNX_constant_data */ + +/* -------------------- GL_SUN_convolution_border_modes -------------------- */ + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 + +#define GL_WRAP_BORDER_SUN 0x81D4 + +#define GLEW_SUN_convolution_border_modes GLEW_GET_VAR(__GLEW_SUN_convolution_border_modes) + +#endif /* GL_SUN_convolution_border_modes */ + +/* -------------------------- GL_SUN_global_alpha -------------------------- */ + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 + +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA + +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); + +#define glGlobalAlphaFactorbSUN GLEW_GET_FUN(__glewGlobalAlphaFactorbSUN) +#define glGlobalAlphaFactordSUN GLEW_GET_FUN(__glewGlobalAlphaFactordSUN) +#define glGlobalAlphaFactorfSUN GLEW_GET_FUN(__glewGlobalAlphaFactorfSUN) +#define glGlobalAlphaFactoriSUN GLEW_GET_FUN(__glewGlobalAlphaFactoriSUN) +#define glGlobalAlphaFactorsSUN GLEW_GET_FUN(__glewGlobalAlphaFactorsSUN) +#define glGlobalAlphaFactorubSUN GLEW_GET_FUN(__glewGlobalAlphaFactorubSUN) +#define glGlobalAlphaFactoruiSUN GLEW_GET_FUN(__glewGlobalAlphaFactoruiSUN) +#define glGlobalAlphaFactorusSUN GLEW_GET_FUN(__glewGlobalAlphaFactorusSUN) + +#define GLEW_SUN_global_alpha GLEW_GET_VAR(__GLEW_SUN_global_alpha) + +#endif /* GL_SUN_global_alpha */ + +/* --------------------------- GL_SUN_mesh_array --------------------------- */ + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 + +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 + +#define GLEW_SUN_mesh_array GLEW_GET_VAR(__GLEW_SUN_mesh_array) + +#endif /* GL_SUN_mesh_array */ + +/* ------------------------ GL_SUN_read_video_pixels ----------------------- */ + +#ifndef GL_SUN_read_video_pixels +#define GL_SUN_read_video_pixels 1 + +typedef void (GLAPIENTRY * PFNGLREADVIDEOPIXELSSUNPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); + +#define glReadVideoPixelsSUN GLEW_GET_FUN(__glewReadVideoPixelsSUN) + +#define GLEW_SUN_read_video_pixels GLEW_GET_VAR(__GLEW_SUN_read_video_pixels) + +#endif /* GL_SUN_read_video_pixels */ + +/* --------------------------- GL_SUN_slice_accum -------------------------- */ + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 + +#define GL_SLICE_ACCUM_SUN 0x85CC + +#define GLEW_SUN_slice_accum GLEW_GET_VAR(__GLEW_SUN_slice_accum) + +#endif /* GL_SUN_slice_accum */ + +/* -------------------------- GL_SUN_triangle_list ------------------------- */ + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 + +#define GL_RESTART_SUN 0x01 +#define GL_REPLACE_MIDDLE_SUN 0x02 +#define GL_REPLACE_OLDEST_SUN 0x03 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB + +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte* code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint* code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort* code); + +#define glReplacementCodePointerSUN GLEW_GET_FUN(__glewReplacementCodePointerSUN) +#define glReplacementCodeubSUN GLEW_GET_FUN(__glewReplacementCodeubSUN) +#define glReplacementCodeubvSUN GLEW_GET_FUN(__glewReplacementCodeubvSUN) +#define glReplacementCodeuiSUN GLEW_GET_FUN(__glewReplacementCodeuiSUN) +#define glReplacementCodeuivSUN GLEW_GET_FUN(__glewReplacementCodeuivSUN) +#define glReplacementCodeusSUN GLEW_GET_FUN(__glewReplacementCodeusSUN) +#define glReplacementCodeusvSUN GLEW_GET_FUN(__glewReplacementCodeusvSUN) + +#define GLEW_SUN_triangle_list GLEW_GET_VAR(__GLEW_SUN_triangle_list) + +#endif /* GL_SUN_triangle_list */ + +/* ----------------------------- GL_SUN_vertex ----------------------------- */ + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 + +typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint* rc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat* tc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *v); + +#define glColor3fVertex3fSUN GLEW_GET_FUN(__glewColor3fVertex3fSUN) +#define glColor3fVertex3fvSUN GLEW_GET_FUN(__glewColor3fVertex3fvSUN) +#define glColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fSUN) +#define glColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fvSUN) +#define glColor4ubVertex2fSUN GLEW_GET_FUN(__glewColor4ubVertex2fSUN) +#define glColor4ubVertex2fvSUN GLEW_GET_FUN(__glewColor4ubVertex2fvSUN) +#define glColor4ubVertex3fSUN GLEW_GET_FUN(__glewColor4ubVertex3fSUN) +#define glColor4ubVertex3fvSUN GLEW_GET_FUN(__glewColor4ubVertex3fvSUN) +#define glNormal3fVertex3fSUN GLEW_GET_FUN(__glewNormal3fVertex3fSUN) +#define glNormal3fVertex3fvSUN GLEW_GET_FUN(__glewNormal3fVertex3fvSUN) +#define glReplacementCodeuiColor3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fSUN) +#define glReplacementCodeuiColor3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fvSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiColor4ubVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fSUN) +#define glReplacementCodeuiColor4ubVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fvSUN) +#define glReplacementCodeuiNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fSUN) +#define glReplacementCodeuiNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fvSUN) +#define glReplacementCodeuiVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fSUN) +#define glReplacementCodeuiVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fvSUN) +#define glTexCoord2fColor3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fSUN) +#define glTexCoord2fColor3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fvSUN) +#define glTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fSUN) +#define glTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fvSUN) +#define glTexCoord2fColor4ubVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fSUN) +#define glTexCoord2fColor4ubVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fvSUN) +#define glTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fSUN) +#define glTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fvSUN) +#define glTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fSUN) +#define glTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fvSUN) +#define glTexCoord4fColor4fNormal3fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fSUN) +#define glTexCoord4fColor4fNormal3fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fvSUN) +#define glTexCoord4fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fSUN) +#define glTexCoord4fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fvSUN) + +#define GLEW_SUN_vertex GLEW_GET_VAR(__GLEW_SUN_vertex) + +#endif /* GL_SUN_vertex */ + +/* -------------------------- GL_WIN_phong_shading ------------------------- */ + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 + +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB + +#define GLEW_WIN_phong_shading GLEW_GET_VAR(__GLEW_WIN_phong_shading) + +#endif /* GL_WIN_phong_shading */ + +/* -------------------------- GL_WIN_specular_fog -------------------------- */ + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 + +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC + +#define GLEW_WIN_specular_fog GLEW_GET_VAR(__GLEW_WIN_specular_fog) + +#endif /* GL_WIN_specular_fog */ + +/* ---------------------------- GL_WIN_swap_hint --------------------------- */ + +#ifndef GL_WIN_swap_hint +#define GL_WIN_swap_hint 1 + +typedef void (GLAPIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsizei width, GLsizei height); + +#define glAddSwapHintRectWIN GLEW_GET_FUN(__glewAddSwapHintRectWIN) + +#define GLEW_WIN_swap_hint GLEW_GET_VAR(__GLEW_WIN_swap_hint) + +#endif /* GL_WIN_swap_hint */ + +/* ------------------------------------------------------------------------- */ + +#if defined(GLEW_MX) && defined(_WIN32) +#define GLEW_FUN_EXPORT +#else +#define GLEW_FUN_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#if defined(GLEW_MX) +#define GLEW_VAR_EXPORT +#else +#define GLEW_VAR_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#if defined(GLEW_MX) && defined(_WIN32) +struct GLEWContextStruct +{ +#endif /* GLEW_MX */ + +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DPROC __glewTexImage3D; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D; + +GLEW_FUN_EXPORT PFNGLACTIVETEXTUREPROC __glewActiveTexture; +GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv; +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage; + +GLEW_FUN_EXPORT PFNGLBLENDCOLORPROC __glewBlendColor; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONPROC __glewBlendEquation; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate; +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer; +GLEW_FUN_EXPORT PFNGLFOGCOORDDPROC __glewFogCoordd; +GLEW_FUN_EXPORT PFNGLFOGCOORDDVPROC __glewFogCoorddv; +GLEW_FUN_EXPORT PFNGLFOGCOORDFPROC __glewFogCoordf; +GLEW_FUN_EXPORT PFNGLFOGCOORDFVPROC __glewFogCoordfv; +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFPROC __glewPointParameterf; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIPROC __glewPointParameteri; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DPROC __glewWindowPos2d; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FPROC __glewWindowPos2f; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IPROC __glewWindowPos2i; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SPROC __glewWindowPos2s; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DPROC __glewWindowPos3d; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FPROC __glewWindowPos3f; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IPROC __glewWindowPos3i; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SPROC __glewWindowPos3s; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYPROC __glewBeginQuery; +GLEW_FUN_EXPORT PFNGLBINDBUFFERPROC __glewBindBuffer; +GLEW_FUN_EXPORT PFNGLBUFFERDATAPROC __glewBufferData; +GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAPROC __glewBufferSubData; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERSPROC __glewDeleteBuffers; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESPROC __glewDeleteQueries; +GLEW_FUN_EXPORT PFNGLENDQUERYPROC __glewEndQuery; +GLEW_FUN_EXPORT PFNGLGENBUFFERSPROC __glewGenBuffers; +GLEW_FUN_EXPORT PFNGLGENQUERIESPROC __glewGenQueries; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv; +GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv; +GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv; +GLEW_FUN_EXPORT PFNGLGETQUERYIVPROC __glewGetQueryiv; +GLEW_FUN_EXPORT PFNGLISBUFFERPROC __glewIsBuffer; +GLEW_FUN_EXPORT PFNGLISQUERYPROC __glewIsQuery; +GLEW_FUN_EXPORT PFNGLMAPBUFFERPROC __glewMapBuffer; +GLEW_FUN_EXPORT PFNGLUNMAPBUFFERPROC __glewUnmapBuffer; + +GLEW_FUN_EXPORT PFNGLATTACHSHADERPROC __glewAttachShader; +GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate; +GLEW_FUN_EXPORT PFNGLCOMPILESHADERPROC __glewCompileShader; +GLEW_FUN_EXPORT PFNGLCREATEPROGRAMPROC __glewCreateProgram; +GLEW_FUN_EXPORT PFNGLCREATESHADERPROC __glewCreateShader; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPROC __glewDeleteProgram; +GLEW_FUN_EXPORT PFNGLDELETESHADERPROC __glewDeleteShader; +GLEW_FUN_EXPORT PFNGLDETACHSHADERPROC __glewDetachShader; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray; +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSPROC __glewDrawBuffers; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray; +GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform; +GLEW_FUN_EXPORT PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders; +GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation; +GLEW_FUN_EXPORT PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVPROC __glewGetProgramiv; +GLEW_FUN_EXPORT PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog; +GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEPROC __glewGetShaderSource; +GLEW_FUN_EXPORT PFNGLGETSHADERIVPROC __glewGetShaderiv; +GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation; +GLEW_FUN_EXPORT PFNGLGETUNIFORMFVPROC __glewGetUniformfv; +GLEW_FUN_EXPORT PFNGLGETUNIFORMIVPROC __glewGetUniformiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv; +GLEW_FUN_EXPORT PFNGLISPROGRAMPROC __glewIsProgram; +GLEW_FUN_EXPORT PFNGLISSHADERPROC __glewIsShader; +GLEW_FUN_EXPORT PFNGLLINKPROGRAMPROC __glewLinkProgram; +GLEW_FUN_EXPORT PFNGLSHADERSOURCEPROC __glewShaderSource; +GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate; +GLEW_FUN_EXPORT PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate; +GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate; +GLEW_FUN_EXPORT PFNGLUNIFORM1FPROC __glewUniform1f; +GLEW_FUN_EXPORT PFNGLUNIFORM1FVPROC __glewUniform1fv; +GLEW_FUN_EXPORT PFNGLUNIFORM1IPROC __glewUniform1i; +GLEW_FUN_EXPORT PFNGLUNIFORM1IVPROC __glewUniform1iv; +GLEW_FUN_EXPORT PFNGLUNIFORM2FPROC __glewUniform2f; +GLEW_FUN_EXPORT PFNGLUNIFORM2FVPROC __glewUniform2fv; +GLEW_FUN_EXPORT PFNGLUNIFORM2IPROC __glewUniform2i; +GLEW_FUN_EXPORT PFNGLUNIFORM2IVPROC __glewUniform2iv; +GLEW_FUN_EXPORT PFNGLUNIFORM3FPROC __glewUniform3f; +GLEW_FUN_EXPORT PFNGLUNIFORM3FVPROC __glewUniform3fv; +GLEW_FUN_EXPORT PFNGLUNIFORM3IPROC __glewUniform3i; +GLEW_FUN_EXPORT PFNGLUNIFORM3IVPROC __glewUniform3iv; +GLEW_FUN_EXPORT PFNGLUNIFORM4FPROC __glewUniform4f; +GLEW_FUN_EXPORT PFNGLUNIFORM4FVPROC __glewUniform4fv; +GLEW_FUN_EXPORT PFNGLUNIFORM4IPROC __glewUniform4i; +GLEW_FUN_EXPORT PFNGLUNIFORM4IVPROC __glewUniform4iv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMPROC __glewUseProgram; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPROC __glewValidateProgram; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer; + +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv; + +GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender; +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback; +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation; +GLEW_FUN_EXPORT PFNGLCLAMPCOLORPROC __glewClampColor; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERFIPROC __glewClearBufferfi; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERFVPROC __glewClearBufferfv; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERIVPROC __glewClearBufferiv; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv; +GLEW_FUN_EXPORT PFNGLCOLORMASKIPROC __glewColorMaski; +GLEW_FUN_EXPORT PFNGLDISABLEIPROC __glewDisablei; +GLEW_FUN_EXPORT PFNGLENABLEIPROC __glewEnablei; +GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback; +GLEW_FUN_EXPORT PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v; +GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation; +GLEW_FUN_EXPORT PFNGLGETSTRINGIPROC __glewGetStringi; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv; +GLEW_FUN_EXPORT PFNGLISENABLEDIPROC __glewIsEnabledi; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIPROC __glewUniform1ui; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIVPROC __glewUniform1uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIPROC __glewUniform2ui; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIVPROC __glewUniform2uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIPROC __glewUniform3ui; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIVPROC __glewUniform3uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIPROC __glewUniform4ui; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIVPROC __glewUniform4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDPROC __glewDrawArraysInstanced; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDPROC __glewDrawElementsInstanced; +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXPROC __glewPrimitiveRestartIndex; +GLEW_FUN_EXPORT PFNGLTEXBUFFERPROC __glewTexBuffer; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREPROC __glewFramebufferTexture; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERI64VPROC __glewGetBufferParameteri64v; +GLEW_FUN_EXPORT PFNGLGETINTEGER64I_VPROC __glewGetInteger64i_v; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIPROC __glewBlendEquationSeparatei; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIPROC __glewBlendEquationi; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIPROC __glewBlendFuncSeparatei; +GLEW_FUN_EXPORT PFNGLBLENDFUNCIPROC __glewBlendFunci; +GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGPROC __glewMinSampleShading; + +GLEW_FUN_EXPORT PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONINDEXEDAMDPROC __glewBlendEquationIndexedAMD; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC __glewBlendEquationSeparateIndexedAMD; +GLEW_FUN_EXPORT PFNGLBLENDFUNCINDEXEDAMDPROC __glewBlendFuncIndexedAMD; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC __glewBlendFuncSeparateIndexedAMD; + +GLEW_FUN_EXPORT PFNGLBEGINPERFMONITORAMDPROC __glewBeginPerfMonitorAMD; +GLEW_FUN_EXPORT PFNGLDELETEPERFMONITORSAMDPROC __glewDeletePerfMonitorsAMD; +GLEW_FUN_EXPORT PFNGLENDPERFMONITORAMDPROC __glewEndPerfMonitorAMD; +GLEW_FUN_EXPORT PFNGLGENPERFMONITORSAMDPROC __glewGenPerfMonitorsAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERDATAAMDPROC __glewGetPerfMonitorCounterDataAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERINFOAMDPROC __glewGetPerfMonitorCounterInfoAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC __glewGetPerfMonitorCounterStringAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSAMDPROC __glewGetPerfMonitorCountersAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSTRINGAMDPROC __glewGetPerfMonitorGroupStringAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSAMDPROC __glewGetPerfMonitorGroupsAMD; +GLEW_FUN_EXPORT PFNGLSELECTPERFMONITORCOUNTERSAMDPROC __glewSelectPerfMonitorCountersAMD; + +GLEW_FUN_EXPORT PFNGLTESSELLATIONFACTORAMDPROC __glewTessellationFactorAMD; +GLEW_FUN_EXPORT PFNGLTESSELLATIONMODEAMDPROC __glewTessellationModeAMD; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE; + +GLEW_FUN_EXPORT PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE; +GLEW_FUN_EXPORT PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE; +GLEW_FUN_EXPORT PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE; +GLEW_FUN_EXPORT PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE; +GLEW_FUN_EXPORT PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE; +GLEW_FUN_EXPORT PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE; +GLEW_FUN_EXPORT PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE; +GLEW_FUN_EXPORT PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE; + +GLEW_FUN_EXPORT PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE; +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVAPPLEPROC __glewGetObjectParameterivAPPLE; +GLEW_FUN_EXPORT PFNGLOBJECTPURGEABLEAPPLEPROC __glewObjectPurgeableAPPLE; +GLEW_FUN_EXPORT PFNGLOBJECTUNPURGEABLEAPPLEPROC __glewObjectUnpurgeableAPPLE; + +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE; +GLEW_FUN_EXPORT PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE; +GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE; +GLEW_FUN_EXPORT PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE; + +GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBAPPLEPROC __glewDisableVertexAttribAPPLE; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBAPPLEPROC __glewEnableVertexAttribAPPLE; +GLEW_FUN_EXPORT PFNGLISVERTEXATTRIBENABLEDAPPLEPROC __glewIsVertexAttribEnabledAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1DAPPLEPROC __glewMapVertexAttrib1dAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1FAPPLEPROC __glewMapVertexAttrib1fAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2DAPPLEPROC __glewMapVertexAttrib2dAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2FAPPLEPROC __glewMapVertexAttrib2fAPPLE; + +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONINDEXEDPROC __glewBindFragDataLocationIndexed; +GLEW_FUN_EXPORT PFNGLGETFRAGDATAINDEXPROC __glewGetFragDataIndex; + +GLEW_FUN_EXPORT PFNGLCLAMPCOLORARBPROC __glewClampColorARB; + +GLEW_FUN_EXPORT PFNGLCOPYBUFFERSUBDATAPROC __glewCopyBufferSubData; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIARBPROC __glewBlendEquationSeparateiARB; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIARBPROC __glewBlendEquationiARB; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIARBPROC __glewBlendFuncSeparateiARB; +GLEW_FUN_EXPORT PFNGLBLENDFUNCIARBPROC __glewBlendFunciARB; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSBASEVERTEXPROC __glewDrawElementsBaseVertex; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __glewDrawElementsInstancedBaseVertex; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC __glewDrawRangeElementsBaseVertex; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC __glewMultiDrawElementsBaseVertex; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINDIRECTPROC __glewDrawArraysIndirect; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINDIRECTPROC __glewDrawElementsIndirect; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB; + +GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer; +GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer; +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer; +GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus; +GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers; +GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer; +GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers; +GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers; +GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv; +GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv; +GLEW_FUN_EXPORT PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer; +GLEW_FUN_EXPORT PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB; + +GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEPROC __glewColorSubTable; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPROC __glewColorTable; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv; +GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable; +GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPROC __glewGetColorTable; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPROC __glewGetHistogram; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv; +GLEW_FUN_EXPORT PFNGLGETMINMAXPROC __glewGetMinmax; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv; +GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter; +GLEW_FUN_EXPORT PFNGLHISTOGRAMPROC __glewHistogram; +GLEW_FUN_EXPORT PFNGLMINMAXPROC __glewMinmax; +GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMPROC __glewResetHistogram; +GLEW_FUN_EXPORT PFNGLRESETMINMAXPROC __glewResetMinmax; +GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D; + +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB; + +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange; +GLEW_FUN_EXPORT PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange; + +GLEW_FUN_EXPORT PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB; + +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB; + +GLEW_FUN_EXPORT PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB; +GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYARBPROC __glewBeginQueryARB; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB; +GLEW_FUN_EXPORT PFNGLENDQUERYARBPROC __glewEndQueryARB; +GLEW_FUN_EXPORT PFNGLGENQUERIESARBPROC __glewGenQueriesARB; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB; +GLEW_FUN_EXPORT PFNGLGETQUERYIVARBPROC __glewGetQueryivARB; +GLEW_FUN_EXPORT PFNGLISQUERYARBPROC __glewIsQueryARB; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB; + +GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXPROC __glewProvokingVertex; + +GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGARBPROC __glewMinSampleShadingARB; + +GLEW_FUN_EXPORT PFNGLBINDSAMPLERPROC __glewBindSampler; +GLEW_FUN_EXPORT PFNGLDELETESAMPLERSPROC __glewDeleteSamplers; +GLEW_FUN_EXPORT PFNGLGENSAMPLERSPROC __glewGenSamplers; +GLEW_FUN_EXPORT PFNGLISSAMPLERPROC __glewIsSampler; + +GLEW_FUN_EXPORT PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB; +GLEW_FUN_EXPORT PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB; +GLEW_FUN_EXPORT PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB; +GLEW_FUN_EXPORT PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB; +GLEW_FUN_EXPORT PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB; +GLEW_FUN_EXPORT PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB; +GLEW_FUN_EXPORT PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB; +GLEW_FUN_EXPORT PFNGLGETHANDLEARBPROC __glewGetHandleARB; +GLEW_FUN_EXPORT PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB; +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB; +GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB; +GLEW_FUN_EXPORT PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB; +GLEW_FUN_EXPORT PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1FARBPROC __glewUniform1fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1IARBPROC __glewUniform1iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2FARBPROC __glewUniform2fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2IARBPROC __glewUniform2iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3FARBPROC __glewUniform3fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3IARBPROC __glewUniform3iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4FARBPROC __glewUniform4fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4IARBPROC __glewUniform4iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB; + +GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINENAMEPROC __glewGetActiveSubroutineName; +GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __glewGetActiveSubroutineUniformName; +GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC __glewGetActiveSubroutineUniformiv; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTAGEIVPROC __glewGetProgramStageiv; +GLEW_FUN_EXPORT PFNGLGETSUBROUTINEINDEXPROC __glewGetSubroutineIndex; +GLEW_FUN_EXPORT PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC __glewGetSubroutineUniformLocation; +GLEW_FUN_EXPORT PFNGLGETUNIFORMSUBROUTINEUIVPROC __glewGetUniformSubroutineuiv; +GLEW_FUN_EXPORT PFNGLUNIFORMSUBROUTINESUIVPROC __glewUniformSubroutinesuiv; + +GLEW_FUN_EXPORT PFNGLCOMPILESHADERINCLUDEARBPROC __glewCompileShaderIncludeARB; +GLEW_FUN_EXPORT PFNGLDELETENAMEDSTRINGARBPROC __glewDeleteNamedStringARB; +GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGARBPROC __glewGetNamedStringARB; +GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGIVARBPROC __glewGetNamedStringivARB; +GLEW_FUN_EXPORT PFNGLISNAMEDSTRINGARBPROC __glewIsNamedStringARB; +GLEW_FUN_EXPORT PFNGLNAMEDSTRINGARBPROC __glewNamedStringARB; + +GLEW_FUN_EXPORT PFNGLCLIENTWAITSYNCPROC __glewClientWaitSync; +GLEW_FUN_EXPORT PFNGLDELETESYNCPROC __glewDeleteSync; +GLEW_FUN_EXPORT PFNGLFENCESYNCPROC __glewFenceSync; +GLEW_FUN_EXPORT PFNGLGETINTEGER64VPROC __glewGetInteger64v; +GLEW_FUN_EXPORT PFNGLGETSYNCIVPROC __glewGetSynciv; +GLEW_FUN_EXPORT PFNGLISSYNCPROC __glewIsSync; +GLEW_FUN_EXPORT PFNGLWAITSYNCPROC __glewWaitSync; + +GLEW_FUN_EXPORT PFNGLPATCHPARAMETERFVPROC __glewPatchParameterfv; +GLEW_FUN_EXPORT PFNGLPATCHPARAMETERIPROC __glewPatchParameteri; + +GLEW_FUN_EXPORT PFNGLTEXBUFFERARBPROC __glewTexBufferARB; + +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB; + +GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVPROC __glewGetMultisamplefv; +GLEW_FUN_EXPORT PFNGLSAMPLEMASKIPROC __glewSampleMaski; +GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLEPROC __glewTexImage2DMultisample; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLEPROC __glewTexImage3DMultisample; + +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VPROC __glewGetQueryObjecti64v; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VPROC __glewGetQueryObjectui64v; +GLEW_FUN_EXPORT PFNGLQUERYCOUNTERPROC __glewQueryCounter; + +GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKPROC __glewBindTransformFeedback; +GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSPROC __glewDeleteTransformFeedbacks; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKPROC __glewDrawTransformFeedback; +GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSPROC __glewGenTransformFeedbacks; +GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKPROC __glewIsTransformFeedback; +GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKPROC __glewPauseTransformFeedback; +GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKPROC __glewResumeTransformFeedback; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYINDEXEDPROC __glewBeginQueryIndexed; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC __glewDrawTransformFeedbackStream; +GLEW_FUN_EXPORT PFNGLENDQUERYINDEXEDPROC __glewEndQueryIndexed; +GLEW_FUN_EXPORT PFNGLGETQUERYINDEXEDIVPROC __glewGetQueryIndexediv; + +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB; + +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEPROC __glewBindBufferBase; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC __glewGetActiveUniformBlockName; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKIVPROC __glewGetActiveUniformBlockiv; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMNAMEPROC __glewGetActiveUniformName; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMSIVPROC __glewGetActiveUniformsiv; +GLEW_FUN_EXPORT PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v; +GLEW_FUN_EXPORT PFNGLGETUNIFORMBLOCKINDEXPROC __glewGetUniformBlockIndex; +GLEW_FUN_EXPORT PFNGLGETUNIFORMINDICESPROC __glewGetUniformIndices; +GLEW_FUN_EXPORT PFNGLUNIFORMBLOCKBINDINGPROC __glewUniformBlockBinding; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays; +GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays; +GLEW_FUN_EXPORT PFNGLISVERTEXARRAYPROC __glewIsVertexArray; + +GLEW_FUN_EXPORT PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB; +GLEW_FUN_EXPORT PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB; +GLEW_FUN_EXPORT PFNGLWEIGHTBVARBPROC __glewWeightbvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTDVARBPROC __glewWeightdvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTFVARBPROC __glewWeightfvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTIVARBPROC __glewWeightivARB; +GLEW_FUN_EXPORT PFNGLWEIGHTSVARBPROC __glewWeightsvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUBVARBPROC __glewWeightubvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUIVARBPROC __glewWeightuivARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUSVARBPROC __glewWeightusvARB; + +GLEW_FUN_EXPORT PFNGLBINDBUFFERARBPROC __glewBindBufferARB; +GLEW_FUN_EXPORT PFNGLBUFFERDATAARBPROC __glewBufferDataARB; +GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB; +GLEW_FUN_EXPORT PFNGLGENBUFFERSARBPROC __glewGenBuffersARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB; +GLEW_FUN_EXPORT PFNGLISBUFFERARBPROC __glewIsBufferARB; +GLEW_FUN_EXPORT PFNGLMAPBUFFERARBPROC __glewMapBufferARB; +GLEW_FUN_EXPORT PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB; + +GLEW_FUN_EXPORT PFNGLBINDPROGRAMARBPROC __glewBindProgramARB; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB; +GLEW_FUN_EXPORT PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB; +GLEW_FUN_EXPORT PFNGLISPROGRAMARBPROC __glewIsProgramARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB; + +GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB; +GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB; +GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB; + +GLEW_FUN_EXPORT PFNGLCOLORP3UIPROC __glewColorP3ui; +GLEW_FUN_EXPORT PFNGLCOLORP3UIVPROC __glewColorP3uiv; +GLEW_FUN_EXPORT PFNGLCOLORP4UIPROC __glewColorP4ui; +GLEW_FUN_EXPORT PFNGLCOLORP4UIVPROC __glewColorP4uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIPROC __glewMultiTexCoordP1ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIVPROC __glewMultiTexCoordP1uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIPROC __glewMultiTexCoordP2ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIVPROC __glewMultiTexCoordP2uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIPROC __glewMultiTexCoordP3ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIVPROC __glewMultiTexCoordP3uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIPROC __glewMultiTexCoordP4ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIVPROC __glewMultiTexCoordP4uiv; +GLEW_FUN_EXPORT PFNGLNORMALP3UIPROC __glewNormalP3ui; +GLEW_FUN_EXPORT PFNGLNORMALP3UIVPROC __glewNormalP3uiv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIPROC __glewSecondaryColorP3ui; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIVPROC __glewSecondaryColorP3uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIPROC __glewTexCoordP1ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIVPROC __glewTexCoordP1uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIPROC __glewTexCoordP2ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIVPROC __glewTexCoordP2uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIPROC __glewTexCoordP3ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIVPROC __glewTexCoordP3uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIPROC __glewTexCoordP4ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIVPROC __glewTexCoordP4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIPROC __glewVertexAttribP1ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIVPROC __glewVertexAttribP1uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIPROC __glewVertexAttribP2ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIVPROC __glewVertexAttribP2uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIPROC __glewVertexAttribP3ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIVPROC __glewVertexAttribP3uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIPROC __glewVertexAttribP4ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIVPROC __glewVertexAttribP4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXP2UIPROC __glewVertexP2ui; +GLEW_FUN_EXPORT PFNGLVERTEXP2UIVPROC __glewVertexP2uiv; +GLEW_FUN_EXPORT PFNGLVERTEXP3UIPROC __glewVertexP3ui; +GLEW_FUN_EXPORT PFNGLVERTEXP3UIVPROC __glewVertexP3uiv; +GLEW_FUN_EXPORT PFNGLVERTEXP4UIPROC __glewVertexP4ui; +GLEW_FUN_EXPORT PFNGLVERTEXP4UIVPROC __glewVertexP4uiv; + +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI; +GLEW_FUN_EXPORT PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI; + +GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI; +GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI; +GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI; +GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI; + +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI; +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI; +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI; +GLEW_FUN_EXPORT PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI; +GLEW_FUN_EXPORT PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI; +GLEW_FUN_EXPORT PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI; +GLEW_FUN_EXPORT PFNGLSAMPLEMAPATIPROC __glewSampleMapATI; +GLEW_FUN_EXPORT PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI; + +GLEW_FUN_EXPORT PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI; +GLEW_FUN_EXPORT PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI; + +GLEW_FUN_EXPORT PFNGLPNTRIANGLESFATIPROC __glPNTrianglewesfATI; +GLEW_FUN_EXPORT PFNGLPNTRIANGLESIATIPROC __glPNTrianglewesiATI; + +GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI; +GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI; + +GLEW_FUN_EXPORT PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI; +GLEW_FUN_EXPORT PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI; +GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI; +GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI; +GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI; +GLEW_FUN_EXPORT PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI; +GLEW_FUN_EXPORT PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI; +GLEW_FUN_EXPORT PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI; + +GLEW_FUN_EXPORT PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI; +GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI; +GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI; + +GLEW_FUN_EXPORT PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT; +GLEW_FUN_EXPORT PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT; +GLEW_FUN_EXPORT PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT; + +GLEW_FUN_EXPORT PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT; + +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT; + +GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT; +GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT; + +GLEW_FUN_EXPORT PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT; +GLEW_FUN_EXPORT PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT; + +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT; +GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT; + +GLEW_FUN_EXPORT PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT; +GLEW_FUN_EXPORT PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT; + +GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT; + +GLEW_FUN_EXPORT PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT; +GLEW_FUN_EXPORT PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT; + +GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT; + +GLEW_FUN_EXPORT PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT; +GLEW_FUN_EXPORT PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT; +GLEW_FUN_EXPORT PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT; +GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEIEXTPROC __glewDisableClientStateiEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC __glewDisableVertexArrayAttribEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYEXTPROC __glewDisableVertexArrayEXT; +GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT; +GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEIEXTPROC __glewEnableClientStateiEXT; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYATTRIBEXTPROC __glewEnableVertexArrayAttribEXT; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYEXTPROC __glewEnableVertexArrayEXT; +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC __glewFlushMappedNamedBufferRangeEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT; +GLEW_FUN_EXPORT PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT; +GLEW_FUN_EXPORT PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT; +GLEW_FUN_EXPORT PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETDOUBLEI_VEXTPROC __glewGetDoublei_vEXT; +GLEW_FUN_EXPORT PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETFLOATI_VEXTPROC __glewGetFloati_vEXT; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETPOINTERI_VEXTPROC __glewGetPointeri_vEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC __glewGetVertexArrayIntegeri_vEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERVEXTPROC __glewGetVertexArrayIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC __glewGetVertexArrayPointeri_vEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERVEXTPROC __glewGetVertexArrayPointervEXT; +GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT; +GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERRANGEEXTPROC __glewMapNamedBufferRangeEXT; +GLEW_FUN_EXPORT PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT; +GLEW_FUN_EXPORT PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT; +GLEW_FUN_EXPORT PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT; +GLEW_FUN_EXPORT PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT; +GLEW_FUN_EXPORT PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT; +GLEW_FUN_EXPORT PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT; +GLEW_FUN_EXPORT PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC __glewNamedCopyBufferSubDataEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT; +GLEW_FUN_EXPORT PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT; +GLEW_FUN_EXPORT PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYCOLOROFFSETEXTPROC __glewVertexArrayColorOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC __glewVertexArrayEdgeFlagOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC __glewVertexArrayFogCoordOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYINDEXOFFSETEXTPROC __glewVertexArrayIndexOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC __glewVertexArrayMultiTexCoordOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYNORMALOFFSETEXTPROC __glewVertexArrayNormalOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC __glewVertexArraySecondaryColorOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC __glewVertexArrayTexCoordOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC __glewVertexArrayVertexAttribIOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC __glewVertexArrayVertexAttribOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC __glewVertexArrayVertexOffsetEXT; + +GLEW_FUN_EXPORT PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT; +GLEW_FUN_EXPORT PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT; +GLEW_FUN_EXPORT PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT; +GLEW_FUN_EXPORT PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT; +GLEW_FUN_EXPORT PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT; + +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT; + +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT; + +GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT; +GLEW_FUN_EXPORT PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT; + +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT; + +GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT; +GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT; +GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT; +GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT; +GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT; +GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT; +GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT; +GLEW_FUN_EXPORT PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT; + +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT; + +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT; + +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT; +GLEW_FUN_EXPORT PFNGLHISTOGRAMEXTPROC __glewHistogramEXT; +GLEW_FUN_EXPORT PFNGLMINMAXEXTPROC __glewMinmaxEXT; +GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT; +GLEW_FUN_EXPORT PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT; + +GLEW_FUN_EXPORT PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT; + +GLEW_FUN_EXPORT PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT; + +GLEW_FUN_EXPORT PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT; +GLEW_FUN_EXPORT PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT; + +GLEW_FUN_EXPORT PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT; +GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT; + +GLEW_FUN_EXPORT PFNGLCOLORTABLEEXTPROC __glewColorTableEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT; + +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT; + +GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT; + +GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXEXTPROC __glewProvokingVertexEXT; + +GLEW_FUN_EXPORT PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT; +GLEW_FUN_EXPORT PFNGLENDSCENEEXTPROC __glewEndSceneEXT; + +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT; + +GLEW_FUN_EXPORT PFNGLACTIVEPROGRAMEXTPROC __glewActiveProgramEXT; +GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMEXTPROC __glewCreateShaderProgramEXT; +GLEW_FUN_EXPORT PFNGLUSESHADERPROGRAMEXTPROC __glewUseShaderProgramEXT; + +GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTUREEXTPROC __glewBindImageTextureEXT; +GLEW_FUN_EXPORT PFNGLMEMORYBARRIEREXTPROC __glewMemoryBarrierEXT; + +GLEW_FUN_EXPORT PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT; + +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT; + +GLEW_FUN_EXPORT PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT; + +GLEW_FUN_EXPORT PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT; +GLEW_FUN_EXPORT PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT; + +GLEW_FUN_EXPORT PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT; +GLEW_FUN_EXPORT PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT; +GLEW_FUN_EXPORT PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT; +GLEW_FUN_EXPORT PFNGLISTEXTUREEXTPROC __glewIsTextureEXT; +GLEW_FUN_EXPORT PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT; + +GLEW_FUN_EXPORT PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT; + +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT; + +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT; + +GLEW_FUN_EXPORT PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT; +GLEW_FUN_EXPORT PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT; +GLEW_FUN_EXPORT PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT; +GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT; +GLEW_FUN_EXPORT PFNGLGETPOINTERVEXTPROC __glewGetPointervEXT; +GLEW_FUN_EXPORT PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT; +GLEW_FUN_EXPORT PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLDVEXTPROC __glewGetVertexAttribLdvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC __glewVertexArrayVertexAttribLOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DEXTPROC __glewVertexAttribL1dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DVEXTPROC __glewVertexAttribL1dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DEXTPROC __glewVertexAttribL2dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DVEXTPROC __glewVertexAttribL2dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DEXTPROC __glewVertexAttribL3dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DVEXTPROC __glewVertexAttribL3dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DEXTPROC __glewVertexAttribL4dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DVEXTPROC __glewVertexAttribL4dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLPOINTEREXTPROC __glewVertexAttribLPointerEXT; + +GLEW_FUN_EXPORT PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT; +GLEW_FUN_EXPORT PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT; +GLEW_FUN_EXPORT PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT; +GLEW_FUN_EXPORT PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT; +GLEW_FUN_EXPORT PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT; +GLEW_FUN_EXPORT PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT; +GLEW_FUN_EXPORT PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT; +GLEW_FUN_EXPORT PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT; +GLEW_FUN_EXPORT PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT; +GLEW_FUN_EXPORT PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT; +GLEW_FUN_EXPORT PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT; +GLEW_FUN_EXPORT PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT; +GLEW_FUN_EXPORT PFNGLSWIZZLEEXTPROC __glewSwizzleEXT; +GLEW_FUN_EXPORT PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT; +GLEW_FUN_EXPORT PFNGLVARIANTBVEXTPROC __glewVariantbvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTDVEXTPROC __glewVariantdvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTFVEXTPROC __glewVariantfvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTIVEXTPROC __glewVariantivEXT; +GLEW_FUN_EXPORT PFNGLVARIANTSVEXTPROC __glewVariantsvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT; +GLEW_FUN_EXPORT PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT; + +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT; + +GLEW_FUN_EXPORT PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY; + +GLEW_FUN_EXPORT PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY; + +GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP; +GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP; + +GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM; +GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM; + +GLEW_FUN_EXPORT PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM; +GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM; +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM; +GLEW_FUN_EXPORT PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM; +GLEW_FUN_EXPORT PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM; + +GLEW_FUN_EXPORT PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL; +GLEW_FUN_EXPORT PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL; + +GLEW_FUN_EXPORT PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL; +GLEW_FUN_EXPORT PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL; + +GLEW_FUN_EXPORT PFNGLBUFFERREGIONENABLEDEXTPROC __glewBufferRegionEnabledEXT; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERREGIONEXTPROC __glewDeleteBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLDRAWBUFFERREGIONEXTPROC __glewDrawBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLNEWBUFFERREGIONEXTPROC __glewNewBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLREADBUFFERREGIONEXTPROC __glewReadBufferRegionEXT; + +GLEW_FUN_EXPORT PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA; + +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA; + +GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV; +GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV; + +GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV; + +GLEW_FUN_EXPORT PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV; +GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV; + +GLEW_FUN_EXPORT PFNGLEVALMAPSNVPROC __glewEvalMapsNV; +GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV; +GLEW_FUN_EXPORT PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV; +GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV; +GLEW_FUN_EXPORT PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV; +GLEW_FUN_EXPORT PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV; +GLEW_FUN_EXPORT PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV; + +GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV; +GLEW_FUN_EXPORT PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV; +GLEW_FUN_EXPORT PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV; + +GLEW_FUN_EXPORT PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV; +GLEW_FUN_EXPORT PFNGLFINISHFENCENVPROC __glewFinishFenceNV; +GLEW_FUN_EXPORT PFNGLGENFENCESNVPROC __glewGenFencesNV; +GLEW_FUN_EXPORT PFNGLGETFENCEIVNVPROC __glewGetFenceivNV; +GLEW_FUN_EXPORT PFNGLISFENCENVPROC __glewIsFenceNV; +GLEW_FUN_EXPORT PFNGLSETFENCENVPROC __glewSetFenceNV; +GLEW_FUN_EXPORT PFNGLTESTFENCENVPROC __glewTestFenceNV; + +GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV; + +GLEW_FUN_EXPORT PFNGLGETUNIFORMI64VNVPROC __glewGetUniformi64vNV; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUI64VNVPROC __glewGetUniformui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64NVPROC __glewProgramUniform1i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64VNVPROC __glewProgramUniform1i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64NVPROC __glewProgramUniform1ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64VNVPROC __glewProgramUniform1ui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64NVPROC __glewProgramUniform2i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64VNVPROC __glewProgramUniform2i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64NVPROC __glewProgramUniform2ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64VNVPROC __glewProgramUniform2ui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64NVPROC __glewProgramUniform3i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64VNVPROC __glewProgramUniform3i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64NVPROC __glewProgramUniform3ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64VNVPROC __glewProgramUniform3ui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64NVPROC __glewProgramUniform4i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64VNVPROC __glewProgramUniform4i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64NVPROC __glewProgramUniform4ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64VNVPROC __glewProgramUniform4ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM1I64NVPROC __glewUniform1i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM1I64VNVPROC __glewUniform1i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM1UI64NVPROC __glewUniform1ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM1UI64VNVPROC __glewUniform1ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM2I64NVPROC __glewUniform2i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM2I64VNVPROC __glewUniform2i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM2UI64NVPROC __glewUniform2ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM2UI64VNVPROC __glewUniform2ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM3I64NVPROC __glewUniform3i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM3I64VNVPROC __glewUniform3i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM3UI64NVPROC __glewUniform3ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM3UI64VNVPROC __glewUniform3ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM4I64NVPROC __glewUniform4i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM4I64VNVPROC __glewUniform4i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM4UI64NVPROC __glewUniform4ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM4UI64VNVPROC __glewUniform4ui64vNV; + +GLEW_FUN_EXPORT PFNGLCOLOR3HNVPROC __glewColor3hNV; +GLEW_FUN_EXPORT PFNGLCOLOR3HVNVPROC __glewColor3hvNV; +GLEW_FUN_EXPORT PFNGLCOLOR4HNVPROC __glewColor4hNV; +GLEW_FUN_EXPORT PFNGLCOLOR4HVNVPROC __glewColor4hvNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDHNVPROC __glewFogCoordhNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV; +GLEW_FUN_EXPORT PFNGLNORMAL3HNVPROC __glewNormal3hNV; +GLEW_FUN_EXPORT PFNGLNORMAL3HVNVPROC __glewNormal3hvNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX2HNVPROC __glewVertex2hNV; +GLEW_FUN_EXPORT PFNGLVERTEX2HVNVPROC __glewVertex2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX3HNVPROC __glewVertex3hNV; +GLEW_FUN_EXPORT PFNGLVERTEX3HVNVPROC __glewVertex3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX4HNVPROC __glewVertex4hNV; +GLEW_FUN_EXPORT PFNGLVERTEX4HVNVPROC __glewVertex4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV; + +GLEW_FUN_EXPORT PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV; +GLEW_FUN_EXPORT PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV; +GLEW_FUN_EXPORT PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV; +GLEW_FUN_EXPORT PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV; +GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV; +GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV; +GLEW_FUN_EXPORT PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV; + +GLEW_FUN_EXPORT PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV; +GLEW_FUN_EXPORT PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV; + +GLEW_FUN_EXPORT PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV; +GLEW_FUN_EXPORT PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV; +GLEW_FUN_EXPORT PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV; + +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV; +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV; + +GLEW_FUN_EXPORT PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV; +GLEW_FUN_EXPORT PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV; +GLEW_FUN_EXPORT PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV; +GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV; + +GLEW_FUN_EXPORT PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV; + +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERUI64VNVPROC __glewGetBufferParameterui64vNV; +GLEW_FUN_EXPORT PFNGLGETINTEGERUI64VNVPROC __glewGetIntegerui64vNV; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC __glewGetNamedBufferParameterui64vNV; +GLEW_FUN_EXPORT PFNGLISBUFFERRESIDENTNVPROC __glewIsBufferResidentNV; +GLEW_FUN_EXPORT PFNGLISNAMEDBUFFERRESIDENTNVPROC __glewIsNamedBufferResidentNV; +GLEW_FUN_EXPORT PFNGLMAKEBUFFERNONRESIDENTNVPROC __glewMakeBufferNonResidentNV; +GLEW_FUN_EXPORT PFNGLMAKEBUFFERRESIDENTNVPROC __glewMakeBufferResidentNV; +GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC __glewMakeNamedBufferNonResidentNV; +GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERRESIDENTNVPROC __glewMakeNamedBufferResidentNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64NVPROC __glewProgramUniformui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64VNVPROC __glewProgramUniformui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORMUI64NVPROC __glewUniformui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORMUI64VNVPROC __glewUniformui64vNV; + +GLEW_FUN_EXPORT PFNGLPATCHPARAMETERFVNVPROC __glewPatchParameterfvNV; +GLEW_FUN_EXPORT PFNGLPATCHPARAMETERINVPROC __glewPatchParameteriNV; + +GLEW_FUN_EXPORT PFNGLTEXTUREBARRIERNVPROC __glewTextureBarrierNV; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTexImage2DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTexImage3DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTextureImage2DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC __glewTextureImage2DMultisampleNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTextureImage3DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC __glewTextureImage3DMultisampleNV; + +GLEW_FUN_EXPORT PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV; +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV; +GLEW_FUN_EXPORT PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV; + +GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKNVPROC __glewBindTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSNVPROC __glewDeleteTransformFeedbacksNV; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKNVPROC __glewDrawTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSNVPROC __glewGenTransformFeedbacksNV; +GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKNVPROC __glewIsTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKNVPROC __glewPauseTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKNVPROC __glewResumeTransformFeedbackNV; + +GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLI64VNVPROC __glewGetVertexAttribLi64vNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLUI64VNVPROC __glewGetVertexAttribLui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64NVPROC __glewVertexAttribL1i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64VNVPROC __glewVertexAttribL1i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64NVPROC __glewVertexAttribL1ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64VNVPROC __glewVertexAttribL1ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64NVPROC __glewVertexAttribL2i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64VNVPROC __glewVertexAttribL2i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64NVPROC __glewVertexAttribL2ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64VNVPROC __glewVertexAttribL2ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64NVPROC __glewVertexAttribL3i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64VNVPROC __glewVertexAttribL3i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64NVPROC __glewVertexAttribL3ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64VNVPROC __glewVertexAttribL3ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64NVPROC __glewVertexAttribL4i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64VNVPROC __glewVertexAttribL4i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64NVPROC __glewVertexAttribL4ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64VNVPROC __glewVertexAttribL4ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLFORMATNVPROC __glewVertexAttribLFormatNV; + +GLEW_FUN_EXPORT PFNGLBUFFERADDRESSRANGENVPROC __glewBufferAddressRangeNV; +GLEW_FUN_EXPORT PFNGLCOLORFORMATNVPROC __glewColorFormatNV; +GLEW_FUN_EXPORT PFNGLEDGEFLAGFORMATNVPROC __glewEdgeFlagFormatNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDFORMATNVPROC __glewFogCoordFormatNV; +GLEW_FUN_EXPORT PFNGLGETINTEGERUI64I_VNVPROC __glewGetIntegerui64i_vNV; +GLEW_FUN_EXPORT PFNGLINDEXFORMATNVPROC __glewIndexFormatNV; +GLEW_FUN_EXPORT PFNGLNORMALFORMATNVPROC __glewNormalFormatNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORFORMATNVPROC __glewSecondaryColorFormatNV; +GLEW_FUN_EXPORT PFNGLTEXCOORDFORMATNVPROC __glewTexCoordFormatNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBFORMATNVPROC __glewVertexAttribFormatNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIFORMATNVPROC __glewVertexAttribIFormatNV; +GLEW_FUN_EXPORT PFNGLVERTEXFORMATNVPROC __glewVertexFormatNV; + +GLEW_FUN_EXPORT PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV; +GLEW_FUN_EXPORT PFNGLBINDPROGRAMNVPROC __glewBindProgramNV; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV; +GLEW_FUN_EXPORT PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV; +GLEW_FUN_EXPORT PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV; +GLEW_FUN_EXPORT PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV; +GLEW_FUN_EXPORT PFNGLISPROGRAMNVPROC __glewIsProgramNV; +GLEW_FUN_EXPORT PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV; +GLEW_FUN_EXPORT PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV; +GLEW_FUN_EXPORT PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV; + +GLEW_FUN_EXPORT PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES; +GLEW_FUN_EXPORT PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES; +GLEW_FUN_EXPORT PFNGLFRUSTUMFOESPROC __glewFrustumfOES; +GLEW_FUN_EXPORT PFNGLGETCLIPPLANEFOESPROC __glewGetClipPlanefOES; +GLEW_FUN_EXPORT PFNGLORTHOFOESPROC __glewOrthofOES; + +GLEW_FUN_EXPORT PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS; +GLEW_FUN_EXPORT PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS; + +GLEW_FUN_EXPORT PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS; +GLEW_FUN_EXPORT PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS; + +GLEW_FUN_EXPORT PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS; +GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS; + +GLEW_FUN_EXPORT PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS; +GLEW_FUN_EXPORT PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS; + +GLEW_FUN_EXPORT PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS; +GLEW_FUN_EXPORT PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS; + +GLEW_FUN_EXPORT PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX; +GLEW_FUN_EXPORT PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX; +GLEW_FUN_EXPORT PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX; +GLEW_FUN_EXPORT PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX; +GLEW_FUN_EXPORT PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX; +GLEW_FUN_EXPORT PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX; + +GLEW_FUN_EXPORT PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX; + +GLEW_FUN_EXPORT PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX; + +GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX; + +GLEW_FUN_EXPORT PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX; + +GLEW_FUN_EXPORT PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX; + +GLEW_FUN_EXPORT PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX; + +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX; + +GLEW_FUN_EXPORT PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX; + +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI; +GLEW_FUN_EXPORT PFNGLCOLORTABLESGIPROC __glewColorTableSGI; +GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI; + +GLEW_FUN_EXPORT PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX; + +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN; + +GLEW_FUN_EXPORT PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN; + +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN; + +GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN; + +GLEW_FUN_EXPORT PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN; + +#if defined(GLEW_MX) && !defined(_WIN32) +struct GLEWContextStruct +{ +#endif /* GLEW_MX */ + +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_3; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_4; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_5; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_0; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_0; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_2; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_3; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_0; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_tbuffer; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_texture_compression_FXT1; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_draw_buffers_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_performance_monitor; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_seamless_cubemap_per_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_stencil_export; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_texture_texture4; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_tessellator; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_aux_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_client_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_element_array; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_fence; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_float_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_flush_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_object_purgeable; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_pixel_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_rgb_422; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_row_bytes; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_specular_vector; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_transform_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_program_evaluators; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_ycbcr_422; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_blend_func_extended; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_color_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_copy_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_elements_base_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_indirect; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_explicit_attrib_location; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_coord_conventions; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader5; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader_fp64; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_pixel; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_imaging; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_instanced_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_matrix_palette; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multitexture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query2; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pixel_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_provoking_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sample_shading; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sampler_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_seamless_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_bit_encoding; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_subroutine; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_100; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_include; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow_ambient; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sync; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_tessellation_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_border_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object_rgb32; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_bptc; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_rgtc; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map_array; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_add; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_combine; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_crossbar; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_dot3; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_gather; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirrored_repeat; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_non_power_of_two; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_query_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rg; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rgb10_a2ui; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_swizzle; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_timer_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback2; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback3; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transpose_matrix; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_uniform_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_program; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_type_2_10_10_10_rev; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_window_pos; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_point_sprites; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_combine3; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_route; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_vertex_shader_output_point_size; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_element_array; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_envmap_bumpmap; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_map_object_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_meminfo; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_pn_triangles; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_separate_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_shader_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_text_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_compression_3dc; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_env_combine3; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_mirror_once; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_attrib_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_streams; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_422_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_Cg_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_abgr; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bindable_uniform; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_equation_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_func_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_logic_op; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_subtract; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_volume_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cmyka; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_subtable; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_compiled_vertex_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_convolution; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_coordinate_frame; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_copy_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cull_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_depth_bounds_test; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_direct_state_access; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers2; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_range_elements; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fog_coord; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fragment_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_blit; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_program_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_histogram; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_array_formats; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_func; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_material; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_light_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_misc_attribute; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multi_draw_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_float; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_paletted_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_point_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_provoking_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_rescale_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_scene_marker; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_secondary_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_specular_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_image_load_store; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_funcs; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shared_texture_palette; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_clear_tag; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_two_side; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_wrap; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_subtexture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture3D; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_dxt1; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_latc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_rgtc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_s3tc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_edge_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_add; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_combine; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_dot3; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_filter_anisotropic; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_integer; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_lod_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_mirror_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_perturb_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_shared_exponent; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_snorm; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_swizzle; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_timer_query; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_transform_feedback; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_attrib_64bit; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_weighting; +GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_frame_terminator; +GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_string_marker; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_convolution_border_modes; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_image_transform; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_occlusion_test; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_texture_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_cull_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_multimode_draw_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_rasterpos_clip; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_static_data; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_texture_mirrored_repeat; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_vertex_array_lists; +GLEW_VAR_EXPORT GLboolean __GLEW_INGR_color_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_INGR_interlace_read; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_parallel_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_texture_scissor; +GLEW_VAR_EXPORT GLboolean __GLEW_KTX_buffer_region; +GLEW_VAR_EXPORT GLboolean __GLEW_MESAX_texture_stack; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_pack_invert; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_resize_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_window_pos; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_ycbcr_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_square; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_conditional_render; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_depth_to_color; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_image; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_range_unclamped; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_evaluators; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_explicit_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fence; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_float_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fog_distance; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program_option; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_multisample_coverage; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program4_1; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program_fp64; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_shader5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_half_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_light_max_exponent; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_filter_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_occlusion_query; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_data_range; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_point_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_present_video; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_primitive_restart; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_buffer_load; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_tessellation_program5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_emboss; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_reflection; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_barrier; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_vtc; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_env_combine4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_expand_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader3; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_attrib_integer_64bit; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_buffer_unified_memory; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program1_1; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2_option; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program3; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_byte_coordinates; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_compressed_paletted_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_read_format; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_single_precision; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_interlace; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_resample; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_subsample; +GLEW_VAR_EXPORT GLboolean __GLEW_PGI_misc_hints; +GLEW_VAR_EXPORT GLboolean __GLEW_PGI_vertex_hints; +GLEW_VAR_EXPORT GLboolean __GLEW_REND_screen_coordinates; +GLEW_VAR_EXPORT GLboolean __GLEW_S3_s3tc; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_color_range; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_detail_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_fog_function; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_generate_mipmap; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_pixel_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_point_line_texgen; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_sharpen_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture4D; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_border_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_edge_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_filter4; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_select; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_histogram; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_pixel; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_alpha_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_clipmap; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_convolution_accuracy; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_flush_raster; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_offset; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragment_specular_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_framezoom; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_interlace; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ir_instrument1; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_list_priority; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture_bits; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_reference_plane; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_resample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow_ambient; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_tag_sample_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_add_env; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_coordinate_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_lod_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_multi_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_range; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_scale_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcb; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_matrix; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_texture_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_SUNX_constant_data; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_convolution_border_modes; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_global_alpha; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_mesh_array; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_read_video_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_slice_accum; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_triangle_list; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_phong_shading; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_specular_fog; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_swap_hint; + +#ifdef GLEW_MX +}; /* GLEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------- */ + +/* error codes */ +#define GLEW_OK 0 +#define GLEW_NO_ERROR 0 +#define GLEW_ERROR_NO_GL_VERSION 1 /* missing GL version */ +#define GLEW_ERROR_GL_VERSION_10_ONLY 2 /* GL 1.1 and up are not supported */ +#define GLEW_ERROR_GLX_VERSION_11_ONLY 3 /* GLX 1.2 and up are not supported */ + +/* string codes */ +#define GLEW_VERSION 1 +#define GLEW_VERSION_MAJOR 2 +#define GLEW_VERSION_MINOR 3 +#define GLEW_VERSION_MICRO 4 + +/* API */ +#ifdef GLEW_MX + +typedef struct GLEWContextStruct GLEWContext; +GLEWAPI GLenum glewContextInit (GLEWContext* ctx); +GLEWAPI GLboolean glewContextIsSupported (GLEWContext* ctx, const char* name); + +#define glewInit() glewContextInit(glewGetContext()) +#define glewIsSupported(x) glewContextIsSupported(glewGetContext(), x) +#define glewIsExtensionSupported(x) glewIsSupported(x) + +#define GLEW_GET_VAR(x) (*(const GLboolean*)&(glewGetContext()->x)) +#ifdef _WIN32 +# define GLEW_GET_FUN(x) glewGetContext()->x +#else +# define GLEW_GET_FUN(x) x +#endif + +#else /* GLEW_MX */ + +GLEWAPI GLenum glewInit (); +GLEWAPI GLboolean glewIsSupported (const char* name); +#define glewIsExtensionSupported(x) glewIsSupported(x) + +#define GLEW_GET_VAR(x) (*(const GLboolean*)&x) +#define GLEW_GET_FUN(x) x + +#endif /* GLEW_MX */ + +GLEWAPI GLboolean glewExperimental; +GLEWAPI GLboolean glewGetExtension (const char* name); +GLEWAPI const GLubyte* glewGetErrorString (GLenum error); +GLEWAPI const GLubyte* glewGetString (GLenum name); + +#ifdef __cplusplus +} +#endif + +#ifdef GLEW_APIENTRY_DEFINED +#undef GLEW_APIENTRY_DEFINED +#undef APIENTRY +#undef GLAPIENTRY +#define GLAPIENTRY +#endif + +#ifdef GLEW_CALLBACK_DEFINED +#undef GLEW_CALLBACK_DEFINED +#undef CALLBACK +#endif + +#ifdef GLEW_WINGDIAPI_DEFINED +#undef GLEW_WINGDIAPI_DEFINED +#undef WINGDIAPI +#endif + +#undef GLAPI +/* #undef GLEWAPI */ + +#endif /* __glew_h__ */ diff --git a/external/cutil/inc/GL/glext.h b/external/cutil/inc/GL/glext.h new file mode 100644 index 0000000..5328249 --- /dev/null +++ b/external/cutil/inc/GL/glext.h @@ -0,0 +1,7125 @@ +#ifndef __glext_h_ +#define __glext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + + Copyright NVIDIA Corporation 2006 + + TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED + *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS + OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR + CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR + LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, + OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE + THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES. + +******************************************************************************/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef extern +#define extern extern +#endif + +/*************************************************************/ + +/* Header file version number, required by OpenGL ABI for Linux */ +/* glext.h last updated 2005/06/06 */ +/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ +#define GL_GLEXT_VERSION 28 + +#ifndef GL_VERSION_1_2 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#endif + +#ifndef GL_ARB_imaging +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#endif + +#ifndef GL_VERSION_1_3 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#endif + +#ifndef GL_VERSION_1_4 +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#endif + +#ifndef GL_VERSION_1_5 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_SRC2_RGB GL_SOURCE2_RGB +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +#endif + +#ifndef GL_VERSION_2_0 +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#endif + +#ifndef GL_VERSION_2_1 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#endif + +#ifndef GL_ARB_multitexture +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +#endif + +#ifndef GL_ARB_multisample +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +#endif + +#ifndef GL_ARB_texture_env_add +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#endif + +#ifndef GL_ARB_texture_compression +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#endif + +#ifndef GL_ARB_texture_border_clamp +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#endif + +#ifndef GL_ARB_point_parameters +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 +#endif + +#ifndef GL_ARB_vertex_blend +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +#endif + +#ifndef GL_ARB_matrix_palette +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 +#endif + +#ifndef GL_ARB_texture_env_combine +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#endif + +#ifndef GL_ARB_texture_env_crossbar +#endif + +#ifndef GL_ARB_texture_env_dot3 +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF +#endif + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_ARB 0x8370 +#endif + +#ifndef GL_ARB_depth_texture +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#endif + +#ifndef GL_ARB_shadow +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E +#endif + +#ifndef GL_ARB_shadow_ambient +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF +#endif + +#ifndef GL_ARB_window_pos +#endif + +#ifndef GL_ARB_vertex_program +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +#endif + +#ifndef GL_ARB_fragment_program +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#endif + +#ifndef GL_ARB_vertex_buffer_object +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA +#endif + +#ifndef GL_ARB_occlusion_query +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_SAMPLES_PASSED_ARB 0x8914 +#endif + +#ifndef GL_ARB_shader_objects +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 +#endif + +#ifndef GL_ARB_vertex_shader +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A +#endif + +#ifndef GL_ARB_fragment_shader +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B +#endif + +#ifndef GL_ARB_shading_language_100 +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C +#endif + +#ifndef GL_ARB_texture_non_power_of_two +#endif + +#ifndef GL_ARB_point_sprite +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 +#endif + +#ifndef GL_ARB_fragment_program_shadow +#endif + +#ifndef GL_ARB_draw_buffers +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 +#endif + +#ifndef GL_ARB_texture_rectangle +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#endif + +#ifndef GL_ARB_color_buffer_float +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D +#endif + +#ifndef GL_ARB_half_float_pixel +#define GL_HALF_FLOAT_ARB 0x140B +#endif + +#ifndef GL_ARB_texture_float +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#endif + +#ifndef GL_ARB_pixel_buffer_object +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF +#endif + +#ifndef GL_EXT_abgr +#define GL_ABGR_EXT 0x8000 +#endif + +#ifndef GL_EXT_blend_color +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +#endif + +#ifndef GL_EXT_texture +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#endif + +#ifndef GL_EXT_texture3D +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_FILTER4_SGIS 0x8146 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +#endif + +#ifndef GL_EXT_subtexture +#endif + +#ifndef GL_EXT_copy_texture +#endif + +#ifndef GL_EXT_histogram +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +#endif + +#ifndef GL_EXT_convolution +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +#endif + +#ifndef GL_SGI_color_matrix +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#endif + +#ifndef GL_SGI_color_table +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +#endif + +#ifndef GL_SGIS_texture4D +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#endif + +#ifndef GL_EXT_cmyka +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#endif + +#ifndef GL_EXT_texture_object +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#endif + +#ifndef GL_SGIS_multisample +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_RESCALE_NORMAL_EXT 0x803A +#endif + +#ifndef GL_EXT_vertex_array +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +#endif + +#ifndef GL_EXT_misc_attribute +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#endif + +#ifndef GL_SGIX_shadow +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#endif + +#ifndef GL_SGIS_texture_border_clamp +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#endif + +#ifndef GL_EXT_blend_logic_op +#endif + +#ifndef GL_SGIX_interlace +#define GL_INTERLACE_SGIX 0x8094 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#endif + +#ifndef GL_SGIS_texture_select +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#endif + +#ifndef GL_EXT_point_parameters +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +#endif + +#ifndef GL_SGIX_instruments +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#endif + +#ifndef GL_SGIX_framezoom +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#endif + +#ifndef GL_FfdMaskSGIX +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +#endif + +#ifndef GL_SGIX_flush_raster +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#endif + +#ifndef GL_HP_image_transform +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_CUBIC_HP 0x815F +#define GL_AVERAGE_HP 0x8160 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#endif + +#ifndef GL_INGR_palette_buffer +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#endif + +#ifndef GL_EXT_color_subtable +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_LIST_PRIORITY_SGIX 0x8182 +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#endif + +#ifndef GL_EXT_index_texture +#endif + +#ifndef GL_EXT_index_material +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +#endif + +#ifndef GL_EXT_index_func +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +#endif + +#ifndef GL_WIN_phong_shading +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB +#endif + +#ifndef GL_WIN_specular_fog +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#endif + +#ifndef GL_EXT_light_texture +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +/* reuse GL_FRAGMENT_DEPTH_EXT */ +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 +#endif + +#ifndef GL_SGIX_impact_pixel_texture +#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 +#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 +#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 +#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 +#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 +#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 +#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A +#endif + +#ifndef GL_EXT_bgra +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 +#endif + +#ifndef GL_SGIX_async +#define GL_ASYNC_MARKER_SGIX 0x8329 +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#endif + +#ifndef GL_INTEL_texture_scissor +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +#endif + +#ifndef GL_HP_occlusion_test +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif + +#ifndef GL_EXT_secondary_color +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF +#endif + +#ifndef GL_EXT_multi_draw_arrays +#endif + +#ifndef GL_EXT_fog_coord +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_FOG_SCALE_SGIX 0x81FC +#define GL_FOG_SCALE_VALUE_SGIX 0x81FD +#endif + +#ifndef GL_SUNX_constant_data +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +#endif + +#ifndef GL_SUN_global_alpha +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +#endif + +#ifndef GL_SUN_triangle_list +#define GL_RESTART_SUN 0x0001 +#define GL_REPLACE_MIDDLE_SUN 0x0002 +#define GL_REPLACE_OLDEST_SUN 0x0003 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +#endif + +#ifndef GL_SUN_vertex +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +#endif + +#ifndef GL_INGR_color_clamp +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INTERLACE_READ_INGR 0x8568 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 +#endif + +#ifndef GL_EXT_texture_cube_map +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_WRAP_BORDER_SUN 0x81D4 +#endif + +#ifndef GL_EXT_texture_env_add +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW0_EXT GL_MODELVIEW +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +#endif + +#ifndef GL_NV_register_combiners +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +/* reuse GL_TEXTURE0_ARB */ +/* reuse GL_TEXTURE1_ARB */ +/* reuse GL_ZERO */ +/* reuse GL_NONE */ +/* reuse GL_FOG */ +#endif + +#ifndef GL_NV_fog_distance +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +/* reuse GL_EYE_PLANE */ +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F +#endif + +#ifndef GL_NV_blend_square +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif + +#ifndef GL_MESA_resize_buffers +#endif + +#ifndef GL_MESA_window_pos +#endif + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_CULL_VERTEX_IBM 103050 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +#endif + +#ifndef GL_SGIX_subsample +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 +#endif + +#ifndef GL_SGI_depth_pass_instrument +#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 +#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 +#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#endif + +#ifndef GL_3DFX_tbuffer +#endif + +#ifndef GL_EXT_multisample +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#endif + +#ifndef GL_SGIX_resample +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +#endif + +#ifndef GL_EXT_texture_env_dot3 +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 +#endif + +#ifndef GL_ATI_texture_mirror_once +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 +#endif + +#ifndef GL_NV_fence +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#endif + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#endif + +#ifndef GL_NV_evaluators +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 +#endif + +#ifndef GL_NV_packed_depth_stencil +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA +#endif + +#ifndef GL_NV_register_combiners2 +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 +#endif + +#ifndef GL_NV_texture_compression_vtc +#endif + +#ifndef GL_NV_texture_rectangle +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#endif + +#ifndef GL_NV_texture_shader +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV +#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV +#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F +#endif + +#ifndef GL_NV_texture_shader2 +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#endif + +#ifndef GL_NV_vertex_program +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F +#endif + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B +#endif + +#ifndef GL_SGIX_scalebias_hint +#define GL_SCALEBIAS_HINT_SGIX 0x8322 +#endif + +#ifndef GL_OML_interlace +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 +#endif + +#ifndef GL_OML_subsample +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 +#endif + +#ifndef GL_OML_resample +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 +#endif + +#ifndef GL_NV_copy_depth_to_color +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F +#endif + +#ifndef GL_ATI_envmap_bumpmap +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C +#endif + +#ifndef GL_ATI_fragment_shader +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_REG_6_ATI 0x8927 +#define GL_REG_7_ATI 0x8928 +#define GL_REG_8_ATI 0x8929 +#define GL_REG_9_ATI 0x892A +#define GL_REG_10_ATI 0x892B +#define GL_REG_11_ATI 0x892C +#define GL_REG_12_ATI 0x892D +#define GL_REG_13_ATI 0x892E +#define GL_REG_14_ATI 0x892F +#define GL_REG_15_ATI 0x8930 +#define GL_REG_16_ATI 0x8931 +#define GL_REG_17_ATI 0x8932 +#define GL_REG_18_ATI 0x8933 +#define GL_REG_19_ATI 0x8934 +#define GL_REG_20_ATI 0x8935 +#define GL_REG_21_ATI 0x8936 +#define GL_REG_22_ATI 0x8937 +#define GL_REG_23_ATI 0x8938 +#define GL_REG_24_ATI 0x8939 +#define GL_REG_25_ATI 0x893A +#define GL_REG_26_ATI 0x893B +#define GL_REG_27_ATI 0x893C +#define GL_REG_28_ATI 0x893D +#define GL_REG_29_ATI 0x893E +#define GL_REG_30_ATI 0x893F +#define GL_REG_31_ATI 0x8940 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_CON_8_ATI 0x8949 +#define GL_CON_9_ATI 0x894A +#define GL_CON_10_ATI 0x894B +#define GL_CON_11_ATI 0x894C +#define GL_CON_12_ATI 0x894D +#define GL_CON_13_ATI 0x894E +#define GL_CON_14_ATI 0x894F +#define GL_CON_15_ATI 0x8950 +#define GL_CON_16_ATI 0x8951 +#define GL_CON_17_ATI 0x8952 +#define GL_CON_18_ATI 0x8953 +#define GL_CON_19_ATI 0x8954 +#define GL_CON_20_ATI 0x8955 +#define GL_CON_21_ATI 0x8956 +#define GL_CON_22_ATI 0x8957 +#define GL_CON_23_ATI 0x8958 +#define GL_CON_24_ATI 0x8959 +#define GL_CON_25_ATI 0x895A +#define GL_CON_26_ATI 0x895B +#define GL_CON_27_ATI 0x895C +#define GL_CON_28_ATI 0x895D +#define GL_CON_29_ATI 0x895E +#define GL_CON_30_ATI 0x895F +#define GL_CON_31_ATI 0x8960 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B +#define GL_RED_BIT_ATI 0x00000001 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#endif + +#ifndef GL_ATI_pn_triangles +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 +#endif + +#ifndef GL_ATI_vertex_array_object +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 +#endif + +#ifndef GL_EXT_vertex_shader +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED +#endif + +#ifndef GL_ATI_vertex_streams +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_STREAM0_ATI 0x876C +#define GL_VERTEX_STREAM1_ATI 0x876D +#define GL_VERTEX_STREAM2_ATI 0x876E +#define GL_VERTEX_STREAM3_ATI 0x876F +#define GL_VERTEX_STREAM4_ATI 0x8770 +#define GL_VERTEX_STREAM5_ATI 0x8771 +#define GL_VERTEX_STREAM6_ATI 0x8772 +#define GL_VERTEX_STREAM7_ATI 0x8773 +#define GL_VERTEX_SOURCE_ATI 0x8774 +#endif + +#ifndef GL_ATI_element_array +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A +#endif + +#ifndef GL_SUN_mesh_array +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 +#endif + +#ifndef GL_SUN_slice_accum +#define GL_SLICE_ACCUM_SUN 0x85CC +#endif + +#ifndef GL_NV_multisample_filter_hint +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 +#endif + +#ifndef GL_NV_depth_clamp +#define GL_DEPTH_CLAMP_NV 0x864F +#endif + +#ifndef GL_NV_occlusion_query +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 +#endif + +#ifndef GL_NV_point_sprite +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 +#endif + +#ifndef GL_NV_texture_shader3 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 +#endif + +#ifndef GL_NV_vertex_program1_1 +#endif + +#ifndef GL_EXT_shadow_funcs +#endif + +#ifndef GL_EXT_stencil_two_side +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +#endif + +#ifndef GL_ATI_text_fragment_shader +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 +#endif + +#ifndef GL_APPLE_client_storage +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#endif + +#ifndef GL_APPLE_element_array +#define GL_ELEMENT_ARRAY_APPLE 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A +#endif + +#ifndef GL_APPLE_fence +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B +#endif + +#ifndef GL_APPLE_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +#endif + +#ifndef GL_APPLE_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF +#endif + +#ifndef GL_APPLE_ycbcr_422 +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif + +#ifndef GL_S3_s3tc +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#endif + +#ifndef GL_ATI_draw_buffers +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 +#endif + +#ifndef GL_ATI_pixel_format_float +#define GL_TYPE_RGBA_FLOAT_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 +#endif + +#ifndef GL_ATI_texture_env_combine3 +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 +#endif + +#ifndef GL_ATI_texture_float +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F +#endif + +#ifndef GL_NV_float_buffer +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E +#endif + +#ifndef GL_NV_fragment_program +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +#endif + +#ifndef GL_NV_half_float +#define GL_HALF_FLOAT_NV 0x140B +#endif + +#ifndef GL_NV_pixel_data_range +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D +#endif + +#ifndef GL_NV_primitive_restart +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 +#endif + +#ifndef GL_NV_texture_expand_normal +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F +#endif + +#ifndef GL_NV_vertex_program2 +#endif + +#ifndef GL_ATI_map_object_buffer +#endif + +#ifndef GL_ATI_separate_stencil +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +#endif + +#ifndef GL_ATI_vertex_attrib_array_object +#endif + +#ifndef GL_OES_read_format +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B +#endif + +#ifndef GL_EXT_depth_bounds_test +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 +#endif + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 +#endif + +#ifndef GL_EXT_blend_equation_separate +#define GL_BLEND_EQUATION_RGB_EXT GL_BLEND_EQUATION +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D +#endif + +#ifndef GL_MESA_pack_invert +#define GL_PACK_INVERT_MESA 0x8758 +#endif + +#ifndef GL_MESA_ycbcr_texture +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_YCBCR_MESA 0x8757 +#endif + +#ifndef GL_EXT_pixel_buffer_object +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF +#endif + +#ifndef GL_NV_fragment_program_option +#endif + +#ifndef GL_NV_fragment_program2 +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 +#endif + +#ifndef GL_NV_vertex_program2_option +/* reuse GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ +/* reuse GL_MAX_PROGRAM_CALL_DEPTH_NV */ +#endif + +#ifndef GL_NV_vertex_program3 +/* reuse GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */ +#endif + +#ifndef GL_EXT_framebuffer_object +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX_EXT 0x8D45 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 +#endif + +#ifndef GL_GREMEDY_string_marker +#endif + +#ifndef GL_EXT_Cg_shader +#define GL_CG_VERTEX_SHADER_EXT 0x890E +#define GL_CG_FRAGMENT_SHADER_EXT 0x890F +#endif + +#ifndef GL_EXT_timer_query +#define GL_TIME_ELAPSED_EXT 0x88BF +#endif + +#ifndef GL_EXT_texture_buffer_object +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E +#endif + +#ifndef GL_EXT_gpu_shader4 +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#endif + +#ifndef GL_EXT_geometry_shader4 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#endif + +#ifndef GL_EXT_bindable_uniform +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF +#endif + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#endif + +#ifndef GL_EXT_texture_shared_exponent +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F +#endif + +#ifndef GL_EXT_packed_float +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C +#endif + +#ifndef GL_EXT_texture_array +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +/* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ +#endif + +#ifndef GL_EXT_texture_integer +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E +#endif + +#ifndef GL_NV_depth_buffer_float +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF +#endif + +#ifndef GL_EXT_texture_compression_latc +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 +#endif + +#ifndef GL_NV_transform_feedback +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F +#endif + +#ifndef GL_NV_geometry_program4 +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 +#endif + +#ifndef GL_NV_gpu_program4 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 +#endif + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_MAX_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8D57 +#define GL_MAX_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E11 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E13 +#endif + +#ifndef GL_EXT_framebuffer_multisample +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#endif + +#ifndef GL_EXT_framebuffer_blit +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA +#endif + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#endif + +/*************************************************************/ + +#include +#ifndef GL_VERSION_2_0 +/* GL type for program/shader text */ +typedef char GLchar; /* native character */ +#endif + +#ifndef GL_VERSION_1_5 +/* GL types for handling large vertex buffer objects */ +typedef ptrdiff_t GLintptr; +typedef ptrdiff_t GLsizeiptr; +#endif + +#ifndef GL_ARB_vertex_buffer_object +/* GL types for handling large vertex buffer objects */ +typedef ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; +#endif + +#ifndef GL_ARB_shader_objects +/* GL types for handling shader object handles and program/shader text */ +typedef char GLcharARB; /* native character */ +typedef unsigned int GLhandleARB; /* shader object handle */ +#endif + +/* GL types for "half" precision (s10e5) float data in host memory */ +#ifndef GL_ARB_half_float_pixel +typedef unsigned short GLhalfARB; +#endif + +#ifndef GL_NV_half_float +typedef unsigned short GLhalfNV; +#endif + +#ifndef GL_EXT_timer_query +typedef signed long long GLint64EXT; +typedef unsigned long long GLuint64EXT; +#endif + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf); +extern void APIENTRY glBlendEquation (GLenum); +extern void APIENTRY glDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +extern void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glColorTableParameterfv (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glColorTableParameteriv (GLenum, GLenum, const GLint *); +extern void APIENTRY glCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei); +extern void APIENTRY glGetColorTable (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetColorTableParameteriv (GLenum, GLenum, GLint *); +extern void APIENTRY glColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei); +extern void APIENTRY glConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glConvolutionParameterf (GLenum, GLenum, GLfloat); +extern void APIENTRY glConvolutionParameterfv (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glConvolutionParameteri (GLenum, GLenum, GLint); +extern void APIENTRY glConvolutionParameteriv (GLenum, GLenum, const GLint *); +extern void APIENTRY glCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei); +extern void APIENTRY glCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +extern void APIENTRY glGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetConvolutionParameterfv (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetConvolutionParameteriv (GLenum, GLenum, GLint *); +extern void APIENTRY glGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +extern void APIENTRY glSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +extern void APIENTRY glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetHistogramParameterfv (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetHistogramParameteriv (GLenum, GLenum, GLint *); +extern void APIENTRY glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetMinmaxParameterfv (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetMinmaxParameteriv (GLenum, GLenum, GLint *); +extern void APIENTRY glHistogram (GLenum, GLsizei, GLenum, GLboolean); +extern void APIENTRY glMinmax (GLenum, GLenum, GLboolean); +extern void APIENTRY glResetHistogram (GLenum); +extern void APIENTRY glResetMinmax (GLenum); +extern void APIENTRY glTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glActiveTexture (GLenum); +extern void APIENTRY glClientActiveTexture (GLenum); +extern void APIENTRY glMultiTexCoord1d (GLenum, GLdouble); +extern void APIENTRY glMultiTexCoord1dv (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord1f (GLenum, GLfloat); +extern void APIENTRY glMultiTexCoord1fv (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord1i (GLenum, GLint); +extern void APIENTRY glMultiTexCoord1iv (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord1s (GLenum, GLshort); +extern void APIENTRY glMultiTexCoord1sv (GLenum, const GLshort *); +extern void APIENTRY glMultiTexCoord2d (GLenum, GLdouble, GLdouble); +extern void APIENTRY glMultiTexCoord2dv (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat); +extern void APIENTRY glMultiTexCoord2fv (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord2i (GLenum, GLint, GLint); +extern void APIENTRY glMultiTexCoord2iv (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord2s (GLenum, GLshort, GLshort); +extern void APIENTRY glMultiTexCoord2sv (GLenum, const GLshort *); +extern void APIENTRY glMultiTexCoord3d (GLenum, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glMultiTexCoord3dv (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord3f (GLenum, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glMultiTexCoord3fv (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord3i (GLenum, GLint, GLint, GLint); +extern void APIENTRY glMultiTexCoord3iv (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord3s (GLenum, GLshort, GLshort, GLshort); +extern void APIENTRY glMultiTexCoord3sv (GLenum, const GLshort *); +extern void APIENTRY glMultiTexCoord4d (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glMultiTexCoord4dv (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord4f (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glMultiTexCoord4fv (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord4i (GLenum, GLint, GLint, GLint, GLint); +extern void APIENTRY glMultiTexCoord4iv (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord4s (GLenum, GLshort, GLshort, GLshort, GLshort); +extern void APIENTRY glMultiTexCoord4sv (GLenum, const GLshort *); +extern void APIENTRY glLoadTransposeMatrixf (const GLfloat *); +extern void APIENTRY glLoadTransposeMatrixd (const GLdouble *); +extern void APIENTRY glMultTransposeMatrixf (const GLfloat *); +extern void APIENTRY glMultTransposeMatrixd (const GLdouble *); +extern void APIENTRY glSampleCoverage (GLclampf, GLboolean); +extern void APIENTRY glCompressedTexImage3D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexImage2D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexImage1D (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexSubImage2D (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexSubImage1D (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glGetCompressedTexImage (GLenum, GLint, GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); +#endif + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendFuncSeparate (GLenum, GLenum, GLenum, GLenum); +extern void APIENTRY glFogCoordf (GLfloat); +extern void APIENTRY glFogCoordfv (const GLfloat *); +extern void APIENTRY glFogCoordd (GLdouble); +extern void APIENTRY glFogCoorddv (const GLdouble *); +extern void APIENTRY glFogCoordPointer (GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glMultiDrawArrays (GLenum, GLint *, GLsizei *, GLsizei); +extern void APIENTRY glMultiDrawElements (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); +extern void APIENTRY glPointParameterf (GLenum, GLfloat); +extern void APIENTRY glPointParameterfv (GLenum, const GLfloat *); +extern void APIENTRY glPointParameteri (GLenum, GLint); +extern void APIENTRY glPointParameteriv (GLenum, const GLint *); +extern void APIENTRY glSecondaryColor3b (GLbyte, GLbyte, GLbyte); +extern void APIENTRY glSecondaryColor3bv (const GLbyte *); +extern void APIENTRY glSecondaryColor3d (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glSecondaryColor3dv (const GLdouble *); +extern void APIENTRY glSecondaryColor3f (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glSecondaryColor3fv (const GLfloat *); +extern void APIENTRY glSecondaryColor3i (GLint, GLint, GLint); +extern void APIENTRY glSecondaryColor3iv (const GLint *); +extern void APIENTRY glSecondaryColor3s (GLshort, GLshort, GLshort); +extern void APIENTRY glSecondaryColor3sv (const GLshort *); +extern void APIENTRY glSecondaryColor3ub (GLubyte, GLubyte, GLubyte); +extern void APIENTRY glSecondaryColor3ubv (const GLubyte *); +extern void APIENTRY glSecondaryColor3ui (GLuint, GLuint, GLuint); +extern void APIENTRY glSecondaryColor3uiv (const GLuint *); +extern void APIENTRY glSecondaryColor3us (GLushort, GLushort, GLushort); +extern void APIENTRY glSecondaryColor3usv (const GLushort *); +extern void APIENTRY glSecondaryColorPointer (GLint, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glWindowPos2d (GLdouble, GLdouble); +extern void APIENTRY glWindowPos2dv (const GLdouble *); +extern void APIENTRY glWindowPos2f (GLfloat, GLfloat); +extern void APIENTRY glWindowPos2fv (const GLfloat *); +extern void APIENTRY glWindowPos2i (GLint, GLint); +extern void APIENTRY glWindowPos2iv (const GLint *); +extern void APIENTRY glWindowPos2s (GLshort, GLshort); +extern void APIENTRY glWindowPos2sv (const GLshort *); +extern void APIENTRY glWindowPos3d (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glWindowPos3dv (const GLdouble *); +extern void APIENTRY glWindowPos3f (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glWindowPos3fv (const GLfloat *); +extern void APIENTRY glWindowPos3i (GLint, GLint, GLint); +extern void APIENTRY glWindowPos3iv (const GLint *); +extern void APIENTRY glWindowPos3s (GLshort, GLshort, GLshort); +extern void APIENTRY glWindowPos3sv (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); +#endif + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGenQueries (GLsizei, GLuint *); +extern void APIENTRY glDeleteQueries (GLsizei, const GLuint *); +extern GLboolean APIENTRY glIsQuery (GLuint); +extern void APIENTRY glBeginQuery (GLenum, GLuint); +extern void APIENTRY glEndQuery (GLenum); +extern void APIENTRY glGetQueryiv (GLenum, GLenum, GLint *); +extern void APIENTRY glGetQueryObjectiv (GLuint, GLenum, GLint *); +extern void APIENTRY glGetQueryObjectuiv (GLuint, GLenum, GLuint *); +extern void APIENTRY glBindBuffer (GLenum, GLuint); +extern void APIENTRY glDeleteBuffers (GLsizei, const GLuint *); +extern void APIENTRY glGenBuffers (GLsizei, GLuint *); +extern GLboolean APIENTRY glIsBuffer (GLuint); +extern void APIENTRY glBufferData (GLenum, GLsizeiptr, const GLvoid *, GLenum); +extern void APIENTRY glBufferSubData (GLenum, GLintptr, GLsizeiptr, const GLvoid *); +extern void APIENTRY glGetBufferSubData (GLenum, GLintptr, GLsizeiptr, GLvoid *); +extern GLvoid* APIENTRY glMapBuffer (GLenum, GLenum); +extern GLboolean APIENTRY glUnmapBuffer (GLenum); +extern void APIENTRY glGetBufferParameteriv (GLenum, GLenum, GLint *); +extern void APIENTRY glGetBufferPointerv (GLenum, GLenum, GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); +typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params); +#endif + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendEquationSeparate (GLenum, GLenum); +extern void APIENTRY glDrawBuffers (GLsizei, const GLenum *); +extern void APIENTRY glStencilOpSeparate (GLenum, GLenum, GLenum, GLenum); +extern void APIENTRY glStencilFuncSeparate (GLenum, GLenum, GLint, GLuint); +extern void APIENTRY glStencilMaskSeparate (GLenum, GLuint); +extern void APIENTRY glAttachShader (GLuint, GLuint); +extern void APIENTRY glBindAttribLocation (GLuint, GLuint, const GLchar *); +extern void APIENTRY glCompileShader (GLuint); +extern GLuint APIENTRY glCreateProgram (void); +extern GLuint APIENTRY glCreateShader (GLenum); +extern void APIENTRY glDeleteProgram (GLuint); +extern void APIENTRY glDeleteShader (GLuint); +extern void APIENTRY glDetachShader (GLuint, GLuint); +extern void APIENTRY glDisableVertexAttribArray (GLuint); +extern void APIENTRY glEnableVertexAttribArray (GLuint); +extern void APIENTRY glGetActiveAttrib (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); +extern void APIENTRY glGetActiveUniform (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); +extern void APIENTRY glGetAttachedShaders (GLuint, GLsizei, GLsizei *, GLuint *); +extern GLint APIENTRY glGetAttribLocation (GLuint, const GLchar *); +extern void APIENTRY glGetProgramiv (GLuint, GLenum, GLint *); +extern void APIENTRY glGetProgramInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); +extern void APIENTRY glGetShaderiv (GLuint, GLenum, GLint *); +extern void APIENTRY glGetShaderInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); +extern void APIENTRY glGetShaderSource (GLuint, GLsizei, GLsizei *, GLchar *); +extern GLint APIENTRY glGetUniformLocation (GLuint, const GLchar *); +extern void APIENTRY glGetUniformfv (GLuint, GLint, GLfloat *); +extern void APIENTRY glGetUniformiv (GLuint, GLint, GLint *); +extern void APIENTRY glGetVertexAttribdv (GLuint, GLenum, GLdouble *); +extern void APIENTRY glGetVertexAttribfv (GLuint, GLenum, GLfloat *); +extern void APIENTRY glGetVertexAttribiv (GLuint, GLenum, GLint *); +extern void APIENTRY glGetVertexAttribPointerv (GLuint, GLenum, GLvoid* *); +extern GLboolean APIENTRY glIsProgram (GLuint); +extern GLboolean APIENTRY glIsShader (GLuint); +extern void APIENTRY glLinkProgram (GLuint); +extern void APIENTRY glShaderSource (GLuint, GLsizei, const GLchar* *, const GLint *); +extern void APIENTRY glUseProgram (GLuint); +extern void APIENTRY glUniform1f (GLint, GLfloat); +extern void APIENTRY glUniform2f (GLint, GLfloat, GLfloat); +extern void APIENTRY glUniform3f (GLint, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glUniform4f (GLint, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glUniform1i (GLint, GLint); +extern void APIENTRY glUniform2i (GLint, GLint, GLint); +extern void APIENTRY glUniform3i (GLint, GLint, GLint, GLint); +extern void APIENTRY glUniform4i (GLint, GLint, GLint, GLint, GLint); +extern void APIENTRY glUniform1fv (GLint, GLsizei, const GLfloat *); +extern void APIENTRY glUniform2fv (GLint, GLsizei, const GLfloat *); +extern void APIENTRY glUniform3fv (GLint, GLsizei, const GLfloat *); +extern void APIENTRY glUniform4fv (GLint, GLsizei, const GLfloat *); +extern void APIENTRY glUniform1iv (GLint, GLsizei, const GLint *); +extern void APIENTRY glUniform2iv (GLint, GLsizei, const GLint *); +extern void APIENTRY glUniform3iv (GLint, GLsizei, const GLint *); +extern void APIENTRY glUniform4iv (GLint, GLsizei, const GLint *); +extern void APIENTRY glUniformMatrix2fv (GLint, GLsizei, GLboolean, const GLfloat *); +extern void APIENTRY glUniformMatrix3fv (GLint, GLsizei, GLboolean, const GLfloat *); +extern void APIENTRY glUniformMatrix4fv (GLint, GLsizei, GLboolean, const GLfloat *); +extern void APIENTRY glValidateProgram (GLuint); +extern void APIENTRY glVertexAttrib1d (GLuint, GLdouble); +extern void APIENTRY glVertexAttrib1dv (GLuint, const GLdouble *); +extern void APIENTRY glVertexAttrib1f (GLuint, GLfloat); +extern void APIENTRY glVertexAttrib1fv (GLuint, const GLfloat *); +extern void APIENTRY glVertexAttrib1s (GLuint, GLshort); +extern void APIENTRY glVertexAttrib1sv (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib2d (GLuint, GLdouble, GLdouble); +extern void APIENTRY glVertexAttrib2dv (GLuint, const GLdouble *); +extern void APIENTRY glVertexAttrib2f (GLuint, GLfloat, GLfloat); +extern void APIENTRY glVertexAttrib2fv (GLuint, const GLfloat *); +extern void APIENTRY glVertexAttrib2s (GLuint, GLshort, GLshort); +extern void APIENTRY glVertexAttrib2sv (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib3d (GLuint, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glVertexAttrib3dv (GLuint, const GLdouble *); +extern void APIENTRY glVertexAttrib3f (GLuint, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glVertexAttrib3fv (GLuint, const GLfloat *); +extern void APIENTRY glVertexAttrib3s (GLuint, GLshort, GLshort, GLshort); +extern void APIENTRY glVertexAttrib3sv (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib4Nbv (GLuint, const GLbyte *); +extern void APIENTRY glVertexAttrib4Niv (GLuint, const GLint *); +extern void APIENTRY glVertexAttrib4Nsv (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib4Nub (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +extern void APIENTRY glVertexAttrib4Nubv (GLuint, const GLubyte *); +extern void APIENTRY glVertexAttrib4Nuiv (GLuint, const GLuint *); +extern void APIENTRY glVertexAttrib4Nusv (GLuint, const GLushort *); +extern void APIENTRY glVertexAttrib4bv (GLuint, const GLbyte *); +extern void APIENTRY glVertexAttrib4d (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glVertexAttrib4dv (GLuint, const GLdouble *); +extern void APIENTRY glVertexAttrib4f (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glVertexAttrib4fv (GLuint, const GLfloat *); +extern void APIENTRY glVertexAttrib4iv (GLuint, const GLint *); +extern void APIENTRY glVertexAttrib4s (GLuint, GLshort, GLshort, GLshort, GLshort); +extern void APIENTRY glVertexAttrib4sv (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib4ubv (GLuint, const GLubyte *); +extern void APIENTRY glVertexAttrib4uiv (GLuint, const GLuint *); +extern void APIENTRY glVertexAttrib4usv (GLuint, const GLushort *); +extern void APIENTRY glVertexAttribPointer (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); +typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); +typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); +typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); +typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +extern void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +extern void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +extern void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +extern void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +extern void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glActiveTextureARB (GLenum); +extern void APIENTRY glClientActiveTextureARB (GLenum); +extern void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble); +extern void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat); +extern void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord1iARB (GLenum, GLint); +extern void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort); +extern void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *); +extern void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble); +extern void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat); +extern void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint); +extern void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort); +extern void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *); +extern void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint); +extern void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort); +extern void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *); +extern void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint); +extern void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort); +extern void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *); +extern void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *); +extern void APIENTRY glMultTransposeMatrixfARB (const GLfloat *); +extern void APIENTRY glMultTransposeMatrixdARB (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +#endif + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSampleCoverageARB (GLclampf, GLboolean); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); +#endif + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 +#endif + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glGetCompressedTexImageARB (GLenum, GLint, GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img); +#endif + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 +#endif + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPointParameterfARB (GLenum, GLfloat); +extern void APIENTRY glPointParameterfvARB (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glWeightbvARB (GLint, const GLbyte *); +extern void APIENTRY glWeightsvARB (GLint, const GLshort *); +extern void APIENTRY glWeightivARB (GLint, const GLint *); +extern void APIENTRY glWeightfvARB (GLint, const GLfloat *); +extern void APIENTRY glWeightdvARB (GLint, const GLdouble *); +extern void APIENTRY glWeightubvARB (GLint, const GLubyte *); +extern void APIENTRY glWeightusvARB (GLint, const GLushort *); +extern void APIENTRY glWeightuivARB (GLint, const GLuint *); +extern void APIENTRY glWeightPointerARB (GLint, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glVertexBlendARB (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); +typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); +typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); +typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); +typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); +typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); +typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); +typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); +typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); +#endif + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCurrentPaletteMatrixARB (GLint); +extern void APIENTRY glMatrixIndexubvARB (GLint, const GLubyte *); +extern void APIENTRY glMatrixIndexusvARB (GLint, const GLushort *); +extern void APIENTRY glMatrixIndexuivARB (GLint, const GLuint *); +extern void APIENTRY glMatrixIndexPointerARB (GLint, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 +#endif + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 +#endif + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 +#endif + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 +#endif + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 +#endif + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 +#endif + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 +#endif + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glWindowPos2dARB (GLdouble, GLdouble); +extern void APIENTRY glWindowPos2dvARB (const GLdouble *); +extern void APIENTRY glWindowPos2fARB (GLfloat, GLfloat); +extern void APIENTRY glWindowPos2fvARB (const GLfloat *); +extern void APIENTRY glWindowPos2iARB (GLint, GLint); +extern void APIENTRY glWindowPos2ivARB (const GLint *); +extern void APIENTRY glWindowPos2sARB (GLshort, GLshort); +extern void APIENTRY glWindowPos2svARB (const GLshort *); +extern void APIENTRY glWindowPos3dARB (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glWindowPos3dvARB (const GLdouble *); +extern void APIENTRY glWindowPos3fARB (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glWindowPos3fvARB (const GLfloat *); +extern void APIENTRY glWindowPos3iARB (GLint, GLint, GLint); +extern void APIENTRY glWindowPos3ivARB (const GLint *); +extern void APIENTRY glWindowPos3sARB (GLshort, GLshort, GLshort); +extern void APIENTRY glWindowPos3svARB (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); +#endif + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glVertexAttrib1dARB (GLuint, GLdouble); +extern void APIENTRY glVertexAttrib1dvARB (GLuint, const GLdouble *); +extern void APIENTRY glVertexAttrib1fARB (GLuint, GLfloat); +extern void APIENTRY glVertexAttrib1fvARB (GLuint, const GLfloat *); +extern void APIENTRY glVertexAttrib1sARB (GLuint, GLshort); +extern void APIENTRY glVertexAttrib1svARB (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib2dARB (GLuint, GLdouble, GLdouble); +extern void APIENTRY glVertexAttrib2dvARB (GLuint, const GLdouble *); +extern void APIENTRY glVertexAttrib2fARB (GLuint, GLfloat, GLfloat); +extern void APIENTRY glVertexAttrib2fvARB (GLuint, const GLfloat *); +extern void APIENTRY glVertexAttrib2sARB (GLuint, GLshort, GLshort); +extern void APIENTRY glVertexAttrib2svARB (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib3dARB (GLuint, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glVertexAttrib3dvARB (GLuint, const GLdouble *); +extern void APIENTRY glVertexAttrib3fARB (GLuint, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glVertexAttrib3fvARB (GLuint, const GLfloat *); +extern void APIENTRY glVertexAttrib3sARB (GLuint, GLshort, GLshort, GLshort); +extern void APIENTRY glVertexAttrib3svARB (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib4NbvARB (GLuint, const GLbyte *); +extern void APIENTRY glVertexAttrib4NivARB (GLuint, const GLint *); +extern void APIENTRY glVertexAttrib4NsvARB (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib4NubARB (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +extern void APIENTRY glVertexAttrib4NubvARB (GLuint, const GLubyte *); +extern void APIENTRY glVertexAttrib4NuivARB (GLuint, const GLuint *); +extern void APIENTRY glVertexAttrib4NusvARB (GLuint, const GLushort *); +extern void APIENTRY glVertexAttrib4bvARB (GLuint, const GLbyte *); +extern void APIENTRY glVertexAttrib4dARB (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glVertexAttrib4dvARB (GLuint, const GLdouble *); +extern void APIENTRY glVertexAttrib4fARB (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glVertexAttrib4fvARB (GLuint, const GLfloat *); +extern void APIENTRY glVertexAttrib4ivARB (GLuint, const GLint *); +extern void APIENTRY glVertexAttrib4sARB (GLuint, GLshort, GLshort, GLshort, GLshort); +extern void APIENTRY glVertexAttrib4svARB (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib4ubvARB (GLuint, const GLubyte *); +extern void APIENTRY glVertexAttrib4uivARB (GLuint, const GLuint *); +extern void APIENTRY glVertexAttrib4usvARB (GLuint, const GLushort *); +extern void APIENTRY glVertexAttribPointerARB (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); +extern void APIENTRY glEnableVertexAttribArrayARB (GLuint); +extern void APIENTRY glDisableVertexAttribArrayARB (GLuint); +extern void APIENTRY glProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glBindProgramARB (GLenum, GLuint); +extern void APIENTRY glDeleteProgramsARB (GLsizei, const GLuint *); +extern void APIENTRY glGenProgramsARB (GLsizei, GLuint *); +extern void APIENTRY glProgramEnvParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glProgramEnvParameter4dvARB (GLenum, GLuint, const GLdouble *); +extern void APIENTRY glProgramEnvParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glProgramEnvParameter4fvARB (GLenum, GLuint, const GLfloat *); +extern void APIENTRY glProgramLocalParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glProgramLocalParameter4dvARB (GLenum, GLuint, const GLdouble *); +extern void APIENTRY glProgramLocalParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glProgramLocalParameter4fvARB (GLenum, GLuint, const GLfloat *); +extern void APIENTRY glGetProgramEnvParameterdvARB (GLenum, GLuint, GLdouble *); +extern void APIENTRY glGetProgramEnvParameterfvARB (GLenum, GLuint, GLfloat *); +extern void APIENTRY glGetProgramLocalParameterdvARB (GLenum, GLuint, GLdouble *); +extern void APIENTRY glGetProgramLocalParameterfvARB (GLenum, GLuint, GLfloat *); +extern void APIENTRY glGetProgramivARB (GLenum, GLenum, GLint *); +extern void APIENTRY glGetProgramStringARB (GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetVertexAttribdvARB (GLuint, GLenum, GLdouble *); +extern void APIENTRY glGetVertexAttribfvARB (GLuint, GLenum, GLfloat *); +extern void APIENTRY glGetVertexAttribivARB (GLuint, GLenum, GLint *); +extern void APIENTRY glGetVertexAttribPointervARB (GLuint, GLenum, GLvoid* *); +extern GLboolean APIENTRY glIsProgramARB (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); +typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); +#endif + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 +/* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ +#endif + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBindBufferARB (GLenum, GLuint); +extern void APIENTRY glDeleteBuffersARB (GLsizei, const GLuint *); +extern void APIENTRY glGenBuffersARB (GLsizei, GLuint *); +extern GLboolean APIENTRY glIsBufferARB (GLuint); +extern void APIENTRY glBufferDataARB (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); +extern void APIENTRY glBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *); +extern void APIENTRY glGetBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *); +extern GLvoid* APIENTRY glMapBufferARB (GLenum, GLenum); +extern GLboolean APIENTRY glUnmapBufferARB (GLenum); +extern void APIENTRY glGetBufferParameterivARB (GLenum, GLenum, GLint *); +extern void APIENTRY glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); +typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params); +#endif + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGenQueriesARB (GLsizei, GLuint *); +extern void APIENTRY glDeleteQueriesARB (GLsizei, const GLuint *); +extern GLboolean APIENTRY glIsQueryARB (GLuint); +extern void APIENTRY glBeginQueryARB (GLenum, GLuint); +extern void APIENTRY glEndQueryARB (GLenum); +extern void APIENTRY glGetQueryivARB (GLenum, GLenum, GLint *); +extern void APIENTRY glGetQueryObjectivARB (GLuint, GLenum, GLint *); +extern void APIENTRY glGetQueryObjectuivARB (GLuint, GLenum, GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); +#endif + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDeleteObjectARB (GLhandleARB); +extern GLhandleARB APIENTRY glGetHandleARB (GLenum); +extern void APIENTRY glDetachObjectARB (GLhandleARB, GLhandleARB); +extern GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum); +extern void APIENTRY glShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *); +extern void APIENTRY glCompileShaderARB (GLhandleARB); +extern GLhandleARB APIENTRY glCreateProgramObjectARB (void); +extern void APIENTRY glAttachObjectARB (GLhandleARB, GLhandleARB); +extern void APIENTRY glLinkProgramARB (GLhandleARB); +extern void APIENTRY glUseProgramObjectARB (GLhandleARB); +extern void APIENTRY glValidateProgramARB (GLhandleARB); +extern void APIENTRY glUniform1fARB (GLint, GLfloat); +extern void APIENTRY glUniform2fARB (GLint, GLfloat, GLfloat); +extern void APIENTRY glUniform3fARB (GLint, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glUniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glUniform1iARB (GLint, GLint); +extern void APIENTRY glUniform2iARB (GLint, GLint, GLint); +extern void APIENTRY glUniform3iARB (GLint, GLint, GLint, GLint); +extern void APIENTRY glUniform4iARB (GLint, GLint, GLint, GLint, GLint); +extern void APIENTRY glUniform1fvARB (GLint, GLsizei, const GLfloat *); +extern void APIENTRY glUniform2fvARB (GLint, GLsizei, const GLfloat *); +extern void APIENTRY glUniform3fvARB (GLint, GLsizei, const GLfloat *); +extern void APIENTRY glUniform4fvARB (GLint, GLsizei, const GLfloat *); +extern void APIENTRY glUniform1ivARB (GLint, GLsizei, const GLint *); +extern void APIENTRY glUniform2ivARB (GLint, GLsizei, const GLint *); +extern void APIENTRY glUniform3ivARB (GLint, GLsizei, const GLint *); +extern void APIENTRY glUniform4ivARB (GLint, GLsizei, const GLint *); +extern void APIENTRY glUniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *); +extern void APIENTRY glUniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *); +extern void APIENTRY glUniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *); +extern void APIENTRY glGetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *); +extern void APIENTRY glGetObjectParameterivARB (GLhandleARB, GLenum, GLint *); +extern void APIENTRY glGetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); +extern void APIENTRY glGetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *); +extern GLint APIENTRY glGetUniformLocationARB (GLhandleARB, const GLcharARB *); +extern void APIENTRY glGetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); +extern void APIENTRY glGetUniformfvARB (GLhandleARB, GLint, GLfloat *); +extern void APIENTRY glGetUniformivARB (GLhandleARB, GLint, GLint *); +extern void APIENTRY glGetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); +typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); +typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); +typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); +typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); +typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); +#endif + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *); +extern void APIENTRY glGetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); +extern GLint APIENTRY glGetAttribLocationARB (GLhandleARB, const GLcharARB *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +#endif + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader 1 +#endif + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 +#endif + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 +#endif + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 +#endif + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 +#endif + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDrawBuffersARB (GLsizei, const GLenum *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); +#endif + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 +#endif + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glClampColorARB (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); +#endif + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 +#endif + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 +#endif + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 +#endif + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 +#endif + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPolygonOffsetEXT (GLfloat, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); +#endif + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 +#endif + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *); +extern void APIENTRY glTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); +typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); +#endif + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); +extern void APIENTRY glCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); +extern void APIENTRY glCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei); +extern void APIENTRY glCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +extern void APIENTRY glCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetHistogramParameterivEXT (GLenum, GLenum, GLint *); +extern void APIENTRY glGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetMinmaxParameterivEXT (GLenum, GLenum, GLint *); +extern void APIENTRY glHistogramEXT (GLenum, GLsizei, GLenum, GLboolean); +extern void APIENTRY glMinmaxEXT (GLenum, GLenum, GLboolean); +extern void APIENTRY glResetHistogramEXT (GLenum); +extern void APIENTRY glResetMinmaxEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); +#endif + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glConvolutionParameterfEXT (GLenum, GLenum, GLfloat); +extern void APIENTRY glConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glConvolutionParameteriEXT (GLenum, GLenum, GLint); +extern void APIENTRY glConvolutionParameterivEXT (GLenum, GLenum, const GLint *); +extern void APIENTRY glCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei); +extern void APIENTRY glCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +extern void APIENTRY glGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetConvolutionParameterivEXT (GLenum, GLenum, GLint *); +extern void APIENTRY glGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +extern void APIENTRY glSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +#endif + +#ifndef GL_EXT_color_matrix +#define GL_EXT_color_matrix 1 +#endif + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glColorTableParameterivSGI (GLenum, GLenum, const GLint *); +extern void APIENTRY glCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei); +extern void APIENTRY glGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPixelTexGenSGIX (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPixelTexGenParameteriSGIS (GLenum, GLint); +extern void APIENTRY glPixelTexGenParameterivSGIS (GLenum, const GLint *); +extern void APIENTRY glPixelTexGenParameterfSGIS (GLenum, GLfloat); +extern void APIENTRY glPixelTexGenParameterfvSGIS (GLenum, const GLfloat *); +extern void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum, GLint *); +extern void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 +#endif + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 +#endif + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 +#ifdef GL_GLEXT_PROTOTYPES +extern GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *); +extern void APIENTRY glBindTextureEXT (GLenum, GLuint); +extern void APIENTRY glDeleteTexturesEXT (GLsizei, const GLuint *); +extern void APIENTRY glGenTexturesEXT (GLsizei, GLuint *); +extern GLboolean APIENTRY glIsTextureEXT (GLuint); +extern void APIENTRY glPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); +typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); +typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); +typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +extern void APIENTRY glGetDetailTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +extern void APIENTRY glGetSharpenTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 +#endif + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSampleMaskSGIS (GLclampf, GLboolean); +extern void APIENTRY glSamplePatternSGIS (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 +#endif + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glArrayElementEXT (GLint); +extern void APIENTRY glColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +extern void APIENTRY glDrawArraysEXT (GLenum, GLint, GLsizei); +extern void APIENTRY glEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *); +extern void APIENTRY glGetPointervEXT (GLenum, GLvoid* *); +extern void APIENTRY glIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +extern void APIENTRY glNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +extern void APIENTRY glTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +extern void APIENTRY glVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); +typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); +typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 +#endif + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 +#endif + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendEquationEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 +#endif + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 +#endif + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles 1 +#endif + +#ifndef GL_SGIX_texture_select +#define GL_SGIX_texture_select 1 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSpriteParameterfSGIX (GLenum, GLfloat); +extern void APIENTRY glSpriteParameterfvSGIX (GLenum, const GLfloat *); +extern void APIENTRY glSpriteParameteriSGIX (GLenum, GLint); +extern void APIENTRY glSpriteParameterivSGIX (GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 +#endif + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPointParameterfEXT (GLenum, GLfloat); +extern void APIENTRY glPointParameterfvEXT (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_SGIS_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPointParameterfSGIS (GLenum, GLfloat); +extern void APIENTRY glPointParameterfvSGIS (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_SGIX_instruments +#define GL_SGIX_instruments 1 +#ifdef GL_GLEXT_PROTOTYPES +extern GLint APIENTRY glGetInstrumentsSGIX (void); +extern void APIENTRY glInstrumentsBufferSGIX (GLsizei, GLint *); +extern GLint APIENTRY glPollInstrumentsSGIX (GLint *); +extern void APIENTRY glReadInstrumentsSGIX (GLint); +extern void APIENTRY glStartInstrumentsSGIX (void); +extern void APIENTRY glStopInstrumentsSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); +typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); +typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); +typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 +#endif + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFrameZoomSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTagSampleBufferSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_SGIX_polynomial_ffd 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDeformationMap3dSGIX (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); +extern void APIENTRY glDeformationMap3fSGIX (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); +extern void APIENTRY glDeformSGIX (GLbitfield); +extern void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); +typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); +typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glReferencePlaneSGIX (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); +#endif + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFlushRasterSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFogFuncSGIS (GLsizei, const GLfloat *); +extern void APIENTRY glGetFogFuncSGIS (GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 +#endif + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glImageTransformParameteriHP (GLenum, GLenum, GLint); +extern void APIENTRY glImageTransformParameterfHP (GLenum, GLenum, GLfloat); +extern void APIENTRY glImageTransformParameterivHP (GLenum, GLenum, const GLint *); +extern void APIENTRY glImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glGetImageTransformParameterivHP (GLenum, GLenum, GLint *); +extern void APIENTRY glGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 +#endif + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glHintPGI (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetColorTableParameterivEXT (GLenum, GLenum, GLint *); +extern void APIENTRY glGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGetListParameterfvSGIX (GLuint, GLenum, GLfloat *); +extern void APIENTRY glGetListParameterivSGIX (GLuint, GLenum, GLint *); +extern void APIENTRY glListParameterfSGIX (GLuint, GLenum, GLfloat); +extern void APIENTRY glListParameterfvSGIX (GLuint, GLenum, const GLfloat *); +extern void APIENTRY glListParameteriSGIX (GLuint, GLenum, GLint); +extern void APIENTRY glListParameterivSGIX (GLuint, GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment 1 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 +#endif + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 +#endif + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glIndexMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glIndexFuncEXT (GLenum, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glLockArraysEXT (GLint, GLsizei); +extern void APIENTRY glUnlockArraysEXT (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCullParameterdvEXT (GLenum, GLdouble *); +extern void APIENTRY glCullParameterfvEXT (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_SGIX_fragment_lighting 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFragmentColorMaterialSGIX (GLenum, GLenum); +extern void APIENTRY glFragmentLightfSGIX (GLenum, GLenum, GLfloat); +extern void APIENTRY glFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glFragmentLightiSGIX (GLenum, GLenum, GLint); +extern void APIENTRY glFragmentLightivSGIX (GLenum, GLenum, const GLint *); +extern void APIENTRY glFragmentLightModelfSGIX (GLenum, GLfloat); +extern void APIENTRY glFragmentLightModelfvSGIX (GLenum, const GLfloat *); +extern void APIENTRY glFragmentLightModeliSGIX (GLenum, GLint); +extern void APIENTRY glFragmentLightModelivSGIX (GLenum, const GLint *); +extern void APIENTRY glFragmentMaterialfSGIX (GLenum, GLenum, GLfloat); +extern void APIENTRY glFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glFragmentMaterialiSGIX (GLenum, GLenum, GLint); +extern void APIENTRY glFragmentMaterialivSGIX (GLenum, GLenum, const GLint *); +extern void APIENTRY glGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetFragmentLightivSGIX (GLenum, GLenum, GLint *); +extern void APIENTRY glGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *); +extern void APIENTRY glLightEnviSGIX (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +#endif + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 +#endif + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 +#endif + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glApplyTextureEXT (GLenum); +extern void APIENTRY glTextureLightEXT (GLenum); +extern void APIENTRY glTextureMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 +#endif + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 +#endif + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glAsyncMarkerSGIX (GLuint); +extern GLint APIENTRY glFinishAsyncSGIX (GLuint *); +extern GLint APIENTRY glPollAsyncSGIX (GLuint *); +extern GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei); +extern void APIENTRY glDeleteAsyncMarkersSGIX (GLuint, GLsizei); +extern GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); +typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); +typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glVertexPointervINTEL (GLint, GLenum, const GLvoid* *); +extern void APIENTRY glNormalPointervINTEL (GLenum, const GLvoid* *); +extern void APIENTRY glColorPointervINTEL (GLint, GLenum, const GLvoid* *); +extern void APIENTRY glTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); +typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +#endif + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPixelTransformParameteriEXT (GLenum, GLenum, GLint); +extern void APIENTRY glPixelTransformParameterfEXT (GLenum, GLenum, GLfloat); +extern void APIENTRY glPixelTransformParameterivEXT (GLenum, GLenum, const GLint *); +extern void APIENTRY glPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 +#endif + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte); +extern void APIENTRY glSecondaryColor3bvEXT (const GLbyte *); +extern void APIENTRY glSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glSecondaryColor3dvEXT (const GLdouble *); +extern void APIENTRY glSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glSecondaryColor3fvEXT (const GLfloat *); +extern void APIENTRY glSecondaryColor3iEXT (GLint, GLint, GLint); +extern void APIENTRY glSecondaryColor3ivEXT (const GLint *); +extern void APIENTRY glSecondaryColor3sEXT (GLshort, GLshort, GLshort); +extern void APIENTRY glSecondaryColor3svEXT (const GLshort *); +extern void APIENTRY glSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte); +extern void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *); +extern void APIENTRY glSecondaryColor3uiEXT (GLuint, GLuint, GLuint); +extern void APIENTRY glSecondaryColor3uivEXT (const GLuint *); +extern void APIENTRY glSecondaryColor3usEXT (GLushort, GLushort, GLushort); +extern void APIENTRY glSecondaryColor3usvEXT (const GLushort *); +extern void APIENTRY glSecondaryColorPointerEXT (GLint, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTextureNormalEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); +extern void APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); +#endif + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFogCoordfEXT (GLfloat); +extern void APIENTRY glFogCoordfvEXT (const GLfloat *); +extern void APIENTRY glFogCoorddEXT (GLdouble); +extern void APIENTRY glFogCoorddvEXT (const GLdouble *); +extern void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); +typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTangent3bEXT (GLbyte, GLbyte, GLbyte); +extern void APIENTRY glTangent3bvEXT (const GLbyte *); +extern void APIENTRY glTangent3dEXT (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glTangent3dvEXT (const GLdouble *); +extern void APIENTRY glTangent3fEXT (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTangent3fvEXT (const GLfloat *); +extern void APIENTRY glTangent3iEXT (GLint, GLint, GLint); +extern void APIENTRY glTangent3ivEXT (const GLint *); +extern void APIENTRY glTangent3sEXT (GLshort, GLshort, GLshort); +extern void APIENTRY glTangent3svEXT (const GLshort *); +extern void APIENTRY glBinormal3bEXT (GLbyte, GLbyte, GLbyte); +extern void APIENTRY glBinormal3bvEXT (const GLbyte *); +extern void APIENTRY glBinormal3dEXT (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glBinormal3dvEXT (const GLdouble *); +extern void APIENTRY glBinormal3fEXT (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glBinormal3fvEXT (const GLfloat *); +extern void APIENTRY glBinormal3iEXT (GLint, GLint, GLint); +extern void APIENTRY glBinormal3ivEXT (const GLint *); +extern void APIENTRY glBinormal3sEXT (GLshort, GLshort, GLshort); +extern void APIENTRY glBinormal3svEXT (const GLshort *); +extern void APIENTRY glTangentPointerEXT (GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glBinormalPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); +typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); +typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); +typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); +typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); +typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); +typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); +typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); +typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); +typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); +typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_SGIX_fog_scale 1 +#endif + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFinishTextureSUNX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); +#endif + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGlobalAlphaFactorbSUN (GLbyte); +extern void APIENTRY glGlobalAlphaFactorsSUN (GLshort); +extern void APIENTRY glGlobalAlphaFactoriSUN (GLint); +extern void APIENTRY glGlobalAlphaFactorfSUN (GLfloat); +extern void APIENTRY glGlobalAlphaFactordSUN (GLdouble); +extern void APIENTRY glGlobalAlphaFactorubSUN (GLubyte); +extern void APIENTRY glGlobalAlphaFactorusSUN (GLushort); +extern void APIENTRY glGlobalAlphaFactoruiSUN (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +#endif + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glReplacementCodeuiSUN (GLuint); +extern void APIENTRY glReplacementCodeusSUN (GLushort); +extern void APIENTRY glReplacementCodeubSUN (GLubyte); +extern void APIENTRY glReplacementCodeuivSUN (const GLuint *); +extern void APIENTRY glReplacementCodeusvSUN (const GLushort *); +extern void APIENTRY glReplacementCodeubvSUN (const GLubyte *); +extern void APIENTRY glReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); +#endif + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat); +extern void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *); +extern void APIENTRY glColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *); +extern void APIENTRY glColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glColor3fVertex3fvSUN (const GLfloat *, const GLfloat *); +extern void APIENTRY glNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *); +extern void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *); +extern void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *, const GLubyte *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif + +#ifndef GL_INGR_blend_func_separate +#define GL_INGR_blend_func_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendFuncSeparateINGR (GLenum, GLenum, GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 +#endif + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glVertexWeightfEXT (GLfloat); +extern void APIENTRY glVertexWeightfvEXT (const GLfloat *); +extern void APIENTRY glVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFlushVertexArrayRangeNV (void); +extern void APIENTRY glVertexArrayRangeNV (GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer); +#endif + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *); +extern void APIENTRY glCombinerParameterfNV (GLenum, GLfloat); +extern void APIENTRY glCombinerParameterivNV (GLenum, const GLint *); +extern void APIENTRY glCombinerParameteriNV (GLenum, GLint); +extern void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum); +extern void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean); +extern void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum); +extern void APIENTRY glGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *); +extern void APIENTRY glGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *); +extern void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); +#endif + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 +#endif + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 +#endif + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glResizeBuffersMESA (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); +#endif + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glWindowPos2dMESA (GLdouble, GLdouble); +extern void APIENTRY glWindowPos2dvMESA (const GLdouble *); +extern void APIENTRY glWindowPos2fMESA (GLfloat, GLfloat); +extern void APIENTRY glWindowPos2fvMESA (const GLfloat *); +extern void APIENTRY glWindowPos2iMESA (GLint, GLint); +extern void APIENTRY glWindowPos2ivMESA (const GLint *); +extern void APIENTRY glWindowPos2sMESA (GLshort, GLshort); +extern void APIENTRY glWindowPos2svMESA (const GLshort *); +extern void APIENTRY glWindowPos3dMESA (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glWindowPos3dvMESA (const GLdouble *); +extern void APIENTRY glWindowPos3fMESA (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glWindowPos3fvMESA (const GLfloat *); +extern void APIENTRY glWindowPos3iMESA (GLint, GLint, GLint); +extern void APIENTRY glWindowPos3ivMESA (const GLint *); +extern void APIENTRY glWindowPos3sMESA (GLshort, GLshort, GLshort); +extern void APIENTRY glWindowPos3svMESA (const GLshort *); +extern void APIENTRY glWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glWindowPos4dvMESA (const GLdouble *); +extern void APIENTRY glWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glWindowPos4fvMESA (const GLfloat *); +extern void APIENTRY glWindowPos4iMESA (GLint, GLint, GLint, GLint); +extern void APIENTRY glWindowPos4ivMESA (const GLint *); +extern void APIENTRY glWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort); +extern void APIENTRY glWindowPos4svMESA (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); +#endif + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glMultiModeDrawArraysIBM (const GLenum *, const GLint *, const GLsizei *, GLsizei, GLint); +extern void APIENTRY glMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* const *, GLsizei, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint); +extern void APIENTRY glFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +#endif + +#ifndef GL_SGIX_subsample +#define GL_SGIX_subsample 1 +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba 1 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#define GL_SGIX_ycrcb_subsample 1 +#endif + +#ifndef GL_SGIX_depth_pass_instrument +#define GL_SGIX_depth_pass_instrument 1 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 +#endif + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTbufferMask3DFX (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); +#endif + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSampleMaskEXT (GLclampf, GLboolean); +extern void APIENTRY glSamplePatternEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 +#endif + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_SGIS_texture_color_mask 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +#endif + +#ifndef GL_SGIX_igloo_interface +#define GL_SGIX_igloo_interface 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glIglooInterfaceSGIX (GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params); +#endif + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 +#endif + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 +#endif + +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDeleteFencesNV (GLsizei, const GLuint *); +extern void APIENTRY glGenFencesNV (GLsizei, GLuint *); +extern GLboolean APIENTRY glIsFenceNV (GLuint); +extern GLboolean APIENTRY glTestFenceNV (GLuint); +extern void APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *); +extern void APIENTRY glFinishFenceNV (GLuint); +extern void APIENTRY glSetFenceNV (GLuint, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#endif + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *); +extern void APIENTRY glMapParameterivNV (GLenum, GLenum, const GLint *); +extern void APIENTRY glMapParameterfvNV (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glGetMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *); +extern void APIENTRY glGetMapParameterivNV (GLenum, GLenum, GLint *); +extern void APIENTRY glGetMapParameterfvNV (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetMapAttribParameterivNV (GLenum, GLuint, GLenum, GLint *); +extern void APIENTRY glGetMapAttribParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); +extern void APIENTRY glEvalMapsNV (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); +typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); +typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +#endif + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 +#endif + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCombinerStageParameterfvNV (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glGetCombinerStageParameterfvNV (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 +#endif + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 +#endif + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 +#endif + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 +#endif + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 +#ifdef GL_GLEXT_PROTOTYPES +extern GLboolean APIENTRY glAreProgramsResidentNV (GLsizei, const GLuint *, GLboolean *); +extern void APIENTRY glBindProgramNV (GLenum, GLuint); +extern void APIENTRY glDeleteProgramsNV (GLsizei, const GLuint *); +extern void APIENTRY glExecuteProgramNV (GLenum, GLuint, const GLfloat *); +extern void APIENTRY glGenProgramsNV (GLsizei, GLuint *); +extern void APIENTRY glGetProgramParameterdvNV (GLenum, GLuint, GLenum, GLdouble *); +extern void APIENTRY glGetProgramParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); +extern void APIENTRY glGetProgramivNV (GLuint, GLenum, GLint *); +extern void APIENTRY glGetProgramStringNV (GLuint, GLenum, GLubyte *); +extern void APIENTRY glGetTrackMatrixivNV (GLenum, GLuint, GLenum, GLint *); +extern void APIENTRY glGetVertexAttribdvNV (GLuint, GLenum, GLdouble *); +extern void APIENTRY glGetVertexAttribfvNV (GLuint, GLenum, GLfloat *); +extern void APIENTRY glGetVertexAttribivNV (GLuint, GLenum, GLint *); +extern void APIENTRY glGetVertexAttribPointervNV (GLuint, GLenum, GLvoid* *); +extern GLboolean APIENTRY glIsProgramNV (GLuint); +extern void APIENTRY glLoadProgramNV (GLenum, GLuint, GLsizei, const GLubyte *); +extern void APIENTRY glProgramParameter4dNV (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glProgramParameter4dvNV (GLenum, GLuint, const GLdouble *); +extern void APIENTRY glProgramParameter4fNV (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glProgramParameter4fvNV (GLenum, GLuint, const GLfloat *); +extern void APIENTRY glProgramParameters4dvNV (GLenum, GLuint, GLuint, const GLdouble *); +extern void APIENTRY glProgramParameters4fvNV (GLenum, GLuint, GLuint, const GLfloat *); +extern void APIENTRY glRequestResidentProgramsNV (GLsizei, const GLuint *); +extern void APIENTRY glTrackMatrixNV (GLenum, GLuint, GLenum, GLenum); +extern void APIENTRY glVertexAttribPointerNV (GLuint, GLint, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glVertexAttrib1dNV (GLuint, GLdouble); +extern void APIENTRY glVertexAttrib1dvNV (GLuint, const GLdouble *); +extern void APIENTRY glVertexAttrib1fNV (GLuint, GLfloat); +extern void APIENTRY glVertexAttrib1fvNV (GLuint, const GLfloat *); +extern void APIENTRY glVertexAttrib1sNV (GLuint, GLshort); +extern void APIENTRY glVertexAttrib1svNV (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib2dNV (GLuint, GLdouble, GLdouble); +extern void APIENTRY glVertexAttrib2dvNV (GLuint, const GLdouble *); +extern void APIENTRY glVertexAttrib2fNV (GLuint, GLfloat, GLfloat); +extern void APIENTRY glVertexAttrib2fvNV (GLuint, const GLfloat *); +extern void APIENTRY glVertexAttrib2sNV (GLuint, GLshort, GLshort); +extern void APIENTRY glVertexAttrib2svNV (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib3dNV (GLuint, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glVertexAttrib3dvNV (GLuint, const GLdouble *); +extern void APIENTRY glVertexAttrib3fNV (GLuint, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glVertexAttrib3fvNV (GLuint, const GLfloat *); +extern void APIENTRY glVertexAttrib3sNV (GLuint, GLshort, GLshort, GLshort); +extern void APIENTRY glVertexAttrib3svNV (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib4dNV (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glVertexAttrib4dvNV (GLuint, const GLdouble *); +extern void APIENTRY glVertexAttrib4fNV (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glVertexAttrib4fvNV (GLuint, const GLfloat *); +extern void APIENTRY glVertexAttrib4sNV (GLuint, GLshort, GLshort, GLshort, GLshort); +extern void APIENTRY glVertexAttrib4svNV (GLuint, const GLshort *); +extern void APIENTRY glVertexAttrib4ubNV (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +extern void APIENTRY glVertexAttrib4ubvNV (GLuint, const GLubyte *); +extern void APIENTRY glVertexAttribs1dvNV (GLuint, GLsizei, const GLdouble *); +extern void APIENTRY glVertexAttribs1fvNV (GLuint, GLsizei, const GLfloat *); +extern void APIENTRY glVertexAttribs1svNV (GLuint, GLsizei, const GLshort *); +extern void APIENTRY glVertexAttribs2dvNV (GLuint, GLsizei, const GLdouble *); +extern void APIENTRY glVertexAttribs2fvNV (GLuint, GLsizei, const GLfloat *); +extern void APIENTRY glVertexAttribs2svNV (GLuint, GLsizei, const GLshort *); +extern void APIENTRY glVertexAttribs3dvNV (GLuint, GLsizei, const GLdouble *); +extern void APIENTRY glVertexAttribs3fvNV (GLuint, GLsizei, const GLfloat *); +extern void APIENTRY glVertexAttribs3svNV (GLuint, GLsizei, const GLshort *); +extern void APIENTRY glVertexAttribs4dvNV (GLuint, GLsizei, const GLdouble *); +extern void APIENTRY glVertexAttribs4fvNV (GLuint, GLsizei, const GLfloat *); +extern void APIENTRY glVertexAttribs4svNV (GLuint, GLsizei, const GLshort *); +extern void APIENTRY glVertexAttribs4ubvNV (GLuint, GLsizei, const GLubyte *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); +typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); +typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); +typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat *v); +typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); +#endif + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 +#endif + +#ifndef GL_SGIX_scalebias_hint +#define GL_SGIX_scalebias_hint 1 +#endif + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 +#endif + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 +#endif + +#ifndef GL_OML_resample +#define GL_OML_resample 1 +#endif + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 +#endif + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTexBumpParameterivATI (GLenum, const GLint *); +extern void APIENTRY glTexBumpParameterfvATI (GLenum, const GLfloat *); +extern void APIENTRY glGetTexBumpParameterivATI (GLenum, GLint *); +extern void APIENTRY glGetTexBumpParameterfvATI (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); +typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +#endif + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +extern GLuint APIENTRY glGenFragmentShadersATI (GLuint); +extern void APIENTRY glBindFragmentShaderATI (GLuint); +extern void APIENTRY glDeleteFragmentShaderATI (GLuint); +extern void APIENTRY glBeginFragmentShaderATI (void); +extern void APIENTRY glEndFragmentShaderATI (void); +extern void APIENTRY glPassTexCoordATI (GLuint, GLuint, GLenum); +extern void APIENTRY glSampleMapATI (GLuint, GLuint, GLenum); +extern void APIENTRY glColorFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +extern void APIENTRY glColorFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +extern void APIENTRY glColorFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +extern void APIENTRY glAlphaFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); +extern void APIENTRY glAlphaFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +extern void APIENTRY glAlphaFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); +extern void APIENTRY glSetFragmentShaderConstantATI (GLuint, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); +#endif + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPNTrianglesiATI (GLenum, GLint); +extern void APIENTRY glPNTrianglesfATI (GLenum, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +#endif + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +extern GLuint APIENTRY glNewObjectBufferATI (GLsizei, const GLvoid *, GLenum); +extern GLboolean APIENTRY glIsObjectBufferATI (GLuint); +extern void APIENTRY glUpdateObjectBufferATI (GLuint, GLuint, GLsizei, const GLvoid *, GLenum); +extern void APIENTRY glGetObjectBufferfvATI (GLuint, GLenum, GLfloat *); +extern void APIENTRY glGetObjectBufferivATI (GLuint, GLenum, GLint *); +extern void APIENTRY glFreeObjectBufferATI (GLuint); +extern void APIENTRY glArrayObjectATI (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint); +extern void APIENTRY glGetArrayObjectfvATI (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetArrayObjectivATI (GLenum, GLenum, GLint *); +extern void APIENTRY glVariantArrayObjectATI (GLuint, GLenum, GLsizei, GLuint, GLuint); +extern void APIENTRY glGetVariantArrayObjectfvATI (GLuint, GLenum, GLfloat *); +extern void APIENTRY glGetVariantArrayObjectivATI (GLuint, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage); +typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); +typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); +#endif + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBeginVertexShaderEXT (void); +extern void APIENTRY glEndVertexShaderEXT (void); +extern void APIENTRY glBindVertexShaderEXT (GLuint); +extern GLuint APIENTRY glGenVertexShadersEXT (GLuint); +extern void APIENTRY glDeleteVertexShaderEXT (GLuint); +extern void APIENTRY glShaderOp1EXT (GLenum, GLuint, GLuint); +extern void APIENTRY glShaderOp2EXT (GLenum, GLuint, GLuint, GLuint); +extern void APIENTRY glShaderOp3EXT (GLenum, GLuint, GLuint, GLuint, GLuint); +extern void APIENTRY glSwizzleEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); +extern void APIENTRY glWriteMaskEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); +extern void APIENTRY glInsertComponentEXT (GLuint, GLuint, GLuint); +extern void APIENTRY glExtractComponentEXT (GLuint, GLuint, GLuint); +extern GLuint APIENTRY glGenSymbolsEXT (GLenum, GLenum, GLenum, GLuint); +extern void APIENTRY glSetInvariantEXT (GLuint, GLenum, const GLvoid *); +extern void APIENTRY glSetLocalConstantEXT (GLuint, GLenum, const GLvoid *); +extern void APIENTRY glVariantbvEXT (GLuint, const GLbyte *); +extern void APIENTRY glVariantsvEXT (GLuint, const GLshort *); +extern void APIENTRY glVariantivEXT (GLuint, const GLint *); +extern void APIENTRY glVariantfvEXT (GLuint, const GLfloat *); +extern void APIENTRY glVariantdvEXT (GLuint, const GLdouble *); +extern void APIENTRY glVariantubvEXT (GLuint, const GLubyte *); +extern void APIENTRY glVariantusvEXT (GLuint, const GLushort *); +extern void APIENTRY glVariantuivEXT (GLuint, const GLuint *); +extern void APIENTRY glVariantPointerEXT (GLuint, GLenum, GLuint, const GLvoid *); +extern void APIENTRY glEnableVariantClientStateEXT (GLuint); +extern void APIENTRY glDisableVariantClientStateEXT (GLuint); +extern GLuint APIENTRY glBindLightParameterEXT (GLenum, GLenum); +extern GLuint APIENTRY glBindMaterialParameterEXT (GLenum, GLenum); +extern GLuint APIENTRY glBindTexGenParameterEXT (GLenum, GLenum, GLenum); +extern GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum, GLenum); +extern GLuint APIENTRY glBindParameterEXT (GLenum); +extern GLboolean APIENTRY glIsVariantEnabledEXT (GLuint, GLenum); +extern void APIENTRY glGetVariantBooleanvEXT (GLuint, GLenum, GLboolean *); +extern void APIENTRY glGetVariantIntegervEXT (GLuint, GLenum, GLint *); +extern void APIENTRY glGetVariantFloatvEXT (GLuint, GLenum, GLfloat *); +extern void APIENTRY glGetVariantPointervEXT (GLuint, GLenum, GLvoid* *); +extern void APIENTRY glGetInvariantBooleanvEXT (GLuint, GLenum, GLboolean *); +extern void APIENTRY glGetInvariantIntegervEXT (GLuint, GLenum, GLint *); +extern void APIENTRY glGetInvariantFloatvEXT (GLuint, GLenum, GLfloat *); +extern void APIENTRY glGetLocalConstantBooleanvEXT (GLuint, GLenum, GLboolean *); +extern void APIENTRY glGetLocalConstantIntegervEXT (GLuint, GLenum, GLint *); +extern void APIENTRY glGetLocalConstantFloatvEXT (GLuint, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); +typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); +typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); +typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); +typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); +typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); +typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); +typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); +typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); +typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); +typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); +typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); +typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data); +typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +#endif + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glVertexStream1sATI (GLenum, GLshort); +extern void APIENTRY glVertexStream1svATI (GLenum, const GLshort *); +extern void APIENTRY glVertexStream1iATI (GLenum, GLint); +extern void APIENTRY glVertexStream1ivATI (GLenum, const GLint *); +extern void APIENTRY glVertexStream1fATI (GLenum, GLfloat); +extern void APIENTRY glVertexStream1fvATI (GLenum, const GLfloat *); +extern void APIENTRY glVertexStream1dATI (GLenum, GLdouble); +extern void APIENTRY glVertexStream1dvATI (GLenum, const GLdouble *); +extern void APIENTRY glVertexStream2sATI (GLenum, GLshort, GLshort); +extern void APIENTRY glVertexStream2svATI (GLenum, const GLshort *); +extern void APIENTRY glVertexStream2iATI (GLenum, GLint, GLint); +extern void APIENTRY glVertexStream2ivATI (GLenum, const GLint *); +extern void APIENTRY glVertexStream2fATI (GLenum, GLfloat, GLfloat); +extern void APIENTRY glVertexStream2fvATI (GLenum, const GLfloat *); +extern void APIENTRY glVertexStream2dATI (GLenum, GLdouble, GLdouble); +extern void APIENTRY glVertexStream2dvATI (GLenum, const GLdouble *); +extern void APIENTRY glVertexStream3sATI (GLenum, GLshort, GLshort, GLshort); +extern void APIENTRY glVertexStream3svATI (GLenum, const GLshort *); +extern void APIENTRY glVertexStream3iATI (GLenum, GLint, GLint, GLint); +extern void APIENTRY glVertexStream3ivATI (GLenum, const GLint *); +extern void APIENTRY glVertexStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glVertexStream3fvATI (GLenum, const GLfloat *); +extern void APIENTRY glVertexStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glVertexStream3dvATI (GLenum, const GLdouble *); +extern void APIENTRY glVertexStream4sATI (GLenum, GLshort, GLshort, GLshort, GLshort); +extern void APIENTRY glVertexStream4svATI (GLenum, const GLshort *); +extern void APIENTRY glVertexStream4iATI (GLenum, GLint, GLint, GLint, GLint); +extern void APIENTRY glVertexStream4ivATI (GLenum, const GLint *); +extern void APIENTRY glVertexStream4fATI (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glVertexStream4fvATI (GLenum, const GLfloat *); +extern void APIENTRY glVertexStream4dATI (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glVertexStream4dvATI (GLenum, const GLdouble *); +extern void APIENTRY glNormalStream3bATI (GLenum, GLbyte, GLbyte, GLbyte); +extern void APIENTRY glNormalStream3bvATI (GLenum, const GLbyte *); +extern void APIENTRY glNormalStream3sATI (GLenum, GLshort, GLshort, GLshort); +extern void APIENTRY glNormalStream3svATI (GLenum, const GLshort *); +extern void APIENTRY glNormalStream3iATI (GLenum, GLint, GLint, GLint); +extern void APIENTRY glNormalStream3ivATI (GLenum, const GLint *); +extern void APIENTRY glNormalStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glNormalStream3fvATI (GLenum, const GLfloat *); +extern void APIENTRY glNormalStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glNormalStream3dvATI (GLenum, const GLdouble *); +extern void APIENTRY glClientActiveVertexStreamATI (GLenum); +extern void APIENTRY glVertexBlendEnviATI (GLenum, GLint); +extern void APIENTRY glVertexBlendEnvfATI (GLenum, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +#endif + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glElementPointerATI (GLenum, const GLvoid *); +extern void APIENTRY glDrawElementArrayATI (GLenum, GLsizei); +extern void APIENTRY glDrawRangeElementArrayATI (GLenum, GLuint, GLuint, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +#endif + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDrawMeshArraysSUN (GLenum, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); +#endif + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 +#endif + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 +#endif + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 +#endif + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGenOcclusionQueriesNV (GLsizei, GLuint *); +extern void APIENTRY glDeleteOcclusionQueriesNV (GLsizei, const GLuint *); +extern GLboolean APIENTRY glIsOcclusionQueryNV (GLuint); +extern void APIENTRY glBeginOcclusionQueryNV (GLuint); +extern void APIENTRY glEndOcclusionQueryNV (void); +extern void APIENTRY glGetOcclusionQueryivNV (GLuint, GLenum, GLint *); +extern void APIENTRY glGetOcclusionQueryuivNV (GLuint, GLenum, GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); +#endif + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPointParameteriNV (GLenum, GLint); +extern void APIENTRY glPointParameterivNV (GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +#endif + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 +#endif + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 +#endif + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 +#endif + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glActiveStencilFaceEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); +#endif + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 +#endif + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 +#endif + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glElementPointerAPPLE (GLenum, const GLvoid *); +extern void APIENTRY glDrawElementArrayAPPLE (GLenum, GLint, GLsizei); +extern void APIENTRY glDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, GLint, GLsizei); +extern void APIENTRY glMultiDrawElementArrayAPPLE (GLenum, const GLint *, const GLsizei *, GLsizei); +extern void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); +#endif + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGenFencesAPPLE (GLsizei, GLuint *); +extern void APIENTRY glDeleteFencesAPPLE (GLsizei, const GLuint *); +extern void APIENTRY glSetFenceAPPLE (GLuint); +extern GLboolean APIENTRY glIsFenceAPPLE (GLuint); +extern GLboolean APIENTRY glTestFenceAPPLE (GLuint); +extern void APIENTRY glFinishFenceAPPLE (GLuint); +extern GLboolean APIENTRY glTestObjectAPPLE (GLenum, GLuint); +extern void APIENTRY glFinishObjectAPPLE (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); +typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); +typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +#endif + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBindVertexArrayAPPLE (GLuint); +extern void APIENTRY glDeleteVertexArraysAPPLE (GLsizei, const GLuint *); +extern void APIENTRY glGenVertexArraysAPPLE (GLsizei, const GLuint *); +extern GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); +typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); +#endif + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glVertexArrayRangeAPPLE (GLsizei, GLvoid *); +extern void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei, GLvoid *); +extern void APIENTRY glVertexArrayParameteriAPPLE (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); +typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); +typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +#endif + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 +#endif + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 +#endif + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDrawBuffersATI (GLsizei, const GLenum *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); +#endif + +#ifndef GL_ATI_pixel_format_float +#define GL_ATI_pixel_format_float 1 +/* This is really a WGL extension, but defines some associated GL enums. + * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string. + */ +#endif + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 +#endif + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 +#endif + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 +#endif + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 +/* Some NV_fragment_program entry points are shared with ARB_vertex_program. */ +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glProgramNamedParameter4fNV (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glProgramNamedParameter4dNV (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glProgramNamedParameter4fvNV (GLuint, GLsizei, const GLubyte *, const GLfloat *); +extern void APIENTRY glProgramNamedParameter4dvNV (GLuint, GLsizei, const GLubyte *, const GLdouble *); +extern void APIENTRY glGetProgramNamedParameterfvNV (GLuint, GLsizei, const GLubyte *, GLfloat *); +extern void APIENTRY glGetProgramNamedParameterdvNV (GLuint, GLsizei, const GLubyte *, GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); +typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); +#endif + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glVertex2hNV (GLhalfNV, GLhalfNV); +extern void APIENTRY glVertex2hvNV (const GLhalfNV *); +extern void APIENTRY glVertex3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +extern void APIENTRY glVertex3hvNV (const GLhalfNV *); +extern void APIENTRY glVertex4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +extern void APIENTRY glVertex4hvNV (const GLhalfNV *); +extern void APIENTRY glNormal3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +extern void APIENTRY glNormal3hvNV (const GLhalfNV *); +extern void APIENTRY glColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +extern void APIENTRY glColor3hvNV (const GLhalfNV *); +extern void APIENTRY glColor4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +extern void APIENTRY glColor4hvNV (const GLhalfNV *); +extern void APIENTRY glTexCoord1hNV (GLhalfNV); +extern void APIENTRY glTexCoord1hvNV (const GLhalfNV *); +extern void APIENTRY glTexCoord2hNV (GLhalfNV, GLhalfNV); +extern void APIENTRY glTexCoord2hvNV (const GLhalfNV *); +extern void APIENTRY glTexCoord3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +extern void APIENTRY glTexCoord3hvNV (const GLhalfNV *); +extern void APIENTRY glTexCoord4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +extern void APIENTRY glTexCoord4hvNV (const GLhalfNV *); +extern void APIENTRY glMultiTexCoord1hNV (GLenum, GLhalfNV); +extern void APIENTRY glMultiTexCoord1hvNV (GLenum, const GLhalfNV *); +extern void APIENTRY glMultiTexCoord2hNV (GLenum, GLhalfNV, GLhalfNV); +extern void APIENTRY glMultiTexCoord2hvNV (GLenum, const GLhalfNV *); +extern void APIENTRY glMultiTexCoord3hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV); +extern void APIENTRY glMultiTexCoord3hvNV (GLenum, const GLhalfNV *); +extern void APIENTRY glMultiTexCoord4hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +extern void APIENTRY glMultiTexCoord4hvNV (GLenum, const GLhalfNV *); +extern void APIENTRY glFogCoordhNV (GLhalfNV); +extern void APIENTRY glFogCoordhvNV (const GLhalfNV *); +extern void APIENTRY glSecondaryColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); +extern void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *); +extern void APIENTRY glVertexWeighthNV (GLhalfNV); +extern void APIENTRY glVertexWeighthvNV (const GLhalfNV *); +extern void APIENTRY glVertexAttrib1hNV (GLuint, GLhalfNV); +extern void APIENTRY glVertexAttrib1hvNV (GLuint, const GLhalfNV *); +extern void APIENTRY glVertexAttrib2hNV (GLuint, GLhalfNV, GLhalfNV); +extern void APIENTRY glVertexAttrib2hvNV (GLuint, const GLhalfNV *); +extern void APIENTRY glVertexAttrib3hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV); +extern void APIENTRY glVertexAttrib3hvNV (GLuint, const GLhalfNV *); +extern void APIENTRY glVertexAttrib4hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); +extern void APIENTRY glVertexAttrib4hvNV (GLuint, const GLhalfNV *); +extern void APIENTRY glVertexAttribs1hvNV (GLuint, GLsizei, const GLhalfNV *); +extern void APIENTRY glVertexAttribs2hvNV (GLuint, GLsizei, const GLhalfNV *); +extern void APIENTRY glVertexAttribs3hvNV (GLuint, GLsizei, const GLhalfNV *); +extern void APIENTRY glVertexAttribs4hvNV (GLuint, GLsizei, const GLhalfNV *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); +typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); +typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); +typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); +typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); +typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); +typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +#endif + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPixelDataRangeNV (GLenum, GLsizei, GLvoid *); +extern void APIENTRY glFlushPixelDataRangeNV (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); +typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +#endif + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPrimitiveRestartNV (void); +extern void APIENTRY glPrimitiveRestartIndexNV (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +#endif + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 +#endif + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 +#endif + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +extern GLvoid* APIENTRY glMapObjectBufferATI (GLuint); +extern void APIENTRY glUnmapObjectBufferATI (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); +#endif + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glStencilOpSeparateATI (GLenum, GLenum, GLenum, GLenum); +extern void APIENTRY glStencilFuncSeparateATI (GLenum, GLenum, GLint, GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +#endif + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glVertexAttribArrayObjectATI (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint); +extern void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint, GLenum, GLfloat *); +extern void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); +#endif + +#ifndef GL_OES_read_format +#define GL_OES_read_format 1 +#endif + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDepthBoundsEXT (GLclampd, GLclampd); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); +#endif + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp 1 +#endif + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendEquationSeparateEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); +#endif + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 +#endif + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture 1 +#endif + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object 1 +#endif + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 +#endif + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 1 +#endif + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 +#endif + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 +#endif + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +extern GLboolean APIENTRY glIsRenderbufferEXT (GLuint); +extern void APIENTRY glBindRenderbufferEXT (GLenum, GLuint); +extern void APIENTRY glDeleteRenderbuffersEXT (GLsizei, const GLuint *); +extern void APIENTRY glGenRenderbuffersEXT (GLsizei, GLuint *); +extern void APIENTRY glRenderbufferStorageEXT (GLenum, GLenum, GLsizei, GLsizei); +extern void APIENTRY glGetRenderbufferParameterivEXT (GLenum, GLenum, GLint *); +extern GLboolean APIENTRY glIsFramebufferEXT (GLuint); +extern void APIENTRY glBindFramebufferEXT (GLenum, GLuint); +extern void APIENTRY glDeleteFramebuffersEXT (GLsizei, const GLuint *); +extern void APIENTRY glGenFramebuffersEXT (GLsizei, GLuint *); +extern GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum); +extern void APIENTRY glFramebufferTexture1DEXT (GLenum, GLenum, GLenum, GLuint, GLint); +extern void APIENTRY glFramebufferTexture2DEXT (GLenum, GLenum, GLenum, GLuint, GLint); +extern void APIENTRY glFramebufferTexture3DEXT (GLenum, GLenum, GLenum, GLuint, GLint, GLint); +extern void APIENTRY glFramebufferRenderbufferEXT (GLenum, GLenum, GLenum, GLuint); +extern void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum, GLenum, GLenum, GLint *); +extern void APIENTRY glGenerateMipmapEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +#endif + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glStringMarkerGREMEDY (GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string); +#endif + +#ifndef GL_EXT_Cg_shader +#define GL_EXT_Cg_shader 1 +#endif + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64EXT *params); +extern void APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64EXT *params); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); +#endif + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); +#endif + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode); +extern void APIENTRY glEndTransformFeedbackNV (void); +extern void APIENTRY glTransformFeedbackAttribsNV (GLuint count, const GLint *attribs, GLenum bufferMode); +extern void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +extern void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +extern void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer); +extern void APIENTRY glTransformFeedbackVaryingsNV (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); +extern void APIENTRY glActiveVaryingNV (GLuint program, const GLchar *name); +extern GLint APIENTRY glGetVaryingLocationNV (GLuint program, const GLchar *name); +extern void APIENTRY glGetActiveVaryingNV (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +extern void APIENTRY glGetTransformFeedbackVaryingNV (GLuint program, GLuint index, GLint *location); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); +typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); +typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); +#endif + + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar); +extern void APIENTRY glClearDepthdNV (GLdouble depth); +extern void APIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); +typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); +typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); +#endif + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc 1 +#endif + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB 1 +#endif + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent 1 +#endif + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float 1 +#endif + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array 1 +#endif + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColorMaskIndexedEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +extern void APIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data); +extern void APIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data); +extern void APIENTRY glEnableIndexedEXT (GLenum target, GLuint index); +extern void APIENTRY glDisableIndexedEXT (GLenum target, GLuint index); +extern GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); +typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); +#endif + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params); +extern void APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params); +extern void APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params); +extern void APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params); +extern void APIENTRY glClearColorIiEXT (GLint red, GLint green, GLint blue, GLint alpha); +extern void APIENTRY glClearColorIuiEXT (GLuint red, GLuint green, GLuint blue, GLuint alpha); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +#endif + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glUniformBufferEXT (GLuint program, GLint location, GLuint buffer); +extern GLint APIENTRY glGetUniformBufferSizeEXT (GLuint program, GLint location); +extern GLintptr APIENTRY glGetUniformOffsetEXT (GLuint program, GLint location); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); +typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); +typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); +#endif + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params); +extern void APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name); +extern GLint APIENTRY glGetFragDataLocationEXT (GLuint program, const GLchar *name); +extern void APIENTRY glUniform1uiEXT (GLint location, GLuint v0); +extern void APIENTRY glUniform2uiEXT (GLint location, GLuint v0, GLuint v1); +extern void APIENTRY glUniform3uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2); +extern void APIENTRY glUniform4uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +extern void APIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuint *value); +extern void APIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value); +extern void APIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value); +extern void APIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value); +extern void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x); +extern void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y); +extern void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z); +extern void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w); +extern void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x); +extern void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y); +extern void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z); +extern void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +extern void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v); +extern void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v); +extern void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v); +extern void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v); +extern void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v); +extern void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v); +extern void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v); +extern void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v); +extern void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v); +extern void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v); +extern void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v); +extern void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v); +extern void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +extern void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params); +extern void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); +#endif + + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); +extern void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level); +extern void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +extern void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#endif + +#ifndef GL_NV_geometry_program4 +#define GL_NV_geometry_program4 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); +#endif + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glProgramLocalParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +extern void APIENTRY glProgramLocalParameterI4ivNV (GLenum target, GLuint index, const GLint *params); +extern void APIENTRY glProgramLocalParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); +extern void APIENTRY glProgramLocalParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +extern void APIENTRY glProgramLocalParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); +extern void APIENTRY glProgramLocalParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); +extern void APIENTRY glProgramEnvParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +extern void APIENTRY glProgramEnvParameterI4ivNV (GLenum target, GLuint index, const GLint *params); +extern void APIENTRY glProgramEnvParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); +extern void APIENTRY glProgramEnvParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +extern void APIENTRY glProgramEnvParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); +extern void APIENTRY glProgramEnvParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); +extern void APIENTRY glGetProgramLocalParameterIivNV (GLenum target, GLuint index, GLint *params); +extern void APIENTRY glGetProgramLocalParameterIuivNV (GLenum target, GLuint index, GLuint *params); +extern void APIENTRY glGetProgramEnvParameterIivNV (GLenum target, GLuint index, GLint *params); +extern void APIENTRY glGetProgramEnvParameterIuivNV (GLenum target, GLuint index, GLuint *params); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +#endif + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glProgramBufferParametersfvNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); +extern void APIENTRY glProgramBufferParametersIivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); +extern void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); +#endif + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +extern void APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc 1 +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/cutil/inc/GL/glut.h b/external/cutil/inc/GL/glut.h new file mode 100644 index 0000000..41105e7 --- /dev/null +++ b/external/cutil/inc/GL/glut.h @@ -0,0 +1,597 @@ +#ifndef __glut_h__ +#define __glut_h__ + +/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */ + +/* This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. */ + +#if defined(_WIN32) + +/* GLUT 3.7 now tries to avoid including + to avoid name space pollution, but Win32's + needs APIENTRY and WINGDIAPI defined properly. */ +# if 0 +# define WIN32_LEAN_AND_MEAN +# include +# else + /* XXX This is from Win32's */ +# ifndef APIENTRY +# define GLUT_APIENTRY_DEFINED +# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +# endif + /* XXX This is from Win32's */ +# ifndef CALLBACK +# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +# endif + /* XXX This is from Win32's and */ +# ifndef WINGDIAPI +# define GLUT_WINGDIAPI_DEFINED +# define WINGDIAPI __declspec(dllimport) +# endif + /* XXX This is from Win32's */ +# ifndef _WCHAR_T_DEFINED +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +# endif +# endif + +#pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */ +#pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */ +#pragma comment (lib, "glu32.lib") /* link with OpenGL Utility lib */ +#pragma message("Note: including lib: glut32.lib\n") +#pragma comment (lib, "glut32.lib") /* link with Win32 GLUT lib */ + +#pragma warning (disable:4244) /* Disable bogus conversion warnings. */ +#pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ + +#endif + +#include +#include + +/* define APIENTRY and CALLBACK to null string if we aren't on Win32 */ +#if !defined(_WIN32) +#define APIENTRY +#define GLUT_APIENTRY_DEFINED +#define CALLBACK +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + GLUT API revision history: + + GLUT_API_VERSION is updated to reflect incompatible GLUT + API changes (interface changes, semantic changes, deletions, + or additions). + + GLUT_API_VERSION=1 First public release of GLUT. 11/29/94 + + GLUT_API_VERSION=2 Added support for OpenGL/GLX multisampling, + extension. Supports new input devices like tablet, dial and button + box, and Spaceball. Easy to query OpenGL extensions. + + GLUT_API_VERSION=3 glutMenuStatus added. + + GLUT_API_VERSION=4 glutInitDisplayString, glutWarpPointer, + glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic + video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc, + glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat, + glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!). +**/ +#ifndef GLUT_API_VERSION /* allow this to be overriden */ +#define GLUT_API_VERSION 3 +#endif + +/** + GLUT implementation revision history: + + GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT + API revisions and implementation revisions (ie, bug fixes). + + GLUT_XLIB_IMPLEMENTATION=1 mjk's first public release of + GLUT Xlib-based implementation. 11/29/94 + + GLUT_XLIB_IMPLEMENTATION=2 mjk's second public release of + GLUT Xlib-based implementation providing GLUT version 2 + interfaces. + + GLUT_XLIB_IMPLEMENTATION=3 mjk's GLUT 2.2 images. 4/17/95 + + GLUT_XLIB_IMPLEMENTATION=4 mjk's GLUT 2.3 images. 6/?/95 + + GLUT_XLIB_IMPLEMENTATION=5 mjk's GLUT 3.0 images. 10/?/95 + + GLUT_XLIB_IMPLEMENTATION=7 mjk's GLUT 3.1+ with glutWarpPoitner. 7/24/96 + + GLUT_XLIB_IMPLEMENTATION=8 mjk's GLUT 3.1+ with glutWarpPoitner + and video resize. 1/3/97 + + GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines. + + GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release. + + GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling. + + GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 release with GameGLUT support. +**/ +#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */ +#define GLUT_XLIB_IMPLEMENTATION 13 +#endif + +/* Display mode bit masks. */ +#define GLUT_RGB 0 +#define GLUT_RGBA GLUT_RGB +#define GLUT_INDEX 1 +#define GLUT_SINGLE 0 +#define GLUT_DOUBLE 2 +#define GLUT_ACCUM 4 +#define GLUT_ALPHA 8 +#define GLUT_DEPTH 16 +#define GLUT_STENCIL 32 +#if (GLUT_API_VERSION >= 2) +#define GLUT_MULTISAMPLE 128 +#define GLUT_STEREO 256 +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_LUMINANCE 512 +#endif + +/* Mouse buttons. */ +#define GLUT_LEFT_BUTTON 0 +#define GLUT_MIDDLE_BUTTON 1 +#define GLUT_RIGHT_BUTTON 2 + +/* Mouse button state. */ +#define GLUT_DOWN 0 +#define GLUT_UP 1 + +#if (GLUT_API_VERSION >= 2) +/* function keys */ +#define GLUT_KEY_F1 1 +#define GLUT_KEY_F2 2 +#define GLUT_KEY_F3 3 +#define GLUT_KEY_F4 4 +#define GLUT_KEY_F5 5 +#define GLUT_KEY_F6 6 +#define GLUT_KEY_F7 7 +#define GLUT_KEY_F8 8 +#define GLUT_KEY_F9 9 +#define GLUT_KEY_F10 10 +#define GLUT_KEY_F11 11 +#define GLUT_KEY_F12 12 +/* directional keys */ +#define GLUT_KEY_LEFT 100 +#define GLUT_KEY_UP 101 +#define GLUT_KEY_RIGHT 102 +#define GLUT_KEY_DOWN 103 +#define GLUT_KEY_PAGE_UP 104 +#define GLUT_KEY_PAGE_DOWN 105 +#define GLUT_KEY_HOME 106 +#define GLUT_KEY_END 107 +#define GLUT_KEY_INSERT 108 +#endif + +/* Entry/exit state. */ +#define GLUT_LEFT 0 +#define GLUT_ENTERED 1 + +/* Menu usage state. */ +#define GLUT_MENU_NOT_IN_USE 0 +#define GLUT_MENU_IN_USE 1 + +/* Visibility state. */ +#define GLUT_NOT_VISIBLE 0 +#define GLUT_VISIBLE 1 + +/* Window status state. */ +#define GLUT_HIDDEN 0 +#define GLUT_FULLY_RETAINED 1 +#define GLUT_PARTIALLY_RETAINED 2 +#define GLUT_FULLY_COVERED 3 + +/* Color index component selection values. */ +#define GLUT_RED 0 +#define GLUT_GREEN 1 +#define GLUT_BLUE 2 + +/* Layers for use. */ +#define GLUT_NORMAL 0 +#define GLUT_OVERLAY 1 + +#if defined(_WIN32) +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN ((void*)0) +#define GLUT_STROKE_MONO_ROMAN ((void*)1) + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 ((void*)2) +#define GLUT_BITMAP_8_BY_13 ((void*)3) +#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4) +#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 ((void*)6) +#define GLUT_BITMAP_HELVETICA_12 ((void*)7) +#define GLUT_BITMAP_HELVETICA_18 ((void*)8) +#endif +#else +/* Stroke font opaque addresses (use constants instead in source code). */ +extern void *glutStrokeRoman; +extern void *glutStrokeMonoRoman; + +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN (&glutStrokeRoman) +#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman) + +/* Bitmap font opaque addresses (use constants instead in source code). */ +extern void *glutBitmap9By15; +extern void *glutBitmap8By13; +extern void *glutBitmapTimesRoman10; +extern void *glutBitmapTimesRoman24; +extern void *glutBitmapHelvetica10; +extern void *glutBitmapHelvetica12; +extern void *glutBitmapHelvetica18; + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15) +#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13) +#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10) +#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10) +#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12) +#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18) +#endif +#endif + +/* glutGet parameters. */ +#define GLUT_WINDOW_X 100 +#define GLUT_WINDOW_Y 101 +#define GLUT_WINDOW_WIDTH 102 +#define GLUT_WINDOW_HEIGHT 103 +#define GLUT_WINDOW_BUFFER_SIZE 104 +#define GLUT_WINDOW_STENCIL_SIZE 105 +#define GLUT_WINDOW_DEPTH_SIZE 106 +#define GLUT_WINDOW_RED_SIZE 107 +#define GLUT_WINDOW_GREEN_SIZE 108 +#define GLUT_WINDOW_BLUE_SIZE 109 +#define GLUT_WINDOW_ALPHA_SIZE 110 +#define GLUT_WINDOW_ACCUM_RED_SIZE 111 +#define GLUT_WINDOW_ACCUM_GREEN_SIZE 112 +#define GLUT_WINDOW_ACCUM_BLUE_SIZE 113 +#define GLUT_WINDOW_ACCUM_ALPHA_SIZE 114 +#define GLUT_WINDOW_DOUBLEBUFFER 115 +#define GLUT_WINDOW_RGBA 116 +#define GLUT_WINDOW_PARENT 117 +#define GLUT_WINDOW_NUM_CHILDREN 118 +#define GLUT_WINDOW_COLORMAP_SIZE 119 +#if (GLUT_API_VERSION >= 2) +#define GLUT_WINDOW_NUM_SAMPLES 120 +#define GLUT_WINDOW_STEREO 121 +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_WINDOW_CURSOR 122 +#endif +#define GLUT_SCREEN_WIDTH 200 +#define GLUT_SCREEN_HEIGHT 201 +#define GLUT_SCREEN_WIDTH_MM 202 +#define GLUT_SCREEN_HEIGHT_MM 203 +#define GLUT_MENU_NUM_ITEMS 300 +#define GLUT_DISPLAY_MODE_POSSIBLE 400 +#define GLUT_INIT_WINDOW_X 500 +#define GLUT_INIT_WINDOW_Y 501 +#define GLUT_INIT_WINDOW_WIDTH 502 +#define GLUT_INIT_WINDOW_HEIGHT 503 +#define GLUT_INIT_DISPLAY_MODE 504 +#if (GLUT_API_VERSION >= 2) +#define GLUT_ELAPSED_TIME 700 +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_WINDOW_FORMAT_ID 123 +#endif + +#if (GLUT_API_VERSION >= 2) +/* glutDeviceGet parameters. */ +#define GLUT_HAS_KEYBOARD 600 +#define GLUT_HAS_MOUSE 601 +#define GLUT_HAS_SPACEBALL 602 +#define GLUT_HAS_DIAL_AND_BUTTON_BOX 603 +#define GLUT_HAS_TABLET 604 +#define GLUT_NUM_MOUSE_BUTTONS 605 +#define GLUT_NUM_SPACEBALL_BUTTONS 606 +#define GLUT_NUM_BUTTON_BOX_BUTTONS 607 +#define GLUT_NUM_DIALS 608 +#define GLUT_NUM_TABLET_BUTTONS 609 +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_DEVICE_IGNORE_KEY_REPEAT 610 +#define GLUT_DEVICE_KEY_REPEAT 611 +#define GLUT_HAS_JOYSTICK 612 +#define GLUT_OWNS_JOYSTICK 613 +#define GLUT_JOYSTICK_BUTTONS 614 +#define GLUT_JOYSTICK_AXES 615 +#define GLUT_JOYSTICK_POLL_RATE 616 +#endif + +#if (GLUT_API_VERSION >= 3) +/* glutLayerGet parameters. */ +#define GLUT_OVERLAY_POSSIBLE 800 +#define GLUT_LAYER_IN_USE 801 +#define GLUT_HAS_OVERLAY 802 +#define GLUT_TRANSPARENT_INDEX 803 +#define GLUT_NORMAL_DAMAGED 804 +#define GLUT_OVERLAY_DAMAGED 805 + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* glutVideoResizeGet parameters. */ +#define GLUT_VIDEO_RESIZE_POSSIBLE 900 +#define GLUT_VIDEO_RESIZE_IN_USE 901 +#define GLUT_VIDEO_RESIZE_X_DELTA 902 +#define GLUT_VIDEO_RESIZE_Y_DELTA 903 +#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 904 +#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 905 +#define GLUT_VIDEO_RESIZE_X 906 +#define GLUT_VIDEO_RESIZE_Y 907 +#define GLUT_VIDEO_RESIZE_WIDTH 908 +#define GLUT_VIDEO_RESIZE_HEIGHT 909 +#endif + +/* glutUseLayer parameters. */ +#define GLUT_NORMAL 0 +#define GLUT_OVERLAY 1 + +/* glutGetModifiers return mask. */ +#define GLUT_ACTIVE_SHIFT 1 +#define GLUT_ACTIVE_CTRL 2 +#define GLUT_ACTIVE_ALT 4 + +/* glutSetCursor parameters. */ +/* Basic arrows. */ +#define GLUT_CURSOR_RIGHT_ARROW 0 +#define GLUT_CURSOR_LEFT_ARROW 1 +/* Symbolic cursor shapes. */ +#define GLUT_CURSOR_INFO 2 +#define GLUT_CURSOR_DESTROY 3 +#define GLUT_CURSOR_HELP 4 +#define GLUT_CURSOR_CYCLE 5 +#define GLUT_CURSOR_SPRAY 6 +#define GLUT_CURSOR_WAIT 7 +#define GLUT_CURSOR_TEXT 8 +#define GLUT_CURSOR_CROSSHAIR 9 +/* Directional cursors. */ +#define GLUT_CURSOR_UP_DOWN 10 +#define GLUT_CURSOR_LEFT_RIGHT 11 +/* Sizing cursors. */ +#define GLUT_CURSOR_TOP_SIDE 12 +#define GLUT_CURSOR_BOTTOM_SIDE 13 +#define GLUT_CURSOR_LEFT_SIDE 14 +#define GLUT_CURSOR_RIGHT_SIDE 15 +#define GLUT_CURSOR_TOP_LEFT_CORNER 16 +#define GLUT_CURSOR_TOP_RIGHT_CORNER 17 +#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18 +#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19 +/* Inherit from parent window. */ +#define GLUT_CURSOR_INHERIT 100 +/* Blank cursor. */ +#define GLUT_CURSOR_NONE 101 +/* Fullscreen crosshair (if available). */ +#define GLUT_CURSOR_FULL_CROSSHAIR 102 +#endif + +/* GLUT initialization sub-API. */ +extern void APIENTRY glutInit(int *argcp, char **argv); +extern void APIENTRY glutInitDisplayMode(unsigned int mode); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +extern void APIENTRY glutInitDisplayString(const char *string); +#endif +extern void APIENTRY glutInitWindowPosition(int x, int y); +extern void APIENTRY glutInitWindowSize(int width, int height); +extern void APIENTRY glutMainLoop(void); + +/* GLUT window sub-API. */ +extern int APIENTRY glutCreateWindow(const char *title); +extern int APIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height); +extern void APIENTRY glutDestroyWindow(int win); +extern void APIENTRY glutPostRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +extern void APIENTRY glutPostWindowRedisplay(int win); +#endif +extern void APIENTRY glutSwapBuffers(void); +extern int APIENTRY glutGetWindow(void); +extern void APIENTRY glutSetWindow(int win); +extern void APIENTRY glutSetWindowTitle(const char *title); +extern void APIENTRY glutSetIconTitle(const char *title); +extern void APIENTRY glutPositionWindow(int x, int y); +extern void APIENTRY glutReshapeWindow(int width, int height); +extern void APIENTRY glutPopWindow(void); +extern void APIENTRY glutPushWindow(void); +extern void APIENTRY glutIconifyWindow(void); +extern void APIENTRY glutShowWindow(void); +extern void APIENTRY glutHideWindow(void); +#if (GLUT_API_VERSION >= 3) +extern void APIENTRY glutFullScreen(void); +extern void APIENTRY glutSetCursor(int cursor); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +extern void APIENTRY glutWarpPointer(int x, int y); +#endif + +/* GLUT overlay sub-API. */ +extern void APIENTRY glutEstablishOverlay(void); +extern void APIENTRY glutRemoveOverlay(void); +extern void APIENTRY glutUseLayer(GLenum layer); +extern void APIENTRY glutPostOverlayRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +extern void APIENTRY glutPostWindowOverlayRedisplay(int win); +#endif +extern void APIENTRY glutShowOverlay(void); +extern void APIENTRY glutHideOverlay(void); +#endif + +/* GLUT menu sub-API. */ +extern int APIENTRY glutCreateMenu(void (*)(int)); +extern void APIENTRY glutDestroyMenu(int menu); +extern int APIENTRY glutGetMenu(void); +extern void APIENTRY glutSetMenu(int menu); +extern void APIENTRY glutAddMenuEntry(const char *label, int value); +extern void APIENTRY glutAddSubMenu(const char *label, int submenu); +extern void APIENTRY glutChangeToMenuEntry(int item, const char *label, int value); +extern void APIENTRY glutChangeToSubMenu(int item, const char *label, int submenu); +extern void APIENTRY glutRemoveMenuItem(int item); +extern void APIENTRY glutAttachMenu(int button); +extern void APIENTRY glutDetachMenu(int button); + +/* GLUT window callback sub-API. */ +extern void APIENTRY glutDisplayFunc(void (*func)(void)); +extern void APIENTRY glutReshapeFunc(void (*func)(int width, int height)); +extern void APIENTRY glutKeyboardFunc(void (*func)(unsigned char key, int x, int y)); +extern void APIENTRY glutMouseFunc(void (*func)(int button, int state, int x, int y)); +extern void APIENTRY glutMotionFunc(void (*func)(int x, int y)); +extern void APIENTRY glutPassiveMotionFunc(void (*func)(int x, int y)); +extern void APIENTRY glutEntryFunc(void (*func)(int state)); +extern void APIENTRY glutVisibilityFunc(void (*func)(int state)); +extern void APIENTRY glutIdleFunc(void (*func)(void)); +extern void APIENTRY glutTimerFunc(unsigned int millis, void (*func)(int value), int value); +extern void APIENTRY glutMenuStateFunc(void (*func)(int state)); +#if (GLUT_API_VERSION >= 2) +extern void APIENTRY glutSpecialFunc(void (*func)(int key, int x, int y)); +extern void APIENTRY glutSpaceballMotionFunc(void (*func)(int x, int y, int z)); +extern void APIENTRY glutSpaceballRotateFunc(void (*func)(int x, int y, int z)); +extern void APIENTRY glutSpaceballButtonFunc(void (*func)(int button, int state)); +extern void APIENTRY glutButtonBoxFunc(void (*func)(int button, int state)); +extern void APIENTRY glutDialsFunc(void (*func)(int dial, int value)); +extern void APIENTRY glutTabletMotionFunc(void (*func)(int x, int y)); +extern void APIENTRY glutTabletButtonFunc(void (*func)(int button, int state, int x, int y)); +#if (GLUT_API_VERSION >= 3) +extern void APIENTRY glutMenuStatusFunc(void (*func)(int status, int x, int y)); +extern void APIENTRY glutOverlayDisplayFunc(void (*func)(void)); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +extern void APIENTRY glutWindowStatusFunc(void (*func)(int state)); +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +extern void APIENTRY glutKeyboardUpFunc(void (*func)(unsigned char key, int x, int y)); +extern void APIENTRY glutSpecialUpFunc(void (*func)(int key, int x, int y)); +extern void APIENTRY glutJoystickFunc(void (*func)(unsigned int buttonMask, int x, int y, int z), int pollInterval); +#endif +#endif +#endif + +/* GLUT color index sub-API. */ +extern void APIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue); +extern GLfloat APIENTRY glutGetColor(int ndx, int component); +extern void APIENTRY glutCopyColormap(int win); + +/* GLUT state retrieval sub-API. */ +extern int APIENTRY glutGet(GLenum type); +extern int APIENTRY glutDeviceGet(GLenum type); +#if (GLUT_API_VERSION >= 2) +/* GLUT extension support sub-API */ +extern int APIENTRY glutExtensionSupported(const char *name); +#endif +#if (GLUT_API_VERSION >= 3) +extern int APIENTRY glutGetModifiers(void); +extern int APIENTRY glutLayerGet(GLenum type); +#endif + +/* GLUT font sub-API */ +extern void APIENTRY glutBitmapCharacter(void *font, int character); +extern int APIENTRY glutBitmapWidth(void *font, int character); +extern void APIENTRY glutStrokeCharacter(void *font, int character); +extern int APIENTRY glutStrokeWidth(void *font, int character); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +extern int APIENTRY glutBitmapLength(void *font, const unsigned char *string); +extern int APIENTRY glutStrokeLength(void *font, const unsigned char *string); +#endif + +/* GLUT pre-built models sub-API */ +extern void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks); +extern void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); +extern void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +extern void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +extern void APIENTRY glutWireCube(GLdouble size); +extern void APIENTRY glutSolidCube(GLdouble size); +extern void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +extern void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +extern void APIENTRY glutWireDodecahedron(void); +extern void APIENTRY glutSolidDodecahedron(void); +extern void APIENTRY glutWireTeapot(GLdouble size); +extern void APIENTRY glutSolidTeapot(GLdouble size); +extern void APIENTRY glutWireOctahedron(void); +extern void APIENTRY glutSolidOctahedron(void); +extern void APIENTRY glutWireTetrahedron(void); +extern void APIENTRY glutSolidTetrahedron(void); +extern void APIENTRY glutWireIcosahedron(void); +extern void APIENTRY glutSolidIcosahedron(void); + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* GLUT video resize sub-API. */ +extern int APIENTRY glutVideoResizeGet(GLenum param); +extern void APIENTRY glutSetupVideoResizing(void); +extern void APIENTRY glutStopVideoResizing(void); +extern void APIENTRY glutVideoResize(int x, int y, int width, int height); +extern void APIENTRY glutVideoPan(int x, int y, int width, int height); + +/* GLUT debugging sub-API. */ +extern void APIENTRY glutReportErrors(void); +#endif + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +/* GLUT device control sub-API. */ +/* glutSetKeyRepeat modes. */ +#define GLUT_KEY_REPEAT_OFF 0 +#define GLUT_KEY_REPEAT_ON 1 +#define GLUT_KEY_REPEAT_DEFAULT 2 + +/* Joystick button masks. */ +#define GLUT_JOYSTICK_BUTTON_A 1 +#define GLUT_JOYSTICK_BUTTON_B 2 +#define GLUT_JOYSTICK_BUTTON_C 4 +#define GLUT_JOYSTICK_BUTTON_D 8 + +extern void APIENTRY glutIgnoreKeyRepeat(int ignore); +extern void APIENTRY glutSetKeyRepeat(int repeatMode); +extern void APIENTRY glutForceJoystickFunc(void); + +/* GLUT game mode sub-API. */ +/* glutGameModeGet. */ +#define GLUT_GAME_MODE_ACTIVE 0 +#define GLUT_GAME_MODE_POSSIBLE 1 +#define GLUT_GAME_MODE_WIDTH 2 +#define GLUT_GAME_MODE_HEIGHT 3 +#define GLUT_GAME_MODE_PIXEL_DEPTH 4 +#define GLUT_GAME_MODE_REFRESH_RATE 5 +#define GLUT_GAME_MODE_DISPLAY_CHANGED 6 + +extern void APIENTRY glutGameModeString(const char *string); +extern int APIENTRY glutEnterGameMode(void); +extern void APIENTRY glutLeaveGameMode(void); +extern int APIENTRY glutGameModeGet(GLenum mode); +#endif + +#ifdef __cplusplus +} + +#endif + +#ifdef GLUT_APIENTRY_DEFINED +# undef GLUT_APIENTRY_DEFINED +# undef APIENTRY +#endif + +#ifdef GLUT_WINGDIAPI_DEFINED +# undef GLUT_WINGDIAPI_DEFINED +# undef WINGDIAPI +#endif + +#endif /* __glut_h__ */ diff --git a/external/cutil/inc/GL/glxew.h b/external/cutil/inc/GL/glxew.h new file mode 100644 index 0000000..6260436 --- /dev/null +++ b/external/cutil/inc/GL/glxew.h @@ -0,0 +1,1091 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2006, Milan Ikits +** Copyright (C) 2002-2006, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +** The contents of this file are subject to the GLX Public License Version 1.0 +** (the "License"). You may not use this file except in compliance with the +** License. You may obtain a copy of the License at Silicon Graphics, Inc., +** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043 +** or at http://www.sgi.com/software/opensource/glx/license.html. +** +** Software distributed under the License is distributed on an "AS IS" +** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY +** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR +** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific +** language governing rights and limitations under the License. +** +** The Original Software is GLX version 1.2 source code, released February, +** 1999. The developer of the Original Software is Silicon Graphics, Inc. +** Those portions of the Subject Software created by Silicon Graphics, Inc. +** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved. +*/ + +#ifndef __glxew_h__ +#define __glxew_h__ +#define __GLXEW_H__ + +#ifdef __glxext_h_ +#error glxext.h included before glxew.h +#endif + +#define __glxext_h_ +#define __GLX_glx_h__ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------------------------- GLX_VERSION_1_0 --------------------------- */ + +#ifndef GLX_VERSION_1_0 +#define GLX_VERSION_1_0 1 + +#define GLX_USE_GL 1 +#define GLX_BUFFER_SIZE 2 +#define GLX_LEVEL 3 +#define GLX_RGBA 4 +#define GLX_DOUBLEBUFFER 5 +#define GLX_STEREO 6 +#define GLX_AUX_BUFFERS 7 +#define GLX_RED_SIZE 8 +#define GLX_GREEN_SIZE 9 +#define GLX_BLUE_SIZE 10 +#define GLX_ALPHA_SIZE 11 +#define GLX_DEPTH_SIZE 12 +#define GLX_STENCIL_SIZE 13 +#define GLX_ACCUM_RED_SIZE 14 +#define GLX_ACCUM_GREEN_SIZE 15 +#define GLX_ACCUM_BLUE_SIZE 16 +#define GLX_ACCUM_ALPHA_SIZE 17 +#define GLX_BAD_SCREEN 1 +#define GLX_BAD_ATTRIBUTE 2 +#define GLX_NO_EXTENSION 3 +#define GLX_BAD_VISUAL 4 +#define GLX_BAD_CONTEXT 5 +#define GLX_BAD_VALUE 6 +#define GLX_BAD_ENUM 7 + +typedef XID GLXDrawable; +typedef XID GLXPixmap; +#ifdef __sun +typedef struct __glXcontextRec *GLXContext; +#else +typedef struct __GLXcontextRec *GLXContext; +#endif + +extern Bool glXQueryExtension (Display *dpy, int *errorBase, int *eventBase); +extern Bool glXQueryVersion (Display *dpy, int *major, int *minor); +extern int glXGetConfig (Display *dpy, XVisualInfo *vis, int attrib, int *value); +extern XVisualInfo* glXChooseVisual (Display *dpy, int screen, int *attribList); +extern GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *vis, Pixmap pixmap); +extern void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix); +extern GLXContext glXCreateContext (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); +extern void glXDestroyContext (Display *dpy, GLXContext ctx); +extern Bool glXIsDirect (Display *dpy, GLXContext ctx); +extern void glXCopyContext (Display *dpy, GLXContext src, GLXContext dst, GLuint mask); +extern Bool glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx); +extern GLXContext glXGetCurrentContext (void); +extern GLXDrawable glXGetCurrentDrawable (void); +extern void glXWaitGL (void); +extern void glXWaitX (void); +extern void glXSwapBuffers (Display *dpy, GLXDrawable drawable); +extern void glXUseXFont (Font font, int first, int count, int listBase); + +#define GLXEW_VERSION_1_0 GLXEW_GET_VAR(__GLXEW_VERSION_1_0) + +#endif /* GLX_VERSION_1_0 */ + +/* ---------------------------- GLX_VERSION_1_1 --------------------------- */ + +#ifndef GLX_VERSION_1_1 +#define GLX_VERSION_1_1 + +#define GLX_VENDOR 0x1 +#define GLX_VERSION 0x2 +#define GLX_EXTENSIONS 0x3 + +extern const char* glXQueryExtensionsString (Display *dpy, int screen); +extern const char* glXGetClientString (Display *dpy, int name); +extern const char* glXQueryServerString (Display *dpy, int screen, int name); + +#define GLXEW_VERSION_1_1 GLXEW_GET_VAR(__GLXEW_VERSION_1_1) + +#endif /* GLX_VERSION_1_1 */ + +/* ---------------------------- GLX_VERSION_1_2 ---------------------------- */ + +#ifndef GLX_VERSION_1_2 +#define GLX_VERSION_1_2 1 + +typedef Display* ( * PFNGLXGETCURRENTDISPLAYPROC) (void); + +#define glXGetCurrentDisplay GLXEW_GET_FUN(__glewXGetCurrentDisplay) + +#define GLXEW_VERSION_1_2 GLXEW_GET_VAR(__GLXEW_VERSION_1_2) + +#endif /* GLX_VERSION_1_2 */ + +/* ---------------------------- GLX_VERSION_1_3 ---------------------------- */ + +#ifndef GLX_VERSION_1_3 +#define GLX_VERSION_1_3 1 + +#define GLX_RGBA_BIT 0x00000001 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_VISUAL_ID 0x800B +#define GLX_SCREEN 0x800C +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_DONT_CARE 0xFFFFFFFF + +typedef XID GLXFBConfigID; +typedef XID GLXWindow; +typedef XID GLXPbuffer; +typedef struct __GLXFBConfigRec *GLXFBConfig; +typedef struct { int event_type; int draw_type; unsigned long serial; Bool send_event; Display *display; GLXDrawable drawable; unsigned int buffer_mask; unsigned int aux_buffer; int x, y; int width, height; int count; } GLXPbufferClobberEvent; +typedef union __GLXEvent { GLXPbufferClobberEvent glxpbufferclobber; long pad[24]; } GLXEvent; + +typedef GLXFBConfig* ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list); +typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); +typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); +typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); +typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win); +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void); +typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value); +typedef GLXFBConfig* ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements); +typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask); +typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); +typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value); +typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask); + +#define glXChooseFBConfig GLXEW_GET_FUN(__glewXChooseFBConfig) +#define glXCreateNewContext GLXEW_GET_FUN(__glewXCreateNewContext) +#define glXCreatePbuffer GLXEW_GET_FUN(__glewXCreatePbuffer) +#define glXCreatePixmap GLXEW_GET_FUN(__glewXCreatePixmap) +#define glXCreateWindow GLXEW_GET_FUN(__glewXCreateWindow) +#define glXDestroyPbuffer GLXEW_GET_FUN(__glewXDestroyPbuffer) +#define glXDestroyPixmap GLXEW_GET_FUN(__glewXDestroyPixmap) +#define glXDestroyWindow GLXEW_GET_FUN(__glewXDestroyWindow) +#define glXGetCurrentReadDrawable GLXEW_GET_FUN(__glewXGetCurrentReadDrawable) +#define glXGetFBConfigAttrib GLXEW_GET_FUN(__glewXGetFBConfigAttrib) +#define glXGetFBConfigs GLXEW_GET_FUN(__glewXGetFBConfigs) +#define glXGetSelectedEvent GLXEW_GET_FUN(__glewXGetSelectedEvent) +#define glXGetVisualFromFBConfig GLXEW_GET_FUN(__glewXGetVisualFromFBConfig) +#define glXMakeContextCurrent GLXEW_GET_FUN(__glewXMakeContextCurrent) +#define glXQueryContext GLXEW_GET_FUN(__glewXQueryContext) +#define glXQueryDrawable GLXEW_GET_FUN(__glewXQueryDrawable) +#define glXSelectEvent GLXEW_GET_FUN(__glewXSelectEvent) + +#define GLXEW_VERSION_1_3 GLXEW_GET_VAR(__GLXEW_VERSION_1_3) + +#endif /* GLX_VERSION_1_3 */ + +/* ---------------------------- GLX_VERSION_1_4 ---------------------------- */ + +#ifndef GLX_VERSION_1_4 +#define GLX_VERSION_1_4 1 + +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 + +extern void ( * glXGetProcAddress (const GLubyte *procName)) (void); + +#define GLXEW_VERSION_1_4 GLXEW_GET_VAR(__GLXEW_VERSION_1_4) + +#endif /* GLX_VERSION_1_4 */ + +/* -------------------------- GLX_3DFX_multisample ------------------------- */ + +#ifndef GLX_3DFX_multisample +#define GLX_3DFX_multisample 1 + +#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 +#define GLX_SAMPLES_3DFX 0x8051 + +#define GLXEW_3DFX_multisample GLXEW_GET_VAR(__GLXEW_3DFX_multisample) + +#endif /* GLX_3DFX_multisample */ + +/* ------------------------- GLX_ARB_fbconfig_float ------------------------ */ + +#ifndef GLX_ARB_fbconfig_float +#define GLX_ARB_fbconfig_float 1 + +#define GLX_RGBA_FLOAT_BIT 0x00000004 +#define GLX_RGBA_FLOAT_TYPE 0x20B9 + +#define GLXEW_ARB_fbconfig_float GLXEW_GET_VAR(__GLXEW_ARB_fbconfig_float) + +#endif /* GLX_ARB_fbconfig_float */ + +/* ------------------------ GLX_ARB_get_proc_address ----------------------- */ + +#ifndef GLX_ARB_get_proc_address +#define GLX_ARB_get_proc_address 1 + +extern void ( * glXGetProcAddressARB (const GLubyte *procName)) (void); + +#define GLXEW_ARB_get_proc_address GLXEW_GET_VAR(__GLXEW_ARB_get_proc_address) + +#endif /* GLX_ARB_get_proc_address */ + +/* -------------------------- GLX_ARB_multisample -------------------------- */ + +#ifndef GLX_ARB_multisample +#define GLX_ARB_multisample 1 + +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 + +#define GLXEW_ARB_multisample GLXEW_GET_VAR(__GLXEW_ARB_multisample) + +#endif /* GLX_ARB_multisample */ + +/* ----------------------- GLX_ATI_pixel_format_float ---------------------- */ + +#ifndef GLX_ATI_pixel_format_float +#define GLX_ATI_pixel_format_float 1 + +#define GLX_RGBA_FLOAT_ATI_BIT 0x00000100 + +#define GLXEW_ATI_pixel_format_float GLXEW_GET_VAR(__GLXEW_ATI_pixel_format_float) + +#endif /* GLX_ATI_pixel_format_float */ + +/* ------------------------- GLX_ATI_render_texture ------------------------ */ + +#ifndef GLX_ATI_render_texture +#define GLX_ATI_render_texture 1 + +#define GLX_BIND_TO_TEXTURE_RGB_ATI 0x9800 +#define GLX_BIND_TO_TEXTURE_RGBA_ATI 0x9801 +#define GLX_TEXTURE_FORMAT_ATI 0x9802 +#define GLX_TEXTURE_TARGET_ATI 0x9803 +#define GLX_MIPMAP_TEXTURE_ATI 0x9804 +#define GLX_TEXTURE_RGB_ATI 0x9805 +#define GLX_TEXTURE_RGBA_ATI 0x9806 +#define GLX_NO_TEXTURE_ATI 0x9807 +#define GLX_TEXTURE_CUBE_MAP_ATI 0x9808 +#define GLX_TEXTURE_1D_ATI 0x9809 +#define GLX_TEXTURE_2D_ATI 0x980A +#define GLX_MIPMAP_LEVEL_ATI 0x980B +#define GLX_CUBE_MAP_FACE_ATI 0x980C +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_X_ATI 0x980D +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_X_ATI 0x980E +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Y_ATI 0x980F +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Y_ATI 0x9810 +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Z_ATI 0x9811 +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Z_ATI 0x9812 +#define GLX_FRONT_LEFT_ATI 0x9813 +#define GLX_FRONT_RIGHT_ATI 0x9814 +#define GLX_BACK_LEFT_ATI 0x9815 +#define GLX_BACK_RIGHT_ATI 0x9816 +#define GLX_AUX0_ATI 0x9817 +#define GLX_AUX1_ATI 0x9818 +#define GLX_AUX2_ATI 0x9819 +#define GLX_AUX3_ATI 0x981A +#define GLX_AUX4_ATI 0x981B +#define GLX_AUX5_ATI 0x981C +#define GLX_AUX6_ATI 0x981D +#define GLX_AUX7_ATI 0x981E +#define GLX_AUX8_ATI 0x981F +#define GLX_AUX9_ATI 0x9820 +#define GLX_BIND_TO_TEXTURE_LUMINANCE_ATI 0x9821 +#define GLX_BIND_TO_TEXTURE_INTENSITY_ATI 0x9822 + +typedef void ( * PFNGLXBINDTEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); +typedef void ( * PFNGLXDRAWABLEATTRIBATIPROC) (Display *dpy, GLXDrawable draw, const int *attrib_list); +typedef void ( * PFNGLXRELEASETEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); + +#define glXBindTexImageATI GLXEW_GET_FUN(__glewXBindTexImageATI) +#define glXDrawableAttribATI GLXEW_GET_FUN(__glewXDrawableAttribATI) +#define glXReleaseTexImageATI GLXEW_GET_FUN(__glewXReleaseTexImageATI) + +#define GLXEW_ATI_render_texture GLXEW_GET_VAR(__GLXEW_ATI_render_texture) + +#endif /* GLX_ATI_render_texture */ + +/* --------------------- GLX_EXT_fbconfig_packed_float --------------------- */ + +#ifndef GLX_EXT_fbconfig_packed_float +#define GLX_EXT_fbconfig_packed_float 1 + +#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 +#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 + +#define GLXEW_EXT_fbconfig_packed_float GLXEW_GET_VAR(__GLXEW_EXT_fbconfig_packed_float) + +#endif /* GLX_EXT_fbconfig_packed_float */ + +/* ------------------------ GLX_EXT_framebuffer_sRGB ----------------------- */ + +#ifndef GLX_EXT_framebuffer_sRGB +#define GLX_EXT_framebuffer_sRGB 1 + +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 + +#define GLXEW_EXT_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_EXT_framebuffer_sRGB) + +#endif /* GLX_EXT_framebuffer_sRGB */ + +/* ------------------------- GLX_EXT_import_context ------------------------ */ + +#ifndef GLX_EXT_import_context +#define GLX_EXT_import_context 1 + +#define GLX_SHARE_CONTEXT_EXT 0x800A +#define GLX_VISUAL_ID_EXT 0x800B +#define GLX_SCREEN_EXT 0x800C + +typedef XID GLXContextID; + +typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display* dpy, GLXContext context); +typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); +typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display* dpy, GLXContextID contextID); +typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display* dpy, GLXContext context, int attribute,int *value); + +#define glXFreeContextEXT GLXEW_GET_FUN(__glewXFreeContextEXT) +#define glXGetContextIDEXT GLXEW_GET_FUN(__glewXGetContextIDEXT) +#define glXImportContextEXT GLXEW_GET_FUN(__glewXImportContextEXT) +#define glXQueryContextInfoEXT GLXEW_GET_FUN(__glewXQueryContextInfoEXT) + +#define GLXEW_EXT_import_context GLXEW_GET_VAR(__GLXEW_EXT_import_context) + +#endif /* GLX_EXT_import_context */ + +/* -------------------------- GLX_EXT_scene_marker ------------------------- */ + +#ifndef GLX_EXT_scene_marker +#define GLX_EXT_scene_marker 1 + +#define GLXEW_EXT_scene_marker GLXEW_GET_VAR(__GLXEW_EXT_scene_marker) + +#endif /* GLX_EXT_scene_marker */ + +/* -------------------------- GLX_EXT_visual_info -------------------------- */ + +#ifndef GLX_EXT_visual_info +#define GLX_EXT_visual_info 1 + +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 + +#define GLXEW_EXT_visual_info GLXEW_GET_VAR(__GLXEW_EXT_visual_info) + +#endif /* GLX_EXT_visual_info */ + +/* ------------------------- GLX_EXT_visual_rating ------------------------- */ + +#ifndef GLX_EXT_visual_rating +#define GLX_EXT_visual_rating 1 + +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D + +#define GLXEW_EXT_visual_rating GLXEW_GET_VAR(__GLXEW_EXT_visual_rating) + +#endif /* GLX_EXT_visual_rating */ + +/* -------------------------- GLX_MESA_agp_offset -------------------------- */ + +#ifndef GLX_MESA_agp_offset +#define GLX_MESA_agp_offset 1 + +typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void* pointer); + +#define glXGetAGPOffsetMESA GLXEW_GET_FUN(__glewXGetAGPOffsetMESA) + +#define GLXEW_MESA_agp_offset GLXEW_GET_VAR(__GLXEW_MESA_agp_offset) + +#endif /* GLX_MESA_agp_offset */ + +/* ------------------------ GLX_MESA_copy_sub_buffer ----------------------- */ + +#ifndef GLX_MESA_copy_sub_buffer +#define GLX_MESA_copy_sub_buffer 1 + +typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display* dpy, GLXDrawable drawable, int x, int y, int width, int height); + +#define glXCopySubBufferMESA GLXEW_GET_FUN(__glewXCopySubBufferMESA) + +#define GLXEW_MESA_copy_sub_buffer GLXEW_GET_VAR(__GLXEW_MESA_copy_sub_buffer) + +#endif /* GLX_MESA_copy_sub_buffer */ + +/* ------------------------ GLX_MESA_pixmap_colormap ----------------------- */ + +#ifndef GLX_MESA_pixmap_colormap +#define GLX_MESA_pixmap_colormap 1 + +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display* dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); + +#define glXCreateGLXPixmapMESA GLXEW_GET_FUN(__glewXCreateGLXPixmapMESA) + +#define GLXEW_MESA_pixmap_colormap GLXEW_GET_VAR(__GLXEW_MESA_pixmap_colormap) + +#endif /* GLX_MESA_pixmap_colormap */ + +/* ------------------------ GLX_MESA_release_buffers ----------------------- */ + +#ifndef GLX_MESA_release_buffers +#define GLX_MESA_release_buffers 1 + +typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display* dpy, GLXDrawable d); + +#define glXReleaseBuffersMESA GLXEW_GET_FUN(__glewXReleaseBuffersMESA) + +#define GLXEW_MESA_release_buffers GLXEW_GET_VAR(__GLXEW_MESA_release_buffers) + +#endif /* GLX_MESA_release_buffers */ + +/* ------------------------- GLX_MESA_set_3dfx_mode ------------------------ */ + +#ifndef GLX_MESA_set_3dfx_mode +#define GLX_MESA_set_3dfx_mode 1 + +#define GLX_3DFX_WINDOW_MODE_MESA 0x1 +#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 + +typedef GLboolean ( * PFNGLXSET3DFXMODEMESAPROC) (GLint mode); + +#define glXSet3DfxModeMESA GLXEW_GET_FUN(__glewXSet3DfxModeMESA) + +#define GLXEW_MESA_set_3dfx_mode GLXEW_GET_VAR(__GLXEW_MESA_set_3dfx_mode) + +#endif /* GLX_MESA_set_3dfx_mode */ + +/* -------------------------- GLX_NV_float_buffer -------------------------- */ + +#ifndef GLX_NV_float_buffer +#define GLX_NV_float_buffer 1 + +#define GLX_FLOAT_COMPONENTS_NV 0x20B0 + +#define GLXEW_NV_float_buffer GLXEW_GET_VAR(__GLXEW_NV_float_buffer) + +#endif /* GLX_NV_float_buffer */ + +/* ----------------------- GLX_NV_vertex_array_range ----------------------- */ + +#ifndef GLX_NV_vertex_array_range +#define GLX_NV_vertex_array_range 1 + +typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); +typedef void ( * PFNGLXFREEMEMORYNVPROC) (void *pointer); + +#define glXAllocateMemoryNV GLXEW_GET_FUN(__glewXAllocateMemoryNV) +#define glXFreeMemoryNV GLXEW_GET_FUN(__glewXFreeMemoryNV) + +#define GLXEW_NV_vertex_array_range GLXEW_GET_VAR(__GLXEW_NV_vertex_array_range) + +#endif /* GLX_NV_vertex_array_range */ + +/* -------------------------- GLX_OML_swap_method -------------------------- */ + +#ifndef GLX_OML_swap_method +#define GLX_OML_swap_method 1 + +#define GLX_SWAP_METHOD_OML 0x8060 +#define GLX_SWAP_EXCHANGE_OML 0x8061 +#define GLX_SWAP_COPY_OML 0x8062 +#define GLX_SWAP_UNDEFINED_OML 0x8063 + +#define GLXEW_OML_swap_method GLXEW_GET_VAR(__GLXEW_OML_swap_method) + +#endif /* GLX_OML_swap_method */ + +/* -------------------------- GLX_OML_sync_control ------------------------- */ + +#if !defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include +#define GLX_OML_sync_control 1 + +typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator); +typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc); +typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); +typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc); +typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc); + +#define glXGetMscRateOML GLXEW_GET_FUN(__glewXGetMscRateOML) +#define glXGetSyncValuesOML GLXEW_GET_FUN(__glewXGetSyncValuesOML) +#define glXSwapBuffersMscOML GLXEW_GET_FUN(__glewXSwapBuffersMscOML) +#define glXWaitForMscOML GLXEW_GET_FUN(__glewXWaitForMscOML) +#define glXWaitForSbcOML GLXEW_GET_FUN(__glewXWaitForSbcOML) + +#define GLXEW_OML_sync_control GLXEW_GET_VAR(__GLXEW_OML_sync_control) + +#endif /* GLX_OML_sync_control */ + +/* ------------------------ GLX_SGIS_blended_overlay ----------------------- */ + +#ifndef GLX_SGIS_blended_overlay +#define GLX_SGIS_blended_overlay 1 + +#define GLX_BLENDED_RGBA_SGIS 0x8025 + +#define GLXEW_SGIS_blended_overlay GLXEW_GET_VAR(__GLXEW_SGIS_blended_overlay) + +#endif /* GLX_SGIS_blended_overlay */ + +/* -------------------------- GLX_SGIS_color_range ------------------------- */ + +#ifndef GLX_SGIS_color_range +#define GLX_SGIS_color_range 1 + +#define GLX_MIN_RED_SGIS 0 +#define GLX_MAX_GREEN_SGIS 0 +#define GLX_MIN_BLUE_SGIS 0 +#define GLX_MAX_ALPHA_SGIS 0 +#define GLX_MIN_GREEN_SGIS 0 +#define GLX_MIN_ALPHA_SGIS 0 +#define GLX_MAX_RED_SGIS 0 +#define GLX_EXTENDED_RANGE_SGIS 0 +#define GLX_MAX_BLUE_SGIS 0 + +#define GLXEW_SGIS_color_range GLXEW_GET_VAR(__GLXEW_SGIS_color_range) + +#endif /* GLX_SGIS_color_range */ + +/* -------------------------- GLX_SGIS_multisample ------------------------- */ + +#ifndef GLX_SGIS_multisample +#define GLX_SGIS_multisample 1 + +#define GLX_SAMPLE_BUFFERS_SGIS 100000 +#define GLX_SAMPLES_SGIS 100001 + +#define GLXEW_SGIS_multisample GLXEW_GET_VAR(__GLXEW_SGIS_multisample) + +#endif /* GLX_SGIS_multisample */ + +/* ---------------------- GLX_SGIS_shared_multisample ---------------------- */ + +#ifndef GLX_SGIS_shared_multisample +#define GLX_SGIS_shared_multisample 1 + +#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 +#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 + +#define GLXEW_SGIS_shared_multisample GLXEW_GET_VAR(__GLXEW_SGIS_shared_multisample) + +#endif /* GLX_SGIS_shared_multisample */ + +/* --------------------------- GLX_SGIX_fbconfig --------------------------- */ + +#ifndef GLX_SGIX_fbconfig +#define GLX_SGIX_fbconfig 1 + +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_RGBA_BIT_SGIX 0x00000001 +#define GLX_PIXMAP_BIT_SGIX 0x00000002 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_SCREEN_EXT 0x800C +#define GLX_DRAWABLE_TYPE_SGIX 0x8010 +#define GLX_RENDER_TYPE_SGIX 0x8011 +#define GLX_X_RENDERABLE_SGIX 0x8012 +#define GLX_FBCONFIG_ID_SGIX 0x8013 +#define GLX_RGBA_TYPE_SGIX 0x8014 +#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 + +typedef XID GLXFBConfigIDSGIX; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; + +typedef GLXFBConfigSGIX* ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, Pixmap pixmap); +typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display* dpy, GLXFBConfigSGIX config, int attribute, int *value); +typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display* dpy, XVisualInfo *vis); +typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfig config); + +#define glXChooseFBConfigSGIX GLXEW_GET_FUN(__glewXChooseFBConfigSGIX) +#define glXCreateContextWithConfigSGIX GLXEW_GET_FUN(__glewXCreateContextWithConfigSGIX) +#define glXCreateGLXPixmapWithConfigSGIX GLXEW_GET_FUN(__glewXCreateGLXPixmapWithConfigSGIX) +#define glXGetFBConfigAttribSGIX GLXEW_GET_FUN(__glewXGetFBConfigAttribSGIX) +#define glXGetFBConfigFromVisualSGIX GLXEW_GET_FUN(__glewXGetFBConfigFromVisualSGIX) +#define glXGetVisualFromFBConfigSGIX GLXEW_GET_FUN(__glewXGetVisualFromFBConfigSGIX) + +#define GLXEW_SGIX_fbconfig GLXEW_GET_VAR(__GLXEW_SGIX_fbconfig) + +#endif /* GLX_SGIX_fbconfig */ + +/* ---------------------------- GLX_SGIX_pbuffer --------------------------- */ + +#ifndef GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer 1 + +#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 +#define GLX_PBUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 +#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 +#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 +#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 +#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 +#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 +#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 +#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 +#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 +#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A +#define GLX_PRESERVED_CONTENTS_SGIX 0x801B +#define GLX_LARGEST_PBUFFER_SGIX 0x801C +#define GLX_WIDTH_SGIX 0x801D +#define GLX_HEIGHT_SGIX 0x801E +#define GLX_EVENT_MASK_SGIX 0x801F +#define GLX_DAMAGED_SGIX 0x8020 +#define GLX_SAVED_SGIX 0x8021 +#define GLX_WINDOW_SGIX 0x8022 +#define GLX_PBUFFER_SGIX 0x8023 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 + +typedef XID GLXPbufferSGIX; +typedef struct { int type; unsigned long serial; Bool send_event; Display *display; GLXDrawable drawable; int event_type; int draw_type; unsigned int mask; int x, y; int width, height; int count; } GLXBufferClobberEventSGIX; + +typedef GLXPbuffer ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display* dpy, GLXFBConfig config, unsigned int width, unsigned int height, int *attrib_list); +typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long *mask); +typedef void ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long mask); + +#define glXCreateGLXPbufferSGIX GLXEW_GET_FUN(__glewXCreateGLXPbufferSGIX) +#define glXDestroyGLXPbufferSGIX GLXEW_GET_FUN(__glewXDestroyGLXPbufferSGIX) +#define glXGetSelectedEventSGIX GLXEW_GET_FUN(__glewXGetSelectedEventSGIX) +#define glXQueryGLXPbufferSGIX GLXEW_GET_FUN(__glewXQueryGLXPbufferSGIX) +#define glXSelectEventSGIX GLXEW_GET_FUN(__glewXSelectEventSGIX) + +#define GLXEW_SGIX_pbuffer GLXEW_GET_VAR(__GLXEW_SGIX_pbuffer) + +#endif /* GLX_SGIX_pbuffer */ + +/* ------------------------- GLX_SGIX_swap_barrier ------------------------- */ + +#ifndef GLX_SGIX_swap_barrier +#define GLX_SGIX_swap_barrier 1 + +typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier); +typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max); + +#define glXBindSwapBarrierSGIX GLXEW_GET_FUN(__glewXBindSwapBarrierSGIX) +#define glXQueryMaxSwapBarriersSGIX GLXEW_GET_FUN(__glewXQueryMaxSwapBarriersSGIX) + +#define GLXEW_SGIX_swap_barrier GLXEW_GET_VAR(__GLXEW_SGIX_swap_barrier) + +#endif /* GLX_SGIX_swap_barrier */ + +/* -------------------------- GLX_SGIX_swap_group -------------------------- */ + +#ifndef GLX_SGIX_swap_group +#define GLX_SGIX_swap_group 1 + +typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); + +#define glXJoinSwapGroupSGIX GLXEW_GET_FUN(__glewXJoinSwapGroupSGIX) + +#define GLXEW_SGIX_swap_group GLXEW_GET_VAR(__GLXEW_SGIX_swap_group) + +#endif /* GLX_SGIX_swap_group */ + +/* ------------------------- GLX_SGIX_video_resize ------------------------- */ + +#ifndef GLX_SGIX_video_resize +#define GLX_SGIX_video_resize 1 + +#define GLX_SYNC_FRAME_SGIX 0x00000000 +#define GLX_SYNC_SWAP_SGIX 0x00000001 + +typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display* display, int screen, int channel, Window window); +typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int x, int y, int w, int h); +typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display* display, int screen, int channel, GLenum synctype); +typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display* display, int screen, int channel, int *x, int *y, int *w, int *h); +typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); + +#define glXBindChannelToWindowSGIX GLXEW_GET_FUN(__glewXBindChannelToWindowSGIX) +#define glXChannelRectSGIX GLXEW_GET_FUN(__glewXChannelRectSGIX) +#define glXChannelRectSyncSGIX GLXEW_GET_FUN(__glewXChannelRectSyncSGIX) +#define glXQueryChannelDeltasSGIX GLXEW_GET_FUN(__glewXQueryChannelDeltasSGIX) +#define glXQueryChannelRectSGIX GLXEW_GET_FUN(__glewXQueryChannelRectSGIX) + +#define GLXEW_SGIX_video_resize GLXEW_GET_VAR(__GLXEW_SGIX_video_resize) + +#endif /* GLX_SGIX_video_resize */ + +/* ---------------------- GLX_SGIX_visual_select_group --------------------- */ + +#ifndef GLX_SGIX_visual_select_group +#define GLX_SGIX_visual_select_group 1 + +#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 + +#define GLXEW_SGIX_visual_select_group GLXEW_GET_VAR(__GLXEW_SGIX_visual_select_group) + +#endif /* GLX_SGIX_visual_select_group */ + +/* ---------------------------- GLX_SGI_cushion ---------------------------- */ + +#ifndef GLX_SGI_cushion +#define GLX_SGI_cushion 1 + +typedef void ( * PFNGLXCUSHIONSGIPROC) (Display* dpy, Window window, float cushion); + +#define glXCushionSGI GLXEW_GET_FUN(__glewXCushionSGI) + +#define GLXEW_SGI_cushion GLXEW_GET_VAR(__GLXEW_SGI_cushion) + +#endif /* GLX_SGI_cushion */ + +/* ----------------------- GLX_SGI_make_current_read ----------------------- */ + +#ifndef GLX_SGI_make_current_read +#define GLX_SGI_make_current_read 1 + +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); +typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + +#define glXGetCurrentReadDrawableSGI GLXEW_GET_FUN(__glewXGetCurrentReadDrawableSGI) +#define glXMakeCurrentReadSGI GLXEW_GET_FUN(__glewXMakeCurrentReadSGI) + +#define GLXEW_SGI_make_current_read GLXEW_GET_VAR(__GLXEW_SGI_make_current_read) + +#endif /* GLX_SGI_make_current_read */ + +/* -------------------------- GLX_SGI_swap_control ------------------------- */ + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control 1 + +typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); + +#define glXSwapIntervalSGI GLXEW_GET_FUN(__glewXSwapIntervalSGI) + +#define GLXEW_SGI_swap_control GLXEW_GET_VAR(__GLXEW_SGI_swap_control) + +#endif /* GLX_SGI_swap_control */ + +/* --------------------------- GLX_SGI_video_sync -------------------------- */ + +#ifndef GLX_SGI_video_sync +#define GLX_SGI_video_sync 1 + +typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (uint* count); +typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int* count); + +#define glXGetVideoSyncSGI GLXEW_GET_FUN(__glewXGetVideoSyncSGI) +#define glXWaitVideoSyncSGI GLXEW_GET_FUN(__glewXWaitVideoSyncSGI) + +#define GLXEW_SGI_video_sync GLXEW_GET_VAR(__GLXEW_SGI_video_sync) + +#endif /* GLX_SGI_video_sync */ + +/* --------------------- GLX_SUN_get_transparent_index --------------------- */ + +#ifndef GLX_SUN_get_transparent_index +#define GLX_SUN_get_transparent_index 1 + +typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display* dpy, Window overlay, Window underlay, unsigned long *pTransparentIndex); + +#define glXGetTransparentIndexSUN GLXEW_GET_FUN(__glewXGetTransparentIndexSUN) + +#define GLXEW_SUN_get_transparent_index GLXEW_GET_VAR(__GLXEW_SUN_get_transparent_index) + +#endif /* GLX_SUN_get_transparent_index */ + +/* -------------------------- GLX_SUN_video_resize ------------------------- */ + +#ifndef GLX_SUN_video_resize +#define GLX_SUN_video_resize 1 + +#define GLX_VIDEO_RESIZE_SUN 0x8171 +#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD + +typedef int ( * PFNGLXGETVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float* factor); +typedef int ( * PFNGLXVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float factor); + +#define glXGetVideoResizeSUN GLXEW_GET_FUN(__glewXGetVideoResizeSUN) +#define glXVideoResizeSUN GLXEW_GET_FUN(__glewXVideoResizeSUN) + +#define GLXEW_SUN_video_resize GLXEW_GET_VAR(__GLXEW_SUN_video_resize) + +#endif /* GLX_SUN_video_resize */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX +#define GLXEW_EXPORT +#else +#define GLXEW_EXPORT extern +#endif /* GLEW_MX */ + +extern PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay; + +extern PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig; +extern PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext; +extern PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer; +extern PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap; +extern PFNGLXCREATEWINDOWPROC __glewXCreateWindow; +extern PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer; +extern PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap; +extern PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow; +extern PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable; +extern PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib; +extern PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs; +extern PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent; +extern PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig; +extern PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent; +extern PFNGLXQUERYCONTEXTPROC __glewXQueryContext; +extern PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable; +extern PFNGLXSELECTEVENTPROC __glewXSelectEvent; + +extern PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI; +extern PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI; +extern PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI; + +extern PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT; +extern PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT; +extern PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT; +extern PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT; + +extern PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA; + +extern PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA; + +extern PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA; + +extern PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA; + +extern PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA; + +extern PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV; +extern PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV; + +#ifdef GLX_OML_sync_control +extern PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML; +extern PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML; +extern PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML; +extern PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML; +extern PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML; +#endif + +extern PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX; +extern PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX; +extern PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX; +extern PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX; +extern PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX; +extern PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX; + +extern PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX; +extern PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX; +extern PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX; +extern PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX; +extern PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX; + +extern PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX; +extern PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX; + +extern PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX; + +extern PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX; +extern PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX; +extern PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX; +extern PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX; +extern PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX; + +extern PFNGLXCUSHIONSGIPROC __glewXCushionSGI; + +extern PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI; +extern PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI; + +extern PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI; + +extern PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI; +extern PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI; + +extern PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN; + +extern PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN; +extern PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN; + +#if defined(GLEW_MX) +struct GLXEWContextStruct +{ +#endif /* GLEW_MX */ + +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_0; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_1; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_2; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_3; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_4; +GLXEW_EXPORT GLboolean __GLXEW_3DFX_multisample; +GLXEW_EXPORT GLboolean __GLXEW_ARB_fbconfig_float; +GLXEW_EXPORT GLboolean __GLXEW_ARB_get_proc_address; +GLXEW_EXPORT GLboolean __GLXEW_ARB_multisample; +GLXEW_EXPORT GLboolean __GLXEW_ATI_pixel_format_float; +GLXEW_EXPORT GLboolean __GLXEW_ATI_render_texture; +GLXEW_EXPORT GLboolean __GLXEW_EXT_fbconfig_packed_float; +GLXEW_EXPORT GLboolean __GLXEW_EXT_framebuffer_sRGB; +GLXEW_EXPORT GLboolean __GLXEW_EXT_import_context; +GLXEW_EXPORT GLboolean __GLXEW_EXT_scene_marker; +GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_info; +GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_rating; +GLXEW_EXPORT GLboolean __GLXEW_MESA_agp_offset; +GLXEW_EXPORT GLboolean __GLXEW_MESA_copy_sub_buffer; +GLXEW_EXPORT GLboolean __GLXEW_MESA_pixmap_colormap; +GLXEW_EXPORT GLboolean __GLXEW_MESA_release_buffers; +GLXEW_EXPORT GLboolean __GLXEW_MESA_set_3dfx_mode; +GLXEW_EXPORT GLboolean __GLXEW_NV_float_buffer; +GLXEW_EXPORT GLboolean __GLXEW_NV_vertex_array_range; +GLXEW_EXPORT GLboolean __GLXEW_OML_swap_method; +GLXEW_EXPORT GLboolean __GLXEW_OML_sync_control; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_blended_overlay; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_color_range; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_multisample; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_shared_multisample; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_fbconfig; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_pbuffer; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_swap_barrier; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_swap_group; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_video_resize; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_visual_select_group; +GLXEW_EXPORT GLboolean __GLXEW_SGI_cushion; +GLXEW_EXPORT GLboolean __GLXEW_SGI_make_current_read; +GLXEW_EXPORT GLboolean __GLXEW_SGI_swap_control; +GLXEW_EXPORT GLboolean __GLXEW_SGI_video_sync; +GLXEW_EXPORT GLboolean __GLXEW_SUN_get_transparent_index; +GLXEW_EXPORT GLboolean __GLXEW_SUN_video_resize; + +#ifdef GLEW_MX +}; /* GLXEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------ */ + +#ifdef GLEW_MX + +typedef struct GLXEWContextStruct GLXEWContext; +extern GLenum glxewContextInit (GLXEWContext* ctx); +extern GLboolean glxewContextIsSupported (GLXEWContext* ctx, const char* name); + +#define glxewInit() glxewContextInit(glxewGetContext()) +#define glxewIsSupported(x) glxewContextIsSupported(glxewGetContext(), x) + +#define GLXEW_GET_VAR(x) glxewGetContext()->x +#define GLXEW_GET_FUN(x) x + +#else /* GLEW_MX */ + +#define GLXEW_GET_VAR(x) x +#define GLXEW_GET_FUN(x) x + +extern GLboolean glxewIsSupported (const char* name); + +#endif /* GLEW_MX */ + +extern GLboolean glxewGetExtension (const char* name); + +#ifdef __cplusplus +} +#endif + +#endif /* __glxew_h__ */ diff --git a/external/cutil/inc/GL/glxext.h b/external/cutil/inc/GL/glxext.h new file mode 100644 index 0000000..df8e773 --- /dev/null +++ b/external/cutil/inc/GL/glxext.h @@ -0,0 +1,800 @@ +#ifndef __glxext_h_ +#define __glxext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +/*************************************************************/ + +/* Header file version number, required by OpenGL ABI for Linux */ +/* glxext.h last updated 2005/01/20 */ +/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ +#define GLX_GLXEXT_VERSION 10 + +#ifndef GLX_ARB_get_proc_address +#endif + +#ifndef GLX_ARB_multisample +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 +#endif + +#ifndef GLX_ARB_fbconfig_float +#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 +#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 +#endif + +#ifndef GLX_SGIS_multisample +#define GLX_SAMPLE_BUFFERS_SGIS 100000 +#define GLX_SAMPLES_SGIS 100001 +#endif + +#ifndef GLX_EXT_visual_info +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 +#endif + +#ifndef GLX_SGI_swap_control +#endif + +#ifndef GLX_SGI_video_sync +#endif + +#ifndef GLX_SGI_make_current_read +#endif + +#ifndef GLX_SGIX_video_source +#endif + +#ifndef GLX_EXT_visual_rating +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +/* reuse GLX_NONE_EXT */ +#endif + +#ifndef GLX_EXT_import_context +#define GLX_SHARE_CONTEXT_EXT 0x800A +#define GLX_VISUAL_ID_EXT 0x800B +#define GLX_SCREEN_EXT 0x800C +#endif + +#ifndef GLX_SGIX_fbconfig +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_PIXMAP_BIT_SGIX 0x00000002 +#define GLX_RGBA_BIT_SGIX 0x00000001 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_DRAWABLE_TYPE_SGIX 0x8010 +#define GLX_RENDER_TYPE_SGIX 0x8011 +#define GLX_X_RENDERABLE_SGIX 0x8012 +#define GLX_FBCONFIG_ID_SGIX 0x8013 +#define GLX_RGBA_TYPE_SGIX 0x8014 +#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 +/* reuse GLX_SCREEN_EXT */ +#endif + +#ifndef GLX_SGIX_pbuffer +#define GLX_PBUFFER_BIT_SGIX 0x00000004 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 +#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 +#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 +#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 +#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 +#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 +#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 +#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 +#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 +#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 +#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A +#define GLX_PRESERVED_CONTENTS_SGIX 0x801B +#define GLX_LARGEST_PBUFFER_SGIX 0x801C +#define GLX_WIDTH_SGIX 0x801D +#define GLX_HEIGHT_SGIX 0x801E +#define GLX_EVENT_MASK_SGIX 0x801F +#define GLX_DAMAGED_SGIX 0x8020 +#define GLX_SAVED_SGIX 0x8021 +#define GLX_WINDOW_SGIX 0x8022 +#define GLX_PBUFFER_SGIX 0x8023 +#endif + +#ifndef GLX_SGI_cushion +#endif + +#ifndef GLX_SGIX_video_resize +#define GLX_SYNC_FRAME_SGIX 0x00000000 +#define GLX_SYNC_SWAP_SGIX 0x00000001 +#endif + +#ifndef GLX_SGIX_dmbuffer +#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024 +#endif + +#ifndef GLX_SGIX_swap_group +#endif + +#ifndef GLX_SGIX_swap_barrier +#endif + +#ifndef GLX_SGIS_blended_overlay +#define GLX_BLENDED_RGBA_SGIS 0x8025 +#endif + +#ifndef GLX_SGIS_shared_multisample +#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 +#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 +#endif + +#ifndef GLX_SUN_get_transparent_index +#endif + +#ifndef GLX_3DFX_multisample +#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 +#define GLX_SAMPLES_3DFX 0x8051 +#endif + +#ifndef GLX_MESA_copy_sub_buffer +#endif + +#ifndef GLX_MESA_pixmap_colormap +#endif + +#ifndef GLX_MESA_release_buffers +#endif + +#ifndef GLX_MESA_set_3dfx_mode +#define GLX_3DFX_WINDOW_MODE_MESA 0x1 +#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 +#endif + +#ifndef GLX_SGIX_visual_select_group +#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 +#endif + +#ifndef GLX_OML_swap_method +#define GLX_SWAP_METHOD_OML 0x8060 +#define GLX_SWAP_EXCHANGE_OML 0x8061 +#define GLX_SWAP_COPY_OML 0x8062 +#define GLX_SWAP_UNDEFINED_OML 0x8063 +#endif + +#ifndef GLX_OML_sync_control +#endif + +#ifndef GLX_NV_float_buffer +#define GLX_FLOAT_COMPONENTS_NV 0x20B0 +#endif + +#ifndef GLX_SGIX_hyperpipe +#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 +#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 +#define GLX_BAD_HYPERPIPE_SGIX 92 +#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 +#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 +#define GLX_PIPE_RECT_SGIX 0x00000001 +#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 +#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 +#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 +#define GLX_HYPERPIPE_ID_SGIX 0x8030 +#endif + +#ifndef GLX_MESA_agp_offset +#endif + + +/*************************************************************/ + +#ifndef GLX_ARB_get_proc_address +/* + * Linux OpenGL ABI specifies glXGetProcAddressARB should be + * in glx.h moving related defines there as well. + */ +#endif + +#ifndef GLX_SGIX_video_source +typedef XID GLXVideoSourceSGIX; +#endif + +#ifndef GLX_SGIX_fbconfig +typedef XID GLXFBConfigIDSGIX; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; +#endif + +#ifndef GLX_SGIX_pbuffer +typedef XID GLXPbufferSGIX; +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came for SendEvent request */ + Display *display; /* display the event was read from */ + GLXDrawable drawable; /* i.d. of Drawable */ + int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ + int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ + unsigned int mask; /* mask indicating which buffers are affected*/ + int x, y; + int width, height; + int count; /* if nonzero, at least this many more */ +} GLXBufferClobberEventSGIX; +#endif + +#ifndef GLX_NV_swap_group +#endif + +#ifndef GLX_NV_video_out +/* + * GLXVideoDeviceNV is an opaque handle to a video device (part of the + * GLX_NV_video_out extension). + */ +typedef unsigned int GLXVideoDeviceNV; + +/* glXBindVideoImageNV iVideoBuffer values (NV_video_out) */ +#define GLX_VIDEO_OUT_COLOR_NV 0x20C3 +#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4 +#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5 +#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 + +/* glXSendPbufferToVideoNV iBufferType values (NV_video_out) */ +#define GLX_VIDEO_OUT_FRAME_NV 0x20C8 +#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9 +#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA +#endif + +#ifndef GLX_EXT_texture_from_pixmap +/* New glXGetFBConfigAttrib tokens */ +#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 +#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 +#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 +#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 +#define GLX_Y_INVERTED_EXT 0x20D4 + +/* New glXCreatePixmap attributes and glXQueryDrawable attributes */ +#define GLX_TEXTURE_FORMAT_EXT 0x20D5 +#define GLX_TEXTURE_TARGET_EXT 0x20D6 +#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 + +/* Values for GLX_TEXTURE_FORMAT_EXT */ +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA + +/* Bits for GLX_BIND_TO_TEXTURE_TARGETS_EXT mask */ +#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 +#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 +#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 + +/* Values for GLX_TEXTURE_TARGET_EXT */ +#define GLX_TEXTURE_1D_EXT 0x20DB +#define GLX_TEXTURE_2D_EXT 0x20DC +#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD + +/* + * Values for the buffer parameter of glXBindTexImageEXT and + * glXReleaseTexImageEXT + */ +#define GLX_FRONT_LEFT_EXT 0x20DE +#define GLX_FRONT_RIGHT_EXT 0x20DF +#define GLX_BACK_LEFT_EXT 0x20E0 +#define GLX_BACK_RIGHT_EXT 0x20E1 +#define GLX_FRONT_EXT GLX_FRONT_LEFT_EXT +#define GLX_BACK_EXT GLX_BACK_LEFT_EXT +#define GLX_AUX0_EXT 0x20E2 +#define GLX_AUX1_EXT 0x20E3 +#define GLX_AUX2_EXT 0x20E4 +#define GLX_AUX3_EXT 0x20E5 +#define GLX_AUX4_EXT 0x20E6 +#define GLX_AUX5_EXT 0x20E7 +#define GLX_AUX6_EXT 0x20E8 +#define GLX_AUX7_EXT 0x20E9 +#define GLX_AUX8_EXT 0x20EA +#define GLX_AUX9_EXT 0x20EB + +#endif + +/* Define int32_t and int64_t types for UST/MSC */ +/* (as used in the GLX_OML_sync_control extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined( __VMS ) || defined(__FreeBSD__) +#include +#elif (defined(__sun__) && defined(__svr4__)) || (defined(__sun) && defined(__SVR4)) +#include +#elif defined(__SCO__) || defined(__USLC__) || defined(__linux__) +#include +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +#else +#error "int32_t and int64_t are undefined!" +#endif + +#ifndef GLX_ARB_get_proc_address +/* Moved to glx.h */ +#endif + +#ifndef GLX_ARB_multisample +#define GLX_ARB_multisample 1 +#endif + +#ifndef GLX_ARB_fbconfig_float +#define GLX_ARB_fbconfig_float 1 +#endif + +#ifndef GLX_SGIS_multisample +#define GLX_SGIS_multisample 1 +#endif + +#ifndef GLX_EXT_visual_info +#define GLX_EXT_visual_info 1 +#endif + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern int glXSwapIntervalSGI (int); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); +#endif + +#ifndef GLX_SGI_video_sync +#define GLX_SGI_video_sync 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern int glXGetVideoSyncSGI (unsigned int *); +extern int glXWaitVideoSyncSGI (int, int, unsigned int *); +extern int glXGetRefreshRateSGI(unsigned int *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int *count); +typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int *count); +typedef int ( * PFNGLXGETREFRESHRATESGIPROC) (unsigned int *); +#endif + +#ifndef GLX_SGI_make_current_read +#define GLX_SGI_make_current_read 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXMakeCurrentReadSGI (Display *, GLXDrawable, GLXDrawable, GLXContext); +extern GLXDrawable glXGetCurrentReadDrawableSGI (void); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); +#endif + +#ifndef GLX_SGIX_video_source +#define GLX_SGIX_video_source 1 +#ifdef _VL_H +#ifdef GLX_GLXEXT_PROTOTYPES +extern GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX (Display *, int, VLServer, VLPath, int, VLNode); +extern void glXDestroyGLXVideoSourceSGIX (Display *, GLXVideoSourceSGIX); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef GLXVideoSourceSGIX ( * PFNGLXCREATEGLXVIDEOSOURCESGIXPROC) (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode); +typedef void ( * PFNGLXDESTROYGLXVIDEOSOURCESGIXPROC) (Display *dpy, GLXVideoSourceSGIX glxvideosource); +#endif /* _VL_H */ +#endif + +#ifndef GLX_EXT_visual_rating +#define GLX_EXT_visual_rating 1 +#endif + +#ifndef GLX_EXT_import_context +#define GLX_EXT_import_context 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Display * glXGetCurrentDisplayEXT (void); +extern int glXQueryContextInfoEXT (Display *, GLXContext, int, int *); +extern GLXContextID glXGetContextIDEXT (const GLXContext); +extern GLXContext glXImportContextEXT (Display *, GLXContextID); +extern void glXFreeContextEXT (Display *, GLXContext); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Display * ( * PFNGLXGETCURRENTDISPLAYEXTPROC) (void); +typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display *dpy, GLXContext context, int attribute, int *value); +typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); +typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display *dpy, GLXContextID contextID); +typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display *dpy, GLXContext context); +#endif + +#ifndef GLX_SGIX_fbconfig +#define GLX_SGIX_fbconfig 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern int glXGetFBConfigAttribSGIX (Display *, GLXFBConfigSGIX, int, int *); +extern GLXFBConfigSGIX * glXChooseFBConfigSGIX (Display *, int, int *, int *); +extern GLXPixmap glXCreateGLXPixmapWithConfigSGIX (Display *, GLXFBConfigSGIX, Pixmap); +extern GLXContext glXCreateContextWithConfigSGIX (Display *, GLXFBConfigSGIX, int, GLXContext, Bool); +extern XVisualInfo * glXGetVisualFromFBConfigSGIX (Display *, GLXFBConfigSGIX); +extern GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX (Display *, XVisualInfo *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value); +typedef GLXFBConfigSGIX * ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, int *attrib_list, int *nelements); +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap); +typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); +typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config); +typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display *dpy, XVisualInfo *vis); +#endif + +#ifndef GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern GLXPbufferSGIX glXCreateGLXPbufferSGIX (Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *); +extern void glXDestroyGLXPbufferSGIX (Display *, GLXPbufferSGIX); +extern int glXQueryGLXPbufferSGIX (Display *, GLXPbufferSGIX, int, unsigned int *); +extern void glXSelectEventSGIX (Display *, GLXDrawable, unsigned long); +extern void glXGetSelectedEventSGIX (Display *, GLXDrawable, unsigned long *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef GLXPbufferSGIX ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list); +typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf); +typedef int ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long mask); +typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long *mask); +#endif + +#ifndef GLX_SGI_cushion +#define GLX_SGI_cushion 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXCushionSGI (Display *, Window, float); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef void ( * PFNGLXCUSHIONSGIPROC) (Display *dpy, Window window, float cushion); +#endif + +#ifndef GLX_SGIX_video_resize +#define GLX_SGIX_video_resize 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern int glXBindChannelToWindowSGIX (Display *, int, int, Window); +extern int glXChannelRectSGIX (Display *, int, int, int, int, int, int); +extern int glXQueryChannelRectSGIX (Display *, int, int, int *, int *, int *, int *); +extern int glXQueryChannelDeltasSGIX (Display *, int, int, int *, int *, int *, int *); +extern int glXChannelRectSyncSGIX (Display *, int, int, GLenum); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display *display, int screen, int channel, Window window); +typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int x, int y, int w, int h); +typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); +typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display *display, int screen, int channel, int *x, int *y, int *w, int *h); +typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display *display, int screen, int channel, GLenum synctype); +#endif + +#ifndef GLX_SGIX_dmbuffer +#define GLX_SGIX_dmbuffer 1 +#ifdef _DM_BUFFER_H_ +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXAssociateDMPbufferSGIX (Display *, GLXPbufferSGIX, DMparams *, DMbuffer); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXASSOCIATEDMPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer); +#endif /* _DM_BUFFER_H_ */ +#endif + +#ifndef GLX_SGIX_swap_group +#define GLX_SGIX_swap_group 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXJoinSwapGroupSGIX (Display *, GLXDrawable, GLXDrawable); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); +#endif + +#ifndef GLX_SGIX_swap_barrier +#define GLX_SGIX_swap_barrier 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXBindSwapBarrierSGIX (Display *, GLXDrawable, int); +extern Bool glXQueryMaxSwapBarriersSGIX (Display *, int, int *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier); +typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max); +#endif + +#ifndef GLX_SUN_get_transparent_index +#define GLX_SUN_get_transparent_index 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Status glXGetTransparentIndexSUN (Display *, Window, Window, long *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex); +#endif + +#ifndef GLX_MESA_copy_sub_buffer +#define GLX_MESA_copy_sub_buffer 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXCopySubBufferMESA (Display *, GLXDrawable, int, int, int, int); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); +#endif + +#ifndef GLX_MESA_pixmap_colormap +#define GLX_MESA_pixmap_colormap 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern GLXPixmap glXCreateGLXPixmapMESA (Display *, XVisualInfo *, Pixmap, Colormap); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); +#endif + +#ifndef GLX_MESA_release_buffers +#define GLX_MESA_release_buffers 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXReleaseBuffersMESA (Display *, GLXDrawable); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display *dpy, GLXDrawable drawable); +#endif + +#ifndef GLX_MESA_set_3dfx_mode +#define GLX_MESA_set_3dfx_mode 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXSet3DfxModeMESA (int); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXSET3DFXMODEMESAPROC) (int mode); +#endif + +#ifndef GLX_SGIX_visual_select_group +#define GLX_SGIX_visual_select_group 1 +#endif + +#ifndef GLX_OML_swap_method +#define GLX_OML_swap_method 1 +#endif + +#ifndef GLX_OML_sync_control +#define GLX_OML_sync_control 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXGetSyncValuesOML (Display *, GLXDrawable, int64_t *, int64_t *, int64_t *); +extern Bool glXGetMscRateOML (Display *, GLXDrawable, int32_t *, int32_t *); +extern int64_t glXSwapBuffersMscOML (Display *, GLXDrawable, int64_t, int64_t, int64_t); +extern Bool glXWaitForMscOML (Display *, GLXDrawable, int64_t, int64_t, int64_t, int64_t *, int64_t *, int64_t *); +extern Bool glXWaitForSbcOML (Display *, GLXDrawable, int64_t, int64_t *, int64_t *, int64_t *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc); +typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator); +typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); +typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc); +typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc); +#endif + +#ifndef GLX_NV_float_buffer +#define GLX_NV_float_buffer 1 +#endif + +#ifndef GLX_SGIX_hyperpipe +#define GLX_SGIX_hyperpipe 1 + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int networkId; +} GLXHyperpipeNetworkSGIX; + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int channel; + unsigned int + participationType; + int timeSlice; +} GLXHyperpipeConfigSGIX; + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int srcXOrigin, srcYOrigin, srcWidth, srcHeight; + int destXOrigin, destYOrigin, destWidth, destHeight; +} GLXPipeRect; + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int XOrigin, YOrigin, maxHeight, maxWidth; +} GLXPipeRectLimits; + +#ifdef GLX_GLXEXT_PROTOTYPES +extern GLXHyperpipeNetworkSGIX * glXQueryHyperpipeNetworkSGIX (Display *, int *); +extern int glXHyperpipeConfigSGIX (Display *, int, int, GLXHyperpipeConfigSGIX *, int *); +extern GLXHyperpipeConfigSGIX * glXQueryHyperpipeConfigSGIX (Display *, int, int *); +extern int glXDestroyHyperpipeConfigSGIX (Display *, int); +extern int glXBindHyperpipeSGIX (Display *, int); +extern int glXQueryHyperpipeBestAttribSGIX (Display *, int, int, int, void *, void *); +extern int glXHyperpipeAttribSGIX (Display *, int, int, int, void *); +extern int glXQueryHyperpipeAttribSGIX (Display *, int, int, int, void *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef GLXHyperpipeNetworkSGIX * ( * PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes); +typedef int ( * PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); +typedef GLXHyperpipeConfigSGIX * ( * PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes); +typedef int ( * PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId); +typedef int ( * PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId); +typedef int ( * PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); +typedef int ( * PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList); +typedef int ( * PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); +#endif + +#ifndef GLX_MESA_agp_offset +#define GLX_MESA_agp_offset 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern unsigned int glXGetAGPOffsetMESA (const void *); +#endif /* GLX_GLXEXT_PROTOTYPES */ +typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void *pointer); +#endif + +/* + * GLX_NV_vertex_array_range is not a real extension name... + */ +#ifndef GLX_NV_vertex_array_range +#define GLX_NV_vertex_array_range 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern void *glXAllocateMemoryNV(GLsizei size, GLfloat readfreq, + GLfloat writefreq, GLfloat priority); + +extern void glXFreeMemoryNV(GLvoid *pointer); +#endif +typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, + GLfloat readfreq, + GLfloat writefreq, + GLfloat priority); + +typedef void ( * PFNGLXFREEMEMORYNVPROC) (GLvoid *pointer); +#endif + +#ifndef GLX_NV_swap_group +#define GLX_NV_swap_group 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern Bool glXJoinSwapGroupNV(Display *dpy, GLXDrawable drawable, + GLuint group); + +extern Bool glXBindSwapBarrierNV(Display *dpy, GLuint group, GLuint barrier); + +extern Bool glXQuerySwapGroupNV(Display *dpy, GLXDrawable drawable, + GLuint *group, GLuint *barrier); + +extern Bool glXQueryMaxSwapGroupsNV(Display *dpy, int screen, + GLuint *maxGroups, GLuint *maxBarriers); + +extern Bool glXQueryFrameCountNV(Display *dpy, int screen, GLuint *count); + +extern Bool glXResetFrameCountNV(Display *dpy, int screen); +#endif +typedef Bool ( * PFNGLXJOINSWAPGROUPNVPROC) (Display *dpy, + GLXDrawable drawable, + GLuint group); + +typedef Bool ( * PFNGLXBINDSWAPBARRIERNVPROC) (Display *dpy, + GLuint group, + GLuint barrier); + +typedef Bool ( * PFNGLXQUERYSWAPGROUPNVPROC) (Display *dpy, + GLXDrawable drawable, + GLuint *group, + GLuint *barrier); + +typedef Bool ( * PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display *dpy, + int screen, + GLuint *maxGroups, + GLuint *maxBarriers); + +typedef Bool ( * PFNGLXQUERYFRAMECOUNTNVPROC) (Display *dpy, + int screen, + GLuint *count); + +typedef Bool ( * PFNGLXRESETFRAMECOUNTNVPROC) (Display *dpy, int screen); +#endif + +#ifndef GLX_NV_video_out +#define GLX_NV_video_out 1 +#ifdef GLX_GLXEXT_PROTOTYPES +extern int glXGetVideoDeviceNV(Display *dpy, int screen, int numVideoDevices, + GLXVideoDeviceNV *pVideoDevice); + +extern int glXReleaseVideoDeviceNV(Display *dpy, int screen, + GLXVideoDeviceNV VideoDevice); + +extern int glXBindVideoImageNV(Display *dpy, GLXVideoDeviceNV VideoDevice, + GLXPbuffer pbuf, int iVideoBuffer); + +extern int glXReleaseVideoImageNV(Display *dpy, GLXPbuffer pbuf); + +extern int glXSendPbufferToVideoNV(Display *dpy, GLXPbuffer pbuf, + int iBufferType, + unsigned long *pulCounterPbuffer, + GLboolean bBlock); + +extern int glXGetVideoInfoNV(Display *dpy, int screen, + GLXVideoDeviceNV VideoDevice, + unsigned long *pulCounterOutputVideo, + unsigned long *pulCounterOutputPbuffer); +#endif +typedef int ( * PFNGLXGETVIDEODEVICENVPROC) (Display *dpy, + int screen, + int numVideoDevices, + GLXVideoDeviceNV *pVideoDevice); + +typedef int ( * PFNGLXRELEASEVIDEODEVICENVPROC) (Display *dpy, + int screen, + GLXVideoDeviceNV VideoDevice); + +typedef int ( * PFNGLXBINDVIDEOIMAGENVPROC) (Display *dpy, + GLXVideoDeviceNV VideoDevice, + GLXPbuffer pbuf, + int iVideoBuffer); + +typedef int ( * PFNGLXRELEASEVIDEOIMAGENVPROC) (Display *dpy, + GLXPbuffer pbuf); + +typedef int ( * PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display *dpy, + GLXPbuffer pbuf, + int iBufferType, + unsigned long *pulCounterPbuffer, + GLboolean bBlock); + +typedef int ( * PFNGLXGETVIDEOINFONVPROC) (Display *dpy, int screen, + GLXVideoDeviceNV VideoDevice, + unsigned long *pulCounterOutputVideo, + unsigned long *pulCounterOutputPbuffer); +#endif + +#ifndef GLX_EXT_texture_from_pixmap +#define GLX_EXT_texture_from_pixmap +#ifdef GLX_GLXEXT_PROTOTYPES +extern void glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, + int buffer, const int *attrib_list); +extern void glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, + int buffer); +#endif +typedef void ( * PFNGLXBINDTEXIMAGEEXTPROC) (Display *dpy, + GLXDrawable drawable, + int buffer, + const int *attrib_list); +typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display *dpy, + GLXDrawable drawable, + int buffer); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/cutil/inc/GL/wglew.h b/external/cutil/inc/GL/wglew.h new file mode 100644 index 0000000..895ab9c --- /dev/null +++ b/external/cutil/inc/GL/wglew.h @@ -0,0 +1,958 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2006, Milan Ikits +** Copyright (C) 2002-2006, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef __wglew_h__ +#define __wglew_h__ +#define __WGLEW_H__ + +#ifdef __wglext_h_ +#error wglext.h included before wglew.h +#endif + +#define __wglext_h_ + +#if !defined(APIENTRY) && !defined(__CYGWIN__) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +#include +#endif + +/* + * GLEW_STATIC needs to be set when using the static version. + * GLEW_BUILD is set when building the DLL version. + */ +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# ifdef GLEW_BUILD +# define GLEWAPI extern __declspec(dllexport) +# else +# define GLEWAPI extern __declspec(dllimport) +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* -------------------------- WGL_3DFX_multisample ------------------------- */ + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 + +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 + +#define WGLEW_3DFX_multisample WGLEW_GET_VAR(__WGLEW_3DFX_multisample) + +#endif /* WGL_3DFX_multisample */ + +/* ------------------------- WGL_3DL_stereo_control ------------------------ */ + +#ifndef WGL_3DL_stereo_control +#define WGL_3DL_stereo_control 1 + +#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 +#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 +#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 +#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 + +typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); + +#define wglSetStereoEmitterState3DL WGLEW_GET_FUN(__wglewSetStereoEmitterState3DL) + +#define WGLEW_3DL_stereo_control WGLEW_GET_VAR(__WGLEW_3DL_stereo_control) + +#endif /* WGL_3DL_stereo_control */ + +/* ------------------------- WGL_ARB_buffer_region ------------------------- */ + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 + +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 + +typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); + +#define wglCreateBufferRegionARB WGLEW_GET_FUN(__wglewCreateBufferRegionARB) +#define wglDeleteBufferRegionARB WGLEW_GET_FUN(__wglewDeleteBufferRegionARB) +#define wglRestoreBufferRegionARB WGLEW_GET_FUN(__wglewRestoreBufferRegionARB) +#define wglSaveBufferRegionARB WGLEW_GET_FUN(__wglewSaveBufferRegionARB) + +#define WGLEW_ARB_buffer_region WGLEW_GET_VAR(__WGLEW_ARB_buffer_region) + +#endif /* WGL_ARB_buffer_region */ + +/* ----------------------- WGL_ARB_extensions_string ----------------------- */ + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 + +typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); + +#define wglGetExtensionsStringARB WGLEW_GET_FUN(__wglewGetExtensionsStringARB) + +#define WGLEW_ARB_extensions_string WGLEW_GET_VAR(__WGLEW_ARB_extensions_string) + +#endif /* WGL_ARB_extensions_string */ + +/* ----------------------- WGL_ARB_make_current_read ----------------------- */ + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 + +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + +#define wglGetCurrentReadDCARB WGLEW_GET_FUN(__wglewGetCurrentReadDCARB) +#define wglMakeContextCurrentARB WGLEW_GET_FUN(__wglewMakeContextCurrentARB) + +#define WGLEW_ARB_make_current_read WGLEW_GET_VAR(__WGLEW_ARB_make_current_read) + +#endif /* WGL_ARB_make_current_read */ + +/* -------------------------- WGL_ARB_multisample -------------------------- */ + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 + +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 + +#define WGLEW_ARB_multisample WGLEW_GET_VAR(__WGLEW_ARB_multisample) + +#endif /* WGL_ARB_multisample */ + +/* ---------------------------- WGL_ARB_pbuffer ---------------------------- */ + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 + +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 + +DECLARE_HANDLE(HPBUFFERARB); + +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int* piValue); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); + +#define wglCreatePbufferARB WGLEW_GET_FUN(__wglewCreatePbufferARB) +#define wglDestroyPbufferARB WGLEW_GET_FUN(__wglewDestroyPbufferARB) +#define wglGetPbufferDCARB WGLEW_GET_FUN(__wglewGetPbufferDCARB) +#define wglQueryPbufferARB WGLEW_GET_FUN(__wglewQueryPbufferARB) +#define wglReleasePbufferDCARB WGLEW_GET_FUN(__wglewReleasePbufferDCARB) + +#define WGLEW_ARB_pbuffer WGLEW_GET_VAR(__WGLEW_ARB_pbuffer) + +#endif /* WGL_ARB_pbuffer */ + +/* -------------------------- WGL_ARB_pixel_format ------------------------- */ + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 + +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B + +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int *piValues); + +#define wglChoosePixelFormatARB WGLEW_GET_FUN(__wglewChoosePixelFormatARB) +#define wglGetPixelFormatAttribfvARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvARB) +#define wglGetPixelFormatAttribivARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribivARB) + +#define WGLEW_ARB_pixel_format WGLEW_GET_VAR(__WGLEW_ARB_pixel_format) + +#endif /* WGL_ARB_pixel_format */ + +/* ----------------------- WGL_ARB_pixel_format_float ---------------------- */ + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float 1 + +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 + +#define WGLEW_ARB_pixel_format_float WGLEW_GET_VAR(__WGLEW_ARB_pixel_format_float) + +#endif /* WGL_ARB_pixel_format_float */ + +/* ------------------------- WGL_ARB_render_texture ------------------------ */ + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 + +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 + +typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int* piAttribList); + +#define wglBindTexImageARB WGLEW_GET_FUN(__wglewBindTexImageARB) +#define wglReleaseTexImageARB WGLEW_GET_FUN(__wglewReleaseTexImageARB) +#define wglSetPbufferAttribARB WGLEW_GET_FUN(__wglewSetPbufferAttribARB) + +#define WGLEW_ARB_render_texture WGLEW_GET_VAR(__WGLEW_ARB_render_texture) + +#endif /* WGL_ARB_render_texture */ + +/* ----------------------- WGL_ATI_pixel_format_float ---------------------- */ + +#ifndef WGL_ATI_pixel_format_float +#define WGL_ATI_pixel_format_float 1 + +#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 +#define GL_RGBA_FLOAT_MODE_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 + +#define WGLEW_ATI_pixel_format_float WGLEW_GET_VAR(__WGLEW_ATI_pixel_format_float) + +#endif /* WGL_ATI_pixel_format_float */ + +/* -------------------- WGL_ATI_render_texture_rectangle ------------------- */ + +#ifndef WGL_ATI_render_texture_rectangle +#define WGL_ATI_render_texture_rectangle 1 + +#define WGL_TEXTURE_RECTANGLE_ATI 0x21A5 + +#define WGLEW_ATI_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_ATI_render_texture_rectangle) + +#endif /* WGL_ATI_render_texture_rectangle */ + +/* -------------------------- WGL_EXT_depth_float -------------------------- */ + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 + +#define WGL_DEPTH_FLOAT_EXT 0x2040 + +#define WGLEW_EXT_depth_float WGLEW_GET_VAR(__WGLEW_EXT_depth_float) + +#endif /* WGL_EXT_depth_float */ + +/* ---------------------- WGL_EXT_display_color_table ---------------------- */ + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 + +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef void (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (GLushort* table, GLuint length); + +#define wglBindDisplayColorTableEXT WGLEW_GET_FUN(__wglewBindDisplayColorTableEXT) +#define wglCreateDisplayColorTableEXT WGLEW_GET_FUN(__wglewCreateDisplayColorTableEXT) +#define wglDestroyDisplayColorTableEXT WGLEW_GET_FUN(__wglewDestroyDisplayColorTableEXT) +#define wglLoadDisplayColorTableEXT WGLEW_GET_FUN(__wglewLoadDisplayColorTableEXT) + +#define WGLEW_EXT_display_color_table WGLEW_GET_VAR(__WGLEW_EXT_display_color_table) + +#endif /* WGL_EXT_display_color_table */ + +/* ----------------------- WGL_EXT_extensions_string ----------------------- */ + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 + +typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); + +#define wglGetExtensionsStringEXT WGLEW_GET_FUN(__wglewGetExtensionsStringEXT) + +#define WGLEW_EXT_extensions_string WGLEW_GET_VAR(__WGLEW_EXT_extensions_string) + +#endif /* WGL_EXT_extensions_string */ + +/* ------------------------ WGL_EXT_framebuffer_sRGB ----------------------- */ + +#ifndef WGL_EXT_framebuffer_sRGB +#define WGL_EXT_framebuffer_sRGB 1 + +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 + +#define WGLEW_EXT_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_EXT_framebuffer_sRGB) + +#endif /* WGL_EXT_framebuffer_sRGB */ + +/* ----------------------- WGL_EXT_make_current_read ----------------------- */ + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 + +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + +#define wglGetCurrentReadDCEXT WGLEW_GET_FUN(__wglewGetCurrentReadDCEXT) +#define wglMakeContextCurrentEXT WGLEW_GET_FUN(__wglewMakeContextCurrentEXT) + +#define WGLEW_EXT_make_current_read WGLEW_GET_VAR(__WGLEW_EXT_make_current_read) + +#endif /* WGL_EXT_make_current_read */ + +/* -------------------------- WGL_EXT_multisample -------------------------- */ + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 + +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 + +#define WGLEW_EXT_multisample WGLEW_GET_VAR(__WGLEW_EXT_multisample) + +#endif /* WGL_EXT_multisample */ + +/* ---------------------------- WGL_EXT_pbuffer ---------------------------- */ + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 + +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 + +DECLARE_HANDLE(HPBUFFEREXT); + +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int* piValue); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); + +#define wglCreatePbufferEXT WGLEW_GET_FUN(__wglewCreatePbufferEXT) +#define wglDestroyPbufferEXT WGLEW_GET_FUN(__wglewDestroyPbufferEXT) +#define wglGetPbufferDCEXT WGLEW_GET_FUN(__wglewGetPbufferDCEXT) +#define wglQueryPbufferEXT WGLEW_GET_FUN(__wglewQueryPbufferEXT) +#define wglReleasePbufferDCEXT WGLEW_GET_FUN(__wglewReleasePbufferDCEXT) + +#define WGLEW_EXT_pbuffer WGLEW_GET_VAR(__WGLEW_EXT_pbuffer) + +#endif /* WGL_EXT_pbuffer */ + +/* -------------------------- WGL_EXT_pixel_format ------------------------- */ + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 + +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C + +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues); + +#define wglChoosePixelFormatEXT WGLEW_GET_FUN(__wglewChoosePixelFormatEXT) +#define wglGetPixelFormatAttribfvEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvEXT) +#define wglGetPixelFormatAttribivEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribivEXT) + +#define WGLEW_EXT_pixel_format WGLEW_GET_VAR(__WGLEW_EXT_pixel_format) + +#endif /* WGL_EXT_pixel_format */ + +/* ------------------- WGL_EXT_pixel_format_packed_float ------------------- */ + +#ifndef WGL_EXT_pixel_format_packed_float +#define WGL_EXT_pixel_format_packed_float 1 + +#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 + +#define WGLEW_EXT_pixel_format_packed_float WGLEW_GET_VAR(__WGLEW_EXT_pixel_format_packed_float) + +#endif /* WGL_EXT_pixel_format_packed_float */ + +/* -------------------------- WGL_EXT_swap_control ------------------------- */ + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 + +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); + +#define wglGetSwapIntervalEXT WGLEW_GET_FUN(__wglewGetSwapIntervalEXT) +#define wglSwapIntervalEXT WGLEW_GET_FUN(__wglewSwapIntervalEXT) + +#define WGLEW_EXT_swap_control WGLEW_GET_VAR(__WGLEW_EXT_swap_control) + +#endif /* WGL_EXT_swap_control */ + +/* --------------------- WGL_I3D_digital_video_control --------------------- */ + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control 1 + +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 + +typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); +typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); + +#define wglGetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewGetDigitalVideoParametersI3D) +#define wglSetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewSetDigitalVideoParametersI3D) + +#define WGLEW_I3D_digital_video_control WGLEW_GET_VAR(__WGLEW_I3D_digital_video_control) + +#endif /* WGL_I3D_digital_video_control */ + +/* ----------------------------- WGL_I3D_gamma ----------------------------- */ + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma 1 + +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F + +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT* puRed, USHORT *puGreen, USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT* puRed, const USHORT *puGreen, const USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); + +#define wglGetGammaTableI3D WGLEW_GET_FUN(__wglewGetGammaTableI3D) +#define wglGetGammaTableParametersI3D WGLEW_GET_FUN(__wglewGetGammaTableParametersI3D) +#define wglSetGammaTableI3D WGLEW_GET_FUN(__wglewSetGammaTableI3D) +#define wglSetGammaTableParametersI3D WGLEW_GET_FUN(__wglewSetGammaTableParametersI3D) + +#define WGLEW_I3D_gamma WGLEW_GET_VAR(__WGLEW_I3D_gamma) + +#endif /* WGL_I3D_gamma */ + +/* ---------------------------- WGL_I3D_genlock ---------------------------- */ + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock 1 + +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C + +typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT* uRate); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT* uDelay); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT* uEdge); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT* uSource); +typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL* pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT* uMaxLineDelay, UINT *uMaxPixelDelay); + +#define wglDisableGenlockI3D WGLEW_GET_FUN(__wglewDisableGenlockI3D) +#define wglEnableGenlockI3D WGLEW_GET_FUN(__wglewEnableGenlockI3D) +#define wglGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGenlockSampleRateI3D) +#define wglGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGenlockSourceDelayI3D) +#define wglGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGenlockSourceEdgeI3D) +#define wglGenlockSourceI3D WGLEW_GET_FUN(__wglewGenlockSourceI3D) +#define wglGetGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGetGenlockSampleRateI3D) +#define wglGetGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGetGenlockSourceDelayI3D) +#define wglGetGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGetGenlockSourceEdgeI3D) +#define wglGetGenlockSourceI3D WGLEW_GET_FUN(__wglewGetGenlockSourceI3D) +#define wglIsEnabledGenlockI3D WGLEW_GET_FUN(__wglewIsEnabledGenlockI3D) +#define wglQueryGenlockMaxSourceDelayI3D WGLEW_GET_FUN(__wglewQueryGenlockMaxSourceDelayI3D) + +#define WGLEW_I3D_genlock WGLEW_GET_VAR(__WGLEW_I3D_genlock) + +#endif /* WGL_I3D_genlock */ + +/* -------------------------- WGL_I3D_image_buffer ------------------------- */ + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer 1 + +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 + +typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, HANDLE* pEvent, LPVOID *pAddress, DWORD *pSize, UINT count); +typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); +typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); +typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, LPVOID* pAddress, UINT count); + +#define wglAssociateImageBufferEventsI3D WGLEW_GET_FUN(__wglewAssociateImageBufferEventsI3D) +#define wglCreateImageBufferI3D WGLEW_GET_FUN(__wglewCreateImageBufferI3D) +#define wglDestroyImageBufferI3D WGLEW_GET_FUN(__wglewDestroyImageBufferI3D) +#define wglReleaseImageBufferEventsI3D WGLEW_GET_FUN(__wglewReleaseImageBufferEventsI3D) + +#define WGLEW_I3D_image_buffer WGLEW_GET_VAR(__WGLEW_I3D_image_buffer) + +#endif /* WGL_I3D_image_buffer */ + +/* ------------------------ WGL_I3D_swap_frame_lock ------------------------ */ + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 + +typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL* pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL* pFlag); + +#define wglDisableFrameLockI3D WGLEW_GET_FUN(__wglewDisableFrameLockI3D) +#define wglEnableFrameLockI3D WGLEW_GET_FUN(__wglewEnableFrameLockI3D) +#define wglIsEnabledFrameLockI3D WGLEW_GET_FUN(__wglewIsEnabledFrameLockI3D) +#define wglQueryFrameLockMasterI3D WGLEW_GET_FUN(__wglewQueryFrameLockMasterI3D) + +#define WGLEW_I3D_swap_frame_lock WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_lock) + +#endif /* WGL_I3D_swap_frame_lock */ + +/* ------------------------ WGL_I3D_swap_frame_usage ----------------------- */ + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 + +typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float* pUsage); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD* pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); + +#define wglBeginFrameTrackingI3D WGLEW_GET_FUN(__wglewBeginFrameTrackingI3D) +#define wglEndFrameTrackingI3D WGLEW_GET_FUN(__wglewEndFrameTrackingI3D) +#define wglGetFrameUsageI3D WGLEW_GET_FUN(__wglewGetFrameUsageI3D) +#define wglQueryFrameTrackingI3D WGLEW_GET_FUN(__wglewQueryFrameTrackingI3D) + +#define WGLEW_I3D_swap_frame_usage WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_usage) + +#endif /* WGL_I3D_swap_frame_usage */ + +/* -------------------------- WGL_NV_float_buffer -------------------------- */ + +#ifndef WGL_NV_float_buffer +#define WGL_NV_float_buffer 1 + +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 + +#define WGLEW_NV_float_buffer WGLEW_GET_VAR(__WGLEW_NV_float_buffer) + +#endif /* WGL_NV_float_buffer */ + +/* ---------------------- WGL_NV_render_depth_texture ---------------------- */ + +#ifndef WGL_NV_render_depth_texture +#define WGL_NV_render_depth_texture 1 + +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 + +#define WGLEW_NV_render_depth_texture WGLEW_GET_VAR(__WGLEW_NV_render_depth_texture) + +#endif /* WGL_NV_render_depth_texture */ + +/* -------------------- WGL_NV_render_texture_rectangle -------------------- */ + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_NV_render_texture_rectangle 1 + +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 + +#define WGLEW_NV_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_NV_render_texture_rectangle) + +#endif /* WGL_NV_render_texture_rectangle */ + +/* ----------------------- WGL_NV_vertex_array_range ----------------------- */ + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 + +typedef void * (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); +typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); + +#define wglAllocateMemoryNV WGLEW_GET_FUN(__wglewAllocateMemoryNV) +#define wglFreeMemoryNV WGLEW_GET_FUN(__wglewFreeMemoryNV) + +#define WGLEW_NV_vertex_array_range WGLEW_GET_VAR(__WGLEW_NV_vertex_array_range) + +#endif /* WGL_NV_vertex_array_range */ + +/* -------------------------- WGL_OML_sync_control ------------------------- */ + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 + +typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32* numerator, INT32 *denominator); +typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64* ust, INT64 *msc, INT64 *sbc); +typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, INT fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64* ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64* ust, INT64 *msc, INT64 *sbc); + +#define wglGetMscRateOML WGLEW_GET_FUN(__wglewGetMscRateOML) +#define wglGetSyncValuesOML WGLEW_GET_FUN(__wglewGetSyncValuesOML) +#define wglSwapBuffersMscOML WGLEW_GET_FUN(__wglewSwapBuffersMscOML) +#define wglSwapLayerBuffersMscOML WGLEW_GET_FUN(__wglewSwapLayerBuffersMscOML) +#define wglWaitForMscOML WGLEW_GET_FUN(__wglewWaitForMscOML) +#define wglWaitForSbcOML WGLEW_GET_FUN(__wglewWaitForSbcOML) + +#define WGLEW_OML_sync_control WGLEW_GET_VAR(__WGLEW_OML_sync_control) + +#endif /* WGL_OML_sync_control */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX +#define WGLEW_EXPORT +#else +#define WGLEW_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#ifdef GLEW_MX +struct WGLEWContextStruct +{ +#endif /* GLEW_MX */ + +WGLEW_EXPORT PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL; + +WGLEW_EXPORT PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB; +WGLEW_EXPORT PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB; +WGLEW_EXPORT PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB; +WGLEW_EXPORT PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB; + +WGLEW_EXPORT PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB; + +WGLEW_EXPORT PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB; +WGLEW_EXPORT PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB; + +WGLEW_EXPORT PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB; +WGLEW_EXPORT PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB; +WGLEW_EXPORT PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB; +WGLEW_EXPORT PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB; +WGLEW_EXPORT PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB; + +WGLEW_EXPORT PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB; + +WGLEW_EXPORT PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB; +WGLEW_EXPORT PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB; +WGLEW_EXPORT PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB; + +WGLEW_EXPORT PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT; + +WGLEW_EXPORT PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT; + +WGLEW_EXPORT PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT; +WGLEW_EXPORT PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT; + +WGLEW_EXPORT PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT; +WGLEW_EXPORT PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT; +WGLEW_EXPORT PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT; +WGLEW_EXPORT PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT; +WGLEW_EXPORT PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT; + +WGLEW_EXPORT PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT; + +WGLEW_EXPORT PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT; +WGLEW_EXPORT PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT; + +WGLEW_EXPORT PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D; +WGLEW_EXPORT PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D; + +WGLEW_EXPORT PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D; +WGLEW_EXPORT PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D; +WGLEW_EXPORT PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D; +WGLEW_EXPORT PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D; + +WGLEW_EXPORT PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D; +WGLEW_EXPORT PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D; +WGLEW_EXPORT PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D; +WGLEW_EXPORT PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D; +WGLEW_EXPORT PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D; + +WGLEW_EXPORT PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D; +WGLEW_EXPORT PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D; +WGLEW_EXPORT PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D; +WGLEW_EXPORT PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D; + +WGLEW_EXPORT PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D; +WGLEW_EXPORT PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D; +WGLEW_EXPORT PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D; +WGLEW_EXPORT PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D; + +WGLEW_EXPORT PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D; +WGLEW_EXPORT PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D; +WGLEW_EXPORT PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D; +WGLEW_EXPORT PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D; + +WGLEW_EXPORT PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV; +WGLEW_EXPORT PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV; + +WGLEW_EXPORT PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML; +WGLEW_EXPORT PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML; +WGLEW_EXPORT PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML; +WGLEW_EXPORT PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML; +WGLEW_EXPORT PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML; +WGLEW_EXPORT PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML; +WGLEW_EXPORT GLboolean __WGLEW_3DFX_multisample; +WGLEW_EXPORT GLboolean __WGLEW_3DL_stereo_control; +WGLEW_EXPORT GLboolean __WGLEW_ARB_buffer_region; +WGLEW_EXPORT GLboolean __WGLEW_ARB_extensions_string; +WGLEW_EXPORT GLboolean __WGLEW_ARB_make_current_read; +WGLEW_EXPORT GLboolean __WGLEW_ARB_multisample; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pbuffer; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pixel_format; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pixel_format_float; +WGLEW_EXPORT GLboolean __WGLEW_ARB_render_texture; +WGLEW_EXPORT GLboolean __WGLEW_ATI_pixel_format_float; +WGLEW_EXPORT GLboolean __WGLEW_ATI_render_texture_rectangle; +WGLEW_EXPORT GLboolean __WGLEW_EXT_depth_float; +WGLEW_EXPORT GLboolean __WGLEW_EXT_display_color_table; +WGLEW_EXPORT GLboolean __WGLEW_EXT_extensions_string; +WGLEW_EXPORT GLboolean __WGLEW_EXT_framebuffer_sRGB; +WGLEW_EXPORT GLboolean __WGLEW_EXT_make_current_read; +WGLEW_EXPORT GLboolean __WGLEW_EXT_multisample; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pbuffer; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pixel_format; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pixel_format_packed_float; +WGLEW_EXPORT GLboolean __WGLEW_EXT_swap_control; +WGLEW_EXPORT GLboolean __WGLEW_I3D_digital_video_control; +WGLEW_EXPORT GLboolean __WGLEW_I3D_gamma; +WGLEW_EXPORT GLboolean __WGLEW_I3D_genlock; +WGLEW_EXPORT GLboolean __WGLEW_I3D_image_buffer; +WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_lock; +WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_usage; +WGLEW_EXPORT GLboolean __WGLEW_NV_float_buffer; +WGLEW_EXPORT GLboolean __WGLEW_NV_render_depth_texture; +WGLEW_EXPORT GLboolean __WGLEW_NV_render_texture_rectangle; +WGLEW_EXPORT GLboolean __WGLEW_NV_vertex_array_range; +WGLEW_EXPORT GLboolean __WGLEW_OML_sync_control; + +#ifdef GLEW_MX +}; /* WGLEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX + +typedef struct WGLEWContextStruct WGLEWContext; +GLEWAPI GLenum wglewContextInit (WGLEWContext* ctx); +GLEWAPI GLboolean wglewContextIsSupported (WGLEWContext* ctx, const char* name); + +#define wglewInit() wglewContextInit(wglewGetContext()) +#define wglewIsSupported(x) wglewContextIsSupported(wglewGetContext(), x) + +#define WGLEW_GET_VAR(x) wglewGetContext()->x +#define WGLEW_GET_FUN(x) wglewGetContext()->x + +#else /* GLEW_MX */ + +#define WGLEW_GET_VAR(x) x +#define WGLEW_GET_FUN(x) x + +GLEWAPI GLboolean wglewIsSupported (const char* name); + +#endif /* GLEW_MX */ + +GLEWAPI GLboolean wglewGetExtension (const char* name); + +#ifdef __cplusplus +} +#endif + +#undef GLEWAPI + +#endif /* __wglew_h__ */ diff --git a/external/cutil/inc/GL/wglext.h b/external/cutil/inc/GL/wglext.h new file mode 100644 index 0000000..bfc9751 --- /dev/null +++ b/external/cutil/inc/GL/wglext.h @@ -0,0 +1,695 @@ +#ifndef __wglext_h_ +#define __wglext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + + +/*************************************************************/ + +/* Header file version number */ +/* wglext.h last updated 2005/01/07 */ +/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ +#define WGL_WGLEXT_VERSION 6 + +#ifndef WGL_ARB_buffer_region +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 +#endif + +#ifndef WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +#ifndef WGL_ARB_extensions_string +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#endif + +#ifndef WGL_ARB_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 +#endif + +#ifndef WGL_ARB_pixel_format_float +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 +#endif + +#ifndef WGL_EXT_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 +#endif + +#ifndef WGL_EXT_depth_float +#define WGL_DEPTH_FLOAT_EXT 0x2040 +#endif + +#ifndef WGL_3DFX_multisample +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 +#endif + +#ifndef WGL_EXT_multisample +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 +#endif + +#ifndef WGL_I3D_digital_video_control +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 +#endif + +#ifndef WGL_I3D_gamma +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F +#endif + +#ifndef WGL_I3D_genlock +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C +#endif + +#ifndef WGL_I3D_image_buffer +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 +#endif + +#ifndef WGL_I3D_swap_frame_lock +#endif + +#ifndef WGL_NV_render_depth_texture +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 +#endif + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 +#endif + +#ifndef WGL_ATI_pixel_format_float +#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 +#define WGL_RGBA_FLOAT_MODE_ATI 0x8820 +#define WGL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 +#endif + +#ifndef WGL_NV_float_buffer +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 +#endif + +#ifndef WGL_NV_swap_group +#endif + +#ifndef WGL_NV_gpu_affinity +#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 +#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 +#endif + + +/*************************************************************/ + +#ifndef WGL_ARB_pbuffer +DECLARE_HANDLE(HPBUFFERARB); +#endif +#ifndef WGL_EXT_pbuffer +DECLARE_HANDLE(HPBUFFEREXT); +#endif + +#ifndef WGL_NV_gpu_affinity +DECLARE_HANDLE(HGPUNV); +typedef struct _GPU_DEVICE { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD Flags; + RECT rcVirtualScreen; +} GPU_DEVICE, *PGPU_DEVICE; +#endif + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HANDLE WINAPI wglCreateBufferRegionARB (HDC, int, UINT); +extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE); +extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE, int, int, int, int); +extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE, int, int, int, int, int, int); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); +typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +#endif + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 +#endif + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern const char * WINAPI wglGetExtensionsStringARB (HDC); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *); +extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC, int, int, UINT, const int *, FLOAT *); +extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglMakeContextCurrentARB (HDC, HDC, HGLRC); +extern HDC WINAPI wglGetCurrentReadDCARB (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC, int, int, int, const int *); +extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB); +extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB, HDC); +extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB); +extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB, int, int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB, int); +extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB, int); +extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB, const int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); +#endif + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float 1 +#endif + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort); +extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *, GLuint); +extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort); +extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +#endif + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern const char * WINAPI wglGetExtensionsStringEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); +#endif + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglMakeContextCurrentEXT (HDC, HDC, HGLRC); +extern HDC WINAPI wglGetCurrentReadDCEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC, int, int, int, const int *); +extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT); +extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT, HDC); +extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT); +extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT, int, int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC, int, int, UINT, int *, int *); +extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC, int, int, UINT, int *, FLOAT *); +extern BOOL WINAPI wglChoosePixelFormatEXT (HDC, const int *, const FLOAT *, UINT, int *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglSwapIntervalEXT (int); +extern int WINAPI wglGetSwapIntervalEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +#endif + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 +#endif + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern void* WINAPI wglAllocateMemoryNV (GLsizei, GLfloat, GLfloat, GLfloat); +extern void WINAPI wglFreeMemoryNV (void *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); +typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); +#endif + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 +#endif + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 +#endif + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetSyncValuesOML (HDC, INT64 *, INT64 *, INT64 *); +extern BOOL WINAPI wglGetMscRateOML (HDC, INT32 *, INT32 *); +extern INT64 WINAPI wglSwapBuffersMscOML (HDC, INT64, INT64, INT64); +extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC, int, INT64, INT64, INT64); +extern BOOL WINAPI wglWaitForMscOML (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *); +extern BOOL WINAPI wglWaitForSbcOML (HDC, INT64, INT64 *, INT64 *, INT64 *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); +typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); +#endif + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC, int, int *); +extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC, int, const int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +#endif + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC, int, int *); +extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC, int, const int *); +extern BOOL WINAPI wglGetGammaTableI3D (HDC, int, USHORT *, USHORT *, USHORT *); +extern BOOL WINAPI wglSetGammaTableI3D (HDC, int, const USHORT *, const USHORT *, const USHORT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); +#endif + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglEnableGenlockI3D (HDC); +extern BOOL WINAPI wglDisableGenlockI3D (HDC); +extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC, BOOL *); +extern BOOL WINAPI wglGenlockSourceI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSampleRateI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC, UINT *); +extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC, UINT *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); +typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); +typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); +#endif + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern LPVOID WINAPI wglCreateImageBufferI3D (HDC, DWORD, UINT); +extern BOOL WINAPI wglDestroyImageBufferI3D (HDC, LPVOID); +extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT); +extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC, const LPVOID *, UINT); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); +typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); +typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); +typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); +#endif + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglEnableFrameLockI3D (void); +extern BOOL WINAPI wglDisableFrameLockI3D (void); +extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *); +extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); +#endif + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetFrameUsageI3D (float *); +extern BOOL WINAPI wglBeginFrameTrackingI3D (void); +extern BOOL WINAPI wglEndFrameTrackingI3D (void); +extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *, DWORD *, float *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); +typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); +#endif + +#ifndef WGL_ATI_pixel_format_float +#define WGL_ATI_pixel_format_float 1 +#endif + +#ifndef WGL_NV_render_depth_texture +#define WGL_NV_render_depth_texture 1 +#endif + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_NV_render_texture_rectangle 1 +#endif + +#ifndef WGL_NV_float_buffer +#define WGL_NV_float_buffer 1 +#endif + +#ifndef WGL_NV_swap_group +#define WGL_NV_swap_group 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglJoinSwapGroupNV(HDC hDC, GLuint group); +extern BOOL WINAPI wglBindSwapBarrierNV(GLuint group, GLuint barrier); +extern BOOL WINAPI wglQuerySwapGroupNV(HDC hDC, GLuint *group, GLuint *barrier); +extern BOOL WINAPI wglQueryMaxSwapGroupsNV(HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); +extern BOOL WINAPI wglQueryFrameCountNV(HDC hDC, GLuint *count); +extern BOOL WINAPI wglResetFrameCountNV(HDC hDC); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); +typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); +typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier); +typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count); +typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); +#endif + +#ifndef WGL_NV_gpu_affinity +#define WGL_NV_gpu_affinity 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglEnumGpusNV (UINT iIndex, HGPUNV *hGpu); +extern BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iIndex, PGPU_DEVICE pGpuDevice); +extern HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *pGpuList); +extern BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iIndex, HGPUNV *hGpu); +extern BOOL WINAPI wglDeleteDCNV (HDC hAffinityDC); +#else +typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iIndex, HGPUNV *hGpu); +typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iIndex, PGPU_DEVICE pGpuDevice); +typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *pGpuList); +typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iIndex, HGPUNV *hGpu); +typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hAffinityDC); +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/cutil/inc/bank_checker.h b/external/cutil/inc/bank_checker.h new file mode 100644 index 0000000..7e75bb6 --- /dev/null +++ b/external/cutil/inc/bank_checker.h @@ -0,0 +1,462 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +/* Helper to check for bank conflicts */ + +#ifndef _BANK_CHECKER_H_ +#define _BANK_CHECKER_H_ + +// includes, system +#include +#include +#include +#include +#include + +//! Helper class to check for bank conflicts +class BankChecker +{ + + //! singleton, handle to the instance + static BankChecker bank_checker; + +public: + + //! Get a handle to the instance of this class + static BankChecker* const getHandle(); + + //! Destructor + ~BankChecker(); + +private: + + //! Constructor + BankChecker(); + +public: + + //! Side effect of shared memory access + //! @param tidx thread id in x dimension of block + //! @param tidy thread id in y dimension of block + //! @param tidz thread id in z dimension of block + //! @param bdimx block size in x dimension + //! @param bdimy block size in y dimension + //! @param bdimz block size in z dimension + //! @param file name of the source file where the access takes place + //! @param line line in the source file where the access takes place + //! @param aname name of the array which is accessed + //! @param index index into the array + void access( unsigned int tidx, unsigned int tidy, unsigned int tidz, + unsigned int bdimx, unsigned int bdimy, unsigned int bdimz, + const char* file, const int line, const std::string& aname, + const int index); + +private: + + ////////////////////////////////////////////////////////////////////////////// + //! Uniquely defined access location + ///////////////////////////////////////////////////////////////////////////// + class AccessLocation { + + friend class BankChecker; + + //! type for hash value based on file + line + num_access + typedef std::string KeyType; + + public: + + //! Constructor, default + inline AccessLocation(); + + //! Constructor + //! @param file file where the shared memory access takes place + //! @param line line in \a file where the shared memory access takes place + //! @param array_name name of the array which is accessed + //! @param ltid linearized thread id + inline AccessLocation( const std::string& file, const unsigned int line, + const std::string& array_name, + const unsigned int ltid ); + + //! Constructor, copy + inline AccessLocation( const AccessLocation&); + + //! Assignment operator + inline AccessLocation& operator=( const AccessLocation&); + + //! Destructor + ~AccessLocation(); + + public: + + //! Get the hash key for the access based on file + line + num_access, + //! i.e. identical accesses result in identical hash values + inline const KeyType& getKey() const; + + public: + + // operators, overloaded + + //! Equality + inline bool operator==( const AccessLocation& other) const; + + public: + + //! Get the name of the file of the access + const std::string& getFile() const + { + return file; + } + + //! Get the line of the access in \a file + const unsigned int& getLine() const + { + return line; + } + + //! Get the number of the access in \a line + const unsigned int& getNumAccessLine() const + { + return num_access_line; + } + + private: + + // member variables + + //! file where shared mem is acccessed + std::string file; + + //! line where shared mem is accessed + unsigned int line; + + //! number of access within line + unsigned int num_access_line; + + //! name of the array which is accessed + std::string array_name; + + //! pre-computed key value + KeyType key; + + // invalid flag for data field + static const unsigned int invalid; + + private: + + // Counter for line accesses in a specific file + // @key file + line of access + // @value number of access in \a values::key + typedef std::map LineAccessCounter; + + //! Tracker for number of accesses per file and line for each thread + //! The access number with the file+line uniquely identifies a specific + //! shared memory access + //! Note: The access number itself would not be sufficient because there + //! might be branches in the code so that a specific access is only + //! by a subset of threads of a warp. + //! @key ltid (linearized thread id) + //! @value line accesses in a specific file + static std::map< unsigned int, LineAccessCounter > thread_access; + + }; + + ////////////////////////////////////////////////////////////////////////////// + //! Comparator for AccessLocation + ////////////////////////////////////////////////////////////////////////////// + struct AccessLocationComparator { + + //! Compare operator for std container + inline bool + operator()( const AccessLocation& lhs, const AccessLocation& rhs) const; + }; + +private: + + ////////////////////////////////////////////////////////////////////////////// + //! Meta information about an access + ////////////////////////////////////////////////////////////////////////////// + class AccessInfo { + + friend class BankChecker; + + public: + + //! Constructor, default + inline AccessInfo(); + + //! Constructor, default + //! @param l linearized thread id + //! @param x thread id in x dimension + //! @param y thread id in y dimension + //! @param z thread id in z dimension + //! @param i index used to access shared memory + inline AccessInfo( const unsigned int l, + const unsigned int x, + const unsigned int y, + const unsigned int z, + const unsigned int i ); + + // Constructor, copy + inline AccessInfo( const AccessInfo& other); + + // Assignment operator + inline AccessInfo& operator=( const AccessInfo& other); + + // Destructor + ~AccessInfo(); + + public: + + //! Provide infos as string + const std::string getInfo() const; + const unsigned int getIndex() const; + private: + + //! linearized thread id + unsigned int ltid; + + // thread id in the three dimensions + unsigned int tidx; + unsigned int tidy; + unsigned int tidz; + + // index used to access shared memory + unsigned int index; + + // invalid flag for data field + static const unsigned int invalid; + + }; + + private: + + // data members + + // list of access information + typedef std::vector AccessInfoList; + typedef AccessInfoList::iterator AccessInfoListIter; + typedef AccessInfoList::const_iterator AccessInfoListCIter; + + // information about the access to a specific location + // @key index index of array access + // @value infos about threads which tried to access the threads + typedef std::map< unsigned int, AccessInfoList > IndexAInfoList; + typedef IndexAInfoList::iterator IndexAInfoListIter; + typedef IndexAInfoList::const_iterator IndexAInfoListCIter; + + typedef std::map< AccessLocation, + IndexAInfoList, + AccessLocationComparator > AccessData; + typedef AccessData::iterator AccessDataIter; + typedef AccessData::const_iterator AccessDataCIter; + + //! Tracker for shared memory accesses + AccessData access_data; + + //! Linearized thread id of last thread processed + unsigned int last_ltid; + + //! Total number of bank conflicts + unsigned int total_num_conflicts; + + // flag if bank checker is used + bool is_active; + +private: + + // private helper functions + + //! Get the linearized thread id for a thread + //! @return linear thread id + //! @param tidx thread id in x dimension of block + //! @param tidy thread id in y dimension of block + //! @param tidz thread id in z dimension of block + //! @param bdimx block size in x dimension + //! @param bdimy block size in y dimension + //! @param bdimz block size in z dimension + unsigned int + getLtid( unsigned int tidx, unsigned int tidy, unsigned int tidz, + unsigned int bdimx, unsigned int bdimy, unsigned int bdimz ); + + //! Reset all internal state for a new warp + void reset(); + + //! Analyse the accesses by one warp + void analyse( const AccessDataCIter& iter_loc); + +public: + + // constants + + // size of warp + static const unsigned int warp_size = 16; + +}; + +// functions, inlined + +//////////////////////////////////////////////////////////////////////////////// +// BankChecker::AccessLocation + +//////////////////////////////////////////////////////////////////////////////// +//! Constructor, standard +//! @param file file where the shared memory access takes place +//! @param line line in \a file where the shared memory access takes place +//! @param array_name name of the array which is accessed +//! @param ltid linearized thread id +//////////////////////////////////////////////////////////////////////////////// +BankChecker::AccessLocation:: +AccessLocation( const std::string& f, const unsigned int l, + const std::string& aname, + const unsigned int ltid ) : + file( f), + line( l), + num_access_line( 0), + array_name( aname) +{ + std::ostringstream oss; + oss << file << "l" << line; + + const std::string sstr = oss.str(); + // check if this (file + line) has already been accessed by this thread + if( thread_access[ltid].end() == thread_access[ltid].find( sstr)) { + thread_access[ltid][oss.str()] = 0; + } + else { + thread_access[ltid][oss.str()]++; + } + + // number of access in this line by thread ltid + num_access_line = thread_access[ltid][oss.str()]; + + // generate key + oss << "c" << num_access_line; + key = oss.str(); +} + +//////////////////////////////////////////////////////////////////////////////// +//! Constructor, copy +//////////////////////////////////////////////////////////////////////////////// +BankChecker::AccessLocation:: +AccessLocation( const AccessLocation& other) : + file( other.file), + line( other.line), + num_access_line( other.num_access_line), + array_name( other.array_name), + key( other.key) +{ } + +//////////////////////////////////////////////////////////////////////////////// +//! Assignment operator +//////////////////////////////////////////////////////////////////////////////// +BankChecker::AccessLocation& BankChecker::AccessLocation:: +operator=( const AccessLocation& other) +{ + + if( this != &other) { + + file = other.file; + line = other.line; + array_name = other.array_name; + num_access_line = other.num_access_line; + } + + return *this; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Equality +//////////////////////////////////////////////////////////////////////////////// +bool BankChecker::AccessLocation:: +operator==( const AccessLocation& other) const +{ + + return ( (file == other.file) + && (line == other.line) + && (num_access_line == other.num_access_line)) ? true : false; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Get the hash key for the access based on file + line + num_access, +//! i.e. identical accesses result in identical hash values +//! @return the key value +//////////////////////////////////////////////////////////////////////////////// +const BankChecker::AccessLocation::KeyType& BankChecker::AccessLocation:: +getKey() const { + + return key; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Compare operator for std container +//////////////////////////////////////////////////////////////////////////////// +inline bool +BankChecker::AccessLocationComparator::operator()( const AccessLocation& lhs, + const AccessLocation& rhs) const { + return (lhs.getKey() < rhs.getKey()); +} + +//////////////////////////////////////////////////////////////////////////////// +// BankChecker::AccessInfo + +//////////////////////////////////////////////////////////////////////////////// +//! Constructor, default +//! @param l linearized thread id +//! @param x thread id in x dimension +//! @param y thread id in y dimension +//! @param z thread id in z dimension +//////////////////////////////////////////////////////////////////////////////// +BankChecker::AccessInfo:: +AccessInfo( const unsigned int l, + const unsigned int x, + const unsigned int y, + const unsigned int z, + const unsigned int i ) : + ltid( l), + tidx( x), + tidy( y), + tidz( z), + index( i) +{ } + +//////////////////////////////////////////////////////////////////////////////// +// Constructor, copy +//////////////////////////////////////////////////////////////////////////////// +BankChecker::AccessInfo:: +AccessInfo( const AccessInfo& other) : + ltid( other.ltid), + tidx( other.tidx), + tidy( other.tidy), + tidz( other.tidz), + index( other.index) +{ } + +//////////////////////////////////////////////////////////////////////////////// +// Assignment operator +//////////////////////////////////////////////////////////////////////////////// +BankChecker::AccessInfo& BankChecker::AccessInfo:: +operator=( const AccessInfo& other) +{ + + if( this != &other) + { + + ltid = other.ltid; + tidx = other.tidx; + tidy = other.tidy; + tidz = other.tidz; + index = other.index; + } + + return *this; +} + +#endif // #ifdef _BANK_CHECKER_H_ diff --git a/external/cutil/inc/cmd_arg_reader.h b/external/cutil/inc/cmd_arg_reader.h new file mode 100644 index 0000000..4ed1ba5 --- /dev/null +++ b/external/cutil/inc/cmd_arg_reader.h @@ -0,0 +1,500 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + /* +* Copyright 1993-2010 NVIDIA Corporation. All rights reserved. +* +* Please refer to the NVIDIA end user license agreement (EULA) associated +* with this source code for terms and conditions that govern your use of +* this software. Any use, reproduction, disclosure, or distribution of +* this software and related documentation outside the terms of the EULA +* is strictly prohibited. +* +*/ + +/* CUda UTility Library */ + +#ifndef _CMDARGREADER_H_ +#define _CMDARGREADER_H_ + +// includes, system +#include +#include +#include +#include +#include + +// includes, project +#include + +//! Preprocessed command line arguments +//! @note Lazy evaluation: The arguments are converted from strings to +//! the correct data type upon request. Converted values are stored +//! in an additonal map so that no additional conversion is +//! necessary. Arrays of command line arguments are stored in +//! std::vectors +//! @note Usage: +//! const std::string* file = +//! CmdArgReader::getArg< std::string>( "model") +//! const std::vector< std::string>* files = +//! CmdArgReader::getArg< std::vector< std::string> >( "model") +//! @note All command line arguments begin with '--' followed by the token; +//! token and value are seperated by '='; example --samples=50 +//! @note Arrays have the form --model=[one.obj,two.obj,three.obj] +//! (without whitespaces) + +//! Command line argument parser +class CmdArgReader +{ + template friend class TestCmdArgReader; + +protected: + + //! @param self handle to the only instance of this class + static CmdArgReader* self; + +public: + + //! Public construction interface + //! @return a handle to the class instance + //! @param argc number of command line arguments (as given to main()) + //! @param argv command line argument string (as given to main()) + static void init( const int argc, const char** argv); + +public: + + //! Get the value of the command line argument with given name + //! @return A const handle to the requested argument. + //! If the argument does not exist or if it + //! is not from type T NULL is returned + //! @param name the name of the requested argument + //! @note T the type of the argument requested + template + static inline const T* getArg( const std::string& name); + + //! Check if a command line argument with the given name exists + //! @return true if a command line argument with name \a name exists, + //! otherwise false + //! @param name name of the command line argument in question + static inline bool existArg( const std::string& name); + + //! Get the original / raw argc program argument + static inline int& getRArgc(); + + //! Get the original / raw argv program argument + static inline char**& getRArgv(); + +public: + + //! Destructor + ~CmdArgReader(); + +protected: + + //! Constructor, default + CmdArgReader(); + +private: + + // private helper functions + + //! Get the value of the command line argument with given name + //! @note Private helper function for 'getArg' to work on the members + //! @return A const handle to the requested argument. If the argument + //! does not exist or if it is not from type T a NULL pointer + //! is returned. + //! @param name the name of the requested argument + //! @note T the type of the argument requested + template + inline const T* getArgHelper( const std::string& name); + + //! Check if a command line argument with name \a name exists + //! @return true if a command line argument of name \a name exists, + //! otherwise false + //! @param name the name of the requested argument + inline bool existArgHelper( const std::string& name) const; + + //! Read args as token value pair into map for better processing + //! (Even the values remain strings until the parameter values is + //! requested by the program.) + //! @param argc the argument count (as given to 'main') + //! @param argv the char* array containing the command line arguments + void createArgsMaps( const int argc, const char** argv); + + //! Helper for "casting" the strings from the map with the unprocessed + //! values to the correct + //! data type. + //! @return true if conversion succeeded, otherwise false + //! @param element the value as string + //! @param val the value as type T + template + static inline bool convertToT( const std::string& element, T& val); + +public: + + // typedefs internal + + //! container for a processed command line argument + //! typeid is used to easily be able to decide if a re-requested token-value + //! pair match the type of the first conversion + typedef std::pair< const std::type_info*, void*> ValType; + //! map of already converted values + typedef std::map< std::string, ValType > ArgsMap; + //! iterator for the map of already converted values + typedef ArgsMap::iterator ArgsMapIter; + typedef ArgsMap::const_iterator ConstArgsMapIter; + + //! map of unprocessed (means unconverted) token-value pairs + typedef std::map< std::string, std::string> UnpMap; + //! iterator for the map of unprocessed (means unconverted) token-value pairs + typedef std::map< std::string, std::string>::iterator UnpMapIter; + +private: + +#ifdef _WIN32 +# pragma warning( disable: 4251) +#endif + + //! rargc original value of argc + static int rargc; + + //! rargv contains command line arguments in raw format + static char** rargv; + + //! args Map containing the already converted token-value pairs + ArgsMap args; + + //! args Map containing the unprocessed / unconverted token-value pairs + UnpMap unprocessed; + + //! iter Iterator for the map with the already converted token-value + //! pairs (to avoid frequent reallocation) + ArgsMapIter iter; + + //! iter Iterator for the map with the unconverted token-value + //! pairs (to avoid frequent reallocation) + UnpMapIter iter_unprocessed; + +#ifdef _WIN32 +# pragma warning( default: 4251) +#endif + +private: + + //! Constructor, copy (not implemented) + CmdArgReader( const CmdArgReader&); + + //! Assignment operator (not implemented) + CmdArgReader& operator=( const CmdArgReader&); +}; + +// variables, exported (extern) + +// functions, inlined (inline) + +//////////////////////////////////////////////////////////////////////////////// +//! Conversion function for command line argument arrays +//! @note This function is used each type for which no template specialization +//! exist (which will cause errors if the type does not fulfill the std::vector +//! interface). +//////////////////////////////////////////////////////////////////////////////// +template +/*static*/ inline bool +CmdArgReader::convertToT( const std::string& element, T& val) +{ + // preallocate storage + val.resize( std::count( element.begin(), element.end(), ',') + 1); + + unsigned int i = 0; + std::string::size_type pos_start = 1; // leave array prefix '[' + std::string::size_type pos_end = 0; + + // do for all elements of the comma seperated list + while( std::string::npos != ( pos_end = element.find(',', pos_end+1)) ) + { + // convert each element by the appropriate function + if ( ! convertToT< typename T::value_type >( + std::string( element, pos_start, pos_end - pos_start), val[i])) + { + return false; + } + + pos_start = pos_end + 1; + ++i; + } + + std::string tmp1( element, pos_start, element.length() - pos_start - 1); + + // process last element (leave array postfix ']') + if ( ! convertToT< typename T::value_type >( std::string( element, + pos_start, + element.length() - pos_start - 1), + val[i])) + { + return false; + } + + // possible to process all elements? + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Conversion function for command line arguments of type int +//////////////////////////////////////////////////////////////////////////////// +template<> +inline bool +CmdArgReader::convertToT( const std::string& element, int& val) +{ + std::istringstream ios( element); + ios >> val; + + bool ret_val = false; + if ( ios.eof()) + { + ret_val = true; + } + + return ret_val; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Conversion function for command line arguments of type float +//////////////////////////////////////////////////////////////////////////////// +template<> +inline bool +CmdArgReader::convertToT( const std::string& element, float& val) +{ + std::istringstream ios( element); + ios >> val; + + bool ret_val = false; + if ( ios.eof()) + { + ret_val = true; + } + + return ret_val; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Conversion function for command line arguments of type double +//////////////////////////////////////////////////////////////////////////////// +template<> +inline bool +CmdArgReader::convertToT( const std::string& element, double& val) +{ + std::istringstream ios( element); + ios >> val; + + bool ret_val = false; + if ( ios.eof()) + { + ret_val = true; + } + + return ret_val; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Conversion function for command line arguments of type string +//////////////////////////////////////////////////////////////////////////////// +template<> +inline bool +CmdArgReader::convertToT( const std::string& element, + std::string& val) +{ + val = element; + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Conversion function for command line arguments of type bool +//////////////////////////////////////////////////////////////////////////////// +template<> +inline bool +CmdArgReader::convertToT( const std::string& element, bool& val) +{ + // check if value is given as string-type { true | false } + if ( "true" == element) + { + val = true; + return true; + } + else if ( "false" == element) + { + val = false; + return true; + } + // check if argument is given as integer { 0 | 1 } + else + { + int tmp; + if ( convertToT( element, tmp)) + { + if ( 1 == tmp) + { + val = true; + return true; + } + else if ( 0 == tmp) + { + val = false; + return true; + } + } + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Get the value of the command line argument with given name +//! @return A const handle to the requested argument. If the argument does +//! not exist or if it is not from type T NULL is returned +//! @param T the type of the argument requested +//! @param name the name of the requested argument +//////////////////////////////////////////////////////////////////////////////// +template +/*static*/ const T* +CmdArgReader::getArg( const std::string& name) +{ + if( ! self) + { + RUNTIME_EXCEPTION("CmdArgReader::getArg(): CmdArgReader not initialized."); + return NULL; + } + + return self->getArgHelper( name); +} + +//////////////////////////////////////////////////////////////////////////////// +//! Check if a command line argument with the given name exists +//! @return true if a command line argument with name \a name exists, +//! otherwise false +//! @param name name of the command line argument in question +//////////////////////////////////////////////////////////////////////////////// +/*static*/ inline bool +CmdArgReader::existArg( const std::string& name) +{ + if( ! self) + { + RUNTIME_EXCEPTION("CmdArgReader::getArg(): CmdArgReader not initialized."); + return false; + } + + return self->existArgHelper( name); +} + +//////////////////////////////////////////////////////////////////////////////// +//! @brief Get the value of the command line argument with given name +//! @return A const handle to the requested argument. If the argument does +//! not exist or if it is not from type T NULL is returned +//! @param T the type of the argument requested +//! @param name the name of the requested argument +//////////////////////////////////////////////////////////////////////////////// +template +const T* +CmdArgReader::getArgHelper( const std::string& name) +{ + // check if argument already processed and stored in correct type + if ( args.end() != (iter = args.find( name))) + { + if ( (*(iter->second.first)) == typeid( T) ) + { + return (T*) iter->second.second; + } + } + else + { + T* tmp = new T; + + // check the array with unprocessed values + if ( unprocessed.end() != (iter_unprocessed = unprocessed.find( name))) + { + // try to "cast" the string to the type requested + if ( convertToT< T >( iter_unprocessed->second, *tmp)) + { + // add the token element pair to map of already converted values + args[name] = std::make_pair( &(typeid( T)), (void*) tmp); + + return tmp; + } + } + + // not used while not inserted into the map -> cleanup + delete tmp; + } + + // failed, argument not available + return NULL; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Check if a command line argument with name \a name exists +//! @return true if a command line argument of name \a name exists, +//! otherwise false +//! @param name the name of the requested argument +//////////////////////////////////////////////////////////////////////////////// +inline bool +CmdArgReader::existArgHelper( const std::string& name) const +{ + bool ret_val = false; + + // check if argument already processed and stored in correct type + if( args.end() != args.find( name)) + { + ret_val = true; + } + else + { + + // check the array with unprocessed values + if ( unprocessed.end() != unprocessed.find( name)) + { + ret_val = true; + } + } + + return ret_val; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Get the original / raw argc program argument +//////////////////////////////////////////////////////////////////////////////// +/*static*/ inline int& +CmdArgReader::getRArgc() +{ + if( ! self) + { + RUNTIME_EXCEPTION("CmdArgReader::getRArgc(): CmdArgReader not initialized."); + } + + return rargc; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Get the original / raw argv program argument +//////////////////////////////////////////////////////////////////////////////// +/*static*/ inline char**& +CmdArgReader::getRArgv() +{ + if( ! self) + { + RUNTIME_EXCEPTION("CmdArgReader::getRArgc(): CmdArgReader not initialized."); + } + + return rargv; +} + +// functions, exported (extern) + +#endif // #ifndef _CMDARGREADER_H_ + diff --git a/external/cutil/inc/cuda_drvapi_dynlink.c b/external/cutil/inc/cuda_drvapi_dynlink.c new file mode 100644 index 0000000..dc1a0de --- /dev/null +++ b/external/cutil/inc/cuda_drvapi_dynlink.c @@ -0,0 +1,539 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * NVIDIA Corporation and its licensors retain all intellectual property and + * proprietary rights in and to this software and related documentation. + * Any use, reproduction, disclosure, or distribution of this software + * and related documentation without an express license agreement from + * NVIDIA Corporation is strictly prohibited. + * + * Please refer to the applicable NVIDIA end user license agreement (EULA) + * associated with this source code for terms and conditions that govern + * your use of this NVIDIA software. + * + */ + +// With these flags defined, this source file will dynamically +// load the corresponding functions. Disabled by default. +//#define CUDA_INIT_D3D9 +//#define CUDA_INIT_D3D10 +//#define CUDA_INIT_D3D11 +//#define CUDA_INIT_OPENGL + +#include +#include "cuda_drvapi_dynlink.h" + +tcuInit *_cuInit; +tcuDriverGetVersion *cuDriverGetVersion; +tcuDeviceGet *cuDeviceGet; +tcuDeviceGetCount *cuDeviceGetCount; +tcuDeviceGetName *cuDeviceGetName; +tcuDeviceComputeCapability *cuDeviceComputeCapability; +tcuDeviceTotalMem *cuDeviceTotalMem; +tcuDeviceGetProperties *cuDeviceGetProperties; +tcuDeviceGetAttribute *cuDeviceGetAttribute; +tcuCtxCreate *cuCtxCreate; +tcuCtxDestroy *cuCtxDestroy; +tcuCtxAttach *cuCtxAttach; +tcuCtxDetach *cuCtxDetach; +tcuCtxPushCurrent *cuCtxPushCurrent; +tcuCtxPopCurrent *cuCtxPopCurrent; +tcuCtxGetCurrent *cuCtxGetCurrent; +tcuCtxSetCurrent *cuCtxSetCurrent; +tcuCtxGetDevice *cuCtxGetDevice; +tcuCtxSynchronize *cuCtxSynchronize; +tcuModuleLoad *cuModuleLoad; +tcuModuleLoadData *cuModuleLoadData; +tcuModuleLoadDataEx *cuModuleLoadDataEx; +tcuModuleLoadFatBinary *cuModuleLoadFatBinary; +tcuModuleUnload *cuModuleUnload; +tcuModuleGetFunction *cuModuleGetFunction; +tcuModuleGetGlobal *cuModuleGetGlobal; +tcuModuleGetTexRef *cuModuleGetTexRef; +tcuModuleGetSurfRef *cuModuleGetSurfRef; +tcuMemGetInfo *cuMemGetInfo; +tcuMemAlloc *cuMemAlloc; +tcuMemAllocPitch *cuMemAllocPitch; +tcuMemFree *cuMemFree; +tcuMemGetAddressRange *cuMemGetAddressRange; +tcuMemAllocHost *cuMemAllocHost; +tcuMemFreeHost *cuMemFreeHost; +tcuMemHostAlloc *cuMemHostAlloc; +tcuMemHostGetDevicePointer *cuMemHostGetDevicePointer; +tcuMemHostRegister *cuMemHostRegister; +tcuMemHostUnregister *cuMemHostUnregister; +tcuMemcpyHtoD *cuMemcpyHtoD; +tcuMemcpyDtoH *cuMemcpyDtoH; +tcuMemcpyDtoD *cuMemcpyDtoD; +tcuMemcpyDtoA *cuMemcpyDtoA; +tcuMemcpyAtoD *cuMemcpyAtoD; +tcuMemcpyHtoA *cuMemcpyHtoA; +tcuMemcpyAtoH *cuMemcpyAtoH; +tcuMemcpyAtoA *cuMemcpyAtoA; +tcuMemcpy2D *cuMemcpy2D; +tcuMemcpy2DUnaligned *cuMemcpy2DUnaligned; +tcuMemcpy3D *cuMemcpy3D; +tcuMemcpyHtoDAsync *cuMemcpyHtoDAsync; +tcuMemcpyDtoHAsync *cuMemcpyDtoHAsync; +tcuMemcpyDtoDAsync *cuMemcpyDtoDAsync; +tcuMemcpyHtoAAsync *cuMemcpyHtoAAsync; +tcuMemcpyAtoHAsync *cuMemcpyAtoHAsync; +tcuMemcpy2DAsync *cuMemcpy2DAsync; +tcuMemcpy3DAsync *cuMemcpy3DAsync; +tcuMemcpy *cuMemcpy; +tcuMemcpyPeer *cuMemcpyPeer; +tcuMemsetD8 *cuMemsetD8; +tcuMemsetD16 *cuMemsetD16; +tcuMemsetD32 *cuMemsetD32; +tcuMemsetD2D8 *cuMemsetD2D8; +tcuMemsetD2D16 *cuMemsetD2D16; +tcuMemsetD2D32 *cuMemsetD2D32; +tcuFuncSetBlockShape *cuFuncSetBlockShape; +tcuFuncSetSharedSize *cuFuncSetSharedSize; +tcuFuncGetAttribute *cuFuncGetAttribute; +tcuFuncSetCacheConfig *cuFuncSetCacheConfig; +tcuLaunchKernel *cuLaunchKernel; +tcuArrayCreate *cuArrayCreate; +tcuArrayGetDescriptor *cuArrayGetDescriptor; +tcuArrayDestroy *cuArrayDestroy; +tcuArray3DCreate *cuArray3DCreate; +tcuArray3DGetDescriptor *cuArray3DGetDescriptor; +tcuTexRefCreate *cuTexRefCreate; +tcuTexRefDestroy *cuTexRefDestroy; +tcuTexRefSetArray *cuTexRefSetArray; +tcuTexRefSetAddress *cuTexRefSetAddress; +tcuTexRefSetAddress2D *cuTexRefSetAddress2D; +tcuTexRefSetFormat *cuTexRefSetFormat; +tcuTexRefSetAddressMode *cuTexRefSetAddressMode; +tcuTexRefSetFilterMode *cuTexRefSetFilterMode; +tcuTexRefSetFlags *cuTexRefSetFlags; +tcuTexRefGetAddress *cuTexRefGetAddress; +tcuTexRefGetArray *cuTexRefGetArray; +tcuTexRefGetAddressMode *cuTexRefGetAddressMode; +tcuTexRefGetFilterMode *cuTexRefGetFilterMode; +tcuTexRefGetFormat *cuTexRefGetFormat; +tcuTexRefGetFlags *cuTexRefGetFlags; +tcuSurfRefSetArray *cuSurfRefSetArray; +tcuSurfRefGetArray *cuSurfRefGetArray; +tcuParamSetSize *cuParamSetSize; +tcuParamSeti *cuParamSeti; +tcuParamSetf *cuParamSetf; +tcuParamSetv *cuParamSetv; +tcuParamSetTexRef *cuParamSetTexRef; +tcuLaunch *cuLaunch; +tcuLaunchGrid *cuLaunchGrid; +tcuLaunchGridAsync *cuLaunchGridAsync; +tcuEventCreate *cuEventCreate; +tcuEventRecord *cuEventRecord; +tcuEventQuery *cuEventQuery; +tcuEventSynchronize *cuEventSynchronize; +tcuEventDestroy *cuEventDestroy; +tcuEventElapsedTime *cuEventElapsedTime; +tcuStreamCreate *cuStreamCreate; +tcuStreamQuery *cuStreamQuery; +tcuStreamSynchronize *cuStreamSynchronize; +tcuStreamDestroy *cuStreamDestroy; +tcuGraphicsUnregisterResource *cuGraphicsUnregisterResource; +tcuGraphicsSubResourceGetMappedArray *cuGraphicsSubResourceGetMappedArray; +tcuGraphicsResourceGetMappedPointer *cuGraphicsResourceGetMappedPointer; +tcuGraphicsResourceSetMapFlags *cuGraphicsResourceSetMapFlags; +tcuGraphicsMapResources *cuGraphicsMapResources; +tcuGraphicsUnmapResources *cuGraphicsUnmapResources; +tcuGetExportTable *cuGetExportTable; +tcuCtxSetLimit *cuCtxSetLimit; +tcuCtxGetLimit *cuCtxGetLimit; +tcuMemHostGetFlags *cuMemHostGetFlags; + +#ifdef CUDA_INIT_D3D9 +// D3D9/CUDA interop (CUDA 1.x compatible API). These functions +// are deprecated; please use the ones below +tcuD3D9Begin *cuD3D9Begin; +tcuD3D9End *cuD3DEnd; +tcuD3D9RegisterVertexBuffer *cuD3D9RegisterVertexBuffer; +tcuD3D9MapVertexBuffer *cuD3D9MapVertexBuffer; +tcuD3D9UnmapVertexBuffer *cuD3D9UnmapVertexBuffer; +tcuD3D9UnregisterVertexBuffer *cuD3D9UnregisterVertexBuffer; + +// D3D9/CUDA interop (CUDA 2.x compatible) +tcuD3D9GetDirect3DDevice *cuD3D9GetDirect3DDevice; +tcuD3D9RegisterResource *cuD3D9RegisterResource; +tcuD3D9UnregisterResource *cuD3D9UnregisterResource; +tcuD3D9MapResources *cuD3D9MapResources; +tcuD3D9UnmapResources *cuD3D9UnmapResources; +tcuD3D9ResourceSetMapFlags *cuD3D9ResourceSetMapFlags; +tcuD3D9ResourceGetSurfaceDimensions *cuD3D9ResourceGetSurfaceDimensions; +tcuD3D9ResourceGetMappedArray *cuD3D9ResourceGetMappedArray; +tcuD3D9ResourceGetMappedPointer *cuD3D9ResourceGetMappedPointer; +tcuD3D9ResourceGetMappedSize *cuD3D9ResourceGetMappedSize; +tcuD3D9ResourceGetMappedPitch *cuD3D9ResourceGetMappedPitch; + +// D3D9/CUDA interop (CUDA 2.0+) +tcuD3D9GetDevice *cuD3D9GetDevice; +tcuD3D9CtxCreate *cuD3D9CtxCreate; +tcuGraphicsD3D9RegisterResource *cuGraphicsD3D9RegisterResource; +#endif + +#ifdef CUDA_INIT_D3D10 +// D3D10/CUDA interop (CUDA 3.0+) +tcuD3D10GetDevice *cuD3D10GetDevice; +tcuD3D10CtxCreate *cuD3D10CtxCreate; +tcuGraphicsD3D10RegisterResource *cuGraphicsD3D10RegisterResource; +#endif + + +#ifdef CUDA_INIT_D3D11 +// D3D11/CUDA interop (CUDA 3.0+) +tcuD3D11GetDevice *cuD3D11GetDevice; +tcuD3D11CtxCreate *cuD3D11CtxCreate; +tcuGraphicsD3D11RegisterResource *cuGraphicsD3D11RegisterResource; +#endif + +// GL/CUDA interop +#ifdef CUDA_INIT_OPENGL +tcuGLCtxCreate *cuGLCtxCreate; +tcuGraphicsGLRegisterBuffer *cuGraphicsGLRegisterBuffer; +tcuGraphicsGLRegisterImage *cuGraphicsGLRegisterImage; +#ifdef _WIN32 +tcuWGLGetDevice *cuWGLGetDevice; +#endif +#endif + +#define STRINGIFY(X) #X + +#ifdef _WIN32 + #include + + #ifdef UNICODE + static LPCWSTR __CudaLibName = L"nvcuda.dll"; + #else + static LPCSTR __CudaLibName = "nvcuda.dll"; + #endif + + typedef HMODULE CUDADRIVER; + + static CUresult LOAD_LIBRARY(CUDADRIVER *pInstance) + { + *pInstance = LoadLibrary(__CudaLibName); + if (*pInstance == NULL) + { + printf("LoadLibrary \"%s\" failed!\n", __CudaLibName); + return CUDA_ERROR_UNKNOWN; + } + return CUDA_SUCCESS; + } + + #define GET_PROC_EX(name, alias, required) \ + alias = (t##name *)GetProcAddress(CudaDrvLib, #name); \ + if (alias == NULL && required) { \ + printf("Failed to find required function \"%s\" in %s\n", \ + #name, __CudaLibName); \ + return CUDA_ERROR_UNKNOWN; \ + } + + #define GET_PROC_EX_V2(name, alias, required) \ + alias = (t##name *)GetProcAddress(CudaDrvLib, STRINGIFY(name##_v2));\ + if (alias == NULL && required) { \ + printf("Failed to find required function \"%s\" in %s\n", \ + STRINGIFY(name##_v2), __CudaLibName); \ + return CUDA_ERROR_UNKNOWN; \ + } + +#elif defined(__unix__) || defined(__APPLE__) || defined(__MACOSX) + + #include + + #if defined(__APPLE__) || defined(__MACOSX) + static char __CudaLibName[] = "/usr/local/cuda/lib/libcuda.dylib"; + #else + static char __CudaLibName[] = "libcuda.so"; + #endif + + typedef void * CUDADRIVER; + + static CUresult LOAD_LIBRARY(CUDADRIVER *pInstance) + { + *pInstance = dlopen(__CudaLibName, RTLD_NOW); + if (*pInstance == NULL) + { + printf("dlopen \"%s\" failed!\n", __CudaLibName); + return CUDA_ERROR_UNKNOWN; + } + return CUDA_SUCCESS; + } + + #define GET_PROC_EX(name, alias, required) \ + alias = (t##name *)dlsym(CudaDrvLib, #name); \ + if (alias == NULL && required) { \ + printf("Failed to find required function \"%s\" in %s\n", \ + #name, __CudaLibName); \ + return CUDA_ERROR_UNKNOWN; \ + } + + #define GET_PROC_EX_V2(name, alias, required) \ + alias = (t##name *)dlsym(CudaDrvLib, STRINGIFY(name##_v2)); \ + if (alias == NULL && required) { \ + printf("Failed to find required function \"%s\" in %s\n", \ + STRINGIFY(name##_v2), __CudaLibName); \ + return CUDA_ERROR_UNKNOWN; \ + } + +#else +#error unsupported platform +#endif + +#define CHECKED_CALL(call) \ + do { \ + CUresult result = (call); \ + if (CUDA_SUCCESS != result) { \ + return result; \ + } \ + } while(0) + +#define GET_PROC_REQUIRED(name) GET_PROC_EX(name,name,1) +#define GET_PROC_OPTIONAL(name) GET_PROC_EX(name,name,0) +#define GET_PROC(name) GET_PROC_REQUIRED(name) +#define GET_PROC_V2(name) GET_PROC_EX_V2(name,name,1) + +CUresult CUDAAPI cuInit(unsigned int Flags, int cudaVersion) +{ + CUDADRIVER CudaDrvLib; + int driverVer = 1000; + + CHECKED_CALL(LOAD_LIBRARY(&CudaDrvLib)); + + // cuInit is required; alias it to _cuInit + GET_PROC_EX(cuInit, _cuInit, 1); + CHECKED_CALL(_cuInit(Flags)); + + // available since 2.2. if not present, version 1.0 is assumed + GET_PROC_OPTIONAL(cuDriverGetVersion); + if (cuDriverGetVersion) { + CHECKED_CALL(cuDriverGetVersion(&driverVer)); + } + + // fetch all function pointers + GET_PROC(cuDeviceGet); + GET_PROC(cuDeviceGetCount); + GET_PROC(cuDeviceGetName); + GET_PROC(cuDeviceComputeCapability); + GET_PROC(cuDeviceGetProperties); + GET_PROC(cuDeviceGetAttribute); + GET_PROC(cuCtxDestroy); + GET_PROC(cuCtxAttach); + GET_PROC(cuCtxDetach); + GET_PROC(cuCtxPushCurrent); + GET_PROC(cuCtxPopCurrent); + GET_PROC(cuCtxGetDevice); + GET_PROC(cuCtxSynchronize); + GET_PROC(cuModuleLoad); + GET_PROC(cuModuleLoadData); + GET_PROC(cuModuleUnload); + GET_PROC(cuModuleGetFunction); + GET_PROC(cuModuleGetTexRef); + GET_PROC(cuMemFreeHost); + GET_PROC(cuMemHostAlloc); + GET_PROC(cuFuncSetBlockShape); + GET_PROC(cuFuncSetSharedSize); + GET_PROC(cuFuncGetAttribute); + GET_PROC(cuArrayDestroy); + GET_PROC(cuTexRefCreate); + GET_PROC(cuTexRefDestroy); + GET_PROC(cuTexRefSetArray); + GET_PROC(cuTexRefSetFormat); + GET_PROC(cuTexRefSetAddressMode); + GET_PROC(cuTexRefSetFilterMode); + GET_PROC(cuTexRefSetFlags); + GET_PROC(cuTexRefGetArray); + GET_PROC(cuTexRefGetAddressMode); + GET_PROC(cuTexRefGetFilterMode); + GET_PROC(cuTexRefGetFormat); + GET_PROC(cuTexRefGetFlags); + GET_PROC(cuParamSetSize); + GET_PROC(cuParamSeti); + GET_PROC(cuParamSetf); + GET_PROC(cuParamSetv); + GET_PROC(cuParamSetTexRef); + GET_PROC(cuLaunch); + GET_PROC(cuLaunchGrid); + GET_PROC(cuLaunchGridAsync); + GET_PROC(cuEventCreate); + GET_PROC(cuEventRecord); + GET_PROC(cuEventQuery); + GET_PROC(cuEventSynchronize); + GET_PROC(cuEventDestroy); + GET_PROC(cuEventElapsedTime); + GET_PROC(cuStreamCreate); + GET_PROC(cuStreamQuery); + GET_PROC(cuStreamSynchronize); + GET_PROC(cuStreamDestroy); + + // These could be _v2 interfaces + if (cudaVersion >= 4000 && __CUDA_API_VERSION >= 4000) + { + GET_PROC_V2(cuCtxDestroy); + GET_PROC_V2(cuCtxPopCurrent); + GET_PROC_V2(cuCtxPushCurrent); + GET_PROC_V2(cuStreamDestroy); + GET_PROC_V2(cuEventDestroy); + } + + if (cudaVersion >= 3020 && __CUDA_API_VERSION >= 3020) + { + GET_PROC_V2(cuDeviceTotalMem); + GET_PROC_V2(cuCtxCreate); + GET_PROC_V2(cuModuleGetGlobal); + GET_PROC_V2(cuMemGetInfo); + GET_PROC_V2(cuMemAlloc); + GET_PROC_V2(cuMemAllocPitch); + GET_PROC_V2(cuMemFree); + GET_PROC_V2(cuMemGetAddressRange); + GET_PROC_V2(cuMemAllocHost); + GET_PROC_V2(cuMemHostGetDevicePointer); + GET_PROC_V2(cuMemcpyHtoD); + GET_PROC_V2(cuMemcpyDtoH); + GET_PROC_V2(cuMemcpyDtoD); + GET_PROC_V2(cuMemcpyDtoA); + GET_PROC_V2(cuMemcpyAtoD); + GET_PROC_V2(cuMemcpyHtoA); + GET_PROC_V2(cuMemcpyAtoH); + GET_PROC_V2(cuMemcpyAtoA); + GET_PROC_V2(cuMemcpy2D); + GET_PROC_V2(cuMemcpy2DUnaligned); + GET_PROC_V2(cuMemcpy3D); + GET_PROC_V2(cuMemcpyHtoDAsync); + GET_PROC_V2(cuMemcpyDtoHAsync); + GET_PROC_V2(cuMemcpyHtoAAsync); + GET_PROC_V2(cuMemcpyAtoHAsync); + GET_PROC_V2(cuMemcpy2DAsync); + GET_PROC_V2(cuMemcpy3DAsync); + GET_PROC_V2(cuMemsetD8); + GET_PROC_V2(cuMemsetD16); + GET_PROC_V2(cuMemsetD32); + GET_PROC_V2(cuMemsetD2D8); + GET_PROC_V2(cuMemsetD2D16); + GET_PROC_V2(cuMemsetD2D32); + GET_PROC_V2(cuArrayCreate); + GET_PROC_V2(cuArrayGetDescriptor); + GET_PROC_V2(cuArray3DCreate); + GET_PROC_V2(cuArray3DGetDescriptor); + GET_PROC_V2(cuTexRefSetAddress); + GET_PROC_V2(cuTexRefSetAddress2D); + GET_PROC_V2(cuTexRefGetAddress); + } else { + GET_PROC(cuDeviceTotalMem); + GET_PROC(cuCtxCreate); + GET_PROC(cuModuleGetGlobal); + GET_PROC(cuMemGetInfo); + GET_PROC(cuMemAlloc); + GET_PROC(cuMemAllocPitch); + GET_PROC(cuMemFree); + GET_PROC(cuMemGetAddressRange); + GET_PROC(cuMemAllocHost); + GET_PROC(cuMemHostGetDevicePointer); + GET_PROC(cuMemcpyHtoD); + GET_PROC(cuMemcpyDtoH); + GET_PROC(cuMemcpyDtoD); + GET_PROC(cuMemcpyDtoA); + GET_PROC(cuMemcpyAtoD); + GET_PROC(cuMemcpyHtoA); + GET_PROC(cuMemcpyAtoH); + GET_PROC(cuMemcpyAtoA); + GET_PROC(cuMemcpy2D); + GET_PROC(cuMemcpy2DUnaligned); + GET_PROC(cuMemcpy3D); + GET_PROC(cuMemcpyHtoDAsync); + GET_PROC(cuMemcpyDtoHAsync); + GET_PROC(cuMemcpyHtoAAsync); + GET_PROC(cuMemcpyAtoHAsync); + GET_PROC(cuMemcpy2DAsync); + GET_PROC(cuMemcpy3DAsync); + GET_PROC(cuMemsetD8); + GET_PROC(cuMemsetD16); + GET_PROC(cuMemsetD32); + GET_PROC(cuMemsetD2D8); + GET_PROC(cuMemsetD2D16); + GET_PROC(cuMemsetD2D32); + GET_PROC(cuArrayCreate); + GET_PROC(cuArrayGetDescriptor); + GET_PROC(cuArray3DCreate); + GET_PROC(cuArray3DGetDescriptor); + GET_PROC(cuTexRefSetAddress); + GET_PROC(cuTexRefSetAddress2D); + GET_PROC(cuTexRefGetAddress); + } + + // The following functions are specific to CUDA versions + if (driverVer >= 2010) { + GET_PROC(cuModuleLoadDataEx); + GET_PROC(cuModuleLoadFatBinary); + #ifdef CUDA_INIT_OPENGL + GET_PROC(cuGLCtxCreate); + GET_PROC(cuGraphicsGLRegisterBuffer); + GET_PROC(cuGraphicsGLRegisterImage); + # ifdef _WIN32 + GET_PROC(cuWGLGetDevice); + # endif + #endif + #ifdef CUDA_INIT_D3D9 + GET_PROC(cuD3D9GetDevice); + GET_PROC(cuD3D9CtxCreate); + GET_PROC(cuGraphicsD3D9RegisterResource); + #endif + } + + if (driverVer >= 2030) { + GET_PROC(cuMemHostGetFlags); + #ifdef CUDA_INIT_D3D10 + GET_PROC(cuD3D10GetDevice); + GET_PROC(cuD3D10CtxCreate); + GET_PROC(cuGraphicsD3D10RegisterResource); + #endif + #ifdef CUDA_INIT_OPENGL + GET_PROC(cuGraphicsGLRegisterBuffer); + GET_PROC(cuGraphicsGLRegisterImage); + #endif + } + + if (driverVer >= 3000) { + GET_PROC(cuMemcpyDtoDAsync); + GET_PROC(cuFuncSetCacheConfig); + #ifdef CUDA_INIT_D3D11 + GET_PROC(cuD3D11GetDevice); + GET_PROC(cuD3D11CtxCreate); + GET_PROC(cuGraphicsD3D11RegisterResource); + #endif + GET_PROC(cuGraphicsUnregisterResource); + GET_PROC(cuGraphicsSubResourceGetMappedArray); + + if (cudaVersion >= 3020 && __CUDA_API_VERSION >= 3020) { + GET_PROC_V2(cuGraphicsResourceGetMappedPointer); + } else { + GET_PROC(cuGraphicsResourceGetMappedPointer); + } + + GET_PROC(cuGraphicsResourceSetMapFlags); + GET_PROC(cuGraphicsMapResources); + GET_PROC(cuGraphicsUnmapResources); + GET_PROC(cuGetExportTable); + } + + if (driverVer >= 3010) { + GET_PROC(cuModuleGetSurfRef); + GET_PROC(cuSurfRefSetArray); + GET_PROC(cuSurfRefGetArray); + GET_PROC(cuCtxSetLimit); + GET_PROC(cuCtxGetLimit); + } + + if (driverVer >= 4000) { + GET_PROC(cuCtxSetCurrent); + GET_PROC(cuCtxGetCurrent); + GET_PROC(cuMemHostRegister); + GET_PROC(cuMemHostUnregister); + GET_PROC(cuMemcpy); + GET_PROC(cuMemcpyPeer); + GET_PROC(cuLaunchKernel); + } + + return CUDA_SUCCESS; +} diff --git a/external/cutil/inc/cutil.h b/external/cutil/inc/cutil.h new file mode 100644 index 0000000..831cabf --- /dev/null +++ b/external/cutil/inc/cutil.h @@ -0,0 +1,929 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + /* +* Copyright 1993-2010 NVIDIA Corporation. All rights reserved. +* +* Please refer to the NVIDIA end user license agreement (EULA) associated +* with this source code for terms and conditions that govern your use of +* this software. Any use, reproduction, disclosure, or distribution of +* this software and related documentation outside the terms of the EULA +* is strictly prohibited. +* +*/ + + +/* CUda UTility Library */ + +#ifndef _CUTIL_H_ +#define _CUTIL_H_ + +#ifdef _WIN32 +# pragma warning( disable : 4996 ) // disable deprecated warning +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + // helper typedefs for building DLL +#ifdef _WIN32 +# ifdef BUILD_DLL +# define DLL_MAPPING __declspec(dllexport) +# else +# define DLL_MAPPING __declspec(dllimport) +# endif +#else +# define DLL_MAPPING +#endif + +#ifdef _WIN32 + #define CUTIL_API __stdcall +#else + #define CUTIL_API +#endif + + //////////////////////////////////////////////////////////////////////////// + //! CUT bool type + //////////////////////////////////////////////////////////////////////////// + enum CUTBoolean + { + CUTFalse = 0, + CUTTrue = 1 + }; + + //////////////////////////////////////////////////////////////////////////// + //! Deallocate memory allocated within Cutil + //! @param pointer to memory + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + void CUTIL_API + cutFree( void* ptr); + + //////////////////////////////////////////////////////////////////////////// + //! Helper for bank conflict checking (should only be used with the + //! CUT_BANK_CHECKER macro) + //! @param tidx thread id in x dimension of block + //! @param tidy thread id in y dimension of block + //! @param tidz thread id in z dimension of block + //! @param bdimx block size in x dimension + //! @param bdimy block size in y dimension + //! @param bdimz block size in z dimension + //! @param file name of the source file where the access takes place + //! @param line line in the source file where the access takes place + //! @param aname name of the array which is accessed + //! @param index index into the array + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + void CUTIL_API + cutCheckBankAccess( unsigned int tidx, unsigned int tidy, unsigned int tidz, + unsigned int bdimx, unsigned int bdimy, + unsigned int bdimz, const char* file, const int line, + const char* aname, const int index); + + //////////////////////////////////////////////////////////////////////////// + //! Find the path for a filename + //! @return the path if succeeded, otherwise 0 + //! @param filename name of the file + //! @param executablePath optional absolute path of the executable + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + char* CUTIL_API + cutFindFilePath(const char* filename, const char* executablePath); + + //////////////////////////////////////////////////////////////////////////// + //! Read file \filename containing single precision floating point data + //! @return CUTTrue if reading the file succeeded, otherwise false + //! @param filename name of the source file + //! @param data uninitialized pointer, returned initialized and pointing to + //! the data read + //! @param len number of data elements in data, -1 on error + //! @note If a NULL pointer is passed to this function and it is + //! initialized within Cutil then cutFree() has to be used to + //! deallocate the memory + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutReadFilef( const char* filename, float** data, unsigned int* len, + bool verbose = false); + + //////////////////////////////////////////////////////////////////////////// + //! Read file \filename containing double precision floating point data + //! @return CUTTrue if reading the file succeeded, otherwise false + //! @param filename name of the source file + //! @param data uninitialized pointer, returned initialized and pointing to + //! the data read + //! @param len number of data elements in data, -1 on error + //! @note If a NULL pointer is passed to this function and it is + //! initialized within Cutil then cutFree() has to be used to + //! deallocate the memory + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutReadFiled( const char* filename, double** data, unsigned int* len, + bool verbose = false); + + //////////////////////////////////////////////////////////////////////////// + //! Read file \filename containing integer data + //! @return CUTTrue if reading the file succeeded, otherwise false + //! @param filename name of the source file + //! @param data uninitialized pointer, returned initialized and pointing to + //! the data read + //! @param len number of data elements in data, -1 on error + //! @note If a NULL pointer is passed to this function and it is + //! initialized within Cutil then cutFree() has to be used to + //! deallocate the memory + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutReadFilei( const char* filename, int** data, unsigned int* len, bool verbose = false); + + //////////////////////////////////////////////////////////////////////////// + //! Read file \filename containing unsigned integer data + //! @return CUTTrue if reading the file succeeded, otherwise false + //! @param filename name of the source file + //! @param data uninitialized pointer, returned initialized and pointing to + //! the data read + //! @param len number of data elements in data, -1 on error + //! @note If a NULL pointer is passed to this function and it is + //! initialized within Cutil then cutFree() has to be used to + //! deallocate the memory + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutReadFileui( const char* filename, unsigned int** data, + unsigned int* len, bool verbose = false); + + //////////////////////////////////////////////////////////////////////////// + //! Read file \filename containing char / byte data + //! @return CUTTrue if reading the file succeeded, otherwise false + //! @param filename name of the source file + //! @param data uninitialized pointer, returned initialized and pointing to + //! the data read + //! @param len number of data elements in data, -1 on error + //! @note If a NULL pointer is passed to this function and it is + //! initialized within Cutil then cutFree() has to be used to + //! deallocate the memory + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutReadFileb( const char* filename, char** data, unsigned int* len, + bool verbose = false); + + //////////////////////////////////////////////////////////////////////////// + //! Read file \filename containing unsigned char / byte data + //! @return CUTTrue if reading the file succeeded, otherwise false + //! @param filename name of the source file + //! @param data uninitialized pointer, returned initialized and pointing to + //! the data read + //! @param len number of data elements in data, -1 on error + //! @note If a NULL pointer is passed to this function and it is + //! initialized within Cutil then cutFree() has to be used to + //! deallocate the memory + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutReadFileub( const char* filename, unsigned char** data, + unsigned int* len, bool verbose = false); + + //////////////////////////////////////////////////////////////////////////// + //! Write a data file \filename containing single precision floating point + //! data + //! @return CUTTrue if writing the file succeeded, otherwise false + //! @param filename name of the file to write + //! @param data pointer to data to write + //! @param len number of data elements in data, -1 on error + //! @param epsilon epsilon for comparison + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutWriteFilef( const char* filename, const float* data, unsigned int len, + const float epsilon, bool verbose = false); + + //////////////////////////////////////////////////////////////////////////// + //! Write a data file \filename containing double precision floating point + //! data + //! @return CUTTrue if writing the file succeeded, otherwise false + //! @param filename name of the file to write + //! @param data pointer to data to write + //! @param len number of data elements in data, -1 on error + //! @param epsilon epsilon for comparison + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutWriteFiled( const char* filename, const float* data, unsigned int len, + const double epsilon, bool verbose = false); + + //////////////////////////////////////////////////////////////////////////// + //! Write a data file \filename containing integer data + //! @return CUTTrue if writing the file succeeded, otherwise false + //! @param filename name of the file to write + //! @param data pointer to data to write + //! @param len number of data elements in data, -1 on error + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutWriteFilei( const char* filename, const int* data, unsigned int len, + bool verbose = false); + + //////////////////////////////////////////////////////////////////////////// + //! Write a data file \filename containing unsigned integer data + //! @return CUTTrue if writing the file succeeded, otherwise false + //! @param filename name of the file to write + //! @param data pointer to data to write + //! @param len number of data elements in data, -1 on error + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutWriteFileui( const char* filename,const unsigned int* data, + unsigned int len, bool verbose = false); + + //////////////////////////////////////////////////////////////////////////// + //! Write a data file \filename containing char / byte data + //! @return CUTTrue if writing the file succeeded, otherwise false + //! @param filename name of the file to write + //! @param data pointer to data to write + //! @param len number of data elements in data, -1 on error + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutWriteFileb( const char* filename, const char* data, unsigned int len, + bool verbose = false); + + //////////////////////////////////////////////////////////////////////////// + //! Write a data file \filename containing unsigned char / byte data + //! @return CUTTrue if writing the file succeeded, otherwise false + //! @param filename name of the file to write + //! @param data pointer to data to write + //! @param len number of data elements in data, -1 on error + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutWriteFileub( const char* filename,const unsigned char* data, + unsigned int len, bool verbose = false); + + //////////////////////////////////////////////////////////////////////////// + //! Load PGM image file (with unsigned char as data element type) + //! @return CUTTrue if reading the file succeeded, otherwise false + //! @param file name of the image file + //! @param data handle to the data read + //! @param w width of the image + //! @param h height of the image + //! @note If a NULL pointer is passed to this function and it is + //! initialized within Cutil then cutFree() has to be used to + //! deallocate the memory + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutLoadPGMub( const char* file, unsigned char** data, + unsigned int *w,unsigned int *h); + + //////////////////////////////////////////////////////////////////////////// + //! Load PPM image file (with unsigned char as data element type) + //! @return CUTTrue if reading the file succeeded, otherwise false + //! @param file name of the image file + //! @param data handle to the data read + //! @param w width of the image + //! @param h height of the image + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutLoadPPMub( const char* file, unsigned char** data, + unsigned int *w,unsigned int *h); + + //////////////////////////////////////////////////////////////////////////// + //! Load PPM image file (with unsigned char as data element type), padding + //! 4th component + //! @return CUTTrue if reading the file succeeded, otherwise false + //! @param file name of the image file + //! @param data handle to the data read + //! @param w width of the image + //! @param h height of the image + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutLoadPPM4ub( const char* file, unsigned char** data, + unsigned int *w,unsigned int *h); + + //////////////////////////////////////////////////////////////////////////// + //! Load PGM image file (with unsigned int as data element type) + //! @return CUTTrue if reading the file succeeded, otherwise false + //! @param file name of the image file + //! @param data handle to the data read + //! @param w width of the image + //! @param h height of the image + //! @note If a NULL pointer is passed to this function and it is + //! initialized within Cutil then cutFree() has to be used to + //! deallocate the memory + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutLoadPGMi( const char* file, unsigned int** data, + unsigned int* w, unsigned int* h); + + //////////////////////////////////////////////////////////////////////////// + //! Load PGM image file (with unsigned short as data element type) + //! @return CUTTrue if reading the file succeeded, otherwise false + //! @param file name of the image file + //! @param data handle to the data read + //! @param w width of the image + //! @param h height of the image + //! @note If a NULL pointer is passed to this function and it is + //! initialized withing Cutil then cutFree() has to be used to + //! deallocate the memory + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutLoadPGMs( const char* file, unsigned short** data, + unsigned int* w, unsigned int* h); + + //////////////////////////////////////////////////////////////////////////// + //! Load PGM image file (with float as data element type) + //! @param file name of the image file + //! @param data handle to the data read + //! @param w width of the image + //! @param h height of the image + //! @note If a NULL pointer is passed to this function and it is + //! initialized withing Cutil then cutFree() has to be used to + //! deallocate the memory + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutLoadPGMf( const char* file, float** data, + unsigned int* w, unsigned int* h); + + //////////////////////////////////////////////////////////////////////////// + //! Save PGM image file (with unsigned char as data element type) + //! @param file name of the image file + //! @param data handle to the data read + //! @param w width of the image + //! @param h height of the image + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutSavePGMub( const char* file, unsigned char* data, + unsigned int w, unsigned int h); + + //////////////////////////////////////////////////////////////////////////// + //! Save PPM image file (with unsigned char as data element type) + //! @param file name of the image file + //! @param data handle to the data read + //! @param w width of the image + //! @param h height of the image + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutSavePPMub( const char* file, unsigned char *data, + unsigned int w, unsigned int h); + + //////////////////////////////////////////////////////////////////////////// + //! Save PPM image file (with unsigned char as data element type, padded to + //! 4 bytes) + //! @param file name of the image file + //! @param data handle to the data read + //! @param w width of the image + //! @param h height of the image + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutSavePPM4ub( const char* file, unsigned char *data, + unsigned int w, unsigned int h); + + //////////////////////////////////////////////////////////////////////////// + //! Save PGM image file (with unsigned int as data element type) + //! @param file name of the image file + //! @param data handle to the data read + //! @param w width of the image + //! @param h height of the image + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutSavePGMi( const char* file, unsigned int* data, + unsigned int w, unsigned int h); + + //////////////////////////////////////////////////////////////////////////// + //! Save PGM image file (with unsigned short as data element type) + //! @param file name of the image file + //! @param data handle to the data read + //! @param w width of the image + //! @param h height of the image + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutSavePGMs( const char* file, unsigned short* data, + unsigned int w, unsigned int h); + + //////////////////////////////////////////////////////////////////////////// + //! Save PGM image file (with float as data element type) + //! @param file name of the image file + //! @param data handle to the data read + //! @param w width of the image + //! @param h height of the image + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutSavePGMf( const char* file, float* data, + unsigned int w, unsigned int h); + + //////////////////////////////////////////////////////////////////////////// + // Command line arguments: General notes + // * All command line arguments begin with '--' followed by the token; + // token and value are seperated by '='; example --samples=50 + // * Arrays have the form --model=[one.obj,two.obj,three.obj] + // (without whitespaces) + //////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////// + //! Check if command line argument \a flag-name is given + //! @return CUTTrue if command line argument \a flag_name has been given, + //! otherwise 0 + //! @param argc argc as passed to main() + //! @param argv argv as passed to main() + //! @param flag_name name of command line flag + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutCheckCmdLineFlag( const int argc, const char** argv, + const char* flag_name); + + //////////////////////////////////////////////////////////////////////////// + //! Get the value of a command line argument of type int + //! @return CUTTrue if command line argument \a arg_name has been given and + //! is of the requested type, otherwise CUTFalse + //! @param argc argc as passed to main() + //! @param argv argv as passed to main() + //! @param arg_name name of the command line argument + //! @param val value of the command line argument + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutGetCmdLineArgumenti( const int argc, const char** argv, + const char* arg_name, int* val); + + //////////////////////////////////////////////////////////////////////////// + //! Get the value of a command line argument of type float + //! @return CUTTrue if command line argument \a arg_name has been given and + //! is of the requested type, otherwise CUTFalse + //! @param argc argc as passed to main() + //! @param argv argv as passed to main() + //! @param arg_name name of the command line argument + //! @param val value of the command line argument + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutGetCmdLineArgumentf( const int argc, const char** argv, + const char* arg_name, float* val); + + //////////////////////////////////////////////////////////////////////////// + //! Get the value of a command line argument of type string + //! @return CUTTrue if command line argument \a arg_name has been given and + //! is of the requested type, otherwise CUTFalse + //! @param argc argc as passed to main() + //! @param argv argv as passed to main() + //! @param arg_name name of the command line argument + //! @param val value of the command line argument + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutGetCmdLineArgumentstr( const int argc, const char** argv, + const char* arg_name, char** val); + + //////////////////////////////////////////////////////////////////////////// + //! Get the value of a command line argument list those element are strings + //! @return CUTTrue if command line argument \a arg_name has been given and + //! is of the requested type, otherwise CUTFalse + //! @param argc argc as passed to main() + //! @param argv argv as passed to main() + //! @param arg_name name of the command line argument + //! @param val command line argument list + //! @param len length of the list / number of elements + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutGetCmdLineArgumentListstr( const int argc, const char** argv, + const char* arg_name, char** val, + unsigned int* len); + + //////////////////////////////////////////////////////////////////////////// + //! Extended assert + //! @return CUTTrue if the condition \a val holds, otherwise CUTFalse + //! @param val condition to test + //! @param file __FILE__ macro + //! @param line __LINE__ macro + //! @note This function should be used via the CONDITION(val) macro + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutCheckCondition( int val, const char* file, const int line); + + //////////////////////////////////////////////////////////////////////////// + //! Compare two float arrays + //! @return CUTTrue if \a reference and \a data are identical, + //! otherwise CUTFalse + //! @param reference handle to the reference data / gold image + //! @param data handle to the computed data + //! @param len number of elements in reference and data + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutComparef( const float* reference, const float* data, + const unsigned int len); + + //////////////////////////////////////////////////////////////////////////// + //! Compare two integer arrays + //! @return CUTTrue if \a reference and \a data are identical, + //! otherwise CUTFalse + //! @param reference handle to the reference data / gold image + //! @param data handle to the computed data + //! @param len number of elements in reference and data + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutComparei( const int* reference, const int* data, + const unsigned int len ); + + //////////////////////////////////////////////////////////////////////////////// + //! Compare two unsigned integer arrays, with epsilon and threshold + //! @return CUTTrue if \a reference and \a data are identical, + //! otherwise CUTFalse + //! @param reference handle to the reference data / gold image + //! @param data handle to the computed data + //! @param len number of elements in reference and data + //! @param threshold tolerance % # of comparison errors (0.15f = 15%) + //////////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutCompareuit( const unsigned int* reference, const unsigned int* data, + const unsigned int len, const float epsilon, const float threshold ); + + //////////////////////////////////////////////////////////////////////////// + //! Compare two unsigned char arrays + //! @return CUTTrue if \a reference and \a data are identical, + //! otherwise CUTFalse + //! @param reference handle to the reference data / gold image + //! @param data handle to the computed data + //! @param len number of elements in reference and data + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutCompareub( const unsigned char* reference, const unsigned char* data, + const unsigned int len ); + + //////////////////////////////////////////////////////////////////////////////// + //! Compare two integers with a tolernance for # of byte errors + //! @return CUTTrue if \a reference and \a data are identical, + //! otherwise CUTFalse + //! @param reference handle to the reference data / gold image + //! @param data handle to the computed data + //! @param len number of elements in reference and data + //! @param epsilon epsilon to use for the comparison + //! @param threshold tolerance % # of comparison errors (0.15f = 15%) + //////////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutCompareubt( const unsigned char* reference, const unsigned char* data, + const unsigned int len, const float epsilon, const float threshold ); + + //////////////////////////////////////////////////////////////////////////////// + //! Compare two integer arrays witha n epsilon tolerance for equality + //! @return CUTTrue if \a reference and \a data are identical, + //! otherwise CUTFalse + //! @param reference handle to the reference data / gold image + //! @param data handle to the computed data + //! @param len number of elements in reference and data + //! @param epsilon epsilon to use for the comparison + //////////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutCompareube( const unsigned char* reference, const unsigned char* data, + const unsigned int len, const float epsilon ); + + //////////////////////////////////////////////////////////////////////////// + //! Compare two float arrays with an epsilon tolerance for equality + //! @return CUTTrue if \a reference and \a data are identical, + //! otherwise CUTFalse + //! @param reference handle to the reference data / gold image + //! @param data handle to the computed data + //! @param len number of elements in reference and data + //! @param epsilon epsilon to use for the comparison + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutComparefe( const float* reference, const float* data, + const unsigned int len, const float epsilon ); + + //////////////////////////////////////////////////////////////////////////////// + //! Compare two float arrays with an epsilon tolerance for equality and a + //! threshold for # pixel errors + //! @return CUTTrue if \a reference and \a data are identical, + //! otherwise CUTFalse + //! @param reference handle to the reference data / gold image + //! @param data handle to the computed data + //! @param len number of elements in reference and data + //! @param epsilon epsilon to use for the comparison + //////////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutComparefet( const float* reference, const float* data, + const unsigned int len, const float epsilon, const float threshold ); + + //////////////////////////////////////////////////////////////////////////// + //! Compare two float arrays using L2-norm with an epsilon tolerance for + //! equality + //! @return CUTTrue if \a reference and \a data are identical, + //! otherwise CUTFalse + //! @param reference handle to the reference data / gold image + //! @param data handle to the computed data + //! @param len number of elements in reference and data + //! @param epsilon epsilon to use for the comparison + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutCompareL2fe( const float* reference, const float* data, + const unsigned int len, const float epsilon ); + + //////////////////////////////////////////////////////////////////////////////// + //! Compare two PPM image files with an epsilon tolerance for equality + //! @return CUTTrue if \a reference and \a data are identical, + //! otherwise CUTFalse + //! @param src_file filename for the image to be compared + //! @param data filename for the reference data / gold image + //! @param epsilon epsilon to use for the comparison + //! @param threshold threshold of pixels that can still mismatch to pass (i.e. 0.15f = 15% must pass) + //! $param verboseErrors output details of image mismatch to std::err + //////////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutComparePPM( const char *src_file, const char *ref_file, const float epsilon, const float threshold, bool verboseErrors = false ); + + + //////////////////////////////////////////////////////////////////////////// + //! Timer functionality + + //////////////////////////////////////////////////////////////////////////// + //! Create a new timer + //! @return CUTTrue if a time has been created, otherwise false + //! @param name of the new timer, 0 if the creation failed + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutCreateTimer( unsigned int* name); + + //////////////////////////////////////////////////////////////////////////// + //! Delete a timer + //! @return CUTTrue if a time has been deleted, otherwise false + //! @param name of the timer to delete + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutDeleteTimer( unsigned int name); + + //////////////////////////////////////////////////////////////////////////// + //! Start the time with name \a name + //! @param name name of the timer to start + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutStartTimer( const unsigned int name); + + //////////////////////////////////////////////////////////////////////////// + //! Stop the time with name \a name. Does not reset. + //! @param name name of the timer to stop + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutStopTimer( const unsigned int name); + + //////////////////////////////////////////////////////////////////////////// + //! Resets the timer's counter. + //! @param name name of the timer to reset. + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + CUTBoolean CUTIL_API + cutResetTimer( const unsigned int name); + + //////////////////////////////////////////////////////////////////////////// + //! Returns total execution time in milliseconds for the timer over all + //! runs since the last reset or timer creation. + //! @param name name of the timer to return the time of + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + float CUTIL_API + cutGetTimerValue( const unsigned int name); + + //////////////////////////////////////////////////////////////////////////// + //! Return the average time in milliseconds for timer execution as the + //! total time for the timer dividied by the number of completed (stopped) + //! runs the timer has made. + //! Excludes the current running time if the timer is currently running. + //! @param name name of the timer to return the time of + //////////////////////////////////////////////////////////////////////////// + DLL_MAPPING + float CUTIL_API + cutGetAverageTimerValue( const unsigned int name); + + //////////////////////////////////////////////////////////////////////////// + //! Macros + +#if CUDART_VERSION >= 4000 +#define CUT_DEVICE_SYNCHRONIZE( ) cudaDeviceSynchronize(); +#else +#define CUT_DEVICE_SYNCHRONIZE( ) cudaThreadSynchronize(); +#endif + +#if CUDART_VERSION >= 4000 +#define CUT_DEVICE_RESET( ) cudaDeviceReset(); +#else +#define CUT_DEVICE_RESET( ) cudaThreadExit(); +#endif + +// This is for the CUTIL bank checker +#define CUT_BANK_CHECKER( array, index) array[index] + +# define CU_SAFE_CALL_NO_SYNC( call ) { \ + CUresult err = call; \ + if( CUDA_SUCCESS != err) { \ + fprintf(stderr, "Cuda driver error %x in file '%s' in line %i.\n", \ + err, __FILE__, __LINE__ ); \ + exit(EXIT_FAILURE); \ + } } + +# define CU_SAFE_CALL( call ) CU_SAFE_CALL_NO_SYNC(call); + +# define CU_SAFE_CTX_SYNC( ) { \ + CUresult err = cuCtxSynchronize(); \ + if( CUDA_SUCCESS != err) { \ + fprintf(stderr, "Cuda driver error %x in file '%s' in line %i.\n", \ + err, __FILE__, __LINE__ ); \ + exit(EXIT_FAILURE); \ + } } + +# define CUDA_SAFE_CALL_NO_SYNC( call) { \ + cudaError err = call; \ + if( cudaSuccess != err) { \ + fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n", \ + __FILE__, __LINE__, cudaGetErrorString( err) ); \ + exit(EXIT_FAILURE); \ + } } + +# define CUDA_SAFE_CALL( call) CUDA_SAFE_CALL_NO_SYNC(call); \ + +# define CUDA_SAFE_THREAD_SYNC( ) { \ + cudaError err = CUT_DEVICE_SYNCHRONIZE(); \ + if ( cudaSuccess != err) { \ + fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n", \ + __FILE__, __LINE__, cudaGetErrorString( err) ); \ + } } + +# define CUFFT_SAFE_CALL( call) { \ + cufftResult err = call; \ + if( CUFFT_SUCCESS != err) { \ + fprintf(stderr, "CUFFT error in file '%s' in line %i.\n", \ + __FILE__, __LINE__); \ + exit(EXIT_FAILURE); \ + } } + +# define CUT_SAFE_CALL( call) \ + if( CUTTrue != call) { \ + fprintf(stderr, "Cut error in file '%s' in line %i.\n", \ + __FILE__, __LINE__); \ + exit(EXIT_FAILURE); \ + } + + //! Check for CUDA error +#ifdef _DEBUG +# define CUT_CHECK_ERROR(errorMessage) { \ + cudaError_t err = cudaGetLastError(); \ + if( cudaSuccess != err) { \ + fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \ + errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\ + exit(EXIT_FAILURE); \ + } \ + err = CUT_DEVICE_SYNCHRONIZE(); \ + if( cudaSuccess != err) { \ + fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \ + errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\ + exit(EXIT_FAILURE); \ + } \ + } +#else +# define CUT_CHECK_ERROR(errorMessage) { \ + cudaError_t err = cudaGetLastError(); \ + if( cudaSuccess != err) { \ + fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \ + errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\ + exit(EXIT_FAILURE); \ + } \ + } +#endif + + //! Check for malloc error +# define CUT_SAFE_MALLOC( mallocCall ) { \ + if( !(mallocCall)) { \ + fprintf(stderr, "Host malloc failure in file '%s' in line %i\n", \ + __FILE__, __LINE__); \ + exit(EXIT_FAILURE); \ + } } while(0); + + //! Check if conditon is true (flexible assert) +# define CUT_CONDITION( val) \ + if( CUTFalse == cutCheckCondition( val, __FILE__, __LINE__)) { \ + exit(EXIT_FAILURE); \ + } + +# define CUT_DEVICE_INIT(ARGC, ARGV) { \ + int deviceCount; \ + CUDA_SAFE_CALL_NO_SYNC(cudaGetDeviceCount(&deviceCount)); \ + if (deviceCount == 0) { \ + fprintf(stderr, "cutil error: no devices supporting CUDA.\n"); \ + exit(EXIT_FAILURE); \ + } \ + int dev = 0; \ + cutGetCmdLineArgumenti(ARGC, (const char **) ARGV, "device", &dev); \ + if (dev < 0) dev = 0; \ + if (dev > deviceCount-1) dev = deviceCount - 1; \ + cudaDeviceProp deviceProp; \ + CUDA_SAFE_CALL_NO_SYNC(cudaGetDeviceProperties(&deviceProp, dev)); \ + if (cutCheckCmdLineFlag(ARGC, (const char **) ARGV, "quiet") == CUTFalse) \ + fprintf(stderr, "Using device %d: %s\n", dev, deviceProp.name); \ + CUDA_SAFE_CALL(cudaSetDevice(dev)); \ +} + + + //! Check for CUDA context lost +# define CUDA_CHECK_CTX_LOST(errorMessage) { \ + cudaError_t err = cudaGetLastError(); \ + if( cudaSuccess != err) { \ + fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \ + errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\ + exit(EXIT_FAILURE); \ + } \ + err = CUT_DEVICE_SYNCHRONIZE(); \ + if( cudaSuccess != err) { \ + fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \ + errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\ + exit(EXIT_FAILURE); \ + } } + +//! Check for CUDA context lost +# define CU_CHECK_CTX_LOST(errorMessage) { \ + cudaError_t err = cudaGetLastError(); \ + if( CUDA_ERROR_INVALID_CONTEXT != err) { \ + fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \ + errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\ + exit(EXIT_FAILURE); \ + } \ + err = CUT_DEVICE_SYNCHRONIZE(); \ + if( cudaSuccess != err) { \ + fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n", \ + errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\ + exit(EXIT_FAILURE); \ + } } + +# define CUT_DEVICE_INIT_DRV(cuDevice, ARGC, ARGV) { \ + cuDevice = 0; \ + int deviceCount = 0; \ + CUresult err = cuInit(0); \ + if (CUDA_SUCCESS == err) \ + CU_SAFE_CALL_NO_SYNC(cuDeviceGetCount(&deviceCount)); \ + if (deviceCount == 0) { \ + fprintf(stderr, "cutil error: no devices supporting CUDA\n"); \ + exit(EXIT_FAILURE); \ + } \ + int dev = 0; \ + cutGetCmdLineArgumenti(ARGC, (const char **) ARGV, "device", &dev); \ + if (dev < 0) dev = 0; \ + if (dev > deviceCount-1) dev = deviceCount - 1; \ + CU_SAFE_CALL_NO_SYNC(cuDeviceGet(&cuDevice, dev)); \ + char name[100]; \ + cuDeviceGetName(name, 100, cuDevice); \ + if (cutCheckCmdLineFlag(ARGC, (const char **) ARGV, "quiet") == CUTFalse) \ + fprintf(stderr, "Using device %d: %s\n", dev, name); \ +} + +#define CUT_EXIT(argc, argv) \ + if (!cutCheckCmdLineFlag(argc, (const char**)argv, "noprompt")) { \ + printf("\nPress ENTER to exit...\n"); \ + fflush( stdout); \ + fflush( stderr); \ + getchar(); \ + } \ + exit(EXIT_SUCCESS); + + +#ifdef __cplusplus +} +#endif // #ifdef _DEBUG (else branch) + +#endif // #ifndef _CUTIL_H_ diff --git a/external/cutil/inc/cutil_gl_error.h b/external/cutil/inc/cutil_gl_error.h new file mode 100644 index 0000000..4da3d39 --- /dev/null +++ b/external/cutil/inc/cutil_gl_error.h @@ -0,0 +1,110 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + /* +* Copyright 1993-2010 NVIDIA Corporation. All rights reserved. +* +* Please refer to the NVIDIA end user license agreement (EULA) associated +* with this source code for terms and conditions that govern your use of +* this software. Any use, reproduction, disclosure, or distribution of +* this software and related documentation outside the terms of the EULA +* is strictly prohibited. +* +*/ + +#ifndef CUTIL_GL_ERROR +#define CUTIL_GL_ERROR + +/* CUda UTility Library */ + +// includes, system +#ifdef _WIN32 +# define WINDOWS_LEAN_AND_MEAN +# include +# include +# undef min +# undef max +#endif + +// includes, graphics +#if defined (__APPLE__) || defined(MACOSX) +#include +#include +#else +#include +#include +#endif + +//////////////////////////////////////////////////////////////////////////// +//! Check for OpenGL error +//! @return CUTTrue if no GL error has been encountered, otherwise 0 +//! @param file __FILE__ macro +//! @param line __LINE__ macro +//! @note The GL error is listed on stderr +//! @note This function should be used via the CHECK_ERROR_GL() macro +//////////////////////////////////////////////////////////////////////////// +CUTBoolean CUTIL_API +cutCheckErrorGL( const char* file, const int line) +{ + CUTBoolean ret_val = CUTTrue; + + // check for error + GLenum gl_error = glGetError(); + if (gl_error != GL_NO_ERROR) + { +#ifdef _WIN32 + char tmpStr[512]; + // NOTE: "%s(%i) : " allows Visual Studio to directly jump to the file at the right line + // when the user double clicks on the error line in the Output pane. Like any compile error. + sprintf_s(tmpStr, 255, "\n%s(%i) : GL Error : %s\n\n", file, line, gluErrorString(gl_error)); + OutputDebugString(tmpStr); +#endif + fprintf(stderr, "GL Error in file '%s' in line %d :\n", file, line); + fprintf(stderr, "%s\n", gluErrorString(gl_error)); + ret_val = CUTFalse; + } + return ret_val; +} + +#ifdef _DEBUG + +#define CUT_CHECK_ERROR_GL() \ + if( CUTFalse == cutCheckErrorGL( __FILE__, __LINE__)) { \ + exit(EXIT_FAILURE); \ + } +// Use this one to do : if(CUT_GL_HAS_ERROR) +#define CUT_GL_HAS_ERROR (cutCheckErrorGL( __FILE__, __LINE__) ? CUTFalse : CUTTrue ) +#ifdef _WIN32 +#define CUT_CHECK_ERROR_GL2()\ + if(CUT_GL_HAS_ERROR)\ + {\ + MessageBox(NULL, "Error in OpenGL. Check VStudio Output...", "Error", MB_OK);\ + exit(EXIT_FAILURE);\ + } +#else // Not _WIN32: +#define CUT_CHECK_ERROR_GL2()\ + if(CUT_GL_HAS_ERROR)\ + {\ + printf("press a key...\n");\ + getc(stdin);\ + exit(EXIT_FAILURE);\ + } +#endif + +#else + +#define CUT_CHECK_ERROR_GL() +#define CUT_CHECK_ERROR_GL2() +#define CUT_GL_HAS_ERROR CUTFalse + +#endif // _DEBUG + +#endif // CUTIL_GL_ERROR diff --git a/external/cutil/inc/cutil_gl_inline.h b/external/cutil/inc/cutil_gl_inline.h new file mode 100644 index 0000000..e13e8f2 --- /dev/null +++ b/external/cutil/inc/cutil_gl_inline.h @@ -0,0 +1,109 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +#ifndef _CUTIL_GL_INLINE_H_ +#define _CUTIL_GL_INLINE_H_ + +#include +#include +#include + +#include +#include +#include +#include +#include + + +inline int cutilGLDeviceInit(int ARGC, char **ARGV) +{ + int deviceCount; + cutilSafeCallNoSync(cudaGetDeviceCount(&deviceCount)); + if (deviceCount == 0) { + fprintf(stderr, "CUTIL CUDA error: no devices supporting CUDA.\n"); + exit(-1); + } + int dev = 0; + cutGetCmdLineArgumenti(ARGC, (const char **) ARGV, "device", &dev); + if (dev < 0) + dev = 0; + if (dev > deviceCount-1) { + fprintf(stderr, "\n"); + fprintf(stderr, ">> %d CUDA capable GPU device(s) detected. <<\n", deviceCount); + fprintf(stderr, ">> cutilDeviceInit (-device=%d) is not a valid GPU device. <<\n", dev); + fprintf(stderr, "\n"); + return -dev; + } + cudaDeviceProp deviceProp; + cutilSafeCallNoSync(cudaGetDeviceProperties(&deviceProp, dev)); + if (deviceProp.major < 1) { + fprintf(stderr, "cutil error: device does not support CUDA.\n"); + exit(-1); \ + } + if (cutCheckCmdLineFlag(ARGC, (const char **) ARGV, "quiet") == CUTFalse) + fprintf(stderr, "Using device %d: %s\n", dev, deviceProp.name); + cutilSafeCall(cudaGLSetGLDevice(dev)); + return dev; +} + +inline int cutilGLDeviceInitDrv(int cuDevice, int ARGC, char ** ARGV) +{ + cuDevice = 0; + int deviceCount = 0; + CUresult err = cuInit(0); + if (CUDA_SUCCESS == err) + cutilDrvSafeCallNoSync(cuDeviceGetCount(&deviceCount)); + if (deviceCount == 0) { + fprintf(stderr, "CUTIL DeviceInitDrv error: no devices supporting CUDA\n"); + exit(-1); + } + + int dev = 0; + cutGetCmdLineArgumenti(ARGC, (const char **) ARGV, "device", &dev); + if (dev < 0) + dev = 0; + if (dev > deviceCount-1) { + fprintf(stderr, "\n"); + fprintf(stderr, ">> %d CUDA capable GPU device(s) detected. <<\n", deviceCount); + fprintf(stderr, ">> cutilDeviceInit (-device=%d) is not a valid GPU device. <<\n", dev); + fprintf(stderr, "\n"); + return -dev; + } + cutilDrvSafeCallNoSync(cuDeviceGet(&cuDevice, dev)); + char name[100]; + cuDeviceGetName(name, 100, cuDevice); + if (cutCheckCmdLineFlag(ARGC, (const char **) ARGV, "quiet") == CUTFalse) { + fprintf(stderr, "Using device %d: %s\n", dev, name); + } + return dev; +} + +// This function will pick the best CUDA device available with OpenGL interop +inline int cutilChooseCudaGLDevice(int argc, char **argv) +{ + int devID = 0; + // If the command-line has a device number specified, use it + if( cutCheckCmdLineFlag(argc, (const char**)argv, "device") ) { + devID = cutilGLDeviceInit(argc, argv); + if (devID < 0) { + printf("exiting...\n"); + cutilExit(argc, argv); + exit(0); + } + } else { + // Otherwise pick the device with highest Gflops/s + devID = cutGetMaxGflopsDeviceId(); + cudaGLSetGLDevice( devID ); + } + return devID; +} + +#endif // _CUTIL_GL_INLINE_H_ diff --git a/external/cutil/inc/cutil_inline.h b/external/cutil/inc/cutil_inline.h new file mode 100644 index 0000000..25c0352 --- /dev/null +++ b/external/cutil/inc/cutil_inline.h @@ -0,0 +1,34 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +#ifndef _CUTIL_INLINE_H_ +#define _CUTIL_INLINE_H_ + +#include +#include +#include + +#include +#include +#include + +inline void print_NVCC_min_spec(const char *sSDKsample, const char *sNVCCReq, const char *sDriverReq) +{ + printf("CUDA %d.%02d Toolkit built this project.\n", CUDART_VERSION/1000, (CUDART_VERSION%100)); + printf(" [ %s ] requirements:\n", sSDKsample); + printf(" -> CUDA %s Toolkit\n" , sNVCCReq); + printf(" -> %s NVIDIA Display Driver.\n", sDriverReq); +} + +#define ALIGN_OFFSET(offset, alignment) offset = (offset + (alignment-1)) & ~((alignment-1)) + + +#endif // _CUTIL_INLINE_H_ diff --git a/external/cutil/inc/cutil_inline_bankchecker.h b/external/cutil/inc/cutil_inline_bankchecker.h new file mode 100644 index 0000000..f00f041 --- /dev/null +++ b/external/cutil/inc/cutil_inline_bankchecker.h @@ -0,0 +1,25 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +#ifndef _CUTIL_INLINE_BANKCHECKER_H_ +#define _CUTIL_INLINE_BANKCHECKER_H_ + +#define cutilBankChecker(array, idx) array[idx] + + // Interface for bank conflict checker +inline void __cutilBankChecker(unsigned int tidx, unsigned int tidy, unsigned int tidz, + unsigned int bdimx, unsigned int bdimy, unsigned int bdimz, + char *aname, int index, char *file, int line) +{ + cutCheckBankAccess( tidx, tidy, tidz, bdimx, bdimy, bdimz, file, line, aname, index); +} + +#endif // _CUTIL_INLINE_BANKCHECKER_H_ diff --git a/external/cutil/inc/cutil_inline_drvapi.h b/external/cutil/inc/cutil_inline_drvapi.h new file mode 100644 index 0000000..54d922c --- /dev/null +++ b/external/cutil/inc/cutil_inline_drvapi.h @@ -0,0 +1,372 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +#ifndef _CUTIL_INLINE_FUNCTIONS_DRVAPI_H_ +#define _CUTIL_INLINE_FUNCTIONS_DRVAPI_H_ + +#include +#include +#include + +#include "drvapi_error_string.h" +#include "string_helper.h" + +// We define these calls here, so the user doesn't need to include __FILE__ and __LINE__ +// The advantage is the developers gets to use the inline function so they can debug +#define cutilDrvSafeCallNoSync(err) __cuSafeCallNoSync (err, __FILE__, __LINE__) +#define cutilDrvSafeCall(err) __cuSafeCall (err, __FILE__, __LINE__) +#define cutilDrvCtxSync() __cuCtxSync (__FILE__, __LINE__) +#define cutilDrvCheckMsg(msg) __cuCheckMsg (msg, __FILE__, __LINE__) +#define cutilDrvAlignOffset(offset, alignment) ( offset = (offset + (alignment-1)) & ~((alignment-1)) ) + +// These are the inline versions for all of the CUTIL functions +inline void __cuSafeCallNoSync( CUresult err, const char *file, const int line ) +{ + if( CUDA_SUCCESS != err) { + fprintf(stderr, "cuSafeCallNoSync() Driver API error = %04d \"%s\" from file <%s>, line %i.\n", + err, getCudaDrvErrorString(err), file, line ); + exit(-1); + } +} +inline void __cuSafeCall( CUresult err, const char *file, const int line ) +{ + __cuSafeCallNoSync( err, file, line ); +} + +inline void __cuCtxSync(const char *file, const int line ) +{ + CUresult err = cuCtxSynchronize(); + if( CUDA_SUCCESS != err ) { + fprintf(stderr, "cuCtxSynchronize() API error = %04d \"%s\" from file <%s>, line %i.\n", + err, getCudaDrvErrorString(err), file, line ); + exit(-1); + } +} + +#define MIN(a,b) ((a < b) ? a : b) +#define MAX(a,b) ((a > b) ? a : b) + +// Beginning of GPU Architecture definitions +inline int _ConvertSMVer2CoresDrvApi(int major, int minor) +{ + // Defines for GPU Architecture types (using the SM version to determine the # of cores per SM + typedef struct { + int SM; // 0xMm (hexidecimal notation), M = SM Major version, and m = SM minor version + int Cores; + } sSMtoCores; + + sSMtoCores nGpuArchCoresPerSM[] = + { { 0x10, 8 }, + { 0x11, 8 }, + { 0x12, 8 }, + { 0x13, 8 }, + { 0x20, 32 }, + { 0x21, 48 }, + { -1, -1 } + }; + + int index = 0; + while (nGpuArchCoresPerSM[index].SM != -1) { + if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor) ) { + return nGpuArchCoresPerSM[index].Cores; + } + index++; + } + printf("MapSMtoCores undefined SMversion %d.%d!\n", major, minor); + return -1; +} +// end of GPU Architecture definitions + +// This function returns the best GPU based on performance +inline int cutilDrvGetMaxGflopsDeviceId() +{ + CUdevice current_device = 0, max_perf_device = 0; + int device_count = 0, sm_per_multiproc = 0; + int max_compute_perf = 0, best_SM_arch = 0; + int major = 0, minor = 0, multiProcessorCount, clockRate; + + cuInit(0); + cutilDrvSafeCallNoSync(cuDeviceGetCount(&device_count)); + + // Find the best major SM Architecture GPU device + while ( current_device < device_count ) { + cutilDrvSafeCallNoSync( cuDeviceComputeCapability(&major, &minor, current_device ) ); + if (major > 0 && major < 9999) { + best_SM_arch = MAX(best_SM_arch, major); + } + current_device++; + } + + // Find the best CUDA capable GPU device + current_device = 0; + while( current_device < device_count ) { + cutilDrvSafeCallNoSync( cuDeviceGetAttribute( &multiProcessorCount, + CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT, + current_device ) ); + cutilDrvSafeCallNoSync( cuDeviceGetAttribute( &clockRate, + CU_DEVICE_ATTRIBUTE_CLOCK_RATE, + current_device ) ); + cutilDrvSafeCallNoSync( cuDeviceComputeCapability(&major, &minor, current_device ) ); + + if (major == 9999 && minor == 9999) { + sm_per_multiproc = 1; + } else { + sm_per_multiproc = _ConvertSMVer2CoresDrvApi(major, minor); + } + + int compute_perf = multiProcessorCount * sm_per_multiproc * clockRate; + if( compute_perf > max_compute_perf ) { + // If we find GPU with SM major > 2, search only these + if ( best_SM_arch > 2 ) { + // If our device==dest_SM_arch, choose this, or else pass + if (major == best_SM_arch) { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } else { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } + ++current_device; + } + return max_perf_device; +} + +// This function returns the best Graphics GPU based on performance +inline int cutilDrvGetMaxGflopsGraphicsDeviceId() +{ + CUdevice current_device = 0, max_perf_device = 0; + int device_count = 0, sm_per_multiproc = 0; + int max_compute_perf = 0, best_SM_arch = 0; + int major = 0, minor = 0, multiProcessorCount, clockRate; + int bTCC = 0; + char deviceName[256]; + + cuInit(0); + cutilDrvSafeCallNoSync(cuDeviceGetCount(&device_count)); + + // Find the best major SM Architecture GPU device that are graphics devices + while ( current_device < device_count ) { + cutilDrvSafeCallNoSync( cuDeviceGetName(deviceName, 256, current_device) ); + cutilDrvSafeCallNoSync( cuDeviceComputeCapability(&major, &minor, current_device ) ); + +#if CUDA_VERSION >= 3020 + cutilDrvSafeCallNoSync( cuDeviceGetAttribute( &bTCC, CU_DEVICE_ATTRIBUTE_TCC_DRIVER, current_device ) ); +#else + // Assume a Tesla GPU is running in TCC if we are running CUDA 3.1 + if (deviceName[0] == 'T') bTCC = 1; +#endif + if (!bTCC) { + if (major > 0 && major < 9999) { + best_SM_arch = MAX(best_SM_arch, major); + } + } + current_device++; + } + + // Find the best CUDA capable GPU device + current_device = 0; + while( current_device < device_count ) { + cutilDrvSafeCallNoSync( cuDeviceGetAttribute( &multiProcessorCount, + CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT, + current_device ) ); + cutilDrvSafeCallNoSync( cuDeviceGetAttribute( &clockRate, + CU_DEVICE_ATTRIBUTE_CLOCK_RATE, + current_device ) ); + cutilDrvSafeCallNoSync( cuDeviceComputeCapability(&major, &minor, current_device ) ); + +#if CUDA_VERSION >= 3020 + cutilDrvSafeCallNoSync( cuDeviceGetAttribute( &bTCC, CU_DEVICE_ATTRIBUTE_TCC_DRIVER, current_device ) ); +#else + // Assume a Tesla GPU is running in TCC if we are running CUDA 3.1 + if (deviceName[0] == 'T') bTCC = 1; +#endif + + if (major == 9999 && minor == 9999) { + sm_per_multiproc = 1; + } else { + sm_per_multiproc = _ConvertSMVer2CoresDrvApi(major, minor); + } + + // If this is a Tesla based GPU and SM 2.0, and TCC is disabled, this is a contendor + if (!bTCC) // Is this GPU running the TCC driver? If so we pass on this + { + int compute_perf = multiProcessorCount * sm_per_multiproc * clockRate; + if( compute_perf > max_compute_perf ) { + // If we find GPU with SM major > 2, search only these + if ( best_SM_arch > 2 ) { + // If our device = dest_SM_arch, then we pick this one + if (major == best_SM_arch) { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } else { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } + } + ++current_device; + } + return max_perf_device; +} + +inline void __cuCheckMsg( const char * msg, const char *file, const int line ) +{ + CUresult err = cuCtxSynchronize(); + if( CUDA_SUCCESS != err) { + fprintf(stderr, "cutilDrvCheckMsg -> %s", msg); + fprintf(stderr, "cutilDrvCheckMsg -> cuCtxSynchronize API error = %04d \"%s\" in file <%s>, line %i.\n", + err, getCudaDrvErrorString(err), file, line ); + exit(-1); + } +} + + +inline int cutilDeviceInitDrv(int ARGC, char ** ARGV) +{ + int cuDevice = 0; + int deviceCount = 0; + CUresult err = cuInit(0); + if (CUDA_SUCCESS == err) + cutilDrvSafeCallNoSync(cuDeviceGetCount(&deviceCount)); + if (deviceCount == 0) { + fprintf(stderr, "CUTIL DeviceInitDrv error: no devices supporting CUDA\n"); + exit(-1); + } + int dev = 0; + dev = getCmdLineArgumentInt(ARGC, (const char **) ARGV, "device="); + if (dev < 0) dev = 0; + if (dev > deviceCount-1) { + fprintf(stderr, "\n"); + fprintf(stderr, ">> %d CUDA capable GPU device(s) detected. <<\n", deviceCount); + fprintf(stderr, ">> cutilDeviceInit (-device=%d) is not a valid GPU device. <<\n", dev); + fprintf(stderr, "\n"); + return -dev; + } + cutilDrvSafeCallNoSync(cuDeviceGet(&cuDevice, dev)); + char name[100]; + cuDeviceGetName(name, 100, cuDevice); + if (checkCmdLineFlag(ARGC, (const char **) ARGV, "quiet") == CUTFalse) { + printf("> Using CUDA Device [%d]: %s\n", dev, name); + } + return dev; +} + +// General initialization call to pick the best CUDA Device +inline CUdevice cutilChooseCudaDeviceDrv(int argc, char **argv, int *p_devID) +{ + CUdevice cuDevice; + int devID = 0; + // If the command-line has a device number specified, use it + if( checkCmdLineFlag(argc, (const char**)argv, "device") ) { + devID = cutilDeviceInitDrv(argc, argv); + if (devID < 0) { + printf("exiting...\n"); + exit(0); + } + } else { + // Otherwise pick the device with highest Gflops/s + char name[100]; + devID = cutilDrvGetMaxGflopsDeviceId(); + cutilDrvSafeCallNoSync(cuDeviceGet(&cuDevice, devID)); + cuDeviceGetName(name, 100, cuDevice); + printf("> Using CUDA Device [%d]: %s\n", devID, name); + } + cuDeviceGet(&cuDevice, devID); + if (p_devID) *p_devID = devID; + return cuDevice; +} + + +//! Check for CUDA context lost +inline void cutilDrvCudaCheckCtxLost(const char *errorMessage, const char *file, const int line ) +{ + CUresult err = cuCtxSynchronize(); + if( CUDA_ERROR_INVALID_CONTEXT != err) { + fprintf(stderr, "Cuda error: %s in file '%s' in line %i\n", + errorMessage, file, line ); + exit(-1); + } + err = cuCtxSynchronize(); + if( CUDA_SUCCESS != err) { + fprintf(stderr, "Cuda error: %s in file '%s' in line %i\n", + errorMessage, file, line ); + exit(-1); + } +} + +#ifndef STRCASECMP +#ifdef _WIN32 +#define STRCASECMP _stricmp +#else +#define STRCASECMP strcasecmp +#endif +#endif + +#ifndef STRNCASECMP +#ifdef _WIN32 +#define STRNCASECMP _strnicmp +#else +#define STRNCASECMP strncasecmp +#endif +#endif + +inline void __cutilDrvQAFinish(int argc, char **argv, bool bStatus) +{ + const char *sStatus[] = { "FAILED", "PASSED", "WAIVED", NULL }; + + bool bFlag = false; + for (int i=1; i < argc; i++) { + if (!STRCASECMP(argv[i], "-qatest") || !STRCASECMP(argv[i], "-noprompt")) { + bFlag |= true; + } + } + + if (bFlag) { + printf("&&&& %s %s", sStatus[bStatus], argv[0]); + for (int i=1; i < argc; i++) printf(" %s", argv[i]); + } else { + printf("[%s] test result\n%s\n", argv[0], sStatus[bStatus]); + } +} + +// General check for CUDA GPU SM Capabilities for a specific device # +inline bool cutilDrvCudaDevCapabilities(int major_version, int minor_version, int deviceNum) +{ + int major, minor, dev; + char device_name[256]; + + cutilDrvSafeCallNoSync( cuDeviceGet(&dev, deviceNum) ); + cutilDrvSafeCallNoSync( cuDeviceComputeCapability(&major, &minor, dev)); + cutilDrvSafeCallNoSync( cuDeviceGetName(device_name, 256, dev) ); + + if((major > major_version) || + (major == major_version && minor >= minor_version)) + { + printf("> Device %d: < %s >, Compute SM %d.%d detected\n", dev, device_name, major, minor); + return true; + } + else + { + printf("There is no device supporting CUDA compute capability %d.%d.\n", major_version, minor_version); + return false; + } +} + +// General check for CUDA GPU SM Capabilities +inline bool cutilDrvCudaCapabilities(int major_version, int minor_version) +{ + return cutilDrvCudaDevCapabilities(major_version, minor_version,0); +} + +#endif // _CUTIL_INLINE_FUNCTIONS_DRVAPI_H_ diff --git a/external/cutil/inc/cutil_inline_runtime.h b/external/cutil/inc/cutil_inline_runtime.h new file mode 100644 index 0000000..a00f244 --- /dev/null +++ b/external/cutil/inc/cutil_inline_runtime.h @@ -0,0 +1,532 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +#ifndef _CUTIL_INLINE_FUNCTIONS_RUNTIME_H_ +#define _CUTIL_INLINE_FUNCTIONS_RUNTIME_H_ + +#ifdef _WIN32 +#ifdef _DEBUG // Do this only in debug mode... +# define WINDOWS_LEAN_AND_MEAN +# include +# include +# undef min +# undef max +#endif +#endif + +#include +#include +#include + +#include +#include + +// We define these calls here, so the user doesn't need to include __FILE__ and __LINE__ +// The advantage is the developers gets to use the inline function so they can debug +#define cutilSafeCallNoSync(err) __cudaSafeCallNoSync(err, __FILE__, __LINE__) +#define cutilSafeCall(err) __cudaSafeCall (err, __FILE__, __LINE__) +#define cutilSafeThreadSync() __cudaSafeThreadSync(__FILE__, __LINE__) +#define cufftSafeCall(err) __cufftSafeCall (err, __FILE__, __LINE__) +#define curandSafeCall(err) __curandSafeCall (err, __FILE__, __LINE__) +#define cutilCheckError(err) __cutilCheckError (err, __FILE__, __LINE__) +#define cutilCheckMsg(msg) __cutilGetLastError (msg, __FILE__, __LINE__) +#define cutilCheckMsgAndSync(msg) __cutilGetLastErrorAndSync (msg, __FILE__, __LINE__) +#define cutilSafeMalloc(mallocCall) __cutilSafeMalloc ((mallocCall), __FILE__, __LINE__) +#define cutilCondition(val) __cutilCondition (val, __FILE__, __LINE__) +#define cutilExit(argc, argv) __cutilExit (argc, argv) + +inline cudaError cutilDeviceSynchronize() +{ +#if CUDART_VERSION >= 4000 + return cudaDeviceSynchronize(); +#else + return cudaThreadSynchronize(); +#endif +} + +inline cudaError cutilDeviceReset() +{ +#if CUDART_VERSION >= 4000 + return cudaDeviceReset(); +#else + return cudaThreadExit(); +#endif +} + +inline void __cutilCondition(int val, char *file, int line) +{ + if( CUTFalse == cutCheckCondition( val, file, line ) ) { + exit(EXIT_FAILURE); + } +} + +inline void __cutilExit(int argc, char **argv) +{ + if (!cutCheckCmdLineFlag(argc, (const char**)argv, "noprompt")) { + printf("\nPress ENTER to exit...\n"); + fflush( stdout); + fflush( stderr); + getchar(); + } + exit(EXIT_SUCCESS); +} + +#define MIN(a,b) ((a < b) ? a : b) +#define MAX(a,b) ((a > b) ? a : b) + +// Beginning of GPU Architecture definitions +inline int _ConvertSMVer2Cores_local(int major, int minor) +{ + // Defines for GPU Architecture types (using the SM version to determine the # of cores per SM + typedef struct { + int SM; // 0xMm (hexidecimal notation), M = SM Major version, and m = SM minor version + int Cores; + } sSMtoCores; + + sSMtoCores nGpuArchCoresPerSM[] = + { { 0x10, 8 }, + { 0x11, 8 }, + { 0x12, 8 }, + { 0x13, 8 }, + { 0x20, 32 }, + { 0x21, 48 }, + { -1, -1 } + }; + + int index = 0; + while (nGpuArchCoresPerSM[index].SM != -1) { + if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor) ) { + return nGpuArchCoresPerSM[index].Cores; + } + index++; + } + printf("MapSMtoCores undefined SMversion %d.%d!\n", major, minor); + return -1; +} +// end of GPU Architecture definitions + +// This function returns the best GPU (with maximum GFLOPS) +inline int cutGetMaxGflopsDeviceId() +{ + int current_device = 0, sm_per_multiproc = 0; + int max_compute_perf = 0, max_perf_device = 0; + int device_count = 0, best_SM_arch = 0; + cudaDeviceProp deviceProp; + + cudaGetDeviceCount( &device_count ); + // Find the best major SM Architecture GPU device + while ( current_device < device_count ) { + cudaGetDeviceProperties( &deviceProp, current_device ); + if (deviceProp.major > 0 && deviceProp.major < 9999) { + best_SM_arch = MAX(best_SM_arch, deviceProp.major); + } + current_device++; + } + + // Find the best CUDA capable GPU device + current_device = 0; + while( current_device < device_count ) { + cudaGetDeviceProperties( &deviceProp, current_device ); + if (deviceProp.major == 9999 && deviceProp.minor == 9999) { + sm_per_multiproc = 1; + } else { + sm_per_multiproc = _ConvertSMVer2Cores_local(deviceProp.major, deviceProp.minor); + } + + int compute_perf = deviceProp.multiProcessorCount * sm_per_multiproc * deviceProp.clockRate; + if( compute_perf > max_compute_perf ) { + // If we find GPU with SM major > 2, search only these + if ( best_SM_arch > 2 ) { + // If our device==dest_SM_arch, choose this, or else pass + if (deviceProp.major == best_SM_arch) { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } else { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } + ++current_device; + } + return max_perf_device; +} + +// This function returns the best GPU (with maximum GFLOPS) +inline int cutGetMaxGflopsGraphicsDeviceId() +{ + int current_device = 0, sm_per_multiproc = 0; + int max_compute_perf = 0, max_perf_device = 0; + int device_count = 0, best_SM_arch = 0; + int bTCC = 0; + cudaDeviceProp deviceProp; + + cudaGetDeviceCount( &device_count ); + // Find the best major SM Architecture GPU device that is graphics capable + while ( current_device < device_count ) { + cudaGetDeviceProperties( &deviceProp, current_device ); + +#if CUDA_VERSION >= 3020 + if (deviceProp.tccDriver) bTCC = 1; +#else + // Assume a Tesla GPU is running in TCC if we are running CUDA 3.1 + if (deviceProp.name[0] == 'T') bTCC = 1; +#endif + + if (!bTCC) { + if (deviceProp.major > 0 && deviceProp.major < 9999) { + best_SM_arch = MAX(best_SM_arch, deviceProp.major); + } + } + current_device++; + } + + // Find the best CUDA capable GPU device + current_device = 0; + while( current_device < device_count ) { + cudaGetDeviceProperties( &deviceProp, current_device ); + if (deviceProp.major == 9999 && deviceProp.minor == 9999) { + sm_per_multiproc = 1; + } else { + sm_per_multiproc = _ConvertSMVer2Cores_local(deviceProp.major, deviceProp.minor); + } + +#if CUDA_VERSION >= 3020 + if (deviceProp.tccDriver) bTCC = 1; +#else + // Assume a Tesla GPU is running in TCC if we are running CUDA 3.1 + if (deviceProp.name[0] == 'T') bTCC = 1; +#endif + + if (!bTCC) // Is this GPU running the TCC driver? If so we pass on this + { + int compute_perf = deviceProp.multiProcessorCount * sm_per_multiproc * deviceProp.clockRate; + if( compute_perf > max_compute_perf ) { + // If we find GPU with SM major > 2, search only these + if ( best_SM_arch > 2 ) { + // If our device==dest_SM_arch, choose this, or else pass + if (deviceProp.major == best_SM_arch) { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } else { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } + } + ++current_device; + } + return max_perf_device; +} + +// Give a little more for Windows : the console window often disapears before we can read the message +#ifdef _WIN32 +# if 1//ndef UNICODE +# ifdef _DEBUG // Do this only in debug mode... + inline void VSPrintf(FILE *file, LPCSTR fmt, ...) + { + size_t fmt2_sz = 2048; + char *fmt2 = (char*)malloc(fmt2_sz); + va_list vlist; + va_start(vlist, fmt); + while((_vsnprintf(fmt2, fmt2_sz, fmt, vlist)) < 0) // means there wasn't anough room + { + fmt2_sz *= 2; + if(fmt2) free(fmt2); + fmt2 = (char*)malloc(fmt2_sz); + } + OutputDebugStringA(fmt2); + fprintf(file, fmt2); + free(fmt2); + } +# define FPRINTF(a) VSPrintf a +# else //debug +# define FPRINTF(a) fprintf a +// For other than Win32 +# endif //debug +# else //unicode +// Unicode case... let's give-up for now and keep basic printf +# define FPRINTF(a) fprintf a +# endif //unicode +#else //win32 +# define FPRINTF(a) fprintf a +#endif //win32 + +// NOTE: "%s(%i) : " allows Visual Studio to directly jump to the file at the right line +// when the user double clicks on the error line in the Output pane. Like any compile error. + +inline void __cudaSafeCallNoSync( cudaError err, const char *file, const int line ) +{ + if( cudaSuccess != err) { + FPRINTF((stderr, "%s(%i) : cudaSafeCallNoSync() Runtime API error %d : %s.\n", + file, line, (int)err, cudaGetErrorString( err ) )); + getchar(); + exit(-1); + } +} + +inline void __cudaSafeCall( cudaError err, const char *file, const int line ) +{ + if( cudaSuccess != err) { + FPRINTF((stderr, "%s(%i) : cudaSafeCall() Runtime API error %d: %s.\n", + file, line, (int)err, cudaGetErrorString( err ) )); + getchar(); + exit(-1); + } +} + +inline void __cudaSafeThreadSync( const char *file, const int line ) +{ + cudaError err = cutilDeviceSynchronize(); + if ( cudaSuccess != err) { + FPRINTF((stderr, "%s(%i) : cudaDeviceSynchronize() Runtime API error %d: %s.\n", + file, line, (int)err, cudaGetErrorString( err ) )); + getchar(); + exit(-1); + } +} + +inline void __cufftSafeCall( cufftResult err, const char *file, const int line ) +{ + if( CUFFT_SUCCESS != err) { + FPRINTF((stderr, "%s(%i) : cufftSafeCall() CUFFT error %d: ", + file, line, (int)err)); + switch (err) { + case CUFFT_INVALID_PLAN: FPRINTF((stderr, "CUFFT_INVALID_PLAN\n")); + case CUFFT_ALLOC_FAILED: FPRINTF((stderr, "CUFFT_ALLOC_FAILED\n")); + case CUFFT_INVALID_TYPE: FPRINTF((stderr, "CUFFT_INVALID_TYPE\n")); + case CUFFT_INVALID_VALUE: FPRINTF((stderr, "CUFFT_INVALID_VALUE\n")); + case CUFFT_INTERNAL_ERROR: FPRINTF((stderr, "CUFFT_INTERNAL_ERROR\n")); + case CUFFT_EXEC_FAILED: FPRINTF((stderr, "CUFFT_EXEC_FAILED\n")); + case CUFFT_SETUP_FAILED: FPRINTF((stderr, "CUFFT_SETUP_FAILED\n")); + case CUFFT_INVALID_SIZE: FPRINTF((stderr, "CUFFT_INVALID_SIZE\n")); + case CUFFT_UNALIGNED_DATA: FPRINTF((stderr, "CUFFT_UNALIGNED_DATA\n")); + default: FPRINTF((stderr, "CUFFT Unknown error code\n")); + } + getchar(); + exit(-1); + } +} + +inline void __curandSafeCall( curandStatus_t err, const char *file, const int line ) + { + if( CURAND_STATUS_SUCCESS != err) { + FPRINTF((stderr, "%s(%i) : curandSafeCall() CURAND error %d: ", + file, line, (int)err)); + switch (err) { + case CURAND_STATUS_VERSION_MISMATCH: FPRINTF((stderr, "CURAND_STATUS_VERSION_MISMATCH")); + case CURAND_STATUS_NOT_INITIALIZED: FPRINTF((stderr, "CURAND_STATUS_NOT_INITIALIZED")); + case CURAND_STATUS_ALLOCATION_FAILED: FPRINTF((stderr, "CURAND_STATUS_ALLOCATION_FAILED")); + case CURAND_STATUS_TYPE_ERROR: FPRINTF((stderr, "CURAND_STATUS_TYPE_ERROR")); + case CURAND_STATUS_OUT_OF_RANGE: FPRINTF((stderr, "CURAND_STATUS_OUT_OF_RANGE")); + case CURAND_STATUS_LENGTH_NOT_MULTIPLE: FPRINTF((stderr, "CURAND_STATUS_LENGTH_NOT_MULTIPLE")); + case CURAND_STATUS_DOUBLE_PRECISION_REQUIRED: + FPRINTF((stderr, "CURAND_STATUS_DOUBLE_PRECISION_REQUIRED")); + case CURAND_STATUS_LAUNCH_FAILURE: FPRINTF((stderr, "CURAND_STATUS_LAUNCH_FAILURE")); + case CURAND_STATUS_PREEXISTING_FAILURE: FPRINTF((stderr, "CURAND_STATUS_PREEXISTING_FAILURE")); + case CURAND_STATUS_INITIALIZATION_FAILED: + FPRINTF((stderr, "CURAND_STATUS_INITIALIZATION_FAILED")); + case CURAND_STATUS_ARCH_MISMATCH: FPRINTF((stderr, "CURAND_STATUS_ARCH_MISMATCH")); + case CURAND_STATUS_INTERNAL_ERROR: FPRINTF((stderr, "CURAND_STATUS_INTERNAL_ERROR")); + default: FPRINTF((stderr, "CURAND Unknown error code\n")); + } + getchar(); + exit(-1); + } +} + + +inline void __cutilCheckError( CUTBoolean err, const char *file, const int line ) +{ + if( CUTTrue != err) { + FPRINTF((stderr, "%s(%i) : CUTIL CUDA error.\n", + file, line)); + getchar(); + exit(-1); + } +} + +inline void __cutilGetLastError( const char *errorMessage, const char *file, const int line ) +{ + cudaError_t err = cudaGetLastError(); + if( cudaSuccess != err) { + FPRINTF((stderr, "%s(%i) : cutilCheckMsg() CUTIL CUDA error : %s : (%d) %s.\n", + file, line, errorMessage, (int)err, cudaGetErrorString( err ) )); + getchar(); + exit(-1); + } +} + +inline void __cutilGetLastErrorAndSync( const char *errorMessage, const char *file, const int line ) +{ + cudaError_t err = cudaGetLastError(); + if( cudaSuccess != err) { + FPRINTF((stderr, "%s(%i) : cutilCheckMsg() CUTIL CUDA error : %s : (%d) %s.\n", + file, line, errorMessage, (int)err, cudaGetErrorString( err ) )); + getchar(); + exit(-1); + } + + err = cutilDeviceSynchronize(); + if( cudaSuccess != err) { + FPRINTF((stderr, "%s(%i) : cutilCheckMsg cudaDeviceSynchronize error: %s : (%d) %s.\n", + file, line, errorMessage, (int)err, cudaGetErrorString( err ) )); + getchar(); + exit(-1); + } +} + +inline void __cutilSafeMalloc( void *pointer, const char *file, const int line ) +{ + if( !(pointer)) { + FPRINTF((stderr, "%s(%i) : cutilSafeMalloc host malloc failure\n", + file, line)); + getchar(); + exit(-1); + } +} + +inline int cutilDeviceInit(int ARGC, char **ARGV) +{ + int deviceCount; + cutilSafeCallNoSync(cudaGetDeviceCount(&deviceCount)); + if (deviceCount == 0) { + FPRINTF((stderr, "CUTIL CUDA error: no devices supporting CUDA.\n")); + getchar(); + exit(-1); + } + int dev = 0; + cutGetCmdLineArgumenti(ARGC, (const char **) ARGV, "device", &dev); + if (dev < 0) + dev = 0; + if (dev > deviceCount-1) { + fprintf(stderr, "\n"); + fprintf(stderr, ">> %d CUDA capable GPU device(s) detected. <<\n", deviceCount); + fprintf(stderr, ">> cutilDeviceInit (-device=%d) is not a valid GPU device. <<\n", dev); + fprintf(stderr, "\n"); + return -dev; + } + cudaDeviceProp deviceProp; + cutilSafeCallNoSync(cudaGetDeviceProperties(&deviceProp, dev)); + if (deviceProp.major < 1) { + FPRINTF((stderr, "cutil error: GPU device does not support CUDA.\n")); + getchar(); + exit(-1); \ + } + printf("> Using CUDA device [%d]: %s\n", dev, deviceProp.name); + cutilSafeCall(cudaSetDevice(dev)); + + return dev; +} + +// General initialization call to pick the best CUDA Device +inline int cutilChooseCudaDevice(int argc, char **argv) +{ + cudaDeviceProp deviceProp; + int devID = 0; + // If the command-line has a device number specified, use it + if( cutCheckCmdLineFlag(argc, (const char**)argv, "device") ) { + devID = cutilDeviceInit(argc, argv); + if (devID < 0) { + printf("exiting...\n"); + cutilExit(argc, argv); + exit(0); + } + } else { + // Otherwise pick the device with highest Gflops/s + devID = cutGetMaxGflopsDeviceId(); + cutilSafeCallNoSync( cudaSetDevice( devID ) ); + cutilSafeCallNoSync( cudaGetDeviceProperties(&deviceProp, devID) ); + printf("> Using CUDA device [%d]: %s\n", devID, deviceProp.name); + } + return devID; +} + +//! Check for CUDA context lost +inline void cutilCudaCheckCtxLost(const char *errorMessage, const char *file, const int line ) +{ + cudaError_t err = cudaGetLastError(); + if( cudaSuccess != err) { + FPRINTF((stderr, "%s(%i) : CUDA error: %s : (%d) %s.\n", + file, line, errorMessage, (int)err, cudaGetErrorString( err ) )); + getchar(); + exit(-1); + } + err = cutilDeviceSynchronize(); + if( cudaSuccess != err) { + FPRINTF((stderr, "%s(%i) : CUDA error: %s : (%d) %s.\n", + file, line, errorMessage, (int)err, cudaGetErrorString( err ) )); + getchar(); + exit(-1); + } +} + +#ifndef STRCASECMP +#ifdef _WIN32 +#define STRCASECMP _stricmp +#else +#define STRCASECMP strcasecmp +#endif +#endif + +#ifndef STRNCASECMP +#ifdef _WIN32 +#define STRNCASECMP _strnicmp +#else +#define STRNCASECMP strncasecmp +#endif +#endif + +inline void __cutilQAFinish(int argc, char **argv, bool bStatus) +{ + const char *sStatus[] = { "FAILED", "PASSED", "WAIVED", NULL }; + + bool bFlag = false; + for (int i=1; i < argc; i++) { + if (!STRCASECMP(argv[i], "-qatest") || !STRCASECMP(argv[i], "-noprompt")) { + bFlag |= true; + } + } + + if (bFlag) { + printf("&&&& %s %s", sStatus[bStatus], argv[0]); + for (int i=1; i < argc; i++) printf(" %s", argv[i]); + } else { + printf("[%s] test result\n%s\n", argv[0], sStatus[bStatus]); + } +} + +// General check for CUDA GPU SM Capabilities +inline bool cutilCudaCapabilities(int major_version, int minor_version) +{ + cudaDeviceProp deviceProp; + deviceProp.major = 0; + deviceProp.minor = 0; + int dev; + + cutilSafeCall( cudaGetDevice(&dev) ); + cutilSafeCall( cudaGetDeviceProperties(&deviceProp, dev)); + + if((deviceProp.major > major_version) || + (deviceProp.major == major_version && deviceProp.minor >= minor_version)) + { + printf("> Device %d: <%16s >, Compute SM %d.%d detected\n", dev, deviceProp.name, deviceProp.major, deviceProp.minor); + return true; + } + else + { + printf("No GPU device was found that can support CUDA compute capability %d.%d.\n", major_version, minor_version); + return false; + } +} + +#endif // _CUTIL_INLINE_FUNCTIONS_RUNTIME_H_ diff --git a/external/cutil/inc/cutil_math.h b/external/cutil/inc/cutil_math.h new file mode 100644 index 0000000..8228191 --- /dev/null +++ b/external/cutil/inc/cutil_math.h @@ -0,0 +1,1351 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +/* + This file implements common mathematical operations on vector types + (float3, float4 etc.) since these are not provided as standard by CUDA. + + The syntax is modelled on the Cg standard library. + + This is part of the CUTIL library and is not supported by NVIDIA. + + Thanks to Linh Hah for additions and fixes. +*/ + +#ifndef CUTIL_MATH_H +#define CUTIL_MATH_H + + +//////////////////////////////////////////////////////////////////////////////// +// missing function by matthias +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ int sign(float val) { + return (float(0) < val) - (val < float(0)); +} + +inline __host__ __device__ int4 sign(const float4& v) { + return make_int4(sign(v.x), sign(v.y), sign(v.z), sign(v.w)); +} + +inline __host__ __device__ int3 sign(const float3& v) { + return make_int3(sign(v.x), sign(v.y), sign(v.z)); +} + +inline __host__ __device__ int2 sign(const float2& v) { + return make_int2(sign(v.x), sign(v.y)); +} + +#include "cuda_runtime.h" + +typedef unsigned int uint; +typedef unsigned short ushort; + +#ifndef __CUDACC__ +#include + + +//////////////////////////////////////////////////////////////////////////////// +// host implementations of CUDA functions +//////////////////////////////////////////////////////////////////////////////// + + +inline float fminf(float a, float b) +{ + return a < b ? a : b; +} + +inline float fmaxf(float a, float b) +{ + return a > b ? a : b; +} + +inline int max(int a, int b) +{ + return a > b ? a : b; +} + +inline int min(int a, int b) +{ + return a < b ? a : b; +} + +inline float rsqrtf(float x) +{ + return 1.0f / sqrtf(x); +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +// constructors +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 make_float2(float s) +{ + return make_float2(s, s); +} +inline __host__ __device__ float2 make_float2(float3 a) +{ + return make_float2(a.x, a.y); +} +inline __host__ __device__ float2 make_float2(int2 a) +{ + return make_float2(float(a.x), float(a.y)); +} +inline __host__ __device__ float2 make_float2(uint2 a) +{ + return make_float2(float(a.x), float(a.y)); +} + +inline __host__ __device__ int2 make_int2(int s) +{ + return make_int2(s, s); +} +inline __host__ __device__ int2 make_int2(int3 a) +{ + return make_int2(a.x, a.y); +} +inline __host__ __device__ int2 make_int2(uint2 a) +{ + return make_int2(int(a.x), int(a.y)); +} +inline __host__ __device__ int2 make_int2(float2 a) +{ + return make_int2(int(a.x), int(a.y)); +} + +inline __host__ __device__ uint2 make_uint2(uint s) +{ + return make_uint2(s, s); +} +inline __host__ __device__ uint2 make_uint2(uint3 a) +{ + return make_uint2(a.x, a.y); +} +inline __host__ __device__ uint2 make_uint2(int2 a) +{ + return make_uint2(uint(a.x), uint(a.y)); +} + +inline __host__ __device__ float3 make_float3(float s) +{ + return make_float3(s, s, s); +} +inline __host__ __device__ float3 make_float3(float2 a) +{ + return make_float3(a.x, a.y, 0.0f); +} +inline __host__ __device__ float3 make_float3(float2 a, float s) +{ + return make_float3(a.x, a.y, s); +} +inline __host__ __device__ float3 make_float3(float4 a) +{ + return make_float3(a.x, a.y, a.z); +} +inline __host__ __device__ float3 make_float3(int3 a) +{ + return make_float3(float(a.x), float(a.y), float(a.z)); +} +inline __host__ __device__ float3 make_float3(uint3 a) +{ + return make_float3(float(a.x), float(a.y), float(a.z)); +} + +inline __host__ __device__ int3 make_int3(int s) +{ + return make_int3(s, s, s); +} +inline __host__ __device__ int3 make_int3(int2 a) +{ + return make_int3(a.x, a.y, 0); +} +inline __host__ __device__ int3 make_int3(int2 a, int s) +{ + return make_int3(a.x, a.y, s); +} +inline __host__ __device__ int3 make_int3(uint3 a) +{ + return make_int3(int(a.x), int(a.y), int(a.z)); +} +inline __host__ __device__ int3 make_int3(float3 a) +{ + return make_int3(int(a.x), int(a.y), int(a.z)); +} + +inline __host__ __device__ uint3 make_uint3(uint s) +{ + return make_uint3(s, s, s); +} +inline __host__ __device__ uint3 make_uint3(uint2 a) +{ + return make_uint3(a.x, a.y, 0); +} +inline __host__ __device__ uint3 make_uint3(uint2 a, uint s) +{ + return make_uint3(a.x, a.y, s); +} +inline __host__ __device__ uint3 make_uint3(uint4 a) +{ + return make_uint3(a.x, a.y, a.z); +} +inline __host__ __device__ uint3 make_uint3(int3 a) +{ + return make_uint3(uint(a.x), uint(a.y), uint(a.z)); +} + +inline __host__ __device__ float4 make_float4(float s) +{ + return make_float4(s, s, s, s); +} +inline __host__ __device__ float4 make_float4(float3 a) +{ + return make_float4(a.x, a.y, a.z, 0.0f); +} +inline __host__ __device__ float4 make_float4(float3 a, float w) +{ + return make_float4(a.x, a.y, a.z, w); +} +inline __host__ __device__ float4 make_float4(int4 a) +{ + return make_float4(float(a.x), float(a.y), float(a.z), float(a.w)); +} +inline __host__ __device__ float4 make_float4(uint4 a) +{ + return make_float4(float(a.x), float(a.y), float(a.z), float(a.w)); +} + +inline __host__ __device__ int4 make_int4(int s) +{ + return make_int4(s, s, s, s); +} +inline __host__ __device__ int4 make_int4(int3 a) +{ + return make_int4(a.x, a.y, a.z, 0); +} +inline __host__ __device__ int4 make_int4(int3 a, int w) +{ + return make_int4(a.x, a.y, a.z, w); +} +inline __host__ __device__ int4 make_int4(uint4 a) +{ + return make_int4(int(a.x), int(a.y), int(a.z), int(a.w)); +} +inline __host__ __device__ int4 make_int4(float4 a) +{ + return make_int4(int(a.x), int(a.y), int(a.z), int(a.w)); +} + + +inline __host__ __device__ uint4 make_uint4(uint s) +{ + return make_uint4(s, s, s, s); +} +inline __host__ __device__ uint4 make_uint4(uint3 a) +{ + return make_uint4(a.x, a.y, a.z, 0); +} +inline __host__ __device__ uint4 make_uint4(uint3 a, uint w) +{ + return make_uint4(a.x, a.y, a.z, w); +} +inline __host__ __device__ uint4 make_uint4(int4 a) +{ + return make_uint4(uint(a.x), uint(a.y), uint(a.z), uint(a.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// negate +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 operator-(float2 &a) +{ + return make_float2(-a.x, -a.y); +} +inline __host__ __device__ int2 operator-(int2 &a) +{ + return make_int2(-a.x, -a.y); +} +inline __host__ __device__ float3 operator-(float3 &a) +{ + return make_float3(-a.x, -a.y, -a.z); +} +inline __host__ __device__ int3 operator-(int3 &a) +{ + return make_int3(-a.x, -a.y, -a.z); +} +inline __host__ __device__ float4 operator-(float4 &a) +{ + return make_float4(-a.x, -a.y, -a.z, -a.w); +} +inline __host__ __device__ int4 operator-(int4 &a) +{ + return make_int4(-a.x, -a.y, -a.z, -a.w); +} + +//////////////////////////////////////////////////////////////////////////////// +// addition +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 operator+(float2 a, float2 b) +{ + return make_float2(a.x + b.x, a.y + b.y); +} +inline __host__ __device__ void operator+=(float2 &a, float2 b) +{ + a.x += b.x; a.y += b.y; +} +inline __host__ __device__ float2 operator+(float2 a, float b) +{ + return make_float2(a.x + b, a.y + b); +} +inline __host__ __device__ float2 operator+(float b, float2 a) +{ + return make_float2(a.x + b, a.y + b); +} +inline __host__ __device__ void operator+=(float2 &a, float b) +{ + a.x += b; a.y += b; +} + +inline __host__ __device__ int2 operator+(int2 a, int2 b) +{ + return make_int2(a.x + b.x, a.y + b.y); +} +inline __host__ __device__ void operator+=(int2 &a, int2 b) +{ + a.x += b.x; a.y += b.y; +} +inline __host__ __device__ int2 operator+(int2 a, int b) +{ + return make_int2(a.x + b, a.y + b); +} +inline __host__ __device__ int2 operator+(int b, int2 a) +{ + return make_int2(a.x + b, a.y + b); +} +inline __host__ __device__ void operator+=(int2 &a, int b) +{ + a.x += b; a.y += b; +} + +inline __host__ __device__ uint2 operator+(uint2 a, uint2 b) +{ + return make_uint2(a.x + b.x, a.y + b.y); +} +inline __host__ __device__ void operator+=(uint2 &a, uint2 b) +{ + a.x += b.x; a.y += b.y; +} +inline __host__ __device__ uint2 operator+(uint2 a, uint b) +{ + return make_uint2(a.x + b, a.y + b); +} +inline __host__ __device__ uint2 operator+(uint b, uint2 a) +{ + return make_uint2(a.x + b, a.y + b); +} +inline __host__ __device__ void operator+=(uint2 &a, uint b) +{ + a.x += b; a.y += b; +} + + +inline __host__ __device__ float3 operator+(float3 a, float3 b) +{ + return make_float3(a.x + b.x, a.y + b.y, a.z + b.z); +} +inline __host__ __device__ void operator+=(float3 &a, float3 b) +{ + a.x += b.x; a.y += b.y; a.z += b.z; +} +inline __host__ __device__ float3 operator+(float3 a, float b) +{ + return make_float3(a.x + b, a.y + b, a.z + b); +} +inline __host__ __device__ void operator+=(float3 &a, float b) +{ + a.x += b; a.y += b; a.z += b; +} + +inline __host__ __device__ int3 operator+(int3 a, int3 b) +{ + return make_int3(a.x + b.x, a.y + b.y, a.z + b.z); +} +inline __host__ __device__ void operator+=(int3 &a, int3 b) +{ + a.x += b.x; a.y += b.y; a.z += b.z; +} +inline __host__ __device__ int3 operator+(int3 a, int b) +{ + return make_int3(a.x + b, a.y + b, a.z + b); +} +inline __host__ __device__ void operator+=(int3 &a, int b) +{ + a.x += b; a.y += b; a.z += b; +} + +inline __host__ __device__ uint3 operator+(uint3 a, uint3 b) +{ + return make_uint3(a.x + b.x, a.y + b.y, a.z + b.z); +} +inline __host__ __device__ void operator+=(uint3 &a, uint3 b) +{ + a.x += b.x; a.y += b.y; a.z += b.z; +} +inline __host__ __device__ uint3 operator+(uint3 a, uint b) +{ + return make_uint3(a.x + b, a.y + b, a.z + b); +} +inline __host__ __device__ void operator+=(uint3 &a, uint b) +{ + a.x += b; a.y += b; a.z += b; +} + +inline __host__ __device__ int3 operator+(int b, int3 a) +{ + return make_int3(a.x + b, a.y + b, a.z + b); +} +inline __host__ __device__ uint3 operator+(uint b, uint3 a) +{ + return make_uint3(a.x + b, a.y + b, a.z + b); +} +inline __host__ __device__ float3 operator+(float b, float3 a) +{ + return make_float3(a.x + b, a.y + b, a.z + b); +} + +inline __host__ __device__ float4 operator+(float4 a, float4 b) +{ + return make_float4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); +} +inline __host__ __device__ void operator+=(float4 &a, float4 b) +{ + a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w; +} +inline __host__ __device__ float4 operator+(float4 a, float b) +{ + return make_float4(a.x + b, a.y + b, a.z + b, a.w + b); +} +inline __host__ __device__ float4 operator+(float b, float4 a) +{ + return make_float4(a.x + b, a.y + b, a.z + b, a.w + b); +} +inline __host__ __device__ void operator+=(float4 &a, float b) +{ + a.x += b; a.y += b; a.z += b; a.w += b; +} + +inline __host__ __device__ int4 operator+(int4 a, int4 b) +{ + return make_int4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); +} +inline __host__ __device__ void operator+=(int4 &a, int4 b) +{ + a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w; +} +inline __host__ __device__ int4 operator+(int4 a, int b) +{ + return make_int4(a.x + b, a.y + b, a.z + b, a.w + b); +} +inline __host__ __device__ int4 operator+(int b, int4 a) +{ + return make_int4(a.x + b, a.y + b, a.z + b, a.w + b); +} +inline __host__ __device__ void operator+=(int4 &a, int b) +{ + a.x += b; a.y += b; a.z += b; a.w += b; +} + +inline __host__ __device__ uint4 operator+(uint4 a, uint4 b) +{ + return make_uint4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); +} +inline __host__ __device__ void operator+=(uint4 &a, uint4 b) +{ + a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w; +} +inline __host__ __device__ uint4 operator+(uint4 a, uint b) +{ + return make_uint4(a.x + b, a.y + b, a.z + b, a.w + b); +} +inline __host__ __device__ uint4 operator+(uint b, uint4 a) +{ + return make_uint4(a.x + b, a.y + b, a.z + b, a.w + b); +} +inline __host__ __device__ void operator+=(uint4 &a, uint b) +{ + a.x += b; a.y += b; a.z += b; a.w += b; +} + +//////////////////////////////////////////////////////////////////////////////// +// subtract +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 operator-(float2 a, float2 b) +{ + return make_float2(a.x - b.x, a.y - b.y); +} +inline __host__ __device__ void operator-=(float2 &a, float2 b) +{ + a.x -= b.x; a.y -= b.y; +} +inline __host__ __device__ float2 operator-(float2 a, float b) +{ + return make_float2(a.x - b, a.y - b); +} +inline __host__ __device__ float2 operator-(float b, float2 a) +{ + return make_float2(b - a.x, b - a.y); +} +inline __host__ __device__ void operator-=(float2 &a, float b) +{ + a.x -= b; a.y -= b; +} + +inline __host__ __device__ int2 operator-(int2 a, int2 b) +{ + return make_int2(a.x - b.x, a.y - b.y); +} +inline __host__ __device__ void operator-=(int2 &a, int2 b) +{ + a.x -= b.x; a.y -= b.y; +} +inline __host__ __device__ int2 operator-(int2 a, int b) +{ + return make_int2(a.x - b, a.y - b); +} +inline __host__ __device__ int2 operator-(int b, int2 a) +{ + return make_int2(b - a.x, b - a.y); +} +inline __host__ __device__ void operator-=(int2 &a, int b) +{ + a.x -= b; a.y -= b; +} + +inline __host__ __device__ uint2 operator-(uint2 a, uint2 b) +{ + return make_uint2(a.x - b.x, a.y - b.y); +} +inline __host__ __device__ void operator-=(uint2 &a, uint2 b) +{ + a.x -= b.x; a.y -= b.y; +} +inline __host__ __device__ uint2 operator-(uint2 a, uint b) +{ + return make_uint2(a.x - b, a.y - b); +} +inline __host__ __device__ uint2 operator-(uint b, uint2 a) +{ + return make_uint2(b - a.x, b - a.y); +} +inline __host__ __device__ void operator-=(uint2 &a, uint b) +{ + a.x -= b; a.y -= b; +} + +inline __host__ __device__ float3 operator-(float3 a, float3 b) +{ + return make_float3(a.x - b.x, a.y - b.y, a.z - b.z); +} +inline __host__ __device__ void operator-=(float3 &a, float3 b) +{ + a.x -= b.x; a.y -= b.y; a.z -= b.z; +} +inline __host__ __device__ float3 operator-(float3 a, float b) +{ + return make_float3(a.x - b, a.y - b, a.z - b); +} +inline __host__ __device__ float3 operator-(float b, float3 a) +{ + return make_float3(b - a.x, b - a.y, b - a.z); +} +inline __host__ __device__ void operator-=(float3 &a, float b) +{ + a.x -= b; a.y -= b; a.z -= b; +} + +inline __host__ __device__ int3 operator-(int3 a, int3 b) +{ + return make_int3(a.x - b.x, a.y - b.y, a.z - b.z); +} +inline __host__ __device__ void operator-=(int3 &a, int3 b) +{ + a.x -= b.x; a.y -= b.y; a.z -= b.z; +} +inline __host__ __device__ int3 operator-(int3 a, int b) +{ + return make_int3(a.x - b, a.y - b, a.z - b); +} +inline __host__ __device__ int3 operator-(int b, int3 a) +{ + return make_int3(b - a.x, b - a.y, b - a.z); +} +inline __host__ __device__ void operator-=(int3 &a, int b) +{ + a.x -= b; a.y -= b; a.z -= b; +} + +inline __host__ __device__ uint3 operator-(uint3 a, uint3 b) +{ + return make_uint3(a.x - b.x, a.y - b.y, a.z - b.z); +} +inline __host__ __device__ void operator-=(uint3 &a, uint3 b) +{ + a.x -= b.x; a.y -= b.y; a.z -= b.z; +} +inline __host__ __device__ uint3 operator-(uint3 a, uint b) +{ + return make_uint3(a.x - b, a.y - b, a.z - b); +} +inline __host__ __device__ uint3 operator-(uint b, uint3 a) +{ + return make_uint3(b - a.x, b - a.y, b - a.z); +} +inline __host__ __device__ void operator-=(uint3 &a, uint b) +{ + a.x -= b; a.y -= b; a.z -= b; +} + +inline __host__ __device__ float4 operator-(float4 a, float4 b) +{ + return make_float4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); +} +inline __host__ __device__ void operator-=(float4 &a, float4 b) +{ + a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w; +} +inline __host__ __device__ float4 operator-(float4 a, float b) +{ + return make_float4(a.x - b, a.y - b, a.z - b, a.w - b); +} +inline __host__ __device__ void operator-=(float4 &a, float b) +{ + a.x -= b; a.y -= b; a.z -= b; a.w -= b; +} + +inline __host__ __device__ int4 operator-(int4 a, int4 b) +{ + return make_int4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); +} +inline __host__ __device__ void operator-=(int4 &a, int4 b) +{ + a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w; +} +inline __host__ __device__ int4 operator-(int4 a, int b) +{ + return make_int4(a.x - b, a.y - b, a.z - b, a.w - b); +} +inline __host__ __device__ int4 operator-(int b, int4 a) +{ + return make_int4(b - a.x, b - a.y, b - a.z, b - a.w); +} +inline __host__ __device__ void operator-=(int4 &a, int b) +{ + a.x -= b; a.y -= b; a.z -= b; a.w -= b; +} + +inline __host__ __device__ uint4 operator-(uint4 a, uint4 b) +{ + return make_uint4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); +} +inline __host__ __device__ void operator-=(uint4 &a, uint4 b) +{ + a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w; +} +inline __host__ __device__ uint4 operator-(uint4 a, uint b) +{ + return make_uint4(a.x - b, a.y - b, a.z - b, a.w - b); +} +inline __host__ __device__ uint4 operator-(uint b, uint4 a) +{ + return make_uint4(b - a.x, b - a.y, b - a.z, b - a.w); +} +inline __host__ __device__ void operator-=(uint4 &a, uint b) +{ + a.x -= b; a.y -= b; a.z -= b; a.w -= b; +} + +//////////////////////////////////////////////////////////////////////////////// +// multiply +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 operator*(float2 a, float2 b) +{ + return make_float2(a.x * b.x, a.y * b.y); +} +inline __host__ __device__ void operator*=(float2 &a, float2 b) +{ + a.x *= b.x; a.y *= b.y; +} +inline __host__ __device__ float2 operator*(float2 a, float b) +{ + return make_float2(a.x * b, a.y * b); +} +inline __host__ __device__ float2 operator*(float b, float2 a) +{ + return make_float2(b * a.x, b * a.y); +} +inline __host__ __device__ void operator*=(float2 &a, float b) +{ + a.x *= b; a.y *= b; +} + +inline __host__ __device__ int2 operator*(int2 a, int2 b) +{ + return make_int2(a.x * b.x, a.y * b.y); +} +inline __host__ __device__ void operator*=(int2 &a, int2 b) +{ + a.x *= b.x; a.y *= b.y; +} +inline __host__ __device__ int2 operator*(int2 a, int b) +{ + return make_int2(a.x * b, a.y * b); +} +inline __host__ __device__ int2 operator*(int b, int2 a) +{ + return make_int2(b * a.x, b * a.y); +} +inline __host__ __device__ void operator*=(int2 &a, int b) +{ + a.x *= b; a.y *= b; +} + +inline __host__ __device__ uint2 operator*(uint2 a, uint2 b) +{ + return make_uint2(a.x * b.x, a.y * b.y); +} +inline __host__ __device__ void operator*=(uint2 &a, uint2 b) +{ + a.x *= b.x; a.y *= b.y; +} +inline __host__ __device__ uint2 operator*(uint2 a, uint b) +{ + return make_uint2(a.x * b, a.y * b); +} +inline __host__ __device__ uint2 operator*(uint b, uint2 a) +{ + return make_uint2(b * a.x, b * a.y); +} +inline __host__ __device__ void operator*=(uint2 &a, uint b) +{ + a.x *= b; a.y *= b; +} + +inline __host__ __device__ float3 operator*(float3 a, float3 b) +{ + return make_float3(a.x * b.x, a.y * b.y, a.z * b.z); +} +inline __host__ __device__ void operator*=(float3 &a, float3 b) +{ + a.x *= b.x; a.y *= b.y; a.z *= b.z; +} +inline __host__ __device__ float3 operator*(float3 a, float b) +{ + return make_float3(a.x * b, a.y * b, a.z * b); +} +inline __host__ __device__ float3 operator*(float b, float3 a) +{ + return make_float3(b * a.x, b * a.y, b * a.z); +} +inline __host__ __device__ void operator*=(float3 &a, float b) +{ + a.x *= b; a.y *= b; a.z *= b; +} + +inline __host__ __device__ int3 operator*(int3 a, int3 b) +{ + return make_int3(a.x * b.x, a.y * b.y, a.z * b.z); +} +inline __host__ __device__ void operator*=(int3 &a, int3 b) +{ + a.x *= b.x; a.y *= b.y; a.z *= b.z; +} +inline __host__ __device__ int3 operator*(int3 a, int b) +{ + return make_int3(a.x * b, a.y * b, a.z * b); +} +inline __host__ __device__ int3 operator*(int b, int3 a) +{ + return make_int3(b * a.x, b * a.y, b * a.z); +} +inline __host__ __device__ void operator*=(int3 &a, int b) +{ + a.x *= b; a.y *= b; a.z *= b; +} + +inline __host__ __device__ uint3 operator*(uint3 a, uint3 b) +{ + return make_uint3(a.x * b.x, a.y * b.y, a.z * b.z); +} +inline __host__ __device__ void operator*=(uint3 &a, uint3 b) +{ + a.x *= b.x; a.y *= b.y; a.z *= b.z; +} +inline __host__ __device__ uint3 operator*(uint3 a, uint b) +{ + return make_uint3(a.x * b, a.y * b, a.z * b); +} +inline __host__ __device__ uint3 operator*(uint b, uint3 a) +{ + return make_uint3(b * a.x, b * a.y, b * a.z); +} +inline __host__ __device__ void operator*=(uint3 &a, uint b) +{ + a.x *= b; a.y *= b; a.z *= b; +} + +inline __host__ __device__ float4 operator*(float4 a, float4 b) +{ + return make_float4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); +} +inline __host__ __device__ void operator*=(float4 &a, float4 b) +{ + a.x *= b.x; a.y *= b.y; a.z *= b.z; a.w *= b.w; +} +inline __host__ __device__ float4 operator*(float4 a, float b) +{ + return make_float4(a.x * b, a.y * b, a.z * b, a.w * b); +} +inline __host__ __device__ float4 operator*(float b, float4 a) +{ + return make_float4(b * a.x, b * a.y, b * a.z, b * a.w); +} +inline __host__ __device__ void operator*=(float4 &a, float b) +{ + a.x *= b; a.y *= b; a.z *= b; a.w *= b; +} + +inline __host__ __device__ int4 operator*(int4 a, int4 b) +{ + return make_int4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); +} +inline __host__ __device__ void operator*=(int4 &a, int4 b) +{ + a.x *= b.x; a.y *= b.y; a.z *= b.z; a.w *= b.w; +} +inline __host__ __device__ int4 operator*(int4 a, int b) +{ + return make_int4(a.x * b, a.y * b, a.z * b, a.w * b); +} +inline __host__ __device__ int4 operator*(int b, int4 a) +{ + return make_int4(b * a.x, b * a.y, b * a.z, b * a.w); +} +inline __host__ __device__ void operator*=(int4 &a, int b) +{ + a.x *= b; a.y *= b; a.z *= b; a.w *= b; +} + +inline __host__ __device__ uint4 operator*(uint4 a, uint4 b) +{ + return make_uint4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); +} +inline __host__ __device__ void operator*=(uint4 &a, uint4 b) +{ + a.x *= b.x; a.y *= b.y; a.z *= b.z; a.w *= b.w; +} +inline __host__ __device__ uint4 operator*(uint4 a, uint b) +{ + return make_uint4(a.x * b, a.y * b, a.z * b, a.w * b); +} +inline __host__ __device__ uint4 operator*(uint b, uint4 a) +{ + return make_uint4(b * a.x, b * a.y, b * a.z, b * a.w); +} +inline __host__ __device__ void operator*=(uint4 &a, uint b) +{ + a.x *= b; a.y *= b; a.z *= b; a.w *= b; +} + +//////////////////////////////////////////////////////////////////////////////// +// divide +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 operator/(float2 a, float2 b) +{ + return make_float2(a.x / b.x, a.y / b.y); +} +inline __host__ __device__ void operator/=(float2 &a, float2 b) +{ + a.x /= b.x; a.y /= b.y; +} +inline __host__ __device__ float2 operator/(float2 a, float b) +{ + return make_float2(a.x / b, a.y / b); +} +inline __host__ __device__ void operator/=(float2 &a, float b) +{ + a.x /= b; a.y /= b; +} +inline __host__ __device__ float2 operator/(float b, float2 a) +{ + return make_float2(b / a.x, b / a.y); +} + +inline __host__ __device__ float3 operator/(float3 a, float3 b) +{ + return make_float3(a.x / b.x, a.y / b.y, a.z / b.z); +} +inline __host__ __device__ void operator/=(float3 &a, float3 b) +{ + a.x /= b.x; a.y /= b.y; a.z /= b.z; +} +inline __host__ __device__ float3 operator/(float3 a, float b) +{ + return make_float3(a.x / b, a.y / b, a.z / b); +} +inline __host__ __device__ void operator/=(float3 &a, float b) +{ + a.x /= b; a.y /= b; a.z /= b; +} +inline __host__ __device__ float3 operator/(float b, float3 a) +{ + return make_float3(b / a.x, b / a.y, b / a.z); +} + +inline __host__ __device__ float4 operator/(float4 a, float4 b) +{ + return make_float4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); +} +inline __host__ __device__ void operator/=(float4 &a, float4 b) +{ + a.x /= b.x; a.y /= b.y; a.z /= b.z; a.w /= b.w; +} +inline __host__ __device__ float4 operator/(float4 a, float b) +{ + return make_float4(a.x / b, a.y / b, a.z / b, a.w / b); +} +inline __host__ __device__ void operator/=(float4 &a, float b) +{ + a.x /= b; a.y /= b; a.z /= b; a.w /= b; +} +inline __host__ __device__ float4 operator/(float b, float4 a){ + return make_float4(b / a.x, b / a.y, b / a.z, b / a.w); +} + +//////////////////////////////////////////////////////////////////////////////// +// min +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 fminf(float2 a, float2 b) +{ + return make_float2(fminf(a.x,b.x), fminf(a.y,b.y)); +} +inline __host__ __device__ float3 fminf(float3 a, float3 b) +{ + return make_float3(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z)); +} +inline __host__ __device__ float4 fminf(float4 a, float4 b) +{ + return make_float4(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z), fminf(a.w,b.w)); +} + +inline __host__ __device__ int2 min(int2 a, int2 b) +{ + return make_int2(min(a.x,b.x), min(a.y,b.y)); +} +inline __host__ __device__ int3 min(int3 a, int3 b) +{ + return make_int3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z)); +} +inline __host__ __device__ int4 min(int4 a, int4 b) +{ + return make_int4(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z), min(a.w,b.w)); +} + +inline __host__ __device__ uint2 min(uint2 a, uint2 b) +{ + return make_uint2(min(a.x,b.x), min(a.y,b.y)); +} +inline __host__ __device__ uint3 min(uint3 a, uint3 b) +{ + return make_uint3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z)); +} +inline __host__ __device__ uint4 min(uint4 a, uint4 b) +{ + return make_uint4(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z), min(a.w,b.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// max +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 fmaxf(float2 a, float2 b) +{ + return make_float2(fmaxf(a.x,b.x), fmaxf(a.y,b.y)); +} +inline __host__ __device__ float3 fmaxf(float3 a, float3 b) +{ + return make_float3(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z)); +} +inline __host__ __device__ float4 fmaxf(float4 a, float4 b) +{ + return make_float4(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z), fmaxf(a.w,b.w)); +} + +inline __host__ __device__ int2 max(int2 a, int2 b) +{ + return make_int2(max(a.x,b.x), max(a.y,b.y)); +} +inline __host__ __device__ int3 max(int3 a, int3 b) +{ + return make_int3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z)); +} +inline __host__ __device__ int4 max(int4 a, int4 b) +{ + return make_int4(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z), max(a.w,b.w)); +} + +inline __host__ __device__ uint2 max(uint2 a, uint2 b) +{ + return make_uint2(max(a.x,b.x), max(a.y,b.y)); +} +inline __host__ __device__ uint3 max(uint3 a, uint3 b) +{ + return make_uint3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z)); +} +inline __host__ __device__ uint4 max(uint4 a, uint4 b) +{ + return make_uint4(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z), max(a.w,b.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// lerp +// - linear interpolation between a and b, based on value t in [0, 1] range +//////////////////////////////////////////////////////////////////////////////// + +inline __device__ __host__ float lerp(float a, float b, float t) +{ + return a + t*(b-a); +} +inline __device__ __host__ float2 lerp(float2 a, float2 b, float t) +{ + return a + t*(b-a); +} +inline __device__ __host__ float3 lerp(float3 a, float3 b, float t) +{ + return a + t*(b-a); +} +inline __device__ __host__ float4 lerp(float4 a, float4 b, float t) +{ + return a + t*(b-a); +} + +//////////////////////////////////////////////////////////////////////////////// +// clamp +// - clamp the value v to be in the range [a, b] +//////////////////////////////////////////////////////////////////////////////// + +inline __device__ __host__ float clamp(float f, float a, float b) +{ + return fmaxf(a, fminf(f, b)); +} +inline __device__ __host__ int clamp(int f, int a, int b) +{ + return max(a, min(f, b)); +} +inline __device__ __host__ uint clamp(uint f, uint a, uint b) +{ + return max(a, min(f, b)); +} + +inline __device__ __host__ float2 clamp(float2 v, float a, float b) +{ + return make_float2(clamp(v.x, a, b), clamp(v.y, a, b)); +} +inline __device__ __host__ float2 clamp(float2 v, float2 a, float2 b) +{ + return make_float2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y)); +} +inline __device__ __host__ float3 clamp(float3 v, float a, float b) +{ + return make_float3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b)); +} +inline __device__ __host__ float3 clamp(float3 v, float3 a, float3 b) +{ + return make_float3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z)); +} +inline __device__ __host__ float4 clamp(float4 v, float a, float b) +{ + return make_float4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b)); +} +inline __device__ __host__ float4 clamp(float4 v, float4 a, float4 b) +{ + return make_float4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w)); +} + +inline __device__ __host__ int2 clamp(int2 v, int a, int b) +{ + return make_int2(clamp(v.x, a, b), clamp(v.y, a, b)); +} +inline __device__ __host__ int2 clamp(int2 v, int2 a, int2 b) +{ + return make_int2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y)); +} +inline __device__ __host__ int3 clamp(int3 v, int a, int b) +{ + return make_int3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b)); +} +inline __device__ __host__ int3 clamp(int3 v, int3 a, int3 b) +{ + return make_int3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z)); +} +inline __device__ __host__ int4 clamp(int4 v, int a, int b) +{ + return make_int4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b)); +} +inline __device__ __host__ int4 clamp(int4 v, int4 a, int4 b) +{ + return make_int4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w)); +} + +inline __device__ __host__ uint2 clamp(uint2 v, uint a, uint b) +{ + return make_uint2(clamp(v.x, a, b), clamp(v.y, a, b)); +} +inline __device__ __host__ uint2 clamp(uint2 v, uint2 a, uint2 b) +{ + return make_uint2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y)); +} +inline __device__ __host__ uint3 clamp(uint3 v, uint a, uint b) +{ + return make_uint3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b)); +} +inline __device__ __host__ uint3 clamp(uint3 v, uint3 a, uint3 b) +{ + return make_uint3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z)); +} +inline __device__ __host__ uint4 clamp(uint4 v, uint a, uint b) +{ + return make_uint4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b)); +} +inline __device__ __host__ uint4 clamp(uint4 v, uint4 a, uint4 b) +{ + return make_uint4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// dot product +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float dot(float2 a, float2 b) +{ + return a.x * b.x + a.y * b.y; +} +inline __host__ __device__ float dot(float3 a, float3 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} +inline __host__ __device__ float dot(float4 a, float4 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +} + +inline __host__ __device__ int dot(int2 a, int2 b) +{ + return a.x * b.x + a.y * b.y; +} +inline __host__ __device__ int dot(int3 a, int3 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} +inline __host__ __device__ int dot(int4 a, int4 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +} + +inline __host__ __device__ uint dot(uint2 a, uint2 b) +{ + return a.x * b.x + a.y * b.y; +} +inline __host__ __device__ uint dot(uint3 a, uint3 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} +inline __host__ __device__ uint dot(uint4 a, uint4 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +} + +//////////////////////////////////////////////////////////////////////////////// +// length +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float length(float2 v) +{ + return sqrtf(dot(v, v)); +} +inline __host__ __device__ float length(float3 v) +{ + return sqrtf(dot(v, v)); +} +inline __host__ __device__ float length(float4 v) +{ + return sqrtf(dot(v, v)); +} + +//////////////////////////////////////////////////////////////////////////////// +// normalize +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 normalize(float2 v) +{ + float invLen = rsqrtf(dot(v, v)); + return v * invLen; +} +inline __host__ __device__ float3 normalize(float3 v) +{ + float invLen = rsqrtf(dot(v, v)); + return v * invLen; +} +inline __host__ __device__ float4 normalize(float4 v) +{ + float invLen = rsqrtf(dot(v, v)); + return v * invLen; +} + +//////////////////////////////////////////////////////////////////////////////// +// floor +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 floorf(float2 v) +{ + return make_float2(floorf(v.x), floorf(v.y)); +} +inline __host__ __device__ float3 floorf(float3 v) +{ + return make_float3(floorf(v.x), floorf(v.y), floorf(v.z)); +} +inline __host__ __device__ float4 floorf(float4 v) +{ + return make_float4(floorf(v.x), floorf(v.y), floorf(v.z), floorf(v.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// frac - returns the fractional portion of a scalar or each vector component +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float fracf(float v) +{ + return v - floorf(v); +} +inline __host__ __device__ float2 fracf(float2 v) +{ + return make_float2(fracf(v.x), fracf(v.y)); +} +inline __host__ __device__ float3 fracf(float3 v) +{ + return make_float3(fracf(v.x), fracf(v.y), fracf(v.z)); +} +inline __host__ __device__ float4 fracf(float4 v) +{ + return make_float4(fracf(v.x), fracf(v.y), fracf(v.z), fracf(v.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// fmod +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 fmodf(float2 a, float2 b) +{ + return make_float2(fmodf(a.x, b.x), fmodf(a.y, b.y)); +} +inline __host__ __device__ float3 fmodf(float3 a, float3 b) +{ + return make_float3(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z)); +} +inline __host__ __device__ float4 fmodf(float4 a, float4 b) +{ + return make_float4(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z), fmodf(a.w, b.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// absolute value +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 fabs(float2 v) +{ + return make_float2(fabs(v.x), fabs(v.y)); +} +inline __host__ __device__ float3 fabs(float3 v) +{ + return make_float3(fabs(v.x), fabs(v.y), fabs(v.z)); +} +inline __host__ __device__ float4 fabs(float4 v) +{ + return make_float4(fabs(v.x), fabs(v.y), fabs(v.z), fabs(v.w)); +} + +inline __host__ __device__ int2 abs(int2 v) +{ + return make_int2(abs(v.x), abs(v.y)); +} +inline __host__ __device__ int3 abs(int3 v) +{ + return make_int3(abs(v.x), abs(v.y), abs(v.z)); +} +inline __host__ __device__ int4 abs(int4 v) +{ + return make_int4(abs(v.x), abs(v.y), abs(v.z), abs(v.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// reflect +// - returns reflection of incident ray I around surface normal N +// - N should be normalized, reflected vector's length is equal to length of I +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float3 reflect(float3 i, float3 n) +{ + return i - 2.0f * n * dot(n,i); +} + +//////////////////////////////////////////////////////////////////////////////// +// cross product +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float3 cross(float3 a, float3 b) +{ + return make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); +} + +//////////////////////////////////////////////////////////////////////////////// +// smoothstep +// - returns 0 if x < a +// - returns 1 if x > b +// - otherwise returns smooth interpolation between 0 and 1 based on x +//////////////////////////////////////////////////////////////////////////////// + +inline __device__ __host__ float smoothstep(float a, float b, float x) +{ + float y = clamp((x - a) / (b - a), 0.0f, 1.0f); + return (y*y*(3.0f - (2.0f*y))); +} +inline __device__ __host__ float2 smoothstep(float2 a, float2 b, float2 x) +{ + float2 y = clamp((x - a) / (b - a), 0.0f, 1.0f); + return (y*y*(make_float2(3.0f) - (make_float2(2.0f)*y))); +} +inline __device__ __host__ float3 smoothstep(float3 a, float3 b, float3 x) +{ + float3 y = clamp((x - a) / (b - a), 0.0f, 1.0f); + return (y*y*(make_float3(3.0f) - (make_float3(2.0f)*y))); +} +inline __device__ __host__ float4 smoothstep(float4 a, float4 b, float4 x) +{ + float4 y = clamp((x - a) / (b - a), 0.0f, 1.0f); + return (y*y*(make_float4(3.0f) - (make_float4(2.0f)*y))); +} + +#endif diff --git a/external/cutil/inc/drvapi_error_string.h b/external/cutil/inc/drvapi_error_string.h new file mode 100644 index 0000000..d7761fd --- /dev/null +++ b/external/cutil/inc/drvapi_error_string.h @@ -0,0 +1,332 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +#ifndef _DRVAPI_ERROR_STRING_H_ +#define _DRVAPI_ERROR_STRING_H_ + +#include +#include +#include + +// Error Code string definitions here +typedef struct +{ + char const *error_string; + int error_id; +} s_CudaErrorStr; + +/** + * Error codes + */ +static s_CudaErrorStr sCudaDrvErrorString[] = +{ + /** + * The API call returned with no errors. In the case of query calls, this + * can also mean that the operation being queried is complete (see + * ::cuEventQuery() and ::cuStreamQuery()). + */ + { "CUDA_SUCCESS", 0 }, + + /** + * This indicates that one or more of the parameters passed to the API call + * is not within an acceptable range of values. + */ + { "CUDA_ERROR_INVALID_VALUE", 1 }, + + /** + * The API call failed because it was unable to allocate enough memory to + * perform the requested operation. + */ + { "CUDA_ERROR_OUT_OF_MEMORY", 2 }, + + /** + * This indicates that the CUDA driver has not been initialized with + * ::cuInit() or that initialization has failed. + */ + { "CUDA_ERROR_NOT_INITIALIZED", 3 }, + + /** + * This indicates that the CUDA driver is in the process of shutting down. + */ + { "CUDA_ERROR_DEINITIALIZED", 4 }, + + /** + * This indicates profiling APIs are called while application is running + * in visual profiler mode. + */ + { "CUDA_ERROR_PROFILER_DISABLED", 5 }, + /** + * This indicates profiling has not been initialized for this context. + * Call cuProfilerInitialize() to resolve this. + */ + { "CUDA_ERROR_PROFILER_NOT_INITIALIZED", 6 }, + /** + * This indicates profiler has already been started and probably + * cuProfilerStart() is incorrectly called. + */ + { "CUDA_ERROR_PROFILER_ALREADY_STARTED", 7 }, + /** + * This indicates profiler has already been stopped and probably + * cuProfilerStop() is incorrectly called. + */ + { "CUDA_ERROR_PROFILER_ALREADY_STOPPED", 8 }, + /** + * This indicates that no CUDA-capable devices were detected by the installed + * CUDA driver. + */ + { "CUDA_ERROR_NO_DEVICE (no CUDA-capable devices were detected)", 100 }, + + /** + * This indicates that the device ordinal supplied by the user does not + * correspond to a valid CUDA device. + */ + { "CUDA_ERROR_INVALID_DEVICE (device specified is not a valid CUDA device)", 101 }, + + + /** + * This indicates that the device kernel image is invalid. This can also + * indicate an invalid CUDA module. + */ + { "CUDA_ERROR_INVALID_IMAGE", 200 }, + + /** + * This most frequently indicates that there is no context bound to the + * current thread. This can also be returned if the context passed to an + * API call is not a valid handle (such as a context that has had + * ::cuCtxDestroy() invoked on it). This can also be returned if a user + * mixes different API versions (i.e. 3010 context with 3020 API calls). + * See ::cuCtxGetApiVersion() for more details. + */ + { "CUDA_ERROR_INVALID_CONTEXT", 201 }, + + /** + * This indicated that the context being supplied as a parameter to the + * API call was already the active context. + * \deprecated + * This error return is deprecated as of CUDA 3.2. It is no longer an + * error to attempt to push the active context via ::cuCtxPushCurrent(). + */ + { "CUDA_ERROR_CONTEXT_ALREADY_CURRENT", 202 }, + + /** + * This indicates that a map or register operation has failed. + */ + { "CUDA_ERROR_MAP_FAILED", 205 }, + + /** + * This indicates that an unmap or unregister operation has failed. + */ + { "CUDA_ERROR_UNMAP_FAILED", 206 }, + + /** + * This indicates that the specified array is currently mapped and thus + * cannot be destroyed. + */ + { "CUDA_ERROR_ARRAY_IS_MAPPED", 207 }, + + /** + * This indicates that the resource is already mapped. + */ + { "CUDA_ERROR_ALREADY_MAPPED", 208 }, + + /** + * This indicates that there is no kernel image available that is suitable + * for the device. This can occur when a user specifies code generation + * options for a particular CUDA source file that do not include the + * corresponding device configuration. + */ + { "CUDA_ERROR_NO_BINARY_FOR_GPU", 209 }, + + /** + * This indicates that a resource has already been acquired. + */ + { "CUDA_ERROR_ALREADY_ACQUIRED", 210 }, + + /** + * This indicates that a resource is not mapped. + */ + { "CUDA_ERROR_NOT_MAPPED", 211 }, + + /** + * This indicates that a mapped resource is not available for access as an + * array. + */ + { "CUDA_ERROR_NOT_MAPPED_AS_ARRAY", 212 }, + + /** + * This indicates that a mapped resource is not available for access as a + * pointer. + */ + { "CUDA_ERROR_NOT_MAPPED_AS_POINTER", 213 }, + + /** + * This indicates that an uncorrectable ECC error was detected during + * execution. + */ + { "CUDA_ERROR_ECC_UNCORRECTABLE", 214 }, + + /** + * This indicates that the ::CUlimit passed to the API call is not + * supported by the active device. + */ + { "CUDA_ERROR_UNSUPPORTED_LIMIT", 215 }, + + /** + * This indicates that the ::CUcontext passed to the API call can + * only be bound to a single CPU thread at a time but is already + * bound to a CPU thread. + */ + { "CUDA_ERROR_CONTEXT_ALREADY_IN_USE", 216 }, + + /** + * This indicates that the device kernel source is invalid. + */ + { "CUDA_ERROR_INVALID_SOURCE", 300 }, + + /** + * This indicates that the file specified was not found. + */ + { "CUDA_ERROR_FILE_NOT_FOUND", 301 }, + + /** + * This indicates that a link to a shared object failed to resolve. + */ + { "CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND", 302 }, + + /** + * This indicates that initialization of a shared object failed. + */ + { "CUDA_ERROR_SHARED_OBJECT_INIT_FAILED", 303 }, + + /** + * This indicates that an OS call failed. + */ + { "CUDA_ERROR_OPERATING_SYSTEM", 304 }, + + + /** + * This indicates that a resource handle passed to the API call was not + * valid. Resource handles are opaque types like ::CUstream and ::CUevent. + */ + { "CUDA_ERROR_INVALID_HANDLE", 400 }, + + + /** + * This indicates that a named symbol was not found. Examples of symbols + * are global/constant variable names, texture names }, and surface names. + */ + { "CUDA_ERROR_NOT_FOUND", 500 }, + + + /** + * This indicates that asynchronous operations issued previously have not + * completed yet. This result is not actually an error, but must be indicated + * differently than ::CUDA_SUCCESS (which indicates completion). Calls that + * may return this value include ::cuEventQuery() and ::cuStreamQuery(). + */ + { "CUDA_ERROR_NOT_READY", 600 }, + + + /** + * An exception occurred on the device while executing a kernel. Common + * causes include dereferencing an invalid device pointer and accessing + * out of bounds shared memory. The context cannot be used }, so it must + * be destroyed (and a new one should be created). All existing device + * memory allocations from this context are invalid and must be + * reconstructed if the program is to continue using CUDA. + */ + { "CUDA_ERROR_LAUNCH_FAILED", 700 }, + + /** + * This indicates that a launch did not occur because it did not have + * appropriate resources. This error usually indicates that the user has + * attempted to pass too many arguments to the device kernel, or the + * kernel launch specifies too many threads for the kernel's register + * count. Passing arguments of the wrong size (i.e. a 64-bit pointer + * when a 32-bit int is expected) is equivalent to passing too many + * arguments and can also result in this error. + */ + { "CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES", 701 }, + + /** + * This indicates that the device kernel took too long to execute. This can + * only occur if timeouts are enabled - see the device attribute + * ::CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT for more information. The + * context cannot be used (and must be destroyed similar to + * ::CUDA_ERROR_LAUNCH_FAILED). All existing device memory allocations from + * this context are invalid and must be reconstructed if the program is to + * continue using CUDA. + */ + { "CUDA_ERROR_LAUNCH_TIMEOUT", 702 }, + + /** + * This error indicates a kernel launch that uses an incompatible texturing + * mode. + */ + { "CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING", 703 }, + + /** + * This error indicates that a call to ::cuCtxEnablePeerAccess() is + * trying to re-enable peer access to a context which has already + * had peer access to it enabled. + */ + { "CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED", 704 }, + + /** + * This error indicates that ::cuCtxDisablePeerAccess() is + * trying to disable peer access which has not been enabled yet + * via ::cuCtxEnablePeerAccess(). + */ + { "CUDA_ERROR_PEER_ACCESS_NOT_ENABLED", 705 }, + + /** + * This error indicates that the primary context for the specified device + * has already been initialized. + */ + { "CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE", 708 }, + + /** + * This error indicates that the context current to the calling thread + * has been destroyed using ::cuCtxDestroy }, or is a primary context which + * has not yet been initialized. + */ + { "CUDA_ERROR_CONTEXT_IS_DESTROYED", 709 }, + + /** + * A device-side assert triggered during kernel execution. The context + * cannot be used anymore, and must be destroyed. All existing device + * memory allocations from this context are invalid and must be + * reconstructed if the program is to continue using CUDA. + */ + { "CUDA_ERROR_ASSERT", 710 }, + + /** + * This indicates that an unknown internal error has occurred. + */ + { "CUDA_ERROR_UNKNOWN", 999 }, + { NULL, -1 } +}; + +// This is just a linear search through the array, since the error_id's are not +// always ocurring consecutively +inline const char * getCudaDrvErrorString(CUresult error_id) +{ + int index = 0; + while (sCudaDrvErrorString[index].error_id != error_id && + sCudaDrvErrorString[index].error_id != -1) + { + index++; + return (const char *)sCudaDrvErrorString[index].error_string; + } + return (const char *)"CUDA_ERROR not found!"; +} + +#endif diff --git a/external/cutil/inc/dynlink/cuda_drvapi_dynlink.h b/external/cutil/inc/dynlink/cuda_drvapi_dynlink.h new file mode 100644 index 0000000..1a8233f --- /dev/null +++ b/external/cutil/inc/dynlink/cuda_drvapi_dynlink.h @@ -0,0 +1,26 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + +#ifndef __cuda_drvapi_dynlink_h__ +#define __cuda_drvapi_dynlink_h__ + +#include "cuda_drvapi_dynlink_cuda.h" + +#if defined(CUDA_INIT_D3D9)||defined(CUDA_INIT_D3D10)||defined(CUDA_INIT_D3D11) +#include "cuda_drvapi_dynlink_d3d.h" +#endif + +#ifdef CUDA_INIT_OPENGL +#include "cuda_drvapi_dynlink_gl.h" +#endif + +#endif //__cuda_drvapi_dynlink_h__ diff --git a/external/cutil/inc/dynlink/cuda_drvapi_dynlink_cuda.h b/external/cutil/inc/dynlink/cuda_drvapi_dynlink_cuda.h new file mode 100644 index 0000000..0daafb5 --- /dev/null +++ b/external/cutil/inc/dynlink/cuda_drvapi_dynlink_cuda.h @@ -0,0 +1,1683 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + +#ifndef __cuda_drvapi_dynlink_cuda_h__ +#define __cuda_drvapi_dynlink_cuda_h__ + +#include + +/** + * CUDA API versioning support + */ +#define __CUDA_API_VERSION 4000 + +/** + * \defgroup CUDA_DRIVER CUDA Driver API + * + * This section describes the low-level CUDA driver application programming + * interface. + * + * @{ + */ + +/** + * \defgroup CUDA_TYPES Data types used by CUDA driver + * @{ + */ + +/** + * CUDA API version number + */ +#define CUDA_VERSION 3020 /* 3.2 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * CUDA device pointer + */ +#if __CUDA_API_VERSION >= 3020 + +#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64) +typedef unsigned long long CUdeviceptr; +#else +typedef unsigned int CUdeviceptr; +#endif + +#endif /* __CUDA_API_VERSION >= 3020 */ + +typedef int CUdevice; /**< CUDA device */ +typedef struct CUctx_st *CUcontext; /**< CUDA context */ +typedef struct CUmod_st *CUmodule; /**< CUDA module */ +typedef struct CUfunc_st *CUfunction; /**< CUDA function */ +typedef struct CUarray_st *CUarray; /**< CUDA array */ +typedef struct CUtexref_st *CUtexref; /**< CUDA texture reference */ +typedef struct CUsurfref_st *CUsurfref; /**< CUDA surface reference */ +typedef struct CUevent_st *CUevent; /**< CUDA event */ +typedef struct CUstream_st *CUstream; /**< CUDA stream */ +typedef struct CUgraphicsResource_st *CUgraphicsResource; /**< CUDA graphics interop resource */ + +typedef struct CUuuid_st { /**< CUDA definition of UUID */ + char bytes[16]; +} CUuuid; + +/** + * Context creation flags + */ +typedef enum CUctx_flags_enum { + CU_CTX_SCHED_AUTO = 0x00, /**< Automatic scheduling */ + CU_CTX_SCHED_SPIN = 0x01, /**< Set spin as default scheduling */ + CU_CTX_SCHED_YIELD = 0x02, /**< Set yield as default scheduling */ + CU_CTX_SCHED_BLOCKING_SYNC = 0x04, /**< Set blocking synchronization as default scheduling */ + CU_CTX_BLOCKING_SYNC = 0x04, /**< Set blocking synchronization as default scheduling \deprecated */ + CU_CTX_MAP_HOST = 0x08, /**< Support mapped pinned allocations */ + CU_CTX_LMEM_RESIZE_TO_MAX = 0x10, /**< Keep local memory allocation after launch */ +#if __CUDA_API_VERSION < 4000 + CU_CTX_SCHED_MASK = 0x03, + CU_CTX_FLAGS_MASK = 0x1f +#else + CU_CTX_SCHED_MASK = 0x07, + CU_CTX_PRIMARY = 0x20, /**< Initialize and return the primary context */ + CU_CTX_FLAGS_MASK = 0x3f +#endif +} CUctx_flags; + +/** + * Event creation flags + */ +typedef enum CUevent_flags_enum { + CU_EVENT_DEFAULT = 0, /**< Default event flag */ + CU_EVENT_BLOCKING_SYNC = 1, /**< Event uses blocking synchronization */ + CU_EVENT_DISABLE_TIMING = 2 /**< Event will not record timing data */ +} CUevent_flags; + +/** + * Array formats + */ +typedef enum CUarray_format_enum { + CU_AD_FORMAT_UNSIGNED_INT8 = 0x01, /**< Unsigned 8-bit integers */ + CU_AD_FORMAT_UNSIGNED_INT16 = 0x02, /**< Unsigned 16-bit integers */ + CU_AD_FORMAT_UNSIGNED_INT32 = 0x03, /**< Unsigned 32-bit integers */ + CU_AD_FORMAT_SIGNED_INT8 = 0x08, /**< Signed 8-bit integers */ + CU_AD_FORMAT_SIGNED_INT16 = 0x09, /**< Signed 16-bit integers */ + CU_AD_FORMAT_SIGNED_INT32 = 0x0a, /**< Signed 32-bit integers */ + CU_AD_FORMAT_HALF = 0x10, /**< 16-bit floating point */ + CU_AD_FORMAT_FLOAT = 0x20 /**< 32-bit floating point */ +} CUarray_format; + +/** + * Texture reference addressing modes + */ +typedef enum CUaddress_mode_enum { + CU_TR_ADDRESS_MODE_WRAP = 0, /**< Wrapping address mode */ + CU_TR_ADDRESS_MODE_CLAMP = 1, /**< Clamp to edge address mode */ + CU_TR_ADDRESS_MODE_MIRROR = 2, /**< Mirror address mode */ + CU_TR_ADDRESS_MODE_BORDER = 3 /**< Border address mode */ +} CUaddress_mode; + +/** + * Texture reference filtering modes + */ +typedef enum CUfilter_mode_enum { + CU_TR_FILTER_MODE_POINT = 0, /**< Point filter mode */ + CU_TR_FILTER_MODE_LINEAR = 1 /**< Linear filter mode */ +} CUfilter_mode; + +/** + * Device properties + */ +typedef enum CUdevice_attribute_enum { + CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK = 1, /**< Maximum number of threads per block */ + CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_X = 2, /**< Maximum block dimension X */ + CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Y = 3, /**< Maximum block dimension Y */ + CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Z = 4, /**< Maximum block dimension Z */ + CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_X = 5, /**< Maximum grid dimension X */ + CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Y = 6, /**< Maximum grid dimension Y */ + CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Z = 7, /**< Maximum grid dimension Z */ + CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK = 8, /**< Maximum shared memory available per block in bytes */ + CU_DEVICE_ATTRIBUTE_SHARED_MEMORY_PER_BLOCK = 8, /**< Deprecated, use CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK */ + CU_DEVICE_ATTRIBUTE_TOTAL_CONSTANT_MEMORY = 9, /**< Memory available on device for __constant__ variables in a CUDA C kernel in bytes */ + CU_DEVICE_ATTRIBUTE_WARP_SIZE = 10, /**< Warp size in threads */ + CU_DEVICE_ATTRIBUTE_MAX_PITCH = 11, /**< Maximum pitch in bytes allowed by memory copies */ + CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_BLOCK = 12, /**< Maximum number of 32-bit registers available per block */ + CU_DEVICE_ATTRIBUTE_REGISTERS_PER_BLOCK = 12, /**< Deprecated, use CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_BLOCK */ + CU_DEVICE_ATTRIBUTE_CLOCK_RATE = 13, /**< Peak clock frequency in kilohertz */ + CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT = 14, /**< Alignment requirement for textures */ + CU_DEVICE_ATTRIBUTE_GPU_OVERLAP = 15, /**< Device can possibly copy memory and execute a kernel concurrently */ + CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT = 16, /**< Number of multiprocessors on device */ + CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT = 17, /**< Specifies whether there is a run time limit on kernels */ + CU_DEVICE_ATTRIBUTE_INTEGRATED = 18, /**< Device is integrated with host memory */ + CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY = 19, /**< Device can map host memory into CUDA address space */ + CU_DEVICE_ATTRIBUTE_COMPUTE_MODE = 20, /**< Compute mode (See ::CUcomputemode for details) */ + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_WIDTH = 21, /**< Maximum 1D texture width */ + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_WIDTH = 22, /**< Maximum 2D texture width */ + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_HEIGHT = 23, /**< Maximum 2D texture height */ + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_WIDTH = 24, /**< Maximum 3D texture width */ + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_HEIGHT = 25, /**< Maximum 3D texture height */ + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_DEPTH = 26, /**< Maximum 3D texture depth */ + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_WIDTH = 27, /**< Maximum texture array width */ + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_HEIGHT = 28, /**< Maximum texture array height */ + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_NUMSLICES = 29, /**< Maximum slices in a texture array */ + CU_DEVICE_ATTRIBUTE_SURFACE_ALIGNMENT = 30, /**< Alignment requirement for surfaces */ + CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS = 31, /**< Device can possibly execute multiple kernels concurrently */ + CU_DEVICE_ATTRIBUTE_ECC_ENABLED = 32, /**< Device has ECC support enabled */ + CU_DEVICE_ATTRIBUTE_PCI_BUS_ID = 33, /**< PCI bus ID of the device */ + CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID = 34, /**< PCI device ID of the device */ + CU_DEVICE_ATTRIBUTE_TCC_DRIVER = 35 /**< Device is using TCC driver model */ + +#if __CUDA_API_VERSION >= 4000 + , + CU_DEVICE_ATTRIBUTE_MEMORY_CLOCK_RATE = 36, /**< Peak memory clock frequency in kilohertz */ + CU_DEVICE_ATTRIBUTE_GLOBAL_MEMORY_BUS_WIDTH = 37, /**< Global memory bus width in bits */ + CU_DEVICE_ATTRIBUTE_L2_CACHE_SIZE = 38, /**< Size of L2 cache in bytes */ + CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_MULTIPROCESSOR = 39, /**< Maximum resident threads per multiprocessor */ + CU_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT = 40, /**< Number of asynchronous engines */ + CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING = 41, /**< Device uses shares a unified address space with the host */ + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_LAYERED_WIDTH = 42, /**< Maximum 1D layered texture width */ + CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_LAYERED_LAYERS = 43 /**< Maximum layers in a 1D layered texture */ +#endif +} CUdevice_attribute; + +/** + * Legacy device properties + */ +typedef struct CUdevprop_st { + int maxThreadsPerBlock; /**< Maximum number of threads per block */ + int maxThreadsDim[3]; /**< Maximum size of each dimension of a block */ + int maxGridSize[3]; /**< Maximum size of each dimension of a grid */ + int sharedMemPerBlock; /**< Shared memory available per block in bytes */ + int totalConstantMemory; /**< Constant memory available on device in bytes */ + int SIMDWidth; /**< Warp size in threads */ + int memPitch; /**< Maximum pitch in bytes allowed by memory copies */ + int regsPerBlock; /**< 32-bit registers available per block */ + int clockRate; /**< Clock frequency in kilohertz */ + int textureAlign; /**< Alignment requirement for textures */ +} CUdevprop; + +/** + * Function properties + */ +typedef enum CUfunction_attribute_enum { + /** + * The maximum number of threads per block, beyond which a launch of the + * function would fail. This number depends on both the function and the + * device on which the function is currently loaded. + */ + CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK = 0, + + /** + * The size in bytes of statically-allocated shared memory required by + * this function. This does not include dynamically-allocated shared + * memory requested by the user at runtime. + */ + CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES = 1, + + /** + * The size in bytes of user-allocated constant memory required by this + * function. + */ + CU_FUNC_ATTRIBUTE_CONST_SIZE_BYTES = 2, + + /** + * The size in bytes of local memory used by each thread of this function. + */ + CU_FUNC_ATTRIBUTE_LOCAL_SIZE_BYTES = 3, + + /** + * The number of registers used by each thread of this function. + */ + CU_FUNC_ATTRIBUTE_NUM_REGS = 4, + + /** + * The PTX virtual architecture version for which the function was + * compiled. This value is the major PTX version * 10 + the minor PTX + * version, so a PTX version 1.3 function would return the value 13. + * Note that this may return the undefined value of 0 for cubins + * compiled prior to CUDA 3.0. + */ + CU_FUNC_ATTRIBUTE_PTX_VERSION = 5, + + /** + * The binary architecture version for which the function was compiled. + * This value is the major binary version * 10 + the minor binary version, + * so a binary version 1.3 function would return the value 13. Note that + * this will return a value of 10 for legacy cubins that do not have a + * properly-encoded binary architecture version. + */ + CU_FUNC_ATTRIBUTE_BINARY_VERSION = 6, + + CU_FUNC_ATTRIBUTE_MAX +} CUfunction_attribute; + +/** + * Function cache configurations + */ +typedef enum CUfunc_cache_enum { + CU_FUNC_CACHE_PREFER_NONE = 0x00, /**< no preference for shared memory or L1 (default) */ + CU_FUNC_CACHE_PREFER_SHARED = 0x01, /**< prefer larger shared memory and smaller L1 cache */ + CU_FUNC_CACHE_PREFER_L1 = 0x02 /**< prefer larger L1 cache and smaller shared memory */ +} CUfunc_cache; + +/** + * Memory types + */ +typedef enum CUmemorytype_enum { + CU_MEMORYTYPE_HOST = 0x01, /**< Host memory */ + CU_MEMORYTYPE_DEVICE = 0x02, /**< Device memory */ + CU_MEMORYTYPE_ARRAY = 0x03 /**< Array memory */ +#if __CUDA_API_VERSION >= 4000 + , + CU_MEMORYTYPE_UNIFIED = 0x04 /**< Unified device or host memory */ +#endif +} CUmemorytype; + +/** + * Compute Modes + */ +typedef enum CUcomputemode_enum { + CU_COMPUTEMODE_DEFAULT = 0, /**< Default compute mode (Multiple contexts allowed per device) */ + CU_COMPUTEMODE_EXCLUSIVE = 1, /**< Compute-exclusive-thread mode (Only one context used by a single thread can be present on this device at a time) */ + CU_COMPUTEMODE_PROHIBITED = 2 /**< Compute-prohibited mode (No contexts can be created on this device at this time) */ +#if __CUDA_API_VERSION >= 4000 + , + CU_COMPUTEMODE_EXCLUSIVE_PROCESS = 3 /**< Compute-exclusive-process mode (Only one context used by a single process can be present on this device at a time) */ +#endif +} CUcomputemode; + +/** + * Online compiler options + */ +typedef enum CUjit_option_enum +{ + /** + * Max number of registers that a thread may use.\n + * Option type: unsigned int + */ + CU_JIT_MAX_REGISTERS = 0, + + /** + * IN: Specifies minimum number of threads per block to target compilation + * for\n + * OUT: Returns the number of threads the compiler actually targeted. + * This restricts the resource utilization fo the compiler (e.g. max + * registers) such that a block with the given number of threads should be + * able to launch based on register limitations. Note, this option does not + * currently take into account any other resource limitations, such as + * shared memory utilization.\n + * Option type: unsigned int + */ + CU_JIT_THREADS_PER_BLOCK, + + /** + * Returns a float value in the option of the wall clock time, in + * milliseconds, spent creating the cubin\n + * Option type: float + */ + CU_JIT_WALL_TIME, + + /** + * Pointer to a buffer in which to print any log messsages from PTXAS + * that are informational in nature (the buffer size is specified via + * option ::CU_JIT_INFO_LOG_BUFFER_SIZE_BYTES) \n + * Option type: char* + */ + CU_JIT_INFO_LOG_BUFFER, + + /** + * IN: Log buffer size in bytes. Log messages will be capped at this size + * (including null terminator)\n + * OUT: Amount of log buffer filled with messages\n + * Option type: unsigned int + */ + CU_JIT_INFO_LOG_BUFFER_SIZE_BYTES, + + /** + * Pointer to a buffer in which to print any log messages from PTXAS that + * reflect errors (the buffer size is specified via option + * ::CU_JIT_ERROR_LOG_BUFFER_SIZE_BYTES)\n + * Option type: char* + */ + CU_JIT_ERROR_LOG_BUFFER, + + /** + * IN: Log buffer size in bytes. Log messages will be capped at this size + * (including null terminator)\n + * OUT: Amount of log buffer filled with messages\n + * Option type: unsigned int + */ + CU_JIT_ERROR_LOG_BUFFER_SIZE_BYTES, + + /** + * Level of optimizations to apply to generated code (0 - 4), with 4 + * being the default and highest level of optimizations.\n + * Option type: unsigned int + */ + CU_JIT_OPTIMIZATION_LEVEL, + + /** + * No option value required. Determines the target based on the current + * attached context (default)\n + * Option type: No option value needed + */ + CU_JIT_TARGET_FROM_CUCONTEXT, + + /** + * Target is chosen based on supplied ::CUjit_target_enum.\n + * Option type: unsigned int for enumerated type ::CUjit_target_enum + */ + CU_JIT_TARGET, + + /** + * Specifies choice of fallback strategy if matching cubin is not found. + * Choice is based on supplied ::CUjit_fallback_enum.\n + * Option type: unsigned int for enumerated type ::CUjit_fallback_enum + */ + CU_JIT_FALLBACK_STRATEGY + +} CUjit_option; + +/** + * Online compilation targets + */ +typedef enum CUjit_target_enum +{ + CU_TARGET_COMPUTE_10 = 0, /**< Compute device class 1.0 */ + CU_TARGET_COMPUTE_11, /**< Compute device class 1.1 */ + CU_TARGET_COMPUTE_12, /**< Compute device class 1.2 */ + CU_TARGET_COMPUTE_13, /**< Compute device class 1.3 */ + CU_TARGET_COMPUTE_20, /**< Compute device class 2.0 */ + CU_TARGET_COMPUTE_21 /**< Compute device class 2.1 */ +} CUjit_target; + +/** + * Cubin matching fallback strategies + */ +typedef enum CUjit_fallback_enum +{ + CU_PREFER_PTX = 0, /**< Prefer to compile ptx */ + + CU_PREFER_BINARY /**< Prefer to fall back to compatible binary code */ + +} CUjit_fallback; + +/** + * Flags to register a graphics resource + */ +typedef enum CUgraphicsRegisterFlags_enum { + CU_GRAPHICS_REGISTER_FLAGS_NONE = 0x00, + CU_GRAPHICS_REGISTER_FLAGS_READ_ONLY = 0x01, + CU_GRAPHICS_REGISTER_FLAGS_WRITE_DISCARD = 0x02, + CU_GRAPHICS_REGISTER_FLAGS_SURFACE_LDST = 0x04 +} CUgraphicsRegisterFlags; + +/** + * Flags for mapping and unmapping interop resources + */ +typedef enum CUgraphicsMapResourceFlags_enum { + CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE = 0x00, + CU_GRAPHICS_MAP_RESOURCE_FLAGS_READ_ONLY = 0x01, + CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD = 0x02 +} CUgraphicsMapResourceFlags; + +/** + * Array indices for cube faces + */ +typedef enum CUarray_cubemap_face_enum { + CU_CUBEMAP_FACE_POSITIVE_X = 0x00, /**< Positive X face of cubemap */ + CU_CUBEMAP_FACE_NEGATIVE_X = 0x01, /**< Negative X face of cubemap */ + CU_CUBEMAP_FACE_POSITIVE_Y = 0x02, /**< Positive Y face of cubemap */ + CU_CUBEMAP_FACE_NEGATIVE_Y = 0x03, /**< Negative Y face of cubemap */ + CU_CUBEMAP_FACE_POSITIVE_Z = 0x04, /**< Positive Z face of cubemap */ + CU_CUBEMAP_FACE_NEGATIVE_Z = 0x05 /**< Negative Z face of cubemap */ +} CUarray_cubemap_face; + +/** + * Limits + */ +typedef enum CUlimit_enum { + CU_LIMIT_STACK_SIZE = 0x00, /**< GPU thread stack size */ + CU_LIMIT_PRINTF_FIFO_SIZE = 0x01, /**< GPU printf FIFO size */ + CU_LIMIT_MALLOC_HEAP_SIZE = 0x02 /**< GPU malloc heap size */ +} CUlimit; + +/** + * Error codes + */ +typedef enum cudaError_enum { + /** + * The API call returned with no errors. In the case of query calls, this + * can also mean that the operation being queried is complete (see + * ::cuEventQuery() and ::cuStreamQuery()). + */ + CUDA_SUCCESS = 0, + + /** + * This indicates that one or more of the parameters passed to the API call + * is not within an acceptable range of values. + */ + CUDA_ERROR_INVALID_VALUE = 1, + + /** + * The API call failed because it was unable to allocate enough memory to + * perform the requested operation. + */ + CUDA_ERROR_OUT_OF_MEMORY = 2, + + /** + * This indicates that the CUDA driver has not been initialized with + * ::cuInit() or that initialization has failed. + */ + CUDA_ERROR_NOT_INITIALIZED = 3, + + /** + * This indicates that the CUDA driver is in the process of shutting down. + */ + CUDA_ERROR_DEINITIALIZED = 4, + + /** + * This indicates profiling APIs are called while application is running + * in visual profiler mode. + */ + CUDA_ERROR_PROFILER_DISABLED = 5, + /** + * This indicates profiling has not been initialized for this context. + * Call cuProfilerInitialize() to resolve this. + */ + CUDA_ERROR_PROFILER_NOT_INITIALIZED = 6, + /** + * This indicates profiler has already been started and probably + * cuProfilerStart() is incorrectly called. + */ + CUDA_ERROR_PROFILER_ALREADY_STARTED = 7, + /** + * This indicates profiler has already been stopped and probably + * cuProfilerStop() is incorrectly called. + */ + CUDA_ERROR_PROFILER_ALREADY_STOPPED = 8, + /** + * This indicates that no CUDA-capable devices were detected by the installed + * CUDA driver. + */ + CUDA_ERROR_NO_DEVICE = 100, + + /** + * This indicates that the device ordinal supplied by the user does not + * correspond to a valid CUDA device. + */ + CUDA_ERROR_INVALID_DEVICE = 101, + + + /** + * This indicates that the device kernel image is invalid. This can also + * indicate an invalid CUDA module. + */ + CUDA_ERROR_INVALID_IMAGE = 200, + + /** + * This most frequently indicates that there is no context bound to the + * current thread. This can also be returned if the context passed to an + * API call is not a valid handle (such as a context that has had + * ::cuCtxDestroy() invoked on it). This can also be returned if a user + * mixes different API versions (i.e. 3010 context with 3020 API calls). + * See ::cuCtxGetApiVersion() for more details. + */ + CUDA_ERROR_INVALID_CONTEXT = 201, + + /** + * This indicated that the context being supplied as a parameter to the + * API call was already the active context. + * \deprecated + * This error return is deprecated as of CUDA 3.2. It is no longer an + * error to attempt to push the active context via ::cuCtxPushCurrent(). + */ + CUDA_ERROR_CONTEXT_ALREADY_CURRENT = 202, + + /** + * This indicates that a map or register operation has failed. + */ + CUDA_ERROR_MAP_FAILED = 205, + + /** + * This indicates that an unmap or unregister operation has failed. + */ + CUDA_ERROR_UNMAP_FAILED = 206, + + /** + * This indicates that the specified array is currently mapped and thus + * cannot be destroyed. + */ + CUDA_ERROR_ARRAY_IS_MAPPED = 207, + + /** + * This indicates that the resource is already mapped. + */ + CUDA_ERROR_ALREADY_MAPPED = 208, + + /** + * This indicates that there is no kernel image available that is suitable + * for the device. This can occur when a user specifies code generation + * options for a particular CUDA source file that do not include the + * corresponding device configuration. + */ + CUDA_ERROR_NO_BINARY_FOR_GPU = 209, + + /** + * This indicates that a resource has already been acquired. + */ + CUDA_ERROR_ALREADY_ACQUIRED = 210, + + /** + * This indicates that a resource is not mapped. + */ + CUDA_ERROR_NOT_MAPPED = 211, + + /** + * This indicates that a mapped resource is not available for access as an + * array. + */ + CUDA_ERROR_NOT_MAPPED_AS_ARRAY = 212, + + /** + * This indicates that a mapped resource is not available for access as a + * pointer. + */ + CUDA_ERROR_NOT_MAPPED_AS_POINTER = 213, + + /** + * This indicates that an uncorrectable ECC error was detected during + * execution. + */ + CUDA_ERROR_ECC_UNCORRECTABLE = 214, + + /** + * This indicates that the ::CUlimit passed to the API call is not + * supported by the active device. + */ + CUDA_ERROR_UNSUPPORTED_LIMIT = 215, + + /** + * This indicates that the ::CUcontext passed to the API call can + * only be bound to a single CPU thread at a time but is already + * bound to a CPU thread. + */ + CUDA_ERROR_CONTEXT_ALREADY_IN_USE = 216, + + /** + * This indicates that the device kernel source is invalid. + */ + CUDA_ERROR_INVALID_SOURCE = 300, + + /** + * This indicates that the file specified was not found. + */ + CUDA_ERROR_FILE_NOT_FOUND = 301, + + /** + * This indicates that a link to a shared object failed to resolve. + */ + CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND = 302, + + /** + * This indicates that initialization of a shared object failed. + */ + CUDA_ERROR_SHARED_OBJECT_INIT_FAILED = 303, + + /** + * This indicates that an OS call failed. + */ + CUDA_ERROR_OPERATING_SYSTEM = 304, + + + /** + * This indicates that a resource handle passed to the API call was not + * valid. Resource handles are opaque types like ::CUstream and ::CUevent. + */ + CUDA_ERROR_INVALID_HANDLE = 400, + + + /** + * This indicates that a named symbol was not found. Examples of symbols + * are global/constant variable names, texture names, and surface names. + */ + CUDA_ERROR_NOT_FOUND = 500, + + + /** + * This indicates that asynchronous operations issued previously have not + * completed yet. This result is not actually an error, but must be indicated + * differently than ::CUDA_SUCCESS (which indicates completion). Calls that + * may return this value include ::cuEventQuery() and ::cuStreamQuery(). + */ + CUDA_ERROR_NOT_READY = 600, + + + /** + * An exception occurred on the device while executing a kernel. Common + * causes include dereferencing an invalid device pointer and accessing + * out of bounds shared memory. The context cannot be used, so it must + * be destroyed (and a new one should be created). All existing device + * memory allocations from this context are invalid and must be + * reconstructed if the program is to continue using CUDA. + */ + CUDA_ERROR_LAUNCH_FAILED = 700, + + /** + * This indicates that a launch did not occur because it did not have + * appropriate resources. This error usually indicates that the user has + * attempted to pass too many arguments to the device kernel, or the + * kernel launch specifies too many threads for the kernel's register + * count. Passing arguments of the wrong size (i.e. a 64-bit pointer + * when a 32-bit int is expected) is equivalent to passing too many + * arguments and can also result in this error. + */ + CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES = 701, + + /** + * This indicates that the device kernel took too long to execute. This can + * only occur if timeouts are enabled - see the device attribute + * ::CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT for more information. The + * context cannot be used (and must be destroyed similar to + * ::CUDA_ERROR_LAUNCH_FAILED). All existing device memory allocations from + * this context are invalid and must be reconstructed if the program is to + * continue using CUDA. + */ + CUDA_ERROR_LAUNCH_TIMEOUT = 702, + + /** + * This error indicates a kernel launch that uses an incompatible texturing + * mode. + */ + CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING = 703, + + /** + * This error indicates that a call to ::cuCtxEnablePeerAccess() is + * trying to re-enable peer access to a context which has already + * had peer access to it enabled. + */ + CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED = 704, + + /** + * This error indicates that a call to ::cuMemPeerRegister is trying to + * register memory from a context which has not had peer access + * enabled yet via ::cuCtxEnablePeerAccess(), or that + * ::cuCtxDisablePeerAccess() is trying to disable peer access + * which has not been enabled yet. + */ + CUDA_ERROR_PEER_ACCESS_NOT_ENABLED = 705, + + /** + * This error indicates that a call to ::cuMemPeerRegister is trying to + * register already-registered memory. + */ + CUDA_ERROR_PEER_MEMORY_ALREADY_REGISTERED = 706, + + /** + * This error indicates that a call to ::cuMemPeerUnregister is trying to + * unregister memory that has not been registered. + */ + CUDA_ERROR_PEER_MEMORY_NOT_REGISTERED = 707, + + /** + * This error indicates that ::cuCtxCreate was called with the flag + * ::CU_CTX_PRIMARY on a device which already has initialized its + * primary context. + */ + CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE = 708, + + /** + * This error indicates that the context current to the calling thread + * has been destroyed using ::cuCtxDestroy, or is a primary context which + * has not yet been initialized. + */ + CUDA_ERROR_CONTEXT_IS_DESTROYED = 709, + + /** + * This indicates that an unknown internal error has occurred. + */ + CUDA_ERROR_UNKNOWN = 999 +} CUresult; + +#if __CUDA_API_VERSION >= 4000 + /** + * If set, host memory is portable between CUDA contexts. + * Flag for ::cuMemHostAlloc() + */ + #define CU_MEMHOSTALLOC_PORTABLE 0x01 + + /** + * If set, host memory is mapped into CUDA address space and + * ::cuMemHostGetDevicePointer() may be called on the host pointer. + * Flag for ::cuMemHostAlloc() + */ + #define CU_MEMHOSTALLOC_DEVICEMAP 0x02 + + /** + * If set, host memory is allocated as write-combined - fast to write, + * faster to DMA, slow to read except via SSE4 streaming load instruction + * (MOVNTDQA). + * Flag for ::cuMemHostAlloc() + */ + #define CU_MEMHOSTALLOC_WRITECOMBINED 0x04 + + /** + * If set, host memory is portable between CUDA contexts. + * Flag for ::cuMemHostRegister() + */ + #define CU_MEMHOSTREGISTER_PORTABLE 0x01 + + /** + * If set, host memory is mapped into CUDA address space and + * ::cuMemHostGetDevicePointer() may be called on the host pointer. + * Flag for ::cuMemHostRegister() + */ + #define CU_MEMHOSTREGISTER_DEVICEMAP 0x02 + + /** + * If set, peer memory is mapped into CUDA address space and + * ::cuMemPeerGetDevicePointer() may be called on the host pointer. + * Flag for ::cuMemPeerRegister() + */ + #define CU_MEMPEERREGISTER_DEVICEMAP 0x02 +#endif + +#if __CUDA_API_VERSION >= 3020 + +/** + * 2D memory copy parameters + */ +typedef struct CUDA_MEMCPY2D_st { + size_t srcXInBytes; /**< Source X in bytes */ + size_t srcY; /**< Source Y */ + + CUmemorytype srcMemoryType; /**< Source memory type (host, device, array) */ + const void *srcHost; /**< Source host pointer */ + CUdeviceptr srcDevice; /**< Source device pointer */ + CUarray srcArray; /**< Source array reference */ + size_t srcPitch; /**< Source pitch (ignored when src is array) */ + + size_t dstXInBytes; /**< Destination X in bytes */ + size_t dstY; /**< Destination Y */ + + CUmemorytype dstMemoryType; /**< Destination memory type (host, device, array) */ + void *dstHost; /**< Destination host pointer */ + CUdeviceptr dstDevice; /**< Destination device pointer */ + CUarray dstArray; /**< Destination array reference */ + size_t dstPitch; /**< Destination pitch (ignored when dst is array) */ + + size_t WidthInBytes; /**< Width of 2D memory copy in bytes */ + size_t Height; /**< Height of 2D memory copy */ +} CUDA_MEMCPY2D; + +/** + * 3D memory copy parameters + */ +typedef struct CUDA_MEMCPY3D_st { + size_t srcXInBytes; /**< Source X in bytes */ + size_t srcY; /**< Source Y */ + size_t srcZ; /**< Source Z */ + size_t srcLOD; /**< Source LOD */ + CUmemorytype srcMemoryType; /**< Source memory type (host, device, array) */ + const void *srcHost; /**< Source host pointer */ + CUdeviceptr srcDevice; /**< Source device pointer */ + CUarray srcArray; /**< Source array reference */ + void *reserved0; /**< Must be NULL */ + size_t srcPitch; /**< Source pitch (ignored when src is array) */ + size_t srcHeight; /**< Source height (ignored when src is array; may be 0 if Depth==1) */ + + size_t dstXInBytes; /**< Destination X in bytes */ + size_t dstY; /**< Destination Y */ + size_t dstZ; /**< Destination Z */ + size_t dstLOD; /**< Destination LOD */ + CUmemorytype dstMemoryType; /**< Destination memory type (host, device, array) */ + void *dstHost; /**< Destination host pointer */ + CUdeviceptr dstDevice; /**< Destination device pointer */ + CUarray dstArray; /**< Destination array reference */ + void *reserved1; /**< Must be NULL */ + size_t dstPitch; /**< Destination pitch (ignored when dst is array) */ + size_t dstHeight; /**< Destination height (ignored when dst is array; may be 0 if Depth==1) */ + + size_t WidthInBytes; /**< Width of 3D memory copy in bytes */ + size_t Height; /**< Height of 3D memory copy */ + size_t Depth; /**< Depth of 3D memory copy */ +} CUDA_MEMCPY3D; + +/** + * 3D memory cross-context copy parameters + */ +typedef struct CUDA_MEMCPY3D_PEER_st { + size_t srcXInBytes; /**< Source X in bytes */ + size_t srcY; /**< Source Y */ + size_t srcZ; /**< Source Z */ + size_t srcLOD; /**< Source LOD */ + CUmemorytype srcMemoryType; /**< Source memory type (host, device, array) */ + const void *srcHost; /**< Source host pointer */ + CUdeviceptr srcDevice; /**< Source device pointer */ + CUarray srcArray; /**< Source array reference */ + CUcontext srcContext; /**< Source context (ignored with srcMemoryType is ::CU_MEMORYTYPE_ARRAY) */ + size_t srcPitch; /**< Source pitch (ignored when src is array) */ + size_t srcHeight; /**< Source height (ignored when src is array; may be 0 if Depth==1) */ + + size_t dstXInBytes; /**< Destination X in bytes */ + size_t dstY; /**< Destination Y */ + size_t dstZ; /**< Destination Z */ + size_t dstLOD; /**< Destination LOD */ + CUmemorytype dstMemoryType; /**< Destination memory type (host, device, array) */ + void *dstHost; /**< Destination host pointer */ + CUdeviceptr dstDevice; /**< Destination device pointer */ + CUarray dstArray; /**< Destination array reference */ + CUcontext dstContext; /**< Destination context (ignored with dstMemoryType is ::CU_MEMORYTYPE_ARRAY) */ + size_t dstPitch; /**< Destination pitch (ignored when dst is array) */ + size_t dstHeight; /**< Destination height (ignored when dst is array; may be 0 if Depth==1) */ + + size_t WidthInBytes; /**< Width of 3D memory copy in bytes */ + size_t Height; /**< Height of 3D memory copy */ + size_t Depth; /**< Depth of 3D memory copy */ +} CUDA_MEMCPY3D_PEER; + +/** + * Array descriptor + */ +typedef struct CUDA_ARRAY_DESCRIPTOR_st +{ + size_t Width; /**< Width of array */ + size_t Height; /**< Height of array */ + + CUarray_format Format; /**< Array format */ + unsigned int NumChannels; /**< Channels per array element */ +} CUDA_ARRAY_DESCRIPTOR; + +/** + * 3D array descriptor + */ +typedef struct CUDA_ARRAY3D_DESCRIPTOR_st +{ + size_t Width; /**< Width of 3D array */ + size_t Height; /**< Height of 3D array */ + size_t Depth; /**< Depth of 3D array */ + + CUarray_format Format; /**< Array format */ + unsigned int NumChannels; /**< Channels per array element */ + unsigned int Flags; /**< Flags */ +} CUDA_ARRAY3D_DESCRIPTOR; + +#endif /* __CUDA_API_VERSION >= 3020 */ + +/** + * If set, the CUDA array is a collection of layers, where each layer is either a 1D + * or a 2D array and the Depth member of CUDA_ARRAY3D_DESCRIPTOR specifies the number + * of layers, not the depth of a 3D array. + */ +#define CUDA_ARRAY3D_LAYERED 0x01 + +/** + * Deprecated, use CUDA_ARRAY3D_LAYERED + */ +#define CUDA_ARRAY3D_2DARRAY 0x01 + +/** + * This flag must be set in order to bind a surface reference + * to the CUDA array + */ +#define CUDA_ARRAY3D_SURFACE_LDST 0x02 + +/** + * Override the texref format with a format inferred from the array. + * Flag for ::cuTexRefSetArray() + */ +#define CU_TRSA_OVERRIDE_FORMAT 0x01 + +/** + * Read the texture as integers rather than promoting the values to floats + * in the range [0,1]. + * Flag for ::cuTexRefSetFlags() + */ +#define CU_TRSF_READ_AS_INTEGER 0x01 + +/** + * Use normalized texture coordinates in the range [0,1) instead of [0,dim). + * Flag for ::cuTexRefSetFlags() + */ +#define CU_TRSF_NORMALIZED_COORDINATES 0x02 + +/** + * Perform sRGB->linear conversion during texture read. + * Flag for ::cuTexRefSetFlags() + */ +#define CU_TRSF_SRGB 0x10 + +/** + * End of array terminator for the \p extra parameter to + * ::cuLaunchKernel + */ +#define CU_LAUNCH_PARAM_END ((void*)0x00) + +/** + * Indicator that the next value in the \p extra parameter to + * ::cuLaunchKernel will be a pointer to a buffer containing all kernel + * parameters used for launching kernel \p f. This buffer needs to + * honor all alignment/padding requirements of the individual parameters. + * If ::CU_LAUNCH_PARAM_BUFFER_SIZE is not also specified in the + * \p extra array, then ::CU_LAUNCH_PARAM_BUFFER_POINTER will have no + * effect. + */ +#define CU_LAUNCH_PARAM_BUFFER_POINTER ((void*)0x01) + +/** + * Indicator that the next value in the \p extra parameter to + * ::cuLaunchKernel will be a pointer to a size_t which contains the + * size of the buffer specified with ::CU_LAUNCH_PARAM_BUFFER_POINTER. + * It is required that ::CU_LAUNCH_PARAM_BUFFER_POINTER also be specified + * in the \p extra array if the value associated with + * ::CU_LAUNCH_PARAM_BUFFER_SIZE is not zero. + */ +#define CU_LAUNCH_PARAM_BUFFER_SIZE ((void*)0x02) + +/** + * For texture references loaded into the module, use default texunit from + * texture reference. + */ +#define CU_PARAM_TR_DEFAULT -1 + +/** + * CUDA API made obselete at API version 3020 + */ +#if defined(__CUDA_API_VERSION_INTERNAL) + #define CUdeviceptr CUdeviceptr_v1 + #define CUDA_MEMCPY2D_st CUDA_MEMCPY2D_v1_st + #define CUDA_MEMCPY2D CUDA_MEMCPY2D_v1 + #define CUDA_MEMCPY3D_st CUDA_MEMCPY3D_v1_st + #define CUDA_MEMCPY3D CUDA_MEMCPY3D_v1 + #define CUDA_ARRAY_DESCRIPTOR_st CUDA_ARRAY_DESCRIPTOR_v1_st + #define CUDA_ARRAY_DESCRIPTOR CUDA_ARRAY_DESCRIPTOR_v1 + #define CUDA_ARRAY3D_DESCRIPTOR_st CUDA_ARRAY3D_DESCRIPTOR_v1_st + #define CUDA_ARRAY3D_DESCRIPTOR CUDA_ARRAY3D_DESCRIPTOR_v1 +#endif /* CUDA_FORCE_LEGACY32_INTERNAL */ + +#if defined(__CUDA_API_VERSION_INTERNAL) || __CUDA_API_VERSION < 3020 + +typedef unsigned int CUdeviceptr; + +typedef struct CUDA_MEMCPY2D_st +{ + unsigned int srcXInBytes; /**< Source X in bytes */ + unsigned int srcY; /**< Source Y */ + CUmemorytype srcMemoryType; /**< Source memory type (host, device, array) */ + const void *srcHost; /**< Source host pointer */ + CUdeviceptr srcDevice; /**< Source device pointer */ + CUarray srcArray; /**< Source array reference */ + unsigned int srcPitch; /**< Source pitch (ignored when src is array) */ + + unsigned int dstXInBytes; /**< Destination X in bytes */ + unsigned int dstY; /**< Destination Y */ + CUmemorytype dstMemoryType; /**< Destination memory type (host, device, array) */ + void *dstHost; /**< Destination host pointer */ + CUdeviceptr dstDevice; /**< Destination device pointer */ + CUarray dstArray; /**< Destination array reference */ + unsigned int dstPitch; /**< Destination pitch (ignored when dst is array) */ + + unsigned int WidthInBytes; /**< Width of 2D memory copy in bytes */ + unsigned int Height; /**< Height of 2D memory copy */ +} CUDA_MEMCPY2D; + +typedef struct CUDA_MEMCPY3D_st +{ + unsigned int srcXInBytes; /**< Source X in bytes */ + unsigned int srcY; /**< Source Y */ + unsigned int srcZ; /**< Source Z */ + unsigned int srcLOD; /**< Source LOD */ + CUmemorytype srcMemoryType; /**< Source memory type (host, device, array) */ + const void *srcHost; /**< Source host pointer */ + CUdeviceptr srcDevice; /**< Source device pointer */ + CUarray srcArray; /**< Source array reference */ + void *reserved0; /**< Must be NULL */ + unsigned int srcPitch; /**< Source pitch (ignored when src is array) */ + unsigned int srcHeight; /**< Source height (ignored when src is array; may be 0 if Depth==1) */ + + unsigned int dstXInBytes; /**< Destination X in bytes */ + unsigned int dstY; /**< Destination Y */ + unsigned int dstZ; /**< Destination Z */ + unsigned int dstLOD; /**< Destination LOD */ + CUmemorytype dstMemoryType; /**< Destination memory type (host, device, array) */ + void *dstHost; /**< Destination host pointer */ + CUdeviceptr dstDevice; /**< Destination device pointer */ + CUarray dstArray; /**< Destination array reference */ + void *reserved1; /**< Must be NULL */ + unsigned int dstPitch; /**< Destination pitch (ignored when dst is array) */ + unsigned int dstHeight; /**< Destination height (ignored when dst is array; may be 0 if Depth==1) */ + + unsigned int WidthInBytes; /**< Width of 3D memory copy in bytes */ + unsigned int Height; /**< Height of 3D memory copy */ + unsigned int Depth; /**< Depth of 3D memory copy */ +} CUDA_MEMCPY3D; + +typedef struct CUDA_ARRAY_DESCRIPTOR_st +{ + unsigned int Width; /**< Width of array */ + unsigned int Height; /**< Height of array */ + + CUarray_format Format; /**< Array format */ + unsigned int NumChannels; /**< Channels per array element */ +} CUDA_ARRAY_DESCRIPTOR; + +typedef struct CUDA_ARRAY3D_DESCRIPTOR_st +{ + unsigned int Width; /**< Width of 3D array */ + unsigned int Height; /**< Height of 3D array */ + unsigned int Depth; /**< Depth of 3D array */ + + CUarray_format Format; /**< Array format */ + unsigned int NumChannels; /**< Channels per array element */ + unsigned int Flags; /**< Flags */ +} CUDA_ARRAY3D_DESCRIPTOR; + +#endif /* (__CUDA_API_VERSION_INTERNAL) || __CUDA_API_VERSION < 3020 */ + +/* + * If set, the CUDA array contains an array of 2D slices + * and the Depth member of CUDA_ARRAY3D_DESCRIPTOR specifies + * the number of slices, not the depth of a 3D array. + */ +#define CUDA_ARRAY3D_2DARRAY 0x01 + +/** + * This flag must be set in order to bind a surface reference + * to the CUDA array + */ +#define CUDA_ARRAY3D_SURFACE_LDST 0x02 + +/** + * Override the texref format with a format inferred from the array. + * Flag for ::cuTexRefSetArray() + */ +#define CU_TRSA_OVERRIDE_FORMAT 0x01 + +/** + * Read the texture as integers rather than promoting the values to floats + * in the range [0,1]. + * Flag for ::cuTexRefSetFlags() + */ +#define CU_TRSF_READ_AS_INTEGER 0x01 + +/** + * Use normalized texture coordinates in the range [0,1) instead of [0,dim). + * Flag for ::cuTexRefSetFlags() + */ +#define CU_TRSF_NORMALIZED_COORDINATES 0x02 + +/** + * Perform sRGB->linear conversion during texture read. + * Flag for ::cuTexRefSetFlags() + */ +#define CU_TRSF_SRGB 0x10 + +/** + * For texture references loaded into the module, use default texunit from + * texture reference. + */ +#define CU_PARAM_TR_DEFAULT -1 + +/** @} */ /* END CUDA_TYPES */ + +#ifdef _WIN32 +#define CUDAAPI __stdcall +#else +#define CUDAAPI +#endif + +/** + * \defgroup CUDA_INITIALIZE Initialization + * + * This section describes the initialization functions of the low-level CUDA + * driver application programming interface. + * + * @{ + */ + + /********************************* + ** Initialization + *********************************/ + typedef CUresult CUDAAPI tcuInit(unsigned int Flags); + + /********************************* + ** Driver Version Query + *********************************/ + typedef CUresult CUDAAPI tcuDriverGetVersion(int *driverVersion); + + /************************************ + ** + ** Device management + ** + ***********************************/ + + typedef CUresult CUDAAPI tcuDeviceGet(CUdevice *device, int ordinal); + typedef CUresult CUDAAPI tcuDeviceGetCount(int *count); + typedef CUresult CUDAAPI tcuDeviceGetName(char *name, int len, CUdevice dev); + typedef CUresult CUDAAPI tcuDeviceComputeCapability(int *major, int *minor, CUdevice dev); +#if __CUDA_API_VERSION >= 3020 + typedef CUresult CUDAAPI tcuDeviceTotalMem(size_t *bytes, CUdevice dev); +#else + typedef CUresult CUDAAPI tcuDeviceTotalMem(unsigned int *bytes, CUdevice dev); +#endif + + typedef CUresult CUDAAPI tcuDeviceGetProperties(CUdevprop *prop, CUdevice dev); + typedef CUresult CUDAAPI tcuDeviceGetAttribute(int *pi, CUdevice_attribute attrib, CUdevice dev); + + /************************************ + ** + ** Context management + ** + ***********************************/ + + typedef CUresult CUDAAPI tcuCtxCreate(CUcontext *pctx, unsigned int flags, CUdevice dev ); + typedef CUresult CUDAAPI tcuCtxDestroy( CUcontext ctx ); + typedef CUresult CUDAAPI tcuCtxAttach(CUcontext *pctx, unsigned int flags); + typedef CUresult CUDAAPI tcuCtxDetach(CUcontext ctx); + typedef CUresult CUDAAPI tcuCtxPushCurrent( CUcontext ctx ); + typedef CUresult CUDAAPI tcuCtxPopCurrent( CUcontext *pctx ); + + typedef CUresult CUDAAPI tcuCtxSetCurrent(CUcontext ctx); + typedef CUresult CUDAAPI tcuCtxGetCurrent(CUcontext *pctx); + + typedef CUresult CUDAAPI tcuCtxGetDevice(CUdevice *device); + typedef CUresult CUDAAPI tcuCtxSynchronize(void); + + + /************************************ + ** + ** Module management + ** + ***********************************/ + + typedef CUresult CUDAAPI tcuModuleLoad(CUmodule *module, const char *fname); + typedef CUresult CUDAAPI tcuModuleLoadData(CUmodule *module, const void *image); + typedef CUresult CUDAAPI tcuModuleLoadDataEx(CUmodule *module, const void *image, unsigned int numOptions, CUjit_option *options, void **optionValues); + typedef CUresult CUDAAPI tcuModuleLoadFatBinary(CUmodule *module, const void *fatCubin); + typedef CUresult CUDAAPI tcuModuleUnload(CUmodule hmod); + typedef CUresult CUDAAPI tcuModuleGetFunction(CUfunction *hfunc, CUmodule hmod, const char *name); + +#if __CUDA_API_VERSION >= 3020 + typedef CUresult CUDAAPI tcuModuleGetGlobal(CUdeviceptr *dptr, size_t *bytes, CUmodule hmod, const char *name); +#else + typedef CUresult CUDAAPI tcuModuleGetGlobal(CUdeviceptr *dptr, unsigned int *bytes, CUmodule hmod, const char *name); +#endif + + typedef CUresult CUDAAPI tcuModuleGetTexRef(CUtexref *pTexRef, CUmodule hmod, const char *name); + typedef CUresult CUDAAPI tcuModuleGetSurfRef(CUsurfref *pSurfRef, CUmodule hmod, const char *name); + + /************************************ + ** + ** Memory management + ** + ***********************************/ +#if __CUDA_API_VERSION >= 3020 + typedef CUresult CUDAAPI tcuMemGetInfo(size_t *free, size_t *total); + typedef CUresult CUDAAPI tcuMemAlloc( CUdeviceptr *dptr, size_t bytesize); + typedef CUresult CUDAAPI tcuMemGetAddressRange( CUdeviceptr *pbase, size_t *psize, CUdeviceptr dptr ); + typedef CUresult CUDAAPI tcuMemAllocPitch( CUdeviceptr *dptr, + size_t *pPitch, + size_t WidthInBytes, + size_t Height, + // size of biggest r/w to be performed by kernels on this memory + // 4, 8 or 16 bytes + unsigned int ElementSizeBytes + ); +#else + typedef CUresult CUDAAPI tcuMemGetInfo(unsigned int *free, unsigned int *total); + typedef CUresult CUDAAPI tcuMemAlloc( CUdeviceptr *dptr, unsigned int bytesize); + typedef CUresult CUDAAPI tcuMemGetAddressRange( CUdeviceptr *pbase, unsigned int *psize, CUdeviceptr dptr ); + typedef CUresult CUDAAPI tcuMemAllocPitch( CUdeviceptr *dptr, + unsigned int *pPitch, + unsigned int WidthInBytes, + unsigned int Height, + // size of biggest r/w to be performed by kernels on this memory + // 4, 8 or 16 bytes + unsigned int ElementSizeBytes + ); +#endif + + typedef CUresult CUDAAPI tcuMemFree(CUdeviceptr dptr); + +#if __CUDA_API_VERSION >= 3020 + typedef CUresult CUDAAPI tcuMemAllocHost(void **pp, size_t bytesize); +#else + typedef CUresult CUDAAPI tcuMemAllocHost(void **pp, unsigned int bytesize); +#endif + + typedef CUresult CUDAAPI tcuMemFreeHost(void *p); + typedef CUresult CUDAAPI tcuMemHostAlloc(void **pp, size_t bytesize, unsigned int Flags ); + + typedef CUresult CUDAAPI tcuMemHostGetDevicePointer( CUdeviceptr *pdptr, void *p, unsigned int Flags ); + typedef CUresult CUDAAPI tcuMemHostGetFlags( unsigned int *pFlags, void *p ); + + typedef CUresult CUDAAPI tcuMemHostRegister(void *p, size_t bytesize, unsigned int Flags); + typedef CUresult CUDAAPI tcuMemHostUnregister(void *p);; + typedef CUresult CUDAAPI tcuMemcpy(CUdeviceptr dst, CUdeviceptr src, size_t ByteCount); + typedef CUresult CUDAAPI tcuMemcpyPeer(CUdeviceptr dstDevice, CUcontext dstContext, CUdeviceptr srcDevice, CUcontext srcContext, size_t ByteCount); + + /************************************ + ** + ** Synchronous Memcpy + ** + ** Intra-device memcpy's done with these functions may execute in parallel with the CPU, + ** but if host memory is involved, they wait until the copy is done before returning. + ** + ***********************************/ + + // 1D functions +#if __CUDA_API_VERSION >= 3020 + // system <-> device memory + typedef CUresult CUDAAPI tcuMemcpyHtoD (CUdeviceptr dstDevice, const void *srcHost, size_t ByteCount ); + typedef CUresult CUDAAPI tcuMemcpyDtoH (void *dstHost, CUdeviceptr srcDevice, size_t ByteCount ); + + // device <-> device memory + typedef CUresult CUDAAPI tcuMemcpyDtoD (CUdeviceptr dstDevice, CUdeviceptr srcDevice, size_t ByteCount ); + + // device <-> array memory + typedef CUresult CUDAAPI tcuMemcpyDtoA ( CUarray dstArray, size_t dstOffset, CUdeviceptr srcDevice, size_t ByteCount ); + typedef CUresult CUDAAPI tcuMemcpyAtoD ( CUdeviceptr dstDevice, CUarray srcArray, size_t srcOffset, size_t ByteCount ); + + // system <-> array memory + typedef CUresult CUDAAPI tcuMemcpyHtoA( CUarray dstArray, size_t dstOffset, const void *srcHost, size_t ByteCount ); + typedef CUresult CUDAAPI tcuMemcpyAtoH( void *dstHost, CUarray srcArray, size_t srcOffset, size_t ByteCount ); + + // array <-> array memory + typedef CUresult CUDAAPI tcuMemcpyAtoA( CUarray dstArray, size_t dstOffset, CUarray srcArray, size_t srcOffset, size_t ByteCount ); +#else + // system <-> device memory + typedef CUresult CUDAAPI tcuMemcpyHtoD (CUdeviceptr dstDevice, const void *srcHost, unsigned int ByteCount ); + typedef CUresult CUDAAPI tcuMemcpyDtoH (void *dstHost, CUdeviceptr srcDevice, unsigned int ByteCount ); + + // device <-> device memory + typedef CUresult CUDAAPI tcuMemcpyDtoD (CUdeviceptr dstDevice, CUdeviceptr srcDevice, unsigned int ByteCount ); + + // device <-> array memory + typedef CUresult CUDAAPI tcuMemcpyDtoA ( CUarray dstArray, unsigned int dstOffset, CUdeviceptr srcDevice, unsigned int ByteCount ); + typedef CUresult CUDAAPI tcuMemcpyAtoD ( CUdeviceptr dstDevice, CUarray srcArray, unsigned int srcOffset, unsigned int ByteCount ); + + // system <-> array memory + typedef CUresult CUDAAPI tcuMemcpyHtoA( CUarray dstArray, unsigned int dstOffset, const void *srcHost, unsigned int ByteCount ); + typedef CUresult CUDAAPI tcuMemcpyAtoH( void *dstHost, CUarray srcArray, unsigned int srcOffset, unsigned int ByteCount ); + + // array <-> array memory + typedef CUresult CUDAAPI tcuMemcpyAtoA( CUarray dstArray, unsigned int dstOffset, CUarray srcArray, unsigned int srcOffset, unsigned int ByteCount ); +#endif + + // 2D memcpy + + typedef CUresult CUDAAPI tcuMemcpy2D( const CUDA_MEMCPY2D *pCopy ); + typedef CUresult CUDAAPI tcuMemcpy2DUnaligned( const CUDA_MEMCPY2D *pCopy ); + + // 3D memcpy + + typedef CUresult CUDAAPI tcuMemcpy3D( const CUDA_MEMCPY3D *pCopy ); + + /************************************ + ** + ** Asynchronous Memcpy + ** + ** Any host memory involved must be DMA'able (e.g., allocated with cuMemAllocHost). + ** memcpy's done with these functions execute in parallel with the CPU and, if + ** the hardware is available, may execute in parallel with the GPU. + ** Asynchronous memcpy must be accompanied by appropriate stream synchronization. + ** + ***********************************/ + + // 1D functions +#if __CUDA_API_VERSION >= 3020 + // system <-> device memory + typedef CUresult CUDAAPI tcuMemcpyHtoDAsync (CUdeviceptr dstDevice, + const void *srcHost, size_t ByteCount, CUstream hStream ); + typedef CUresult CUDAAPI tcuMemcpyDtoHAsync (void *dstHost, + CUdeviceptr srcDevice, size_t ByteCount, CUstream hStream ); + + // device <-> device memory + typedef CUresult CUDAAPI tcuMemcpyDtoDAsync (CUdeviceptr dstDevice, + CUdeviceptr srcDevice, size_t ByteCount, CUstream hStream ); + + // system <-> array memory + typedef CUresult CUDAAPI tcuMemcpyHtoAAsync( CUarray dstArray, size_t dstOffset, + const void *srcHost, size_t ByteCount, CUstream hStream ); + typedef CUresult CUDAAPI tcuMemcpyAtoHAsync( void *dstHost, CUarray srcArray, size_t srcOffset, + size_t ByteCount, CUstream hStream ); + +#else + // system <-> device memory + typedef CUresult CUDAAPI tcuMemcpyHtoDAsync (CUdeviceptr dstDevice, + const void *srcHost, unsigned int ByteCount, CUstream hStream ); + typedef CUresult CUDAAPI tcuMemcpyDtoHAsync (void *dstHost, + CUdeviceptr srcDevice, unsigned int ByteCount, CUstream hStream ); + + // device <-> device memory + typedef CUresult CUDAAPI tcuMemcpyDtoDAsync (CUdeviceptr dstDevice, + CUdeviceptr srcDevice, unsigned int ByteCount, CUstream hStream ); + + // system <-> array memory + typedef CUresult CUDAAPI tcuMemcpyHtoAAsync( CUarray dstArray, unsigned int dstOffset, + const void *srcHost, unsigned int ByteCount, CUstream hStream ); + typedef CUresult CUDAAPI tcuMemcpyAtoHAsync( void *dstHost, CUarray srcArray, unsigned int srcOffset, + unsigned int ByteCount, CUstream hStream ); +#endif + + // 2D memcpy + typedef CUresult CUDAAPI tcuMemcpy2DAsync( const CUDA_MEMCPY2D *pCopy, CUstream hStream ); + + // 3D memcpy + typedef CUresult CUDAAPI tcuMemcpy3DAsync( const CUDA_MEMCPY3D *pCopy, CUstream hStream ); + + /************************************ + ** + ** Memset + ** + ***********************************/ + typedef CUresult CUDAAPI tcuMemsetD8( CUdeviceptr dstDevice, unsigned char uc, unsigned int N ); + typedef CUresult CUDAAPI tcuMemsetD16( CUdeviceptr dstDevice, unsigned short us, unsigned int N ); + typedef CUresult CUDAAPI tcuMemsetD32( CUdeviceptr dstDevice, unsigned int ui, unsigned int N ); + +#if __CUDA_API_VERSION >= 3020 + typedef CUresult CUDAAPI tcuMemsetD2D8( CUdeviceptr dstDevice, unsigned int dstPitch, unsigned char uc, size_t Width, size_t Height ); + typedef CUresult CUDAAPI tcuMemsetD2D16( CUdeviceptr dstDevice, unsigned int dstPitch, unsigned short us, size_t Width, size_t Height ); + typedef CUresult CUDAAPI tcuMemsetD2D32( CUdeviceptr dstDevice, unsigned int dstPitch, unsigned int ui, size_t Width, size_t Height ); +#else + typedef CUresult CUDAAPI tcuMemsetD2D8( CUdeviceptr dstDevice, unsigned int dstPitch, unsigned char uc, unsigned int Width, unsigned int Height ); + typedef CUresult CUDAAPI tcuMemsetD2D16( CUdeviceptr dstDevice, unsigned int dstPitch, unsigned short us, unsigned int Width, unsigned int Height ); + typedef CUresult CUDAAPI tcuMemsetD2D32( CUdeviceptr dstDevice, unsigned int dstPitch, unsigned int ui, unsigned int Width, unsigned int Height ); +#endif + + /************************************ + ** + ** Function management + ** + ***********************************/ + + + typedef CUresult CUDAAPI tcuFuncSetBlockShape (CUfunction hfunc, int x, int y, int z); + typedef CUresult CUDAAPI tcuFuncSetSharedSize (CUfunction hfunc, unsigned int bytes); + typedef CUresult CUDAAPI tcuFuncGetAttribute (int *pi, CUfunction_attribute attrib, CUfunction hfunc); + typedef CUresult CUDAAPI tcuFuncSetCacheConfig(CUfunction hfunc, CUfunc_cache config); + typedef CUresult CUDAAPI tcuLaunchKernel(CUfunction f, + unsigned int gridDimX, unsigned int gridDimY, unsigned int gridDimZ, + unsigned int blockDimX, unsigned int blockDimY, unsigned int blockDimZ, + unsigned int sharedMemBytes, + CUstream hStream, void **kernelParams, void **extra); + + /************************************ + ** + ** Array management + ** + ***********************************/ + + typedef CUresult CUDAAPI tcuArrayCreate( CUarray *pHandle, const CUDA_ARRAY_DESCRIPTOR *pAllocateArray ); + typedef CUresult CUDAAPI tcuArrayGetDescriptor( CUDA_ARRAY_DESCRIPTOR *pArrayDescriptor, CUarray hArray ); + typedef CUresult CUDAAPI tcuArrayDestroy( CUarray hArray ); + + typedef CUresult CUDAAPI tcuArray3DCreate( CUarray *pHandle, const CUDA_ARRAY3D_DESCRIPTOR *pAllocateArray ); + typedef CUresult CUDAAPI tcuArray3DGetDescriptor( CUDA_ARRAY3D_DESCRIPTOR *pArrayDescriptor, CUarray hArray ); + + + /************************************ + ** + ** Texture reference management + ** + ***********************************/ + typedef CUresult CUDAAPI tcuTexRefCreate( CUtexref *pTexRef ); + typedef CUresult CUDAAPI tcuTexRefDestroy( CUtexref hTexRef ); + + typedef CUresult CUDAAPI tcuTexRefSetArray( CUtexref hTexRef, CUarray hArray, unsigned int Flags ); + +#if __CUDA_API_VERSION >= 3020 + typedef CUresult CUDAAPI tcuTexRefSetAddress( size_t *ByteOffset, CUtexref hTexRef, CUdeviceptr dptr, size_t bytes ); + typedef CUresult CUDAAPI tcuTexRefSetAddress2D( CUtexref hTexRef, const CUDA_ARRAY_DESCRIPTOR *desc, CUdeviceptr dptr, size_t Pitch); +#else + typedef CUresult CUDAAPI tcuTexRefSetAddress( unsigned int *ByteOffset, CUtexref hTexRef, CUdeviceptr dptr, unsigned int bytes ); + typedef CUresult CUDAAPI tcuTexRefSetAddress2D( CUtexref hTexRef, const CUDA_ARRAY_DESCRIPTOR *desc, CUdeviceptr dptr, unsigned int Pitch); +#endif + + typedef CUresult CUDAAPI tcuTexRefSetFormat( CUtexref hTexRef, CUarray_format fmt, int NumPackedComponents ); + typedef CUresult CUDAAPI tcuTexRefSetAddressMode( CUtexref hTexRef, int dim, CUaddress_mode am ); + typedef CUresult CUDAAPI tcuTexRefSetFilterMode( CUtexref hTexRef, CUfilter_mode fm ); + typedef CUresult CUDAAPI tcuTexRefSetFlags( CUtexref hTexRef, unsigned int Flags ); + + typedef CUresult CUDAAPI tcuTexRefGetAddress( CUdeviceptr *pdptr, CUtexref hTexRef ); + typedef CUresult CUDAAPI tcuTexRefGetArray( CUarray *phArray, CUtexref hTexRef ); + typedef CUresult CUDAAPI tcuTexRefGetAddressMode( CUaddress_mode *pam, CUtexref hTexRef, int dim ); + typedef CUresult CUDAAPI tcuTexRefGetFilterMode( CUfilter_mode *pfm, CUtexref hTexRef ); + typedef CUresult CUDAAPI tcuTexRefGetFormat( CUarray_format *pFormat, int *pNumChannels, CUtexref hTexRef ); + typedef CUresult CUDAAPI tcuTexRefGetFlags( unsigned int *pFlags, CUtexref hTexRef ); + + /************************************ + ** + ** Surface reference management + ** + ***********************************/ + + typedef CUresult CUDAAPI tcuSurfRefSetArray( CUsurfref hSurfRef, CUarray hArray, unsigned int Flags ); + typedef CUresult CUDAAPI tcuSurfRefGetArray( CUarray *phArray, CUsurfref hSurfRef ); + + /************************************ + ** + ** Parameter management + ** + ***********************************/ + + typedef CUresult CUDAAPI tcuParamSetSize (CUfunction hfunc, unsigned int numbytes); + typedef CUresult CUDAAPI tcuParamSeti (CUfunction hfunc, int offset, unsigned int value); + typedef CUresult CUDAAPI tcuParamSetf (CUfunction hfunc, int offset, float value); + typedef CUresult CUDAAPI tcuParamSetv (CUfunction hfunc, int offset, void *ptr, unsigned int numbytes); + typedef CUresult CUDAAPI tcuParamSetTexRef(CUfunction hfunc, int texunit, CUtexref hTexRef); + + + /************************************ + ** + ** Launch functions + ** + ***********************************/ + + typedef CUresult CUDAAPI tcuLaunch ( CUfunction f ); + typedef CUresult CUDAAPI tcuLaunchGrid (CUfunction f, int grid_width, int grid_height); + typedef CUresult CUDAAPI tcuLaunchGridAsync( CUfunction f, int grid_width, int grid_height, CUstream hStream ); + + /************************************ + ** + ** Events + ** + ***********************************/ + typedef CUresult CUDAAPI tcuEventCreate( CUevent *phEvent, unsigned int Flags ); + typedef CUresult CUDAAPI tcuEventRecord( CUevent hEvent, CUstream hStream ); + typedef CUresult CUDAAPI tcuEventQuery( CUevent hEvent ); + typedef CUresult CUDAAPI tcuEventSynchronize( CUevent hEvent ); + typedef CUresult CUDAAPI tcuEventDestroy( CUevent hEvent ); + typedef CUresult CUDAAPI tcuEventElapsedTime( float *pMilliseconds, CUevent hStart, CUevent hEnd ); + + /************************************ + ** + ** Streams + ** + ***********************************/ + typedef CUresult CUDAAPI tcuStreamCreate( CUstream *phStream, unsigned int Flags ); + typedef CUresult CUDAAPI tcuStreamQuery( CUstream hStream ); + typedef CUresult CUDAAPI tcuStreamSynchronize( CUstream hStream ); + typedef CUresult CUDAAPI tcuStreamDestroy( CUstream hStream ); + + /************************************ + ** + ** Graphics interop + ** + ***********************************/ + typedef CUresult CUDAAPI tcuGraphicsUnregisterResource(CUgraphicsResource resource); + typedef CUresult CUDAAPI tcuGraphicsSubResourceGetMappedArray( CUarray *pArray, CUgraphicsResource resource, unsigned int arrayIndex, unsigned int mipLevel ); + +#if __CUDA_API_VERSION >= 3020 + typedef CUresult CUDAAPI tcuGraphicsResourceGetMappedPointer( CUdeviceptr *pDevPtr, size_t *pSize, CUgraphicsResource resource ); +#else + typedef CUresult CUDAAPI tcuGraphicsResourceGetMappedPointer( CUdeviceptr *pDevPtr, unsigned int *pSize, CUgraphicsResource resource ); +#endif + + typedef CUresult CUDAAPI tcuGraphicsResourceSetMapFlags( CUgraphicsResource resource, unsigned int flags ); + typedef CUresult CUDAAPI tcuGraphicsMapResources( unsigned int count, CUgraphicsResource *resources, CUstream hStream ); + typedef CUresult CUDAAPI tcuGraphicsUnmapResources( unsigned int count, CUgraphicsResource *resources, CUstream hStream ); + + /************************************ + ** + ** Export tables + ** + ***********************************/ + typedef CUresult CUDAAPI tcuGetExportTable( const void **ppExportTable, const CUuuid *pExportTableId ); + + /************************************ + ** + ** Limits + ** + ***********************************/ + + typedef CUresult CUDAAPI tcuCtxSetLimit(CUlimit limit, size_t value); + typedef CUresult CUDAAPI tcuCtxGetLimit(size_t *pvalue, CUlimit limit); + + + /************************************ + ************************************/ + + extern CUresult CUDAAPI cuInit(unsigned int, int cudaVersion); + + extern tcuDriverGetVersion *cuDriverGetVersion; + extern tcuDeviceGet *cuDeviceGet; + extern tcuDeviceGetCount *cuDeviceGetCount; + extern tcuDeviceGetName *cuDeviceGetName; + extern tcuDeviceComputeCapability *cuDeviceComputeCapability; + extern tcuDeviceGetProperties *cuDeviceGetProperties; + extern tcuDeviceGetAttribute *cuDeviceGetAttribute; + extern tcuCtxDestroy *cuCtxDestroy; + extern tcuCtxAttach *cuCtxAttach; + extern tcuCtxDetach *cuCtxDetach; + extern tcuCtxPushCurrent *cuCtxPushCurrent; + extern tcuCtxPopCurrent *cuCtxPopCurrent; + + extern tcuCtxSetCurrent *cuCtxSetCurrent; + extern tcuCtxGetCurrent *cuCtxGetCurrent; + + extern tcuCtxGetDevice *cuCtxGetDevice; + extern tcuCtxSynchronize *cuCtxSynchronize; + extern tcuModuleLoad *cuModuleLoad; + extern tcuModuleLoadData *cuModuleLoadData; + extern tcuModuleLoadDataEx *cuModuleLoadDataEx; + extern tcuModuleLoadFatBinary *cuModuleLoadFatBinary; + extern tcuModuleUnload *cuModuleUnload; + extern tcuModuleGetFunction *cuModuleGetFunction; + extern tcuModuleGetTexRef *cuModuleGetTexRef; + extern tcuModuleGetSurfRef *cuModuleGetSurfRef; + extern tcuMemFreeHost *cuMemFreeHost; + extern tcuMemHostAlloc *cuMemHostAlloc; + extern tcuMemHostGetFlags *cuMemHostGetFlags; + + extern tcuMemHostRegister *cuMemHostRegister; + extern tcuMemHostUnregister *cuMemHostUnregister; + extern tcuMemcpy *cuMemcpy; + extern tcuMemcpyPeer *cuMemcpyPeer; + + extern tcuDeviceTotalMem *cuDeviceTotalMem; + extern tcuCtxCreate *cuCtxCreate; + extern tcuModuleGetGlobal *cuModuleGetGlobal; + extern tcuMemGetInfo *cuMemGetInfo; + extern tcuMemAlloc *cuMemAlloc; + extern tcuMemAllocPitch *cuMemAllocPitch; + extern tcuMemFree *cuMemFree; + extern tcuMemGetAddressRange *cuMemGetAddressRange; + extern tcuMemAllocHost *cuMemAllocHost; + extern tcuMemHostGetDevicePointer *cuMemHostGetDevicePointer; + extern tcuFuncSetBlockShape *cuFuncSetBlockShape; + extern tcuFuncSetSharedSize *cuFuncSetSharedSize; + extern tcuFuncGetAttribute *cuFuncGetAttribute; + extern tcuFuncSetCacheConfig *cuFuncSetCacheConfig; + extern tcuLaunchKernel *cuLaunchKernel; + extern tcuArrayDestroy *cuArrayDestroy; + extern tcuTexRefCreate *cuTexRefCreate; + extern tcuTexRefDestroy *cuTexRefDestroy; + extern tcuTexRefSetArray *cuTexRefSetArray; + extern tcuTexRefSetFormat *cuTexRefSetFormat; + extern tcuTexRefSetAddressMode *cuTexRefSetAddressMode; + extern tcuTexRefSetFilterMode *cuTexRefSetFilterMode; + extern tcuTexRefSetFlags *cuTexRefSetFlags; + extern tcuTexRefGetArray *cuTexRefGetArray; + extern tcuTexRefGetAddressMode *cuTexRefGetAddressMode; + extern tcuTexRefGetFilterMode *cuTexRefGetFilterMode; + extern tcuTexRefGetFormat *cuTexRefGetFormat; + extern tcuTexRefGetFlags *cuTexRefGetFlags; + extern tcuSurfRefSetArray *cuSurfRefSetArray; + extern tcuSurfRefGetArray *cuSurfRefGetArray; + extern tcuParamSetSize *cuParamSetSize; + extern tcuParamSeti *cuParamSeti; + extern tcuParamSetf *cuParamSetf; + extern tcuParamSetv *cuParamSetv; + extern tcuParamSetTexRef *cuParamSetTexRef; + extern tcuLaunch *cuLaunch; + extern tcuLaunchGrid *cuLaunchGrid; + extern tcuLaunchGridAsync *cuLaunchGridAsync; + extern tcuEventCreate *cuEventCreate; + extern tcuEventRecord *cuEventRecord; + extern tcuEventQuery *cuEventQuery; + extern tcuEventSynchronize *cuEventSynchronize; + extern tcuEventDestroy *cuEventDestroy; + extern tcuEventElapsedTime *cuEventElapsedTime; + extern tcuStreamCreate *cuStreamCreate; + extern tcuStreamQuery *cuStreamQuery; + extern tcuStreamSynchronize *cuStreamSynchronize; + extern tcuStreamDestroy *cuStreamDestroy; + extern tcuGraphicsUnregisterResource *cuGraphicsUnregisterResource; + extern tcuGraphicsSubResourceGetMappedArray *cuGraphicsSubResourceGetMappedArray; + extern tcuGraphicsResourceSetMapFlags *cuGraphicsResourceSetMapFlags; + extern tcuGraphicsMapResources *cuGraphicsMapResources; + extern tcuGraphicsUnmapResources *cuGraphicsUnmapResources; + extern tcuGetExportTable *cuGetExportTable; + extern tcuCtxSetLimit *cuCtxSetLimit; + extern tcuCtxGetLimit *cuCtxGetLimit; + +// These functions could be using the CUDA 3.2 interface (_v2) + extern tcuMemcpyHtoD *cuMemcpyHtoD; + extern tcuMemcpyDtoH *cuMemcpyDtoH; + extern tcuMemcpyDtoD *cuMemcpyDtoD; + extern tcuMemcpyDtoA *cuMemcpyDtoA; + extern tcuMemcpyAtoD *cuMemcpyAtoD; + extern tcuMemcpyHtoA *cuMemcpyHtoA; + extern tcuMemcpyAtoH *cuMemcpyAtoH; + extern tcuMemcpyAtoA *cuMemcpyAtoA; + extern tcuMemcpy2D *cuMemcpy2D; + extern tcuMemcpy2DUnaligned *cuMemcpy2DUnaligned; + extern tcuMemcpy3D *cuMemcpy3D; + extern tcuMemcpyHtoDAsync *cuMemcpyHtoDAsync; + extern tcuMemcpyDtoHAsync *cuMemcpyDtoHAsync; + extern tcuMemcpyDtoDAsync *cuMemcpyDtoDAsync; + extern tcuMemcpyHtoAAsync *cuMemcpyHtoAAsync; + extern tcuMemcpyAtoHAsync *cuMemcpyAtoHAsync; + extern tcuMemcpy2DAsync *cuMemcpy2DAsync; + extern tcuMemcpy3DAsync *cuMemcpy3DAsync; + extern tcuMemsetD8 *cuMemsetD8; + extern tcuMemsetD16 *cuMemsetD16; + extern tcuMemsetD32 *cuMemsetD32; + extern tcuMemsetD2D8 *cuMemsetD2D8; + extern tcuMemsetD2D16 *cuMemsetD2D16; + extern tcuMemsetD2D32 *cuMemsetD2D32; + extern tcuArrayCreate *cuArrayCreate; + extern tcuArrayGetDescriptor *cuArrayGetDescriptor; + extern tcuArray3DCreate *cuArray3DCreate; + extern tcuArray3DGetDescriptor *cuArray3DGetDescriptor; + extern tcuTexRefSetAddress *cuTexRefSetAddress; + extern tcuTexRefSetAddress2D *cuTexRefSetAddress2D; + extern tcuTexRefGetAddress *cuTexRefGetAddress; + extern tcuGraphicsResourceGetMappedPointer *cuGraphicsResourceGetMappedPointer; + +#ifdef __cplusplus +} +#endif + +//#undef __CUDA_API_VERSION + +#endif //__cuda_drvapi_dynlink_cuda_h__ diff --git a/external/cutil/inc/dynlink/cuda_drvapi_dynlink_d3d.h b/external/cutil/inc/dynlink/cuda_drvapi_dynlink_d3d.h new file mode 100644 index 0000000..d4d9c8a --- /dev/null +++ b/external/cutil/inc/dynlink/cuda_drvapi_dynlink_d3d.h @@ -0,0 +1,108 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +#ifndef __cuda_drvapi_dynlink_d3d_h__ +#define __cuda_drvapi_dynlink_d3d_h__ + +#if defined(_WIN32) + #pragma warning(disable: 4312) + + #if defined (CUDA_INIT_D3D9) || defined(CUDA_INIT_D3D10) || defined(CUDA_INIT_D3D11) + #include + #include + #endif + + #ifdef CUDA_INIT_D3D9 + #include + #pragma warning( disable : 4996 ) // disable deprecated warning + #include + #pragma warning( default : 4996 ) + + /** + * CUDA 2.x compatibility - Flags to register a D3D9 graphics resource + */ + typedef enum CUd3d9register_flags_enum { + CU_D3D9_REGISTER_FLAGS_NONE = 0x00, + CU_D3D9_REGISTER_FLAGS_ARRAY = 0x01, + } CUd3d9register_flags; + + /** + * CUDA 2.x compatibility - Flags for D3D9 mapping and unmapping interop resources + */ + typedef enum CUd3d9map_flags_enum { + CU_D3D9_MAPRESOURCE_FLAGS_NONE = 0x00, + CU_D3D9_MAPRESOURCE_FLAGS_READONLY = 0x01, + CU_D3D9_MAPRESOURCE_FLAGS_WRITEDISCARD = 0x02, + } CUd3d9map_flags; + + // D3D9/CUDA interop (CUDA 1.x compatible API). These functions are deprecated, please use the ones below + typedef CUresult CUDAAPI tcuD3D9Begin( IDirect3DDevice9 *pDevice ); + typedef CUresult CUDAAPI tcuD3D9End( void ); + typedef CUresult CUDAAPI tcuD3D9RegisterVertexBuffer( IDirect3DVertexBuffer9 *pVB ); + typedef CUresult CUDAAPI tcuD3D9MapVertexBuffer( CUdeviceptr *pDevPtr, unsigned int *pSize, IDirect3DVertexBuffer9 *pVB ); + typedef CUresult CUDAAPI tcuD3D9UnmapVertexBuffer( IDirect3DVertexBuffer9 *pVB ); + typedef CUresult CUDAAPI tcuD3D9UnregisterVertexBuffer( IDirect3DVertexBuffer9 *pVB ); + + // D3D9/CUDA interop (CUDA 2.x compatible) + typedef CUresult CUDAAPI tcuD3D9GetDirect3DDevice( IDirect3DDevice9 **ppD3DDevice ); + typedef CUresult CUDAAPI tcuD3D9RegisterResource( IDirect3DResource9 *pResource, unsigned int Flags ); + typedef CUresult CUDAAPI tcuD3D9UnregisterResource( IDirect3DResource9 *pResource ); + + typedef CUresult CUDAAPI tcuD3D9MapResources( unsigned int count, IDirect3DResource9 **ppResource ); + typedef CUresult CUDAAPI tcuD3D9UnmapResources( unsigned int count, IDirect3DResource9 **ppResource ); + typedef CUresult CUDAAPI tcuD3D9ResourceSetMapFlags( IDirect3DResource9 *pResource, unsigned int Flags ); + + typedef CUresult CUDAAPI tcuD3D9ResourceGetSurfaceDimensions( unsigned int *pWidth, unsigned int *pHeight, unsigned int *pDepth, IDirect3DResource9 *pResource, unsigned int Face, unsigned int Level ); + typedef CUresult CUDAAPI tcuD3D9ResourceGetMappedArray( CUarray *pArray, IDirect3DResource9 *pResource, unsigned int Face, unsigned int Level ); + typedef CUresult CUDAAPI tcuD3D9ResourceGetMappedPointer( CUdeviceptr *pDevPtr, IDirect3DResource9 *pResource, unsigned int Face, unsigned int Level ); + typedef CUresult CUDAAPI tcuD3D9ResourceGetMappedSize( unsigned int *pSize, IDirect3DResource9 *pResource, unsigned int Face, unsigned int Level ); + typedef CUresult CUDAAPI tcuD3D9ResourceGetMappedPitch( unsigned int *pPitch, unsigned int *pPitchSlice, IDirect3DResource9 *pResource, unsigned int Face, unsigned int Level ); + + // D3D9/CUDA interop (CUDA 2.0+) + typedef CUresult CUDAAPI tcuD3D9GetDevice( CUdevice *pCudaDevice, const char *pszAdapterName); + typedef CUresult CUDAAPI tcuD3D9CtxCreate( CUcontext *pCtx, CUdevice *pCudaDevice, unsigned int Flags, IDirect3DDevice9 *pD3DDevice ); + typedef CUresult CUDAAPI tcuGraphicsD3D9RegisterResource( CUgraphicsResource *pCudaResource, IDirect3DResource9 *pD3DResource, unsigned int Flags ); + #endif + + #ifdef CUDA_INIT_D3D10 + #include + #include + #include + #include + + #pragma warning( disable : 4996 ) // disable deprecated warning + #include + #pragma warning( default : 4996 ) + + // D3D11/CUDA interop (CUDA 3.0) + typedef CUresult CUDAAPI tcuD3D10GetDevice( CUdevice *pCudaDevice, IDXGIAdapter *pAdapter ); + typedef CUresult CUDAAPI tcuD3D10CtxCreate( CUcontext *pCtx, CUdevice *pCudaDevice, unsigned int Flags, ID3D10Device *pD3DDevice ); + typedef CUresult CUDAAPI tcuGraphicsD3D10RegisterResource( CUgraphicsResource *pCudaResource, ID3D10Resource *pD3DResource, unsigned int Flags ); + #endif // CUDA_INIT_D3D10 + + #ifdef CUDA_INIT_D3D11 + #include + #include + #include + + #pragma warning( disable : 4996 ) // disable deprecated warning + #include + #pragma warning( default : 4996 ) + + // D3D11/CUDA interop (CUDA 3.0) + typedef CUresult CUDAAPI tcuD3D11GetDevice( CUdevice *pCudaDevice, IDXGIAdapter *pAdapter ); + typedef CUresult CUDAAPI tcuD3D11CtxCreate( CUcontext *pCtx, CUdevice *pCudaDevice, unsigned int Flags, ID3D11Device *pD3DDevice ); + typedef CUresult CUDAAPI tcuGraphicsD3D11RegisterResource( CUgraphicsResource *pCudaResource, ID3D11Resource *pD3DResource, unsigned int Flags ); + #endif // CUDA_INIT_D3D11 + +#endif // WIN32 + +#endif // __cuda_drvapi_dynlink_cuda_d3d_h__ diff --git a/external/cutil/inc/dynlink/cuda_drvapi_dynlink_gl.h b/external/cutil/inc/dynlink/cuda_drvapi_dynlink_gl.h new file mode 100644 index 0000000..0de80f1 --- /dev/null +++ b/external/cutil/inc/dynlink/cuda_drvapi_dynlink_gl.h @@ -0,0 +1,58 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +#ifndef __cuda_drvapi_dynlink_cuda_gl_h__ +#define __cuda_drvapi_dynlink_cuda_gl_h__ + +#ifdef CUDA_INIT_OPENGL + + #ifdef _WIN32 + # define WINDOWS_LEAN_AND_MEAN + # define NOMINMAX + # include + #endif + + // includes, system + #include + #include + #include + #include + + // includes, GL + #include + + #if defined (__APPLE__) || defined(MACOSX) + #include + #else + #include + #endif + + /************************************ + ** + ** OpenGL Graphics/Interop + ** + ***********************************/ + + // OpenGL/CUDA interop (CUDA 2.0+) + typedef CUresult CUDAAPI tcuGLCtxCreate( CUcontext *pCtx, unsigned int Flags, CUdevice device ); + typedef CUresult CUDAAPI tcuGraphicsGLRegisterBuffer( CUgraphicsResource *pCudaResource, GLuint buffer, unsigned int Flags ); + typedef CUresult CUDAAPI tcuGraphicsGLRegisterImage( CUgraphicsResource *pCudaResource, GLuint image, GLenum target, unsigned int Flags ); + + #ifdef _WIN32 + #include + // WIN32 + typedef CUresult CUDAAPI tcuWGLGetDevice( CUdevice *pDevice, HGPUNV hGpu ); + #endif + +#endif // CUDA_INIT_OPENGL + +#endif // __cuda_drvapi_dynlink_cuda_gl_h__ + diff --git a/external/cutil/inc/dynlink_d3d10.h b/external/cutil/inc/dynlink_d3d10.h new file mode 100644 index 0000000..fee2ec0 --- /dev/null +++ b/external/cutil/inc/dynlink_d3d10.h @@ -0,0 +1,285 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + //-------------------------------------------------------------------------------------- +// File: dynlink_d3d10.h +// +// Shortcut macros and functions for using DX objects +// +// Copyright (c) Microsoft Corporation. All rights reserved +//-------------------------------------------------------------------------------------- + +#ifndef _DYNLINK_D3D10_H_ +#define _DYNLINK_D3D10_H_ + +// Standard Windows includes +#include +#include +#include +#include +#include +#include // for InitCommonControls() +#include // for ExtractIcon() +#include // for placement new +#include +#include +#include +#include + +// CRT's memory leak detection +#if defined(DEBUG) || defined(_DEBUG) +#include +#endif + +// Direct3D9 includes +#include +#include + +// Direct3D10 includes +#include +#include +#include +#include + +// XInput includes +#include + +// HRESULT translation for Direct3D10 and other APIs +#include + +// strsafe.h deprecates old unsecure string functions. If you +// really do not want to it to (not recommended), then uncomment the next line +//#define STRSAFE_NO_DEPRECATE + +#ifndef STRSAFE_NO_DEPRECATE +#pragma deprecated("strncpy") +#pragma deprecated("wcsncpy") +#pragma deprecated("_tcsncpy") +#pragma deprecated("wcsncat") +#pragma deprecated("strncat") +#pragma deprecated("_tcsncat") +#endif + +#pragma warning( disable : 4996 ) // disable deprecated warning +#include +#pragma warning( default : 4996 ) + +//-------------------------------------------------------------------------------------- +// Structs +//-------------------------------------------------------------------------------------- +struct DXUTD3D9DeviceSettings +{ + UINT AdapterOrdinal; + D3DDEVTYPE DeviceType; + D3DFORMAT AdapterFormat; + DWORD BehaviorFlags; + D3DPRESENT_PARAMETERS pp; +}; + +struct DXUTD3D10DeviceSettings +{ + UINT AdapterOrdinal; + D3D10_DRIVER_TYPE DriverType; + UINT Output; + DXGI_SWAP_CHAIN_DESC sd; + UINT32 CreateFlags; + UINT32 SyncInterval; + DWORD PresentFlags; + bool AutoCreateDepthStencil; // DXUT will create the a depth stencil resource and view if true + DXGI_FORMAT AutoDepthStencilFormat; +}; + +enum DXUTDeviceVersion { DXUT_D3D9_DEVICE, DXUT_D3D10_DEVICE }; +struct DXUTDeviceSettings +{ + DXUTDeviceVersion ver; + union + { + DXUTD3D9DeviceSettings d3d9; // only valid if ver == DXUT_D3D9_DEVICE + DXUTD3D10DeviceSettings d3d10; // only valid if ver == DXUT_D3D10_DEVICE + }; +}; + + +//-------------------------------------------------------------------------------------- +// Error codes +//-------------------------------------------------------------------------------------- +#define DXUTERR_NODIRECT3D MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0901) +#define DXUTERR_NOCOMPATIBLEDEVICES MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0902) +#define DXUTERR_MEDIANOTFOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0903) +#define DXUTERR_NONZEROREFCOUNT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0904) +#define DXUTERR_CREATINGDEVICE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0905) +#define DXUTERR_RESETTINGDEVICE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0906) +#define DXUTERR_CREATINGDEVICEOBJECTS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0907) +#define DXUTERR_RESETTINGDEVICEOBJECTS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0908) +#define DXUTERR_DEVICEREMOVED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x090A) + + +typedef HRESULT ( WINAPI* LPCREATEDXGIFACTORY )( REFIID, void** ); +typedef HRESULT ( WINAPI* LPD3D10CREATEDEVICE )( IDXGIAdapter*, D3D10_DRIVER_TYPE, HMODULE, UINT, UINT32, + ID3D10Device** ); +typedef HRESULT ( WINAPI* LPD3D10CREATEDEVICE1 )( IDXGIAdapter*, D3D10_DRIVER_TYPE, HMODULE, UINT, + D3D10_FEATURE_LEVEL1, UINT, ID3D10Device1** ); +typedef HRESULT ( WINAPI* LPD3D10CREATESTATEBLOCK )( ID3D10Device* pDevice, D3D10_STATE_BLOCK_MASK* pStateBlockMask, + ID3D10StateBlock** ppStateBlock ); +typedef HRESULT ( WINAPI* LPD3D10STATEBLOCKMASKUNION )( D3D10_STATE_BLOCK_MASK* pA, D3D10_STATE_BLOCK_MASK* pB, + D3D10_STATE_BLOCK_MASK* pResult ); +typedef HRESULT ( WINAPI* LPD3D10STATEBLOCKMASKINTERSECT )( D3D10_STATE_BLOCK_MASK* pA, D3D10_STATE_BLOCK_MASK* pB, + D3D10_STATE_BLOCK_MASK* pResult ); +typedef HRESULT ( WINAPI* LPD3D10STATEBLOCKMASKDIFFERENCE )( D3D10_STATE_BLOCK_MASK* pA, D3D10_STATE_BLOCK_MASK* pB, + D3D10_STATE_BLOCK_MASK* pResult ); +typedef HRESULT ( WINAPI* LPD3D10STATEBLOCKMASKENABLECAPTURE )( D3D10_STATE_BLOCK_MASK* pMask, + D3D10_DEVICE_STATE_TYPES StateType, UINT RangeStart, + UINT RangeLength ); +typedef HRESULT ( WINAPI* LPD3D10STATEBLOCKMASKDISABLECAPTURE )( D3D10_STATE_BLOCK_MASK* pMask, + D3D10_DEVICE_STATE_TYPES StateType, UINT RangeStart, + UINT RangeLength ); +typedef HRESULT ( WINAPI* LPD3D10STATEBLOCKMASKENABLEALL )( D3D10_STATE_BLOCK_MASK* pMask ); +typedef HRESULT ( WINAPI* LPD3D10STATEBLOCKMASKDISABLEALL )( D3D10_STATE_BLOCK_MASK* pMask ); +typedef BOOL ( WINAPI* LPD3D10STATEBLOCKMASKGETSETTING )( D3D10_STATE_BLOCK_MASK* pMask, + D3D10_DEVICE_STATE_TYPES StateType, UINT Entry ); + +typedef HRESULT ( WINAPI* LPD3D10COMPILEEFFECTFROMMEMORY )( void *pData, SIZE_T DataLength, LPCSTR pSrcFileName, + CONST D3D10_SHADER_MACRO *pDefines, + ID3D10Include *pInclude, UINT HLSLFlags, UINT FXFlags, + ID3D10Blob **ppCompiledEffect, ID3D10Blob **ppErrors ); +typedef HRESULT ( WINAPI* LPD3D10CREATEEFFECTFROMMEMORY )( void *pData, SIZE_T DataLength, UINT FXFlags, + ID3D10Device *pDevice, + ID3D10EffectPool *pEffectPool, + ID3D10Effect **ppEffect ); +typedef HRESULT ( WINAPI* LPD3D10CREATEEFFECTPOOLFROMMEMORY )( void *pData, SIZE_T DataLength, UINT FXFlags, + ID3D10Device *pDevice, ID3D10EffectPool **ppEffectPool ); + +typedef HRESULT ( WINAPI* LPD3D10CREATEDEVICEANDSWAPCHAIN )( IDXGIAdapter *pAdapter, + D3D10_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + UINT SDKVersion, + DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, + IDXGISwapChain **ppSwapChain, + ID3D10Device **ppDevice ); + +typedef HRESULT ( WINAPI* LPD3D10CREATEDEVICEANDSWAPCHAIN1 )( IDXGIAdapter *pAdapter, + D3D10_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + D3D10_FEATURE_LEVEL1 HardwareLevel, + UINT SDKVersion, + DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, + IDXGISwapChain **ppSwapChain, + ID3D10Device1 **ppDevice ); + +// Build a perspective projection matrix. (left-handed) +typedef D3DXMATRIX* ( WINAPI* LPD3DXMATRIXPERSPECTIVEFOVLH )( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); + +// Build a lookat matrix. (left-handed) +typedef D3DXMATRIX* ( WINAPI* LPD3DXMATRIXLOOKATLH ) ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, CONST D3DXVECTOR3 *pUp ); + +// Module and function pointers +static HMODULE g_hModDXGI = NULL; +static HMODULE g_hModD3DX10 = NULL; +static HMODULE g_hModD3D10 = NULL; +static HMODULE g_hModD3D101 = NULL; +static LPCREATEDXGIFACTORY sFnPtr_CreateDXGIFactory = NULL; +static LPD3D10CREATESTATEBLOCK sFnPtr_D3D10CreateStateBlock = NULL; +static LPD3D10CREATEDEVICE sFnPtr_D3D10CreateDevice = NULL; +static LPD3D10CREATEDEVICE1 sFnPtr_D3D10CreateDevice1 = NULL; +static LPD3D10STATEBLOCKMASKUNION sFnPtr_D3D10StateBlockMaskUnion = NULL; +static LPD3D10STATEBLOCKMASKINTERSECT sFnPtr_D3D10StateBlockMaskIntersect = NULL; +static LPD3D10STATEBLOCKMASKDIFFERENCE sFnPtr_D3D10StateBlockMaskDifference = NULL; +static LPD3D10STATEBLOCKMASKENABLECAPTURE sFnPtr_D3D10StateBlockMaskEnableCapture = NULL; +static LPD3D10STATEBLOCKMASKDISABLECAPTURE sFnPtr_D3D10StateBlockMaskDisableCapture = NULL; +static LPD3D10STATEBLOCKMASKENABLEALL sFnPtr_D3D10StateBlockMaskEnableAll = NULL; +static LPD3D10STATEBLOCKMASKDISABLEALL sFnPtr_D3D10StateBlockMaskDisableAll = NULL; +static LPD3D10STATEBLOCKMASKGETSETTING sFnPtr_D3D10StateBlockMaskGetSetting = NULL; +static LPD3D10COMPILEEFFECTFROMMEMORY sFnPtr_D3D10CompileEffectFromMemory = NULL; +static LPD3D10CREATEEFFECTFROMMEMORY sFnPtr_D3D10CreateEffectFromMemory = NULL; +static LPD3D10CREATEEFFECTPOOLFROMMEMORY sFnPtr_D3D10CreateEffectPoolFromMemory = NULL; +static LPD3D10CREATEDEVICEANDSWAPCHAIN sFnPtr_D3D10CreateDeviceAndSwapChain = NULL; +static LPD3D10CREATEDEVICEANDSWAPCHAIN1 sFnPtr_D3D10CreateDeviceAndSwapChain1 = NULL; +static LPD3DXMATRIXPERSPECTIVEFOVLH sFnPtr_D3DXMatrixPerspectiveFovLH = NULL; +static LPD3DXMATRIXLOOKATLH sFnPtr_D3DXMatrixLookAtLH = NULL; + +// unload the D3D10 DLLs +static bool dynlinkUnloadD3D10API( void ) +{ + if (g_hModD3D10) { + FreeLibrary( g_hModD3D10 ); g_hModD3D10 = NULL; + } + if (g_hModD3DX10) { + FreeLibrary( g_hModD3DX10 ); g_hModD3DX10 = NULL; + } + if (g_hModDXGI) { + FreeLibrary( g_hModDXGI ); g_hModDXGI = NULL; + } + if (g_hModD3D101) { + FreeLibrary( g_hModD3D101 ); g_hModD3D101 = NULL; + } + return true; +} + +// Dynamically load the D3D10 DLLs loaded and map the function pointers +static bool dynlinkLoadD3D10API( void ) +{ + // First check to see if the D3D10 Library is present. + // if it succeeds, then we can call GetProcAddress to grab all of the DX10 functions + g_hModD3D10 = LoadLibrary("d3d10.dll"); + if( g_hModD3D10 != NULL ) + { + sFnPtr_D3D10CreateStateBlock = ( LPD3D10CREATESTATEBLOCK ) GetProcAddress( g_hModD3D10, "D3D10CreateStateBlock" ); + sFnPtr_D3D10CreateDevice = ( LPD3D10CREATEDEVICE ) GetProcAddress( g_hModD3D10, "D3D10CreateDevice" ); + + sFnPtr_D3D10StateBlockMaskUnion = ( LPD3D10STATEBLOCKMASKUNION ) GetProcAddress( g_hModD3D10, "D3D10StateBlockMaskUnion" ); + sFnPtr_D3D10StateBlockMaskIntersect = ( LPD3D10STATEBLOCKMASKINTERSECT ) GetProcAddress( g_hModD3D10, "D3D10StateBlockMaskIntersect" ); + sFnPtr_D3D10StateBlockMaskDifference = ( LPD3D10STATEBLOCKMASKDIFFERENCE ) GetProcAddress( g_hModD3D10, "D3D10StateBlockMaskDifference" ); + sFnPtr_D3D10StateBlockMaskEnableCapture = ( LPD3D10STATEBLOCKMASKENABLECAPTURE) GetProcAddress( g_hModD3D10, "D3D10StateBlockMaskEnableCapture" ); + sFnPtr_D3D10StateBlockMaskDisableCapture = ( LPD3D10STATEBLOCKMASKDISABLECAPTURE)GetProcAddress( g_hModD3D10, "D3D10StateBlockMaskDisableCapture" ); + + sFnPtr_D3D10StateBlockMaskEnableAll = ( LPD3D10STATEBLOCKMASKENABLEALL ) GetProcAddress( g_hModD3D10, "D3D10StateBlockMaskEnableAll" ); + sFnPtr_D3D10StateBlockMaskDisableAll = ( LPD3D10STATEBLOCKMASKDISABLEALL ) GetProcAddress( g_hModD3D10, "D3D10StateBlockMaskDisableAll" ); + sFnPtr_D3D10StateBlockMaskGetSetting = ( LPD3D10STATEBLOCKMASKGETSETTING ) GetProcAddress( g_hModD3D10, "D3D10StateBlockMaskGetSetting" ); + + sFnPtr_D3D10CompileEffectFromMemory = ( LPD3D10COMPILEEFFECTFROMMEMORY ) GetProcAddress( g_hModD3D10, "D3D10CompileEffectFromMemory" ); + sFnPtr_D3D10CreateEffectFromMemory = ( LPD3D10CREATEEFFECTFROMMEMORY ) GetProcAddress( g_hModD3D10, "D3D10CreateEffectFromMemory" ); + sFnPtr_D3D10CreateEffectPoolFromMemory = ( LPD3D10CREATEEFFECTPOOLFROMMEMORY ) GetProcAddress( g_hModD3D10, "D3D10CreateEffectPoolFromMemory" ); + + sFnPtr_D3D10CreateDeviceAndSwapChain = (LPD3D10CREATEDEVICEANDSWAPCHAIN ) GetProcAddress( g_hModD3D10, "D3D10CreateDeviceAndSwapChain" ); + } + + g_hModD3DX10 = LoadLibrary( "d3dx10.dll" ); + if ( g_hModD3DX10 ) + { + sFnPtr_D3DXMatrixPerspectiveFovLH = ( LPD3DXMATRIXPERSPECTIVEFOVLH ) GetProcAddress( g_hModD3DX10, "D3DXMatrixPerspectiveFovLH" ); + sFnPtr_D3DXMatrixLookAtLH = ( LPD3DXMATRIXLOOKATLH ) GetProcAddress( g_hModD3DX10, "D3DXMatrixLookAtLH" ); + } + + g_hModDXGI = LoadLibrary( "dxgi.dll" ); + if( g_hModDXGI ) + { + sFnPtr_CreateDXGIFactory = ( LPCREATEDXGIFACTORY ) GetProcAddress( g_hModDXGI , "CreateDXGIFactory" ); + } + + // This may fail if this machine isn't Windows Vista SP1 or later + g_hModD3D101 = LoadLibrary( "d3d10_1.dll" ); + if( g_hModD3D101 != NULL ) + { + sFnPtr_D3D10CreateDevice1 = ( LPD3D10CREATEDEVICE1 ) GetProcAddress( g_hModD3D101, "D3D10CreateDevice1" ); + sFnPtr_D3D10CreateDeviceAndSwapChain1 = (LPD3D10CREATEDEVICEANDSWAPCHAIN1 ) GetProcAddress( g_hModD3D101, "D3D10CreateDeviceAndSwapChain1" ); + } + + if (g_hModD3D10 == NULL || g_hModD3DX10 == NULL || g_hModDXGI == NULL || g_hModD3D101 == NULL) { + dynlinkUnloadD3D10API(); + return false; + } + return true; +} + +#endif diff --git a/external/cutil/inc/dynlink_d3d11.h b/external/cutil/inc/dynlink_d3d11.h new file mode 100644 index 0000000..d9079ba --- /dev/null +++ b/external/cutil/inc/dynlink_d3d11.h @@ -0,0 +1,159 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + //-------------------------------------------------------------------------------------- +// File: dynlink_d3d11.h +// +// Shortcut macros and functions for using DX objects +// +// Copyright (c) Microsoft Corporation. All rights reserved +//-------------------------------------------------------------------------------------- + +#ifndef _DYNLINK_D3D11_H_ +#define _DYNLINK_D3D11_H_ + +// Standard Windows includes +#include +#include +#include +#include +#include +#include // for InitCommonControls() +#include // for ExtractIcon() +#include // for placement new +#include +#include +#include +#include + +// CRT's memory leak detection +#if defined(DEBUG) || defined(_DEBUG) +#include +#endif + +// Direct3D9 includes +//#include +//#include + +// Direct3D10 includes +#include +#include +#include +// #include <..\Samples\C++\Effects11\Inc\d3dx11effect.h> + +// XInput includes +#include + +// HRESULT translation for Direct3D10 and other APIs +#include + +// strsafe.h deprecates old unsecure string functions. If you +// really do not want to it to (not recommended), then uncomment the next line +//#define STRSAFE_NO_DEPRECATE + +#ifndef STRSAFE_NO_DEPRECATE +#pragma deprecated("strncpy") +#pragma deprecated("wcsncpy") +#pragma deprecated("_tcsncpy") +#pragma deprecated("wcsncat") +#pragma deprecated("strncat") +#pragma deprecated("_tcsncat") +#endif + +#pragma warning( disable : 4996 ) // disable deprecated warning +#include +#pragma warning( default : 4996 ) + +typedef HRESULT (WINAPI * LPCREATEDXGIFACTORY)(REFIID, void ** ); +typedef HRESULT (WINAPI * LPD3D11CREATEDEVICEANDSWAPCHAIN)(__in_opt IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, __in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, __in_opt CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, __out_opt IDXGISwapChain** ppSwapChain, __out_opt ID3D11Device** ppDevice, __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, __out_opt ID3D11DeviceContext** ppImmediateContext ); +typedef HRESULT (WINAPI * LPD3D11CREATEDEVICE)( IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT32, D3D_FEATURE_LEVEL*, UINT, UINT32, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext** ); +typedef void (WINAPI * LPD3DX11COMPILEFROMMEMORY)(LPCSTR pSrcData, SIZE_T SrcDataLen, LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, +LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult); + +static HMODULE s_hModDXGI = NULL; +static LPCREATEDXGIFACTORY sFnPtr_CreateDXGIFactory = NULL; +static HMODULE s_hModD3D11 = NULL; +static HMODULE s_hModD3DX11 = NULL; +static LPD3D11CREATEDEVICE sFnPtr_D3D11CreateDevice = NULL; +static LPD3D11CREATEDEVICEANDSWAPCHAIN sFnPtr_D3D11CreateDeviceAndSwapChain = NULL; +static LPD3DX11COMPILEFROMMEMORY sFnPtr_D3DX11CompileFromMemory = NULL; + +// unload the D3D10 DLLs +static bool dynlinkUnloadD3D11API( void ) +{ + if (s_hModDXGI) { + FreeLibrary( s_hModDXGI ); s_hModDXGI = NULL; + } + if (s_hModD3D11) { + FreeLibrary( s_hModD3D11 ); s_hModD3D11 = NULL; + } + if (s_hModD3DX11) { + FreeLibrary( s_hModD3DX11 ); s_hModD3DX11 = NULL; + } + return true; +} + +// Dynamically load the D3D11 DLLs loaded and map the function pointers +static bool dynlinkLoadD3D11API( void ) +{ + // If both modules are non-NULL, this function has already been called. Note + // that this doesn't guarantee that all ProcAddresses were found. + if( s_hModD3D11 != NULL && s_hModD3DX11 != NULL && s_hModDXGI != NULL ) + return true; + +#if 1 + // This may fail if Direct3D 11 isn't installed + s_hModD3D11 = LoadLibrary( "d3d11.dll" ); + if( s_hModD3D11 != NULL ) + { + sFnPtr_D3D11CreateDevice = ( LPD3D11CREATEDEVICE )GetProcAddress( s_hModD3D11, "D3D11CreateDevice" ); + sFnPtr_D3D11CreateDeviceAndSwapChain = (LPD3D11CREATEDEVICEANDSWAPCHAIN)GetProcAddress( s_hModD3D11, "D3D11CreateDeviceAndSwapChain" ); + } + + // first try to load D3DX11CompileFromMemory from DirectX 2010 June + s_hModD3DX11 = LoadLibrary( "D3DX11d_43.dll" ); + if( s_hModD3DX11 != NULL ) + { + sFnPtr_D3DX11CompileFromMemory = ( LPD3DX11COMPILEFROMMEMORY ) GetProcAddress( s_hModD3DX11, "D3DX11CompileFromMemory" ); + } + else // if absent try to take it from DirectX 2010 Feb + { + s_hModD3DX11 = LoadLibrary( "D3DX11d_42.dll" ); + if( s_hModD3DX11 != NULL ) + { + sFnPtr_D3DX11CompileFromMemory = ( LPD3DX11COMPILEFROMMEMORY ) GetProcAddress( s_hModD3DX11, "D3DX11CompileFromMemory" ); + } + } + + if( !sFnPtr_CreateDXGIFactory ) + { + s_hModDXGI = LoadLibrary( "dxgi.dll" ); + if( s_hModDXGI ) + { + sFnPtr_CreateDXGIFactory = ( LPCREATEDXGIFACTORY )GetProcAddress( s_hModDXGI, "CreateDXGIFactory1" ); + } + + return ( s_hModDXGI != NULL ) && ( s_hModD3D11 != NULL ); + } + + return ( s_hModD3D11 != NULL ); +#else + sFnPtr_D3D11CreateDevice = ( LPD3D11CREATEDEVICE )D3D11CreateDeviceAndSwapChain; + sFnPtr_D3D11CreateDeviceAndSwapChain = (LPD3D11CREATEDEVICEANDSWAPCHAIN)D3D11CreateDeviceAndSwapChain; + //sFnPtr_D3DX11CreateEffectFromMemory = ( LPD3DX11CREATEEFFECTFROMMEMORY )D3DX11CreateEffectFromMemory; + sFnPtr_D3DX11CompileFromMemory = ( LPD3DX11COMPILEFROMMEMORY )D3DX11CompileFromMemory; + sFnPtr_CreateDXGIFactory = ( LPCREATEDXGIFACTORY )CreateDXGIFactory; + return true; +#endif + return true; +} + +#endif diff --git a/external/cutil/inc/error_checker.h b/external/cutil/inc/error_checker.h new file mode 100644 index 0000000..34fd654 --- /dev/null +++ b/external/cutil/inc/error_checker.h @@ -0,0 +1,61 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +/* CUda UTility Library */ + +#ifndef _ERRORCHECKER_H_ +#define _ERRORCHECKER_H_ + +// includes, system +#include +#include + +// includes, project +#include + +// typedefs +//typedef unsigned int GLuint; + +//! Class providing the handler / tester functions for errors as static members +class ErrorChecker +{ +public: + //! Check if a condition is true. + //! @note In prinicple has the same functionality as assert but allows + //! much better control this version prints an error and terminates + //! the program, no exception is thrown. + inline static void condition( bool val, const char* file, const int line); +}; + +// functions, inlined + +// includes, system +#include + +//////////////////////////////////////////////////////////////////////////////// +//! Check if a condition is true. +//! @note In prinicple has the same functionality as assert but allows much +//! better control this version prints an error and terminates the +//! program, no exception is thrown. +//////////////////////////////////////////////////////////////////////////////// +/* static */ inline void +ErrorChecker::condition( bool val, const char* file, const int line) +{ + if ( ! val) + { + std::ostringstream os; + os << "Condition failed: " << file << " in line " << line; + RUNTIME_EXCEPTION( os.str() ); + } +} + +#endif // _ERRORCHECKER_H_ + diff --git a/external/cutil/inc/exception.h b/external/cutil/inc/exception.h new file mode 100644 index 0000000..e4650d9 --- /dev/null +++ b/external/cutil/inc/exception.h @@ -0,0 +1,151 @@ +/* +* Copyright 1993-2010 NVIDIA Corporation. All rights reserved. +* +* Please refer to the NVIDIA end user license agreement (EULA) associated +* with this source code for terms and conditions that govern your use of +* this software. Any use, reproduction, disclosure, or distribution of +* this software and related documentation outside the terms of the EULA +* is strictly prohibited. +* +*/ + +/* CUda UTility Library */ +#ifndef _EXCEPTION_H_ +#define _EXCEPTION_H_ + +// includes, system +#include +#include +#include +#include + +//! Exception wrapper. +//! @param Std_Exception Exception out of namespace std for easy typing. +template +class Exception : public Std_Exception +{ +public: + + //! @brief Static construction interface + //! @return Alwayss throws ( Located_Exception) + //! @param file file in which the Exception occurs + //! @param line line in which the Exception occurs + //! @param detailed details on the code fragment causing the Exception + static void throw_it( const char* file, + const int line, + const char* detailed = "-" ); + + //! Static construction interface + //! @return Alwayss throws ( Located_Exception) + //! @param file file in which the Exception occurs + //! @param line line in which the Exception occurs + //! @param detailed details on the code fragment causing the Exception + static void throw_it( const char* file, + const int line, + const std::string& detailed); + + //! Destructor + virtual ~Exception() throw(); + +private: + + //! Constructor, default (private) + Exception(); + + //! Constructor, standard + //! @param str string returned by what() + Exception( const std::string& str); + +}; + +//////////////////////////////////////////////////////////////////////////////// +//! Exception handler function for arbitrary exceptions +//! @param ex exception to handle +//////////////////////////////////////////////////////////////////////////////// +template +inline void +handleException( const Exception_Typ& ex) +{ + std::cerr << ex.what() << std::endl; + + exit( EXIT_FAILURE); +} + +//! Convenience macros + +//! Exception caused by dynamic program behavior, e.g. file does not exist +#define RUNTIME_EXCEPTION( msg) \ + Exception::throw_it( __FILE__, __LINE__, msg) + +//! Logic exception in program, e.g. an assert failed +#define LOGIC_EXCEPTION( msg) \ + Exception::throw_it( __FILE__, __LINE__, msg) + +//! Out of range exception +#define RANGE_EXCEPTION( msg) \ + Exception::throw_it( __FILE__, __LINE__, msg) + +//////////////////////////////////////////////////////////////////////////////// +//! Implementation + +// includes, system +#include + +//////////////////////////////////////////////////////////////////////////////// +//! Static construction interface. +//! @param Exception causing code fragment (file and line) and detailed infos. +//////////////////////////////////////////////////////////////////////////////// +/*static*/ template +void +Exception:: +throw_it( const char* file, const int line, const char* detailed) +{ + std::stringstream s; + + // Quiet heavy-weight but exceptions are not for + // performance / release versions + s << "Exception in file '" << file << "' in line " << line << "\n" + << "Detailed description: " << detailed << "\n"; + + throw Exception( s.str()); +} + +//////////////////////////////////////////////////////////////////////////////// +//! Static construction interface. +//! @param Exception causing code fragment (file and line) and detailed infos. +//////////////////////////////////////////////////////////////////////////////// +/*static*/ template +void +Exception:: +throw_it( const char* file, const int line, const std::string& msg) +{ + throw_it( file, line, msg.c_str()); +} + +//////////////////////////////////////////////////////////////////////////////// +//! Constructor, default (private). +//////////////////////////////////////////////////////////////////////////////// +template +Exception::Exception() : + Exception("Unknown Exception.\n") +{ } + +//////////////////////////////////////////////////////////////////////////////// +//! Constructor, standard (private). +//! String returned by what(). +//////////////////////////////////////////////////////////////////////////////// +template +Exception::Exception( const std::string& s) : + Std_Exception( s) +{ } + +//////////////////////////////////////////////////////////////////////////////// +//! Destructor +//////////////////////////////////////////////////////////////////////////////// +template +Exception::~Exception() throw() { } + +// functions, exported + +#endif // #ifndef _EXCEPTION_H_ + diff --git a/external/cutil/inc/helper_cuda.h b/external/cutil/inc/helper_cuda.h new file mode 100644 index 0000000..8a1585c --- /dev/null +++ b/external/cutil/inc/helper_cuda.h @@ -0,0 +1,1038 @@ +/** + * Copyright 1993-2013 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +//////////////////////////////////////////////////////////////////////////////// +// These are CUDA Helper functions for initialization and error checking + +#ifndef HELPER_CUDA_H +#define HELPER_CUDA_H + +#pragma once + +#include +#include +#include + +#include + +/* +inline void __ExitInTime(int seconds) +{ + fprintf(stdout, "> exiting in %d seconds: ", seconds); + fflush(stdout); + time_t t; + int count; + + for (t=time(0)+seconds, count=seconds; time(0) < t; count--) { + fprintf(stdout, "%d...", count); +#if defined(WIN32) + Sleep(1000); +#else + sleep(1); +#endif + } + + fprintf(stdout,"done!\n\n"); + fflush(stdout); +} + +#define EXIT_TIME_DELAY 2 + +inline void EXIT_DELAY(int return_code) +{ + __ExitInTime(EXIT_TIME_DELAY); + exit(return_code); +} +*/ + +#ifndef EXIT_WAIVED +#define EXIT_WAIVED 2 +#endif + +// Note, it is required that your SDK sample to include the proper header files, please +// refer the CUDA examples for examples of the needed CUDA headers, which may change depending +// on which CUDA functions are used. + +// CUDA Runtime error messages +#ifdef __DRIVER_TYPES_H__ +static const char *_cudaGetErrorEnum(cudaError_t error) +{ + switch (error) + { + case cudaSuccess: + return "cudaSuccess"; + + case cudaErrorMissingConfiguration: + return "cudaErrorMissingConfiguration"; + + case cudaErrorMemoryAllocation: + return "cudaErrorMemoryAllocation"; + + case cudaErrorInitializationError: + return "cudaErrorInitializationError"; + + case cudaErrorLaunchFailure: + return "cudaErrorLaunchFailure"; + + case cudaErrorPriorLaunchFailure: + return "cudaErrorPriorLaunchFailure"; + + case cudaErrorLaunchTimeout: + return "cudaErrorLaunchTimeout"; + + case cudaErrorLaunchOutOfResources: + return "cudaErrorLaunchOutOfResources"; + + case cudaErrorInvalidDeviceFunction: + return "cudaErrorInvalidDeviceFunction"; + + case cudaErrorInvalidConfiguration: + return "cudaErrorInvalidConfiguration"; + + case cudaErrorInvalidDevice: + return "cudaErrorInvalidDevice"; + + case cudaErrorInvalidValue: + return "cudaErrorInvalidValue"; + + case cudaErrorInvalidPitchValue: + return "cudaErrorInvalidPitchValue"; + + case cudaErrorInvalidSymbol: + return "cudaErrorInvalidSymbol"; + + case cudaErrorMapBufferObjectFailed: + return "cudaErrorMapBufferObjectFailed"; + + case cudaErrorUnmapBufferObjectFailed: + return "cudaErrorUnmapBufferObjectFailed"; + + case cudaErrorInvalidHostPointer: + return "cudaErrorInvalidHostPointer"; + + case cudaErrorInvalidDevicePointer: + return "cudaErrorInvalidDevicePointer"; + + case cudaErrorInvalidTexture: + return "cudaErrorInvalidTexture"; + + case cudaErrorInvalidTextureBinding: + return "cudaErrorInvalidTextureBinding"; + + case cudaErrorInvalidChannelDescriptor: + return "cudaErrorInvalidChannelDescriptor"; + + case cudaErrorInvalidMemcpyDirection: + return "cudaErrorInvalidMemcpyDirection"; + + case cudaErrorAddressOfConstant: + return "cudaErrorAddressOfConstant"; + + case cudaErrorTextureFetchFailed: + return "cudaErrorTextureFetchFailed"; + + case cudaErrorTextureNotBound: + return "cudaErrorTextureNotBound"; + + case cudaErrorSynchronizationError: + return "cudaErrorSynchronizationError"; + + case cudaErrorInvalidFilterSetting: + return "cudaErrorInvalidFilterSetting"; + + case cudaErrorInvalidNormSetting: + return "cudaErrorInvalidNormSetting"; + + case cudaErrorMixedDeviceExecution: + return "cudaErrorMixedDeviceExecution"; + + case cudaErrorCudartUnloading: + return "cudaErrorCudartUnloading"; + + case cudaErrorUnknown: + return "cudaErrorUnknown"; + + case cudaErrorNotYetImplemented: + return "cudaErrorNotYetImplemented"; + + case cudaErrorMemoryValueTooLarge: + return "cudaErrorMemoryValueTooLarge"; + + case cudaErrorInvalidResourceHandle: + return "cudaErrorInvalidResourceHandle"; + + case cudaErrorNotReady: + return "cudaErrorNotReady"; + + case cudaErrorInsufficientDriver: + return "cudaErrorInsufficientDriver"; + + case cudaErrorSetOnActiveProcess: + return "cudaErrorSetOnActiveProcess"; + + case cudaErrorInvalidSurface: + return "cudaErrorInvalidSurface"; + + case cudaErrorNoDevice: + return "cudaErrorNoDevice"; + + case cudaErrorECCUncorrectable: + return "cudaErrorECCUncorrectable"; + + case cudaErrorSharedObjectSymbolNotFound: + return "cudaErrorSharedObjectSymbolNotFound"; + + case cudaErrorSharedObjectInitFailed: + return "cudaErrorSharedObjectInitFailed"; + + case cudaErrorUnsupportedLimit: + return "cudaErrorUnsupportedLimit"; + + case cudaErrorDuplicateVariableName: + return "cudaErrorDuplicateVariableName"; + + case cudaErrorDuplicateTextureName: + return "cudaErrorDuplicateTextureName"; + + case cudaErrorDuplicateSurfaceName: + return "cudaErrorDuplicateSurfaceName"; + + case cudaErrorDevicesUnavailable: + return "cudaErrorDevicesUnavailable"; + + case cudaErrorInvalidKernelImage: + return "cudaErrorInvalidKernelImage"; + + case cudaErrorNoKernelImageForDevice: + return "cudaErrorNoKernelImageForDevice"; + + case cudaErrorIncompatibleDriverContext: + return "cudaErrorIncompatibleDriverContext"; + + case cudaErrorPeerAccessAlreadyEnabled: + return "cudaErrorPeerAccessAlreadyEnabled"; + + case cudaErrorPeerAccessNotEnabled: + return "cudaErrorPeerAccessNotEnabled"; + + case cudaErrorDeviceAlreadyInUse: + return "cudaErrorDeviceAlreadyInUse"; + + case cudaErrorProfilerDisabled: + return "cudaErrorProfilerDisabled"; + + case cudaErrorProfilerNotInitialized: + return "cudaErrorProfilerNotInitialized"; + + case cudaErrorProfilerAlreadyStarted: + return "cudaErrorProfilerAlreadyStarted"; + + case cudaErrorProfilerAlreadyStopped: + return "cudaErrorProfilerAlreadyStopped"; + +#if __CUDA_API_VERSION >= 0x4000 + + case cudaErrorAssert: + return "cudaErrorAssert"; + + case cudaErrorTooManyPeers: + return "cudaErrorTooManyPeers"; + + case cudaErrorHostMemoryAlreadyRegistered: + return "cudaErrorHostMemoryAlreadyRegistered"; + + case cudaErrorHostMemoryNotRegistered: + return "cudaErrorHostMemoryNotRegistered"; +#endif + + case cudaErrorStartupFailure: + return "cudaErrorStartupFailure"; + + case cudaErrorApiFailureBase: + return "cudaErrorApiFailureBase"; + } + + return ""; +} +#endif + +#ifdef __cuda_cuda_h__ +// CUDA Driver API errors +static const char *_cudaGetErrorEnum(CUresult error) +{ + switch (error) + { + case CUDA_SUCCESS: + return "CUDA_SUCCESS"; + + case CUDA_ERROR_INVALID_VALUE: + return "CUDA_ERROR_INVALID_VALUE"; + + case CUDA_ERROR_OUT_OF_MEMORY: + return "CUDA_ERROR_OUT_OF_MEMORY"; + + case CUDA_ERROR_NOT_INITIALIZED: + return "CUDA_ERROR_NOT_INITIALIZED"; + + case CUDA_ERROR_DEINITIALIZED: + return "CUDA_ERROR_DEINITIALIZED"; + + case CUDA_ERROR_PROFILER_DISABLED: + return "CUDA_ERROR_PROFILER_DISABLED"; + + case CUDA_ERROR_PROFILER_NOT_INITIALIZED: + return "CUDA_ERROR_PROFILER_NOT_INITIALIZED"; + + case CUDA_ERROR_PROFILER_ALREADY_STARTED: + return "CUDA_ERROR_PROFILER_ALREADY_STARTED"; + + case CUDA_ERROR_PROFILER_ALREADY_STOPPED: + return "CUDA_ERROR_PROFILER_ALREADY_STOPPED"; + + case CUDA_ERROR_NO_DEVICE: + return "CUDA_ERROR_NO_DEVICE"; + + case CUDA_ERROR_INVALID_DEVICE: + return "CUDA_ERROR_INVALID_DEVICE"; + + case CUDA_ERROR_INVALID_IMAGE: + return "CUDA_ERROR_INVALID_IMAGE"; + + case CUDA_ERROR_INVALID_CONTEXT: + return "CUDA_ERROR_INVALID_CONTEXT"; + + case CUDA_ERROR_CONTEXT_ALREADY_CURRENT: + return "CUDA_ERROR_CONTEXT_ALREADY_CURRENT"; + + case CUDA_ERROR_MAP_FAILED: + return "CUDA_ERROR_MAP_FAILED"; + + case CUDA_ERROR_UNMAP_FAILED: + return "CUDA_ERROR_UNMAP_FAILED"; + + case CUDA_ERROR_ARRAY_IS_MAPPED: + return "CUDA_ERROR_ARRAY_IS_MAPPED"; + + case CUDA_ERROR_ALREADY_MAPPED: + return "CUDA_ERROR_ALREADY_MAPPED"; + + case CUDA_ERROR_NO_BINARY_FOR_GPU: + return "CUDA_ERROR_NO_BINARY_FOR_GPU"; + + case CUDA_ERROR_ALREADY_ACQUIRED: + return "CUDA_ERROR_ALREADY_ACQUIRED"; + + case CUDA_ERROR_NOT_MAPPED: + return "CUDA_ERROR_NOT_MAPPED"; + + case CUDA_ERROR_NOT_MAPPED_AS_ARRAY: + return "CUDA_ERROR_NOT_MAPPED_AS_ARRAY"; + + case CUDA_ERROR_NOT_MAPPED_AS_POINTER: + return "CUDA_ERROR_NOT_MAPPED_AS_POINTER"; + + case CUDA_ERROR_ECC_UNCORRECTABLE: + return "CUDA_ERROR_ECC_UNCORRECTABLE"; + + case CUDA_ERROR_UNSUPPORTED_LIMIT: + return "CUDA_ERROR_UNSUPPORTED_LIMIT"; + + case CUDA_ERROR_CONTEXT_ALREADY_IN_USE: + return "CUDA_ERROR_CONTEXT_ALREADY_IN_USE"; + + case CUDA_ERROR_INVALID_SOURCE: + return "CUDA_ERROR_INVALID_SOURCE"; + + case CUDA_ERROR_FILE_NOT_FOUND: + return "CUDA_ERROR_FILE_NOT_FOUND"; + + case CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND: + return "CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND"; + + case CUDA_ERROR_SHARED_OBJECT_INIT_FAILED: + return "CUDA_ERROR_SHARED_OBJECT_INIT_FAILED"; + + case CUDA_ERROR_OPERATING_SYSTEM: + return "CUDA_ERROR_OPERATING_SYSTEM"; + + case CUDA_ERROR_INVALID_HANDLE: + return "CUDA_ERROR_INVALID_HANDLE"; + + case CUDA_ERROR_NOT_FOUND: + return "CUDA_ERROR_NOT_FOUND"; + + case CUDA_ERROR_NOT_READY: + return "CUDA_ERROR_NOT_READY"; + + case CUDA_ERROR_LAUNCH_FAILED: + return "CUDA_ERROR_LAUNCH_FAILED"; + + case CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES: + return "CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES"; + + case CUDA_ERROR_LAUNCH_TIMEOUT: + return "CUDA_ERROR_LAUNCH_TIMEOUT"; + + case CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING: + return "CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING"; + + case CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED: + return "CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED"; + + case CUDA_ERROR_PEER_ACCESS_NOT_ENABLED: + return "CUDA_ERROR_PEER_ACCESS_NOT_ENABLED"; + + case CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE: + return "CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE"; + + case CUDA_ERROR_CONTEXT_IS_DESTROYED: + return "CUDA_ERROR_CONTEXT_IS_DESTROYED"; + + case CUDA_ERROR_ASSERT: + return "CUDA_ERROR_ASSERT"; + + case CUDA_ERROR_TOO_MANY_PEERS: + return "CUDA_ERROR_TOO_MANY_PEERS"; + + case CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED: + return "CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED"; + + case CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED: + return "CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED"; + + case CUDA_ERROR_UNKNOWN: + return "CUDA_ERROR_UNKNOWN"; + } + + return ""; +} +#endif + +#ifdef CUBLAS_API_H_ +// cuBLAS API errors +static const char *_cudaGetErrorEnum(cublasStatus_t error) +{ + switch (error) + { + case CUBLAS_STATUS_SUCCESS: + return "CUBLAS_STATUS_SUCCESS"; + + case CUBLAS_STATUS_NOT_INITIALIZED: + return "CUBLAS_STATUS_NOT_INITIALIZED"; + + case CUBLAS_STATUS_ALLOC_FAILED: + return "CUBLAS_STATUS_ALLOC_FAILED"; + + case CUBLAS_STATUS_INVALID_VALUE: + return "CUBLAS_STATUS_INVALID_VALUE"; + + case CUBLAS_STATUS_ARCH_MISMATCH: + return "CUBLAS_STATUS_ARCH_MISMATCH"; + + case CUBLAS_STATUS_MAPPING_ERROR: + return "CUBLAS_STATUS_MAPPING_ERROR"; + + case CUBLAS_STATUS_EXECUTION_FAILED: + return "CUBLAS_STATUS_EXECUTION_FAILED"; + + case CUBLAS_STATUS_INTERNAL_ERROR: + return "CUBLAS_STATUS_INTERNAL_ERROR"; + } + + return ""; +} +#endif + +#ifdef _CUFFT_H_ +// cuFFT API errors +static const char *_cudaGetErrorEnum(cufftResult error) +{ + switch (error) + { + case CUFFT_SUCCESS: + return "CUFFT_SUCCESS"; + + case CUFFT_INVALID_PLAN: + return "CUFFT_INVALID_PLAN"; + + case CUFFT_ALLOC_FAILED: + return "CUFFT_ALLOC_FAILED"; + + case CUFFT_INVALID_TYPE: + return "CUFFT_INVALID_TYPE"; + + case CUFFT_INVALID_VALUE: + return "CUFFT_INVALID_VALUE"; + + case CUFFT_INTERNAL_ERROR: + return "CUFFT_INTERNAL_ERROR"; + + case CUFFT_EXEC_FAILED: + return "CUFFT_EXEC_FAILED"; + + case CUFFT_SETUP_FAILED: + return "CUFFT_SETUP_FAILED"; + + case CUFFT_INVALID_SIZE: + return "CUFFT_INVALID_SIZE"; + + case CUFFT_UNALIGNED_DATA: + return "CUFFT_UNALIGNED_DATA"; + } + + return ""; +} +#endif + + +#ifdef CUSPARSEAPI +// cuSPARSE API errors +static const char *_cudaGetErrorEnum(cusparseStatus_t error) +{ + switch (error) + { + case CUSPARSE_STATUS_SUCCESS: + return "CUSPARSE_STATUS_SUCCESS"; + + case CUSPARSE_STATUS_NOT_INITIALIZED: + return "CUSPARSE_STATUS_NOT_INITIALIZED"; + + case CUSPARSE_STATUS_ALLOC_FAILED: + return "CUSPARSE_STATUS_ALLOC_FAILED"; + + case CUSPARSE_STATUS_INVALID_VALUE: + return "CUSPARSE_STATUS_INVALID_VALUE"; + + case CUSPARSE_STATUS_ARCH_MISMATCH: + return "CUSPARSE_STATUS_ARCH_MISMATCH"; + + case CUSPARSE_STATUS_MAPPING_ERROR: + return "CUSPARSE_STATUS_MAPPING_ERROR"; + + case CUSPARSE_STATUS_EXECUTION_FAILED: + return "CUSPARSE_STATUS_EXECUTION_FAILED"; + + case CUSPARSE_STATUS_INTERNAL_ERROR: + return "CUSPARSE_STATUS_INTERNAL_ERROR"; + + case CUSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED: + return "CUSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED"; + } + + return ""; +} +#endif + +#ifdef CURAND_H_ +// cuRAND API errors +static const char *_cudaGetErrorEnum(curandStatus_t error) +{ + switch (error) + { + case CURAND_STATUS_SUCCESS: + return "CURAND_STATUS_SUCCESS"; + + case CURAND_STATUS_VERSION_MISMATCH: + return "CURAND_STATUS_VERSION_MISMATCH"; + + case CURAND_STATUS_NOT_INITIALIZED: + return "CURAND_STATUS_NOT_INITIALIZED"; + + case CURAND_STATUS_ALLOCATION_FAILED: + return "CURAND_STATUS_ALLOCATION_FAILED"; + + case CURAND_STATUS_TYPE_ERROR: + return "CURAND_STATUS_TYPE_ERROR"; + + case CURAND_STATUS_OUT_OF_RANGE: + return "CURAND_STATUS_OUT_OF_RANGE"; + + case CURAND_STATUS_LENGTH_NOT_MULTIPLE: + return "CURAND_STATUS_LENGTH_NOT_MULTIPLE"; + + case CURAND_STATUS_DOUBLE_PRECISION_REQUIRED: + return "CURAND_STATUS_DOUBLE_PRECISION_REQUIRED"; + + case CURAND_STATUS_LAUNCH_FAILURE: + return "CURAND_STATUS_LAUNCH_FAILURE"; + + case CURAND_STATUS_PREEXISTING_FAILURE: + return "CURAND_STATUS_PREEXISTING_FAILURE"; + + case CURAND_STATUS_INITIALIZATION_FAILED: + return "CURAND_STATUS_INITIALIZATION_FAILED"; + + case CURAND_STATUS_ARCH_MISMATCH: + return "CURAND_STATUS_ARCH_MISMATCH"; + + case CURAND_STATUS_INTERNAL_ERROR: + return "CURAND_STATUS_INTERNAL_ERROR"; + } + + return ""; +} +#endif + +#ifdef NV_NPPIDEFS_H +// NPP API errors +static const char *_cudaGetErrorEnum(NppStatus error) +{ + switch (error) + { + case NPP_NOT_SUPPORTED_MODE_ERROR: + return "NPP_NOT_SUPPORTED_MODE_ERROR"; + + case NPP_ROUND_MODE_NOT_SUPPORTED_ERROR: + return "NPP_ROUND_MODE_NOT_SUPPORTED_ERROR"; + + case NPP_RESIZE_NO_OPERATION_ERROR: + return "NPP_RESIZE_NO_OPERATION_ERROR"; + + case NPP_NOT_SUFFICIENT_COMPUTE_CAPABILITY: + return "NPP_NOT_SUFFICIENT_COMPUTE_CAPABILITY"; + +#if ((NPP_VERSION_MAJOR << 12) + (NPP_VERSION_MINOR << 4)) <= 0x5000 + case NPP_BAD_ARG_ERROR: + return "NPP_BAD_ARGUMENT_ERROR"; + + case NPP_COEFF_ERROR: + return "NPP_COEFFICIENT_ERROR"; + + case NPP_RECT_ERROR: + return "NPP_RECTANGLE_ERROR"; + + case NPP_QUAD_ERROR: + return "NPP_QUADRANGLE_ERROR"; + + case NPP_MEM_ALLOC_ERR: + return "NPP_MEMORY_ALLOCATION_ERROR"; + + case NPP_HISTO_NUMBER_OF_LEVELS_ERROR: + return "NPP_HISTOGRAM_NUMBER_OF_LEVELS_ERROR"; + + case NPP_INVALID_INPUT: + return "NPP_INVALID_INPUT"; + + case NPP_POINTER_ERROR: + return "NPP_POINTER_ERROR"; + + case NPP_WARNING: + return "NPP_WARNING"; + + case NPP_ODD_ROI_WARNING: + return "NPP_ODD_ROI_WARNING"; +#else + + // These are for CUDA 5.5 or higher + case NPP_BAD_ARGUMENT_ERROR: + return "NPP_BAD_ARGUMENT_ERROR"; + + case NPP_COEFFICIENT_ERROR: + return "NPP_COEFFICIENT_ERROR"; + + case NPP_RECTANGLE_ERROR: + return "NPP_RECTANGLE_ERROR"; + + case NPP_QUADRANGLE_ERROR: + return "NPP_QUADRANGLE_ERROR"; + + case NPP_MEMORY_ALLOCATION_ERR: + return "NPP_MEMORY_ALLOCATION_ERROR"; + + case NPP_HISTOGRAM_NUMBER_OF_LEVELS_ERROR: + return "NPP_HISTOGRAM_NUMBER_OF_LEVELS_ERROR"; + + case NPP_INVALID_HOST_POINTER_ERROR: + return "NPP_INVALID_HOST_POINTER_ERROR"; + + case NPP_INVALID_DEVICE_POINTER_ERROR: + return "NPP_INVALID_DEVICE_POINTER_ERROR"; +#endif + + case NPP_LUT_NUMBER_OF_LEVELS_ERROR: + return "NPP_LUT_NUMBER_OF_LEVELS_ERROR"; + + case NPP_TEXTURE_BIND_ERROR: + return "NPP_TEXTURE_BIND_ERROR"; + + case NPP_WRONG_INTERSECTION_ROI_ERROR: + return "NPP_WRONG_INTERSECTION_ROI_ERROR"; + + case NPP_NOT_EVEN_STEP_ERROR: + return "NPP_NOT_EVEN_STEP_ERROR"; + + case NPP_INTERPOLATION_ERROR: + return "NPP_INTERPOLATION_ERROR"; + + case NPP_RESIZE_FACTOR_ERROR: + return "NPP_RESIZE_FACTOR_ERROR"; + + case NPP_HAAR_CLASSIFIER_PIXEL_MATCH_ERROR: + return "NPP_HAAR_CLASSIFIER_PIXEL_MATCH_ERROR"; + + +#if ((NPP_VERSION_MAJOR << 12) + (NPP_VERSION_MINOR << 4)) <= 0x5000 + case NPP_MEMFREE_ERR: + return "NPP_MEMFREE_ERR"; + + case NPP_MEMSET_ERR: + return "NPP_MEMSET_ERR"; + + case NPP_MEMCPY_ERR: + return "NPP_MEMCPY_ERROR"; + + case NPP_MIRROR_FLIP_ERR: + return "NPP_MIRROR_FLIP_ERR"; +#else + case NPP_MEMFREE_ERROR: + return "NPP_MEMFREE_ERROR"; + + case NPP_MEMSET_ERROR: + return "NPP_MEMSET_ERROR"; + + case NPP_MEMCPY_ERROR: + return "NPP_MEMCPY_ERROR"; + + case NPP_MIRROR_FLIP_ERROR: + return "NPP_MIRROR_FLIP_ERROR"; +#endif + + case NPP_ALIGNMENT_ERROR: + return "NPP_ALIGNMENT_ERROR"; + + case NPP_STEP_ERROR: + return "NPP_STEP_ERROR"; + + case NPP_SIZE_ERROR: + return "NPP_SIZE_ERROR"; + + case NPP_NULL_POINTER_ERROR: + return "NPP_NULL_POINTER_ERROR"; + + case NPP_CUDA_KERNEL_EXECUTION_ERROR: + return "NPP_CUDA_KERNEL_EXECUTION_ERROR"; + + case NPP_NOT_IMPLEMENTED_ERROR: + return "NPP_NOT_IMPLEMENTED_ERROR"; + + case NPP_ERROR: + return "NPP_ERROR"; + + case NPP_SUCCESS: + return "NPP_SUCCESS"; + + case NPP_WRONG_INTERSECTION_QUAD_WARNING: + return "NPP_WRONG_INTERSECTION_QUAD_WARNING"; + + case NPP_MISALIGNED_DST_ROI_WARNING: + return "NPP_MISALIGNED_DST_ROI_WARNING"; + + case NPP_AFFINE_QUAD_INCORRECT_WARNING: + return "NPP_AFFINE_QUAD_INCORRECT_WARNING"; + + case NPP_DOUBLE_SIZE_WARNING: + return "NPP_DOUBLE_SIZE_WARNING"; + + case NPP_WRONG_INTERSECTION_ROI_WARNING: + return "NPP_WRONG_INTERSECTION_ROI_WARNING"; + } + + return ""; +} +#endif + +#ifdef __DRIVER_TYPES_H__ +#ifndef DEVICE_RESET +#define DEVICE_RESET cudaDeviceReset(); +#endif +#else +#ifndef DEVICE_RESET +#define DEVICE_RESET +#endif +#endif + +template< typename T > +void check(T result, char const *const func, const char *const file, int const line) +{ + if (result) + { + fprintf(stderr, "CUDA error at %s:%d code=%d(%s) \"%s\" \n", + file, line, static_cast(result), _cudaGetErrorEnum(result), func); + DEVICE_RESET + // Make sure we call CUDA Device Reset before exiting + exit(EXIT_FAILURE); + } +} + +#ifdef __DRIVER_TYPES_H__ +// This will output the proper CUDA error strings in the event that a CUDA host call returns an error +#define checkCudaErrors(val) check ( (val), #val, __FILE__, __LINE__ ) + +// This will output the proper error string when calling cudaGetLastError +#define getLastCudaError(msg) __getLastCudaError (msg, __FILE__, __LINE__) + +inline void __getLastCudaError(const char *errorMessage, const char *file, const int line) +{ + cudaError_t err = cudaGetLastError(); + + if (cudaSuccess != err) + { + fprintf(stderr, "%s(%i) : getLastCudaError() CUDA error : %s : (%d) %s.\n", + file, line, errorMessage, (int)err, cudaGetErrorString(err)); + DEVICE_RESET + exit(EXIT_FAILURE); + } +} +#endif + +#ifndef MAX +#define MAX(a,b) (a > b ? a : b) +#endif + +// Beginning of GPU Architecture definitions +inline int _ConvertSMVer2Cores(int major, int minor) +{ + // Defines for GPU Architecture types (using the SM version to determine the # of cores per SM + typedef struct + { + int SM; // 0xMm (hexidecimal notation), M = SM Major version, and m = SM minor version + int Cores; + } sSMtoCores; + + sSMtoCores nGpuArchCoresPerSM[] = + { + { 0x10, 8 }, // Tesla Generation (SM 1.0) G80 class + { 0x11, 8 }, // Tesla Generation (SM 1.1) G8x class + { 0x12, 8 }, // Tesla Generation (SM 1.2) G9x class + { 0x13, 8 }, // Tesla Generation (SM 1.3) GT200 class + { 0x20, 32 }, // Fermi Generation (SM 2.0) GF100 class + { 0x21, 48 }, // Fermi Generation (SM 2.1) GF10x class + { 0x30, 192}, // Kepler Generation (SM 3.0) GK10x class + { 0x35, 192}, // Kepler Generation (SM 3.5) GK11x class + { -1, -1 } + }; + + int index = 0; + + while (nGpuArchCoresPerSM[index].SM != -1) + { + if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor)) + { + return nGpuArchCoresPerSM[index].Cores; + } + + index++; + } + + // If we don't find the values, we default use the previous one to run properly + printf("MapSMtoCores for SM %d.%d is undefined. Default to use %d Cores/SM\n", major, minor, nGpuArchCoresPerSM[7].Cores); + return nGpuArchCoresPerSM[7].Cores; +} +// end of GPU Architecture definitions + +#ifdef __CUDA_RUNTIME_H__ +// General GPU Device CUDA Initialization +inline int gpuDeviceInit(int devID) +{ + int device_count; + checkCudaErrors(cudaGetDeviceCount(&device_count)); + + if (device_count == 0) + { + fprintf(stderr, "gpuDeviceInit() CUDA error: no devices supporting CUDA.\n"); + exit(EXIT_FAILURE); + } + + if (devID < 0) + { + devID = 0; + } + + if (devID > device_count-1) + { + fprintf(stderr, "\n"); + fprintf(stderr, ">> %d CUDA capable GPU device(s) detected. <<\n", device_count); + fprintf(stderr, ">> gpuDeviceInit (-device=%d) is not a valid GPU device. <<\n", devID); + fprintf(stderr, "\n"); + return -devID; + } + + cudaDeviceProp deviceProp; + checkCudaErrors(cudaGetDeviceProperties(&deviceProp, devID)); + + if (deviceProp.computeMode == cudaComputeModeProhibited) + { + fprintf(stderr, "Error: device is running in , no threads can use ::cudaSetDevice().\n"); + return -1; + } + + if (deviceProp.major < 1) + { + fprintf(stderr, "gpuDeviceInit(): GPU device does not support CUDA.\n"); + exit(EXIT_FAILURE); + } + + checkCudaErrors(cudaSetDevice(devID)); + printf("gpuDeviceInit() CUDA Device [%d]: \"%s\n", devID, deviceProp.name); + + return devID; +} + +// This function returns the best GPU (with maximum GFLOPS) +inline int gpuGetMaxGflopsDeviceId() +{ + int current_device = 0, sm_per_multiproc = 0; + int max_compute_perf = 0, max_perf_device = 0; + int device_count = 0, best_SM_arch = 0; + cudaDeviceProp deviceProp; + cudaGetDeviceCount(&device_count); + + checkCudaErrors(cudaGetDeviceCount(&device_count)); + + if (device_count == 0) + { + fprintf(stderr, "gpuGetMaxGflopsDeviceId() CUDA error: no devices supporting CUDA.\n"); + exit(EXIT_FAILURE); + } + + // Find the best major SM Architecture GPU device + while (current_device < device_count) + { + cudaGetDeviceProperties(&deviceProp, current_device); + + // If this GPU is not running on Compute Mode prohibited, then we can add it to the list + if (deviceProp.computeMode != cudaComputeModeProhibited) + { + if (deviceProp.major > 0 && deviceProp.major < 9999) + { + best_SM_arch = MAX(best_SM_arch, deviceProp.major); + } + } + + current_device++; + } + + // Find the best CUDA capable GPU device + current_device = 0; + + while (current_device < device_count) + { + cudaGetDeviceProperties(&deviceProp, current_device); + + // If this GPU is not running on Compute Mode prohibited, then we can add it to the list + if (deviceProp.computeMode != cudaComputeModeProhibited) + { + if (deviceProp.major == 9999 && deviceProp.minor == 9999) + { + sm_per_multiproc = 1; + } + else + { + sm_per_multiproc = _ConvertSMVer2Cores(deviceProp.major, deviceProp.minor); + } + + int compute_perf = deviceProp.multiProcessorCount * sm_per_multiproc * deviceProp.clockRate; + + if (compute_perf > max_compute_perf) + { + // If we find GPU with SM major > 2, search only these + if (best_SM_arch > 2) + { + // If our device==dest_SM_arch, choose this, or else pass + if (deviceProp.major == best_SM_arch) + { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } + else + { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } + } + + ++current_device; + } + + return max_perf_device; +} + + +// Initialization code to find the best CUDA Device +inline int findCudaDevice(int argc, const char **argv) +{ + cudaDeviceProp deviceProp; + int devID = 0; + + // If the command-line has a device number specified, use it + if (checkCmdLineFlag(argc, argv, "device")) + { + devID = getCmdLineArgumentInt(argc, argv, "device="); + + if (devID < 0) + { + printf("Invalid command line parameter\n "); + exit(EXIT_FAILURE); + } + else + { + devID = gpuDeviceInit(devID); + + if (devID < 0) + { + printf("exiting...\n"); + exit(EXIT_FAILURE); + } + } + } + else + { + // Otherwise pick the device with highest Gflops/s + devID = gpuGetMaxGflopsDeviceId(); + checkCudaErrors(cudaSetDevice(devID)); + checkCudaErrors(cudaGetDeviceProperties(&deviceProp, devID)); + printf("GPU Device %d: \"%s\" with compute capability %d.%d\n\n", devID, deviceProp.name, deviceProp.major, deviceProp.minor); + } + + return devID; +} + +// General check for CUDA GPU SM Capabilities +inline bool checkCudaCapabilities(int major_version, int minor_version) +{ + cudaDeviceProp deviceProp; + deviceProp.major = 0; + deviceProp.minor = 0; + int dev; + + checkCudaErrors(cudaGetDevice(&dev)); + checkCudaErrors(cudaGetDeviceProperties(&deviceProp, dev)); + + if ((deviceProp.major > major_version) || + (deviceProp.major == major_version && deviceProp.minor >= minor_version)) + { + printf("> Device %d: <%16s >, Compute SM %d.%d detected\n", dev, deviceProp.name, deviceProp.major, deviceProp.minor); + return true; + } + else + { + printf("No GPU device was found that can support CUDA compute capability %d.%d.\n", major_version, minor_version); + return false; + } +} +#endif + +// end of CUDA Helper Functions + + +#endif diff --git a/external/cutil/inc/helper_cuda_drvapi.h b/external/cutil/inc/helper_cuda_drvapi.h new file mode 100644 index 0000000..50276b8 --- /dev/null +++ b/external/cutil/inc/helper_cuda_drvapi.h @@ -0,0 +1,482 @@ +/** + * Copyright 1993-2013 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +// Helper functions for CUDA Driver API error handling (make sure that CUDA_H is included in your projects) +#ifndef HELPER_CUDA_DRVAPI_H +#define HELPER_CUDA_DRVAPI_H + +#include +#include +#include + +#include +#include + +#ifndef MAX +#define MAX(a,b) (a > b ? a : b) +#endif + +#ifndef EXIT_WAIVED +#define EXIT_WAIVED 2 +#endif + +//////////////////////////////////////////////////////////////////////////////// +// These are CUDA Helper functions + +// add a level of protection to the CUDA SDK samples, let's force samples to explicitly include CUDA.H +#ifdef __cuda_cuda_h__ +// This will output the proper CUDA error strings in the event that a CUDA host call returns an error +#ifndef checkCudaErrors +#define checkCudaErrors(err) __checkCudaErrors (err, __FILE__, __LINE__) + +// These are the inline versions for all of the SDK helper functions +inline void __checkCudaErrors(CUresult err, const char *file, const int line) +{ + if (CUDA_SUCCESS != err) + { + fprintf(stderr, "checkCudaErrors() Driver API error = %04d \"%s\" from file <%s>, line %i.\n", + err, getCudaDrvErrorString(err), file, line); + exit(EXIT_FAILURE); + } +} +#endif + +#ifdef getLastCudaDrvErrorMsg +#undef getLastCudaDrvErrorMsg +#endif + +#define getLastCudaDrvErrorMsg(msg) __getLastCudaDrvErrorMsg (msg, __FILE__, __LINE__) + +inline void __getLastCudaDrvErrorMsg(const char *msg, const char *file, const int line) +{ + CUresult err = cuCtxSynchronize(); + + if (CUDA_SUCCESS != err) + { + fprintf(stderr, "getLastCudaDrvErrorMsg -> %s", msg); + fprintf(stderr, "getLastCudaDrvErrorMsg -> cuCtxSynchronize API error = %04d \"%s\" in file <%s>, line %i.\n", + err, getCudaDrvErrorString(err), file, line); + exit(EXIT_FAILURE); + } +} + +// This function wraps the CUDA Driver API into a template function +template +inline void getCudaAttribute(T *attribute, CUdevice_attribute device_attribute, int device) +{ + CUresult error_result = cuDeviceGetAttribute(attribute, device_attribute, device); + + if (error_result != CUDA_SUCCESS) + { + printf("cuDeviceGetAttribute returned %d\n-> %s\n", (int)error_result, getCudaDrvErrorString(error_result)); + exit(EXIT_SUCCESS); + } +} +#endif + +// Beginning of GPU Architecture definitions +inline int _ConvertSMVer2CoresDRV(int major, int minor) +{ + // Defines for GPU Architecture types (using the SM version to determine the # of cores per SM + typedef struct + { + int SM; // 0xMm (hexidecimal notation), M = SM Major version, and m = SM minor version + int Cores; + } sSMtoCores; + + sSMtoCores nGpuArchCoresPerSM[] = + { + { 0x10, 8 }, // Tesla Generation (SM 1.0) G80 class + { 0x11, 8 }, // Tesla Generation (SM 1.1) G8x class + { 0x12, 8 }, // Tesla Generation (SM 1.2) G9x class + { 0x13, 8 }, // Tesla Generation (SM 1.3) GT200 class + { 0x20, 32 }, // Fermi Generation (SM 2.0) GF100 class + { 0x21, 48 }, // Fermi Generation (SM 2.1) GF10x class + { 0x30, 192}, // Kepler Generation (SM 3.0) GK10x class + { 0x35, 192}, // Kepler Generation (SM 3.5) GK11x class + { -1, -1 } + }; + + int index = 0; + + while (nGpuArchCoresPerSM[index].SM != -1) + { + if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor)) + { + return nGpuArchCoresPerSM[index].Cores; + } + + index++; + } + + // If we don't find the values, we default use the previous one to run properly + printf("MapSMtoCores for SM %d.%d is undefined. Default to use %d Cores/SM\n", major, minor, nGpuArchCoresPerSM[7].Cores); + return nGpuArchCoresPerSM[7].Cores; +} +// end of GPU Architecture definitions + +#ifdef __cuda_cuda_h__ +// General GPU Device CUDA Initialization +inline int gpuDeviceInitDRV(int ARGC, const char **ARGV) +{ + int cuDevice = 0; + int deviceCount = 0; + CUresult err = cuInit(0); + + if (CUDA_SUCCESS == err) + { + checkCudaErrors(cuDeviceGetCount(&deviceCount)); + } + + if (deviceCount == 0) + { + fprintf(stderr, "cudaDeviceInit error: no devices supporting CUDA\n"); + exit(EXIT_FAILURE); + } + + int dev = 0; + dev = getCmdLineArgumentInt(ARGC, (const char **) ARGV, "device="); + + if (dev < 0) + { + dev = 0; + } + + if (dev > deviceCount-1) + { + fprintf(stderr, "\n"); + fprintf(stderr, ">> %d CUDA capable GPU device(s) detected. <<\n", deviceCount); + fprintf(stderr, ">> cudaDeviceInit (-device=%d) is not a valid GPU device. <<\n", dev); + fprintf(stderr, "\n"); + return -dev; + } + + checkCudaErrors(cuDeviceGet(&cuDevice, dev)); + char name[100]; + cuDeviceGetName(name, 100, cuDevice); + + int computeMode; + getCudaAttribute(&computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE, dev); + + if (computeMode == CU_COMPUTEMODE_PROHIBITED) + { + fprintf(stderr, "Error: device is running in , no threads can use this CUDA Device.\n"); + return -1; + } + + if (checkCmdLineFlag(ARGC, (const char **) ARGV, "quiet") == false) + { + printf("gpuDeviceInitDRV() Using CUDA Device [%d]: %s\n", dev, name); + } + + return dev; +} + +// This function returns the best GPU based on performance +inline int gpuGetMaxGflopsDeviceIdDRV() +{ + CUdevice current_device = 0, max_perf_device = 0; + int device_count = 0, sm_per_multiproc = 0; + int max_compute_perf = 0, best_SM_arch = 0; + int major = 0, minor = 0 , multiProcessorCount, clockRate; + + cuInit(0); + checkCudaErrors(cuDeviceGetCount(&device_count)); + + if (device_count == 0) + { + fprintf(stderr, "gpuGetMaxGflopsDeviceIdDRV error: no devices supporting CUDA\n"); + exit(EXIT_FAILURE); + } + + // Find the best major SM Architecture GPU device + while (current_device < device_count) + { + checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device)); + + if (major > 0 && major < 9999) + { + best_SM_arch = MAX(best_SM_arch, major); + } + + current_device++; + } + + // Find the best CUDA capable GPU device + current_device = 0; + + while (current_device < device_count) + { + checkCudaErrors(cuDeviceGetAttribute(&multiProcessorCount, + CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT, + current_device)); + checkCudaErrors(cuDeviceGetAttribute(&clockRate, + CU_DEVICE_ATTRIBUTE_CLOCK_RATE, + current_device)); + checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device)); + + int computeMode; + getCudaAttribute(&computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE, current_device); + + if (computeMode != CU_COMPUTEMODE_PROHIBITED) + { + if (major == 9999 && minor == 9999) + { + sm_per_multiproc = 1; + } + else + { + sm_per_multiproc = _ConvertSMVer2CoresDRV(major, minor); + } + + int compute_perf = multiProcessorCount * sm_per_multiproc * clockRate; + + if (compute_perf > max_compute_perf) + { + // If we find GPU with SM major > 2, search only these + if (best_SM_arch > 2) + { + // If our device==dest_SM_arch, choose this, or else pass + if (major == best_SM_arch) + { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } + else + { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } + } + + ++current_device; + } + + return max_perf_device; +} + +// This function returns the best Graphics GPU based on performance +inline int gpuGetMaxGflopsGLDeviceIdDRV() +{ + CUdevice current_device = 0, max_perf_device = 0; + int device_count = 0, sm_per_multiproc = 0; + int max_compute_perf = 0, best_SM_arch = 0; + int major = 0, minor = 0, multiProcessorCount, clockRate; + int bTCC = 0; + char deviceName[256]; + + cuInit(0); + checkCudaErrors(cuDeviceGetCount(&device_count)); + + if (device_count == 0) + { + fprintf(stderr, "gpuGetMaxGflopsGLDeviceIdDRV error: no devices supporting CUDA\n"); + exit(EXIT_FAILURE); + } + + // Find the best major SM Architecture GPU device that are graphics devices + while (current_device < device_count) + { + checkCudaErrors(cuDeviceGetName(deviceName, 256, current_device)); + checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device)); + +#if CUDA_VERSION >= 3020 + checkCudaErrors(cuDeviceGetAttribute(&bTCC, CU_DEVICE_ATTRIBUTE_TCC_DRIVER, current_device)); +#else + + // Assume a Tesla GPU is running in TCC if we are running CUDA 3.1 + if (deviceName[0] == 'T') + { + bTCC = 1; + } + +#endif + + int computeMode; + getCudaAttribute(&computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE, current_device); + + if (computeMode != CU_COMPUTEMODE_PROHIBITED) + { + if (!bTCC) + { + if (major > 0 && major < 9999) + { + best_SM_arch = MAX(best_SM_arch, major); + } + } + } + + current_device++; + } + + // Find the best CUDA capable GPU device + current_device = 0; + + while (current_device < device_count) + { + checkCudaErrors(cuDeviceGetAttribute(&multiProcessorCount, + CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT, + current_device)); + checkCudaErrors(cuDeviceGetAttribute(&clockRate, + CU_DEVICE_ATTRIBUTE_CLOCK_RATE, + current_device)); + checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device)); + +#if CUDA_VERSION >= 3020 + checkCudaErrors(cuDeviceGetAttribute(&bTCC, CU_DEVICE_ATTRIBUTE_TCC_DRIVER, current_device)); +#else + + // Assume a Tesla GPU is running in TCC if we are running CUDA 3.1 + if (deviceName[0] == 'T') + { + bTCC = 1; + } + +#endif + + int computeMode; + getCudaAttribute(&computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE, current_device); + + if (computeMode != CU_COMPUTEMODE_PROHIBITED) + { + if (major == 9999 && minor == 9999) + { + sm_per_multiproc = 1; + } + else + { + sm_per_multiproc = _ConvertSMVer2CoresDRV(major, minor); + } + + // If this is a Tesla based GPU and SM 2.0, and TCC is disabled, this is a contendor + if (!bTCC) // Is this GPU running the TCC driver? If so we pass on this + { + int compute_perf = multiProcessorCount * sm_per_multiproc * clockRate; + + if (compute_perf > max_compute_perf) + { + // If we find GPU with SM major > 2, search only these + if (best_SM_arch > 2) + { + // If our device = dest_SM_arch, then we pick this one + if (major == best_SM_arch) + { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } + else + { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } + } + } + + ++current_device; + } + + return max_perf_device; +} + +// General initialization call to pick the best CUDA Device +inline CUdevice findCudaDeviceDRV(int argc, const char **argv) +{ + CUdevice cuDevice; + int devID = 0; + + // If the command-line has a device number specified, use it + if (checkCmdLineFlag(argc, (const char **)argv, "device")) + { + devID = gpuDeviceInitDRV(argc, argv); + + if (devID < 0) + { + printf("exiting...\n"); + exit(EXIT_SUCCESS); + } + } + else + { + // Otherwise pick the device with highest Gflops/s + char name[100]; + devID = gpuGetMaxGflopsDeviceIdDRV(); + checkCudaErrors(cuDeviceGet(&cuDevice, devID)); + cuDeviceGetName(name, 100, cuDevice); + printf("> Using CUDA Device [%d]: %s\n", devID, name); + } + + cuDeviceGet(&cuDevice, devID); + + return cuDevice; +} + +// This function will pick the best CUDA device available with OpenGL interop +inline CUdevice findCudaGLDeviceDRV(int argc, const char **argv) +{ + CUdevice cuDevice; + int devID = 0; + + // If the command-line has a device number specified, use it + if (checkCmdLineFlag(argc, (const char **)argv, "device")) + { + devID = gpuDeviceInitDRV(argc, (const char **)argv); + + if (devID < 0) + { + printf("no CUDA capable devices found, exiting...\n"); + exit(EXIT_SUCCESS); + } + } + else + { + char name[100]; + // Otherwise pick the device with highest Gflops/s + devID = gpuGetMaxGflopsGLDeviceIdDRV(); + checkCudaErrors(cuDeviceGet(&cuDevice, devID)); + cuDeviceGetName(name, 100, cuDevice); + printf("> Using CUDA/GL Device [%d]: %s\n", devID, name); + } + + return devID; +} + +// General check for CUDA GPU SM Capabilities +inline bool checkCudaCapabilitiesDRV(int major_version, int minor_version, int devID) +{ + CUdevice cuDevice; + char name[256]; + int major = 0, minor = 0; + + checkCudaErrors(cuDeviceGet(&cuDevice, devID)); + checkCudaErrors(cuDeviceGetName(name, 100, cuDevice)); + checkCudaErrors(cuDeviceComputeCapability(&major, &minor, devID)); + + if ((major > major_version) || + (major == major_version && minor >= minor_version)) + { + printf("> Device %d: <%16s >, Compute SM %d.%d detected\n", devID, name, major, minor); + return true; + } + else + { + printf("No GPU device was found that can support CUDA compute capability %d.%d.\n", major_version, minor_version); + return false; + } +} +#endif + +// end of CUDA Helper Functions + +#endif diff --git a/external/cutil/inc/helper_cuda_gl.h b/external/cutil/inc/helper_cuda_gl.h new file mode 100644 index 0000000..49f3d5b --- /dev/null +++ b/external/cutil/inc/helper_cuda_gl.h @@ -0,0 +1,165 @@ +/** + * Copyright 1993-2013 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +#ifndef HELPER_CUDA_GL_H +#define HELPER_CUDA_GL_H + +#include +#include +#include + +// includes, graphics +#if defined (__APPLE__) || defined(MACOSX) +#include +#include +#else +#include +#include +#endif + +#ifndef EXIT_WAIVED +#define EXIT_WAIVED 2 +#endif + +#ifdef __DRIVER_TYPES_H__ +#ifndef DEVICE_RESET +#define DEVICE_RESET cudaDeviceReset() +#endif +#else +#ifndef DEVICE_RESET +#define DEVICE_RESET +#endif +#endif + +#ifdef __CUDA_GL_INTEROP_H__ +//////////////////////////////////////////////////////////////////////////////// +// These are CUDA OpenGL Helper functions + +inline int gpuGLDeviceInit(int ARGC, const char **ARGV) +{ + int deviceCount; + checkCudaErrors(cudaGetDeviceCount(&deviceCount)); + + if (deviceCount == 0) + { + fprintf(stderr, "CUDA error: no devices supporting CUDA.\n"); + exit(EXIT_FAILURE); + } + + int dev = 0; + dev = getCmdLineArgumentInt(ARGC, ARGV, "device="); + + if (dev < 0) + { + dev = 0; + } + + if (dev > deviceCount-1) + { + fprintf(stderr, "\n"); + fprintf(stderr, ">> %d CUDA capable GPU device(s) detected. <<\n", deviceCount); + fprintf(stderr, ">> gpuGLDeviceInit (-device=%d) is not a valid GPU device. <<\n", dev); + fprintf(stderr, "\n"); + return -dev; + } + + cudaDeviceProp deviceProp; + checkCudaErrors(cudaGetDeviceProperties(&deviceProp, dev)); + + if (deviceProp.computeMode == cudaComputeModeProhibited) + { + fprintf(stderr, "Error: device is running in , no threads can use ::cudaSetDevice().\n"); + return -1; + } + + if (deviceProp.major < 1) + { + fprintf(stderr, "Error: device does not support CUDA.\n"); + exit(EXIT_FAILURE); + } + + if (checkCmdLineFlag(ARGC, ARGV, "quiet") == false) + { + fprintf(stderr, "Using device %d: %s\n", dev, deviceProp.name); + } + + checkCudaErrors(cudaGLSetGLDevice(dev)); + return dev; +} + +// This function will pick the best CUDA device available with OpenGL interop +inline int findCudaGLDevice(int argc, const char **argv) +{ + int devID = 0; + + // If the command-line has a device number specified, use it + if (checkCmdLineFlag(argc, (const char **)argv, "device")) + { + devID = gpuGLDeviceInit(argc, (const char **)argv); + + if (devID < 0) + { + printf("no CUDA capable devices found, exiting...\n"); + DEVICE_RESET + exit(EXIT_SUCCESS); + } + } + else + { + // Otherwise pick the device with highest Gflops/s + devID = gpuGetMaxGflopsDeviceId(); + cudaGLSetGLDevice(devID); + } + + return devID; +} + +//////////////////////////////////////////////////////////////////////////// +//! Check for OpenGL error +//! @return bool if no GL error has been encountered, otherwise 0 +//! @param file __FILE__ macro +//! @param line __LINE__ macro +//! @note The GL error is listed on stderr +//! @note This function should be used via the CHECK_ERROR_GL() macro +//////////////////////////////////////////////////////////////////////////// +inline bool +sdkCheckErrorGL(const char *file, const int line) +{ + bool ret_val = true; + + // check for error + GLenum gl_error = glGetError(); + + if (gl_error != GL_NO_ERROR) + { +#ifdef _WIN32 + char tmpStr[512]; + // NOTE: "%s(%i) : " allows Visual Studio to directly jump to the file at the right line + // when the user double clicks on the error line in the Output pane. Like any compile error. + sprintf_s(tmpStr, 255, "\n%s(%i) : GL Error : %s\n\n", file, line, gluErrorString(gl_error)); + fprintf(stderr, "%s", tmpStr); +#endif + fprintf(stderr, "GL Error in file '%s' in line %d :\n", file, line); + fprintf(stderr, "%s\n", gluErrorString(gl_error)); + ret_val = false; + } + + return ret_val; +} + +#define SDK_CHECK_ERROR_GL() \ + if( false == sdkCheckErrorGL( __FILE__, __LINE__)) { \ + DEVICE_RESET \ + exit(EXIT_FAILURE); \ + } +#endif + +#endif diff --git a/external/cutil/inc/helper_functions.h b/external/cutil/inc/helper_functions.h new file mode 100644 index 0000000..11538ba --- /dev/null +++ b/external/cutil/inc/helper_functions.h @@ -0,0 +1,42 @@ +/** + * Copyright 1993-2013 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +// These are helper functions for the SDK samples (string parsing, timers, image helpers, etc) +#ifndef HELPER_FUNCTIONS_H +#define HELPER_FUNCTIONS_H + +#ifdef WIN32 +#pragma warning(disable:4996) +#endif + +// includes, project +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +// includes, timer, string parsing, image helpers +#include // helper functions for timers +#include // helper functions for string parsing +#include // helper functions for image compare, dump, data comparisons + +#ifndef EXIT_WAIVED +#define EXIT_WAIVED 2 +#endif + +#endif // HELPER_FUNCTIONS_H diff --git a/external/cutil/inc/helper_image.h b/external/cutil/inc/helper_image.h new file mode 100644 index 0000000..d6c59db --- /dev/null +++ b/external/cutil/inc/helper_image.h @@ -0,0 +1,1110 @@ +/** + * Copyright 1993-2013 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +// These are helper functions for the SDK samples (image,bitmap) +#ifndef HELPER_IMAGE_H +#define HELPER_IMAGE_H + +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifndef MIN +#define MIN(a,b) ((a < b) ? a : b) +#endif +#ifndef MAX +#define MAX(a,b) ((a > b) ? a : b) +#endif + +#ifndef EXIT_WAIVED +#define EXIT_WAIVED 2 +#endif + +#include + +// namespace unnamed (internal) +namespace +{ + //! size of PGM file header + const unsigned int PGMHeaderSize = 0x40; + + // types + + //! Data converter from unsigned char / unsigned byte to type T + template + struct ConverterFromUByte; + + //! Data converter from unsigned char / unsigned byte + template<> + struct ConverterFromUByte + { + //! Conversion operator + //! @return converted value + //! @param val value to convert + float operator()(const unsigned char &val) + { + return static_cast(val); + } + }; + + //! Data converter from unsigned char / unsigned byte to float + template<> + struct ConverterFromUByte + { + //! Conversion operator + //! @return converted value + //! @param val value to convert + float operator()(const unsigned char &val) + { + return static_cast(val) / 255.0f; + } + }; + + //! Data converter from unsigned char / unsigned byte to type T + template + struct ConverterToUByte; + + //! Data converter from unsigned char / unsigned byte to unsigned int + template<> + struct ConverterToUByte + { + //! Conversion operator (essentially a passthru + //! @return converted value + //! @param val value to convert + unsigned char operator()(const unsigned char &val) + { + return val; + } + }; + + //! Data converter from unsigned char / unsigned byte to unsigned int + template<> + struct ConverterToUByte + { + //! Conversion operator + //! @return converted value + //! @param val value to convert + unsigned char operator()(const float &val) + { + return static_cast(val * 255.0f); + } + }; +} + +#ifdef _WIN32 +#ifndef FOPEN +#define FOPEN(fHandle,filename,mode) fopen_s(&fHandle, filename, mode) +#endif +#ifndef FOPEN_FAIL +#define FOPEN_FAIL(result) (result != 0) +#endif +#ifndef SSCANF +#define SSCANF sscanf_s +#endif +#else +#ifndef FOPEN +#define FOPEN(fHandle,filename,mode) (fHandle = fopen(filename, mode)) +#endif +#ifndef FOPEN_FAIL +#define FOPEN_FAIL(result) (result == NULL) +#endif +#ifndef SSCANF +#define SSCANF sscanf +#endif +#endif + +inline bool +__loadPPM(const char *file, unsigned char **data, + unsigned int *w, unsigned int *h, unsigned int *channels) +{ + FILE *fp = NULL; + + if (FOPEN_FAIL(FOPEN(fp, file, "rb"))) + { + std::cerr << "__LoadPPM() : Failed to open file: " << file << std::endl; + return false; + } + + // check header + char header[PGMHeaderSize]; + + if (fgets(header, PGMHeaderSize, fp) == NULL) + { + std::cerr << "__LoadPPM() : reading PGM header returned NULL" << std::endl; + return false; + } + + if (strncmp(header, "P5", 2) == 0) + { + *channels = 1; + } + else if (strncmp(header, "P6", 2) == 0) + { + *channels = 3; + } + else + { + std::cerr << "__LoadPPM() : File is not a PPM or PGM image" << std::endl; + *channels = 0; + return false; + } + + // parse header, read maxval, width and height + unsigned int width = 0; + unsigned int height = 0; + unsigned int maxval = 0; + unsigned int i = 0; + + while (i < 3) + { + if (fgets(header, PGMHeaderSize, fp) == NULL) + { + std::cerr << "__LoadPPM() : reading PGM header returned NULL" << std::endl; + return false; + } + + if (header[0] == '#') + { + continue; + } + + if (i == 0) + { + i += SSCANF(header, "%u %u %u", &width, &height, &maxval); + } + else if (i == 1) + { + i += SSCANF(header, "%u %u", &height, &maxval); + } + else if (i == 2) + { + i += SSCANF(header, "%u", &maxval); + } + } + + // check if given handle for the data is initialized + if (NULL != *data) + { + if (*w != width || *h != height) + { + std::cerr << "__LoadPPM() : Invalid image dimensions." << std::endl; + } + } + else + { + *data = (unsigned char *) malloc(sizeof(unsigned char) * width * height * *channels); + *w = width; + *h = height; + } + + // read and close file + if (fread(*data, sizeof(unsigned char), width * height * *channels, fp) == 0) + { + std::cerr << "__LoadPPM() read data returned error." << std::endl; + } + + fclose(fp); + + return true; +} + +template +inline bool +sdkLoadPGM(const char *file, T **data, unsigned int *w, unsigned int *h) +{ + unsigned char *idata = NULL; + unsigned int channels; + + if (true != __loadPPM(file, &idata, w, h, &channels)) + { + return false; + } + + unsigned int size = *w * *h * channels; + + // initialize mem if necessary + // the correct size is checked / set in loadPGMc() + if (NULL == *data) + { + *data = (T *) malloc(sizeof(T) * size); + } + + // copy and cast data + std::transform(idata, idata + size, *data, ConverterFromUByte()); + + free(idata); + + return true; +} + +template +inline bool +sdkLoadPPM4(const char *file, T **data, + unsigned int *w,unsigned int *h) +{ + unsigned char *idata = 0; + unsigned int channels; + + if (__loadPPM(file, &idata, w, h, &channels)) + { + // pad 4th component + int size = *w * *h; + // keep the original pointer + unsigned char *idata_orig = idata; + *data = (T *) malloc(sizeof(T) * size * 4); + unsigned char *ptr = *data; + + for (int i=0; i 0); + assert(h > 0); + + std::fstream fh(file, std::fstream::out | std::fstream::binary); + + if (fh.bad()) + { + std::cerr << "__savePPM() : Opening file failed." << std::endl; + return false; + } + + if (channels == 1) + { + fh << "P5\n"; + } + else if (channels == 3) + { + fh << "P6\n"; + } + else + { + std::cerr << "__savePPM() : Invalid number of channels." << std::endl; + return false; + } + + fh << w << "\n" << h << "\n" << 0xff << std::endl; + + for (unsigned int i = 0; (i < (w*h*channels)) && fh.good(); ++i) + { + fh << data[i]; + } + + fh.flush(); + + if (fh.bad()) + { + std::cerr << "__savePPM() : Writing data failed." << std::endl; + return false; + } + + fh.close(); + + return true; +} + +template +inline bool +sdkSavePGM(const char *file, T *data, unsigned int w, unsigned int h) +{ + unsigned int size = w * h; + unsigned char *idata = + (unsigned char *) malloc(sizeof(unsigned char) * size); + + std::transform(data, data + size, idata, ConverterToUByte()); + + // write file + bool result = __savePPM(file, idata, w, h, 1); + + // cleanup + free(idata); + + return result; +} + +inline bool +sdkSavePPM4ub(const char *file, unsigned char *data, + unsigned int w, unsigned int h) +{ + // strip 4th component + int size = w * h; + unsigned char *ndata = (unsigned char *) malloc(sizeof(unsigned char) * size*3); + unsigned char *ptr = ndata; + + for (int i=0; i +inline bool +sdkReadFile(const char *filename, T **data, unsigned int *len, bool verbose) +{ + // check input arguments + assert(NULL != filename); + assert(NULL != len); + + // intermediate storage for the data read + std::vector data_read; + + // open file for reading + FILE *fh = NULL; + + // check if filestream is valid + if (FOPEN_FAIL(FOPEN(fh, filename, "r"))) + { + printf("Unable to open input file: %s\n", filename); + return false; + } + + // read all data elements + T token; + + while (!feof(fh)) + { + fscanf(fh, "%f", &token); + data_read.push_back(token); + } + + // the last element is read twice + data_read.pop_back(); + fclose(fh); + + // check if the given handle is already initialized + if (NULL != *data) + { + if (*len != data_read.size()) + { + std::cerr << "sdkReadFile() : Initialized memory given but " + << "size mismatch with signal read " + << "(data read / data init = " << (unsigned int)data_read.size() + << " / " << *len << ")" << std::endl; + + return false; + } + } + else + { + // allocate storage for the data read + *data = (T *) malloc(sizeof(T) * data_read.size()); + // store signal size + *len = static_cast(data_read.size()); + } + + // copy data + memcpy(*data, &data_read.front(), sizeof(T) * data_read.size()); + + return true; +} + +////////////////////////////////////////////////////////////////////////////// +//! Read file \filename and return the data +//! @return bool if reading the file succeeded, otherwise false +//! @param filename name of the source file +//! @param data uninitialized pointer, returned initialized and pointing to +//! the data read +//! @param len number of data elements in data, -1 on error +////////////////////////////////////////////////////////////////////////////// +template +inline bool +sdkReadFileBlocks(const char *filename, T **data, unsigned int *len, unsigned int block_num, unsigned int block_size, bool verbose) +{ + // check input arguments + assert(NULL != filename); + assert(NULL != len); + + // open file for reading + FILE *fh = fopen(filename, "rb"); + + if (fh == NULL && verbose) + { + std::cerr << "sdkReadFile() : Opening file failed." << std::endl; + return false; + } + + // check if the given handle is already initialized + // allocate storage for the data read + data[block_num] = (T *) malloc(block_size); + + // read all data elements + fseek(fh, block_num * block_size, SEEK_SET); + *len = fread(data[block_num], sizeof(T), block_size/sizeof(T), fh); + + fclose(fh); + + return true; +} + +////////////////////////////////////////////////////////////////////////////// +//! Write a data file \filename +//! @return true if writing the file succeeded, otherwise false +//! @param filename name of the source file +//! @param data data to write +//! @param len number of data elements in data, -1 on error +//! @param epsilon epsilon for comparison +////////////////////////////////////////////////////////////////////////////// +template +inline bool +sdkWriteFile(const char *filename, const T *data, unsigned int len, + const S epsilon, bool verbose, bool append = false) +{ + assert(NULL != filename); + assert(NULL != data); + + // open file for writing + // if (append) { + std::fstream fh(filename, std::fstream::out | std::fstream::ate); + + if (verbose) + { + std::cerr << "sdkWriteFile() : Open file " << filename << " for write/append." << std::endl; + } + + /* } else { + std::fstream fh(filename, std::fstream::out); + if (verbose) { + std::cerr << "sdkWriteFile() : Open file " << filename << " for write." << std::endl; + } + } + */ + + // check if filestream is valid + if (! fh.good()) + { + if (verbose) + { + std::cerr << "sdkWriteFile() : Opening file failed." << std::endl; + } + + return false; + } + + // first write epsilon + fh << "# " << epsilon << "\n"; + + // write data + for (unsigned int i = 0; (i < len) && (fh.good()); ++i) + { + fh << data[i] << ' '; + } + + // Check if writing succeeded + if (! fh.good()) + { + if (verbose) + { + std::cerr << "sdkWriteFile() : Writing file failed." << std::endl; + } + + return false; + } + + // file ends with nl + fh << std::endl; + + return true; +} + +////////////////////////////////////////////////////////////////////////////// +//! Compare two arrays of arbitrary type +//! @return true if \a reference and \a data are identical, otherwise false +//! @param reference timer_interface to the reference data / gold image +//! @param data handle to the computed data +//! @param len number of elements in reference and data +//! @param epsilon epsilon to use for the comparison +////////////////////////////////////////////////////////////////////////////// +template +inline bool +compareData(const T *reference, const T *data, const unsigned int len, + const S epsilon, const float threshold) +{ + assert(epsilon >= 0); + + bool result = true; + unsigned int error_count = 0; + + for (unsigned int i = 0; i < len; ++i) + { + float diff = (float)reference[i] - (float)data[i]; + bool comp = (diff <= epsilon) && (diff >= -epsilon); + result &= comp; + + error_count += !comp; + +#if 0 + + if (! comp) + { + std::cerr << "ERROR, i = " << i << ",\t " + << reference[i] << " / " + << data[i] + << " (reference / data)\n"; + } + +#endif + } + + if (threshold == 0.0f) + { + return (result) ? true : false; + } + else + { + if (error_count) + { + printf("%4.2f(%%) of bytes mismatched (count=%d)\n", (float)error_count*100/(float)len, error_count); + } + + return (len*threshold > error_count) ? true : false; + } +} + +#ifndef __MIN_EPSILON_ERROR +#define __MIN_EPSILON_ERROR 1e-3f +#endif + +////////////////////////////////////////////////////////////////////////////// +//! Compare two arrays of arbitrary type +//! @return true if \a reference and \a data are identical, otherwise false +//! @param reference handle to the reference data / gold image +//! @param data handle to the computed data +//! @param len number of elements in reference and data +//! @param epsilon epsilon to use for the comparison +//! @param epsilon threshold % of (# of bytes) for pass/fail +////////////////////////////////////////////////////////////////////////////// +template +inline bool +compareDataAsFloatThreshold(const T *reference, const T *data, const unsigned int len, + const S epsilon, const float threshold) +{ + assert(epsilon >= 0); + + // If we set epsilon to be 0, let's set a minimum threshold + float max_error = MAX((float)epsilon, __MIN_EPSILON_ERROR); + int error_count = 0; + bool result = true; + + for (unsigned int i = 0; i < len; ++i) + { + float diff = fabs((float)reference[i] - (float)data[i]); + bool comp = (diff < max_error); + result &= comp; + + if (! comp) + { + error_count++; +#if 0 + + if (error_count < 50) + { + printf("\n ERROR(epsilon=%4.3f), i=%d, (ref)0x%02x / (data)0x%02x / (diff)%d\n", + max_error, i, + *(unsigned int *)&reference[i], + *(unsigned int *)&data[i], + (unsigned int)diff); + } + +#endif + } + } + + if (threshold == 0.0f) + { + if (error_count) + { + printf("total # of errors = %d\n", error_count); + } + + return (error_count == 0) ? true : false; + } + else + { + if (error_count) + { + printf("%4.2f(%%) of bytes mismatched (count=%d)\n", (float)error_count*100/(float)len, error_count); + } + + return ((len*threshold > error_count) ? true : false); + } +} + +inline +void sdkDumpBin(void *data, unsigned int bytes, const char *filename) +{ + printf("sdkDumpBin: <%s>\n", filename); + FILE *fp; + FOPEN(fp, filename, "wb"); + fwrite(data, bytes, 1, fp); + fflush(fp); + fclose(fp); +} + +inline +bool sdkCompareBin2BinUint(const char *src_file, const char *ref_file, unsigned int nelements, const float epsilon, const float threshold, char *exec_path) +{ + unsigned int *src_buffer, *ref_buffer; + FILE *src_fp = NULL, *ref_fp = NULL; + + unsigned long error_count = 0; + size_t fsize = 0; + + if (FOPEN_FAIL(FOPEN(src_fp, src_file, "rb"))) + { + printf("compareBin2Bin unable to open src_file: %s\n", src_file); + error_count++; + } + + char *ref_file_path = sdkFindFilePath(ref_file, exec_path); + + if (ref_file_path == NULL) + { + printf("compareBin2Bin unable to find <%s> in <%s>\n", ref_file, exec_path); + printf(">>> Check info.xml and [project//data] folder <%s> <<<\n", ref_file); + printf("Aborting comparison!\n"); + printf(" FAILED\n"); + error_count++; + + if (src_fp) + { + fclose(src_fp); + } + + if (ref_fp) + { + fclose(ref_fp); + } + } + else + { + if (FOPEN_FAIL(FOPEN(ref_fp, ref_file_path, "rb"))) + { + printf("compareBin2Bin unable to open ref_file: %s\n", ref_file_path); + error_count++; + } + + if (src_fp && ref_fp) + { + src_buffer = (unsigned int *)malloc(nelements*sizeof(unsigned int)); + ref_buffer = (unsigned int *)malloc(nelements*sizeof(unsigned int)); + + fsize = fread(src_buffer, nelements, sizeof(unsigned int), src_fp); + fsize = fread(ref_buffer, nelements, sizeof(unsigned int), ref_fp); + + printf("> compareBin2Bin nelements=%d, epsilon=%4.2f, threshold=%4.2f\n", nelements, epsilon, threshold); + printf(" src_file <%s>, size=%d bytes\n", src_file, (int)fsize); + printf(" ref_file <%s>, size=%d bytes\n", ref_file_path, (int)fsize); + + if (!compareData(ref_buffer, src_buffer, nelements, epsilon, threshold)) + { + error_count++; + } + + fclose(src_fp); + fclose(ref_fp); + + free(src_buffer); + free(ref_buffer); + } + else + { + if (src_fp) + { + fclose(src_fp); + } + + if (ref_fp) + { + fclose(ref_fp); + } + } + } + + if (error_count == 0) + { + printf(" OK\n"); + } + else + { + printf(" FAILURE: %d errors...\n", (unsigned int)error_count); + } + + return (error_count == 0); // returns true if all pixels pass +} + +inline +bool sdkCompareBin2BinFloat(const char *src_file, const char *ref_file, unsigned int nelements, const float epsilon, const float threshold, char *exec_path) +{ + float *src_buffer, *ref_buffer; + FILE *src_fp = NULL, *ref_fp = NULL; + size_t fsize = 0; + + unsigned long error_count = 0; + + if (FOPEN_FAIL(FOPEN(src_fp, src_file, "rb"))) + { + printf("compareBin2Bin unable to open src_file: %s\n", src_file); + error_count = 1; + } + + char *ref_file_path = sdkFindFilePath(ref_file, exec_path); + + if (ref_file_path == NULL) + { + printf("compareBin2Bin unable to find <%s> in <%s>\n", ref_file, exec_path); + printf(">>> Check info.xml and [project//data] folder <%s> <<<\n", exec_path); + printf("Aborting comparison!\n"); + printf(" FAILED\n"); + error_count++; + + if (src_fp) + { + fclose(src_fp); + } + + if (ref_fp) + { + fclose(ref_fp); + } + } + else + { + if (FOPEN_FAIL(FOPEN(ref_fp, ref_file_path, "rb"))) + { + printf("compareBin2Bin unable to open ref_file: %s\n", ref_file_path); + error_count = 1; + } + + if (src_fp && ref_fp) + { + src_buffer = (float *)malloc(nelements*sizeof(float)); + ref_buffer = (float *)malloc(nelements*sizeof(float)); + + fsize = fread(src_buffer, nelements, sizeof(float), src_fp); + fsize = fread(ref_buffer, nelements, sizeof(float), ref_fp); + + printf("> compareBin2Bin nelements=%d, epsilon=%4.2f, threshold=%4.2f\n", nelements, epsilon, threshold); + printf(" src_file <%s>, size=%d bytes\n", src_file, (int)fsize); + printf(" ref_file <%s>, size=%d bytes\n", ref_file_path, (int)fsize); + + if (!compareDataAsFloatThreshold(ref_buffer, src_buffer, nelements, epsilon, threshold)) + { + error_count++; + } + + fclose(src_fp); + fclose(ref_fp); + + free(src_buffer); + free(ref_buffer); + } + else + { + if (src_fp) + { + fclose(src_fp); + } + + if (ref_fp) + { + fclose(ref_fp); + } + } + } + + if (error_count == 0) + { + printf(" OK\n"); + } + else + { + printf(" FAILURE: %d errors...\n", (unsigned int)error_count); + } + + return (error_count == 0); // returns true if all pixels pass +} + +inline bool +sdkCompareL2fe(const float *reference, const float *data, + const unsigned int len, const float epsilon) +{ + assert(epsilon >= 0); + + float error = 0; + float ref = 0; + + for (unsigned int i = 0; i < len; ++i) + { + + float diff = reference[i] - data[i]; + error += diff * diff; + ref += reference[i] * reference[i]; + } + + float normRef = sqrtf(ref); + + if (fabs(ref) < 1e-7) + { +#ifdef _DEBUG + std::cerr << "ERROR, reference l2-norm is 0\n"; +#endif + return false; + } + + float normError = sqrtf(error); + error = normError / normRef; + bool result = error < epsilon; +#ifdef _DEBUG + + if (! result) + { + std::cerr << "ERROR, l2-norm error " + << error << " is greater than epsilon " << epsilon << "\n"; + } + +#endif + + return result; +} + +inline bool +sdkLoadPPMub(const char *file, unsigned char **data, + unsigned int *w,unsigned int *h) +{ + unsigned int channels; + return __loadPPM(file, data, w, h, &channels); +} + +inline bool +sdkLoadPPM4ub(const char *file, unsigned char **data, + unsigned int *w, unsigned int *h) +{ + unsigned char *idata = 0; + unsigned int channels; + + if (__loadPPM(file, &idata, w, h, &channels)) + { + // pad 4th component + int size = *w * *h; + // keep the original pointer + unsigned char *idata_orig = idata; + *data = (unsigned char *) malloc(sizeof(unsigned char) * size * 4); + unsigned char *ptr = *data; + + for (int i=0; i Compare (a)rendered: <" << src_file << ">\n"; + std::cerr << "> (b)reference: <" << ref_file << ">\n"; + } + + + if (sdkLoadPPM4ub(ref_file, &ref_data, &ref_width, &ref_height) != true) + { + if (verboseErrors) + { + std::cerr << "PPMvsPPM: unable to load ref image file: "<< ref_file << "\n"; + } + + return false; + } + + if (sdkLoadPPM4ub(src_file, &src_data, &src_width, &src_height) != true) + { + std::cerr << "PPMvsPPM: unable to load src image file: " << src_file << "\n"; + return false; + } + + if (src_height != ref_height || src_width != ref_width) + { + if (verboseErrors) std::cerr << "PPMvsPPM: source and ref size mismatch (" << src_width << + "," << src_height << ")vs(" << ref_width << "," << ref_height << ")\n"; + } + + if (verboseErrors) std::cerr << "PPMvsPPM: comparing images size (" << src_width << + "," << src_height << ") epsilon(" << epsilon << "), threshold(" << threshold*100 << "%)\n"; + + if (compareData(ref_data, src_data, src_width*src_height*4, epsilon, threshold) == false) + { + error_count=1; + } + + if (error_count == 0) + { + if (verboseErrors) + { + std::cerr << " OK\n\n"; + } + } + else + { + if (verboseErrors) + { + std::cerr << " FAILURE! "< Compare (a)rendered: <" << src_file << ">\n"; + std::cerr << "> (b)reference: <" << ref_file << ">\n"; + } + + + if (sdkLoadPPMub(ref_file, &ref_data, &ref_width, &ref_height) != true) + { + if (verboseErrors) + { + std::cerr << "PGMvsPGM: unable to load ref image file: "<< ref_file << "\n"; + } + + return false; + } + + if (sdkLoadPPMub(src_file, &src_data, &src_width, &src_height) != true) + { + std::cerr << "PGMvsPGM: unable to load src image file: " << src_file << "\n"; + return false; + } + + if (src_height != ref_height || src_width != ref_width) + { + if (verboseErrors) std::cerr << "PGMvsPGM: source and ref size mismatch (" << src_width << + "," << src_height << ")vs(" << ref_width << "," << ref_height << ")\n"; + } + + if (verboseErrors) std::cerr << "PGMvsPGM: comparing images size (" << src_width << + "," << src_height << ") epsilon(" << epsilon << "), threshold(" << threshold*100 << "%)\n"; + + if (compareData(ref_data, src_data, src_width*src_height, epsilon, threshold) == false) + { + error_count=1; + } + + if (error_count == 0) + { + if (verboseErrors) + { + std::cerr << " OK\n\n"; + } + } + else + { + if (verboseErrors) + { + std::cerr << " FAILURE! "< + +//////////////////////////////////////////////////////////////////////////////// +// host implementations of CUDA functions +//////////////////////////////////////////////////////////////////////////////// + +inline float fminf(float a, float b) +{ + return a < b ? a : b; +} + +inline float fmaxf(float a, float b) +{ + return a > b ? a : b; +} + +inline int max(int a, int b) +{ + return a > b ? a : b; +} + +inline int min(int a, int b) +{ + return a < b ? a : b; +} + +inline float rsqrtf(float x) +{ + return 1.0f / sqrtf(x); +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +// constructors +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 make_float2(float s) +{ + return make_float2(s, s); +} +inline __host__ __device__ float2 make_float2(float3 a) +{ + return make_float2(a.x, a.y); +} +inline __host__ __device__ float2 make_float2(int2 a) +{ + return make_float2(float(a.x), float(a.y)); +} +inline __host__ __device__ float2 make_float2(uint2 a) +{ + return make_float2(float(a.x), float(a.y)); +} + +inline __host__ __device__ int2 make_int2(int s) +{ + return make_int2(s, s); +} +inline __host__ __device__ int2 make_int2(int3 a) +{ + return make_int2(a.x, a.y); +} +inline __host__ __device__ int2 make_int2(uint2 a) +{ + return make_int2(int(a.x), int(a.y)); +} +inline __host__ __device__ int2 make_int2(float2 a) +{ + return make_int2(int(a.x), int(a.y)); +} + +inline __host__ __device__ uint2 make_uint2(uint s) +{ + return make_uint2(s, s); +} +inline __host__ __device__ uint2 make_uint2(uint3 a) +{ + return make_uint2(a.x, a.y); +} +inline __host__ __device__ uint2 make_uint2(int2 a) +{ + return make_uint2(uint(a.x), uint(a.y)); +} + +inline __host__ __device__ float3 make_float3(float s) +{ + return make_float3(s, s, s); +} +inline __host__ __device__ float3 make_float3(float2 a) +{ + return make_float3(a.x, a.y, 0.0f); +} +inline __host__ __device__ float3 make_float3(float2 a, float s) +{ + return make_float3(a.x, a.y, s); +} +inline __host__ __device__ float3 make_float3(float4 a) +{ + return make_float3(a.x, a.y, a.z); +} +inline __host__ __device__ float3 make_float3(int3 a) +{ + return make_float3(float(a.x), float(a.y), float(a.z)); +} +inline __host__ __device__ float3 make_float3(uint3 a) +{ + return make_float3(float(a.x), float(a.y), float(a.z)); +} + +inline __host__ __device__ int3 make_int3(int s) +{ + return make_int3(s, s, s); +} +inline __host__ __device__ int3 make_int3(int2 a) +{ + return make_int3(a.x, a.y, 0); +} +inline __host__ __device__ int3 make_int3(int2 a, int s) +{ + return make_int3(a.x, a.y, s); +} +inline __host__ __device__ int3 make_int3(uint3 a) +{ + return make_int3(int(a.x), int(a.y), int(a.z)); +} +inline __host__ __device__ int3 make_int3(float3 a) +{ + return make_int3(int(a.x), int(a.y), int(a.z)); +} + +inline __host__ __device__ uint3 make_uint3(uint s) +{ + return make_uint3(s, s, s); +} +inline __host__ __device__ uint3 make_uint3(uint2 a) +{ + return make_uint3(a.x, a.y, 0); +} +inline __host__ __device__ uint3 make_uint3(uint2 a, uint s) +{ + return make_uint3(a.x, a.y, s); +} +inline __host__ __device__ uint3 make_uint3(uint4 a) +{ + return make_uint3(a.x, a.y, a.z); +} +inline __host__ __device__ uint3 make_uint3(int3 a) +{ + return make_uint3(uint(a.x), uint(a.y), uint(a.z)); +} + +inline __host__ __device__ float4 make_float4(float s) +{ + return make_float4(s, s, s, s); +} +inline __host__ __device__ float4 make_float4(float3 a) +{ + return make_float4(a.x, a.y, a.z, 0.0f); +} +inline __host__ __device__ float4 make_float4(float3 a, float w) +{ + return make_float4(a.x, a.y, a.z, w); +} +inline __host__ __device__ float4 make_float4(int4 a) +{ + return make_float4(float(a.x), float(a.y), float(a.z), float(a.w)); +} +inline __host__ __device__ float4 make_float4(uint4 a) +{ + return make_float4(float(a.x), float(a.y), float(a.z), float(a.w)); +} + +inline __host__ __device__ int4 make_int4(int s) +{ + return make_int4(s, s, s, s); +} +inline __host__ __device__ int4 make_int4(int3 a) +{ + return make_int4(a.x, a.y, a.z, 0); +} +inline __host__ __device__ int4 make_int4(int3 a, int w) +{ + return make_int4(a.x, a.y, a.z, w); +} +inline __host__ __device__ int4 make_int4(uint4 a) +{ + return make_int4(int(a.x), int(a.y), int(a.z), int(a.w)); +} +inline __host__ __device__ int4 make_int4(float4 a) +{ + return make_int4(int(a.x), int(a.y), int(a.z), int(a.w)); +} + + +inline __host__ __device__ uint4 make_uint4(uint s) +{ + return make_uint4(s, s, s, s); +} +inline __host__ __device__ uint4 make_uint4(uint3 a) +{ + return make_uint4(a.x, a.y, a.z, 0); +} +inline __host__ __device__ uint4 make_uint4(uint3 a, uint w) +{ + return make_uint4(a.x, a.y, a.z, w); +} +inline __host__ __device__ uint4 make_uint4(int4 a) +{ + return make_uint4(uint(a.x), uint(a.y), uint(a.z), uint(a.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// negate +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 operator-(float2 &a) +{ + return make_float2(-a.x, -a.y); +} +inline __host__ __device__ int2 operator-(int2 &a) +{ + return make_int2(-a.x, -a.y); +} +inline __host__ __device__ float3 operator-(float3 &a) +{ + return make_float3(-a.x, -a.y, -a.z); +} +inline __host__ __device__ int3 operator-(int3 &a) +{ + return make_int3(-a.x, -a.y, -a.z); +} +inline __host__ __device__ float4 operator-(float4 &a) +{ + return make_float4(-a.x, -a.y, -a.z, -a.w); +} +inline __host__ __device__ int4 operator-(int4 &a) +{ + return make_int4(-a.x, -a.y, -a.z, -a.w); +} + +//////////////////////////////////////////////////////////////////////////////// +// addition +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 operator+(float2 a, float2 b) +{ + return make_float2(a.x + b.x, a.y + b.y); +} +inline __host__ __device__ void operator+=(float2 &a, float2 b) +{ + a.x += b.x; + a.y += b.y; +} +inline __host__ __device__ float2 operator+(float2 a, float b) +{ + return make_float2(a.x + b, a.y + b); +} +inline __host__ __device__ float2 operator+(float b, float2 a) +{ + return make_float2(a.x + b, a.y + b); +} +inline __host__ __device__ void operator+=(float2 &a, float b) +{ + a.x += b; + a.y += b; +} + +inline __host__ __device__ int2 operator+(int2 a, int2 b) +{ + return make_int2(a.x + b.x, a.y + b.y); +} +inline __host__ __device__ void operator+=(int2 &a, int2 b) +{ + a.x += b.x; + a.y += b.y; +} +inline __host__ __device__ int2 operator+(int2 a, int b) +{ + return make_int2(a.x + b, a.y + b); +} +inline __host__ __device__ int2 operator+(int b, int2 a) +{ + return make_int2(a.x + b, a.y + b); +} +inline __host__ __device__ void operator+=(int2 &a, int b) +{ + a.x += b; + a.y += b; +} + +inline __host__ __device__ uint2 operator+(uint2 a, uint2 b) +{ + return make_uint2(a.x + b.x, a.y + b.y); +} +inline __host__ __device__ void operator+=(uint2 &a, uint2 b) +{ + a.x += b.x; + a.y += b.y; +} +inline __host__ __device__ uint2 operator+(uint2 a, uint b) +{ + return make_uint2(a.x + b, a.y + b); +} +inline __host__ __device__ uint2 operator+(uint b, uint2 a) +{ + return make_uint2(a.x + b, a.y + b); +} +inline __host__ __device__ void operator+=(uint2 &a, uint b) +{ + a.x += b; + a.y += b; +} + + +inline __host__ __device__ float3 operator+(float3 a, float3 b) +{ + return make_float3(a.x + b.x, a.y + b.y, a.z + b.z); +} +inline __host__ __device__ void operator+=(float3 &a, float3 b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; +} +inline __host__ __device__ float3 operator+(float3 a, float b) +{ + return make_float3(a.x + b, a.y + b, a.z + b); +} +inline __host__ __device__ void operator+=(float3 &a, float b) +{ + a.x += b; + a.y += b; + a.z += b; +} + +inline __host__ __device__ int3 operator+(int3 a, int3 b) +{ + return make_int3(a.x + b.x, a.y + b.y, a.z + b.z); +} +inline __host__ __device__ void operator+=(int3 &a, int3 b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; +} +inline __host__ __device__ int3 operator+(int3 a, int b) +{ + return make_int3(a.x + b, a.y + b, a.z + b); +} +inline __host__ __device__ void operator+=(int3 &a, int b) +{ + a.x += b; + a.y += b; + a.z += b; +} + +inline __host__ __device__ uint3 operator+(uint3 a, uint3 b) +{ + return make_uint3(a.x + b.x, a.y + b.y, a.z + b.z); +} +inline __host__ __device__ void operator+=(uint3 &a, uint3 b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; +} +inline __host__ __device__ uint3 operator+(uint3 a, uint b) +{ + return make_uint3(a.x + b, a.y + b, a.z + b); +} +inline __host__ __device__ void operator+=(uint3 &a, uint b) +{ + a.x += b; + a.y += b; + a.z += b; +} + +inline __host__ __device__ int3 operator+(int b, int3 a) +{ + return make_int3(a.x + b, a.y + b, a.z + b); +} +inline __host__ __device__ uint3 operator+(uint b, uint3 a) +{ + return make_uint3(a.x + b, a.y + b, a.z + b); +} +inline __host__ __device__ float3 operator+(float b, float3 a) +{ + return make_float3(a.x + b, a.y + b, a.z + b); +} + +inline __host__ __device__ float4 operator+(float4 a, float4 b) +{ + return make_float4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); +} +inline __host__ __device__ void operator+=(float4 &a, float4 b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; + a.w += b.w; +} +inline __host__ __device__ float4 operator+(float4 a, float b) +{ + return make_float4(a.x + b, a.y + b, a.z + b, a.w + b); +} +inline __host__ __device__ float4 operator+(float b, float4 a) +{ + return make_float4(a.x + b, a.y + b, a.z + b, a.w + b); +} +inline __host__ __device__ void operator+=(float4 &a, float b) +{ + a.x += b; + a.y += b; + a.z += b; + a.w += b; +} + +inline __host__ __device__ int4 operator+(int4 a, int4 b) +{ + return make_int4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); +} +inline __host__ __device__ void operator+=(int4 &a, int4 b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; + a.w += b.w; +} +inline __host__ __device__ int4 operator+(int4 a, int b) +{ + return make_int4(a.x + b, a.y + b, a.z + b, a.w + b); +} +inline __host__ __device__ int4 operator+(int b, int4 a) +{ + return make_int4(a.x + b, a.y + b, a.z + b, a.w + b); +} +inline __host__ __device__ void operator+=(int4 &a, int b) +{ + a.x += b; + a.y += b; + a.z += b; + a.w += b; +} + +inline __host__ __device__ uint4 operator+(uint4 a, uint4 b) +{ + return make_uint4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); +} +inline __host__ __device__ void operator+=(uint4 &a, uint4 b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; + a.w += b.w; +} +inline __host__ __device__ uint4 operator+(uint4 a, uint b) +{ + return make_uint4(a.x + b, a.y + b, a.z + b, a.w + b); +} +inline __host__ __device__ uint4 operator+(uint b, uint4 a) +{ + return make_uint4(a.x + b, a.y + b, a.z + b, a.w + b); +} +inline __host__ __device__ void operator+=(uint4 &a, uint b) +{ + a.x += b; + a.y += b; + a.z += b; + a.w += b; +} + +//////////////////////////////////////////////////////////////////////////////// +// subtract +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 operator-(float2 a, float2 b) +{ + return make_float2(a.x - b.x, a.y - b.y); +} +inline __host__ __device__ void operator-=(float2 &a, float2 b) +{ + a.x -= b.x; + a.y -= b.y; +} +inline __host__ __device__ float2 operator-(float2 a, float b) +{ + return make_float2(a.x - b, a.y - b); +} +inline __host__ __device__ float2 operator-(float b, float2 a) +{ + return make_float2(b - a.x, b - a.y); +} +inline __host__ __device__ void operator-=(float2 &a, float b) +{ + a.x -= b; + a.y -= b; +} + +inline __host__ __device__ int2 operator-(int2 a, int2 b) +{ + return make_int2(a.x - b.x, a.y - b.y); +} +inline __host__ __device__ void operator-=(int2 &a, int2 b) +{ + a.x -= b.x; + a.y -= b.y; +} +inline __host__ __device__ int2 operator-(int2 a, int b) +{ + return make_int2(a.x - b, a.y - b); +} +inline __host__ __device__ int2 operator-(int b, int2 a) +{ + return make_int2(b - a.x, b - a.y); +} +inline __host__ __device__ void operator-=(int2 &a, int b) +{ + a.x -= b; + a.y -= b; +} + +inline __host__ __device__ uint2 operator-(uint2 a, uint2 b) +{ + return make_uint2(a.x - b.x, a.y - b.y); +} +inline __host__ __device__ void operator-=(uint2 &a, uint2 b) +{ + a.x -= b.x; + a.y -= b.y; +} +inline __host__ __device__ uint2 operator-(uint2 a, uint b) +{ + return make_uint2(a.x - b, a.y - b); +} +inline __host__ __device__ uint2 operator-(uint b, uint2 a) +{ + return make_uint2(b - a.x, b - a.y); +} +inline __host__ __device__ void operator-=(uint2 &a, uint b) +{ + a.x -= b; + a.y -= b; +} + +inline __host__ __device__ float3 operator-(float3 a, float3 b) +{ + return make_float3(a.x - b.x, a.y - b.y, a.z - b.z); +} +inline __host__ __device__ void operator-=(float3 &a, float3 b) +{ + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; +} +inline __host__ __device__ float3 operator-(float3 a, float b) +{ + return make_float3(a.x - b, a.y - b, a.z - b); +} +inline __host__ __device__ float3 operator-(float b, float3 a) +{ + return make_float3(b - a.x, b - a.y, b - a.z); +} +inline __host__ __device__ void operator-=(float3 &a, float b) +{ + a.x -= b; + a.y -= b; + a.z -= b; +} + +inline __host__ __device__ int3 operator-(int3 a, int3 b) +{ + return make_int3(a.x - b.x, a.y - b.y, a.z - b.z); +} +inline __host__ __device__ void operator-=(int3 &a, int3 b) +{ + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; +} +inline __host__ __device__ int3 operator-(int3 a, int b) +{ + return make_int3(a.x - b, a.y - b, a.z - b); +} +inline __host__ __device__ int3 operator-(int b, int3 a) +{ + return make_int3(b - a.x, b - a.y, b - a.z); +} +inline __host__ __device__ void operator-=(int3 &a, int b) +{ + a.x -= b; + a.y -= b; + a.z -= b; +} + +inline __host__ __device__ uint3 operator-(uint3 a, uint3 b) +{ + return make_uint3(a.x - b.x, a.y - b.y, a.z - b.z); +} +inline __host__ __device__ void operator-=(uint3 &a, uint3 b) +{ + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; +} +inline __host__ __device__ uint3 operator-(uint3 a, uint b) +{ + return make_uint3(a.x - b, a.y - b, a.z - b); +} +inline __host__ __device__ uint3 operator-(uint b, uint3 a) +{ + return make_uint3(b - a.x, b - a.y, b - a.z); +} +inline __host__ __device__ void operator-=(uint3 &a, uint b) +{ + a.x -= b; + a.y -= b; + a.z -= b; +} + +inline __host__ __device__ float4 operator-(float4 a, float4 b) +{ + return make_float4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); +} +inline __host__ __device__ void operator-=(float4 &a, float4 b) +{ + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; + a.w -= b.w; +} +inline __host__ __device__ float4 operator-(float4 a, float b) +{ + return make_float4(a.x - b, a.y - b, a.z - b, a.w - b); +} +inline __host__ __device__ void operator-=(float4 &a, float b) +{ + a.x -= b; + a.y -= b; + a.z -= b; + a.w -= b; +} + +inline __host__ __device__ int4 operator-(int4 a, int4 b) +{ + return make_int4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); +} +inline __host__ __device__ void operator-=(int4 &a, int4 b) +{ + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; + a.w -= b.w; +} +inline __host__ __device__ int4 operator-(int4 a, int b) +{ + return make_int4(a.x - b, a.y - b, a.z - b, a.w - b); +} +inline __host__ __device__ int4 operator-(int b, int4 a) +{ + return make_int4(b - a.x, b - a.y, b - a.z, b - a.w); +} +inline __host__ __device__ void operator-=(int4 &a, int b) +{ + a.x -= b; + a.y -= b; + a.z -= b; + a.w -= b; +} + +inline __host__ __device__ uint4 operator-(uint4 a, uint4 b) +{ + return make_uint4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); +} +inline __host__ __device__ void operator-=(uint4 &a, uint4 b) +{ + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; + a.w -= b.w; +} +inline __host__ __device__ uint4 operator-(uint4 a, uint b) +{ + return make_uint4(a.x - b, a.y - b, a.z - b, a.w - b); +} +inline __host__ __device__ uint4 operator-(uint b, uint4 a) +{ + return make_uint4(b - a.x, b - a.y, b - a.z, b - a.w); +} +inline __host__ __device__ void operator-=(uint4 &a, uint b) +{ + a.x -= b; + a.y -= b; + a.z -= b; + a.w -= b; +} + +//////////////////////////////////////////////////////////////////////////////// +// multiply +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 operator*(float2 a, float2 b) +{ + return make_float2(a.x * b.x, a.y * b.y); +} +inline __host__ __device__ void operator*=(float2 &a, float2 b) +{ + a.x *= b.x; + a.y *= b.y; +} +inline __host__ __device__ float2 operator*(float2 a, float b) +{ + return make_float2(a.x * b, a.y * b); +} +inline __host__ __device__ float2 operator*(float b, float2 a) +{ + return make_float2(b * a.x, b * a.y); +} +inline __host__ __device__ void operator*=(float2 &a, float b) +{ + a.x *= b; + a.y *= b; +} + +inline __host__ __device__ int2 operator*(int2 a, int2 b) +{ + return make_int2(a.x * b.x, a.y * b.y); +} +inline __host__ __device__ void operator*=(int2 &a, int2 b) +{ + a.x *= b.x; + a.y *= b.y; +} +inline __host__ __device__ int2 operator*(int2 a, int b) +{ + return make_int2(a.x * b, a.y * b); +} +inline __host__ __device__ int2 operator*(int b, int2 a) +{ + return make_int2(b * a.x, b * a.y); +} +inline __host__ __device__ void operator*=(int2 &a, int b) +{ + a.x *= b; + a.y *= b; +} + +inline __host__ __device__ uint2 operator*(uint2 a, uint2 b) +{ + return make_uint2(a.x * b.x, a.y * b.y); +} +inline __host__ __device__ void operator*=(uint2 &a, uint2 b) +{ + a.x *= b.x; + a.y *= b.y; +} +inline __host__ __device__ uint2 operator*(uint2 a, uint b) +{ + return make_uint2(a.x * b, a.y * b); +} +inline __host__ __device__ uint2 operator*(uint b, uint2 a) +{ + return make_uint2(b * a.x, b * a.y); +} +inline __host__ __device__ void operator*=(uint2 &a, uint b) +{ + a.x *= b; + a.y *= b; +} + +inline __host__ __device__ float3 operator*(float3 a, float3 b) +{ + return make_float3(a.x * b.x, a.y * b.y, a.z * b.z); +} +inline __host__ __device__ void operator*=(float3 &a, float3 b) +{ + a.x *= b.x; + a.y *= b.y; + a.z *= b.z; +} +inline __host__ __device__ float3 operator*(float3 a, float b) +{ + return make_float3(a.x * b, a.y * b, a.z * b); +} +inline __host__ __device__ float3 operator*(float b, float3 a) +{ + return make_float3(b * a.x, b * a.y, b * a.z); +} +inline __host__ __device__ void operator*=(float3 &a, float b) +{ + a.x *= b; + a.y *= b; + a.z *= b; +} + +inline __host__ __device__ int3 operator*(int3 a, int3 b) +{ + return make_int3(a.x * b.x, a.y * b.y, a.z * b.z); +} +inline __host__ __device__ void operator*=(int3 &a, int3 b) +{ + a.x *= b.x; + a.y *= b.y; + a.z *= b.z; +} +inline __host__ __device__ int3 operator*(int3 a, int b) +{ + return make_int3(a.x * b, a.y * b, a.z * b); +} +inline __host__ __device__ int3 operator*(int b, int3 a) +{ + return make_int3(b * a.x, b * a.y, b * a.z); +} +inline __host__ __device__ void operator*=(int3 &a, int b) +{ + a.x *= b; + a.y *= b; + a.z *= b; +} + +inline __host__ __device__ uint3 operator*(uint3 a, uint3 b) +{ + return make_uint3(a.x * b.x, a.y * b.y, a.z * b.z); +} +inline __host__ __device__ void operator*=(uint3 &a, uint3 b) +{ + a.x *= b.x; + a.y *= b.y; + a.z *= b.z; +} +inline __host__ __device__ uint3 operator*(uint3 a, uint b) +{ + return make_uint3(a.x * b, a.y * b, a.z * b); +} +inline __host__ __device__ uint3 operator*(uint b, uint3 a) +{ + return make_uint3(b * a.x, b * a.y, b * a.z); +} +inline __host__ __device__ void operator*=(uint3 &a, uint b) +{ + a.x *= b; + a.y *= b; + a.z *= b; +} + +inline __host__ __device__ float4 operator*(float4 a, float4 b) +{ + return make_float4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); +} +inline __host__ __device__ void operator*=(float4 &a, float4 b) +{ + a.x *= b.x; + a.y *= b.y; + a.z *= b.z; + a.w *= b.w; +} +inline __host__ __device__ float4 operator*(float4 a, float b) +{ + return make_float4(a.x * b, a.y * b, a.z * b, a.w * b); +} +inline __host__ __device__ float4 operator*(float b, float4 a) +{ + return make_float4(b * a.x, b * a.y, b * a.z, b * a.w); +} +inline __host__ __device__ void operator*=(float4 &a, float b) +{ + a.x *= b; + a.y *= b; + a.z *= b; + a.w *= b; +} + +inline __host__ __device__ int4 operator*(int4 a, int4 b) +{ + return make_int4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); +} +inline __host__ __device__ void operator*=(int4 &a, int4 b) +{ + a.x *= b.x; + a.y *= b.y; + a.z *= b.z; + a.w *= b.w; +} +inline __host__ __device__ int4 operator*(int4 a, int b) +{ + return make_int4(a.x * b, a.y * b, a.z * b, a.w * b); +} +inline __host__ __device__ int4 operator*(int b, int4 a) +{ + return make_int4(b * a.x, b * a.y, b * a.z, b * a.w); +} +inline __host__ __device__ void operator*=(int4 &a, int b) +{ + a.x *= b; + a.y *= b; + a.z *= b; + a.w *= b; +} + +inline __host__ __device__ uint4 operator*(uint4 a, uint4 b) +{ + return make_uint4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); +} +inline __host__ __device__ void operator*=(uint4 &a, uint4 b) +{ + a.x *= b.x; + a.y *= b.y; + a.z *= b.z; + a.w *= b.w; +} +inline __host__ __device__ uint4 operator*(uint4 a, uint b) +{ + return make_uint4(a.x * b, a.y * b, a.z * b, a.w * b); +} +inline __host__ __device__ uint4 operator*(uint b, uint4 a) +{ + return make_uint4(b * a.x, b * a.y, b * a.z, b * a.w); +} +inline __host__ __device__ void operator*=(uint4 &a, uint b) +{ + a.x *= b; + a.y *= b; + a.z *= b; + a.w *= b; +} + +//////////////////////////////////////////////////////////////////////////////// +// divide +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 operator/(float2 a, float2 b) +{ + return make_float2(a.x / b.x, a.y / b.y); +} +inline __host__ __device__ void operator/=(float2 &a, float2 b) +{ + a.x /= b.x; + a.y /= b.y; +} +inline __host__ __device__ float2 operator/(float2 a, float b) +{ + return make_float2(a.x / b, a.y / b); +} +inline __host__ __device__ void operator/=(float2 &a, float b) +{ + a.x /= b; + a.y /= b; +} +inline __host__ __device__ float2 operator/(float b, float2 a) +{ + return make_float2(b / a.x, b / a.y); +} + +inline __host__ __device__ float3 operator/(float3 a, float3 b) +{ + return make_float3(a.x / b.x, a.y / b.y, a.z / b.z); +} +inline __host__ __device__ void operator/=(float3 &a, float3 b) +{ + a.x /= b.x; + a.y /= b.y; + a.z /= b.z; +} +inline __host__ __device__ float3 operator/(float3 a, float b) +{ + return make_float3(a.x / b, a.y / b, a.z / b); +} +inline __host__ __device__ void operator/=(float3 &a, float b) +{ + a.x /= b; + a.y /= b; + a.z /= b; +} +inline __host__ __device__ float3 operator/(float b, float3 a) +{ + return make_float3(b / a.x, b / a.y, b / a.z); +} + +inline __host__ __device__ float4 operator/(float4 a, float4 b) +{ + return make_float4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); +} +inline __host__ __device__ void operator/=(float4 &a, float4 b) +{ + a.x /= b.x; + a.y /= b.y; + a.z /= b.z; + a.w /= b.w; +} +inline __host__ __device__ float4 operator/(float4 a, float b) +{ + return make_float4(a.x / b, a.y / b, a.z / b, a.w / b); +} +inline __host__ __device__ void operator/=(float4 &a, float b) +{ + a.x /= b; + a.y /= b; + a.z /= b; + a.w /= b; +} +inline __host__ __device__ float4 operator/(float b, float4 a) +{ + return make_float4(b / a.x, b / a.y, b / a.z, b / a.w); +} + +//////////////////////////////////////////////////////////////////////////////// +// min +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 fminf(float2 a, float2 b) +{ + return make_float2(fminf(a.x,b.x), fminf(a.y,b.y)); +} +inline __host__ __device__ float3 fminf(float3 a, float3 b) +{ + return make_float3(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z)); +} +inline __host__ __device__ float4 fminf(float4 a, float4 b) +{ + return make_float4(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z), fminf(a.w,b.w)); +} + +inline __host__ __device__ int2 min(int2 a, int2 b) +{ + return make_int2(min(a.x,b.x), min(a.y,b.y)); +} +inline __host__ __device__ int3 min(int3 a, int3 b) +{ + return make_int3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z)); +} +inline __host__ __device__ int4 min(int4 a, int4 b) +{ + return make_int4(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z), min(a.w,b.w)); +} + +inline __host__ __device__ uint2 min(uint2 a, uint2 b) +{ + return make_uint2(min(a.x,b.x), min(a.y,b.y)); +} +inline __host__ __device__ uint3 min(uint3 a, uint3 b) +{ + return make_uint3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z)); +} +inline __host__ __device__ uint4 min(uint4 a, uint4 b) +{ + return make_uint4(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z), min(a.w,b.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// max +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 fmaxf(float2 a, float2 b) +{ + return make_float2(fmaxf(a.x,b.x), fmaxf(a.y,b.y)); +} +inline __host__ __device__ float3 fmaxf(float3 a, float3 b) +{ + return make_float3(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z)); +} +inline __host__ __device__ float4 fmaxf(float4 a, float4 b) +{ + return make_float4(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z), fmaxf(a.w,b.w)); +} + +inline __host__ __device__ int2 max(int2 a, int2 b) +{ + return make_int2(max(a.x,b.x), max(a.y,b.y)); +} +inline __host__ __device__ int3 max(int3 a, int3 b) +{ + return make_int3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z)); +} +inline __host__ __device__ int4 max(int4 a, int4 b) +{ + return make_int4(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z), max(a.w,b.w)); +} + +inline __host__ __device__ uint2 max(uint2 a, uint2 b) +{ + return make_uint2(max(a.x,b.x), max(a.y,b.y)); +} +inline __host__ __device__ uint3 max(uint3 a, uint3 b) +{ + return make_uint3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z)); +} +inline __host__ __device__ uint4 max(uint4 a, uint4 b) +{ + return make_uint4(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z), max(a.w,b.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// lerp +// - linear interpolation between a and b, based on value t in [0, 1] range +//////////////////////////////////////////////////////////////////////////////// + +inline __device__ __host__ float lerp(float a, float b, float t) +{ + return a + t*(b-a); +} +inline __device__ __host__ float2 lerp(float2 a, float2 b, float t) +{ + return a + t*(b-a); +} +inline __device__ __host__ float3 lerp(float3 a, float3 b, float t) +{ + return a + t*(b-a); +} +inline __device__ __host__ float4 lerp(float4 a, float4 b, float t) +{ + return a + t*(b-a); +} + +//////////////////////////////////////////////////////////////////////////////// +// clamp +// - clamp the value v to be in the range [a, b] +//////////////////////////////////////////////////////////////////////////////// + +inline __device__ __host__ float clamp(float f, float a, float b) +{ + return fmaxf(a, fminf(f, b)); +} +inline __device__ __host__ int clamp(int f, int a, int b) +{ + return max(a, min(f, b)); +} +inline __device__ __host__ uint clamp(uint f, uint a, uint b) +{ + return max(a, min(f, b)); +} + +inline __device__ __host__ float2 clamp(float2 v, float a, float b) +{ + return make_float2(clamp(v.x, a, b), clamp(v.y, a, b)); +} +inline __device__ __host__ float2 clamp(float2 v, float2 a, float2 b) +{ + return make_float2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y)); +} +inline __device__ __host__ float3 clamp(float3 v, float a, float b) +{ + return make_float3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b)); +} +inline __device__ __host__ float3 clamp(float3 v, float3 a, float3 b) +{ + return make_float3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z)); +} +inline __device__ __host__ float4 clamp(float4 v, float a, float b) +{ + return make_float4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b)); +} +inline __device__ __host__ float4 clamp(float4 v, float4 a, float4 b) +{ + return make_float4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w)); +} + +inline __device__ __host__ int2 clamp(int2 v, int a, int b) +{ + return make_int2(clamp(v.x, a, b), clamp(v.y, a, b)); +} +inline __device__ __host__ int2 clamp(int2 v, int2 a, int2 b) +{ + return make_int2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y)); +} +inline __device__ __host__ int3 clamp(int3 v, int a, int b) +{ + return make_int3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b)); +} +inline __device__ __host__ int3 clamp(int3 v, int3 a, int3 b) +{ + return make_int3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z)); +} +inline __device__ __host__ int4 clamp(int4 v, int a, int b) +{ + return make_int4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b)); +} +inline __device__ __host__ int4 clamp(int4 v, int4 a, int4 b) +{ + return make_int4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w)); +} + +inline __device__ __host__ uint2 clamp(uint2 v, uint a, uint b) +{ + return make_uint2(clamp(v.x, a, b), clamp(v.y, a, b)); +} +inline __device__ __host__ uint2 clamp(uint2 v, uint2 a, uint2 b) +{ + return make_uint2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y)); +} +inline __device__ __host__ uint3 clamp(uint3 v, uint a, uint b) +{ + return make_uint3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b)); +} +inline __device__ __host__ uint3 clamp(uint3 v, uint3 a, uint3 b) +{ + return make_uint3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z)); +} +inline __device__ __host__ uint4 clamp(uint4 v, uint a, uint b) +{ + return make_uint4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b)); +} +inline __device__ __host__ uint4 clamp(uint4 v, uint4 a, uint4 b) +{ + return make_uint4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// dot product +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float dot(float2 a, float2 b) +{ + return a.x * b.x + a.y * b.y; +} +inline __host__ __device__ float dot(float3 a, float3 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} +inline __host__ __device__ float dot(float4 a, float4 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +} + +inline __host__ __device__ int dot(int2 a, int2 b) +{ + return a.x * b.x + a.y * b.y; +} +inline __host__ __device__ int dot(int3 a, int3 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} +inline __host__ __device__ int dot(int4 a, int4 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +} + +inline __host__ __device__ uint dot(uint2 a, uint2 b) +{ + return a.x * b.x + a.y * b.y; +} +inline __host__ __device__ uint dot(uint3 a, uint3 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} +inline __host__ __device__ uint dot(uint4 a, uint4 b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +} + +//////////////////////////////////////////////////////////////////////////////// +// length +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float length(float2 v) +{ + return sqrtf(dot(v, v)); +} +inline __host__ __device__ float length(float3 v) +{ + return sqrtf(dot(v, v)); +} +inline __host__ __device__ float length(float4 v) +{ + return sqrtf(dot(v, v)); +} + +//////////////////////////////////////////////////////////////////////////////// +// normalize +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 normalize(float2 v) +{ + float invLen = rsqrtf(dot(v, v)); + return v * invLen; +} +inline __host__ __device__ float3 normalize(float3 v) +{ + float invLen = rsqrtf(dot(v, v)); + return v * invLen; +} +inline __host__ __device__ float4 normalize(float4 v) +{ + float invLen = rsqrtf(dot(v, v)); + return v * invLen; +} + +//////////////////////////////////////////////////////////////////////////////// +// floor +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 floorf(float2 v) +{ + return make_float2(floorf(v.x), floorf(v.y)); +} +inline __host__ __device__ float3 floorf(float3 v) +{ + return make_float3(floorf(v.x), floorf(v.y), floorf(v.z)); +} +inline __host__ __device__ float4 floorf(float4 v) +{ + return make_float4(floorf(v.x), floorf(v.y), floorf(v.z), floorf(v.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// frac - returns the fractional portion of a scalar or each vector component +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float fracf(float v) +{ + return v - floorf(v); +} +inline __host__ __device__ float2 fracf(float2 v) +{ + return make_float2(fracf(v.x), fracf(v.y)); +} +inline __host__ __device__ float3 fracf(float3 v) +{ + return make_float3(fracf(v.x), fracf(v.y), fracf(v.z)); +} +inline __host__ __device__ float4 fracf(float4 v) +{ + return make_float4(fracf(v.x), fracf(v.y), fracf(v.z), fracf(v.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// fmod +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 fmodf(float2 a, float2 b) +{ + return make_float2(fmodf(a.x, b.x), fmodf(a.y, b.y)); +} +inline __host__ __device__ float3 fmodf(float3 a, float3 b) +{ + return make_float3(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z)); +} +inline __host__ __device__ float4 fmodf(float4 a, float4 b) +{ + return make_float4(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z), fmodf(a.w, b.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// absolute value +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float2 fabs(float2 v) +{ + return make_float2(fabs(v.x), fabs(v.y)); +} +inline __host__ __device__ float3 fabs(float3 v) +{ + return make_float3(fabs(v.x), fabs(v.y), fabs(v.z)); +} +inline __host__ __device__ float4 fabs(float4 v) +{ + return make_float4(fabs(v.x), fabs(v.y), fabs(v.z), fabs(v.w)); +} + +inline __host__ __device__ int2 abs(int2 v) +{ + return make_int2(abs(v.x), abs(v.y)); +} +inline __host__ __device__ int3 abs(int3 v) +{ + return make_int3(abs(v.x), abs(v.y), abs(v.z)); +} +inline __host__ __device__ int4 abs(int4 v) +{ + return make_int4(abs(v.x), abs(v.y), abs(v.z), abs(v.w)); +} + +//////////////////////////////////////////////////////////////////////////////// +// reflect +// - returns reflection of incident ray I around surface normal N +// - N should be normalized, reflected vector's length is equal to length of I +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float3 reflect(float3 i, float3 n) +{ + return i - 2.0f * n * dot(n,i); +} + +//////////////////////////////////////////////////////////////////////////////// +// cross product +//////////////////////////////////////////////////////////////////////////////// + +inline __host__ __device__ float3 cross(float3 a, float3 b) +{ + return make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); +} + +//////////////////////////////////////////////////////////////////////////////// +// smoothstep +// - returns 0 if x < a +// - returns 1 if x > b +// - otherwise returns smooth interpolation between 0 and 1 based on x +//////////////////////////////////////////////////////////////////////////////// + +inline __device__ __host__ float smoothstep(float a, float b, float x) +{ + float y = clamp((x - a) / (b - a), 0.0f, 1.0f); + return (y*y*(3.0f - (2.0f*y))); +} +inline __device__ __host__ float2 smoothstep(float2 a, float2 b, float2 x) +{ + float2 y = clamp((x - a) / (b - a), 0.0f, 1.0f); + return (y*y*(make_float2(3.0f) - (make_float2(2.0f)*y))); +} +inline __device__ __host__ float3 smoothstep(float3 a, float3 b, float3 x) +{ + float3 y = clamp((x - a) / (b - a), 0.0f, 1.0f); + return (y*y*(make_float3(3.0f) - (make_float3(2.0f)*y))); +} +inline __device__ __host__ float4 smoothstep(float4 a, float4 b, float4 x) +{ + float4 y = clamp((x - a) / (b - a), 0.0f, 1.0f); + return (y*y*(make_float4(3.0f) - (make_float4(2.0f)*y))); +} + +#endif diff --git a/external/cutil/inc/helper_string.h b/external/cutil/inc/helper_string.h new file mode 100644 index 0000000..961642a --- /dev/null +++ b/external/cutil/inc/helper_string.h @@ -0,0 +1,472 @@ +/** + * Copyright 1993-2013 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +// These are helper functions for the SDK samples (string parsing, timers, etc) +#ifndef STRING_HELPER_H +#define STRING_HELPER_H + +#include +#include +#include +#include + +#if defined(WIN32) || defined(_WIN32) || defined(WIN64) +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE +#endif +#ifndef STRCASECMP +#define STRCASECMP _stricmp +#endif +#ifndef STRNCASECMP +#define STRNCASECMP _strnicmp +#endif +#ifndef STRCPY +#define STRCPY(sFilePath, nLength, sPath) strcpy_s(sFilePath, nLength, sPath) +#endif + +#ifndef FOPEN +#define FOPEN(fHandle,filename,mode) fopen_s(&fHandle, filename, mode) +#endif +#ifndef FOPEN_FAIL +#define FOPEN_FAIL(result) (result != 0) +#endif +#ifndef SSCANF +#define SSCANF sscanf_s +#endif +#ifndef SPRINTF +#define SPRINTF sprintf_s +#endif +#else // Linux Includes +#include +#include + +#ifndef STRCASECMP +#define STRCASECMP strcasecmp +#endif +#ifndef STRNCASECMP +#define STRNCASECMP strncasecmp +#endif +#ifndef STRCPY +#define STRCPY(sFilePath, nLength, sPath) strcpy(sFilePath, sPath) +#endif + +#ifndef FOPEN +#define FOPEN(fHandle,filename,mode) (fHandle = fopen(filename, mode)) +#endif +#ifndef FOPEN_FAIL +#define FOPEN_FAIL(result) (result == NULL) +#endif +#ifndef SSCANF +#define SSCANF sscanf +#endif +#ifndef SPRINTF +#define SPRINTF sprintf +#endif +#endif + +#ifndef EXIT_WAIVED +#define EXIT_WAIVED 2 +#endif + +// CUDA Utility Helper Functions +inline int stringRemoveDelimiter(char delimiter, const char *string) +{ + int string_start = 0; + + while (string[string_start] == delimiter) + { + string_start++; + } + + if (string_start >= (int)strlen(string)-1) + { + return 0; + } + + return string_start; +} + +inline int getFileExtension(char *filename, char **extension) +{ + int string_length = (int)strlen(filename); + + while (filename[string_length--] != '.') + { + if (string_length == 0) + break; + } + + if (string_length > 0) string_length += 2; + + if (string_length == 0) + *extension = NULL; + else + *extension = &filename[string_length]; + + return string_length; +} + + +inline bool checkCmdLineFlag(const int argc, const char **argv, const char *string_ref) +{ + bool bFound = false; + + if (argc >= 1) + { + for (int i=1; i < argc; i++) + { + int string_start = stringRemoveDelimiter('-', argv[i]); + const char *string_argv = &argv[i][string_start]; + + const char *equal_pos = strchr(string_argv, '='); + int argv_length = (int)(equal_pos == 0 ? strlen(string_argv) : equal_pos - string_argv); + + int length = (int)strlen(string_ref); + + if (length == argv_length && !STRNCASECMP(string_argv, string_ref, length)) + { + bFound = true; + continue; + } + } + } + + return bFound; +} + +// This function wraps the CUDA Driver API into a template function +template +inline bool getCmdLineArgumentValue(const int argc, const char **argv, const char *string_ref, T *value) +{ + bool bFound = false; + + if (argc >= 1) + { + for (int i=1; i < argc; i++) + { + int string_start = stringRemoveDelimiter('-', argv[i]); + const char *string_argv = &argv[i][string_start]; + int length = (int)strlen(string_ref); + + if (!STRNCASECMP(string_argv, string_ref, length)) + { + if (length+1 <= (int)strlen(string_argv)) + { + int auto_inc = (string_argv[length] == '=') ? 1 : 0; + *value = (T)atoi(&string_argv[length + auto_inc]); + } + + bFound = true; + i=argc; + } + } + } + + return bFound; +} + +inline int getCmdLineArgumentInt(const int argc, const char **argv, const char *string_ref) +{ + bool bFound = false; + int value = -1; + + if (argc >= 1) + { + for (int i=1; i < argc; i++) + { + int string_start = stringRemoveDelimiter('-', argv[i]); + const char *string_argv = &argv[i][string_start]; + int length = (int)strlen(string_ref); + + if (!STRNCASECMP(string_argv, string_ref, length)) + { + if (length+1 <= (int)strlen(string_argv)) + { + int auto_inc = (string_argv[length] == '=') ? 1 : 0; + value = atoi(&string_argv[length + auto_inc]); + } + else + { + value = 0; + } + + bFound = true; + continue; + } + } + } + + if (bFound) + { + return value; + } + else + { + return 0; + } +} + +inline float getCmdLineArgumentFloat(const int argc, const char **argv, const char *string_ref) +{ + bool bFound = false; + float value = -1; + + if (argc >= 1) + { + for (int i=1; i < argc; i++) + { + int string_start = stringRemoveDelimiter('-', argv[i]); + const char *string_argv = &argv[i][string_start]; + int length = (int)strlen(string_ref); + + if (!STRNCASECMP(string_argv, string_ref, length)) + { + if (length+1 <= (int)strlen(string_argv)) + { + int auto_inc = (string_argv[length] == '=') ? 1 : 0; + value = (float)atof(&string_argv[length + auto_inc]); + } + else + { + value = 0.f; + } + + bFound = true; + continue; + } + } + } + + if (bFound) + { + return value; + } + else + { + return 0; + } +} + +inline bool getCmdLineArgumentString(const int argc, const char **argv, + const char *string_ref, char **string_retval) +{ + bool bFound = false; + + if (argc >= 1) + { + for (int i=1; i < argc; i++) + { + int string_start = stringRemoveDelimiter('-', argv[i]); + char *string_argv = (char *)&argv[i][string_start]; + int length = (int)strlen(string_ref); + + if (!STRNCASECMP(string_argv, string_ref, length)) + { + *string_retval = &string_argv[length+1]; + bFound = true; + continue; + } + } + } + + if (!bFound) + { + *string_retval = NULL; + } + + return bFound; +} + +////////////////////////////////////////////////////////////////////////////// +//! Find the path for a file assuming that +//! files are found in the searchPath. +//! +//! @return the path if succeeded, otherwise 0 +//! @param filename name of the file +//! @param executable_path optional absolute path of the executable +////////////////////////////////////////////////////////////////////////////// +inline char *sdkFindFilePath(const char *filename, const char *executable_path) +{ + // defines a variable that is replaced with the name of the executable + + // Typical relative search paths to locate needed companion files (e.g. sample input data, or JIT source files) + // The origin for the relative search may be the .exe file, a .bat file launching an .exe, a browser .exe launching the .exe or .bat, etc + const char *searchPath[] = + { + "./", // same dir + "./common/", // "/common/" subdir + "./common/data/", // "/common/data/" subdir + "./data/", // "/data/" subdir + "./src/", // "/src/" subdir + "./src//data/", // "/src//data/" subdir + "./inc/", // "/inc/" subdir + "./0_Simple/", // "/0_Simple/" subdir + "./1_Utilities/", // "/1_Utilities/" subdir + "./2_Graphics/", // "/2_Graphics/" subdir + "./3_Imaging/", // "/3_Imaging/" subdir + "./4_Financial/", // "/4_Financial/" subdir + "./5_Simulations/", // "/5_Simulations/" subdir + "./6_Advanced/", // "/6_Advanced/" subdir + "./7_CUDALibraries/", // "/7_CUDALibraries/" subdir + "./samples/", // "/samples/" subdir + + "../", // up 1 in tree + "../common/", // up 1 in tree, "/common/" subdir + "../common/data/", // up 1 in tree, "/common/data/" subdir + "../data/", // up 1 in tree, "/data/" subdir + "../src/", // up 1 in tree, "/src/" subdir + "../inc/", // up 1 in tree, "/inc/" subdir + + "../0_Simple//data/", // up 1 in tree, "/0_Simple//" subdir + "../1_Utilities//data/", // up 1 in tree, "/1_Utilities//" subdir + "../2_Graphics//data/", // up 1 in tree, "/2_Graphics//" subdir + "../3_Imaging//data/", // up 1 in tree, "/3_Imaging//" subdir + "../4_Financial//data/", // up 1 in tree, "/4_Financial//" subdir + "../5_Simulations//data/", // up 1 in tree, "/5_Simulations//" subdir + "../6_Advanced//data/", // up 1 in tree, "/6_Advanced//" subdir + "../7_CUDALibraries//data/", // up 1 in tree, "/7_CUDALibraries//" subdir + "../samples//data/", // up 1 in tree, "/samples//" subdir + "../../", // up 2 in tree + "../../common/", // up 2 in tree, "/common/" subdir + "../../common/data/", // up 2 in tree, "/common/data/" subdir + "../../data/", // up 2 in tree, "/data/" subdir + "../../src/", // up 2 in tree, "/src/" subdir + "../../inc/", // up 2 in tree, "/inc/" subdir + "../../sandbox//data/", // up 2 in tree, "/sandbox//" subdir + "../../0_Simple//data/", // up 2 in tree, "/0_Simple//" subdir + "../../1_Utilities//data/", // up 2 in tree, "/1_Utilities//" subdir + "../../2_Graphics//data/", // up 2 in tree, "/2_Graphics//" subdir + "../../3_Imaging//data/", // up 2 in tree, "/3_Imaging//" subdir + "../../4_Financial//data/", // up 2 in tree, "/4_Financial//" subdir + "../../5_Simulations//data/", // up 2 in tree, "/5_Simulations//" subdir + "../../6_Advanced//data/", // up 2 in tree, "/6_Advanced//" subdir + "../../7_CUDALibraries//data/", // up 2 in tree, "/7_CUDALibraries//" subdir + "../../samples//data/", // up 2 in tree, "/samples//" subdir + "../../../", // up 3 in tree + "../../../src//", // up 3 in tree, "/src//" subdir + "../../../src//data/", // up 3 in tree, "/src//data/" subdir + "../../../src//src/", // up 3 in tree, "/src//src/" subdir + "../../../src//inc/", // up 3 in tree, "/src//inc/" subdir + "../../../sandbox//", // up 3 in tree, "/sandbox//" subdir + "../../../sandbox//data/", // up 3 in tree, "/sandbox//data/" subdir + "../../../sandbox//src/", // up 3 in tree, "/sandbox//src/" subdir + "../../../sandbox//inc/", // up 3 in tree, "/sandbox//inc/" subdir + "../../../0_Simple//data/", // up 3 in tree, "/0_Simple//" subdir + "../../../1_Utilities//data/", // up 3 in tree, "/1_Utilities//" subdir + "../../../2_Graphics//data/", // up 3 in tree, "/2_Graphics//" subdir + "../../../3_Imaging//data/", // up 3 in tree, "/3_Imaging//" subdir + "../../../4_Financial//data/", // up 3 in tree, "/4_Financial//" subdir + "../../../5_Simulations//data/",// up 3 in tree, "/5_Simulations//" subdir + "../../../6_Advanced//data/", // up 3 in tree, "/6_Advanced//" subdir + "../../../7_CUDALibraries//data/", // up 3 in tree, "/7_CUDALibraries//" subdir + "../../../samples//data/", // up 3 in tree, "/samples//" subdir + "../../../common/", // up 3 in tree, "../../../common/" subdir + "../../../common/data/", // up 3 in tree, "../../../common/data/" subdir + "../../../data/", // up 3 in tree, "../../../data/" subdir + "../../../../", // up 4 in tree + "../../../../src//", // up 4 in tree, "/src//" subdir + "../../../../src//data/", // up 4 in tree, "/src//data/" subdir + "../../../../src//src/", // up 4 in tree, "/src//src/" subdir + "../../../../src//inc/", // up 4 in tree, "/src//inc/" subdir + "../../../../sandbox//", // up 4 in tree, "/sandbox//" subdir + "../../../../sandbox//data/", // up 4 in tree, "/sandbox//data/" subdir + "../../../../sandbox//src/", // up 4 in tree, "/sandbox//src/" subdir + "../../../../sandbox//inc/", // up 4 in tree, "/sandbox//inc/" subdir + "../../../../0_Simple//data/", // up 4 in tree, "/0_Simple//" subdir + "../../../../1_Utilities//data/", // up 4 in tree, "/1_Utilities//" subdir + "../../../../2_Graphics//data/", // up 4 in tree, "/2_Graphics//" subdir + "../../../../3_Imaging//data/", // up 4 in tree, "/3_Imaging//" subdir + "../../../../4_Financial//data/", // up 4 in tree, "/4_Financial//" subdir + "../../../../5_Simulations//data/",// up 4 in tree, "/5_Simulations//" subdir + "../../../../6_Advanced//data/", // up 4 in tree, "/6_Advanced//" subdir + "../../../../7_CUDALibraries//data/", // up 4 in tree, "/7_CUDALibraries//" subdir + "../../../../samples//data/", // up 4 in tree, "/samples//" subdir + "../../../../common/", // up 4 in tree, "../../../common/" subdir + "../../../../common/data/", // up 4 in tree, "../../../common/data/" subdir + "../../../../data/", // up 4 in tree, "../../../data/" subdir + }; + + // Extract the executable name + std::string executable_name; + + if (executable_path != 0) + { + executable_name = std::string(executable_path); + +#ifdef _WIN32 + // Windows path delimiter + size_t delimiter_pos = executable_name.find_last_of('\\'); + executable_name.erase(0, delimiter_pos + 1); + + if (executable_name.rfind(".exe") != std::string::npos) + { + // we strip .exe, only if the .exe is found + executable_name.resize(executable_name.size() - 4); + } + +#else + // Linux & OSX path delimiter + size_t delimiter_pos = executable_name.find_last_of('/'); + executable_name.erase(0,delimiter_pos+1); +#endif + } + + // Loop over all search paths and return the first hit + for (unsigned int i = 0; i < sizeof(searchPath)/sizeof(char *); ++i) + { + std::string path(searchPath[i]); + size_t executable_name_pos = path.find(""); + + // If there is executable_name variable in the searchPath + // replace it with the value + if (executable_name_pos != std::string::npos) + { + if (executable_path != 0) + { + path.replace(executable_name_pos, strlen(""), executable_name); + } + else + { + // Skip this path entry if no executable argument is given + continue; + } + } + +#ifdef _DEBUG + printf("sdkFindFilePath <%s> in %s\n", filename, path.c_str()); +#endif + + // Test if the file exists + path.append(filename); + FILE *fp; + FOPEN(fp, path.c_str(), "rb"); + + if (fp != NULL) + { + fclose(fp); + // File found + // returning an allocated array here for backwards compatibility reasons + char *file_path = (char *) malloc(path.length() + 1); + STRCPY(file_path, path.length() + 1, path.c_str()); + return file_path; + } + + if (fp) + { + fclose(fp); + } + } + + // File not found + return 0; +} + +#endif diff --git a/external/cutil/inc/helper_timer.h b/external/cutil/inc/helper_timer.h new file mode 100644 index 0000000..d656e36 --- /dev/null +++ b/external/cutil/inc/helper_timer.h @@ -0,0 +1,499 @@ +/** + * Copyright 1993-2013 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +// Helper Timing Functions +#ifndef HELPER_TIMER_H +#define HELPER_TIMER_H + +#ifndef EXIT_WAIVED +#define EXIT_WAIVED 2 +#endif + +// includes, system +#include + +// includes, project +#include + +// Definition of the StopWatch Interface, this is used if we don't want to use the CUT functions +// But rather in a self contained class interface +class StopWatchInterface +{ + public: + StopWatchInterface() {}; + virtual ~StopWatchInterface() {}; + + public: + //! Start time measurement + virtual void start() = 0; + + //! Stop time measurement + virtual void stop() = 0; + + //! Reset time counters to zero + virtual void reset() = 0; + + //! Time in msec. after start. If the stop watch is still running (i.e. there + //! was no call to stop()) then the elapsed time is returned, otherwise the + //! time between the last start() and stop call is returned + virtual float getTime() = 0; + + //! Mean time to date based on the number of times the stopwatch has been + //! _stopped_ (ie finished sessions) and the current total time + virtual float getAverageTime() = 0; +}; + + +////////////////////////////////////////////////////////////////// +// Begin Stopwatch timer class definitions for all OS platforms // +////////////////////////////////////////////////////////////////// +#ifdef WIN32 +// includes, system +#define WINDOWS_LEAN_AND_MEAN +#include +#undef min +#undef max + +//! Windows specific implementation of StopWatch +class StopWatchWin : public StopWatchInterface +{ + public: + //! Constructor, default + StopWatchWin() : + start_time(), end_time(), + diff_time(0.0f), total_time(0.0f), + running(false), clock_sessions(0), freq(0), freq_set(false) + { + if (! freq_set) + { + // helper variable + LARGE_INTEGER temp; + + // get the tick frequency from the OS + QueryPerformanceFrequency((LARGE_INTEGER *) &temp); + + // convert to type in which it is needed + freq = ((double) temp.QuadPart) / 1000.0; + + // rememeber query + freq_set = true; + } + }; + + // Destructor + ~StopWatchWin() { }; + + public: + //! Start time measurement + inline void start(); + + //! Stop time measurement + inline void stop(); + + //! Reset time counters to zero + inline void reset(); + + //! Time in msec. after start. If the stop watch is still running (i.e. there + //! was no call to stop()) then the elapsed time is returned, otherwise the + //! time between the last start() and stop call is returned + inline float getTime(); + + //! Mean time to date based on the number of times the stopwatch has been + //! _stopped_ (ie finished sessions) and the current total time + inline float getAverageTime(); + + private: + // member variables + + //! Start of measurement + LARGE_INTEGER start_time; + //! End of measurement + LARGE_INTEGER end_time; + + //! Time difference between the last start and stop + float diff_time; + + //! TOTAL time difference between starts and stops + float total_time; + + //! flag if the stop watch is running + bool running; + + //! Number of times clock has been started + //! and stopped to allow averaging + int clock_sessions; + + //! tick frequency + double freq; + + //! flag if the frequency has been set + bool freq_set; +}; + +// functions, inlined + +//////////////////////////////////////////////////////////////////////////////// +//! Start time measurement +//////////////////////////////////////////////////////////////////////////////// +inline void +StopWatchWin::start() +{ + QueryPerformanceCounter((LARGE_INTEGER *) &start_time); + running = true; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Stop time measurement and increment add to the current diff_time summation +//! variable. Also increment the number of times this clock has been run. +//////////////////////////////////////////////////////////////////////////////// +inline void +StopWatchWin::stop() +{ + QueryPerformanceCounter((LARGE_INTEGER *) &end_time); + diff_time = (float) + (((double) end_time.QuadPart - (double) start_time.QuadPart) / freq); + + total_time += diff_time; + clock_sessions++; + running = false; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Reset the timer to 0. Does not change the timer running state but does +//! recapture this point in time as the current start time if it is running. +//////////////////////////////////////////////////////////////////////////////// +inline void +StopWatchWin::reset() +{ + diff_time = 0; + total_time = 0; + clock_sessions = 0; + + if (running) + { + QueryPerformanceCounter((LARGE_INTEGER *) &start_time); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +//! Time in msec. after start. If the stop watch is still running (i.e. there +//! was no call to stop()) then the elapsed time is returned added to the +//! current diff_time sum, otherwise the current summed time difference alone +//! is returned. +//////////////////////////////////////////////////////////////////////////////// +inline float +StopWatchWin::getTime() +{ + // Return the TOTAL time to date + float retval = total_time; + + if (running) + { + LARGE_INTEGER temp; + QueryPerformanceCounter((LARGE_INTEGER *) &temp); + retval += (float) + (((double)(temp.QuadPart - start_time.QuadPart)) / freq); + } + + return retval; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Time in msec. for a single run based on the total number of COMPLETED runs +//! and the total time. +//////////////////////////////////////////////////////////////////////////////// +inline float +StopWatchWin::getAverageTime() +{ + return (clock_sessions > 0) ? (total_time/clock_sessions) : 0.0f; +} +#else +// Declarations for Stopwatch on Linux and Mac OSX +// includes, system +#include +#include + +//! Windows specific implementation of StopWatch +class StopWatchLinux : public StopWatchInterface +{ + public: + //! Constructor, default + StopWatchLinux() : + start_time(), diff_time(0.0), total_time(0.0), + running(false), clock_sessions(0) + { }; + + // Destructor + virtual ~StopWatchLinux() + { }; + + public: + //! Start time measurement + inline void start(); + + //! Stop time measurement + inline void stop(); + + //! Reset time counters to zero + inline void reset(); + + //! Time in msec. after start. If the stop watch is still running (i.e. there + //! was no call to stop()) then the elapsed time is returned, otherwise the + //! time between the last start() and stop call is returned + inline float getTime(); + + //! Mean time to date based on the number of times the stopwatch has been + //! _stopped_ (ie finished sessions) and the current total time + inline float getAverageTime(); + + private: + + // helper functions + + //! Get difference between start time and current time + inline float getDiffTime(); + + private: + + // member variables + + //! Start of measurement + struct timeval start_time; + + //! Time difference between the last start and stop + float diff_time; + + //! TOTAL time difference between starts and stops + float total_time; + + //! flag if the stop watch is running + bool running; + + //! Number of times clock has been started + //! and stopped to allow averaging + int clock_sessions; +}; + +// functions, inlined + +//////////////////////////////////////////////////////////////////////////////// +//! Start time measurement +//////////////////////////////////////////////////////////////////////////////// +inline void +StopWatchLinux::start() +{ + gettimeofday(&start_time, 0); + running = true; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Stop time measurement and increment add to the current diff_time summation +//! variable. Also increment the number of times this clock has been run. +//////////////////////////////////////////////////////////////////////////////// +inline void +StopWatchLinux::stop() +{ + diff_time = getDiffTime(); + total_time += diff_time; + running = false; + clock_sessions++; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Reset the timer to 0. Does not change the timer running state but does +//! recapture this point in time as the current start time if it is running. +//////////////////////////////////////////////////////////////////////////////// +inline void +StopWatchLinux::reset() +{ + diff_time = 0; + total_time = 0; + clock_sessions = 0; + + if (running) + { + gettimeofday(&start_time, 0); + } +} + +//////////////////////////////////////////////////////////////////////////////// +//! Time in msec. after start. If the stop watch is still running (i.e. there +//! was no call to stop()) then the elapsed time is returned added to the +//! current diff_time sum, otherwise the current summed time difference alone +//! is returned. +//////////////////////////////////////////////////////////////////////////////// +inline float +StopWatchLinux::getTime() +{ + // Return the TOTAL time to date + float retval = total_time; + + if (running) + { + retval += getDiffTime(); + } + + return retval; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Time in msec. for a single run based on the total number of COMPLETED runs +//! and the total time. +//////////////////////////////////////////////////////////////////////////////// +inline float +StopWatchLinux::getAverageTime() +{ + return (clock_sessions > 0) ? (total_time/clock_sessions) : 0.0f; +} +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +inline float +StopWatchLinux::getDiffTime() +{ + struct timeval t_time; + gettimeofday(&t_time, 0); + + // time difference in milli-seconds + return (float)(1000.0 * (t_time.tv_sec - start_time.tv_sec) + + (0.001 * (t_time.tv_usec - start_time.tv_usec))); +} +#endif // _WIN32 + +//////////////////////////////////////////////////////////////////////////////// +//! Timer functionality exported + +//////////////////////////////////////////////////////////////////////////////// +//! Create a new timer +//! @return true if a time has been created, otherwise false +//! @param name of the new timer, 0 if the creation failed +//////////////////////////////////////////////////////////////////////////////// +inline bool +sdkCreateTimer(StopWatchInterface **timer_interface) +{ + //printf("sdkCreateTimer called object %08x\n", (void *)*timer_interface); +#ifdef _WIN32 + *timer_interface = (StopWatchInterface *)new StopWatchWin(); +#else + *timer_interface = (StopWatchInterface *)new StopWatchLinux(); +#endif + return (*timer_interface != NULL) ? true : false; +} + + +//////////////////////////////////////////////////////////////////////////////// +//! Delete a timer +//! @return true if a time has been deleted, otherwise false +//! @param name of the timer to delete +//////////////////////////////////////////////////////////////////////////////// +inline bool +sdkDeleteTimer(StopWatchInterface **timer_interface) +{ + //printf("sdkDeleteTimer called object %08x\n", (void *)*timer_interface); + if (*timer_interface) + { + delete *timer_interface; + *timer_interface = NULL; + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Start the time with name \a name +//! @param name name of the timer to start +//////////////////////////////////////////////////////////////////////////////// +inline bool +sdkStartTimer(StopWatchInterface **timer_interface) +{ + //printf("sdkStartTimer called object %08x\n", (void *)*timer_interface); + if (*timer_interface) + { + (*timer_interface)->start(); + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Stop the time with name \a name. Does not reset. +//! @param name name of the timer to stop +//////////////////////////////////////////////////////////////////////////////// +inline bool +sdkStopTimer(StopWatchInterface **timer_interface) +{ + // printf("sdkStopTimer called object %08x\n", (void *)*timer_interface); + if (*timer_interface) + { + (*timer_interface)->stop(); + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Resets the timer's counter. +//! @param name name of the timer to reset. +//////////////////////////////////////////////////////////////////////////////// +inline bool +sdkResetTimer(StopWatchInterface **timer_interface) +{ + // printf("sdkResetTimer called object %08x\n", (void *)*timer_interface); + if (*timer_interface) + { + (*timer_interface)->reset(); + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Return the average time for timer execution as the total time +//! for the timer dividied by the number of completed (stopped) runs the timer +//! has made. +//! Excludes the current running time if the timer is currently running. +//! @param name name of the timer to return the time of +//////////////////////////////////////////////////////////////////////////////// +inline float +sdkGetAverageTimerValue(StopWatchInterface **timer_interface) +{ + // printf("sdkGetAverageTimerValue called object %08x\n", (void *)*timer_interface); + if (*timer_interface) + { + return (*timer_interface)->getAverageTime(); + } + else + { + return 0.0f; + } +} + +//////////////////////////////////////////////////////////////////////////////// +//! Total execution time for the timer over all runs since the last reset +//! or timer creation. +//! @param name name of the timer to obtain the value of. +//////////////////////////////////////////////////////////////////////////////// +inline float +sdkGetTimerValue(StopWatchInterface **timer_interface) +{ + // printf("sdkGetTimerValue called object %08x\n", (void *)*timer_interface); + if (*timer_interface) + { + return (*timer_interface)->getTime(); + } + else + { + return 0.0f; + } +} + +#endif // HELPER_TIMER_H diff --git a/external/cutil/inc/multithreading.h b/external/cutil/inc/multithreading.h new file mode 100644 index 0000000..9a4d395 --- /dev/null +++ b/external/cutil/inc/multithreading.h @@ -0,0 +1,60 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +#ifndef MULTITHREADING_H +#define MULTITHREADING_H + + +//Simple portable thread library. + +#if _WIN32 + //Windows threads. + #include + + typedef HANDLE CUTThread; + typedef unsigned (WINAPI *CUT_THREADROUTINE)(void *); + + #define CUT_THREADPROC unsigned WINAPI + #define CUT_THREADEND return 0 + +#else + //POSIX threads. + #include + + typedef pthread_t CUTThread; + typedef void *(*CUT_THREADROUTINE)(void *); + + #define CUT_THREADPROC void + #define CUT_THREADEND +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + +//Create thread. +CUTThread cutStartThread(CUT_THREADROUTINE, void *data); + +//Wait for thread to finish. +void cutEndThread(CUTThread thread); + +//Destroy thread. +void cutDestroyThread(CUTThread thread); + +//Wait for multiple threads. +void cutWaitForThreads(const CUTThread *threads, int num); + +#ifdef __cplusplus +} //extern "C" +#endif + +#endif //MULTITHREADING_H diff --git a/external/cutil/inc/nvGLWidgets.h b/external/cutil/inc/nvGLWidgets.h new file mode 100644 index 0000000..aef9364 --- /dev/null +++ b/external/cutil/inc/nvGLWidgets.h @@ -0,0 +1,136 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + // +// nvGLWidgets.h - User Interface library +// +// +// Author: Ignacio Castano, Samuel Gateau, Evan Hart +// Email: sdkfeedback@nvidia.com +// +// Copyright (c) NVIDIA Corporation. All rights reserved. +//////////////////////////////////////////////////////////////////////////////// +#ifndef NV_GL_WIDGETS_H +#define NV_GL_WIDGETS_H + +#include "nvWidgets.h" + +namespace nv { + + //************************************************************************* + // GLUIPainter + class GLUIPainter : public UIPainter + { + public: + + NVSDKENTRY GLUIPainter(); + + NVSDKENTRY virtual void begin( const Rect& window ); + NVSDKENTRY virtual void end(); + + // These methods should be called between begin/end + NVSDKENTRY virtual void drawFrame(const Rect & r, int margin, int style); + + NVSDKENTRY virtual Rect getLabelRect(const Rect & r, const char * text, Rect & rt, int& nbLines) const; + NVSDKENTRY virtual void drawLabel(const Rect & r, const char * text, const Rect & rt, const int& nbLines, bool isHover, int style); + + NVSDKENTRY virtual Rect getButtonRect(const Rect & r, const char * text, Rect & rt) const; + NVSDKENTRY virtual void drawButton(const Rect & r, const char * text, const Rect & rt, bool isDown, bool isHover, bool isFocus, int style); + + NVSDKENTRY virtual Rect getCheckRect(const Rect & r, const char * text, Rect & rt, Rect & rc) const; + NVSDKENTRY virtual void drawCheckButton(const Rect & r, const char * text, const Rect & rt, const Rect & rr, bool isChecked, bool isHover, bool isFocus, int style); + + NVSDKENTRY virtual Rect getRadioRect(const Rect & r, const char * text, Rect & rt, Rect & rr) const; + NVSDKENTRY virtual void drawRadioButton(const Rect & r, const char * text, const Rect & rt, const Rect & rr, bool isOn, bool isHover, bool isFocus, int style); + + NVSDKENTRY virtual Rect getHorizontalSliderRect(const Rect & r, Rect& rs, float v, Rect& rc) const; + NVSDKENTRY virtual void drawHorizontalSlider(const Rect & r, Rect& rs, float v, Rect& rc, bool isHover, int style); + + NVSDKENTRY virtual Rect getItemRect(const Rect & r, const char * text, Rect & rt) const; + NVSDKENTRY virtual Rect getListRect(const Rect & r, int numOptions, const char * options[], Rect& ri, Rect & rt) const; + NVSDKENTRY virtual void drawListItem(const Rect & r, const char * text, const Rect & rt, bool isSelected, bool isHover, int style); + NVSDKENTRY virtual void drawListBox(const Rect & r, int numOptions, const char * options[], const Rect& ri, const Rect & rt, int selected, int hovered, int style); + + NVSDKENTRY virtual Rect getComboRect(const Rect & r, int numOptions, const char * options[], int selected, Rect& rt, Rect& ra) const; + NVSDKENTRY virtual Rect getComboOptionsRect(const Rect & rCombo, int numOptions, const char * options[], Rect& ri, Rect & rit) const; + NVSDKENTRY virtual void drawComboBox(const Rect & rect, int numOptions, const char * options[], const Rect & rt, const Rect& rd, int selected, bool isHover, bool isFocus, int style); + NVSDKENTRY virtual void drawComboOptions(const Rect & rect, int numOptions, const char * options[], const Rect& ri, const Rect & rit, int selected, int hovered, bool isHover, bool isFocus, int style); + + NVSDKENTRY virtual Rect getLineEditRect(const Rect & r, const char * text, Rect & rt) const; + NVSDKENTRY virtual void drawLineEdit(const Rect & r, const char * text, const Rect & rt, int caretPos, bool isSelected, bool isHover, int style); + + NVSDKENTRY virtual Rect getPanelRect(const Rect & r, const char * text, Rect& rt, Rect& ra) const; + NVSDKENTRY virtual void drawPanel(const Rect & rect, const char * text, const Rect & rt, const Rect & ra, bool isUnfold, bool isHover, bool isFocus, int style); + + NVSDKENTRY virtual Rect getTextureViewRect(const Rect & rect, Rect& rt) const; + NVSDKENTRY virtual void drawTextureView(const Rect & rect, const void* texID, const Rect& rt, const Rect & rz, int mipLevel, int style); + + // Eval widget dimensions + NVSDKENTRY virtual int getCanvasMargin() const; + NVSDKENTRY virtual int getCanvasSpace() const; + NVSDKENTRY virtual int getFontHeight() const; + NVSDKENTRY virtual int getTextLineWidth(const char * text) const; + NVSDKENTRY virtual int getTextSize(const char * text, int& nbLines) const; + NVSDKENTRY virtual int getTextLineWidthAt(const char * text, int charNb) const; + NVSDKENTRY virtual int getPickedCharNb(const char * text, const Point& at) const; + + NVSDKENTRY virtual void drawDebugRect(const Rect & r); + + protected: + + // Draw primitive shapes + NVSDKENTRY void drawText( const Rect& r , const char * text, int nbLines = 1, int caretPos = -1, bool isHover = false, bool isOn = false, bool isFocus = false ); + NVSDKENTRY void drawFrame( const Rect& rect, const Point& corner, bool isHover = false, bool isOn = false, bool isFocus = false ) const; + NVSDKENTRY void drawBoolFrame( const Rect& rect, const Point& corner, bool isHover = false, bool isOn = false, bool isFocus = false ) const; + + NVSDKENTRY void drawString( int x, int y, const char * text, int nbLines ); + NVSDKENTRY void drawRect( const Rect& rect, int fillColorId, int borderColorId ) const; + NVSDKENTRY void drawRoundedRect( const Rect& rect, const Point& corner, int fillColorId, int borderColorId ) const; + NVSDKENTRY void drawRoundedRectOutline( const Rect& rect, const Point& corner, int borderColorId ) const; + NVSDKENTRY void drawCircle( const Rect& rect, int fillColorId, int borderColorId ) const; + NVSDKENTRY void drawMinus( const Rect& rect, int width, int fillColorId, int borderColorId ) const; + NVSDKENTRY void drawPlus( const Rect& rect, int width, int fillColorId, int borderColorId ) const; + NVSDKENTRY void drawDownArrow( const Rect& rect, int width, int fillColorId, int borderColorId ) const; + NVSDKENTRY void drawUpArrow( const Rect& rect, int width, int fillColorId, int borderColorId ) const; + + NVSDKENTRY void init(); + + enum Color + { + cBase = 0, + cBool = 8, + cOutline = 16, + cFont = 20, + cFontBack = 24, + cTranslucent = 32, + cNbColors = 33, + }; + + private: + + GLuint m_setupStateDL; + GLuint m_restoreStateDL; + GLuint m_textListBase; + GLuint m_foregroundDL; + + GLuint m_widgetProgram; + GLuint m_originUniform; + GLuint m_sizeUniform; + GLuint m_fillColorUniform; + GLuint m_borderColorUniform; + GLuint m_zonesUniform; + + vec4f m_colors[cNbColors]; + }; +}; + + +#endif diff --git a/external/cutil/inc/nvGlutWidgets.h b/external/cutil/inc/nvGlutWidgets.h new file mode 100644 index 0000000..c18b830 --- /dev/null +++ b/external/cutil/inc/nvGlutWidgets.h @@ -0,0 +1,162 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + // +// nvGlutWidgets +// +// Adaptor classes to integrate the nvWidgets UI library with the GLUT windowing +// toolkit. The adaptors convert native GLUT UI data to native nvWidgets data. All +// adaptor classes are implemented as in-line code in this header. The adaptor +// defaults to using the standard OpenGL paintor implementation. +// +// Author: Ignacio Castano, Samuel Gateau, Evan Hart +// Email: sdkfeedback@nvidia.com +// +// Copyright (c) NVIDIA Corporation. All rights reserved. +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef NV_GLUT_WIDGETS_H +#define NV_GLUT_WIDGETS_H + +#include +#include + + +namespace nv { + +class GlutUIContext : public UIContext { + +protected: + + bool _ownPainter; + +public: + + // + // Default UI constructor + // + // Creates private OpenGL painter + ////////////////////////////////////////////////////////////////// + GlutUIContext() : + UIContext( *(new GLUIPainter()) ), + _ownPainter(true) + { + } + + // + // Alternate UI constructor + // + // Allows for overriding the standard painter + ////////////////////////////////////////////////////////////////// + GlutUIContext(UIPainter& painter) : + UIContext( painter ), + _ownPainter(false) + { + } + + // + // UI destructor + // + // Destroy painter if it is private + ////////////////////////////////////////////////////////////////// + ~GlutUIContext() { + if (_ownPainter) delete getPainter(); + } + + // + // UI method for processing GLUT mouse button events + // + // Call this method from the glutMouseFunc callback, the + // modifier parameter maps to glutGetModifiers. + ////////////////////////////////////////////////////////////////// + virtual void mouse(int button, int state, int modifier, int x, int y) { + int modifierMask = 0; + + if ( button == GLUT_LEFT_BUTTON) button = MouseButton_Left; + else if ( button == GLUT_MIDDLE_BUTTON) button = MouseButton_Middle; + else if ( button == GLUT_RIGHT_BUTTON) button = MouseButton_Right; + + if ( modifier & GLUT_ACTIVE_ALT) modifierMask |= ButtonFlags_Alt; + if ( modifier & GLUT_ACTIVE_SHIFT) modifierMask |= ButtonFlags_Shift; + if ( modifier & GLUT_ACTIVE_CTRL) modifierMask |= ButtonFlags_Ctrl; + + if ( state == GLUT_DOWN) state = 1; else state = 0; + + UIContext::mouse( button, state, modifierMask, x, y); + } + + // + // UI method for processing key events + // + // Call this method from the glutReshapeFunc callback + ////////////////////////////////////////////////////////////////// + void specialKeyboard(int k, int x, int y) { UIContext::keyboard( translateKey(k), x, y); } + + // + // Translate non-ascii keys from GLUT to nvWidgets + ////////////////////////////////////////////////////////////////// + unsigned char translateKey( int k ) + { + switch (k) + { + case GLUT_KEY_F1 : + return Key_F1; + case GLUT_KEY_F2 : + return Key_F2; + case GLUT_KEY_F3 : + return Key_F3; + case GLUT_KEY_F4 : + return Key_F4; + case GLUT_KEY_F5 : + return Key_F5; + case GLUT_KEY_F6 : + return Key_F6; + case GLUT_KEY_F7 : + return Key_F7; + case GLUT_KEY_F8 : + return Key_F8; + case GLUT_KEY_F9 : + return Key_F9; + case GLUT_KEY_F10 : + return Key_F10; + case GLUT_KEY_F11 : + return Key_F11; + case GLUT_KEY_F12 : + return Key_F12; + case GLUT_KEY_LEFT : + return Key_Left; + case GLUT_KEY_UP : + return Key_Up; + case GLUT_KEY_RIGHT : + return Key_Right; + case GLUT_KEY_DOWN : + return Key_Down; + case GLUT_KEY_PAGE_UP : + return Key_PageUp; + case GLUT_KEY_PAGE_DOWN : + return Key_PageDown; + case GLUT_KEY_HOME : + return Key_Home; + case GLUT_KEY_END : + return Key_End; + case GLUT_KEY_INSERT : + return Key_Insert; + default: + return 0; + } + } +}; + +}; + + + +#endif diff --git a/external/cutil/inc/nvMath.h b/external/cutil/inc/nvMath.h new file mode 100644 index 0000000..94b112b --- /dev/null +++ b/external/cutil/inc/nvMath.h @@ -0,0 +1,94 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + // +// Template math library for common 3D functionality +// +// This code is in part deriver from glh, a cross platform glut helper library. +// The copyright for glh follows this notice. +// +// Copyright (c) NVIDIA Corporation. All rights reserved. +//////////////////////////////////////////////////////////////////////////////// + +/* + Copyright (c) 2000 Cass Everitt + Copyright (c) 2000 NVIDIA Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * The names of contributors to this software may not be used + to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + + Cass Everitt - cass@r3.nu +*/ + +#ifndef NV_MATH_H +#define NV_MATH_H + +#include + +#include +#include +#include + +#define NV_PI float(3.1415926535897932384626433832795) + +namespace nv { + +typedef vec2 vec2f; +typedef vec3 vec3f; +typedef vec3 vec3i; +typedef vec3 vec3ui; +typedef vec4 vec4f; +typedef matrix4 matrix4f; +typedef quaternion quaternionf; + + +inline void applyRotation(const quaternionf & r) +{ + float angle; + vec3f axis; + r.get_value(axis, angle); + glRotatef( angle/3.1415926f * 180.0f, axis[0], axis[1], axis[2]); +} + + + +}; + +#endif diff --git a/external/cutil/inc/nvMatrix.h b/external/cutil/inc/nvMatrix.h new file mode 100644 index 0000000..8443731 --- /dev/null +++ b/external/cutil/inc/nvMatrix.h @@ -0,0 +1,389 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + // +// Template math library for common 3D functionality +// +// nvMatrix.h - template matrix code +// +// This code is in part deriver from glh, a cross platform glut helper library. +// The copyright for glh follows this notice. +// +// Copyright (c) NVIDIA Corporation. All rights reserved. +//////////////////////////////////////////////////////////////////////////////// + +/* + Copyright (c) 2000 Cass Everitt + Copyright (c) 2000 NVIDIA Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * The names of contributors to this software may not be used + to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + + Cass Everitt - cass@r3.nu +*/ + +#ifndef NV_MATRIX_H +#define NV_MATRIX_H + +namespace nv { + +template class vec2; +template class vec3; +template class vec4; + +//////////////////////////////////////////////////////////////////////////////// +// +// Matrix +// +//////////////////////////////////////////////////////////////////////////////// +template +class matrix4 +{ + +public: + + matrix4() { make_identity(); } + + matrix4( T t ) + { set_value(t); } + + matrix4( const T * m ) + { set_value(m); } + + matrix4( T a00, T a01, T a02, T a03, + T a10, T a11, T a12, T a13, + T a20, T a21, T a22, T a23, + T a30, T a31, T a32, T a33 ) : + _11(a00), _12(a01), _13(a02), _14(a03), + _21(a10), _22(a11), _23(a12), _24(a13), + _31(a20), _32(a21), _33(a22), _34(a23), + _41(a30), _42(a31), _43(a32), _44(a33) + {} + + + void get_value( T * mp ) const { + int c = 0; + for(int j=0; j < 4; j++) + for(int i=0; i < 4; i++) + mp[c++] = element(i,j); + } + + const T * get_value() const { + return _array; + } + + void set_value( T * mp) { + int c = 0; + for(int j=0; j < 4; j++) + for(int i=0; i < 4; i++) + element(i,j) = mp[c++]; + } + + void set_value( T r ) { + for(int i=0; i < 4; i++) + for(int j=0; j < 4; j++) + element(i,j) = r; + } + + void make_identity() { + element(0,0) = 1.0; + element(0,1) = 0.0; + element(0,2) = 0.0; + element(0,3) = 0.0; + + element(1,0) = 0.0; + element(1,1) = 1.0; + element(1,2) = 0.0; + element(1,3) = 0.0; + + element(2,0) = 0.0; + element(2,1) = 0.0; + element(2,2) = 1.0; + element(2,3) = 0.0; + + element(3,0) = 0.0; + element(3,1) = 0.0; + element(3,2) = 0.0; + element(3,3) = 1.0; + } + + // set a uniform scale + void set_scale( T s ) { + element(0,0) = s; + element(1,1) = s; + element(2,2) = s; + } + + void set_scale( const vec3 & s ) { + for (int i = 0; i < 3; i++) element(i,i) = s[i]; + } + + + void set_translate( const vec3 & t ) { + for (int i = 0; i < 3; i++) element(i,3) = t[i]; + } + + void set_row(int r, const vec4 & t) { + for (int i = 0; i < 4; i++) element(r,i) = t[i]; + } + + void set_column(int c, const vec4 & t) { + for (int i = 0; i < 4; i++) element(i,c) = t[i]; + } + + vec4 get_row(int r) const { + vec4 v; + for (int i = 0; i < 4; i++) v[i] = element(r,i); + return v; + } + + vec4 get_column(int c) const { + vec4 v; + for (int i = 0; i < 4; i++) v[i] = element(i,c); + return v; + } + + friend matrix4 inverse( const matrix4 & m) { + matrix4 minv; + + T r1[8], r2[8], r3[8], r4[8]; + T *s[4], *tmprow; + + s[0] = &r1[0]; + s[1] = &r2[0]; + s[2] = &r3[0]; + s[3] = &r4[0]; + + register int i,j,p,jj; + for(i=0;i<4;i++) { + for(j=0;j<4;j++) { + s[i][j] = m.element(i,j); + if(i==j) s[i][j+4] = 1.0; + else s[i][j+4] = 0.0; + } + } + T scp[4]; + for(i=0;i<4;i++) { + scp[i] = T(fabs(s[i][0])); + for(j=1;j<4;j++) + if(T(fabs(s[i][j])) > scp[i]) scp[i] = T(fabs(s[i][j])); + if(scp[i] == 0.0) return minv; // singular matrix! + } + + int pivot_to; + T scp_max; + for(i=0;i<4;i++) { + // select pivot row + pivot_to = i; + scp_max = T(fabs(s[i][i]/scp[i])); + // find out which row should be on top + for(p=i+1;p<4;p++) + if (T(fabs(s[p][i]/scp[p])) > scp_max) { + scp_max = T(fabs(s[p][i]/scp[p])); + pivot_to = p; + } + // Pivot if necessary + if(pivot_to != i) { + tmprow = s[i]; + s[i] = s[pivot_to]; + s[pivot_to] = tmprow; + T tmpscp; + tmpscp = scp[i]; + scp[i] = scp[pivot_to]; + scp[pivot_to] = tmpscp; + } + + T mji; + // perform gaussian elimination + for(j=i+1;j<4;j++) { + mji = s[j][i]/s[i][i]; + s[j][i] = 0.0; + for(jj=i+1;jj<8;jj++) + s[j][jj] -= mji*s[i][jj]; + } + } + if(s[3][3] == 0.0) return minv; // singular matrix! + + // + // Now we have an upper triangular matrix. + // + // x x x x | y y y y + // 0 x x x | y y y y + // 0 0 x x | y y y y + // 0 0 0 x | y y y y + // + // we'll back substitute to get the inverse + // + // 1 0 0 0 | z z z z + // 0 1 0 0 | z z z z + // 0 0 1 0 | z z z z + // 0 0 0 1 | z z z z + // + + T mij; + for(i=3;i>0;i--) { + for(j=i-1;j > -1; j--) { + mij = s[j][i]/s[i][i]; + for(jj=j+1;jj<8;jj++) + s[j][jj] -= mij*s[i][jj]; + } + } + + for(i=0;i<4;i++) + for(j=0;j<4;j++) + minv(i,j) = s[i][j+4] / s[i][i]; + + return minv; + } + + + friend matrix4 transpose( const matrix4 & m) { + matrix4 mtrans; + + for(int i=0;i<4;i++) + for(int j=0;j<4;j++) + mtrans(i,j) = m.element(j,i); + return mtrans; + } + + matrix4 & operator *= ( const matrix4 & rhs ) { + matrix4 mt(*this); + set_value(T(0)); + + for(int i=0; i < 4; i++) + for(int j=0; j < 4; j++) + for(int c=0; c < 4; c++) + element(i,j) += mt(i,c) * rhs(c,j); + return *this; + } + + friend matrix4 operator * ( const matrix4 & lhs, const matrix4 & rhs ) { + matrix4 r(T(0)); + + for(int i=0; i < 4; i++) + for(int j=0; j < 4; j++) + for(int c=0; c < 4; c++) + r.element(i,j) += lhs(i,c) * rhs(c,j); + return r; + } + + // dst = M * src + vec4 operator *( const vec4 &src) const { + vec4 r; + for ( int i = 0; i < 4; i++) + r[i] = ( src[0] * element(i,0) + src[1] * element(i,1) + + src[2] * element(i,2) + src[3] * element(i,3)); + return r; + } + + // dst = src * M + friend vec4 operator *( const vec4 &lhs, const matrix4 &rhs) { + vec4 r; + for ( int i = 0; i < 4; i++) + r[i] = ( lhs[0] * rhs.element(0,i) + lhs[1] * rhs.element(1,i) + + lhs[2] * rhs.element(2,i) + lhs[3] * rhs.element(3,i)); + return r; + } + + T & operator () (int row, int col) { + return element(row,col); + } + + const T & operator () (int row, int col) const { + return element(row,col); + } + + T & element (int row, int col) { + return _array[row | (col<<2)]; + } + + const T & element (int row, int col) const { + return _array[row | (col<<2)]; + } + + matrix4 & operator *= ( const T & r ) { + for (int i = 0; i < 4; ++i) { + element(0,i) *= r; + element(1,i) *= r; + element(2,i) *= r; + element(3,i) *= r; + } + return *this; + } + + matrix4 & operator += ( const matrix4 & mat ) { + for (int i = 0; i < 4; ++i) { + element(0,i) += mat.element(0,i); + element(1,i) += mat.element(1,i); + element(2,i) += mat.element(2,i); + element(3,i) += mat.element(3,i); + } + return *this; + } + + + friend bool operator == ( const matrix4 & lhs, const matrix4 & rhs ) { + bool r = true; + for (int i = 0; i < 16; i++) + r &= lhs._array[i] == rhs._array[i]; + return r; + } + + friend bool operator != ( const matrix4 & lhs, const matrix4 & rhs ) { + bool r = true; + for (int i = 0; i < 16; i++) + r &= lhs._array[i] != rhs._array[i]; + return r; + } + + union { + struct { + T _11, _12, _13, _14; // standard names for components + T _21, _22, _23, _24; // standard names for components + T _31, _32, _33, _34; // standard names for components + T _41, _42, _43, _44; // standard names for components + }; + T _array[16]; // array access + }; +}; + +}; + +#endif diff --git a/external/cutil/inc/nvQuaternion.h b/external/cutil/inc/nvQuaternion.h new file mode 100644 index 0000000..e17fa28 --- /dev/null +++ b/external/cutil/inc/nvQuaternion.h @@ -0,0 +1,468 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + // +// Template math library for common 3D functionality +// +// nvQuaterion.h - quaternion template and utility functions +// +// This code is in part deriver from glh, a cross platform glut helper library. +// The copyright for glh follows this notice. +// +// Copyright (c) NVIDIA Corporation. All rights reserved. +//////////////////////////////////////////////////////////////////////////////// + +/* + Copyright (c) 2000 Cass Everitt + Copyright (c) 2000 NVIDIA Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * The names of contributors to this software may not be used + to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + + Cass Everitt - cass@r3.nu +*/ +#ifndef NV_QUATERNION_H +#define NV_QUATERNION_H + +namespace nv { + +template class vec2; +template class vec3; +template class vec4; + +//////////////////////////////////////////////////////////////////////////////// +// +// Quaternion +// +//////////////////////////////////////////////////////////////////////////////// + +template< class T> +class quaternion +{ +public: + + quaternion() : x(0.0), y(0.0), z(0.0), w(0.0) + { + } + + quaternion( const T v[4] ) + { + set_value( v ); + } + + + quaternion( T q0, T q1, T q2, T q3 ) + { + set_value( q0, q1, q2, q3 ); + } + + + quaternion( const matrix4 & m ) + { + set_value( m ); + } + + + quaternion( const vec3 &axis, T radians ) + { + set_value( axis, radians ); + } + + + quaternion( const vec3 &rotateFrom, const vec3 &rotateTo ) + { + set_value( rotateFrom, rotateTo ); + } + + quaternion( const vec3 & from_look, const vec3 & from_up, + const vec3& to_look, const vec3& to_up) + { + set_value(from_look, from_up, to_look, to_up); + } + + const T * get_value() const + { + return &_array[0]; + } + + void get_value( T &q0, T &q1, T &q2, T &q3 ) const + { + q0 = _array[0]; + q1 = _array[1]; + q2 = _array[2]; + q3 = _array[3]; + } + + quaternion & set_value( T q0, T q1, T q2, T q3 ) + { + _array[0] = q0; + _array[1] = q1; + _array[2] = q2; + _array[3] = q3; + return *this; + } + + void get_value( vec3 &axis, T &radians ) const + { + radians = T(acos( _array[3] ) * T(2.0)); + if ( radians == T(0.0) ) + axis = vec3( 0.0, 0.0, 1.0 ); + else + { + axis[0] = _array[0]; + axis[1] = _array[1]; + axis[2] = _array[2]; + axis = normalize(axis); + } + } + + void get_value( matrix4 & m ) const + { + T s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz; + + T norm = _array[0] * _array[0] + _array[1] * _array[1] + _array[2] * _array[2] + _array[3] * _array[3]; + + s = ( norm == T(0.0)) ? T(0.0) : ( T(2.0) / norm ); + + xs = _array[0] * s; + ys = _array[1] * s; + zs = _array[2] * s; + + wx = _array[3] * xs; + wy = _array[3] * ys; + wz = _array[3] * zs; + + xx = _array[0] * xs; + xy = _array[0] * ys; + xz = _array[0] * zs; + + yy = _array[1] * ys; + yz = _array[1] * zs; + zz = _array[2] * zs; + + m(0,0) = T( T(1.0) - ( yy + zz )); + m(1,0) = T ( xy + wz ); + m(2,0) = T ( xz - wy ); + + m(0,1) = T ( xy - wz ); + m(1,1) = T ( T(1.0) - ( xx + zz )); + m(2,1) = T ( yz + wx ); + + m(0,2) = T ( xz + wy ); + m(1,2) = T ( yz - wx ); + m(2,2) = T ( T(1.0) - ( xx + yy )); + + m(3,0) = m(3,1) = m(3,2) = m(0,3) = m(1,3) = m(2,3) = T(0.0); + m(3,3) = T(1.0); + } + + quaternion & set_value( const T * qp ) + { + for ( int i = 0; i < 4; i++) _array[i] = qp[i]; + + return *this; + } + + quaternion & set_value( const matrix4 & m ) + { + T tr, s; + int i, j, k; + const int nxt[3] = { 1, 2, 0 }; + + tr = m(0,0) + m(1,1) + m(2,2); + + if ( tr > T(0) ) + { + s = T(sqrt( tr + m(3,3) )); + _array[3] = T ( s * 0.5 ); + s = T(0.5) / s; + + _array[0] = T ( ( m(1,2) - m(2,1) ) * s ); + _array[1] = T ( ( m(2,0) - m(0,2) ) * s ); + _array[2] = T ( ( m(0,1) - m(1,0) ) * s ); + } + else + { + i = 0; + if ( m(1,1) > m(0,0) ) + i = 1; + + if ( m(2,2) > m(i,i) ) + i = 2; + + j = nxt[i]; + k = nxt[j]; + + s = T(sqrt( ( m(i,j) - ( m(j,j) + m(k,k) )) + T(1.0) )); + + _array[i] = T ( s * 0.5 ); + s = T(0.5 / s); + + _array[3] = T ( ( m(j,k) - m(k,j) ) * s ); + _array[j] = T ( ( m(i,j) + m(j,i) ) * s ); + _array[k] = T ( ( m(i,k) + m(k,i) ) * s ); + } + + return *this; + } + + quaternion & set_value( const vec3 &axis, T theta ) + { + T sqnorm = square_norm(axis); + + if (sqnorm == T(0.0)) + { + // axis too small. + x = y = z = T(0.0); + w = T(1.0); + } + else + { + theta *= T(0.5); + T sin_theta = T(sin(theta)); + + if ( sqnorm != T(1)) + sin_theta /= T(sqrt(sqnorm)); + x = sin_theta * axis[0]; + y = sin_theta * axis[1]; + z = sin_theta * axis[2]; + w = T(cos(theta)); + } + return *this; + } + + quaternion & set_value( const vec3 & rotateFrom, const vec3 & rotateTo ) + { + vec3 p1, p2; + T alpha; + + p1 = normalize(rotateFrom); + p2 = normalize(rotateTo); + + alpha = dot( p1, p2); + + if( alpha == T(1.0) ) { + *this = quaternion(); + return *this; + } + + // ensures that the anti-parallel case leads to a positive dot + if( alpha == T(-1.0)) + { + vec3 v; + + if(p1[0] != p1[1] || p1[0] != p1[2]) + v = vec3(p1[1], p1[2], p1[0]); + else + v = vec3(-p1[0], p1[1], p1[2]); + + v -= p1 * dot( p1, v); + v = normalize(v); + + set_value(v, T(3.1415926)); + return *this; + } + + p1 = normalize( cross( p1, p2)); + + set_value(p1,T(acos(alpha))); + + return *this; + } + + quaternion & set_value( const vec3 & from_look, const vec3 & from_up, + const vec3 & to_look, const vec3 & to_up) + { + quaternion r_look = quaternion(from_look, to_look); + + vec3 rotated_from_up(from_up); + r_look.mult_vec(rotated_from_up); + + quaternion r_twist = quaternion(rotated_from_up, to_up); + + *this = r_twist; + *this *= r_look; + return *this; + } + + quaternion & operator *= ( const quaternion & qr ) { + quaternion ql(*this); + + w = ql.w * qr.w - ql.x * qr.x - ql.y * qr.y - ql.z * qr.z; + x = ql.w * qr.x + ql.x * qr.w + ql.y * qr.z - ql.z * qr.y; + y = ql.w * qr.y + ql.y * qr.w + ql.z * qr.x - ql.x * qr.z; + z = ql.w * qr.z + ql.z * qr.w + ql.x * qr.y - ql.y * qr.x; + + return *this; + } + + friend quaternion normalize( const quaternion &q) { + quaternion r(q); + T rnorm = T(1.0) / T(sqrt( q.w * q.w + q.x * q.x + q.y * q.y + q.z * q.z)); + + r.x *= rnorm; + r.y *= rnorm; + r.z *= rnorm; + r.w *= rnorm; + } + + friend quaternion conjugate( const quaternion & q) { + quaternion r(q); + r._array[0] *= T(-1.0); + r._array[1] *= T(-1.0); + r._array[2] *= T(-1.0); + return r; + } + + friend quaternion inverse( const quaternion & q) { + return conjugate(q); + } + + // + // Quaternion multiplication with cartesian vector + // v' = q*v*q(star) + // + void mult_vec( const vec3 &src, vec3 &dst ) const + { + T v_coef = w * w - x * x - y * y - z * z; + T u_coef = T(2.0) * (src[0] * x + src[1] * y + src[2] * z); + T c_coef = T(2.0) * w; + + dst.v[0] = v_coef * src.v[0] + u_coef * x + c_coef * (y * src.v[2] - z * src.v[1]); + dst.v[1] = v_coef * src.v[1] + u_coef * y + c_coef * (z * src.v[0] - x * src.v[2]); + dst.v[2] = v_coef * src.v[2] + u_coef * z + c_coef * (x * src.v[1] - y * src.v[0]); + } + + void mult_vec( vec3 & src_and_dst) const + { + mult_vec(vec3(src_and_dst), src_and_dst); + } + + void scale_angle( T scaleFactor ) { + vec3 axis; + T radians; + + get_value(axis, radians); + radians *= scaleFactor; + set_value(axis, radians); + } + + friend quaternion slerp( const quaternion & p, const quaternion & q, T alpha ) + { + quaternion r; + + T cos_omega = p.x * q.x + p.y * q.y + p.z * q.z + p.w * q.w; + // if B is on opposite hemisphere from A, use -B instead + + int bflip; + if ( ( bflip = (cos_omega < T(0))) ) + cos_omega = -cos_omega; + + // complementary interpolation parameter + T beta = T(1) - alpha; + + if(cos_omega >= T(1)) + return p; + + T omega = T(acos(cos_omega)); + T one_over_sin_omega = T(1.0) / T(sin(omega)); + + beta = T(sin(omega*beta) * one_over_sin_omega); + alpha = T(sin(omega*alpha) * one_over_sin_omega); + + if (bflip) + alpha = -alpha; + + r.x = beta * p._array[0]+ alpha * q._array[0]; + r.y = beta * p._array[1]+ alpha * q._array[1]; + r.z = beta * p._array[2]+ alpha * q._array[2]; + r.w = beta * p._array[3]+ alpha * q._array[3]; + return r; + } + + T & operator []( int i ) { + return _array[i]; + } + + const T & operator []( int i ) const { + return _array[i]; + } + + + friend bool operator == ( const quaternion & lhs, const quaternion & rhs ) { + bool r = true; + for (int i = 0; i < 4; i++) + r &= lhs._array[i] == rhs._array[i]; + return r; + } + + friend bool operator != ( const quaternion & lhs, const quaternion & rhs ) { + bool r = true; + for (int i = 0; i < 4; i++) + r &= lhs._array[i] == rhs._array[i]; + return r; + } + + friend quaternion operator * ( const quaternion & lhs, const quaternion & rhs ) { + quaternion r(lhs); + r *= rhs; + return r; + } + + + union + { + struct + { + T x; + T y; + T z; + T w; + }; + T _array[4]; + }; + +}; + + + +}; + +#endif diff --git a/external/cutil/inc/nvShaderUtils.h b/external/cutil/inc/nvShaderUtils.h new file mode 100644 index 0000000..2c6c7b7 --- /dev/null +++ b/external/cutil/inc/nvShaderUtils.h @@ -0,0 +1,244 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + // +// Utility functions for compiling shaders and programs +// +// Author: Evan Hart +// Copyright (c) NVIDIA Corporation. All rights reserved. +//////////////////////////////////////////////////////////////////////////////// + + +#ifndef NV_SHADER_UTILS_H +#define NV_SHADER_UTILS_H + +#include +#include + +#include + +namespace nv +{ + + +// +// +//////////////////////////////////////////////////////////// +inline GLuint CompileGLSLShader( GLenum target, const char* shader) +{ + GLuint object; + + object = glCreateShader( target); + + if (!object) + return object; + + glShaderSource( object, 1, &shader, NULL); + + glCompileShader(object); + + // check if shader compiled + GLint compiled = 0; + glGetShaderiv(object, GL_COMPILE_STATUS, &compiled); + + if (!compiled) + { +#ifdef NV_REPORT_COMPILE_ERRORS + char temp[256] = ""; + glGetShaderInfoLog( object, 256, NULL, temp); + fprintf( stderr, "Compile failed:\n%s\n", temp); +#endif + glDeleteShader( object); + return 0; + } + + return object; +} + +// +// +//////////////////////////////////////////////////////////// +inline GLuint CompileGLSLShaderFromFile( GLenum target, const char* filename) +{ + FILE *shaderFile; + char *text; + long size; + size_t fsize = 0; + + // read files as binary to prevent problems from newline translation + #ifdef _WIN32 + if (fopen_s(&shaderFile, filename, "rb") != 0) + #else + if ((shaderFile = fopen(filename, "rb")) == 0) + #endif + { + return 0; + } + + // Get the length of the file + fseek( shaderFile, 0, SEEK_END); + size = ftell(shaderFile); + + // Read the file contents from the start, then close file and add a null terminator + fseek( shaderFile, 0, SEEK_SET); + text = new char[size+1]; + fsize = fread( text, size, 1, shaderFile); + fclose( shaderFile); + if (fsize == 0) + printf("CompileGLSLShaderFromFile(), error... fsize = 0\n"); + + text[size] = '\0'; + + GLuint object = CompileGLSLShader( target, text); + + delete []text; + + return object; +} + + +// Create a program composed of vertex and fragment shaders. +inline GLuint LinkGLSLProgram( GLuint vertexShader, GLuint fragmentShader) +{ + GLuint program = glCreateProgram(); + glAttachShader(program, vertexShader); + glAttachShader(program, fragmentShader); + glLinkProgram(program); + +#ifdef NV_REPORT_COMPILE_ERRORS + // Get error log. + GLint charsWritten, infoLogLength; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength); + + char * infoLog = new char[infoLogLength]; + glGetProgramInfoLog(program, infoLogLength, &charsWritten, infoLog); + printf(infoLog); + delete [] infoLog; +#endif + + // Test linker result. + GLint linkSucceed = GL_FALSE; + glGetProgramiv(program, GL_LINK_STATUS, &linkSucceed); + + if (linkSucceed == GL_FALSE) + { + glDeleteProgram(program); + return 0; + } + + return program; +} + + +// Create a program composed of vertex, geometry and fragment shaders. +inline GLuint LinkGLSLProgram( GLuint vertexShader, GLuint geometryShader, GLint inputType, GLint vertexOut, GLint outputType, GLuint fragmentShader) +{ + GLuint program = glCreateProgram(); + glAttachShader(program, vertexShader); + glAttachShader(program, geometryShader); + glProgramParameteriEXT(program, GL_GEOMETRY_INPUT_TYPE_EXT, inputType); + glProgramParameteriEXT(program, GL_GEOMETRY_VERTICES_OUT_EXT, vertexOut); + glProgramParameteriEXT(program, GL_GEOMETRY_OUTPUT_TYPE_EXT, outputType); + glAttachShader(program, fragmentShader); + glLinkProgram(program); + +#ifdef NV_REPORT_COMPILE_ERRORS + // Get error log. + GLint charsWritten, infoLogLength; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength); + + char * infoLog = new char[infoLogLength]; + glGetProgramInfoLog(program, infoLogLength, &charsWritten, infoLog); + printf(infoLog); + delete [] infoLog; +#endif + + // Test linker result. + GLint linkSucceed = GL_FALSE; + glGetProgramiv(program, GL_LINK_STATUS, &linkSucceed); + + if (linkSucceed == GL_FALSE) + { + glDeleteProgram(program); + return 0; + } + + return program; +} + +// +// +//////////////////////////////////////////////////////////// +inline GLuint CompileASMShader(GLenum program_type, const char *code) +{ + GLuint program_id; + glGenProgramsARB(1, &program_id); + glBindProgramARB(program_type, program_id); + glProgramStringARB(program_type, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei) strlen(code), (GLubyte *) code); + + GLint error_pos; + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos); + if (error_pos != -1) { +#ifdef NV_REPORT_COMPILE_ERRORS + const GLubyte *error_string; + error_string = glGetString(GL_PROGRAM_ERROR_STRING_ARB); + fprintf(stderr, "Program error at position: %d\n%s\n", (int)error_pos, error_string); +#endif + return 0; + } + return program_id; +} + +// +// +//////////////////////////////////////////////////////////// +inline GLuint CompileASMShaderFromFile( GLenum target, const char* filename) +{ + FILE *shaderFile; + char *text; + long size; + size_t fsize = 0; + + // read files as binary to prevent problems from newline translation + #ifdef _WIN32 + if (fopen_s(&shaderFile, filename, "rb") != 0) + #else + if ((shaderFile = fopen(filename, "rb")) == 0) + #endif + { + return 0; + } + + // Get the length of the file + fseek( shaderFile, 0, SEEK_END); + size = ftell(shaderFile); + + // Read the file contents from the start, then close file and add a null terminator + fseek( shaderFile, 0, SEEK_SET); + text = new char[size+1]; + fsize = fread( text, size, 1, shaderFile); + fclose( shaderFile); + if (fsize == 0) + printf("CompileGLSLShaderFromFile(), error... fsize = 0\n"); + + text[size] = '\0'; + + GLuint program_id = CompileASMShader( target, text); + + delete []text; + + return program_id; +} + +} // nv namespace + +#endif + diff --git a/external/cutil/inc/nvVector.h b/external/cutil/inc/nvVector.h new file mode 100644 index 0000000..1fc87c9 --- /dev/null +++ b/external/cutil/inc/nvVector.h @@ -0,0 +1,753 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + // +// Template math library for common 3D functionality +// +// nvVector.h - 2-vector, 3-vector, and 4-vector templates and utilities +// +// This code is in part deriver from glh, a cross platform glut helper library. +// The copyright for glh follows this notice. +// +// Copyright (c) NVIDIA Corporation. All rights reserved. +//////////////////////////////////////////////////////////////////////////////// + +/* + Copyright (c) 2000 Cass Everitt + Copyright (c) 2000 NVIDIA Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * The names of contributors to this software may not be used + to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + + Cass Everitt - cass@r3.nu +*/ +#ifndef NV_VECTOR_H +#define NV_VECTOR_H + +namespace nv { + +template class vec2; +template class vec3; +template class vec4; + +////////////////////////////////////////////////////////////////////// +// +// vec2 - template class for 2-tuple vector +// +////////////////////////////////////////////////////////////////////// +template +class vec2 { +public: + + typedef T value_type; + int size() const { return 2;} + + //////////////////////////////////////////////////////// + // + // Constructors + // + //////////////////////////////////////////////////////// + + // Default/scalar constructor + vec2(const T & t = T()) { + for(int i = 0; i < size(); i++) _array[i] = t; + } + + // Construct from array + vec2(const T * tp) { + for(int i = 0; i < size(); i++) _array[i] = tp[i]; + } + + // Construct from explicit values + vec2( const T v0, const T v1) { + x = v0; + y = v1; + } + + explicit vec2( const vec3 &u) { + for(int i = 0; i < size(); i++) _array[i] = u._array[i]; + } + + explicit vec2( const vec4 &u) { + for(int i = 0; i < size(); i++) _array[i] = u._array[i]; + } + + const T * get_value() const { + return _array; + } + + vec2 & set_value( const T * rhs ) { + for(int i = 0; i < size(); i++) _array[i] = rhs[i]; + return *this; + } + + // indexing operators + T & operator [] ( int i ) { + return _array[i]; + } + + const T & operator [] ( int i ) const { + return _array[i]; + } + + // type-cast operators + operator T * () { + return _array; + } + + operator const T * () const { + return _array; + } + + //////////////////////////////////////////////////////// + // + // Math operators + // + //////////////////////////////////////////////////////// + + // scalar multiply assign + friend vec2 & operator *= ( vec2 &lhs, T d ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] *= d; + return lhs; + } + + // component-wise vector multiply assign + friend vec2 & operator *= ( vec2 &lhs, const vec2 &rhs ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] *= rhs[i]; + return lhs; + } + + // scalar divide assign + friend vec2 & operator /= ( vec2 &lhs, T d ) { + if(d == 0) return lhs; + for(int i = 0; i < lhs.size(); i++) lhs._array[i] /= d; + return lhs; + } + + // component-wise vector divide assign + friend vec2 & operator /= ( vec2 &lhs, const vec2 & rhs ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] /= rhs._array[i]; + return lhs; + } + + // component-wise vector add assign + friend vec2 & operator += ( vec2 &lhs, const vec2 & rhs ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] += rhs._array[i]; + return lhs; + } + + // component-wise vector subtract assign + friend vec2 & operator -= ( vec2 &lhs, const vec2 & rhs ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] -= rhs._array[i]; + return lhs; + } + + // unary negate + friend vec2 operator - ( const vec2 &rhs) { + vec2 rv; + for(int i = 0; i < rhs.size(); i++) rv._array[i] = -rhs._array[i]; + return rv; + } + + // vector add + friend vec2 operator + ( const vec2 & lhs, const vec2 & rhs) { + vec2 rt(lhs); + return rt += rhs; + } + + // vector subtract + friend vec2 operator - ( const vec2 & lhs, const vec2 & rhs) { + vec2 rt(lhs); + return rt -= rhs; + } + + // scalar multiply + friend vec2 operator * ( const vec2 & lhs, T rhs) { + vec2 rt(lhs); + return rt *= rhs; + } + + // scalar multiply + friend vec2 operator * ( T lhs, const vec2 & rhs) { + vec2 rt(lhs); + return rt *= rhs; + } + + // vector component-wise multiply + friend vec2 operator * ( const vec2 & lhs, const vec2 & rhs){ + vec2 rt(lhs); + return rt *= rhs; + } + + // scalar multiply + friend vec2 operator / ( const vec2 & lhs, T rhs) { + vec2 rt(lhs); + return rt /= rhs; + } + + // vector component-wise multiply + friend vec2 operator / ( const vec2 & lhs, const vec2 & rhs){ + vec2 rt(lhs); + return rt /= rhs; + } + + //////////////////////////////////////////////////////// + // + // Comparison operators + // + //////////////////////////////////////////////////////// + + // equality + friend bool operator == ( const vec2 &lhs, const vec2 &rhs ) { + bool r = true; + for (int i = 0; i < lhs.size(); i++) + r &= lhs._array[i] == rhs._array[i]; + return r; + } + + // inequality + friend bool operator != ( const vec2 &lhs, const vec2 &rhs ) { + bool r = true; + for (int i = 0; i < lhs.size(); i++) + r &= lhs._array[i] != rhs._array[i]; + return r; + } + + //data intentionally left public to allow vec2.x + union { + struct { + T x,y; // standard names for components + }; + struct { + T s,t; // standard names for components + }; + T _array[2]; // array access + }; +}; + +////////////////////////////////////////////////////////////////////// +// +// vec3 - template class for 3-tuple vector +// +////////////////////////////////////////////////////////////////////// +template +class vec3 { +public: + + typedef T value_type; + int size() const { return 3;} + + //////////////////////////////////////////////////////// + // + // Constructors + // + //////////////////////////////////////////////////////// + + // Default/scalar constructor + vec3(const T & t = T()) { + for(int i = 0; i < size(); i++) _array[i] = t; + } + + // Construct from array + vec3(const T * tp) { + for(int i = 0; i < size(); i++) _array[i] = tp[i]; + } + + // Construct from explicit values + vec3( const T v0, const T v1, const T v2) { + x = v0; + y = v1; + z = v2; + } + + explicit vec3( const vec4 &u) { + for(int i = 0; i < size(); i++) _array[i] = u._array[i]; + } + + explicit vec3( const vec2 &u, T v0) { + x = u.x; + y = u.y; + z = v0; + } + + const T * get_value() const { + return _array; + } + + vec3 & set_value( const T * rhs ) { + for(int i = 0; i < size(); i++) _array[i] = rhs[i]; + return *this; + } + + // indexing operators + T & operator [] ( int i ) { + return _array[i]; + } + + const T & operator [] ( int i ) const { + return _array[i]; + } + + // type-cast operators + operator T * () { + return _array; + } + + operator const T * () const { + return _array; + } + + //////////////////////////////////////////////////////// + // + // Math operators + // + //////////////////////////////////////////////////////// + + // scalar multiply assign + friend vec3 & operator *= ( vec3 &lhs, T d ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] *= d; + return lhs; + } + + // component-wise vector multiply assign + friend vec3 & operator *= ( vec3 &lhs, const vec3 &rhs ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] *= rhs[i]; + return lhs; + } + + // scalar divide assign + friend vec3 & operator /= ( vec3 &lhs, T d ) { + if(d == 0) return lhs; + for(int i = 0; i < lhs.size(); i++) lhs._array[i] /= d; + return lhs; + } + + // component-wise vector divide assign + friend vec3 & operator /= ( vec3 &lhs, const vec3 & rhs ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] /= rhs._array[i]; + return lhs; + } + + // component-wise vector add assign + friend vec3 & operator += ( vec3 &lhs, const vec3 & rhs ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] += rhs._array[i]; + return lhs; + } + + // component-wise vector subtract assign + friend vec3 & operator -= ( vec3 &lhs, const vec3 & rhs ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] -= rhs._array[i]; + return lhs; + } + + // unary negate + friend vec3 operator - ( const vec3 &rhs) { + vec3 rv; + for(int i = 0; i < rhs.size(); i++) rv._array[i] = -rhs._array[i]; + return rv; + } + + // vector add + friend vec3 operator + ( const vec3 & lhs, const vec3 & rhs) { + vec3 rt(lhs); + return rt += rhs; + } + + // vector subtract + friend vec3 operator - ( const vec3 & lhs, const vec3 & rhs) { + vec3 rt(lhs); + return rt -= rhs; + } + + // scalar multiply + friend vec3 operator * ( const vec3 & lhs, T rhs) { + vec3 rt(lhs); + return rt *= rhs; + } + + // scalar multiply + friend vec3 operator * ( T lhs, const vec3 & rhs) { + vec3 rt(lhs); + return rt *= rhs; + } + + // vector component-wise multiply + friend vec3 operator * ( const vec3 & lhs, const vec3 & rhs){ + vec3 rt(lhs); + return rt *= rhs; + } + + // scalar multiply + friend vec3 operator / ( const vec3 & lhs, T rhs) { + vec3 rt(lhs); + return rt /= rhs; + } + + // vector component-wise multiply + friend vec3 operator / ( const vec3 & lhs, const vec3 & rhs){ + vec3 rt(lhs); + return rt /= rhs; + } + + //////////////////////////////////////////////////////// + // + // Comparison operators + // + //////////////////////////////////////////////////////// + + // equality + friend bool operator == ( const vec3 &lhs, const vec3 &rhs ) { + bool r = true; + for (int i = 0; i < lhs.size(); i++) + r &= lhs._array[i] == rhs._array[i]; + return r; + } + + // inequality + friend bool operator != ( const vec3 &lhs, const vec3 &rhs ) { + bool r = true; + for (int i = 0; i < lhs.size(); i++) + r &= lhs._array[i] != rhs._array[i]; + return r; + } + + //////////////////////////////////////////////////////////////////////////////// + // + // dimension specific operations + // + //////////////////////////////////////////////////////////////////////////////// + + // cross product + friend vec3 cross( const vec3 & lhs, const vec3 & rhs) { + vec3 r; + + r.x = lhs.y * rhs.z - lhs.z * rhs.y; + r.y = lhs.z * rhs.x - lhs.x * rhs.z; + r.z = lhs.x * rhs.y - lhs.y * rhs.x; + + return r; + } + + //data intentionally left public to allow vec2.x + union { + struct { + T x, y, z; // standard names for components + }; + struct { + T s, t, r; // standard names for components + }; + T _array[3]; // array access + }; +}; + +////////////////////////////////////////////////////////////////////// +// +// vec4 - template class for 4-tuple vector +// +////////////////////////////////////////////////////////////////////// +template +class vec4 { +public: + + typedef T value_type; + int size() const { return 4;} + + //////////////////////////////////////////////////////// + // + // Constructors + // + //////////////////////////////////////////////////////// + + // Default/scalar constructor + vec4(const T & t = T()) { + for(int i = 0; i < size(); i++) _array[i] = t; + } + + // Construct from array + vec4(const T * tp) { + for(int i = 0; i < size(); i++) _array[i] = tp[i]; + } + + // Construct from explicit values + vec4( const T v0, const T v1, const T v2, const T v3) { + x = v0; + y = v1; + z = v2; + w = v3; + } + + explicit vec4( const vec3 &u, T v0) { + x = u.x; + y = u.y; + z = u.z; + w = v0; + } + + explicit vec4( const vec2 &u, T v0, T v1) { + x = u.x; + y = u.y; + z = v0; + w = v1; + } + + const T * get_value() const { + return _array; + } + + vec4 & set_value( const T * rhs ) { + for(int i = 0; i < size(); i++) _array[i] = rhs[i]; + return *this; + } + + // indexing operators + T & operator [] ( int i ) { + return _array[i]; + } + + const T & operator [] ( int i ) const { + return _array[i]; + } + + // type-cast operators + operator T * () { + return _array; + } + + operator const T * () const { + return _array; + } + + //////////////////////////////////////////////////////// + // + // Math operators + // + //////////////////////////////////////////////////////// + + // scalar multiply assign + friend vec4 & operator *= ( vec4 &lhs, T d ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] *= d; + return lhs; + } + + // component-wise vector multiply assign + friend vec4 & operator *= ( vec4 &lhs, const vec4 &rhs ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] *= rhs[i]; + return lhs; + } + + // scalar divide assign + friend vec4 & operator /= ( vec4 &lhs, T d ) { + if(d == 0) return lhs; + for(int i = 0; i < lhs.size(); i++) lhs._array[i] /= d; + return lhs; + } + + // component-wise vector divide assign + friend vec4 & operator /= ( vec4 &lhs, const vec4 & rhs ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] /= rhs._array[i]; + return lhs; + } + + // component-wise vector add assign + friend vec4 & operator += ( vec4 &lhs, const vec4 & rhs ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] += rhs._array[i]; + return lhs; + } + + // component-wise vector subtract assign + friend vec4 & operator -= ( vec4 &lhs, const vec4 & rhs ) { + for(int i = 0; i < lhs.size(); i++) lhs._array[i] -= rhs._array[i]; + return lhs; + } + + // unary negate + friend vec4 operator - ( const vec4 &rhs) { + vec4 rv; + for(int i = 0; i < rhs.size(); i++) rv._array[i] = -rhs._array[i]; + return rv; + } + + // vector add + friend vec4 operator + ( const vec4 & lhs, const vec4 & rhs) { + vec4 rt(lhs); + return rt += rhs; + } + + // vector subtract + friend vec4 operator - ( const vec4 & lhs, const vec4 & rhs) { + vec4 rt(lhs); + return rt -= rhs; + } + + // scalar multiply + friend vec4 operator * ( const vec4 & lhs, T rhs) { + vec4 rt(lhs); + return rt *= rhs; + } + + // scalar multiply + friend vec4 operator * ( T lhs, const vec4 & rhs) { + vec4 rt(lhs); + return rt *= rhs; + } + + // vector component-wise multiply + friend vec4 operator * ( const vec4 & lhs, const vec4 & rhs){ + vec4 rt(lhs); + return rt *= rhs; + } + + // scalar multiply + friend vec4 operator / ( const vec4 & lhs, T rhs) { + vec4 rt(lhs); + return rt /= rhs; + } + + // vector component-wise multiply + friend vec4 operator / ( const vec4 & lhs, const vec4 & rhs){ + vec4 rt(lhs); + return rt /= rhs; + } + + //////////////////////////////////////////////////////// + // + // Comparison operators + // + //////////////////////////////////////////////////////// + + // equality + friend bool operator == ( const vec4 &lhs, const vec4 &rhs ) { + bool r = true; + for (int i = 0; i < lhs.size(); i++) + r &= lhs._array[i] == rhs._array[i]; + return r; + } + + // inequality + friend bool operator != ( const vec4 &lhs, const vec4 &rhs ) { + bool r = true; + for (int i = 0; i < lhs.size(); i++) + r &= lhs._array[i] != rhs._array[i]; + return r; + } + + //data intentionally left public to allow vec2.x + union { + struct { + T x, y, z, w; // standard names for components + }; + struct { + T s, t, r, q; // standard names for components + }; + T _array[4]; // array access + }; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +// Generic vector operations +// +//////////////////////////////////////////////////////////////////////////////// + +// compute the dot product of two vectors +template +inline typename T::value_type dot( const T & lhs, const T & rhs ) { + typename T::value_type r = 0; + for(int i = 0; i < lhs.size(); i++) r += lhs._array[i] * rhs._array[i]; + return r; +} + +// return the length of the provided vector +template< class T> +inline typename T::value_type length( const T & vec) { + typename T::value_type r = 0; + for(int i = 0; i < vec.size(); i++) r += vec._array[i]*vec._array[i]; + return typename T::value_type(sqrt(r)); +} + +// return the squared norm +template< class T> +inline typename T::value_type square_norm( const T & vec) { + typename T::value_type r = 0; + for(int i = 0; i < vec.size(); i++) r += vec._array[i]*vec._array[i]; + return r; +} + +// return the normalized version of the vector +template< class T> +inline T normalize( const T & vec) { + typename T::value_type sum(0); + T r; + for(int i = 0; i < vec.size(); i++) + sum += vec._array[i] * vec._array[i]; + sum = typename T::value_type(sqrt(sum)); + if (sum > 0) + for(int i = 0; i < vec.size(); i++) + r._array[i] = vec._array[i] / sum; + return r; +} + +// In VC8 : min and max are already defined by a #define... +#ifdef min +#undef min +#endif +#ifdef max +#undef max +#endif +//componentwise min +template< class T> +inline T min( const T & lhs, const T & rhs ) { + T rt; + for (int i = 0; i < lhs.size(); i++) rt._array[i] = std::min( lhs._array[i], rhs._array[i]); + return rt; +} + +// componentwise max +template< class T> +inline T max( const T & lhs, const T & rhs ) { + T rt; + for (int i = 0; i < lhs.size(); i++) rt._array[i] = std::max( lhs._array[i], rhs._array[i]); + return rt; +} + + +}; + +#endif diff --git a/external/cutil/inc/nvWidgets.h b/external/cutil/inc/nvWidgets.h new file mode 100644 index 0000000..60c20c1 --- /dev/null +++ b/external/cutil/inc/nvWidgets.h @@ -0,0 +1,378 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + // +// nvWidgets.h - User Interface library +// +// +// Author: Ignacio Castano, Samuel Gateau, Evan Hart +// Email: sdkfeedback@nvidia.com +// +// Copyright (c) NVIDIA Corporation. All rights reserved. +//////////////////////////////////////////////////////////////////////////////// +#ifndef NV_WIDGETS_H +#define NV_WIDGETS_H + +#include +#include // clock +#include + +#ifdef WIN32 +#ifdef NVWIDGETS_EXPORTS +#define NVSDKENTRY __declspec(dllexport) +#else +#define NVSDKENTRY __declspec(dllimport) +#endif +#endif + + +namespace nv +{ + struct Point + { + NVSDKENTRY Point() : x(0), y(0) {} + NVSDKENTRY Point(int ix, int iy) : x(ix), y(iy) {} + NVSDKENTRY Point(const Point & p) : x(p.x), y(p.y) {} + + NVSDKENTRY const Point& operator= (const Point & p) { this->x = p.x; this->y = p.y; return *this; } + + int x, y; + }; + + struct Rect + { + NVSDKENTRY Rect() : x(0), y(0), w(0), h(0) {} + NVSDKENTRY Rect(const Point & p) : x(p.x), y(p.y), w(0), h(0) {} + NVSDKENTRY Rect(int ix, int iy, int iw = 0, int ih = 0) : x(ix), y(iy), w(iw), h(ih) {} + NVSDKENTRY Rect(const Rect & r) : x(r.x), y(r.y), w(r.w), h(r.h) {} + + NVSDKENTRY const Rect& operator= (const Rect & r) { this->x = r.x; this->y = r.y; this->w = r.w; this->h = r.h; return *this; } + + int x, y; + int w, h; + + NVSDKENTRY static const Rect null; + }; + + enum ButtonFlags + { + ButtonFlags_Off = 0x0, + ButtonFlags_On = 0x1, + ButtonFlags_Begin = 0x2, + ButtonFlags_End = 0x4, + ButtonFlags_Shift = 0x8, + ButtonFlags_Alt = 0x10, + ButtonFlags_Ctrl = 0x20, + }; + + struct ButtonState + { + int state; + time_t time; + Point cursor; + }; + + // An enum to identify the mouse buttons + enum MouseButton + { + MouseButton_Left, + MouseButton_Middle, + MouseButton_Right, + }; + + // An enum to identify the special key buttons not translated with ASCII codes + enum Key + { + Key_F1 = 128, + Key_F2, + Key_F3, + Key_F4, + Key_F5, + Key_F6, + Key_F7, + Key_F8, + Key_F9, + Key_F10, + Key_F11, + Key_F12, + + Key_Left, + Key_Up, + Key_Right, + Key_Down, + Key_PageUp, + Key_PageDown, + Key_Home, + Key_End, + Key_Insert, + }; + + // The various flags to modify the behavior of the groups + enum GroupFlags + { + // Layout behavior flags + GroupFlags_LayoutNone = 0x01, + GroupFlags_LayoutVertical = 0x02, + GroupFlags_LayoutHorizontal = 0x04, + GroupFlags_LayoutMask = 0x07, + GroupFlags_LayoutXMask = 0xffff ^ GroupFlags_LayoutMask, + + // Alignment flags for the widgets inserted in the group + GroupFlags_AlignLeft = 0x10, + GroupFlags_AlignRight = 0x20, + GroupFlags_AlignTop = 0x40, + GroupFlags_AlignBottom = 0x80, + GroupFlags_AlignMask = 0xf0, + GroupFlags_AlignXMask = 0xffff ^ GroupFlags_AlignMask, + + // Start flags defining the starting origin of the group + GroupFlags_StartLeft = 0x100, + GroupFlags_StartRight = 0x200, + GroupFlags_StartTop = 0x400, + GroupFlags_StartBottom = 0x800, + GroupFlags_StartMask = 0xf00, + GroupFlags_StartXMask = 0xffff ^ GroupFlags_StartMask, + + // Optional flags + GroupFlags_LayoutForce = 0x8000, + GroupFlags_LayoutDefault = 0x4000, + GroupFlags_LayoutNoMargin = 0x2000, + GroupFlags_LayoutNoSpace = 0x1000, + + // Predefined configurations + GroupFlags_GrowRightFromBottom = GroupFlags_LayoutHorizontal | GroupFlags_StartLeft | GroupFlags_AlignLeft | GroupFlags_StartBottom | GroupFlags_AlignBottom , + GroupFlags_GrowRightFromTop = GroupFlags_LayoutHorizontal | GroupFlags_StartLeft | GroupFlags_AlignLeft | GroupFlags_StartTop | GroupFlags_AlignTop , + GroupFlags_GrowLeftFromBottom = GroupFlags_LayoutHorizontal | GroupFlags_StartRight | GroupFlags_AlignRight | GroupFlags_StartBottom | GroupFlags_AlignBottom, + GroupFlags_GrowLeftFromTop = GroupFlags_LayoutHorizontal | GroupFlags_StartRight | GroupFlags_AlignRight | GroupFlags_StartTop | GroupFlags_AlignTop, + GroupFlags_GrowUpFromLeft = GroupFlags_LayoutVertical | GroupFlags_StartBottom | GroupFlags_AlignBottom | GroupFlags_StartLeft | GroupFlags_AlignLeft , + GroupFlags_GrowUpFromRight = GroupFlags_LayoutVertical | GroupFlags_StartBottom | GroupFlags_AlignBottom | GroupFlags_StartRight | GroupFlags_AlignRight , + GroupFlags_GrowDownFromLeft = GroupFlags_LayoutVertical | GroupFlags_StartTop | GroupFlags_AlignTop | GroupFlags_StartLeft | GroupFlags_AlignLeft , + GroupFlags_GrowDownFromRight = GroupFlags_LayoutVertical | GroupFlags_StartTop | GroupFlags_AlignTop | GroupFlags_StartRight | GroupFlags_AlignRight , + + GroupFlags_LayoutDefaultFallback = GroupFlags_GrowDownFromLeft, + }; + + struct Group + { + Rect bounds; // anchor point + width and height of the region + int flags; // group behavior + int margin; // border + int space; // interior + }; + + //************************************************************************* + // UIPainter + class UIPainter + { + public: + NVSDKENTRY UIPainter() {} + + NVSDKENTRY virtual void begin( const Rect& window ) { init(); } + NVSDKENTRY virtual void end() {} + + // These methods should be called between begin/end + + NVSDKENTRY virtual void drawFrame(const Rect & r, int margin, int style) = 0; + + NVSDKENTRY virtual Rect getLabelRect(const Rect & r, const char * text, Rect & rt, int& nbLines) const = 0; + NVSDKENTRY virtual void drawLabel(const Rect & r, const char * text, const Rect & rt, const int& nbLines, bool isHover, int style) = 0; + + NVSDKENTRY virtual Rect getButtonRect(const Rect & r, const char * text, Rect & rt) const = 0; + NVSDKENTRY virtual void drawButton(const Rect & r, const char * text, const Rect & rt, bool isDown, bool isHover, bool isFocus, int style) = 0; + + NVSDKENTRY virtual Rect getCheckRect(const Rect & r, const char * text, Rect & rt, Rect & rc) const = 0; + NVSDKENTRY virtual void drawCheckButton(const Rect & r, const char * text, const Rect & rt, const Rect & rr, bool isChecked, bool isHover, bool isFocus, int style) = 0; + + NVSDKENTRY virtual Rect getRadioRect(const Rect & r, const char * text, Rect & rt, Rect & rr) const = 0; + NVSDKENTRY virtual void drawRadioButton(const Rect & r, const char * text, const Rect & rt, const Rect & rr, bool isOn, bool isHover, bool isFocus, int style) = 0; + + NVSDKENTRY virtual Rect getHorizontalSliderRect(const Rect & r, Rect& rs, float v, Rect& rc) const = 0; + NVSDKENTRY virtual void drawHorizontalSlider(const Rect & r, Rect& rs, float v, Rect& rc, bool isHover, int style) = 0; + + NVSDKENTRY virtual Rect getItemRect(const Rect & r, const char * text, Rect & rt) const = 0; + NVSDKENTRY virtual void drawListItem(const Rect & r, const char * text, const Rect & rt, bool isSelected, bool isHover, int style) = 0; + + NVSDKENTRY virtual Rect getListRect(const Rect & r, int numOptions, const char * options[], Rect& ri, Rect & rt) const = 0; + NVSDKENTRY virtual void drawListBox(const Rect & r, int numOptions, const char * options[], const Rect& ri, const Rect & rt, int selected, int hovered, int style) = 0; + + NVSDKENTRY virtual Rect getComboRect(const Rect & r, int numOptions, const char * options[], int selected, Rect& rt, Rect& ra) const = 0; + NVSDKENTRY virtual Rect getComboOptionsRect(const Rect & rCombo, int numOptions, const char * options[], Rect& ri, Rect & rit) const = 0; + NVSDKENTRY virtual void drawComboBox(const Rect & rect, int numOptions, const char * options[], const Rect & rt, const Rect & ra, int selected, bool isHover, bool isFocus, int style) = 0; + NVSDKENTRY virtual void drawComboOptions(const Rect & rect, int numOptions, const char * options[], const Rect& ri, const Rect & rit, int selected, int hovered, bool isHover, bool isFocus, int style) = 0; + + NVSDKENTRY virtual Rect getLineEditRect(const Rect & r, const char * text, Rect & rt) const = 0; + NVSDKENTRY virtual void drawLineEdit(const Rect & r, const char * text, const Rect & rt, int caretPos, bool isSelected, bool isHover, int style) = 0; + + NVSDKENTRY virtual Rect getPanelRect(const Rect & r, const char * text, Rect& rt, Rect& ra) const = 0; + NVSDKENTRY virtual void drawPanel(const Rect & rect, const char * text, const Rect & rt, const Rect & ra, bool isUnfold, bool isHover, bool isFocus, int style) = 0; + + NVSDKENTRY virtual Rect getTextureViewRect(const Rect & rect, Rect& rt) const = 0; + NVSDKENTRY virtual void drawTextureView(const Rect & rect, const void* texID, const Rect& rt, const Rect & rz, int mipLevel, int style) = 0; + + // Eval widget dimensions + NVSDKENTRY virtual int getCanvasMargin() const = 0; + NVSDKENTRY virtual int getCanvasSpace() const = 0; + NVSDKENTRY virtual int getFontHeight() const = 0; + NVSDKENTRY virtual int getTextLineWidth(const char * text) const = 0; + NVSDKENTRY virtual int getTextSize(const char * text, int& nbLines) const = 0; + NVSDKENTRY virtual int getPickedCharNb(const char * text, const Point& at) const = 0; + + NVSDKENTRY virtual void drawDebugRect(const Rect & r) = 0; + + protected: + + NVSDKENTRY void init() {} + }; + + + class UIContext + { + public: + NVSDKENTRY UIContext( UIPainter& painter ); + + // + // UI method for processing window size events + ////////////////////////////////////////////////////////////////// + NVSDKENTRY void reshape(int w, int h); + + // + // Check if the UI is currently on Focus + ////////////////////////////////////////////////////////////////// + NVSDKENTRY bool isOnFocus() const { return m_uiOnFocus; } + + // + // UI method for processing mouse events + ////////////////////////////////////////////////////////////////// + NVSDKENTRY void mouse(int button, int state, int modifier, int x, int y); + NVSDKENTRY void mouse(int button, int state, int x, int y) { mouse( button, state, 0, x, y); } + + // + // UI method for processing mouse motion events + ////////////////////////////////////////////////////////////////// + NVSDKENTRY void mouseMotion(int x, int y); + + // + // UI method for processing key events + ////////////////////////////////////////////////////////////////// + NVSDKENTRY void keyboard(unsigned char k, int x, int y); + + // + // UI method for entering UI processing mode + // + // This function must be used to begin the UI processing + ////////////////////////////////////////////////////////////////// + NVSDKENTRY void begin(); + + // + // UI method for leaving UI processing mode + // + // This function must be used to end the UI processing + ////////////////////////////////////////////////////////////////// + NVSDKENTRY void end(); + + //////////////////////////////////////////////////////////////////////////// + // + // UI element processing + // + // The following methods provide the interface for rendering and querying + // UI objects. These methods must be called between begin/end. + //////////////////////////////////////////////////////////////////////////// + + // + // UI method for drawing a static text label + // + // rect - optionally provides a location and size for the label + // text - Text to display for the label + ////////////////////////////////////////////////////////////////// + NVSDKENTRY void doLabel(const Rect & rect, const char * text, int style = 0); + + // + // UI method for rendering and processing a push button + // + // rect - optionally provides a location and size for the button + // text - text to display on the button + // state - whether the button is depressed + // if state is NULL, the buttoin behave like a touch button + // else, the button behave like a togle button + // style - optional style flag to modify the look + ////////////////////////////////////////////////////////////////// + NVSDKENTRY bool doButton(const Rect & rect, const char * text, bool * state = NULL, int style = 0); + + NVSDKENTRY bool doCheckButton(const Rect & rect, const char * text, bool * state, int style = 0); + + NVSDKENTRY bool doRadioButton(int reference, const Rect & r, const char * text, int * value, int style = 0); + + NVSDKENTRY bool doHorizontalSlider(const Rect & rect, float min, float max, float * value, int style = 0); + + NVSDKENTRY bool doListItem(int index, const Rect & rect, const char * text, int * selected, int style = 0); + NVSDKENTRY bool doListBox(const Rect & rect, int numOptions, const char * options[], int * selected, int style = 0); + NVSDKENTRY bool doComboBox(const Rect & rect, int numOptions, const char * options[], int * selected, int style = 0); + + NVSDKENTRY bool doLineEdit(const Rect & rect, char * text, int maxTextLength, int * nbCharsReturned, int style = 0); + + NVSDKENTRY void beginGroup(int groupFlags = GroupFlags_LayoutDefault, const Rect& rect = Rect::null); + NVSDKENTRY void endGroup(); + + NVSDKENTRY void beginFrame(int groupFlags = GroupFlags_LayoutDefault, const Rect& rect = Rect::null, int style = 0); + NVSDKENTRY void endFrame(); + + NVSDKENTRY bool beginPanel(Rect & rect, const char * text, bool * isUnfold, int groupFlags = GroupFlags_LayoutDefault, int style = 0); + NVSDKENTRY void endPanel(); + + NVSDKENTRY int getGroupWidth() { return m_groupStack[m_groupIndex].bounds.w; } + NVSDKENTRY int getGroupHeight() { return m_groupStack[m_groupIndex].bounds.h; } + + NVSDKENTRY int getCursorX() { return m_currentCursor.x;} + NVSDKENTRY int getCursorY() { return m_currentCursor.y;} + + NVSDKENTRY const ButtonState& getMouseState( int button) { return m_mouseButton[button]; } + + NVSDKENTRY void doTextureView(const Rect & rect, const void* texID, Rect & zoomRect, int mipLevel = 0, int style = 0); + + protected: + NVSDKENTRY UIPainter* getPainter() { return m_painter; } + + private: + NVSDKENTRY void setCursor(int x, int y); + + NVSDKENTRY static bool overlap(const Rect & rect, const Point & p); + + NVSDKENTRY bool hasFocus(const Rect & rect); + NVSDKENTRY bool isHover(const Rect & rect); + + NVSDKENTRY Rect placeRect(const Rect & r); + + private: + UIPainter * m_painter; + + int m_groupIndex; + Group m_groupStack[64]; + + Rect m_window; + + Point m_currentCursor; + ButtonState m_mouseButton[3]; + unsigned char m_keyBuffer[32]; + int m_nbKeys; + + int m_focusCaretPos; + Point m_focusPoint; + bool m_twoStepFocus; + bool m_uiOnFocus; + }; + +}; + + + + + +#endif // NV_WIDGETS_H diff --git a/external/cutil/inc/param.h b/external/cutil/inc/param.h new file mode 100644 index 0000000..6ffb5e8 --- /dev/null +++ b/external/cutil/inc/param.h @@ -0,0 +1,237 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + /* + Simple parameter system + sgreen@nvidia.com 4/2001 +*/ + +#ifndef PARAM_H +#define PARAM_H + +#include +#include +#include +#include +#include +#include + +// base class for named parameter +class ParamBase { +public: + ParamBase(const char *name) : m_name(name) { } + virtual ~ParamBase() { } + + std::string &GetName() { return m_name; } + + virtual float GetFloatValue() = 0; + virtual int GetIntValue() = 0; + virtual std::string GetValueString() = 0; + + virtual void Reset() = 0; + virtual void Increment() = 0; + virtual void Decrement() = 0; + + virtual float GetPercentage() = 0; + virtual void SetPercentage(float p) = 0; + + virtual void Write(std::ostream &stream) = 0; + virtual void Read(std::istream &stream) = 0; + + virtual bool IsList() = 0; + +protected: + std::string m_name; +}; + +// derived class for single-valued parameter +template class Param : public ParamBase { +public: + Param(const char *name, T value = 0, T min = 0, T max = 10000, T step = 1, T* ptr = 0) : + ParamBase(name), + m_default(value), + m_min(min), + m_max(max), + m_step(step), + m_precision(3) + { + if (ptr) { + m_ptr = ptr; + } else { + m_ptr = &m_value; + } + *m_ptr = value; + } + ~Param() { } + + T GetValue() const { return *m_ptr; } + T SetValue(const T value) { *m_ptr = value; } + + float GetFloatValue() { return (float) *m_ptr; } + int GetIntValue() { return (int) *m_ptr; } + + std::string GetValueString() + { + std::ostringstream ost; + ost< m_max) + *m_ptr = m_max; + } + + void Decrement() + { + *m_ptr -= m_step; + if (*m_ptr < m_min) + *m_ptr = m_min; + } + + void Write(std::ostream &stream) { stream << m_name << " " << *m_ptr << '\n'; } + void Read(std::istream &stream) { stream >> m_name >> *m_ptr; } + + bool IsList() { return false; } + +private: + T m_value; + T *m_ptr; // pointer to value declared elsewhere + T m_default, m_min, m_max, m_step; + int m_precision; // number of digits after decimal point in string output +}; + + +extern const Param dummy; + +// list of parameters +class ParamList : public ParamBase { +public: + ParamList(const char *name = "") : + ParamBase(name) + { + active = true; + } + ~ParamList() { } + + float GetFloatValue() { return 0.0f; } + int GetIntValue() { return 0; } + + void AddParam(ParamBase *param) + { + m_params.push_back(param); + m_map[param->GetName()] = param; + m_current = m_params.begin(); + } + + // look-up parameter based on name + ParamBase *GetParam(char *name) + { + ParamBase *p = m_map[name]; + + if (p) + return p; + else + return (ParamBase *) &dummy; + } + + ParamBase *GetParam(int i) + { + return m_params[i]; + } + + ParamBase *GetCurrent() + { + return *m_current; + } + + int GetSize() { return (int)m_params.size(); } + + std::string GetValueString() + { + return m_name; + } + + // functions to traverse list + void Reset() + { + m_current = m_params.begin(); + } + + void Increment() + { + m_current++; + if (m_current == m_params.end()) + m_current = m_params.begin(); + } + + void Decrement() + { + if (m_current == m_params.begin()) + m_current = m_params.end()-1; + else + m_current--; + + } + + float GetPercentage() { return 0.0f; } + void SetPercentage(float /*p*/) {} + + void Write(std::ostream &stream) + { + stream << m_name << '\n'; + for(std::vector::const_iterator p = m_params.begin(); p != m_params.end(); ++p) { + (*p)->Write(stream); + } + } + + void Read(std::istream &stream) + { + stream >> m_name; + for(std::vector::const_iterator p = m_params.begin(); p != m_params.end(); ++p) { + (*p)->Read(stream); + } + } + + bool IsList() { return true; } + + void ResetAll() + { + for(std::vector::const_iterator p = m_params.begin(); p != m_params.end(); ++p) { + (*p)->Reset(); + } + } + +protected: + bool active; + std::vector m_params; + std::map m_map; + std::vector::const_iterator m_current; +}; + +#endif diff --git a/external/cutil/inc/paramgl.h b/external/cutil/inc/paramgl.h new file mode 100644 index 0000000..7532f5e --- /dev/null +++ b/external/cutil/inc/paramgl.h @@ -0,0 +1,76 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + /* + ParamListGL + - class derived from ParamList to do simple OpenGL rendering of a parameter list + sgg 8/2001 +*/ + +#ifndef PARAMGL_H +#define PARAMGL_H + +#if defined(__APPLE__) || defined(MACOSX) +#include +#else +#include +#endif + +#include + +void beginWinCoords(); +void endWinCoords(); +void glPrint(int x, int y, const char *s, void *font); +void glPrintShadowed(int x, int y, const char *s, void *font, float *color); + +class ParamListGL : public ParamList { +public: + ParamListGL(const char *name = ""); + + void Render(int x, int y, bool shadow = false); + bool Mouse(int x, int y, int button=GLUT_LEFT_BUTTON, int state=GLUT_DOWN); + bool Motion(int x, int y); + void Special(int key, int x, int y); + + void SetFont(void *font, int height) { m_font = font; m_font_h = height; } + + void SetSelectedColor(float r, float g, float b) { m_text_color_selected = Color(r, g, b); } + void SetUnSelectedColor(float r, float g, float b) { m_text_color_unselected = Color(r, g, b); } + void SetBarColorInner(float r, float g, float b) { m_bar_color_inner = Color(r, g, b); } + void SetBarColorOuter(float r, float g, float b) { m_bar_color_outer = Color(r, g, b); } + +private: + void *m_font; + int m_font_h; // font height + + int m_bar_x; // bar start x position + int m_bar_w; // bar width + int m_bar_h; // bar height + int m_text_x; // text start x position + int m_separation; // bar separation in y + int m_value_x; // value text x position + int m_bar_offset; // bar offset in y + + int m_start_x, m_start_y; + + struct Color { + Color(float _r, float _g, float _b) { r = _r; g = _g; b = _b; } + float r, g, b; + }; + + Color m_text_color_selected; + Color m_text_color_unselected; + Color m_text_color_shadow; + Color m_bar_color_outer; + Color m_bar_color_inner; +}; + +#endif diff --git a/external/cutil/inc/rendercheck_d3d10.h b/external/cutil/inc/rendercheck_d3d10.h new file mode 100644 index 0000000..8f25be3 --- /dev/null +++ b/external/cutil/inc/rendercheck_d3d10.h @@ -0,0 +1,37 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +#pragma once + +#ifndef _RENDERCHECK_D3D10_H_ +#define _RENDERCHECK_D3D10_H_ + +#include +#include +#include +#include +#include +#include + +class CheckRenderD3D10 +{ +public: + + CheckRenderD3D10() {} + + static HRESULT ActiveRenderTargetToPPM(ID3D10Device *pDevice, const char *zFileName); + static HRESULT ResourceToPPM(ID3D10Device*pDevice, ID3D10Resource *pResource, const char *zFileName); + + static bool PPMvsPPM( const char *src_file, const char *ref_file, const char *exec_path, + const float epsilon, const float threshold = 0.0f ); +}; + +#endif \ No newline at end of file diff --git a/external/cutil/inc/rendercheck_d3d11.h b/external/cutil/inc/rendercheck_d3d11.h new file mode 100644 index 0000000..6b9afbd --- /dev/null +++ b/external/cutil/inc/rendercheck_d3d11.h @@ -0,0 +1,38 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + + +#pragma once + +#ifndef _RENDERCHECK_D3D11_H_ +#define _RENDERCHECK_D3D11_H_ + +#include +#include +#include +#include +#include +#include + +class CheckRenderD3D11 +{ +public: + + CheckRenderD3D11() {} + + static HRESULT ActiveRenderTargetToPPM(ID3D11Device *pDevice, const char *zFileName); + static HRESULT ResourceToPPM(ID3D11Device *pDevice, ID3D11Resource *pResource, const char *zFileName); + + static bool PPMvsPPM( const char *src_file, const char *ref_file, const char *exec_path, + const float epsilon, const float threshold = 0.0f ); +}; + +#endif \ No newline at end of file diff --git a/external/cutil/inc/rendercheck_d3d9.h b/external/cutil/inc/rendercheck_d3d9.h new file mode 100644 index 0000000..d0d2dbe --- /dev/null +++ b/external/cutil/inc/rendercheck_d3d9.h @@ -0,0 +1,36 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +#pragma once + +#ifndef _RENDERCHECK_D3D9_H_ +#define _RENDERCHECK_D3D9_H_ + +#include +#include +#include +#include +#include + +class CheckRenderD3D9 +{ +public: + + CheckRenderD3D9() {} + + static HRESULT BackbufferToPPM(IDirect3DDevice9*pDevice, const char *zFileName); + static HRESULT SurfaceToPPM(IDirect3DDevice9*pDevice, IDirect3DSurface9 *pSurface, const char *zFileName); + + static bool PPMvsPPM( const char *src_file, const char *ref_file, const char *exec_path, + const float epsilon, const float threshold = 0.0f ); +}; + +#endif \ No newline at end of file diff --git a/external/cutil/inc/rendercheck_gl.h b/external/cutil/inc/rendercheck_gl.h new file mode 100644 index 0000000..acf62d7 --- /dev/null +++ b/external/cutil/inc/rendercheck_gl.h @@ -0,0 +1,239 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +#ifndef _RENDERCHECK_GL_H_ +#define _RENDERCHECK_GL_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#if defined(__APPLE__) || defined(MACOSX) +#include +#else + #include +#endif + +#include + +using std::vector; +using std::map; +using std::string; + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#if _DEBUG +#define CHECK_FBO checkStatus(__FILE__, __LINE__, true) +#else +#define CHECK_FBO true +#endif + + + +class CheckRender +{ +public: + CheckRender(unsigned int width, unsigned int height, unsigned int Bpp, + bool bQAReadback, bool bUseFBO, bool bUsePBO); + + virtual ~CheckRender(); + + virtual void allocateMemory( unsigned int width, unsigned int height, unsigned int Bpp, + bool bQAReadback, bool bUseFBO, bool bUsePBO ); + + virtual void setExecPath(char *path) { + strcpy(m_ExecPath, path); + } + virtual void EnableQAReadback(bool bStatus) { m_bQAReadback = bStatus; } + virtual bool IsQAReadback() { return m_bQAReadback; } + virtual bool IsFBO() { return m_bUseFBO; } + virtual bool IsPBO() { return m_bUsePBO; } + virtual void * imageData() { return m_pImageData; } + + // Interface to this class functions + virtual void setPixelFormat(GLenum format) { m_PixelFormat = format; } + virtual int getPixelFormat() { return m_PixelFormat; } + virtual bool checkStatus(const char *zfile, int line, bool silent) = 0; + virtual bool readback( GLuint width, GLuint height ) = 0; + virtual bool readback( GLuint width, GLuint height, GLuint bufObject ) = 0; + virtual bool readback( GLuint width, GLuint height, unsigned char *membuf ) = 0; + + virtual void bindReadback(); + virtual void unbindReadback(); + + virtual void savePGM( const char *zfilename, bool bInvert, void **ppReadBuf ); + virtual void savePPM( const char *zfilename, bool bInvert, void **ppReadBuf ); + + virtual bool PGMvsPGM( const char *src_file, const char *ref_file, const float epsilon, const float threshold = 0.0f ); + virtual bool PPMvsPPM( const char *src_file, const char *ref_file, const float epsilon, const float threshold = 0.0f ); + + void setThresholdCompare(float value) { m_fThresholdCompare = value; } + + virtual void dumpBin(void *data, unsigned int bytes, const char *filename); + virtual bool compareBin2BinUint(const char *src_file, const char *ref_file, unsigned int nelements, const float epsilon, const float threshold); + virtual bool compareBin2BinFloat(const char *src_file, const char *ref_file, unsigned int nelements, const float epsilon, const float threshold); + +protected: + unsigned int m_Width, m_Height, m_Bpp; + unsigned char *m_pImageData; // This is the image data stored in system memory + bool m_bQAReadback, m_bUseFBO, m_bUsePBO; + GLuint m_pboReadback; + GLenum m_PixelFormat; + float m_fThresholdCompare; + char m_ExecPath[256]; +}; + + +class CheckBackBuffer : public CheckRender +{ +public: + CheckBackBuffer(unsigned int width, unsigned int height, unsigned int Bpp, bool bUseOpenGL = true); + virtual ~CheckBackBuffer(); + + virtual bool checkStatus(const char *zfile, int line, bool silent); + virtual bool readback( GLuint width, GLuint height ); + virtual bool readback( GLuint width, GLuint height, GLuint bufObject ); + virtual bool readback( GLuint width, GLuint height, unsigned char *membuf ); + +private: + virtual void bindFragmentProgram() {}; + virtual void bindRenderPath() {}; + virtual void unbindRenderPath() {}; + + // bind to the BackBuffer to Texture + virtual void bindTexture() {}; + + // release this bind + virtual void unbindTexture() {}; +}; + + +// structure defining the properties of a single buffer +struct bufferConfig { + string name; + GLenum format; + int bits; +}; + +// structures defining properties of an FBO +struct fboConfig { + string name; + GLenum colorFormat; + GLenum depthFormat; + int redbits; + int depthBits; + int depthSamples; + int coverageSamples; +}; + +struct fboData { + GLuint colorTex; //color texture + GLuint depthTex; //depth texture + GLuint fb; // render framebuffer + GLuint resolveFB; //multisample resolve target + GLuint colorRB; //color render buffer + GLuint depthRB; // depth render buffer +}; + + +class CFrameBufferObject +{ +public: + CFrameBufferObject (unsigned int width, unsigned int height, unsigned int Bpp, bool bUseFloat, GLenum eTarget); + + virtual ~CFrameBufferObject(); + + GLuint createTexture(GLenum target, int w, int h, GLint internalformat, GLenum format); + void attachTexture( GLenum texTarget, + GLuint texId, + GLenum attachment = GL_COLOR_ATTACHMENT0_EXT, + int mipLevel = 0, + int zSlice = 0); + + bool initialize(unsigned width, unsigned height, fboConfig & rConfigFBO, fboData & rActiveFBO); + bool create( GLuint width, GLuint height, fboConfig &config, fboData &data ); + bool createMSAA( GLuint width, GLuint height, fboConfig *p_config, fboData *p_data ); + bool createCSAA( GLuint width, GLuint height, fboConfig *p_config, fboData *p_data ); + + virtual void freeResources(); + virtual bool checkStatus(const char *zfile, int line, bool silent); + + virtual void renderQuad(int width, int height, GLenum eTarget); + + // bind to the Fragment Program + void bindFragmentProgram() { + glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_textureProgram); + glEnable(GL_FRAGMENT_PROGRAM_ARB); + } + + // bind to the FrameBuffer Object + void bindRenderPath() { + glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_fboData.fb ); + } + + // release current FrameBuffer Object + void unbindRenderPath() { + glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); + } + + // bind to the FBO to Texture + void bindTexture() { + glBindTexture( m_eGLTarget, m_fboData.colorTex ); + } + + // release this bind + void unbindTexture() { + glBindTexture( m_eGLTarget, 0 ); + } + + GLuint getFbo() { return m_fboData.fb; } + GLuint getTex() { return m_fboData.colorTex; } + GLuint getDepthTex() { return m_fboData.depthTex; } + +private: + GLuint m_Width, m_Height; + fboData m_fboData; + fboConfig m_fboConfig; + + GLuint m_textureProgram; + GLuint m_overlayProgram; + + bool m_bUseFloat; + GLenum m_eGLTarget; +}; + + +// CheckFBO - render and verify contents of the FBO +class CheckFBO: public CheckRender +{ +public: + CheckFBO(unsigned int width, unsigned int height, unsigned int Bpp); + CheckFBO(unsigned int width, unsigned int height, unsigned int Bpp, CFrameBufferObject *pFrameBufferObject); + + virtual ~CheckFBO(); + + virtual bool checkStatus(const char *zfile, int line, bool silent); + virtual bool readback( GLuint width, GLuint height ); + virtual bool readback( GLuint width, GLuint height, GLuint bufObject ); + virtual bool readback( GLuint width, GLuint height, unsigned char *membuf ); + +private: + CFrameBufferObject *m_pFrameBufferObject; +}; + +#endif // _RENDERCHECK_GL_H_ + diff --git a/external/cutil/inc/sdkHelper.h b/external/cutil/inc/sdkHelper.h new file mode 100644 index 0000000..0729f8a --- /dev/null +++ b/external/cutil/inc/sdkHelper.h @@ -0,0 +1,760 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +// These are helper functions for the SDK samples (string parsing, timers, etc) +#ifndef SDK_HELPER_H +#define SDK_HELPER_H + +#ifdef WIN32 +#pragma warning(disable:4996) +#endif + +// includes, project +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +// includes, timer +#include +#include + +#ifndef MIN +#define MIN(a,b) ((a < b) ? a : b) +#endif +#ifndef MAX +#define MAX(a,b) ((a > b) ? a : b) +#endif + +// Beginning of GPU Architecture definitions +inline int _ConvertSMVer2Cores(int major, int minor) +{ + // Defines for GPU Architecture types (using the SM version to determine the # of cores per SM + typedef struct { + int SM; // 0xMm (hexidecimal notation), M = SM Major version, and m = SM minor version + int Cores; + } sSMtoCores; + + sSMtoCores nGpuArchCoresPerSM[] = + { { 0x10, 8 }, // Tesla Generation (SM 1.0) G80 class + { 0x11, 8 }, // Tesla Generation (SM 1.1) G8x class + { 0x12, 8 }, // Tesla Generation (SM 1.2) G9x class + { 0x13, 8 }, // Tesla Generation (SM 1.3) GT200 class + { 0x20, 32 }, // Fermi Generation (SM 2.0) GF100 class + { 0x21, 48 }, // Fermi Generation (SM 2.1) GF10x class + { -1, -1 } + }; + + int index = 0; + while (nGpuArchCoresPerSM[index].SM != -1) { + if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor) ) { + return nGpuArchCoresPerSM[index].Cores; + } + index++; + } + printf("MapSMtoCores undefined SM %d.%d is undefined (please update to the latest SDK)!\n", major, minor); + return -1; +} +// end of GPU Architecture definitions + +// namespace unnamed (internal) +namespace +{ + //! size of PGM file header + const unsigned int PGMHeaderSize = 0x40; + + // types + + //! Data converter from unsigned char / unsigned byte to type T + template + struct ConverterFromUByte; + + //! Data converter from unsigned char / unsigned byte + template<> + struct ConverterFromUByte + { + //! Conversion operator + //! @return converted value + //! @param val value to convert + float operator()( const unsigned char& val) + { + return static_cast(val); + } + }; + + //! Data converter from unsigned char / unsigned byte to float + template<> + struct ConverterFromUByte + { + //! Conversion operator + //! @return converted value + //! @param val value to convert + float operator()( const unsigned char& val) + { + return static_cast( val) / 255.0f; + } + }; + + //! Data converter from unsigned char / unsigned byte to type T + template + struct ConverterToUByte; + + //! Data converter from unsigned char / unsigned byte to unsigned int + template<> + struct ConverterToUByte + { + //! Conversion operator (essentially a passthru + //! @return converted value + //! @param val value to convert + unsigned char operator()( const unsigned char& val) + { + return val; + } + }; + + //! Data converter from unsigned char / unsigned byte to unsigned int + template<> + struct ConverterToUByte + { + //! Conversion operator + //! @return converted value + //! @param val value to convert + unsigned char operator()( const float& val) + { + return static_cast( val * 255.0f); + } + }; +} + +#ifdef _WIN32 + #define FOPEN(fHandle,filename,mode) fopen_s(&fHandle, filename, mode) + #define FOPEN_FAIL(result) (result != 0) + #define SSCANF sscanf_s +#else + #define FOPEN(fHandle,filename,mode) (fHandle = fopen(filename, mode)) + #define FOPEN_FAIL(result) (result == NULL) + #define SSCANF sscanf +#endif + +inline bool +__loadPPM( const char* file, unsigned char** data, + unsigned int *w, unsigned int *h, unsigned int *channels ) +{ + FILE *fp = NULL; + if( FOPEN_FAIL(FOPEN(fp, file, "rb")) ) + { + std::cerr << "__LoadPPM() : Failed to open file: " << file << std::endl; + return false; + } + + // check header + char header[PGMHeaderSize]; + if (fgets( header, PGMHeaderSize, fp) == NULL) { + std::cerr << "__LoadPPM() : reading PGM header returned NULL" << std::endl; + return false; + } + if (strncmp(header, "P5", 2) == 0) + { + *channels = 1; + } + else if (strncmp(header, "P6", 2) == 0) + { + *channels = 3; + } + else { + std::cerr << "__LoadPPM() : File is not a PPM or PGM image" << std::endl; + *channels = 0; + return false; + } + + // parse header, read maxval, width and height + unsigned int width = 0; + unsigned int height = 0; + unsigned int maxval = 0; + unsigned int i = 0; + while(i < 3) + { + if (fgets(header, PGMHeaderSize, fp) == NULL) { + std::cerr << "__LoadPPM() : reading PGM header returned NULL" << std::endl; + return false; + } + if(header[0] == '#') + continue; + + if(i == 0) + { + i += SSCANF( header, "%u %u %u", &width, &height, &maxval); + } + else if (i == 1) + { + i += SSCANF( header, "%u %u", &height, &maxval); + } + else if (i == 2) + { + i += SSCANF(header, "%u", &maxval); + } + } + + // check if given handle for the data is initialized + if( NULL != *data) + { + if (*w != width || *h != height) + { + std::cerr << "__LoadPPM() : Invalid image dimensions." << std::endl; + } + } + else + { + *data = (unsigned char*) malloc( sizeof( unsigned char) * width * height * *channels); + *w = width; + *h = height; + } + + // read and close file + if (fread( *data, sizeof(unsigned char), width * height * *channels, fp) == 0) { + std::cerr << "__LoadPPM() read data returned error." << std::endl; + } + fclose(fp); + + return true; +} + +template +inline bool +sdkLoadPGM( const char* file, T** data, unsigned int *w, unsigned int *h) +{ + unsigned char* idata = NULL; + unsigned int channels; + if( true != __loadPPM(file, &idata, w, h, &channels)) + { + return false; + } + + unsigned int size = *w * *h * channels; + + // initialize mem if necessary + // the correct size is checked / set in loadPGMc() + if( NULL == *data) + { + *data = (T*) malloc( sizeof(T) * size ); + } + + // copy and cast data + std::transform( idata, idata + size, *data, ConverterFromUByte()); + + free( idata ); + + return true; +} + +template +inline bool +sdkLoadPPM4( const char* file, T** data, + unsigned int *w,unsigned int *h) +{ + unsigned char *idata = 0; + unsigned int channels; + + if (__loadPPM( file, &idata, w, h, &channels)) { + // pad 4th component + int size = *w * *h; + // keep the original pointer + unsigned char* idata_orig = idata; + *data = (T*) malloc( sizeof(T) * size * 4); + unsigned char *ptr = *data; + for(int i=0; i 0); + assert( h > 0); + + std::fstream fh( file, std::fstream::out | std::fstream::binary ); + if( fh.bad()) + { + std::cerr << "__savePPM() : Opening file failed." << std::endl; + return false; + } + + if (channels == 1) + { + fh << "P5\n"; + } + else if (channels == 3) { + fh << "P6\n"; + } + else { + std::cerr << "__savePPM() : Invalid number of channels." << std::endl; + return false; + } + + fh << w << "\n" << h << "\n" << 0xff << std::endl; + + for( unsigned int i = 0; (i < (w*h*channels)) && fh.good(); ++i) + { + fh << data[i]; + } + fh.flush(); + + if( fh.bad()) + { + std::cerr << "__savePPM() : Writing data failed." << std::endl; + return false; + } + fh.close(); + + return true; +} + +template +inline bool +sdkSavePGM( const char* file, T *data, unsigned int w, unsigned int h) +{ + unsigned int size = w * h; + unsigned char* idata = + (unsigned char*) malloc( sizeof(unsigned char) * size); + + std::transform( data, data + size, idata, ConverterToUByte()); + + // write file + bool result = __savePPM(file, idata, w, h, 1); + + // cleanup + free( idata ); + + return result; +} + +inline bool +sdkSavePPM4ub( const char* file, unsigned char *data, + unsigned int w, unsigned int h) +{ + // strip 4th component + int size = w * h; + unsigned char *ndata = (unsigned char*) malloc( sizeof(unsigned char) * size*3); + unsigned char *ptr = ndata; + for(int i=0; i +inline bool +sdkWriteFile( const char* filename, const T* data, unsigned int len, + const S epsilon, bool verbose) +{ + assert( NULL != filename); + assert( NULL != data); + + // open file for writing + std::fstream fh( filename, std::fstream::out); + // check if filestream is valid + if( ! fh.good()) + { + if (verbose) + std::cerr << "cutWriteFile() : Opening file failed." << std::endl; + return false; + } + + // first write epsilon + fh << "# " << epsilon << "\n"; + + // write data + for( unsigned int i = 0; (i < len) && (fh.good()); ++i) + { + fh << data[i] << ' '; + } + + // Check if writing succeeded + if( ! fh.good()) + { + if (verbose) + std::cerr << "cutWriteFile() : Writing file failed." << std::endl; + return false; + } + + // file ends with nl + fh << std::endl; + + return true; +} + +////////////////////////////////////////////////////////////////////////////// +//! Compare two arrays of arbitrary type +//! @return true if \a reference and \a data are identical, otherwise false +//! @param reference timer_interface to the reference data / gold image +//! @param data handle to the computed data +//! @param len number of elements in reference and data +//! @param epsilon epsilon to use for the comparison +////////////////////////////////////////////////////////////////////////////// +template +inline bool +compareData( const T* reference, const T* data, const unsigned int len, + const S epsilon, const float threshold) +{ + assert( epsilon >= 0); + + bool result = true; + unsigned int error_count = 0; + + for( unsigned int i = 0; i < len; ++i) { + float diff = (float)reference[i] - (float)data[i]; + bool comp = (diff <= epsilon) && (diff >= -epsilon); + result &= comp; + + error_count += !comp; + +#ifdef _DEBUG + if( ! comp) + { + std::cerr << "ERROR, i = " << i << ",\t " + << reference[i] << " / " + << data[i] + << " (reference / data)\n"; + } +#endif + } + + if (threshold == 0.0f) { + return (result) ? true : false; + } else { + if (error_count) { + printf("%4.2f(%%) of bytes mismatched (count=%d)\n", (float)error_count*100/(float)len, error_count); + } + return (len*threshold > error_count) ? true : false; + } +} + +#ifndef __MIN_EPSILON_ERROR +#define __MIN_EPSILON_ERROR 1e-3f +#endif + +////////////////////////////////////////////////////////////////////////////// +//! Compare two arrays of arbitrary type +//! @return true if \a reference and \a data are identical, otherwise false +//! @param reference handle to the reference data / gold image +//! @param data handle to the computed data +//! @param len number of elements in reference and data +//! @param epsilon epsilon to use for the comparison +//! @param epsilon threshold % of (# of bytes) for pass/fail +////////////////////////////////////////////////////////////////////////////// +template +inline bool +compareDataAsFloatThreshold( const T* reference, const T* data, const unsigned int len, + const S epsilon, const float threshold) +{ + assert( epsilon >= 0); + + // If we set epsilon to be 0, let's set a minimum threshold + float max_error = MAX( (float)epsilon, __MIN_EPSILON_ERROR ); + int error_count = 0; + bool result = true; + + for( unsigned int i = 0; i < len; ++i) { + float diff = fabs((float)reference[i] - (float)data[i]); + bool comp = (diff < max_error); + result &= comp; + + if( ! comp) + { + error_count++; +#ifdef _DEBUG + if (error_count < 50) { + printf("\n ERROR(epsilon=%4.3f), i=%d, (ref)0x%02x / (data)0x%02x / (diff)%d\n", + max_error, i, + *(unsigned int *)&reference[i], + *(unsigned int *)&data[i], + (unsigned int)diff); + } +#endif + } + } + + if (threshold == 0.0f) { + if (error_count) { + printf("total # of errors = %d\n", error_count); + } + return (error_count == 0) ? true : false; + } else { + if (error_count) { + printf("%4.2f(%%) of bytes mismatched (count=%d)\n", (float)error_count*100/(float)len, error_count); + } + return ((len*threshold > error_count) ? true : false); + } +} + +inline bool +sdkCompareL2fe( const float* reference, const float* data, + const unsigned int len, const float epsilon ) +{ + assert( epsilon >= 0); + + float error = 0; + float ref = 0; + + for( unsigned int i = 0; i < len; ++i) { + + float diff = reference[i] - data[i]; + error += diff * diff; + ref += reference[i] * reference[i]; + } + + float normRef = sqrtf(ref); + if (fabs(ref) < 1e-7) { +#ifdef _DEBUG + std::cerr << "ERROR, reference l2-norm is 0\n"; +#endif + return false; + } + float normError = sqrtf(error); + error = normError / normRef; + bool result = error < epsilon; +#ifdef _DEBUG + if( ! result) + { + std::cerr << "ERROR, l2-norm error " + << error << " is greater than epsilon " << epsilon << "\n"; + } +#endif + + return result; +} + +inline bool +sdkLoadPPMub( const char* file, unsigned char** data, + unsigned int *w,unsigned int *h) +{ + unsigned int channels; + return __loadPPM( file, data, w, h, &channels); +} + +inline bool +sdkLoadPPM4ub( const char* file, unsigned char** data, + unsigned int *w, unsigned int *h) +{ + unsigned char *idata = 0; + unsigned int channels; + + if (__loadPPM( file, &idata, w, h, &channels)) { + // pad 4th component + int size = *w * *h; + // keep the original pointer + unsigned char* idata_orig = idata; + *data = (unsigned char*) malloc( sizeof(unsigned char) * size * 4); + unsigned char *ptr = *data; + for(int i=0; i Compare (a)rendered: <" << src_file << ">\n"; + std::cerr << "> (b)reference: <" << ref_file << ">\n"; + } + + + if (sdkLoadPPM4ub(ref_file, &ref_data, &ref_width, &ref_height) != true) + { + if(verboseErrors) std::cerr << "PPMvsPPM: unable to load ref image file: "<< ref_file << "\n"; + return false; + } + + if (sdkLoadPPM4ub(src_file, &src_data, &src_width, &src_height) != true) + { + std::cerr << "PPMvsPPM: unable to load src image file: " << src_file << "\n"; + return false; + } + + if(src_height != ref_height || src_width != ref_width) + { + if(verboseErrors) std::cerr << "PPMvsPPM: source and ref size mismatch (" << src_width << + "," << src_height << ")vs(" << ref_width << "," << ref_height << ")\n"; + } + + if(verboseErrors) std::cerr << "PPMvsPPM: comparing images size (" << src_width << + "," << src_height << ") epsilon(" << epsilon << "), threshold(" << threshold*100 << "%)\n"; + + if (compareData( ref_data, src_data, src_width*src_height*4, epsilon, threshold ) == false) + { + error_count=1; + } + + if (error_count == 0) { + if(verboseErrors) std::cerr << " OK\n\n"; + } else { + if(verboseErrors) std::cerr << " FAILURE! "<start(); + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Stop the time with name \a name. Does not reset. +//! @param name name of the timer to stop +//////////////////////////////////////////////////////////////////////////////// +inline bool +sdkStopTimer( StopWatchInterface **timer_interface ) +{ + if (*timer_interface) (*timer_interface)->stop(); + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Resets the timer's counter. +//! @param name name of the timer to reset. +//////////////////////////////////////////////////////////////////////////////// +inline bool +sdkResetTimer( StopWatchInterface **timer_interface ) +{ + if (*timer_interface) (*timer_interface)->reset(); + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Return the average time for timer execution as the total time +//! for the timer dividied by the number of completed (stopped) runs the timer +//! has made. +//! Excludes the current running time if the timer is currently running. +//! @param name name of the timer to return the time of +//////////////////////////////////////////////////////////////////////////////// +inline float +sdkGetAverageTimerValue( StopWatchInterface **timer_interface ) +{ + if (*timer_interface) + return (*timer_interface)->getAverageTime(); + else + return 0.0f; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Total execution time for the timer over all runs since the last reset +//! or timer creation. +//! @param name name of the timer to obtain the value of. +//////////////////////////////////////////////////////////////////////////////// +inline float +sdkGetTimerValue( StopWatchInterface **timer_interface ) +{ + if (*timer_interface) + return (*timer_interface)->getTime(); + else + return 0.0f; +} + +#endif // SDK_HELPER_H diff --git a/external/cutil/inc/stopwatch.h b/external/cutil/inc/stopwatch.h new file mode 100644 index 0000000..16df38c --- /dev/null +++ b/external/cutil/inc/stopwatch.h @@ -0,0 +1,45 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +/* CUda UTility Library */ + +#ifndef _STOPWATCH_H_ +#define _STOPWATCH_H_ + +// stop watch base class +#include + +// include OS specific policy +#ifdef _WIN32 +# include +typedef StopWatchWin OSStopWatch; +#else +# include +typedef StopWatchLinux OSStopWatch; +#endif + +// concrete stop watch type +typedef StopWatchBase StopWatchC; + +namespace StopWatch +{ +//! Create a stop watch +const unsigned int create(); + +//! Get a handle to the stop watch with the name \a name +StopWatchC& get( const unsigned int& name); + +// Delete the stop watch with the name \a name +void destroy( const unsigned int& name); +} // end namespace, stopwatch + +#endif // _STOPWATCH_H_ + diff --git a/external/cutil/inc/stopwatch_base.h b/external/cutil/inc/stopwatch_base.h new file mode 100644 index 0000000..7b23a7b --- /dev/null +++ b/external/cutil/inc/stopwatch_base.h @@ -0,0 +1,76 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +/* CUda UTility Library */ + +#ifndef _STOPWATCH_BASE_H_ +#define _STOPWATCH_BASE_H_ + +// includes, system +#include + +//! Simple stop watch +template +class StopWatchBase : public OSPolicy +{ +public: + + // generic, specialized type + typedef StopWatchBase SelfType; + // generic, specialized type pointer + typedef StopWatchBase* SelfTypePtr; + + //! global index for all stop watches + static std::vector< SelfTypePtr > swatches; + +public: + + //! Constructor, default + StopWatchBase(); + + // Destructor + ~StopWatchBase(); + +public: + + //! Start time measurement + inline void start(); + + //! Stop time measurement + inline void stop(); + + //! Reset time counters to zero + inline void reset(); + + //! Time in msec. after start. If the stop watch is still running (i.e. there + //! was no call to stop()) then the elapsed time is returned, otherwise the + //! time between the last start() and stop call is returned + inline float getTime(); + + //! Mean time to date based on the number of times the stopwatch has been + //! _stopped_ (ie finished sessions) and the current total time + inline float getAverageTime(); + +private: + + //! Constructor, copy (not implemented) + StopWatchBase( const StopWatchBase&); + + //! Assignment operator (not implemented) + StopWatchBase& operator=( const StopWatchBase&); +}; + +// include, implementation +#include + + +#endif // _STOPWATCH_BASE_H_ + diff --git a/external/cutil/inc/stopwatch_base.inl b/external/cutil/inc/stopwatch_base.inl new file mode 100644 index 0000000..ad5c29a --- /dev/null +++ b/external/cutil/inc/stopwatch_base.inl @@ -0,0 +1,81 @@ +/* +* Copyright 1993-2010 NVIDIA Corporation. All rights reserved. +* +* Please refer to the NVIDIA end user license agreement (EULA) associated +* with this source code for terms and conditions that govern your use of +* this software. Any use, reproduction, disclosure, or distribution of +* this software and related documentation outside the terms of the EULA +* is strictly prohibited. +* +*/ + +/* CUda UTility Library */ + +//////////////////////////////////////////////////////////////////////////////// +//! Constructor, default +//////////////////////////////////////////////////////////////////////////////// +template +StopWatchBase::StopWatchBase() : +OSPolicy() +{ } + +//////////////////////////////////////////////////////////////////////////////// +//! Destructor +//////////////////////////////////////////////////////////////////////////////// +template +StopWatchBase::~StopWatchBase() { } + +/////////////////////////////////////////////////////////////////////////////// +//! Start time measurement +//////////////////////////////////////////////////////////////////////////////// +template +inline void +StopWatchBase::start() +{ + OSPolicy::start(); +} + +//////////////////////////////////////////////////////////////////////////////// +//! Stop time measurement +//////////////////////////////////////////////////////////////////////////////// +template +inline void +StopWatchBase::stop() +{ + OSPolicy::stop(); +} + + +//////////////////////////////////////////////////////////////////////////////// +//! Reset the timer to 0. Does not change the timer running state but does +//! recapture this point in time as the current start time if it is running. +//////////////////////////////////////////////////////////////////////////////// +template +inline void +StopWatchBase::reset() +{ + OSPolicy::reset(); +} + +//////////////////////////////////////////////////////////////////////////////// +//! Time in msec. after start. If the stop watch is still running (i.e. there +//! was no call to stop()) then the elapsed time is returned, otherwise the +//! time between the last start() and stop call is returned +//////////////////////////////////////////////////////////////////////////////// +template +inline float +StopWatchBase::getTime() +{ + return OSPolicy::getTime(); +} + +//////////////////////////////////////////////////////////////////////////////// +//! Time in msec. for a single run based on the total number of COMPLETED runs +//! and the total time. +//////////////////////////////////////////////////////////////////////////////// +template +inline float +StopWatchBase::getAverageTime() +{ + return OSPolicy::getAverageTime(); +} diff --git a/external/cutil/inc/stopwatch_functions.h b/external/cutil/inc/stopwatch_functions.h new file mode 100644 index 0000000..653c1de --- /dev/null +++ b/external/cutil/inc/stopwatch_functions.h @@ -0,0 +1,357 @@ +/* + * Copyright 1993-2011 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +/* Stopwatch Timing Functions (this is the inlined version compared to the CUTIL version) */ + +#ifndef STOPWATCH_FUNCTIONS_H +#define STOPWATCH_FUNCTIONS_H + +// includes, system +#include + +// includes, project +#include + +// Definition of the StopWatch Interface, this is used if we don't want to use the CUT functions +// But rather in a self contained class interface +class StopWatchInterface +{ +public: + StopWatchInterface() {}; + virtual ~StopWatchInterface() {}; + +public: + //! Start time measurement + virtual void start() = 0; + + //! Stop time measurement + virtual void stop() = 0; + + //! Reset time counters to zero + virtual void reset() = 0; + + //! Time in msec. after start. If the stop watch is still running (i.e. there + //! was no call to stop()) then the elapsed time is returned, otherwise the + //! time between the last start() and stop call is returned + virtual float getTime() = 0; + + //! Mean time to date based on the number of times the stopwatch has been + //! _stopped_ (ie finished sessions) and the current total time + virtual float getAverageTime() = 0; +}; + + +////////////////////////////////////////////////////////////////// +// Begin Stopwatch timer class definitions for all OS platforms // +////////////////////////////////////////////////////////////////// +#ifdef _WIN32 + // includes, system + #define WINDOWS_LEAN_AND_MEAN + #include + #undef min + #undef max + + //! Windows specific implementation of StopWatch + class StopWatchWin : public StopWatchInterface + { + public: + //! Constructor, default + StopWatchWin() : + start_time(), end_time(), + diff_time(0.0f), total_time(0.0f), + running( false ), clock_sessions(0), freq_set(false) + { + if( ! freq_set) { + // helper variable + LARGE_INTEGER temp; + + // get the tick frequency from the OS + QueryPerformanceFrequency((LARGE_INTEGER*) &temp); + + // convert to type in which it is needed + freq = ((double) temp.QuadPart) / 1000.0; + + // rememeber query + freq_set = true; + } + }; + + // Destructor + ~StopWatchWin() { }; + + public: + //! Start time measurement + inline void start(); + + //! Stop time measurement + inline void stop(); + + //! Reset time counters to zero + inline void reset(); + + //! Time in msec. after start. If the stop watch is still running (i.e. there + //! was no call to stop()) then the elapsed time is returned, otherwise the + //! time between the last start() and stop call is returned + inline float getTime(); + + //! Mean time to date based on the number of times the stopwatch has been + //! _stopped_ (ie finished sessions) and the current total time + inline float getAverageTime(); + + private: + // member variables + + //! Start of measurement + LARGE_INTEGER start_time; + //! End of measurement + LARGE_INTEGER end_time; + + //! Time difference between the last start and stop + float diff_time; + + //! TOTAL time difference between starts and stops + float total_time; + + //! flag if the stop watch is running + bool running; + + //! Number of times clock has been started + //! and stopped to allow averaging + int clock_sessions; + + //! tick frequency + double freq; + + //! flag if the frequency has been set + bool freq_set; + }; + + // functions, inlined + + //////////////////////////////////////////////////////////////////////////////// + //! Start time measurement + //////////////////////////////////////////////////////////////////////////////// + inline void + StopWatchWin::start() + { + QueryPerformanceCounter((LARGE_INTEGER*) &start_time); + running = true; + } + + //////////////////////////////////////////////////////////////////////////////// + //! Stop time measurement and increment add to the current diff_time summation + //! variable. Also increment the number of times this clock has been run. + //////////////////////////////////////////////////////////////////////////////// + inline void + StopWatchWin::stop() + { + QueryPerformanceCounter((LARGE_INTEGER*) &end_time); + diff_time = (float) + (((double) end_time.QuadPart - (double) start_time.QuadPart) / freq); + + total_time += diff_time; + clock_sessions++; + running = false; + } + + //////////////////////////////////////////////////////////////////////////////// + //! Reset the timer to 0. Does not change the timer running state but does + //! recapture this point in time as the current start time if it is running. + //////////////////////////////////////////////////////////////////////////////// + inline void + StopWatchWin::reset() + { + diff_time = 0; + total_time = 0; + clock_sessions = 0; + if( running ) + QueryPerformanceCounter((LARGE_INTEGER*) &start_time); + } + + + //////////////////////////////////////////////////////////////////////////////// + //! Time in msec. after start. If the stop watch is still running (i.e. there + //! was no call to stop()) then the elapsed time is returned added to the + //! current diff_time sum, otherwise the current summed time difference alone + //! is returned. + //////////////////////////////////////////////////////////////////////////////// + inline float + StopWatchWin::getTime() + { + // Return the TOTAL time to date + float retval = total_time; + if(running) + { + LARGE_INTEGER temp; + QueryPerformanceCounter((LARGE_INTEGER*) &temp); + retval += (float) + (((double) (temp.QuadPart - start_time.QuadPart)) / freq); + } + + return retval; + } + + //////////////////////////////////////////////////////////////////////////////// + //! Time in msec. for a single run based on the total number of COMPLETED runs + //! and the total time. + //////////////////////////////////////////////////////////////////////////////// + inline float + StopWatchWin::getAverageTime() + { + return (clock_sessions > 0) ? (total_time/clock_sessions) : 0.0f; + } +#else + // Declarations for Stopwatch on Linux and Mac OSX + // includes, system + #include + #include + + //! Windows specific implementation of StopWatch + class StopWatchLinux : public StopWatchInterface + { + public: + //! Constructor, default + StopWatchLinux() : + start_time(), diff_time( 0.0), total_time(0.0), + running( false ), clock_sessions(0) + { }; + + // Destructor + virtual ~StopWatchLinux() + { }; + + public: + //! Start time measurement + inline void start(); + + //! Stop time measurement + inline void stop(); + + //! Reset time counters to zero + inline void reset(); + + //! Time in msec. after start. If the stop watch is still running (i.e. there + //! was no call to stop()) then the elapsed time is returned, otherwise the + //! time between the last start() and stop call is returned + inline float getTime(); + + //! Mean time to date based on the number of times the stopwatch has been + //! _stopped_ (ie finished sessions) and the current total time + inline float getAverageTime(); + + private: + + // helper functions + + //! Get difference between start time and current time + inline float getDiffTime(); + + private: + + // member variables + + //! Start of measurement + struct timeval start_time; + + //! Time difference between the last start and stop + float diff_time; + + //! TOTAL time difference between starts and stops + float total_time; + + //! flag if the stop watch is running + bool running; + + //! Number of times clock has been started + //! and stopped to allow averaging + int clock_sessions; + }; + + // functions, inlined + + //////////////////////////////////////////////////////////////////////////////// + //! Start time measurement + //////////////////////////////////////////////////////////////////////////////// + inline void + StopWatchLinux::start() { + gettimeofday( &start_time, 0); + running = true; + } + + //////////////////////////////////////////////////////////////////////////////// + //! Stop time measurement and increment add to the current diff_time summation + //! variable. Also increment the number of times this clock has been run. + //////////////////////////////////////////////////////////////////////////////// + inline void + StopWatchLinux::stop() { + diff_time = getDiffTime(); + total_time += diff_time; + running = false; + clock_sessions++; + } + + //////////////////////////////////////////////////////////////////////////////// + //! Reset the timer to 0. Does not change the timer running state but does + //! recapture this point in time as the current start time if it is running. + //////////////////////////////////////////////////////////////////////////////// + inline void + StopWatchLinux::reset() + { + diff_time = 0; + total_time = 0; + clock_sessions = 0; + if( running ) + gettimeofday( &start_time, 0); + } + + //////////////////////////////////////////////////////////////////////////////// + //! Time in msec. after start. If the stop watch is still running (i.e. there + //! was no call to stop()) then the elapsed time is returned added to the + //! current diff_time sum, otherwise the current summed time difference alone + //! is returned. + //////////////////////////////////////////////////////////////////////////////// + inline float + StopWatchLinux::getTime() + { + // Return the TOTAL time to date + float retval = total_time; + if( running) { + retval += getDiffTime(); + } + + return retval; + } + + //////////////////////////////////////////////////////////////////////////////// + //! Time in msec. for a single run based on the total number of COMPLETED runs + //! and the total time. + //////////////////////////////////////////////////////////////////////////////// + inline float + StopWatchLinux::getAverageTime() + { + return (clock_sessions > 0) ? (total_time/clock_sessions) : 0.0f; + } + //////////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////////// + inline float + StopWatchLinux::getDiffTime() + { + struct timeval t_time; + gettimeofday( &t_time, 0); + + // time difference in milli-seconds + return (float) (1000.0 * ( t_time.tv_sec - start_time.tv_sec) + + (0.001 * (t_time.tv_usec - start_time.tv_usec)) ); + } +#endif // _WIN32 + +#endif diff --git a/external/cutil/inc/stopwatch_linux.h b/external/cutil/inc/stopwatch_linux.h new file mode 100644 index 0000000..4f7cb07 --- /dev/null +++ b/external/cutil/inc/stopwatch_linux.h @@ -0,0 +1,165 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +/* CUda UTility Library */ + +#ifndef _STOPWATCH_LINUX_H_ +#define _STOPWATCH_LINUX_H_ + +// includes, system +#include +#include + +//! Windows specific implementation of StopWatch +class StopWatchLinux +{ +protected: + + //! Constructor, default + StopWatchLinux(); + + // Destructor + ~StopWatchLinux(); + +public: + + //! Start time measurement + inline void start(); + + //! Stop time measurement + inline void stop(); + + //! Reset time counters to zero + inline void reset(); + + //! Time in msec. after start. If the stop watch is still running (i.e. there + //! was no call to stop()) then the elapsed time is returned, otherwise the + //! time between the last start() and stop call is returned + inline const float getTime() const; + + //! Mean time to date based on the number of times the stopwatch has been + //! _stopped_ (ie finished sessions) and the current total time + inline const float getAverageTime() const; + +private: + + // helper functions + + //! Get difference between start time and current time + inline float getDiffTime() const; + +private: + + // member variables + + //! Start of measurement + struct timeval start_time; + + //! Time difference between the last start and stop + float diff_time; + + //! TOTAL time difference between starts and stops + float total_time; + + //! flag if the stop watch is running + bool running; + + //! Number of times clock has been started + //! and stopped to allow averaging + int clock_sessions; +}; + +// functions, inlined + +//////////////////////////////////////////////////////////////////////////////// +//! Start time measurement +//////////////////////////////////////////////////////////////////////////////// +inline void +StopWatchLinux::start() { + + gettimeofday( &start_time, 0); + running = true; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Stop time measurement and increment add to the current diff_time summation +//! variable. Also increment the number of times this clock has been run. +//////////////////////////////////////////////////////////////////////////////// +inline void +StopWatchLinux::stop() { + + diff_time = getDiffTime(); + total_time += diff_time; + running = false; + clock_sessions++; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Reset the timer to 0. Does not change the timer running state but does +//! recapture this point in time as the current start time if it is running. +//////////////////////////////////////////////////////////////////////////////// +inline void +StopWatchLinux::reset() +{ + diff_time = 0; + total_time = 0; + clock_sessions = 0; + if( running ) + gettimeofday( &start_time, 0); +} + +//////////////////////////////////////////////////////////////////////////////// +//! Time in msec. after start. If the stop watch is still running (i.e. there +//! was no call to stop()) then the elapsed time is returned added to the +//! current diff_time sum, otherwise the current summed time difference alone +//! is returned. +//////////////////////////////////////////////////////////////////////////////// +inline const float +StopWatchLinux::getTime() const +{ + // Return the TOTAL time to date + float retval = total_time; + if( running) { + + retval += getDiffTime(); + } + + return retval; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Time in msec. for a single run based on the total number of COMPLETED runs +//! and the total time. +//////////////////////////////////////////////////////////////////////////////// +inline const float +StopWatchLinux::getAverageTime() const +{ + return (clock_sessions > 0) ? (total_time/clock_sessions) : 0.0f; +} + + + +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +inline float +StopWatchLinux::getDiffTime() const +{ + struct timeval t_time; + gettimeofday( &t_time, 0); + + // time difference in milli-seconds + return (float) (1000.0 * ( t_time.tv_sec - start_time.tv_sec) + + (0.001 * (t_time.tv_usec - start_time.tv_usec)) ); +} + +#endif // _STOPWATCH_LINUX_H_ + diff --git a/external/cutil/inc/stopwatch_win.h b/external/cutil/inc/stopwatch_win.h new file mode 100644 index 0000000..8c274aa --- /dev/null +++ b/external/cutil/inc/stopwatch_win.h @@ -0,0 +1,159 @@ +/* + * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. + * + * Please refer to the NVIDIA end user license agreement (EULA) associated + * with this source code for terms and conditions that govern your use of + * this software. Any use, reproduction, disclosure, or distribution of + * this software and related documentation outside the terms of the EULA + * is strictly prohibited. + * + */ + +/* CUda UTility Library */ + +#ifndef _STOPWATCH_WIN_H_ +#define _STOPWATCH_WIN_H_ + +// includes, system +#define WINDOWS_LEAN_AND_MEAN +#include +#undef min +#undef max + +//! Windows specific implementation of StopWatch +class StopWatchWin +{ +protected: + + //! Constructor, default + StopWatchWin(); + + // Destructor + ~StopWatchWin(); + +public: + + //! Start time measurement + inline void start(); + + //! Stop time measurement + inline void stop(); + + //! Reset time counters to zero + inline void reset(); + + //! Time in msec. after start. If the stop watch is still running (i.e. there + //! was no call to stop()) then the elapsed time is returned, otherwise the + //! time between the last start() and stop call is returned + inline const float getTime() const; + + //! Mean time to date based on the number of times the stopwatch has been + //! _stopped_ (ie finished sessions) and the current total time + inline const float getAverageTime() const; + +private: + + // member variables + + //! Start of measurement + LARGE_INTEGER start_time; + //! End of measurement + LARGE_INTEGER end_time; + + //! Time difference between the last start and stop + float diff_time; + + //! TOTAL time difference between starts and stops + float total_time; + + //! flag if the stop watch is running + bool running; + + //! Number of times clock has been started + //! and stopped to allow averaging + int clock_sessions; + + //! tick frequency + static double freq; + + //! flag if the frequency has been set + static bool freq_set; +}; + +// functions, inlined + +//////////////////////////////////////////////////////////////////////////////// +//! Start time measurement +//////////////////////////////////////////////////////////////////////////////// +inline void +StopWatchWin::start() +{ + QueryPerformanceCounter((LARGE_INTEGER*) &start_time); + running = true; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Stop time measurement and increment add to the current diff_time summation +//! variable. Also increment the number of times this clock has been run. +//////////////////////////////////////////////////////////////////////////////// +inline void +StopWatchWin::stop() +{ + QueryPerformanceCounter((LARGE_INTEGER*) &end_time); + diff_time = (float) + (((double) end_time.QuadPart - (double) start_time.QuadPart) / freq); + + total_time += diff_time; + clock_sessions++; + running = false; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Reset the timer to 0. Does not change the timer running state but does +//! recapture this point in time as the current start time if it is running. +//////////////////////////////////////////////////////////////////////////////// +inline void +StopWatchWin::reset() +{ + diff_time = 0; + total_time = 0; + clock_sessions = 0; + if( running ) + QueryPerformanceCounter((LARGE_INTEGER*) &start_time); +} + + +//////////////////////////////////////////////////////////////////////////////// +//! Time in msec. after start. If the stop watch is still running (i.e. there +//! was no call to stop()) then the elapsed time is returned added to the +//! current diff_time sum, otherwise the current summed time difference alone +//! is returned. +//////////////////////////////////////////////////////////////////////////////// +inline const float +StopWatchWin::getTime() const +{ + // Return the TOTAL time to date + float retval = total_time; + if(running) + { + LARGE_INTEGER temp; + QueryPerformanceCounter((LARGE_INTEGER*) &temp); + retval += (float) + (((double) (temp.QuadPart - start_time.QuadPart)) / freq); + } + + return retval; +} + +//////////////////////////////////////////////////////////////////////////////// +//! Time in msec. for a single run based on the total number of COMPLETED runs +//! and the total time. +//////////////////////////////////////////////////////////////////////////////// +inline const float +StopWatchWin::getAverageTime() const +{ + return (clock_sessions > 0) ? (total_time/clock_sessions) : 0.0f; +} + +#endif // _STOPWATCH_WIN_H_ + diff --git a/external/cutil/inc/string_helper.h b/external/cutil/inc/string_helper.h new file mode 100644 index 0000000..a150ca1 --- /dev/null +++ b/external/cutil/inc/string_helper.h @@ -0,0 +1,228 @@ +// These are helper functions for the SDK samples (string parsing, timers, etc) +#ifndef STRING_HELPER_H +#define STRING_HELPER_H + +#include +#include +#include +#include + +#ifdef _WIN32 + #ifndef STRCASECMP + #define STRCASECMP _stricmp + #endif + #ifndef STRNCASECMP + #define STRNCASECMP _strnicmp + #endif +#else + #include + #include + + #ifndef STRCASECMP + #define STRCASECMP strcasecmp + #endif + #ifndef STRNCASECMP + #define STRNCASECMP strncasecmp + #endif +#endif + +// CUDA Utility Helper Functions +inline int stringRemoveDelimiter(char delimiter, const char *string) +{ + int string_start = 0; + while (string[string_start] == delimiter) + string_start++; + + if (string_start >= (int)strlen(string)-1) { + return 0; + } + return string_start; +} + +inline int checkCmdLineFlag(const int argc, const char **argv, const char *string_ref) +{ + bool bFound = false; + if (argc >= 1) { + for (int i=1; i < argc; i++) { + int string_start = stringRemoveDelimiter('-', argv[i]); + const char *string_argv = &argv[i][string_start]; + int length = (int)strlen(string_ref); + if (!STRNCASECMP(string_argv, string_ref, length) ) { + bFound = true; + continue; + } + } + } + return (int)bFound; +} + +inline int getCmdLineArgumentInt(const int argc, const char **argv, const char *string_ref) +{ + bool bFound = false; + int value = -1; + if (argc >= 1) { + for (int i=1; i < argc; i++) { + int string_start = stringRemoveDelimiter('-', argv[i]); + const char *string_argv = &argv[i][string_start]; + int length = (int)strlen(string_ref); + if (!STRNCASECMP(string_argv, string_ref, length) ) { + if (length+1 <= (int)strlen(string_argv)) { + int auto_inc = (string_argv[length] == '=') ? 1 : 0; + value = atoi(&string_argv[length + auto_inc]); + } else { + value = 0; + } + bFound = true; + continue; + } + } + } + if (bFound) { + return value; + } else { + return 0; + } +} + +inline bool getCmdLineArgumentString(const int argc, const char **argv, + const char *string_ref, char **string_retval) +{ + bool bFound = false; + if (argc >= 1) { + for (int i=1; i < argc; i++) { + int string_start = stringRemoveDelimiter('-', argv[i]); + char *string_argv = (char *)&argv[i][string_start]; + int length = (int)strlen(string_ref); + if (!STRNCASECMP(string_argv, string_ref, length) ) { + *string_retval = &string_argv[length+1]; + bFound = true; + continue; + } + } + } + if (!bFound) { + *string_retval = NULL; + } + return bFound; +} + +////////////////////////////////////////////////////////////////////////////// +//! Find the path for a file assuming that +//! files are found in the searchPath. +//! +//! @return the path if succeeded, otherwise 0 +//! @param filename name of the file +//! @param executable_path optional absolute path of the executable +////////////////////////////////////////////////////////////////////////////// +inline char* sdkFindFilePath(const char* filename, const char* executable_path) +{ + // defines a variable that is replaced with the name of the executable + + // Typical relative search paths to locate needed companion files (e.g. sample input data, or JIT source files) + // The origin for the relative search may be the .exe file, a .bat file launching an .exe, a browser .exe launching the .exe or .bat, etc + const char* searchPath[] = + { + "./", // same dir + "./data/", // "/data/" subdir + "./src/", // "/src/" subdir + "./src//data/", // "/src//data/" subdir + "./inc/", // "/inc/" subdir + "../", // up 1 in tree + "../data/", // up 1 in tree, "/data/" subdir + "../src/", // up 1 in tree, "/src/" subdir + "../inc/", // up 1 in tree, "/inc/" subdir + "../OpenCL/src//", // up 1 in tree, "/OpenCL/src//" subdir + "../OpenCL/src//data/", // up 1 in tree, "/OpenCL/src//data/" subdir + "../OpenCL/src//src/", // up 1 in tree, "/OpenCL/src//src/" subdir + "../OpenCL/src//inc/", // up 1 in tree, "/OpenCL/src//inc/" subdir + "../C/src//", // up 1 in tree, "/C/src//" subdir + "../C/src//data/", // up 1 in tree, "/C/src//data/" subdir + "../C/src//src/", // up 1 in tree, "/C/src//src/" subdir + "../C/src//inc/", // up 1 in tree, "/C/src//inc/" subdir + "../DirectCompute/src//", // up 1 in tree, "/DirectCompute/src//" subdir + "../DirectCompute/src//data/", // up 1 in tree, "/DirectCompute/src//data/" subdir + "../DirectCompute/src//src/", // up 1 in tree, "/DirectCompute/src//src/" subdir + "../DirectCompute/src//inc/", // up 1 in tree, "/DirectCompute/src//inc/" subdir + "../../", // up 2 in tree + "../../data/", // up 2 in tree, "/data/" subdir + "../../src/", // up 2 in tree, "/src/" subdir + "../../inc/", // up 2 in tree, "/inc/" subdir + "../../../", // up 3 in tree + "../../../src//", // up 3 in tree, "/src//" subdir + "../../../src//data/", // up 3 in tree, "/src//data/" subdir + "../../../src//src/", // up 3 in tree, "/src//src/" subdir + "../../../src//inc/", // up 3 in tree, "/src//inc/" subdir + "../../../sandbox//", // up 3 in tree, "/sandbox//" subdir + "../../../sandbox//data/", // up 3 in tree, "/sandbox//data/" subdir + "../../../sandbox//src/", // up 3 in tree, "/sandbox//src/" subdir + "../../../sandbox//inc/" // up 3 in tree, "/sandbox//inc/" subdir + }; + + // Extract the executable name + std::string executable_name; + if (executable_path != 0) + { + executable_name = std::string(executable_path); + + #ifdef _WIN32 + // Windows path delimiter + size_t delimiter_pos = executable_name.find_last_of('\\'); + executable_name.erase(0, delimiter_pos + 1); + + if (executable_name.rfind(".exe") != std::string::npos) + { + // we strip .exe, only if the .exe is found + executable_name.resize(executable_name.size() - 4); + } + #else + // Linux & OSX path delimiter + size_t delimiter_pos = executable_name.find_last_of('/'); + executable_name.erase(0,delimiter_pos+1); + #endif + + } + + // Loop over all search paths and return the first hit + for( unsigned int i = 0; i < sizeof(searchPath)/sizeof(char*); ++i ) + { + std::string path(searchPath[i]); + size_t executable_name_pos = path.find(""); + + // If there is executable_name variable in the searchPath + // replace it with the value + if(executable_name_pos != std::string::npos) + { + if(executable_path != 0) + { + path.replace(executable_name_pos, strlen(""), executable_name); + + } + else + { + // Skip this path entry if no executable argument is given + continue; + } + } + + // Test if the file exists + path.append(filename); + std::fstream fh(path.c_str(), std::fstream::in); + if (fh.good()) + { + // File found + // returning an allocated array here for backwards compatibility reasons + char* file_path = (char*) malloc(path.length() + 1); + #ifdef _WIN32 + strcpy_s(file_path, path.length() + 1, path.c_str()); + #else + strcpy(file_path, path.c_str()); + #endif + return file_path; + } + } + + // File not found + return 0; +} + +#endif diff --git a/external/mLib b/external/mLib new file mode 160000 index 0000000..a9a85db --- /dev/null +++ b/external/mLib @@ -0,0 +1 @@ +Subproject commit a9a85db0da4228623b7cb42a13691dd4753548d6 diff --git a/img/legend.png b/img/legend.png new file mode 100644 index 0000000..0354c93 Binary files /dev/null and b/img/legend.png differ