From 4b695ecaf6c81341c1cb76366a918df504888696 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Thu, 10 Jan 2019 22:07:45 +0100 Subject: [PATCH] add tinygltfloader --- src/core/include/pw/core/buffer.hpp | 4 + .../scene => core/include/pw/core}/mesh.hpp | 0 src/{scene => core}/src/mesh.cpp | 0 src/deps/tinygltfloader-0.9.2/.clang-format | 7 + src/deps/tinygltfloader-0.9.2/.travis.yml | 10 + src/deps/tinygltfloader-0.9.2/Makefile | 2 + src/deps/tinygltfloader-0.9.2/README.md | 93 + src/deps/tinygltfloader-0.9.2/appveyor.yml | 12 + src/deps/tinygltfloader-0.9.2/box.gltf | 267 + .../examples/glview/README.md | 24 + .../examples/glview/glview.cc | 546 ++ .../examples/glview/premake4.lua | 36 + .../examples/glview/shader.frag | 11 + .../examples/glview/shader.vert | 16 + .../examples/glview/trackball.cc | 292 + .../examples/glview/trackball.h | 75 + .../images/glview_duck.png | Bin 0 -> 108605 bytes src/deps/tinygltfloader-0.9.2/picojson.h | 1039 +++ src/deps/tinygltfloader-0.9.2/premake4.lua | 29 + src/deps/tinygltfloader-0.9.2/stb_image.h | 6509 +++++++++++++++++ src/deps/tinygltfloader-0.9.2/test.cc | 377 + src/deps/tinygltfloader-0.9.2/test_runner.py | 64 + .../tinygltfloader-0.9.2/tiny_gltf_loader.h | 1391 ++++ .../tools/windows/premake5.exe | Bin 0 -> 514560 bytes src/deps/tinygltfloader-0.9.2/vcsetup.bat | 1 + 25 files changed, 10805 insertions(+) create mode 100644 src/core/include/pw/core/buffer.hpp rename src/{scene/include/pw/scene => core/include/pw/core}/mesh.hpp (100%) rename src/{scene => core}/src/mesh.cpp (100%) create mode 100644 src/deps/tinygltfloader-0.9.2/.clang-format create mode 100644 src/deps/tinygltfloader-0.9.2/.travis.yml create mode 100644 src/deps/tinygltfloader-0.9.2/Makefile create mode 100644 src/deps/tinygltfloader-0.9.2/README.md create mode 100644 src/deps/tinygltfloader-0.9.2/appveyor.yml create mode 100644 src/deps/tinygltfloader-0.9.2/box.gltf create mode 100644 src/deps/tinygltfloader-0.9.2/examples/glview/README.md create mode 100644 src/deps/tinygltfloader-0.9.2/examples/glview/glview.cc create mode 100644 src/deps/tinygltfloader-0.9.2/examples/glview/premake4.lua create mode 100644 src/deps/tinygltfloader-0.9.2/examples/glview/shader.frag create mode 100644 src/deps/tinygltfloader-0.9.2/examples/glview/shader.vert create mode 100644 src/deps/tinygltfloader-0.9.2/examples/glview/trackball.cc create mode 100644 src/deps/tinygltfloader-0.9.2/examples/glview/trackball.h create mode 100644 src/deps/tinygltfloader-0.9.2/images/glview_duck.png create mode 100644 src/deps/tinygltfloader-0.9.2/picojson.h create mode 100644 src/deps/tinygltfloader-0.9.2/premake4.lua create mode 100644 src/deps/tinygltfloader-0.9.2/stb_image.h create mode 100644 src/deps/tinygltfloader-0.9.2/test.cc create mode 100644 src/deps/tinygltfloader-0.9.2/test_runner.py create mode 100644 src/deps/tinygltfloader-0.9.2/tiny_gltf_loader.h create mode 100644 src/deps/tinygltfloader-0.9.2/tools/windows/premake5.exe create mode 100644 src/deps/tinygltfloader-0.9.2/vcsetup.bat diff --git a/src/core/include/pw/core/buffer.hpp b/src/core/include/pw/core/buffer.hpp new file mode 100644 index 0000000..dc80c89 --- /dev/null +++ b/src/core/include/pw/core/buffer.hpp @@ -0,0 +1,4 @@ +#ifndef BUFFER_HPP +#define BUFFER_HPP + +#endif // BUFFER_HPP diff --git a/src/scene/include/pw/scene/mesh.hpp b/src/core/include/pw/core/mesh.hpp similarity index 100% rename from src/scene/include/pw/scene/mesh.hpp rename to src/core/include/pw/core/mesh.hpp diff --git a/src/scene/src/mesh.cpp b/src/core/src/mesh.cpp similarity index 100% rename from src/scene/src/mesh.cpp rename to src/core/src/mesh.cpp diff --git a/src/deps/tinygltfloader-0.9.2/.clang-format b/src/deps/tinygltfloader-0.9.2/.clang-format new file mode 100644 index 0000000..a94a2c4 --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/.clang-format @@ -0,0 +1,7 @@ +--- +BasedOnStyle: LLVM +IndentWidth: 2 +TabWidth: 2 +UseTab: Never +BreakBeforeBraces: Attach +Standard: Cpp03 diff --git a/src/deps/tinygltfloader-0.9.2/.travis.yml b/src/deps/tinygltfloader-0.9.2/.travis.yml new file mode 100644 index 0000000..6dc7a50 --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/.travis.yml @@ -0,0 +1,10 @@ +language: cpp + +compiler: gcc + +before_install: + - sudo apt-get update -qq -y + +script: + - make + - ./loader_test box.gltf diff --git a/src/deps/tinygltfloader-0.9.2/Makefile b/src/deps/tinygltfloader-0.9.2/Makefile new file mode 100644 index 0000000..032035a --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/Makefile @@ -0,0 +1,2 @@ +all: + g++ -Wall -Werror -g -O2 -o loader_test test.cc diff --git a/src/deps/tinygltfloader-0.9.2/README.md b/src/deps/tinygltfloader-0.9.2/README.md new file mode 100644 index 0000000..e422143 --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/README.md @@ -0,0 +1,93 @@ +# Tiny glTF loader, header only C++ glTF parsing library. + +`TinyGLTFLoader` is a header only C++ glTF https://github.com/KhronosGroup/glTF parsing library + +![](images/glview_duck.png) + +[![Build Status](https://travis-ci.org/syoyo/tinygltfloader.svg?branch=master)](https://travis-ci.org/syoyo/tinygltfloader) + +[![Build status](https://ci.appveyor.com/api/projects/status/i5ku97hf0r0quti3?svg=true)](https://ci.appveyor.com/project/syoyo/tinygltfloader) + +## Features + +* Portable C++. C++-98 with STL dependency only. +* Moderate parsing time and memory consumption. +* glTF specification v1.0.0 +* Buffers + * [x] Parse BASE64 encoded embedded buffer fata(DataURI). + * [x] Load `.bin` file. +* Image(Using stb_image) + * [x] Parse BASE64 encoded embedded image fata(DataURI). + * [x] Load external image file. + * [x] PNG(8bit only) + * [x] JPEG(8bit only) + * [x] BMP + * [x] GIF + +## Limitation + +Currently, TinyGLTFLoader only loads nodes and geometry(mesh/buffer) data. + +## Examples + +* [glview](examples/glview) : Simple glTF geometry viewer. + +## TODOs + +* [ ] Support multiple scenes in `.gltf` +* [ ] Parse `animation`, `program`, `sampler`, `shader`, `technique`, `texture` +* [ ] Compression/decompression(Open3DGC, etc) +* [ ] Support `extensions` and `extras` property +* [ ] HDR image +* [ ] Binary glTF. + +## License + +TinyGLTFLoader is licensed under 2-clause BSD. + +TinyGLTFLoader uses the following third party libraries. + +* picojson.h : Copyright 2009-2010 Cybozu Labs, Inc. Copyright 2011-2014 Kazuho Oku +* base64 : Copyright (C) 2004-2008 René Nyffenegger +* stb_image.h : v2.08 - public domain image loader - http://nothings.org/stb_image.h + + +## Build and example + +Copy `stb_image.h`, `picojson.h` and `tiny_gltf_loader.h` to your project. + +``` +// Define these only in *one* .cc file. +#define TINYGLTF_LOADER_IMPLEMENTATION +#define STB_IMAGE_IMPLEMENTATION +#include "tiny_gltf_loader.h" + +using namespace tinygltf; + +Scene scene; +TinyGLTFLoader loader; +std::string err; + +bool ret = loader.LoadFromFile(scene, err, argv[1]); +if (!err.empty()) { + printf("Err: %s\n", err.c_str()); +} + +if (!ret) { + printf("Failed to parse glTF\n"); + return -1; +} +``` + +## Running tests. + +### Setup + +Python 2.6 or 2.7 required. +Git clone https://github.com/KhronosGroup/glTF to your local dir. + +### Run test + +After building `loader_test`, edit `test_runner.py`, then, + + $ python test_runner.py diff --git a/src/deps/tinygltfloader-0.9.2/appveyor.yml b/src/deps/tinygltfloader-0.9.2/appveyor.yml new file mode 100644 index 0000000..f7ffacd --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/appveyor.yml @@ -0,0 +1,12 @@ +version: 0.9.{build} + +# scripts that runs after repo cloning. +install: + - vcsetup.bat + +platform: x64 +configuration: Release + +build: + parallel: true + project: TinyGLTFLoaderSolution.sln diff --git a/src/deps/tinygltfloader-0.9.2/box.gltf b/src/deps/tinygltfloader-0.9.2/box.gltf new file mode 100644 index 0000000..30e81fc --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/box.gltf @@ -0,0 +1,267 @@ +{ + "accessors": { + "accessor_21": { + "bufferView": "bufferView_29", + "byteOffset": 0, + "byteStride": 0, + "componentType": 5123, + "count": 36, + "type": "SCALAR" + }, + "accessor_23": { + "bufferView": "bufferView_30", + "byteOffset": 0, + "byteStride": 12, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.5, + 0.5 + ], + "min": [ + -0.5, + -0.5, + -0.5 + ], + "type": "VEC3" + }, + "accessor_25": { + "bufferView": "bufferView_30", + "byteOffset": 288, + "byteStride": 12, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "type": "VEC3" + }, + "accessor_27": { + "bufferView": "bufferView_30", + "byteOffset": 576, + "byteStride": 8, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1 + ], + "min": [ + 0, + 0 + ], + "type": "VEC2" + } + }, + "animations": {}, + "asset": { + "generator": "collada2gltf@ceec062e3d5793f2f249f53cbd843aee382ad40b", + "premultipliedAlpha": true, + "profile": { + "api": "WebGL", + "version": "1.0.2" + }, + "version": 1 + }, + "bufferViews": { + "bufferView_29": { + "buffer": "box", + "byteLength": 72, + "byteOffset": 0, + "target": 34963 + }, + "bufferView_30": { + "buffer": "box", + "byteLength": 768, + "byteOffset": 72, + "target": 34962 + } + }, + "buffers": { + "box": { + "byteLength": 840, + "type": "arraybuffer", + "uri": "data:application/octet-stream;base64,AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUAAAAAvwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAC/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AACAPgAAAAAAAIA+oKqqPgAAAD8AAAAAAAAAP6Cqqj4AAIA+oKqqPgAAAACgqqo+AACAPrCqKj8AAAAAsKoqPwAAAD+gqqo+AACAPqCqqj4AAAA/sKoqPwAAgD6wqio/AABAP6Cqqj4AAAA/oKqqPgAAQD+wqio/AAAAP7CqKj8AAIA/oKqqPgAAQD+gqqo+AACAP7CqKj8AAEA/sKoqPwAAgD4AAIA/AAAAPwAAgD8AAIA+sKoqPwAAAD+wqio/" + } + }, + "materials": { + "Effect-Red": { + "name": "Red", + "technique": "technique0", + "values": { + "diffuse": [ + 0.8, + 0, + 0, + 1 + ], + "shininess": 256, + "specular": [ + 0.2, + 0.2, + 0.2, + 1 + ] + } + } + }, + "meshes": { + "Geometry-mesh002": { + "name": "Mesh", + "primitives": [ + { + "attributes": { + "NORMAL": "accessor_25", + "POSITION": "accessor_23", + "TEXCOORD_0": "accessor_27" + }, + "indices": "accessor_21", + "material": "Effect-Red", + "mode": 4 + } + ] + } + }, + "nodes": { + "Geometry-mesh002Node": { + "children": [], + "matrix": [ + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1 + ], + "meshes": [ + "Geometry-mesh002" + ], + "name": "Mesh" + }, + "node_1": { + "children": [ + "Geometry-mesh002Node" + ], + "matrix": [ + 1, + 0, + 0, + 0, + 0, + 0, + -1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1 + ], + "name": "Y_UP_Transform" + } + }, + "programs": { + "program_0": { + "attributes": [ + "a_normal", + "a_position" + ], + "fragmentShader": "box0FS", + "vertexShader": "box0VS" + } + }, + "scene": "defaultScene", + "scenes": { + "defaultScene": { + "nodes": [ + "node_1" + ] + } + }, + "shaders": { + "box0FS": { + "type": 35632, + "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Owp2YXJ5aW5nIHZlYzMgdl9ub3JtYWw7CnVuaWZvcm0gdmVjNCB1X2RpZmZ1c2U7CnVuaWZvcm0gdmVjNCB1X3NwZWN1bGFyOwp1bmlmb3JtIGZsb2F0IHVfc2hpbmluZXNzOwp2b2lkIG1haW4odm9pZCkgewp2ZWMzIG5vcm1hbCA9IG5vcm1hbGl6ZSh2X25vcm1hbCk7CnZlYzQgY29sb3IgPSB2ZWM0KDAuLCAwLiwgMC4sIDAuKTsKdmVjNCBkaWZmdXNlID0gdmVjNCgwLiwgMC4sIDAuLCAxLik7CnZlYzQgc3BlY3VsYXI7CmRpZmZ1c2UgPSB1X2RpZmZ1c2U7CnNwZWN1bGFyID0gdV9zcGVjdWxhcjsKZGlmZnVzZS54eXogKj0gbWF4KGRvdChub3JtYWwsdmVjMygwLiwwLiwxLikpLCAwLik7CmNvbG9yLnh5eiArPSBkaWZmdXNlLnh5ejsKY29sb3IgPSB2ZWM0KGNvbG9yLnJnYiAqIGRpZmZ1c2UuYSwgZGlmZnVzZS5hKTsKZ2xfRnJhZ0NvbG9yID0gY29sb3I7Cn0K" + }, + "box0VS": { + "type": 35633, + "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwphdHRyaWJ1dGUgdmVjMyBhX3Bvc2l0aW9uOwphdHRyaWJ1dGUgdmVjMyBhX25vcm1hbDsKdmFyeWluZyB2ZWMzIHZfbm9ybWFsOwp1bmlmb3JtIG1hdDMgdV9ub3JtYWxNYXRyaXg7CnVuaWZvcm0gbWF0NCB1X21vZGVsVmlld01hdHJpeDsKdW5pZm9ybSBtYXQ0IHVfcHJvamVjdGlvbk1hdHJpeDsKdm9pZCBtYWluKHZvaWQpIHsKdmVjNCBwb3MgPSB1X21vZGVsVmlld01hdHJpeCAqIHZlYzQoYV9wb3NpdGlvbiwxLjApOwp2X25vcm1hbCA9IHVfbm9ybWFsTWF0cml4ICogYV9ub3JtYWw7CmdsX1Bvc2l0aW9uID0gdV9wcm9qZWN0aW9uTWF0cml4ICogcG9zOwp9Cg==" + } + }, + "skins": {}, + "techniques": { + "technique0": { + "attributes": { + "a_normal": "normal", + "a_position": "position" + }, + "parameters": { + "diffuse": { + "type": 35666 + }, + "modelViewMatrix": { + "semantic": "MODELVIEW", + "type": 35676 + }, + "normal": { + "semantic": "NORMAL", + "type": 35665 + }, + "normalMatrix": { + "semantic": "MODELVIEWINVERSETRANSPOSE", + "type": 35675 + }, + "position": { + "semantic": "POSITION", + "type": 35665 + }, + "projectionMatrix": { + "semantic": "PROJECTION", + "type": 35676 + }, + "shininess": { + "type": 5126 + }, + "specular": { + "type": 35666 + } + }, + "program": "program_0", + "states": { + "enable": [ + 2929, + 2884 + ] + }, + "uniforms": { + "u_diffuse": "diffuse", + "u_modelViewMatrix": "modelViewMatrix", + "u_normalMatrix": "normalMatrix", + "u_projectionMatrix": "projectionMatrix", + "u_shininess": "shininess", + "u_specular": "specular" + } + } + } +} \ No newline at end of file diff --git a/src/deps/tinygltfloader-0.9.2/examples/glview/README.md b/src/deps/tinygltfloader-0.9.2/examples/glview/README.md new file mode 100644 index 0000000..cff927a --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/examples/glview/README.md @@ -0,0 +1,24 @@ +Simple OpenGL viewer for glTF geometry. + +## Requirements + +* premake4 : Requires recent `premake4` for macosx and linux, `premake5` for windows. +* GLEW +* glfw3 + +### MacOSX and Linux + + > premake4 gmake + $ make + +### Windows(not tested) + + > premake5.exe vs2013 + Open .sln in Visual Studio 2013 + +## TODO + +* [x] Texture + * [ ] Various texture format. +* [ ] Shader +* [ ] Animation diff --git a/src/deps/tinygltfloader-0.9.2/examples/glview/glview.cc b/src/deps/tinygltfloader-0.9.2/examples/glview/glview.cc new file mode 100644 index 0000000..fd3a466 --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/examples/glview/glview.cc @@ -0,0 +1,546 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define GLFW_INCLUDE_GLU +#include + +#include "trackball.h" + +#define TINYGLTF_LOADER_IMPLEMENTATION +#define STB_IMAGE_IMPLEMENTATION +#include "tiny_gltf_loader.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define CheckGLErrors(desc) \ + { \ + GLenum e = glGetError(); \ + if (e != GL_NO_ERROR) { \ + printf("OpenGL error in \"%s\": %d (%d) %s:%d\n", desc, e, e, __FILE__, \ + __LINE__); \ + exit(20); \ + } \ + } + +#define CAM_Z (3.0f) +int width = 768; +int height = 768; + +double prevMouseX, prevMouseY; +bool mouseLeftPressed; +bool mouseMiddlePressed; +bool mouseRightPressed; +float curr_quat[4]; +float prev_quat[4]; +float eye[3], lookat[3], up[3]; + +GLFWwindow *window; + +typedef struct { GLuint vb; } GLBufferState; + +typedef struct { + std::vector diffuseTex; // for each primitive in mesh +} GLMeshState; + +typedef struct { + std::map attribs; + std::map uniforms; +} GLProgramState; + +std::map gBufferState; +std::map gMeshState; +GLProgramState gGLProgramState; + +void CheckErrors(std::string desc) { + GLenum e = glGetError(); + if (e != GL_NO_ERROR) { + fprintf(stderr, "OpenGL error in \"%s\": %d (%d)\n", desc.c_str(), e, e); + exit(20); + } +} + +bool LoadShader(GLenum shaderType, // GL_VERTEX_SHADER or GL_FRAGMENT_SHADER(or + // maybe GL_COMPUTE_SHADER) + GLuint &shader, const char *shaderSourceFilename) { + GLint val = 0; + + // free old shader/program + if (shader != 0) { + glDeleteShader(shader); + } + + std::vector srcbuf; + FILE *fp = fopen(shaderSourceFilename, "rb"); + if (!fp) { + fprintf(stderr, "failed to load shader: %s\n", shaderSourceFilename); + return false; + } + fseek(fp, 0, SEEK_END); + size_t len = ftell(fp); + rewind(fp); + srcbuf.resize(len + 1); + len = fread(&srcbuf.at(0), 1, len, fp); + srcbuf[len] = 0; + fclose(fp); + + const GLchar *srcs[1]; + srcs[0] = &srcbuf.at(0); + + shader = glCreateShader(shaderType); + glShaderSource(shader, 1, srcs, NULL); + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &val); + if (val != GL_TRUE) { + char log[4096]; + GLsizei msglen; + glGetShaderInfoLog(shader, 4096, &msglen, log); + printf("%s\n", log); + // assert(val == GL_TRUE && "failed to compile shader"); + printf("ERR: Failed to load or compile shader [ %s ]\n", + shaderSourceFilename); + return false; + } + + printf("Load shader [ %s ] OK\n", shaderSourceFilename); + return true; +} + +bool LinkShader(GLuint &prog, GLuint &vertShader, GLuint &fragShader) { + GLint val = 0; + + if (prog != 0) { + glDeleteProgram(prog); + } + + prog = glCreateProgram(); + + glAttachShader(prog, vertShader); + glAttachShader(prog, fragShader); + glLinkProgram(prog); + + glGetProgramiv(prog, GL_LINK_STATUS, &val); + assert(val == GL_TRUE && "failed to link shader"); + + printf("Link shader OK\n"); + + return true; +} + +void reshapeFunc(GLFWwindow *window, int w, int h) { + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, (float)w / (float)h, 0.1f, 1000.0f); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + width = w; + height = h; +} + +void keyboardFunc(GLFWwindow *window, int key, int scancode, int action, + int mods) { + if (action == GLFW_PRESS || action == GLFW_REPEAT) { + // Close window + if (key == GLFW_KEY_Q || key == GLFW_KEY_ESCAPE) + glfwSetWindowShouldClose(window, GL_TRUE); + } +} + +void clickFunc(GLFWwindow *window, int button, int action, int mods) { + double x, y; + glfwGetCursorPos(window, &x, &y); + + if (button == GLFW_MOUSE_BUTTON_LEFT) { + mouseLeftPressed = true; + if (action == GLFW_PRESS) { + int id = -1; + // int id = ui.Proc(x, y); + if (id < 0) { // outside of UI + trackball(prev_quat, 0.0, 0.0, 0.0, 0.0); + } + } else if (action == GLFW_RELEASE) { + mouseLeftPressed = false; + } + } + if (button == GLFW_MOUSE_BUTTON_RIGHT) { + if (action == GLFW_PRESS) { + mouseRightPressed = true; + } else if (action == GLFW_RELEASE) { + mouseRightPressed = false; + } + } + if (button == GLFW_MOUSE_BUTTON_MIDDLE) { + if (action == GLFW_PRESS) { + mouseMiddlePressed = true; + } else if (action == GLFW_RELEASE) { + mouseMiddlePressed = false; + } + } +} + +void motionFunc(GLFWwindow *window, double mouse_x, double mouse_y) { + float rotScale = 1.0f; + float transScale = 2.0f; + + if (mouseLeftPressed) { + trackball(prev_quat, rotScale * (2.0f * prevMouseX - width) / (float)width, + rotScale * (height - 2.0f * prevMouseY) / (float)height, + rotScale * (2.0f * mouse_x - width) / (float)width, + rotScale * (height - 2.0f * mouse_y) / (float)height); + + add_quats(prev_quat, curr_quat, curr_quat); + } else if (mouseMiddlePressed) { + eye[0] += -transScale * (mouse_x - prevMouseX) / (float)width; + lookat[0] += -transScale * (mouse_x - prevMouseX) / (float)width; + eye[1] += transScale * (mouse_y - prevMouseY) / (float)height; + lookat[1] += transScale * (mouse_y - prevMouseY) / (float)height; + } else if (mouseRightPressed) { + eye[2] += transScale * (mouse_y - prevMouseY) / (float)height; + lookat[2] += transScale * (mouse_y - prevMouseY) / (float)height; + } + + // Update mouse point + prevMouseX = mouse_x; + prevMouseY = mouse_y; +} + +static void SetupGLState(Scene &scene, GLuint progId) { + // Buffer + { + std::map::const_iterator it( + scene.bufferViews.begin()); + std::map::const_iterator itEnd( + scene.bufferViews.end()); + + for (; it != itEnd; it++) { + const BufferView &bufferView = it->second; + if (bufferView.target == 0) { + continue; // Unsupported bufferView. + } + + const Buffer &buffer = scene.buffers[bufferView.buffer]; + GLBufferState state; + glGenBuffers(1, &state.vb); + glBindBuffer(bufferView.target, state.vb); + glBufferData(bufferView.target, bufferView.byteLength, + &buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW); + glBindBuffer(bufferView.target, 0); + + gBufferState[it->first] = state; + } + } + + // Texture + { + std::map::const_iterator it(scene.meshes.begin()); + std::map::const_iterator itEnd(scene.meshes.end()); + + for (; it != itEnd; it++) { + const Mesh &mesh = it->second; + + gMeshState[mesh.name].diffuseTex.resize(mesh.primitives.size()); + for (size_t primId = 0; primId < mesh.primitives.size(); primId++) { + const Primitive &primitive = mesh.primitives[primId]; + + gMeshState[mesh.name].diffuseTex[primId] = 0; + + if (primitive.material.empty()) { + continue; + } + Material &mat = scene.materials[primitive.material]; + printf("material.name = %s\n", mat.name.c_str()); + if (mat.values.find("diffuse") != mat.values.end()) { + std::string diffuseTexName = mat.values["diffuse"].stringValue; + if (scene.textures.find(diffuseTexName) != scene.textures.end()) { + Texture &tex = scene.textures[diffuseTexName]; + if (scene.images.find(tex.source) != scene.images.end()) { + Image &image = scene.images[tex.source]; + GLuint texId; + glGenTextures(1, &texId); + glBindTexture(tex.target, texId); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexParameterf(tex.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(tex.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // Ignore Texture.fomat. + GLenum format = GL_RGBA; + if (image.component == 3) { + format = GL_RGB; + } + glTexImage2D(tex.target, 0, tex.internalFormat, image.width, + image.height, 0, format, tex.type, + &image.image.at(0)); + + CheckErrors("texImage2D"); + glBindTexture(tex.target, 0); + + printf("TexId = %d\n", texId); + gMeshState[mesh.name].diffuseTex[primId] = texId; + } + } + } + } + } + } + + glUseProgram(progId); + GLint vtloc = glGetAttribLocation(progId, "in_vertex"); + GLint nrmloc = glGetAttribLocation(progId, "in_normal"); + GLint uvloc = glGetAttribLocation(progId, "in_texcoord"); + + GLint diffuseTexLoc = glGetUniformLocation(progId, "diffuseTex"); + + gGLProgramState.attribs["POSITION"] = vtloc; + gGLProgramState.attribs["NORMAL"] = nrmloc; + gGLProgramState.attribs["TEXCOORD_0"] = uvloc; + gGLProgramState.uniforms["diffuseTex"] = diffuseTexLoc; +}; + +void DrawMesh(Scene &scene, const Mesh &mesh) { + + if (gGLProgramState.uniforms["diffuseTex"] >= 0) { + glUniform1i(gGLProgramState.uniforms["diffuseTex"], 0); // TEXTURE0 + } + + for (size_t i = 0; i < mesh.primitives.size(); i++) { + const Primitive &primitive = mesh.primitives[i]; + + if (primitive.indices.empty()) + return; + + std::map::const_iterator it( + primitive.attributes.begin()); + std::map::const_iterator itEnd( + primitive.attributes.end()); + + // Assume TEXTURE_2D target for the texture object. + glBindTexture(GL_TEXTURE_2D, gMeshState[mesh.name].diffuseTex[i]); + + for (; it != itEnd; it++) { + const Accessor &accessor = scene.accessors[it->second]; + glBindBuffer(GL_ARRAY_BUFFER, gBufferState[accessor.bufferView].vb); + CheckErrors("bind buffer"); + int count = 1; + if (accessor.type == TINYGLTF_TYPE_SCALAR) { + count = 1; + } else if (accessor.type == TINYGLTF_TYPE_VEC2) { + count = 2; + } else if (accessor.type == TINYGLTF_TYPE_VEC3) { + count = 3; + } else if (accessor.type == TINYGLTF_TYPE_VEC4) { + count = 4; + } + // it->first would be "POSITION", "NORMAL", "TEXCOORD_0", ... + if ((it->first.compare("POSITION") == 0) || + (it->first.compare("NORMAL") == 0) || + (it->first.compare("TEXCOORD_0") == 0)) { + glVertexAttribPointer( + gGLProgramState.attribs[it->first], count, accessor.componentType, + GL_FALSE, accessor.byteStride, BUFFER_OFFSET(accessor.byteOffset)); + CheckErrors("vertex attrib pointer"); + glEnableVertexAttribArray(gGLProgramState.attribs[it->first]); + CheckErrors("enable vertex attrib array"); + } + } + + const Accessor &indexAccessor = scene.accessors[primitive.indices]; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, + gBufferState[indexAccessor.bufferView].vb); + CheckErrors("bind buffer"); + int mode = -1; + if (primitive.mode == TINYGLTF_MODE_TRIANGLES) { + mode = GL_TRIANGLES; + } else if (primitive.mode == TINYGLTF_MODE_TRIANGLE_STRIP) { + mode = GL_TRIANGLE_STRIP; + } else if (primitive.mode == TINYGLTF_MODE_TRIANGLE_FAN) { + mode = GL_TRIANGLE_FAN; + } else if (primitive.mode == TINYGLTF_MODE_POINTS) { + mode = GL_POINTS; + } else if (primitive.mode == TINYGLTF_MODE_LINE) { + mode = GL_LINES; + } else if (primitive.mode == TINYGLTF_MODE_LINE_LOOP) { + mode = GL_LINE_LOOP; + }; + glDrawElements(mode, indexAccessor.count, indexAccessor.componentType, + BUFFER_OFFSET(indexAccessor.byteOffset)); + CheckErrors("draw elements"); + + { + std::map::const_iterator it( + primitive.attributes.begin()); + std::map::const_iterator itEnd( + primitive.attributes.end()); + + for (; it != itEnd; it++) { + if ((it->first.compare("POSITION") == 0) || + (it->first.compare("NORMAL") == 0) || + (it->first.compare("TEXCOORD_0") == 0)) { + glDisableVertexAttribArray(gGLProgramState.attribs[it->first]); + } + } + } + } +} + +void DrawScene(Scene &scene) { + std::map::const_iterator it(scene.meshes.begin()); + std::map::const_iterator itEnd(scene.meshes.end()); + + for (; it != itEnd; it++) { + DrawMesh(scene, it->second); + } +} + +static void Init() { + trackball(curr_quat, 0, 0, 0, 0); + + eye[0] = 0.0f; + eye[1] = 0.0f; + eye[2] = CAM_Z; + + lookat[0] = 0.0f; + lookat[1] = 0.0f; + lookat[2] = 0.0f; + + up[0] = 0.0f; + up[1] = 1.0f; + up[2] = 0.0f; +} + +int main(int argc, char **argv) { + if (argc < 2) { + std::cout << "glview input.gltf \n" << std::endl; + return 0; + } + + float scale = 1.0f; + if (argc > 2) { + scale = atof(argv[2]); + } + + Scene scene; + TinyGLTFLoader loader; + std::string err; + + bool ret = loader.LoadFromFile(scene, err, argv[1]); + if (!err.empty()) { + printf("ERR: %s\n", err.c_str()); + } + if (!ret) { + printf("Failed to load .glTF : %s\n", argv[1]); + exit(-1); + } + + Init(); + + if (!glfwInit()) { + std::cerr << "Failed to initialize GLFW." << std::endl; + return -1; + } + + window = glfwCreateWindow(width, height, "Simple glTF geometry viewer", NULL, + NULL); + if (window == NULL) { + std::cerr << "Failed to open GLFW window. " << std::endl; + glfwTerminate(); + return 1; + } + + glfwGetWindowSize(window, &width, &height); + + glfwMakeContextCurrent(window); + + // Callback + glfwSetWindowSizeCallback(window, reshapeFunc); + glfwSetKeyCallback(window, keyboardFunc); + glfwSetMouseButtonCallback(window, clickFunc); + glfwSetCursorPosCallback(window, motionFunc); + + glewExperimental = true; + if (glewInit() != GLEW_OK) { + std::cerr << "Failed to initialize GLEW." << std::endl; + return -1; + } + + reshapeFunc(window, width, height); + + GLuint vertId = 0, fragId = 0, progId = 0; + if (false == LoadShader(GL_VERTEX_SHADER, vertId, "shader.vert")) { + return -1; + } + CheckErrors("load vert shader"); + + if (false == LoadShader(GL_FRAGMENT_SHADER, fragId, "shader.frag")) { + return -1; + } + CheckErrors("load frag shader"); + + if (false == LinkShader(progId, vertId, fragId)) { + return -1; + } + + CheckErrors("link"); + + { + GLint vtxLoc = glGetAttribLocation(progId, "in_vertex"); + if (vtxLoc < 0) { + printf("vertex loc not found.\n"); + exit(-1); + } + + GLint tnLoc = glGetAttribLocation(progId, "in_normal"); + if (tnLoc < 0) { + printf("normal loc not found.\n"); + exit(-1); + } + } + + glUseProgram(progId); + CheckErrors("useProgram"); + + SetupGLState(scene, progId); + CheckErrors("SetupGLState"); + + while (glfwWindowShouldClose(window) == GL_FALSE) { + glfwPollEvents(); + glClearColor(0.1f, 0.2f, 0.3f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); + + GLfloat mat[4][4]; + build_rotmatrix(mat, curr_quat); + + // camera(define it in projection matrix) + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + gluLookAt(eye[0], eye[1], eye[2], lookat[0], lookat[1], lookat[2], up[0], + up[1], up[2]); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glMultMatrixf(&mat[0][0]); + + glScalef(scale, scale, scale); + + DrawScene(scene); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + glFlush(); + + glfwSwapBuffers(window); + } + + glfwTerminate(); +} diff --git a/src/deps/tinygltfloader-0.9.2/examples/glview/premake4.lua b/src/deps/tinygltfloader-0.9.2/examples/glview/premake4.lua new file mode 100644 index 0000000..afcfa97 --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/examples/glview/premake4.lua @@ -0,0 +1,36 @@ +solution "glview" + -- location ( "build" ) + configurations { "Debug", "Release" } + platforms {"native", "x64", "x32"} + + project "glview" + + kind "ConsoleApp" + language "C++" + files { "glview.cc", "trackball.cc" } + includedirs { "./" } + includedirs { "../../" } + + configuration { "linux" } + linkoptions { "`pkg-config --libs glfw3`" } + links { "GL", "GLU", "m", "GLEW" } + + configuration { "windows" } + links { "glfw3", "gdi32", "winmm", "user32", "GLEW", "glu32","opengl32", "kernel32" } + defines { "_CRT_SECURE_NO_WARNINGS" } + + configuration { "macosx" } + includedirs { "/usr/local/include" } + buildoptions { "-Wno-deprecated-declarations" } + libdirs { "/usr/local/lib" } + links { "glfw3", "GLEW" } + linkoptions { "-framework OpenGL", "-framework Cocoa", "-framework IOKit", "-framework CoreVideo" } + + configuration "Debug" + defines { "DEBUG" } + flags { "Symbols", "ExtraWarnings"} + + configuration "Release" + defines { "NDEBUG" } + flags { "Optimize", "ExtraWarnings"} + diff --git a/src/deps/tinygltfloader-0.9.2/examples/glview/shader.frag b/src/deps/tinygltfloader-0.9.2/examples/glview/shader.frag new file mode 100644 index 0000000..1f30d3e --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/examples/glview/shader.frag @@ -0,0 +1,11 @@ +uniform sampler2D diffuseTex; + +varying vec3 normal; +varying vec2 texcoord; + +void main(void) +{ + //gl_FragColor = vec4(0.5 * normalize(normal) + 0.5, 1.0); + //gl_FragColor = vec4(texcoord, 0.0, 1.0); + gl_FragColor = texture2D(diffuseTex, texcoord); +} diff --git a/src/deps/tinygltfloader-0.9.2/examples/glview/shader.vert b/src/deps/tinygltfloader-0.9.2/examples/glview/shader.vert new file mode 100644 index 0000000..e21752d --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/examples/glview/shader.vert @@ -0,0 +1,16 @@ +attribute vec3 in_vertex; +attribute vec3 in_normal; +attribute vec2 in_texcoord; + +varying vec3 normal; +varying vec2 texcoord; + +void main(void) +{ + vec4 p = gl_ModelViewProjectionMatrix * vec4(in_vertex, 1); + gl_Position = p; + vec4 nn = gl_ModelViewMatrixInverseTranspose * vec4(normalize(in_normal), 0); + normal = nn.xyz; + + texcoord = in_texcoord; +} diff --git a/src/deps/tinygltfloader-0.9.2/examples/glview/trackball.cc b/src/deps/tinygltfloader-0.9.2/examples/glview/trackball.cc new file mode 100644 index 0000000..86ff3b3 --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/examples/glview/trackball.cc @@ -0,0 +1,292 @@ +/* + * (c) Copyright 1993, 1994, Silicon Graphics, Inc. + * ALL RIGHTS RESERVED + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright notice + * and this permission notice appear in supporting documentation, and that + * the name of Silicon Graphics, Inc. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" + * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY + * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, + * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF + * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN + * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE + * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor + * clauses in the FAR or the DOD or NASA FAR Supplement. + * Unpublished-- rights reserved under the copyright laws of the + * United States. Contractor/manufacturer is Silicon Graphics, + * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. + * + * OpenGL(TM) is a trademark of Silicon Graphics, Inc. + */ +/* + * Trackball code: + * + * Implementation of a virtual trackball. + * Implemented by Gavin Bell, lots of ideas from Thant Tessman and + * the August '88 issue of Siggraph's "Computer Graphics," pp. 121-129. + * + * Vector manip code: + * + * Original code from: + * David M. Ciemiewicz, Mark Grossman, Henry Moreton, and Paul Haeberli + * + * Much mucking with by: + * Gavin Bell + */ +#include +#include "trackball.h" + +/* + * This size should really be based on the distance from the center of + * rotation to the point on the object underneath the mouse. That + * point would then track the mouse as closely as possible. This is a + * simple example, though, so that is left as an Exercise for the + * Programmer. + */ +#define TRACKBALLSIZE (0.8) + +/* + * Local function prototypes (not defined in trackball.h) + */ +static float tb_project_to_sphere(float, float, float); +static void normalize_quat(float[4]); + +static void vzero(float *v) { + v[0] = 0.0; + v[1] = 0.0; + v[2] = 0.0; +} + +static void vset(float *v, float x, float y, float z) { + v[0] = x; + v[1] = y; + v[2] = z; +} + +static void vsub(const float *src1, const float *src2, float *dst) { + dst[0] = src1[0] - src2[0]; + dst[1] = src1[1] - src2[1]; + dst[2] = src1[2] - src2[2]; +} + +static void vcopy(const float *v1, float *v2) { + register int i; + for (i = 0; i < 3; i++) + v2[i] = v1[i]; +} + +static void vcross(const float *v1, const float *v2, float *cross) { + float temp[3]; + + temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]); + temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]); + temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]); + vcopy(temp, cross); +} + +static float vlength(const float *v) { + return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +} + +static void vscale(float *v, float div) { + v[0] *= div; + v[1] *= div; + v[2] *= div; +} + +static void vnormal(float *v) { vscale(v, 1.0 / vlength(v)); } + +static float vdot(const float *v1, const float *v2) { + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; +} + +static void vadd(const float *src1, const float *src2, float *dst) { + dst[0] = src1[0] + src2[0]; + dst[1] = src1[1] + src2[1]; + dst[2] = src1[2] + src2[2]; +} + +/* + * Ok, simulate a track-ball. Project the points onto the virtual + * trackball, then figure out the axis of rotation, which is the cross + * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0) + * Note: This is a deformed trackball-- is a trackball in the center, + * but is deformed into a hyperbolic sheet of rotation away from the + * center. This particular function was chosen after trying out + * several variations. + * + * It is assumed that the arguments to this routine are in the range + * (-1.0 ... 1.0) + */ +void trackball(float q[4], float p1x, float p1y, float p2x, float p2y) { + float a[3]; /* Axis of rotation */ + float phi; /* how much to rotate about axis */ + float p1[3], p2[3], d[3]; + float t; + + if (p1x == p2x && p1y == p2y) { + /* Zero rotation */ + vzero(q); + q[3] = 1.0; + return; + } + + /* + * First, figure out z-coordinates for projection of P1 and P2 to + * deformed sphere + */ + vset(p1, p1x, p1y, tb_project_to_sphere(TRACKBALLSIZE, p1x, p1y)); + vset(p2, p2x, p2y, tb_project_to_sphere(TRACKBALLSIZE, p2x, p2y)); + + /* + * Now, we want the cross product of P1 and P2 + */ + vcross(p2, p1, a); + + /* + * Figure out how much to rotate around that axis. + */ + vsub(p1, p2, d); + t = vlength(d) / (2.0 * TRACKBALLSIZE); + + /* + * Avoid problems with out-of-control values... + */ + if (t > 1.0) + t = 1.0; + if (t < -1.0) + t = -1.0; + phi = 2.0 * asin(t); + + axis_to_quat(a, phi, q); +} + +/* + * Given an axis and angle, compute quaternion. + */ +void axis_to_quat(float a[3], float phi, float q[4]) { + vnormal(a); + vcopy(a, q); + vscale(q, sin(phi / 2.0)); + q[3] = cos(phi / 2.0); +} + +/* + * Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet + * if we are away from the center of the sphere. + */ +static float tb_project_to_sphere(float r, float x, float y) { + float d, t, z; + + d = sqrt(x * x + y * y); + if (d < r * 0.70710678118654752440) { /* Inside sphere */ + z = sqrt(r * r - d * d); + } else { /* On hyperbola */ + t = r / 1.41421356237309504880; + z = t * t / d; + } + return z; +} + +/* + * Given two rotations, e1 and e2, expressed as quaternion rotations, + * figure out the equivalent single rotation and stuff it into dest. + * + * This routine also normalizes the result every RENORMCOUNT times it is + * called, to keep error from creeping in. + * + * NOTE: This routine is written so that q1 or q2 may be the same + * as dest (or each other). + */ + +#define RENORMCOUNT 97 + +void add_quats(float q1[4], float q2[4], float dest[4]) { + static int count = 0; + float t1[4], t2[4], t3[4]; + float tf[4]; + + vcopy(q1, t1); + vscale(t1, q2[3]); + + vcopy(q2, t2); + vscale(t2, q1[3]); + + vcross(q2, q1, t3); + vadd(t1, t2, tf); + vadd(t3, tf, tf); + tf[3] = q1[3] * q2[3] - vdot(q1, q2); + + dest[0] = tf[0]; + dest[1] = tf[1]; + dest[2] = tf[2]; + dest[3] = tf[3]; + + if (++count > RENORMCOUNT) { + count = 0; + normalize_quat(dest); + } +} + +/* + * Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0 + * If they don't add up to 1.0, dividing by their magnitued will + * renormalize them. + * + * Note: See the following for more information on quaternions: + * + * - Shoemake, K., Animating rotation with quaternion curves, Computer + * Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985. + * - Pletinckx, D., Quaternion calculus as a basic tool in computer + * graphics, The Visual Computer 5, 2-13, 1989. + */ +static void normalize_quat(float q[4]) { + int i; + float mag; + + mag = (q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); + for (i = 0; i < 4; i++) + q[i] /= mag; +} + +/* + * Build a rotation matrix, given a quaternion rotation. + * + */ +void build_rotmatrix(float m[4][4], const float q[4]) { + m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]); + m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]); + m[0][2] = 2.0 * (q[2] * q[0] + q[1] * q[3]); + m[0][3] = 0.0; + + m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]); + m[1][1] = 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]); + m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]); + m[1][3] = 0.0; + + m[2][0] = 2.0 * (q[2] * q[0] - q[1] * q[3]); + m[2][1] = 2.0 * (q[1] * q[2] + q[0] * q[3]); + m[2][2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]); + m[2][3] = 0.0; + + m[3][0] = 0.0; + m[3][1] = 0.0; + m[3][2] = 0.0; + m[3][3] = 1.0; +} diff --git a/src/deps/tinygltfloader-0.9.2/examples/glview/trackball.h b/src/deps/tinygltfloader-0.9.2/examples/glview/trackball.h new file mode 100644 index 0000000..b1f9437 --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/examples/glview/trackball.h @@ -0,0 +1,75 @@ +/* + * (c) Copyright 1993, 1994, Silicon Graphics, Inc. + * ALL RIGHTS RESERVED + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright notice + * and this permission notice appear in supporting documentation, and that + * the name of Silicon Graphics, Inc. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" + * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY + * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, + * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF + * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN + * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE + * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor + * clauses in the FAR or the DOD or NASA FAR Supplement. + * Unpublished-- rights reserved under the copyright laws of the + * United States. Contractor/manufacturer is Silicon Graphics, + * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. + * + * OpenGL(TM) is a trademark of Silicon Graphics, Inc. + */ +/* + * trackball.h + * A virtual trackball implementation + * Written by Gavin Bell for Silicon Graphics, November 1988. + */ + +/* + * Pass the x and y coordinates of the last and current positions of + * the mouse, scaled so they are from (-1.0 ... 1.0). + * + * The resulting rotation is returned as a quaternion rotation in the + * first paramater. + */ +void trackball(float q[4], float p1x, float p1y, float p2x, float p2y); + +void negate_quat(float *q, float *qn); + +/* + * Given two quaternions, add them together to get a third quaternion. + * Adding quaternions to get a compound rotation is analagous to adding + * translations to get a compound translation. When incrementally + * adding rotations, the first argument here should be the new + * rotation, the second and third the total rotation (which will be + * over-written with the resulting new total rotation). + */ +void add_quats(float *q1, float *q2, float *dest); + +/* + * A useful function, builds a rotation matrix in Matrix based on + * given quaternion. + */ +void build_rotmatrix(float m[4][4], const float q[4]); + +/* + * This function computes a quaternion based on an axis (defined by + * the given vector) and an angle about which to rotate. The angle is + * expressed in radians. The result is put into the third argument. + */ +void axis_to_quat(float a[3], float phi, float q[4]); diff --git a/src/deps/tinygltfloader-0.9.2/images/glview_duck.png b/src/deps/tinygltfloader-0.9.2/images/glview_duck.png new file mode 100644 index 0000000000000000000000000000000000000000..e19caffd567f3db5dfe3de5e75e11a05f7d52711 GIT binary patch literal 108605 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%0DH0YO;YxGd^PnEk}v=`cncoT|`EK2u1 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// for isnan/isinf +#if __cplusplus>=201103L +# include +#else +extern "C" { +# ifdef _MSC_VER +# include +# elif defined(__INTEL_COMPILER) +# include +# else +# include +# endif +} +#endif + +#ifndef PICOJSON_USE_RVALUE_REFERENCE +# if (defined(__cpp_rvalue_references) && __cpp_rvalue_references >= 200610) || (defined(_MSC_VER) && _MSC_VER >= 1600) +# define PICOJSON_USE_RVALUE_REFERENCE 1 +# else +# define PICOJSON_USE_RVALUE_REFERENCE 0 +# endif +#endif//PICOJSON_USE_RVALUE_REFERENCE + + +// experimental support for int64_t (see README.mkdn for detail) +#ifdef PICOJSON_USE_INT64 +# define __STDC_FORMAT_MACROS +# include +# include +#endif + +// to disable the use of localeconv(3), set PICOJSON_USE_LOCALE to 0 +#ifndef PICOJSON_USE_LOCALE +# define PICOJSON_USE_LOCALE 1 +#endif +#if PICOJSON_USE_LOCALE +extern "C" { +# include +} +#endif + +#ifndef PICOJSON_ASSERT +# define PICOJSON_ASSERT(e) do { if (! (e)) throw std::runtime_error(#e); } while (0) +#endif + +#ifdef _MSC_VER + #define SNPRINTF _snprintf_s + #pragma warning(push) + #pragma warning(disable : 4244) // conversion from int to char + #pragma warning(disable : 4127) // conditional expression is constant + #pragma warning(disable : 4702) // unreachable code +#else + #define SNPRINTF snprintf +#endif + +namespace picojson { + + enum { + null_type, + boolean_type, + number_type, + string_type, + array_type, + object_type +#ifdef PICOJSON_USE_INT64 + , int64_type +#endif + }; + + enum { + INDENT_WIDTH = 2 + }; + + struct null {}; + + class value { + public: + typedef std::vector array; + typedef std::map object; + union _storage { + bool boolean_; + double number_; +#ifdef PICOJSON_USE_INT64 + int64_t int64_; +#endif + std::string* string_; + array* array_; + object* object_; + }; + protected: + int type_; + _storage u_; + public: + value(); + value(int type, bool); + explicit value(bool b); +#ifdef PICOJSON_USE_INT64 + explicit value(int64_t i); +#endif + explicit value(double n); + explicit value(const std::string& s); + explicit value(const array& a); + explicit value(const object& o); + explicit value(const char* s); + value(const char* s, size_t len); + ~value(); + value(const value& x); + value& operator=(const value& x); +#if PICOJSON_USE_RVALUE_REFERENCE + value(value&& x)throw(); + value& operator=(value&& x)throw(); +#endif + void swap(value& x)throw(); + template bool is() const; + template const T& get() const; + template T& get(); + bool evaluate_as_boolean() const; + const value& get(size_t idx) const; + const value& get(const std::string& key) const; + value& get(size_t idx); + value& get(const std::string& key); + + bool contains(size_t idx) const; + bool contains(const std::string& key) const; + std::string to_str() const; + template void serialize(Iter os, bool prettify = false) const; + std::string serialize(bool prettify = false) const; + private: + template value(const T*); // intentionally defined to block implicit conversion of pointer to bool + template static void _indent(Iter os, int indent); + template void _serialize(Iter os, int indent) const; + std::string _serialize(int indent) const; + }; + + typedef value::array array; + typedef value::object object; + + inline value::value() : type_(null_type) {} + + inline value::value(int type, bool) : type_(type) { + switch (type) { +#define INIT(p, v) case p##type: u_.p = v; break + INIT(boolean_, false); + INIT(number_, 0.0); +#ifdef PICOJSON_USE_INT64 + INIT(int64_, 0); +#endif + INIT(string_, new std::string()); + INIT(array_, new array()); + INIT(object_, new object()); +#undef INIT + default: break; + } + } + + inline value::value(bool b) : type_(boolean_type) { + u_.boolean_ = b; + } + +#ifdef PICOJSON_USE_INT64 + inline value::value(int64_t i) : type_(int64_type) { + u_.int64_ = i; + } +#endif + + inline value::value(double n) : type_(number_type) { + if ( +#ifdef _MSC_VER + ! _finite(n) +#elif __cplusplus>=201103L || !(defined(isnan) && defined(isinf)) + std::isnan(n) || std::isinf(n) +#else + isnan(n) || isinf(n) +#endif + ) { + throw std::overflow_error(""); + } + u_.number_ = n; + } + + inline value::value(const std::string& s) : type_(string_type) { + u_.string_ = new std::string(s); + } + + inline value::value(const array& a) : type_(array_type) { + u_.array_ = new array(a); + } + + inline value::value(const object& o) : type_(object_type) { + u_.object_ = new object(o); + } + + inline value::value(const char* s) : type_(string_type) { + u_.string_ = new std::string(s); + } + + inline value::value(const char* s, size_t len) : type_(string_type) { + u_.string_ = new std::string(s, len); + } + + inline value::~value() { + switch (type_) { +#define DEINIT(p) case p##type: delete u_.p; break + DEINIT(string_); + DEINIT(array_); + DEINIT(object_); +#undef DEINIT + default: break; + } + } + + inline value::value(const value& x) : type_(x.type_) { + switch (type_) { +#define INIT(p, v) case p##type: u_.p = v; break + INIT(string_, new std::string(*x.u_.string_)); + INIT(array_, new array(*x.u_.array_)); + INIT(object_, new object(*x.u_.object_)); +#undef INIT + default: + u_ = x.u_; + break; + } + } + + inline value& value::operator=(const value& x) { + if (this != &x) { + value t(x); + swap(t); + } + return *this; + } + +#if PICOJSON_USE_RVALUE_REFERENCE + inline value::value(value&& x)throw() : type_(null_type) { + swap(x); + } + inline value& value::operator=(value&& x)throw() { + swap(x); + return *this; + } +#endif + inline void value::swap(value& x)throw() { + std::swap(type_, x.type_); + std::swap(u_, x.u_); + } + +#define IS(ctype, jtype) \ + template <> inline bool value::is() const { \ + return type_ == jtype##_type; \ + } + IS(null, null) + IS(bool, boolean) +#ifdef PICOJSON_USE_INT64 + IS(int64_t, int64) +#endif + IS(std::string, string) + IS(array, array) + IS(object, object) +#undef IS + template <> inline bool value::is() const { + return type_ == number_type +#ifdef PICOJSON_USE_INT64 + || type_ == int64_type +#endif + ; + } + +#define GET(ctype, var) \ + template <> inline const ctype& value::get() const { \ + PICOJSON_ASSERT("type mismatch! call is() before get()" \ + && is()); \ + return var; \ + } \ + template <> inline ctype& value::get() { \ + PICOJSON_ASSERT("type mismatch! call is() before get()" \ + && is()); \ + return var; \ + } + GET(bool, u_.boolean_) + GET(std::string, *u_.string_) + GET(array, *u_.array_) + GET(object, *u_.object_) +#ifdef PICOJSON_USE_INT64 + GET(double, (type_ == int64_type && (const_cast(this)->type_ = number_type, const_cast(this)->u_.number_ = u_.int64_), u_.number_)) + GET(int64_t, u_.int64_) +#else + GET(double, u_.number_) +#endif +#undef GET + + inline bool value::evaluate_as_boolean() const { + switch (type_) { + case null_type: + return false; + case boolean_type: + return u_.boolean_; + case number_type: + return u_.number_ != 0; +#ifdef PICOJSON_USE_INT64 + case int64_type: + return u_.int64_ != 0; +#endif + case string_type: + return ! u_.string_->empty(); + default: + return true; + } + } + + inline const value& value::get(size_t idx) const { + static value s_null; + PICOJSON_ASSERT(is()); + return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null; + } + + inline value& value::get(size_t idx) { + static value s_null; + PICOJSON_ASSERT(is()); + return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null; + } + + inline const value& value::get(const std::string& key) const { + static value s_null; + PICOJSON_ASSERT(is()); + object::const_iterator i = u_.object_->find(key); + return i != u_.object_->end() ? i->second : s_null; + } + + inline value& value::get(const std::string& key) { + static value s_null; + PICOJSON_ASSERT(is()); + object::iterator i = u_.object_->find(key); + return i != u_.object_->end() ? i->second : s_null; + } + + inline bool value::contains(size_t idx) const { + PICOJSON_ASSERT(is()); + return idx < u_.array_->size(); + } + + inline bool value::contains(const std::string& key) const { + PICOJSON_ASSERT(is()); + object::const_iterator i = u_.object_->find(key); + return i != u_.object_->end(); + } + + inline std::string value::to_str() const { + switch (type_) { + case null_type: return "null"; + case boolean_type: return u_.boolean_ ? "true" : "false"; +#ifdef PICOJSON_USE_INT64 + case int64_type: { + char buf[sizeof("-9223372036854775808")]; + SNPRINTF(buf, sizeof(buf), "%" PRId64, u_.int64_); + return buf; + } +#endif + case number_type: { + char buf[256]; + double tmp; + SNPRINTF(buf, sizeof(buf), fabs(u_.number_) < (1ULL << 53) && modf(u_.number_, &tmp) == 0 ? "%.f" : "%.17g", u_.number_); +#if PICOJSON_USE_LOCALE + char *decimal_point = localeconv()->decimal_point; + if (strcmp(decimal_point, ".") != 0) { + size_t decimal_point_len = strlen(decimal_point); + for (char *p = buf; *p != '\0'; ++p) { + if (strncmp(p, decimal_point, decimal_point_len) == 0) { + return std::string(buf, p) + "." + (p + decimal_point_len); + } + } + } +#endif + return buf; + } + case string_type: return *u_.string_; + case array_type: return "array"; + case object_type: return "object"; + default: PICOJSON_ASSERT(0); +#ifdef _MSC_VER + __assume(0); +#endif + } + return std::string(); + } + + template void copy(const std::string& s, Iter oi) { + std::copy(s.begin(), s.end(), oi); + } + + template void serialize_str(const std::string& s, Iter oi) { + *oi++ = '"'; + for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) { + switch (*i) { +#define MAP(val, sym) case val: copy(sym, oi); break + MAP('"', "\\\""); + MAP('\\', "\\\\"); + MAP('/', "\\/"); + MAP('\b', "\\b"); + MAP('\f', "\\f"); + MAP('\n', "\\n"); + MAP('\r', "\\r"); + MAP('\t', "\\t"); +#undef MAP + default: + if (static_cast(*i) < 0x20 || *i == 0x7f) { + char buf[7]; + SNPRINTF(buf, sizeof(buf), "\\u%04x", *i & 0xff); + copy(buf, buf + 6, oi); + } else { + *oi++ = *i; + } + break; + } + } + *oi++ = '"'; + } + + template void value::serialize(Iter oi, bool prettify) const { + return _serialize(oi, prettify ? 0 : -1); + } + + inline std::string value::serialize(bool prettify) const { + return _serialize(prettify ? 0 : -1); + } + + template void value::_indent(Iter oi, int indent) { + *oi++ = '\n'; + for (int i = 0; i < indent * INDENT_WIDTH; ++i) { + *oi++ = ' '; + } + } + + template void value::_serialize(Iter oi, int indent) const { + switch (type_) { + case string_type: + serialize_str(*u_.string_, oi); + break; + case array_type: { + *oi++ = '['; + if (indent != -1) { + ++indent; + } + for (array::const_iterator i = u_.array_->begin(); + i != u_.array_->end(); + ++i) { + if (i != u_.array_->begin()) { + *oi++ = ','; + } + if (indent != -1) { + _indent(oi, indent); + } + i->_serialize(oi, indent); + } + if (indent != -1) { + --indent; + if (! u_.array_->empty()) { + _indent(oi, indent); + } + } + *oi++ = ']'; + break; + } + case object_type: { + *oi++ = '{'; + if (indent != -1) { + ++indent; + } + for (object::const_iterator i = u_.object_->begin(); + i != u_.object_->end(); + ++i) { + if (i != u_.object_->begin()) { + *oi++ = ','; + } + if (indent != -1) { + _indent(oi, indent); + } + serialize_str(i->first, oi); + *oi++ = ':'; + if (indent != -1) { + *oi++ = ' '; + } + i->second._serialize(oi, indent); + } + if (indent != -1) { + --indent; + if (! u_.object_->empty()) { + _indent(oi, indent); + } + } + *oi++ = '}'; + break; + } + default: + copy(to_str(), oi); + break; + } + if (indent == 0) { + *oi++ = '\n'; + } + } + + inline std::string value::_serialize(int indent) const { + std::string s; + _serialize(std::back_inserter(s), indent); + return s; + } + + template class input { + protected: + Iter cur_, end_; + int last_ch_; + bool ungot_; + int line_; + public: + input(const Iter& first, const Iter& last) : cur_(first), end_(last), last_ch_(-1), ungot_(false), line_(1) {} + int getc() { + if (ungot_) { + ungot_ = false; + return last_ch_; + } + if (cur_ == end_) { + last_ch_ = -1; + return -1; + } + if (last_ch_ == '\n') { + line_++; + } + last_ch_ = *cur_ & 0xff; + ++cur_; + return last_ch_; + } + void ungetc() { + if (last_ch_ != -1) { + PICOJSON_ASSERT(! ungot_); + ungot_ = true; + } + } + Iter cur() const { return cur_; } + int line() const { return line_; } + void skip_ws() { + while (1) { + int ch = getc(); + if (! (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) { + ungetc(); + break; + } + } + } + bool expect(int expect) { + skip_ws(); + if (getc() != expect) { + ungetc(); + return false; + } + return true; + } + bool match(const std::string& pattern) { + for (std::string::const_iterator pi(pattern.begin()); + pi != pattern.end(); + ++pi) { + if (getc() != *pi) { + ungetc(); + return false; + } + } + return true; + } + }; + + template inline int _parse_quadhex(input &in) { + int uni_ch = 0, hex; + for (int i = 0; i < 4; i++) { + if ((hex = in.getc()) == -1) { + return -1; + } + if ('0' <= hex && hex <= '9') { + hex -= '0'; + } else if ('A' <= hex && hex <= 'F') { + hex -= 'A' - 0xa; + } else if ('a' <= hex && hex <= 'f') { + hex -= 'a' - 0xa; + } else { + in.ungetc(); + return -1; + } + uni_ch = uni_ch * 16 + hex; + } + return uni_ch; + } + + template inline bool _parse_codepoint(String& out, input& in) { + int uni_ch; + if ((uni_ch = _parse_quadhex(in)) == -1) { + return false; + } + if (0xd800 <= uni_ch && uni_ch <= 0xdfff) { + if (0xdc00 <= uni_ch) { + // a second 16-bit of a surrogate pair appeared + return false; + } + // first 16-bit of surrogate pair, get the next one + if (in.getc() != '\\' || in.getc() != 'u') { + in.ungetc(); + return false; + } + int second = _parse_quadhex(in); + if (! (0xdc00 <= second && second <= 0xdfff)) { + return false; + } + uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff); + uni_ch += 0x10000; + } + if (uni_ch < 0x80) { + out.push_back(uni_ch); + } else { + if (uni_ch < 0x800) { + out.push_back(0xc0 | (uni_ch >> 6)); + } else { + if (uni_ch < 0x10000) { + out.push_back(0xe0 | (uni_ch >> 12)); + } else { + out.push_back(0xf0 | (uni_ch >> 18)); + out.push_back(0x80 | ((uni_ch >> 12) & 0x3f)); + } + out.push_back(0x80 | ((uni_ch >> 6) & 0x3f)); + } + out.push_back(0x80 | (uni_ch & 0x3f)); + } + return true; + } + + template inline bool _parse_string(String& out, input& in) { + while (1) { + int ch = in.getc(); + if (ch < ' ') { + in.ungetc(); + return false; + } else if (ch == '"') { + return true; + } else if (ch == '\\') { + if ((ch = in.getc()) == -1) { + return false; + } + switch (ch) { +#define MAP(sym, val) case sym: out.push_back(val); break + MAP('"', '\"'); + MAP('\\', '\\'); + MAP('/', '/'); + MAP('b', '\b'); + MAP('f', '\f'); + MAP('n', '\n'); + MAP('r', '\r'); + MAP('t', '\t'); +#undef MAP + case 'u': + if (! _parse_codepoint(out, in)) { + return false; + } + break; + default: + return false; + } + } else { + out.push_back(ch); + } + } + return false; + } + + template inline bool _parse_array(Context& ctx, input& in) { + if (! ctx.parse_array_start()) { + return false; + } + size_t idx = 0; + if (in.expect(']')) { + return ctx.parse_array_stop(idx); + } + do { + if (! ctx.parse_array_item(in, idx)) { + return false; + } + idx++; + } while (in.expect(',')); + return in.expect(']') && ctx.parse_array_stop(idx); + } + + template inline bool _parse_object(Context& ctx, input& in) { + if (! ctx.parse_object_start()) { + return false; + } + if (in.expect('}')) { + return true; + } + do { + std::string key; + if (! in.expect('"') + || ! _parse_string(key, in) + || ! in.expect(':')) { + return false; + } + if (! ctx.parse_object_item(in, key)) { + return false; + } + } while (in.expect(',')); + return in.expect('}'); + } + + template inline std::string _parse_number(input& in) { + std::string num_str; + while (1) { + int ch = in.getc(); + if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-' + || ch == 'e' || ch == 'E') { + num_str.push_back(ch); + } else if (ch == '.') { +#if PICOJSON_USE_LOCALE + num_str += localeconv()->decimal_point; +#else + num_str.push_back('.'); +#endif + } else { + in.ungetc(); + break; + } + } + return num_str; + } + + template inline bool _parse(Context& ctx, input& in) { + in.skip_ws(); + int ch = in.getc(); + switch (ch) { +#define IS(ch, text, op) case ch: \ + if (in.match(text) && op) { \ + return true; \ + } else { \ + return false; \ + } + IS('n', "ull", ctx.set_null()); + IS('f', "alse", ctx.set_bool(false)); + IS('t', "rue", ctx.set_bool(true)); +#undef IS + case '"': + return ctx.parse_string(in); + case '[': + return _parse_array(ctx, in); + case '{': + return _parse_object(ctx, in); + default: + if (('0' <= ch && ch <= '9') || ch == '-') { + double f; + char *endp; + in.ungetc(); + std::string num_str = _parse_number(in); + if (num_str.empty()) { + return false; + } +#ifdef PICOJSON_USE_INT64 + { + errno = 0; + intmax_t ival = strtoimax(num_str.c_str(), &endp, 10); + if (errno == 0 + && std::numeric_limits::min() <= ival + && ival <= std::numeric_limits::max() + && endp == num_str.c_str() + num_str.size()) { + ctx.set_int64(ival); + return true; + } + } +#endif + f = strtod(num_str.c_str(), &endp); + if (endp == num_str.c_str() + num_str.size()) { + ctx.set_number(f); + return true; + } + return false; + } + break; + } + in.ungetc(); + return false; + } + + class deny_parse_context { + public: + bool set_null() { return false; } + bool set_bool(bool) { return false; } +#ifdef PICOJSON_USE_INT64 + bool set_int64(int64_t) { return false; } +#endif + bool set_number(double) { return false; } + template bool parse_string(input&) { return false; } + bool parse_array_start() { return false; } + template bool parse_array_item(input&, size_t) { + return false; + } + bool parse_array_stop(size_t) { return false; } + bool parse_object_start() { return false; } + template bool parse_object_item(input&, const std::string&) { + return false; + } + }; + + class default_parse_context { + protected: + value* out_; + public: + default_parse_context(value* out) : out_(out) {} + bool set_null() { + *out_ = value(); + return true; + } + bool set_bool(bool b) { + *out_ = value(b); + return true; + } +#ifdef PICOJSON_USE_INT64 + bool set_int64(int64_t i) { + *out_ = value(i); + return true; + } +#endif + bool set_number(double f) { + *out_ = value(f); + return true; + } + template bool parse_string(input& in) { + *out_ = value(string_type, false); + return _parse_string(out_->get(), in); + } + bool parse_array_start() { + *out_ = value(array_type, false); + return true; + } + template bool parse_array_item(input& in, size_t) { + array& a = out_->get(); + a.push_back(value()); + default_parse_context ctx(&a.back()); + return _parse(ctx, in); + } + bool parse_array_stop(size_t) { return true; } + bool parse_object_start() { + *out_ = value(object_type, false); + return true; + } + template bool parse_object_item(input& in, const std::string& key) { + object& o = out_->get(); + default_parse_context ctx(&o[key]); + return _parse(ctx, in); + } + private: + default_parse_context(const default_parse_context&); + default_parse_context& operator=(const default_parse_context&); + }; + + class null_parse_context { + public: + struct dummy_str { + void push_back(int) {} + }; + public: + null_parse_context() {} + bool set_null() { return true; } + bool set_bool(bool) { return true; } +#ifdef PICOJSON_USE_INT64 + bool set_int64(int64_t) { return true; } +#endif + bool set_number(double) { return true; } + template bool parse_string(input& in) { + dummy_str s; + return _parse_string(s, in); + } + bool parse_array_start() { return true; } + template bool parse_array_item(input& in, size_t) { + return _parse(*this, in); + } + bool parse_array_stop(size_t) { return true; } + bool parse_object_start() { return true; } + template bool parse_object_item(input& in, const std::string&) { + return _parse(*this, in); + } + private: + null_parse_context(const null_parse_context&); + null_parse_context& operator=(const null_parse_context&); + }; + + // obsolete, use the version below + template inline std::string parse(value& out, Iter& pos, const Iter& last) { + std::string err; + pos = parse(out, pos, last, &err); + return err; + } + + template inline Iter _parse(Context& ctx, const Iter& first, const Iter& last, std::string* err) { + input in(first, last); + if (! _parse(ctx, in) && err != NULL) { + char buf[64]; + SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line()); + *err = buf; + while (1) { + int ch = in.getc(); + if (ch == -1 || ch == '\n') { + break; + } else if (ch >= ' ') { + err->push_back(ch); + } + } + } + return in.cur(); + } + + template inline Iter parse(value& out, const Iter& first, const Iter& last, std::string* err) { + default_parse_context ctx(&out); + return _parse(ctx, first, last, err); + } + + inline std::string parse(value& out, const std::string& s) { + std::string err; + parse(out, s.begin(), s.end(), &err); + return err; + } + + inline std::string parse(value& out, std::istream& is) { + std::string err; + parse(out, std::istreambuf_iterator(is.rdbuf()), + std::istreambuf_iterator(), &err); + return err; + } + + template struct last_error_t { + static std::string s; + }; + template std::string last_error_t::s; + + inline void set_last_error(const std::string& s) { + last_error_t::s = s; + } + + inline const std::string& get_last_error() { + return last_error_t::s; + } + + inline bool operator==(const value& x, const value& y) { + if (x.is()) + return y.is(); +#define PICOJSON_CMP(type) \ + if (x.is()) \ + return y.is() && x.get() == y.get() + PICOJSON_CMP(bool); + PICOJSON_CMP(double); + PICOJSON_CMP(std::string); + PICOJSON_CMP(array); + PICOJSON_CMP(object); +#undef PICOJSON_CMP + PICOJSON_ASSERT(0); +#ifdef _MSC_VER + __assume(0); +#endif + return false; + } + + inline bool operator!=(const value& x, const value& y) { + return ! (x == y); + } +} + +#if !PICOJSON_USE_RVALUE_REFERENCE +namespace std { + template<> inline void swap(picojson::value& x, picojson::value& y) + { + x.swap(y); + } +} +#endif + +inline std::istream& operator>>(std::istream& is, picojson::value& x) +{ + picojson::set_last_error(std::string()); + std::string err = picojson::parse(x, is); + if (! err.empty()) { + picojson::set_last_error(err); + is.setstate(std::ios::failbit); + } + return is; +} + +inline std::ostream& operator<<(std::ostream& os, const picojson::value& x) +{ + x.serialize(std::ostream_iterator(os)); + return os; +} +#ifdef _MSC_VER + #pragma warning(pop) +#endif + +#endif diff --git a/src/deps/tinygltfloader-0.9.2/premake4.lua b/src/deps/tinygltfloader-0.9.2/premake4.lua new file mode 100644 index 0000000..d6178d7 --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/premake4.lua @@ -0,0 +1,29 @@ +sources = { + "test.cc", + } + +-- premake4.lua +solution "TinyGLTFLoaderSolution" + configurations { "Release", "Debug" } + + if (os.is("windows")) then + platforms { "x32", "x64" } + else + platforms { "native", "x32", "x64" } + end + + -- A project defines one build target + project "tinygltfloader" + kind "ConsoleApp" + language "C++" + files { sources } + + configuration "Debug" + defines { "DEBUG" } -- -DDEBUG + flags { "Symbols" } + targetname "test_tinygltfloader_debug" + + configuration "Release" + -- defines { "NDEBUG" } -- -NDEBUG + flags { "Symbols", "Optimize" } + targetname "test_tinygltfloader" diff --git a/src/deps/tinygltfloader-0.9.2/stb_image.h b/src/deps/tinygltfloader-0.9.2/stb_image.h new file mode 100644 index 0000000..0a9de39 --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/stb_image.h @@ -0,0 +1,6509 @@ +/* stb_image - v2.08 - 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.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 + 1.48 (2014-12-14) fix incorrectly-named assert() + 1.47 (2014-12-14) 1/2/4-bit PNG support (both grayscale and paletted) + optimize PNG + fix bug in interlaced PNG with user-specified channel count + + See end of file for full revision history. + + + ============================ Contributors ========================= + + Image formats Bug fixes & warning fixes + Sean Barrett (jpeg, png, bmp) Marc LeBlanc + Nicolas Schulz (hdr, psd) Christpher Lloyd + Jonathan Dummer (tga) Dave Moore + Jean-Marc Lienher (gif) Won Chun + Tom Seddon (pic) the Horde3D community + Thatcher Ulrich (psd) Janez Zemva + Ken Miller (pgm, ppm) Jonathan Blow + urraka@github (animated gif) Laurent Gomila + Aruelien Pocheville + Ryamond Barbiero + David Woo + Extensions, features Martin Golini + Jetro Lauha (stbi_info) Roy Eltham + Martin "SpartanJ" Golini (stbi_info) Luke Graham + James "moose2000" Brown (iPhone PNG) Thomas Ruf + Ben "Disch" Wenger (io callbacks) John Bartholomew + Omar Cornut (1/2/4-bit PNG) Ken Hamada + Nicolas Guillemot (vertical flip) Cort Stratton + Richard Mitton (16-bit PSD) Blazej Dariusz Roszkowski + Thibault Reuille + Paul Du Bois + Guillaume George + Jerry Jansson + Hayaki Saito + Johan Duparc + Ronny Chevalier + Optimizations & bugfixes Michal Cichon + Fabian "ryg" Giesen Tero Hanninen + Arseny Kapoulkine Sergio Gonzalez + Cass Everitt + Engin Manap + If your name should be here but Martins Mozeiko + isn't, let Sean know. Joseph Thomson + Phil Jordan + Nathan Reed + Michaelangel007@github + Nick Verigakis + +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. + +*/ + +#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 + +#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_HDR + +// 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) +// ok +#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) +// ok +#else +#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC." +#endif + +#ifndef STBI_MALLOC +#define STBI_MALLOC(sz) malloc(sz) +#define STBI_REALLOC(p,sz) realloc(p,sz) +#define STBI_FREE(p) free(p) +#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) +#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 + 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 + 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 +} + +static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; +static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; + +#ifndef STBI_NO_LINEAR +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 + +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 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"); + + for (i=0; i < s->img_n; ++i) { + 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! + return stbi__err("bad component ID","Corrupt JPEG"); + 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) { + 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) +{ + stbi__jpeg j; + j.s = s; + stbi__setup_jpeg(&j); + return load_jpeg_image(&j, x,y,comp,req_comp); +} + +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) +{ + stbi__jpeg j; + j.s = s; + return stbi__jpeg_info_raw(&j, x, y, comp); +} +#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; + z->zout = zout; + if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); + cur = (int) (z->zout - z->zout_start); + limit = (int) (z->zout_end - z->zout_start); + while (cur + n > limit) + limit *= 2; + q = (char *) STBI_REALLOC(z->zout_start, 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_uncomperssed_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_uncomperssed_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; +} 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) +{ + stbi__context *s = a->s; + stbi__uint32 i,j,stride = x*out_n; + stbi__uint32 img_len, img_width_bytes; + int k; + int img_n = s->img_n; // copy it into a local for later + + STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); + a->out = (stbi_uc *) stbi__malloc(x * y * out_n); // 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++; + int filter_bytes = img_n; + int width = x; + 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 { + 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)*img_n; + #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[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \ + for (k=0; k < img_n; ++k) + switch (filter) { + CASE(STBI__F_none) cur[k] = raw[k]; break; + CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-out_n]); 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-out_n])>>1)); break; + CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],prior[k],prior[k-out_n])); break; + CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-out_n] >> 1)); break; + CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],0,0)); break; + } + #undef CASE + } + } + + // 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]; + } + } + } + } + } + + 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__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__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__uint32 ioff=0, idata_limit=0, i, pal_len=0; + int first=1,k,interlace=0, color=0, depth=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?)"); + depth = stbi__get8(s); if (depth != 1 && depth != 2 && depth != 4 && depth != 8) return stbi__err("1/2/4/8-bit only","PNG not supported: 1/2/4/8-bit only"); + color = stbi__get8(s); if (color > 6) 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; + for (k=0; k < s->img_n; ++k) + tc[k] = (stbi_uc) (stbi__get16be(s) & 255) * stbi__depth_scale_table[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_uc *p; + if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + p = (stbi_uc *) STBI_REALLOC(z->idata, 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 * 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, depth, color, interlace)) return 0; + if (has_trans) + 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)) { + 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_out_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; +} + +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=255; + stbi_uc pal[256][4]; + int psize=0,i,j,compress=0,width; + int bpp, flip_vertically, pad, target, offset, 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 + offset = stbi__get32le(s); + hsz = stbi__get32le(s); + 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"); + bpp = stbi__get16le(s); + if (bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit"); + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + if (hsz == 12) { + if (bpp < 24) + psize = (offset - 14 - 24) / 3; + } else { + 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 (bpp == 16 || bpp == 32) { + mr = mg = mb = 0; + if (compress == 0) { + if (bpp == 32) { + mr = 0xffu << 16; + mg = 0xffu << 8; + mb = 0xffu << 0; + ma = 0xffu << 24; + all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 + } else { + mr = 31u << 10; + mg = 31u << 5; + mb = 31u << 0; + } + } else if (compress == 3) { + mr = stbi__get32le(s); + mg = stbi__get32le(s); + mb = stbi__get32le(s); + // not documented, but generated by photoshop and handled by mspaint + if (mr == mg && mg == mb) { + // ?!?!? + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else { + STBI_ASSERT(hsz == 108 || hsz == 124); + mr = stbi__get32le(s); + mg = stbi__get32le(s); + mb = stbi__get32le(s); + 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 + } + } + if (bpp < 16) + psize = (offset - 14 - 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 (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 (hsz != 12) stbi__get8(s); + pal[i][3] = 255; + } + stbi__skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4)); + if (bpp == 4) width = (s->img_x + 1) >> 1; + else if (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 (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 = (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, offset - 14 - hsz); + if (bpp == 24) width = 3 * s->img_x; + else if (bpp == 16) width = 2*s->img_x; + else /* bpp = 32 and pad = 0 */ width=0; + pad = (-width) & 3; + if (bpp == 24) { + easy = 1; + } else if (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 { + 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 +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) +{ + int tga_w, tga_h, tga_comp; + int sz; + stbi__get8(s); // discard Offset + sz = stbi__get8(s); // color type + if( sz > 1 ) { + stbi__rewind(s); + return 0; // only RGB or indexed allowed + } + sz = stbi__get8(s); // image type + // only RGB or grey allowed, +/- RLE + if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0; + stbi__skip(s,9); + 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 + } + sz = stbi__get8(s); // bits per pixel + // only RGB or RGBA or grey allowed + if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) { + stbi__rewind(s); + return 0; + } + tga_comp = sz; + if (x) *x = tga_w; + if (y) *y = tga_h; + if (comp) *comp = tga_comp / 8; + return 1; // seems to have passed everything +} + +static int stbi__tga_test(stbi__context *s) +{ + int res; + int sz; + stbi__get8(s); // discard Offset + sz = stbi__get8(s); // color type + if ( sz > 1 ) return 0; // only RGB or indexed allowed + sz = stbi__get8(s); // image type + if ( (sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11) ) return 0; // only RGB or grey allowed, +/- RLE + stbi__get16be(s); // discard palette start + stbi__get16be(s); // discard palette length + stbi__get8(s); // discard bits per palette color entry + stbi__get16be(s); // discard x origin + stbi__get16be(s); // discard y origin + if ( stbi__get16be(s) < 1 ) return 0; // test width + if ( stbi__get16be(s) < 1 ) return 0; // test height + sz = stbi__get8(s); // bits per pixel + if ( (sz != 8) && (sz != 16) && (sz != 24) && (sz != 32) ) + res = 0; + else + res = 1; + stbi__rewind(s); + return res; +} + +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_bits_per_pixel / 8; + int tga_inverted = stbi__get8(s); + // 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; + } + /* int tga_alpha_bits = tga_inverted & 15; */ + tga_inverted = 1 - ((tga_inverted >> 5) & 1); + + // error check + if ( //(tga_indexed) || + (tga_width < 1) || (tga_height < 1) || + (tga_image_type < 1) || (tga_image_type > 3) || + ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) && + (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32)) + ) + { + return NULL; // we don't report this as a bad TGA because we don't even know if it's TGA + } + + // If I'm paletted, then I'll use the number of bits from the palette + if ( tga_indexed ) + { + tga_comp = tga_palette_bits / 8; + } + + // 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) { + 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_palette_bits / 8 ); + if (!tga_palette) { + STBI_FREE(tga_data); + return stbi__errpuc("outofmem", "Out of memory"); + } + if (!stbi__getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8 )) { + 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 1 byte, then perform the lookup + int pal_idx = stbi__get8(s); + if ( pal_idx >= tga_palette_len ) + { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_bits_per_pixel / 8; + for (j = 0; j*8 < tga_bits_per_pixel; ++j) + { + raw_data[j] = tga_palette[pal_idx+j]; + } + } else + { + // read in the data raw + for (j = 0; j*8 < tga_bits_per_pixel; ++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 (tga_comp >= 3) + { + 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 (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; + if (!stbi__gif_header(s, &g, comp, 1)) { + stbi__rewind( s ); + return 0; + } + if (x) *x = g.w; + if (y) *y = g.h; + 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; + 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); + + 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 (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 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) +{ + int hsz; + if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') { + stbi__rewind( s ); + return 0; + } + stbi__skip(s,12); + hsz = stbi__get32le(s); + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) { + stbi__rewind( s ); + return 0; + } + if (hsz == 12) { + *x = stbi__get16le(s); + *y = stbi__get16le(s); + } else { + *x = stbi__get32le(s); + *y = stbi__get32le(s); + } + if (stbi__get16le(s) != 1) { + stbi__rewind( s ); + return 0; + } + *comp = stbi__get16le(s) / 8; + 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) +{ + while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) + *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.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-bit 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/src/deps/tinygltfloader-0.9.2/test.cc b/src/deps/tinygltfloader-0.9.2/test.cc new file mode 100644 index 0000000..7d6056d --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/test.cc @@ -0,0 +1,377 @@ +#define TINYGLTF_LOADER_IMPLEMENTATION +#define STB_IMAGE_IMPLEMENTATION +#include "tiny_gltf_loader.h" + +#include +#include +#include + +std::string PrintMode(int mode) { + if (mode == TINYGLTF_MODE_POINTS) { + return "POINTS"; + } else if (mode == TINYGLTF_MODE_LINE) { + return "LINE"; + } else if (mode == TINYGLTF_MODE_LINE_LOOP) { + return "LINE_LOOP"; + } else if (mode == TINYGLTF_MODE_TRIANGLES) { + return "TRIANGLES"; + } else if (mode == TINYGLTF_MODE_TRIANGLE_FAN) { + return "TRIANGLE_FAN"; + } else if (mode == TINYGLTF_MODE_TRIANGLE_STRIP) { + return "TRIANGLE_STRIP"; + } + return "**UNKNOWN**"; +} + +std::string PrintType(int ty) { + if (ty == TINYGLTF_TYPE_SCALAR) { + return "SCALAR"; + } else if (ty == TINYGLTF_TYPE_VECTOR) { + return "VECTOR"; + } else if (ty == TINYGLTF_TYPE_VEC2) { + return "VEC2"; + } else if (ty == TINYGLTF_TYPE_VEC3) { + return "VEC3"; + } else if (ty == TINYGLTF_TYPE_VEC4) { + return "VEC4"; + } else if (ty == TINYGLTF_TYPE_MATRIX) { + return "MATRIX"; + } else if (ty == TINYGLTF_TYPE_MAT2) { + return "MAT2"; + } else if (ty == TINYGLTF_TYPE_MAT3) { + return "MAT3"; + } else if (ty == TINYGLTF_TYPE_MAT4) { + return "MAT4"; + } + return "**UNKNOWN**"; +} + +std::string PrintComponentType(int ty) { + if (ty == TINYGLTF_COMPONENT_TYPE_BYTE) { + return "BYTE"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) { + return "UNSIGNED_BYTE"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_SHORT) { + return "SHORT"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) { + return "UNSIGNED_SHORT"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_INT) { + return "INT"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT) { + return "UNSIGNED_INT"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_FLOAT) { + return "FLOAT"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_DOUBLE) { + return "DOUBLE"; + } + + return "**UNKNOWN**"; +} + +std::string PrintFloatArray(const std::vector &arr) { + if (arr.size() == 0) { + return ""; + } + + std::stringstream ss; + ss << "[ "; + for (size_t i = 0; i < arr.size(); i++) { + ss << arr[i] << ((i != arr.size() - 1) ? ", " : ""); + } + ss << " ]"; + + return ss.str(); +} + +std::string PrintStringArray(const std::vector &arr) { + if (arr.size() == 0) { + return ""; + } + + std::stringstream ss; + ss << "[ "; + for (size_t i = 0; i < arr.size(); i++) { + ss << arr[i] << ((i != arr.size() - 1) ? ", " : ""); + } + ss << " ]"; + + return ss.str(); +} + +std::string Indent(int indent) { + std::string s; + for (int i = 0; i < indent; i++) { + s += " "; + } + + return s; +} + +void DumpNode(const Node &node, int indent) { + std::cout << Indent(indent) << "name : " << node.name << std::endl; + std::cout << Indent(indent) << "camera : " << node.camera << std::endl; + if (!node.rotation.empty()) { + std::cout << Indent(indent) + << "rotation : " << PrintFloatArray(node.rotation) + << std::endl; + } + if (!node.scale.empty()) { + std::cout << Indent(indent) + << "scale : " << PrintFloatArray(node.scale) << std::endl; + } + if (!node.translation.empty()) { + std::cout << Indent(indent) + << "translation : " << PrintFloatArray(node.translation) + << std::endl; + } + + if (!node.matrix.empty()) { + std::cout << Indent(indent) + << "matrix : " << PrintFloatArray(node.matrix) << std::endl; + } + + std::cout << Indent(indent) + << "meshes : " << PrintStringArray(node.meshes) << std::endl; + + std::cout << Indent(indent) + << "children : " << PrintStringArray(node.children) << std::endl; +} + +void DumpPrimitive(const Primitive &primitive, int indent) { + std::cout << Indent(indent) << "material : " << primitive.material + << std::endl; + std::cout << Indent(indent) << "mode : " << PrintMode(primitive.mode) + << "(" << primitive.mode << ")" << std::endl; + std::cout << Indent(indent) + << "attributes(items=" << primitive.attributes.size() << ")" + << std::endl; + std::map::const_iterator it( + primitive.attributes.begin()); + std::map::const_iterator itEnd( + primitive.attributes.end()); + for (; it != itEnd; it++) { + std::cout << Indent(indent + 1) << it->first << ": " << it->second + << std::endl; + } +} + +void Dump(const Scene &scene) { + std::cout << "=== Dump glTF ===" << std::endl; + std::cout << "asset.generator : " << scene.asset.generator + << std::endl; + std::cout << "asset.premultipliedAlpha : " << scene.asset.premultipliedAlpha + << std::endl; + std::cout << "asset.version : " << scene.asset.version + << std::endl; + std::cout << "asset.profile.api : " << scene.asset.profile_api + << std::endl; + std::cout << "asset.profile.version : " << scene.asset.profile_version + << std::endl; + std::cout << std::endl; + std::cout << "=== Dump scene ===" << std::endl; + std::cout << "defaultScene: " << scene.defaultScene << std::endl; + + { + std::map >::const_iterator it( + scene.scenes.begin()); + std::map >::const_iterator itEnd( + scene.scenes.end()); + std::cout << "scenes(items=" << scene.scenes.size() << ")" << std::endl; + for (; it != itEnd; it++) { + std::cout << Indent(1) << "name : " << it->first << std::endl; + std::cout << Indent(2) << "nodes : [ "; + for (size_t i = 0; i < it->second.size(); i++) { + std::cout << it->second[i] + << ((i != (it->second.size() - 1)) ? ", " : ""); + } + std::cout << " ] " << std::endl; + } + } + + { + std::map::const_iterator it(scene.meshes.begin()); + std::map::const_iterator itEnd(scene.meshes.end()); + std::cout << "meshes(item=" << scene.meshes.size() << ")" << std::endl; + for (; it != itEnd; it++) { + std::cout << Indent(1) << "name : " << it->second.name << std::endl; + std::cout << Indent(1) + << "primitives(items=" << it->second.primitives.size() + << "): " << std::endl; + + for (size_t i = 0; i < it->second.primitives.size(); i++) { + DumpPrimitive(it->second.primitives[i], 2); + } + } + } + + { + std::map::const_iterator it(scene.accessors.begin()); + std::map::const_iterator itEnd( + scene.accessors.end()); + std::cout << "accessos(items=" << scene.accessors.size() << ")" + << std::endl; + for (; it != itEnd; it++) { + std::cout << Indent(1) << "name : " << it->first << std::endl; + std::cout << Indent(2) << "bufferView : " << it->second.bufferView + << std::endl; + std::cout << Indent(2) << "byteOffset : " << it->second.byteOffset + << std::endl; + std::cout << Indent(2) << "byteStride : " << it->second.byteStride + << std::endl; + std::cout << Indent(2) << "componentType: " + << PrintComponentType(it->second.componentType) << "(" + << it->second.componentType << ")" << std::endl; + std::cout << Indent(2) << "count : " << it->second.count + << std::endl; + std::cout << Indent(2) << "type : " << PrintType(it->second.type) + << std::endl; + if (!it->second.minValues.empty()) { + std::cout << Indent(2) << "min : ["; + for (size_t i = 0; i < it->second.minValues.size(); i++) { + std::cout << it->second.minValues[i] + << ((i != it->second.minValues.size() - 1) ? ", " : ""); + } + std::cout << "]" << std::endl; + } + if (!it->second.maxValues.empty()) { + std::cout << Indent(2) << "max : ["; + for (size_t i = 0; i < it->second.maxValues.size(); i++) { + std::cout << it->second.maxValues[i] + << ((i != it->second.maxValues.size() - 1) ? ", " : ""); + } + std::cout << "]" << std::endl; + } + } + } + + { + std::map::const_iterator it( + scene.bufferViews.begin()); + std::map::const_iterator itEnd( + scene.bufferViews.end()); + std::cout << "bufferViews(items=" << scene.bufferViews.size() << ")" + << std::endl; + for (; it != itEnd; it++) { + std::cout << Indent(1) << "name : " << it->first << std::endl; + std::cout << Indent(2) << "buffer : " << it->second.buffer + << std::endl; + std::cout << Indent(2) << "byteLength : " << it->second.byteLength + << std::endl; + std::cout << Indent(2) << "byteOffset : " << it->second.byteOffset + << std::endl; + } + } + + { + std::map::const_iterator it(scene.buffers.begin()); + std::map::const_iterator itEnd(scene.buffers.end()); + std::cout << "buffers(items=" << scene.buffers.size() << ")" << std::endl; + for (; it != itEnd; it++) { + std::cout << Indent(1) << "name : " << it->first << std::endl; + std::cout << Indent(2) << "byteLength : " << it->second.data.size() + << std::endl; + } + } + + { + std::map::const_iterator it(scene.materials.begin()); + std::map::const_iterator itEnd( + scene.materials.end()); + std::cout << "materials(items=" << scene.materials.size() << ")" + << std::endl; + for (; it != itEnd; it++) { + std::cout << Indent(1) << "name : " << it->first << std::endl; + std::cout << Indent(1) << "technique : " << it->second.technique + << std::endl; + std::cout << Indent(1) << "values(items=" << it->second.values.size() + << std::endl; + + ParameterMap::const_iterator p(it->second.values.begin()); + ParameterMap::const_iterator pEnd(it->second.values.end()); + for (; p != pEnd; p++) { + if (!p->second.numberArray.empty()) { + std::cout << Indent(3) << p->first + << PrintFloatArray(p->second.numberArray) << std::endl; + } + if (!p->second.stringValue.empty()) { + std::cout << Indent(3) << p->first << " : " << p->second.stringValue + << std::endl; + } + } + } + } + + { + std::map::const_iterator it(scene.nodes.begin()); + std::map::const_iterator itEnd(scene.nodes.end()); + std::cout << "nodes(items=" << scene.nodes.size() << ")" << std::endl; + for (; it != itEnd; it++) { + std::cout << Indent(1) << "name : " << it->first << std::endl; + + DumpNode(it->second, 2); + } + } + + { + std::map::const_iterator it(scene.images.begin()); + std::map::const_iterator itEnd(scene.images.end()); + std::cout << "images(items=" << scene.images.size() << ")" << std::endl; + for (; it != itEnd; it++) { + std::cout << Indent(1) << "name : " << it->first << std::endl; + + std::cout << Indent(2) << "width : " << it->second.width << std::endl; + std::cout << Indent(2) << "height : " << it->second.height + << std::endl; + std::cout << Indent(2) << "component : " << it->second.component + << std::endl; + std::cout << Indent(2) << "name : " << it->second.name << std::endl; + } + } + + { + std::map::const_iterator it(scene.textures.begin()); + std::map::const_iterator itEnd(scene.textures.end()); + std::cout << "textures(items=" << scene.textures.size() << ")" << std::endl; + for (; it != itEnd; it++) { + std::cout << Indent(1) << "name : " << it->first << std::endl; + std::cout << Indent(1) << "format : " << it->second.format + << std::endl; + std::cout << Indent(1) << "internalFormat : " << it->second.internalFormat + << std::endl; + std::cout << Indent(1) << "sampler : " << it->second.sampler + << std::endl; + std::cout << Indent(1) << "source : " << it->second.source + << std::endl; + std::cout << Indent(1) << "target : " << it->second.target + << std::endl; + std::cout << Indent(1) << "type : " << it->second.type + << std::endl; + } + } +} + +int main(int argc, char **argv) { + if (argc < 2) { + printf("Needs input.gltf\n"); + exit(1); + } + + Scene scene; + TinyGLTFLoader loader; + std::string err; + + bool ret = loader.LoadFromFile(scene, err, argv[1]); + + if (!err.empty()) { + printf("Err: %s\n", err.c_str()); + } + + if (!ret) { + printf("Failed to parse glTF\n"); + return -1; + } + + Dump(scene); + + return 0; +} diff --git a/src/deps/tinygltfloader-0.9.2/test_runner.py b/src/deps/tinygltfloader-0.9.2/test_runner.py new file mode 100644 index 0000000..26d27e8 --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/test_runner.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python + +# Assume python 2.6 or 2.7 + +import glob +import os +import subprocess + +## Simple test runner. + +# -- config ----------------------- + +# Absolute path pointing to your cloned git repo of https://github.com/KhronosGroup/glTF/sampleModels +base_model_dir = "/Users/syoyo/work/glTF/sampleModels" + +kinds = [ "glTF", "glTF-Binary", "glTF-Embedded", "glTF-MaterialsCommon"] +# --------------------------------- + +failed = [] +success = [] + +def run(filename): + + print("Testing: " + filename) + cmd = ["./loader_test", filename] + try: + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (stdout, stderr) = p.communicate() + except: + print "Failed to execute: ", cmd + raise + + if p.returncode != 0: + failed.append(filename) + print(stdout) + print(stderr) + else: + success.append(filename) + + +def test(): + + for d in os.listdir(base_model_dir): + p = os.path.join(base_model_dir, d) + if os.path.isdir(p): + for k in kinds: + targetDir = os.path.join(p, k) + g = glob.glob(targetDir + "/*.gltf") + for gltf in g: + run(gltf) + + +def main(): + + test() + + print("Success : {0}".format(len(success))) + print("Failed : {0}".format(len(failed))) + + for fail in failed: + print("FAIL: " + fail) + +if __name__ == '__main__': + main() diff --git a/src/deps/tinygltfloader-0.9.2/tiny_gltf_loader.h b/src/deps/tinygltfloader-0.9.2/tiny_gltf_loader.h new file mode 100644 index 0000000..361d634 --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/tiny_gltf_loader.h @@ -0,0 +1,1391 @@ +// +// Tiny glTF loader. +// +// Copyright (c) 2015, Syoyo Fujita. +// All rights reserved. +// (Licensed under 2-clause BSD liecense) +// +// 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. +// +// +// Version: +// - v0.9.2 Support parsing `texture` +// - v0.9.1 Support loading glTF asset from memory +// - v0.9.0 Initial +// +// Tiny glTF loader is using following libraries: +// +// - picojson: C++ JSON library. +// - base64: base64 decode/encode library. +// - stb_image: Image loading library. +// +#ifndef TINY_GLTF_LOADER_H +#define TINY_GLTF_LOADER_H + +#include +#include +#include + +namespace tinygltf { + +#define TINYGLTF_MODE_POINTS (0) +#define TINYGLTF_MODE_LINE (1) +#define TINYGLTF_MODE_LINE_LOOP (2) +#define TINYGLTF_MODE_TRIANGLES (4) +#define TINYGLTF_MODE_TRIANGLE_STRIP (5) +#define TINYGLTF_MODE_TRIANGLE_FAN (6) + +#define TINYGLTF_COMPONENT_TYPE_BYTE (5120) +#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE (5121) +#define TINYGLTF_COMPONENT_TYPE_SHORT (5122) +#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT (5123) +#define TINYGLTF_COMPONENT_TYPE_INT (5124) +#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT (5125) +#define TINYGLTF_COMPONENT_TYPE_FLOAT (5126) +#define TINYGLTF_COMPONENT_TYPE_DOUBLE (5127) + +#define TINYGLTF_TYPE_VEC2 (2) +#define TINYGLTF_TYPE_VEC3 (3) +#define TINYGLTF_TYPE_VEC4 (4) +#define TINYGLTF_TYPE_MAT2 (32 + 2) +#define TINYGLTF_TYPE_MAT3 (32 + 3) +#define TINYGLTF_TYPE_MAT4 (32 + 4) +#define TINYGLTF_TYPE_SCALAR (64 + 1) +#define TINYGLTF_TYPE_VECTOR (64 + 4) +#define TINYGLTF_TYPE_MATRIX (64 + 16) + +#define TINYGLTF_IMAGE_FORMAT_JPEG (0) +#define TINYGLTF_IMAGE_FORMAT_PNG (1) +#define TINYGLTF_IMAGE_FORMAT_BMP (2) +#define TINYGLTF_IMAGE_FORMAT_GIF (3) + +#define TINYGLTF_TEXTURE_FORMAT_RGBA (6408) +#define TINYGLTF_TEXTURE_TARGET_TEXTURE2D (3553) +#define TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE (5121) + +#define TINYGLTF_TARGET_ARRAY_BUFFER (34962) +#define TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER (34963) + +typedef struct { + std::string stringValue; + std::vector numberArray; +} Parameter; + +typedef std::map ParameterMap; + +typedef struct { + std::string name; + int width; + int height; + int component; + std::vector image; +} Image; + +typedef struct { + int format; + int internalFormat; + std::string sampler; // Required + std::string source; // Required + int target; + int type; + std::string name; +} Texture; + +typedef struct { + std::string name; + std::string technique; + ParameterMap values; +} Material; + +typedef struct { + std::string name; + std::string buffer; // Required + size_t byteOffset; // Required + size_t byteLength; // default: 0 + int target; +} BufferView; + +typedef struct { + std::string bufferView; + std::string name; + size_t byteOffset; + size_t byteStride; + int componentType; // One of TINYGLTF_COMPONENT_TYPE_*** + size_t count; + int type; // One of TINYGLTF_TYPE_*** + std::vector minValues; // Optional + std::vector maxValues; // Optional +} Accessor; + +class Camera { +public: + Camera() {} + ~Camera() {} + + std::string name; + bool isOrthographic; // false = perspective. + + // Some common properties. + float aspectRatio; + float yFov; + float zFar; + float zNear; +}; + +typedef struct { + std::map attributes; // A dictionary object of + // strings, where each string + // is the ID of the accessor + // containing an attribute. + std::string material; // The ID of the material to apply to this primitive + // when rendering. + std::string indices; // The ID of the accessor that contains the indices. + int mode; // one of TINYGLTF_MODE_*** +} Primitive; + +typedef struct { + std::string name; + std::vector primitives; +} Mesh; + +class Node { +public: + Node() {} + ~Node() {} + + std::string camera; // camera object referenced by this node. + + std::string name; + std::vector children; + std::vector rotation; // length must be 0 or 4 + std::vector scale; // length must be 0 or 3 + std::vector translation; // length must be 0 or 3 + std::vector matrix; // length must be 0 or 16 + std::vector meshes; +}; + +typedef struct { + std::string name; + std::vector data; +} Buffer; + +typedef struct { + std::string generator; + std::string version; + std::string profile_api; + std::string profile_version; + bool premultipliedAlpha; +} Asset; + +class Scene { +public: + Scene() {} + ~Scene() {} + + std::map accessors; + std::map buffers; + std::map bufferViews; + std::map materials; + std::map meshes; + std::map nodes; + std::map textures; + std::map images; + std::map > scenes; // list of nodes + + std::string defaultScene; + + Asset asset; +}; + +class TinyGLTFLoader { +public: + TinyGLTFLoader(){}; + ~TinyGLTFLoader(){}; + + /// Loads glTF asset from a file. + /// Returns false and set error string to `err` if there's an error. + bool LoadFromFile(Scene &scene, std::string &err, + const std::string &filename); + + /// Loads glTF asset from string(memory). + /// `length` = strlen(str); + /// Returns false and set error string to `err` if there's an error. + bool LoadFromString(Scene &scene, std::string &err, const char *str, + const unsigned int length, const std::string &baseDir); +}; + +} // namespace tinygltf + +#ifdef TINYGLTF_LOADER_IMPLEMENTATION +#include +#include +#include + +#include "picojson.h" +#include "stb_image.h" + +#ifdef _WIN32 +#include +#else +#include +#endif + +using namespace tinygltf; + +namespace { + +bool FileExists(const std::string &abs_filename) { + bool ret; + FILE *fp = fopen(abs_filename.c_str(), "rb"); + if (fp) { + ret = true; + fclose(fp); + } else { + ret = false; + } + + return ret; +} + +std::string ExpandFilePath(const std::string &filepath) { +#ifdef _WIN32 + DWORD len = ExpandEnvironmentStringsA(filepath.c_str(), NULL, 0); + char *str = new char[len]; + ExpandEnvironmentStringsA(filepath.c_str(), str, len); + + std::string s(str); + + delete[] str; + + return s; +#else + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + // no expansion + std::string s = filepath; +#else + std::string s; + wordexp_t p; + + if (filepath.empty()) { + return ""; + } + + // char** w; + int ret = wordexp(filepath.c_str(), &p, 0); + if (ret) { + // err + s = filepath; + return s; + } + + // Use first element only. + if (p.we_wordv) { + s = std::string(p.we_wordv[0]); + wordfree(&p); + } else { + s = filepath; + } + +#endif + + return s; +#endif +} + +std::string JoinPath(const std::string &path0, const std::string &path1) { + if (path0.empty()) { + return path1; + } else { + // check '/' + char lastChar = *path0.rbegin(); + if (lastChar != '/') { + return path0 + std::string("/") + path1; + } else { + return path0 + path1; + } + } +} + +std::string FindFile(const std::vector &paths, + const std::string &filepath) { + for (size_t i = 0; i < paths.size(); i++) { + std::string absPath = ExpandFilePath(JoinPath(paths[i], filepath)); + if (FileExists(absPath)) { + return absPath; + } + } + + return std::string(); +} + +// std::string GetFilePathExtension(const std::string& FileName) +//{ +// if(FileName.find_last_of(".") != std::string::npos) +// return FileName.substr(FileName.find_last_of(".")+1); +// return ""; +//} + +std::string GetBaseDir(const std::string &filepath) { + if (filepath.find_last_of("/\\") != std::string::npos) + return filepath.substr(0, filepath.find_last_of("/\\")); + return ""; +} + +// std::string base64_encode(unsigned char const* , unsigned int len); +std::string base64_decode(std::string const &s); + +/* + base64.cpp and base64.h + + Copyright (C) 2004-2008 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author 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 source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + 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 source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch + +*/ + +//#include "base64.h" +//#include + +static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +static inline bool is_base64(unsigned char c) { + return (isalnum(c) || (c == '+') || (c == '/')); +} + +#if 0 +std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { + std::string ret; + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; + + while (in_len--) { + char_array_3[i++] = *(bytes_to_encode++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for(i = 0; (i <4) ; i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) + { + for(j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + while((i++ < 3)) + ret += '='; + + } + + return ret; + +} +#endif + +std::string base64_decode(std::string const &encoded_string) { + int in_len = encoded_string.size(); + int i = 0; + int j = 0; + int in_ = 0; + unsigned char char_array_4[4], char_array_3[3]; + std::string ret; + + while (in_len-- && (encoded_string[in_] != '=') && + is_base64(encoded_string[in_])) { + char_array_4[i++] = encoded_string[in_]; + in_++; + if (i == 4) { + for (i = 0; i < 4; i++) + char_array_4[i] = base64_chars.find(char_array_4[i]); + + char_array_3[0] = + (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = + ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret += char_array_3[i]; + i = 0; + } + } + + if (i) { + for (j = i; j < 4; j++) + char_array_4[j] = 0; + + for (j = 0; j < 4; j++) + char_array_4[j] = base64_chars.find(char_array_4[j]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = + ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; (j < i - 1); j++) + ret += char_array_3[j]; + } + + return ret; +} + +bool LoadExternalFile(std::vector &out, std::string &err, + const std::string &filename, const std::string &basedir, + size_t reqBytes, bool checkSize) { + out.clear(); + + std::vector paths; + paths.push_back(basedir); + paths.push_back("."); + + std::string filepath = FindFile(paths, filename); + if (filepath.empty()) { + err += "File not found : " + filename; + return false; + } + + std::ifstream f(filepath.c_str(), std::ifstream::binary); + if (!f) { + err += "File open error : " + filepath; + return false; + } + + f.seekg(0, f.end); + size_t sz = f.tellg(); + std::vector buf(sz); + + f.seekg(0, f.beg); + f.read(reinterpret_cast(&buf.at(0)), sz); + f.close(); + + if (checkSize) { + if (reqBytes == sz) { + out.swap(buf); + return true; + } else { + std::stringstream ss; + ss << "File size mismatch : " << filepath << ", requestedBytes " + << reqBytes << ", but got " << sz << std::endl; + err += ss.str(); + return false; + } + } + + out.swap(buf); + return true; +} + +bool IsDataURI(const std::string &in) { + std::string header = "data:application/octet-stream;base64,"; + if (in.find(header) == 0) { + return true; + } + + header = "data:image/png;base64,"; + if (in.find(header) == 0) { + return true; + } + + header = "data:image/jpeg;base64,"; + if (in.find(header) == 0) { + return true; + } + + return false; +} + +bool DecodeDataURI(std::vector &out, const std::string &in, + size_t reqBytes, bool checkSize) { + std::string header = "data:application/octet-stream;base64,"; + std::string data; + if (in.find(header) == 0) { + data = base64_decode(in.substr(header.size())); // cut mime string. + } + + if (data.empty()) { + header = "data:image/jpeg;base64,"; + if (in.find(header) == 0) { + data = base64_decode(in.substr(header.size())); // cut mime string. + } + } + + if (data.empty()) { + header = "data:image/png;base64,"; + if (in.find(header) == 0) { + data = base64_decode(in.substr(header.size())); // cut mime string. + } + } + + if (data.empty()) { + return false; + } + + if (checkSize) { + if (data.size() != reqBytes) { + return false; + } + out.resize(reqBytes); + } else { + out.resize(data.size()); + } + std::copy(data.begin(), data.end(), out.begin()); + return true; + + return false; +} + +bool ParseBooleanProperty(bool &ret, std::string &err, + const picojson::object &o, + const std::string &property, bool required) { + picojson::object::const_iterator it = o.find(property); + if (it == o.end()) { + if (required) { + err += "'" + property + "' property is missing.\n"; + } + return false; + } + + if (!it->second.is()) { + if (required) { + err += "'" + property + "' property is not a bool type.\n"; + } + return false; + } + + ret = it->second.get(); + + return true; +} + +bool ParseNumberProperty(double &ret, std::string &err, + const picojson::object &o, const std::string &property, + bool required) { + picojson::object::const_iterator it = o.find(property); + if (it == o.end()) { + if (required) { + err += "'" + property + "' property is missing.\n"; + } + return false; + } + + if (!it->second.is()) { + if (required) { + err += "'" + property + "' property is not a number type.\n"; + } + return false; + } + + ret = it->second.get(); + + return true; +} + +bool ParseNumberArrayProperty(std::vector &ret, std::string &err, + const picojson::object &o, + const std::string &property, bool required) { + picojson::object::const_iterator it = o.find(property); + if (it == o.end()) { + if (required) { + err += "'" + property + "' property is missing.\n"; + } + return false; + } + + if (!it->second.is()) { + if (required) { + err += "'" + property + "' property is not an array.\n"; + } + return false; + } + + ret.clear(); + const picojson::array &arr = it->second.get(); + for (size_t i = 0; i < arr.size(); i++) { + if (!arr[i].is()) { + if (required) { + err += "'" + property + "' property is not a number.\n"; + } + return false; + } + ret.push_back(arr[i].get()); + } + + return true; +} + +bool ParseStringProperty(std::string &ret, std::string &err, + const picojson::object &o, const std::string &property, + bool required) { + picojson::object::const_iterator it = o.find(property); + if (it == o.end()) { + if (required) { + err += "'" + property + "' property is missing.\n"; + } + return false; + } + + if (!it->second.is()) { + if (required) { + err += "'" + property + "' property is not a string type.\n"; + } + return false; + } + + ret = it->second.get(); + + return true; +} + +bool ParseStringArrayProperty(std::vector &ret, std::string &err, + const picojson::object &o, + const std::string &property, bool required) { + picojson::object::const_iterator it = o.find(property); + if (it == o.end()) { + if (required) { + err += "'" + property + "' property is missing.\n"; + } + return false; + } + + if (!it->second.is()) { + if (required) { + err += "'" + property + "' property is not an array.\n"; + } + return false; + } + + ret.clear(); + const picojson::array &arr = it->second.get(); + for (size_t i = 0; i < arr.size(); i++) { + if (!arr[i].is()) { + if (required) { + err += "'" + property + "' property is not a string.\n"; + } + return false; + } + ret.push_back(arr[i].get()); + } + + return true; +} + +bool ParseAsset(Asset &asset, std::string &err, const picojson::object &o) { + + ParseStringProperty(asset.generator, err, o, "generator", false); + ParseBooleanProperty(asset.premultipliedAlpha, err, o, "premultipliedAlpha", + false); + + ParseStringProperty(asset.version, err, o, "version", false); + + picojson::object::const_iterator profile = o.find("profile"); + if (profile != o.end()) { + const picojson::value &v = profile->second; + if (v.contains("api") & v.get("api").is()) { + asset.profile_api = v.get("api").get(); + } + if (v.contains("version") & v.get("version").is()) { + asset.profile_version = v.get("version").get(); + } + } + + return true; +} + +bool ParseImage(Image &image, std::string &err, const picojson::object &o, + const std::string &basedir) { + + std::string uri; + if (!ParseStringProperty(uri, err, o, "uri", true)) { + return false; + } + + ParseStringProperty(image.name, err, o, "name", false); + + std::vector img; + if (IsDataURI(uri)) { + if (!DecodeDataURI(img, uri, 0, false)) { + err += "Failed to decode 'uri'.\n"; + return false; + } + } else { + // Assume external file + if (!LoadExternalFile(img, err, uri, basedir, 0, false)) { + err += "Failed to load external 'uri'.\n"; + return false; + } + if (img.empty()) { + err += "File is empty.\n"; + return false; + } + } + + int w, h, comp; + unsigned char *data = + stbi_load_from_memory(&img.at(0), img.size(), &w, &h, &comp, 0); + if (!data) { + err += "Unknown image format.\n"; + return false; + } + + if (w < 1 || h < 1) { + err += "Unknown image format.\n"; + return false; + } + + image.width = w; + image.height = h; + image.component = comp; + image.image.resize(w * h * comp); + std::copy(data, data + w * h * comp, image.image.begin()); + + return true; +} + +bool ParseTexture(Texture &texture, std::string &err, const picojson::object &o, + const std::string &basedir) { + + if (!ParseStringProperty(texture.sampler, err, o, "sampler", true)) { + return false; + } + + if (!ParseStringProperty(texture.source, err, o, "source", true)) { + return false; + } + + ParseStringProperty(texture.name, err, o, "name", false); + + double format = TINYGLTF_TEXTURE_FORMAT_RGBA; + ParseNumberProperty(format, err, o, "format", false); + + double internalFormat = TINYGLTF_TEXTURE_FORMAT_RGBA; + ParseNumberProperty(internalFormat, err, o, "internalFormat", false); + + double target = TINYGLTF_TEXTURE_TARGET_TEXTURE2D; + ParseNumberProperty(target, err, o, "target", false); + + double type = TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE; + ParseNumberProperty(type, err, o, "type", false); + + texture.format = static_cast(format); + texture.internalFormat = static_cast(internalFormat); + texture.target = static_cast(target); + texture.type = static_cast(type); + + return true; +} + +bool ParseBuffer(Buffer &buffer, std::string &err, const picojson::object &o, + const std::string &basedir) { + double byteLength; + if (!ParseNumberProperty(byteLength, err, o, "byteLength", true)) { + return false; + } + + std::string uri; + if (!ParseStringProperty(uri, err, o, "uri", true)) { + return false; + } + + picojson::object::const_iterator type = o.find("type"); + if (type != o.end()) { + if (type->second.is()) { + const std::string &ty = (type->second).get(); + if (ty.compare("arraybuffer") == 0) { + // buffer.type = "arraybuffer"; + } + } + } + + size_t bytes = static_cast(byteLength); + if (IsDataURI(uri)) { + if (!DecodeDataURI(buffer.data, uri, bytes, true)) { + err += "Failed to decode 'uri'.\n"; + return false; + } + } else { + // Assume external .bin file. + if (!LoadExternalFile(buffer.data, err, uri, basedir, bytes, true)) { + return false; + } + } + + ParseStringProperty(buffer.name, err, o, "name", false); + + return true; +} + +bool ParseBufferView(BufferView &bufferView, std::string &err, + const picojson::object &o) { + std::string buffer; + if (!ParseStringProperty(buffer, err, o, "buffer", true)) { + return false; + } + + double byteOffset; + if (!ParseNumberProperty(byteOffset, err, o, "byteOffset", true)) { + return false; + } + + double byteLength = 0.0; + ParseNumberProperty(byteLength, err, o, "byteLength", false); + + double target = 0.0; + ParseNumberProperty(target, err, o, "target", false); + int targetValue = static_cast(target); + if ((targetValue == TINYGLTF_TARGET_ARRAY_BUFFER) || + (targetValue == TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER)) { + // OK + } else { + targetValue = 0; + } + bufferView.target = targetValue; + + ParseStringProperty(bufferView.name, err, o, "name", false); + + bufferView.buffer = buffer; + bufferView.byteOffset = static_cast(byteOffset); + bufferView.byteLength = static_cast(byteLength); + + return true; +} + +bool ParseAccessor(Accessor &accessor, std::string &err, + const picojson::object &o) { + std::string bufferView; + if (!ParseStringProperty(bufferView, err, o, "bufferView", true)) { + return false; + } + + double byteOffset; + if (!ParseNumberProperty(byteOffset, err, o, "byteOffset", true)) { + return false; + } + + double componentType; + if (!ParseNumberProperty(componentType, err, o, "componentType", true)) { + return false; + } + + double count = 0.0; + if (!ParseNumberProperty(count, err, o, "count", true)) { + return false; + } + + std::string type; + if (!ParseStringProperty(type, err, o, "type", true)) { + return false; + } + + if (type.compare("SCALAR") == 0) { + accessor.type = TINYGLTF_TYPE_SCALAR; + } else if (type.compare("VEC2") == 0) { + accessor.type = TINYGLTF_TYPE_VEC2; + } else if (type.compare("VEC3") == 0) { + accessor.type = TINYGLTF_TYPE_VEC3; + } else if (type.compare("VEC4") == 0) { + accessor.type = TINYGLTF_TYPE_VEC4; + } else if (type.compare("MAT2") == 0) { + accessor.type = TINYGLTF_TYPE_MAT2; + } else if (type.compare("MAT3") == 0) { + accessor.type = TINYGLTF_TYPE_MAT3; + } else if (type.compare("MAT4") == 0) { + accessor.type = TINYGLTF_TYPE_MAT4; + } else { + std::stringstream ss; + ss << "Unsupported `type` for accessor object. Got \"" << type << "\"\n"; + err += ss.str(); + return false; + } + + double byteStride = 0.0; + ParseNumberProperty(byteStride, err, o, "byteStride", false); + + ParseStringProperty(accessor.name, err, o, "name", false); + + accessor.minValues.clear(); + accessor.maxValues.clear(); + ParseNumberArrayProperty(accessor.minValues, err, o, "min", false); + ParseNumberArrayProperty(accessor.maxValues, err, o, "max", false); + + accessor.count = static_cast(count); + accessor.bufferView = bufferView; + accessor.byteOffset = static_cast(byteOffset); + accessor.byteStride = static_cast(byteStride); + + { + int comp = static_cast(componentType); + if (comp >= TINYGLTF_COMPONENT_TYPE_BYTE && + comp <= TINYGLTF_COMPONENT_TYPE_DOUBLE) { + // OK + accessor.componentType = comp; + } else { + std::stringstream ss; + ss << "Invalid `componentType` in accessor. Got " << comp << "\n"; + err += ss.str(); + return false; + } + } + + return true; +} + +bool ParsePrimitive(Primitive &primitive, std::string &err, + const picojson::object &o) { + if (!ParseStringProperty(primitive.material, err, o, "material", true)) { + return false; + } + + double mode = static_cast(TINYGLTF_MODE_TRIANGLES); + ParseNumberProperty(mode, err, o, "mode", false); + + int primMode = static_cast(mode); + if (primMode != TINYGLTF_MODE_TRIANGLES) { + err += "Currently TinyGLTFLoader doesn not support primitive mode other \n" + "than TRIANGLES.\n"; + return false; + } + primitive.mode = primMode; + + primitive.indices = ""; + ParseStringProperty(primitive.indices, err, o, "indices", false); + + primitive.attributes.clear(); + picojson::object::const_iterator attribsObject = o.find("attributes"); + if ((attribsObject != o.end()) && + (attribsObject->second).is()) { + const picojson::object &attribs = + (attribsObject->second).get(); + picojson::object::const_iterator it(attribs.begin()); + picojson::object::const_iterator itEnd(attribs.end()); + for (; it != itEnd; it++) { + const std::string &name = it->first; + if (!(it->second).is()) { + err += "attribute expects string value.\n"; + return false; + } + const std::string &value = (it->second).get(); + + primitive.attributes[name] = value; + } + } + + return true; +} + +bool ParseMesh(Mesh &mesh, std::string &err, const picojson::object &o) { + ParseStringProperty(mesh.name, err, o, "name", false); + + mesh.primitives.clear(); + picojson::object::const_iterator primObject = o.find("primitives"); + if ((primObject != o.end()) && (primObject->second).is()) { + const picojson::array &primArray = + (primObject->second).get(); + for (size_t i = 0; i < primArray.size(); i++) { + Primitive primitive; + ParsePrimitive(primitive, err, primArray[i].get()); + mesh.primitives.push_back(primitive); + } + } + + return true; +} + +bool ParseNode(Node &node, std::string &err, const picojson::object &o) { + ParseStringProperty(node.name, err, o, "name", false); + + ParseNumberArrayProperty(node.rotation, err, o, "rotation", false); + ParseNumberArrayProperty(node.scale, err, o, "scale", false); + ParseNumberArrayProperty(node.translation, err, o, "translation", false); + ParseNumberArrayProperty(node.matrix, err, o, "matrix", false); + ParseStringArrayProperty(node.meshes, err, o, "meshes", false); + + node.children.clear(); + picojson::object::const_iterator childrenObject = o.find("children"); + if ((childrenObject != o.end()) && + (childrenObject->second).is()) { + const picojson::array &childrenArray = + (childrenObject->second).get(); + for (size_t i = 0; i < childrenArray.size(); i++) { + Node node; + if (!childrenArray[i].is()) { + err += "Invalid `children` array.\n"; + return false; + } + const std::string &childrenNode = childrenArray[i].get(); + node.children.push_back(childrenNode); + } + } + + return true; +} + +bool ParseMaterial(Material &material, std::string &err, + const picojson::object &o) { + ParseStringProperty(material.name, err, o, "name", false); + ParseStringProperty(material.technique, err, o, "technique", false); + + material.values.clear(); + picojson::object::const_iterator valuesIt = o.find("values"); + if ((valuesIt != o.end()) && (valuesIt->second).is()) { + + const picojson::object &valuesObject = + (valuesIt->second).get(); + picojson::object::const_iterator it(valuesObject.begin()); + picojson::object::const_iterator itEnd(valuesObject.end()); + + for (; it != itEnd; it++) { + // Assume number values. + Parameter param; + if (ParseStringProperty(param.stringValue, err, valuesObject, it->first, + false)) { + // Found string property. + } else if (!ParseNumberArrayProperty(param.numberArray, err, valuesObject, + it->first, false)) { + // Fallback to numer property. + double value; + if (ParseNumberProperty(value, err, valuesObject, it->first, false)) { + param.numberArray.push_back(value); + } + } + + material.values[it->first] = param; + } + } + + return true; +} +} + +bool TinyGLTFLoader::LoadFromString(Scene &scene, std::string &err, + const char *str, unsigned int length, + const std::string &baseDir) { + picojson::value v; + std::string perr = picojson::parse(v, str, str + length); + + if (!perr.empty()) { + err = perr; + return false; + } + + if (v.contains("scene") && v.get("scene").is()) { + // OK + } else { + err += "\"scene\" object not found in .gltf\n"; + return false; + } + + if (v.contains("scenes") && v.get("scenes").is()) { + // OK + } else { + err += "\"scenes\" object not found in .gltf\n"; + return false; + } + + if (v.contains("nodes") && v.get("nodes").is()) { + // OK + } else { + err += "\"nodes\" object not found in .gltf\n"; + return false; + } + + if (v.contains("accessors") && v.get("accessors").is()) { + // OK + } else { + err += "\"accessors\" object not found in .gltf\n"; + return false; + } + + if (v.contains("buffers") && v.get("buffers").is()) { + // OK + } else { + err += "\"buffers\" object not found in .gltf\n"; + return false; + } + + if (v.contains("bufferViews") && + v.get("bufferViews").is()) { + // OK + } else { + err += "\"bufferViews\" object not found in .gltf\n"; + return false; + } + + scene.buffers.clear(); + scene.bufferViews.clear(); + scene.accessors.clear(); + scene.meshes.clear(); + scene.nodes.clear(); + scene.defaultScene = ""; + + // 0. Parse Asset + if (v.contains("asset") && v.get("asset").is()) { + const picojson::object &root = v.get("asset").get(); + + ParseAsset(scene.asset, err, root); + } + + // 1. Parse Buffer + if (v.contains("buffers") && v.get("buffers").is()) { + const picojson::object &root = v.get("buffers").get(); + + picojson::object::const_iterator it(root.begin()); + picojson::object::const_iterator itEnd(root.end()); + for (; it != itEnd; it++) { + + Buffer buffer; + if (!ParseBuffer(buffer, err, (it->second).get(), + baseDir)) { + return false; + } + + scene.buffers[it->first] = buffer; + } + } + + // 2. Parse BufferView + if (v.contains("bufferViews") && + v.get("bufferViews").is()) { + + const picojson::object &root = v.get("bufferViews").get(); + + picojson::object::const_iterator it(root.begin()); + picojson::object::const_iterator itEnd(root.end()); + for (; it != itEnd; it++) { + + BufferView bufferView; + if (!ParseBufferView(bufferView, err, + (it->second).get())) { + return false; + } + + scene.bufferViews[it->first] = bufferView; + } + } + + // 3. Parse Accessor + if (v.contains("accessors") && v.get("accessors").is()) { + + const picojson::object &root = v.get("accessors").get(); + + picojson::object::const_iterator it(root.begin()); + picojson::object::const_iterator itEnd(root.end()); + for (; it != itEnd; it++) { + + Accessor accessor; + if (!ParseAccessor(accessor, err, (it->second).get())) { + return false; + } + + scene.accessors[it->first] = accessor; + } + } + + // 4. Parse Mesh + if (v.contains("meshes") && v.get("meshes").is()) { + + const picojson::object &root = v.get("meshes").get(); + + picojson::object::const_iterator it(root.begin()); + picojson::object::const_iterator itEnd(root.end()); + for (; it != itEnd; it++) { + + Mesh mesh; + if (!ParseMesh(mesh, err, (it->second).get())) { + return false; + } + + scene.meshes[it->first] = mesh; + } + } + + // 5. Parse Node + if (v.contains("nodes") && v.get("nodes").is()) { + + const picojson::object &root = v.get("nodes").get(); + + picojson::object::const_iterator it(root.begin()); + picojson::object::const_iterator itEnd(root.end()); + for (; it != itEnd; it++) { + + Node node; + if (!ParseNode(node, err, (it->second).get())) { + return false; + } + + scene.nodes[it->first] = node; + } + } + + // 6. Parse scenes. + if (v.contains("scenes") && v.get("scenes").is()) { + + const picojson::object &root = v.get("scenes").get(); + + picojson::object::const_iterator it(root.begin()); + picojson::object::const_iterator itEnd(root.end()); + for (; it != itEnd; it++) { + + const picojson::object &o = (it->second).get(); + std::vector nodes; + if (!ParseStringArrayProperty(nodes, err, o, "nodes", false)) { + return false; + } + + scene.scenes[it->first] = nodes; + } + } + + // 7. Parse default scenes. + if (v.contains("scene") && v.get("scene").is()) { + + const std::string defaultScene = v.get("scene").get(); + + scene.defaultScene = defaultScene; + } + + // 8. Parse Material + if (v.contains("materials") && v.get("materials").is()) { + + const picojson::object &root = v.get("materials").get(); + + picojson::object::const_iterator it(root.begin()); + picojson::object::const_iterator itEnd(root.end()); + for (; it != itEnd; it++) { + + Material material; + if (!ParseMaterial(material, err, (it->second).get())) { + return false; + } + + scene.materials[it->first] = material; + } + } + + // 9. Parse Image + if (v.contains("images") && v.get("images").is()) { + + const picojson::object &root = v.get("images").get(); + + picojson::object::const_iterator it(root.begin()); + picojson::object::const_iterator itEnd(root.end()); + for (; it != itEnd; it++) { + + Image image; + if (!ParseImage(image, err, (it->second).get(), + baseDir)) { + return false; + } + + scene.images[it->first] = image; + } + } + + // 9. Parse Texture + if (v.contains("textures") && v.get("textures").is()) { + + const picojson::object &root = v.get("textures").get(); + + picojson::object::const_iterator it(root.begin()); + picojson::object::const_iterator itEnd(root.end()); + for (; it != itEnd; it++) { + + Texture texture; + if (!ParseTexture(texture, err, (it->second).get(), + baseDir)) { + return false; + } + + scene.textures[it->first] = texture; + } + } + + return true; +} + +bool TinyGLTFLoader::LoadFromFile(Scene &scene, std::string &err, + const std::string &filename) { + std::stringstream ss; + + std::ifstream f(filename.c_str()); + if (!f) { + ss << "Failed to open file: " << filename << std::endl; + err = ss.str(); + return false; + } + + f.seekg(0, f.end); + size_t sz = f.tellg(); + std::vector buf(sz); + + f.seekg(0, f.beg); + f.read(&buf.at(0), sz); + f.close(); + + std::string basedir = GetBaseDir(filename); + + bool ret = LoadFromString(scene, err, &buf.at(0), buf.size(), basedir); + + return ret; +} + +#endif // TINYGLTF_LOADER_IMPLEMENTATION + +#endif // TINY_GLTF_LOADER_H diff --git a/src/deps/tinygltfloader-0.9.2/tools/windows/premake5.exe b/src/deps/tinygltfloader-0.9.2/tools/windows/premake5.exe new file mode 100644 index 0000000000000000000000000000000000000000..c0bf928d0ab4b377eed48ef1d0162e97d5d1eaeb GIT binary patch literal 514560 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,jV*)uZk&RJ9MdBa9i6-or}V*qO~P+QuGw>QqRf) zGH`*Pi~QKxtsB8xMYXGCUlI-a7E&TF`l_gM#Uo`~@O^zd$DOnq-sn@x4h6kc&Xs3c zu$maH<$?fy^-g9QA#!~+-kY2&-f26u=2YaruqHJ@M;B=DBXC~hOw?7!ha0=)B-JM> zZrgdIbEacH$18$XU2MEd*nCc25K5d=5zS-c3q1iA1cW5W{z7${0hKT~>{%=u-^EQOZd?bFkq9snM^US`}$s6y_2Kk zOk!7GqR#W!iLVdZukO$jcJ&wN>h(l`2Mpb1MM)YOjLaK@%(xyReauY4=R*ARevOnNRCt;rusHZG657Ez>?UqDB1Zr zjAJInc4wFkn@^ELQk&ib3y>LXl#KD8yun{~SB^<hAj2k|8*(wQNDiN}=k-)ms@1zJdR3LFe|y_r>H*q}WMgWh zFhiDRP#UbC2%95PIp?W5zcjsR6h2A z)Sh8!zRJ;qNPt)35k0A;lvVm#B7$yAFJTbZTE9 z!np0+hVyJKE0T5eXQ*MK7C4A8%%fxVs9L|OcwFXoejb6&QXEr$xQSax}<3fDPmlZyfnojK3l(vrr7NwJoKA<>~azBIwh zJ>J~NSZh@w#O#&O)L)y`9lb&_v(pYKS?TFKp6ysE@xbhepmMXpQ=LbrvNyF?W$2Ef zQxmPy&TWBU7|&062qAm@>dZP}XZY6Ju^`t`eT>udOYaMH+*22OKJ)OQ&cA0nf+%;k z+OA003NidH0EkGT1P9(y`O<#ToMc1GprkJKt%o#HVIQ5=%Ice>mynDgzDTQGYjhr4 zaa~_83oZ}eE;#3nTq9m`hSx@?r!J7%CWGt{$HjCfmuagu(?-X>U7cr7TdwXMzNBp&XTQMWL*8uGHYvc)cWt} zk-_~}XL3;eLgnGui<%~lg9J)jmpguWMEJR}z!7!xKGTy%)|-Y|7XxtgUELRYLRHd}YFF8wj@n!z-h-iY z&Zu|EEc!hXlsTGRF~<`bW-TNdbo4`A4$5m(b;PDED%;nfBPZVfYjCzFoUP~U7i+;_ zPIk+%i;TLi-tNmuWyF{9Ubx+-d#s9(&$9Y-?$ugWTi&;avKedlOddEbrsXwOFP_=x z6XDp`o@`a+SQ4arKl>%^!En%`I73$Q|mJ{_g#F?O1EB$La#paBpOC z&Ln4%_v7Y+Ha`H7OZ$u2UgKi+#s5)m=lf0vy11Np4eDBFyauad^xlNQtW56gd_UWo zeV!+t%inylJf3}C0oF%WgU8ClK-pu>o8lBZ<#|(FSTHA_(`W)!u_ro`(=jKP1;Fm) zStxybU30hQ3N>4lXbb7O8YLS+V^>X1#&kit==4|%^dUENIm;+Hh8IWl6ec!@dEFw| ze3LsAv6uO+OQom@n|WM_v|KUM2!&$R&^z^0UA?LLELj?!M0Jm#6L8@U8u#76w!OMn zMnpYsD$$5S6#^x*mZzQ`P)Q->r7ZeZQxYz32oLd{ouZ^A! zdRHi(gtcAE>0@W?_%RKp5a3Y>UgzrJ}Bu6~Nk=vp*oP4aR!uYJhctfG}I%dOF z9&R7UtMZ{*@u~t%sK?k=#KW}}@ep10vKyraJN~JanW!zS7!y5AZDCj3Unn*YpB;Q4 z_Km`f*f&t3b1QYNCwU)8w*J6v0M*Zv2OQ1kUdnkuQ9Rq zHuT}M3agM4+|kUJ_{NB2JRYCl8n519by+WZ=Wl4qwH9sgzP@fg|I01ySI~OSsx*YC zx8x;9=PbwT@ujy|f2$~kS7aT|iGFHP!_sz()av%k*-ze<*(NpDI5=Il#!_QjerYNy z+Xuy|vW~v=k9hQ!c(ffY<=3pYI^PldgIKc2v28)ca#v(zV*YLQ)azG2>xGl4ZckO; z!T@PdV6R`ogKnbwHh*fP^iJJG9;?@}w%yXX64G#`;|L}bUDhk{gye}=x5gK3z^jRu znqw6NBXOK(ZM&yrD~`8&T5{q`H^if@-op`(W1pQI>vVdzH@|G@;#PGlLsGJ%eqm~( z3|nfWjIZL-pm99mF&9AoG|}cTSTTkl$7VR!T2{z}#jAVRqLH8DqjsplBT+4~P+>$g z7F=y!y+_@NHmP_!)=HQ(v=m~ifH=bPA$`w_HM3hp&ecK@!OF3aNkKa?5Y4mlhGS&H z{xNU3Gfp%|{p5<*x@uxu#Ztn1wE1z6qH;RGyH}6q%68{Fa)n86iLd=q@5lrzq1s{h zgOTDPVSZ0ps^+DCAS*>mK!m|cYiY0eR>+QRb2;|nwiO$SDwkaIWEW=LT622=VeT<$ zeh4j#8T`|E7c;fG{EdHsg_y4Sf)Q-||HuwPKwN66X`ADkCOA+Vy>#iN0reC;7=E|~ zW5J~Xo-hz#sX+j)XenGf#=;)wRW^%~Kp~@+xY!fB($$+WC;BmiX_G~n9*m!&!x*Hp zecNa1{V9240-d4S@Gx7?;>^a_(Xp7!`)v|ivRD==q{w>irT5uG1hU-KqxD{+4LhVG zxBp_mAnxQvm_H1ZP-2`C!~@82>TRS-{FkjRkE$dyM5JJ31``hN=6h+ zQNK&)anD8?T)i}}(RyBF8LMB@l!jwdswSCPqnV)Zrt>yNKg5qu@-3)~w2ulvJ5c^$ zj2v4qmL0-xj?p~5LK;;d=f^K|rD#NdIaCY&ew4?L_9a_=G#X|xC|Y%qAy%VwysU8_ybjFUh@ey zKte(or*#3P7-SX=Lt!>inF2wss{p_}Jw!>paLy&`K&MuAPA@q_g}*UJfQ@~{9Kb#x zx0c813C1&p&eWjlsktGsCR1f0-JyR7nda9bC@rP31{Ee3d^WzgG29r1$a}kc0RbsQ z&e+>>Rv@uD6$ocGsH+VEG^oQops=uxQxkgcx0WG_+seglW^p_i@_2a}Q zm)4Irztx~_VzzajWqgv6@Kg@;VEy@+#byQA<`7yAE(kRjIP|Kpwc*b*5OSmss6q0@ zDZT@1!7h#G;tG^20SqSo;kkHu0o;OU8f`TqD8hb_LBtK)TRP7}i95rZ=Ndllm>`2Q5kUfUu>2_d9?x}QtU z@J!rf;DZNuh2T{{jQ|{8g~7a$C1abcqJ`#yt}w^4Cr(DVZhAli1kOt7_$x=j*Dyxr zT&35-_hQ6XL*>pxk&(r7rJ2Rv05K2-t7JPHuy~Z&@D`gb0$j}jh%E&utRAK=-Lqdw zrP_DzF}){CrH&wuP+00Ns?sg5?`!#0ovDaSZjLU;Fa_2Ld8X}GK{b@8Yq0^^a19^G zAwx7vw-Hd+gX5TjXnT&yq{*|cq=~$|h;4B7u^NF(9QzIFYgNpQL2O#RKv;^PQ*V_Bz}LbxtWDP*?yEhM z+85}-y0Ne13mPGG?aW&oOH17bY?Mb_U)*Z&RL3O_GfJCTr|F)TQ;DvvL>?rS-Glt% zsr5M&Y%g$retM#}bM2r7=n~l7l0y=~OzUXk(&KSZWFbnYf3w&zPvyLL)P2jVyrs3- zp>}rg&~DtH3lUv_QcG68?GF@`GbD8$4GWHHN_!D6jDbdL@XsZpJe+AUj|_LUHh*|5 zhxV%TY7vnARzIRwIL^z@c#%C1?;>16k$~QJ(of=@U|P6KZ#Ht|O}fpYEU2E!lBV*^ z>EB*L0kyP;RI|UsgXKMvxo5x2hc?Qb=|~A!^)42hg+pNs3Zc?mi}P5w-zKKh$!u&x z{VsfmaoH9LrziEN^>W2&p~|6Jh)uRW(3`rn3_Q45zCWcvAubSunH>}j_nDf&w#%pNklZRxH|AymX zV|r=Jy$G{~Z53v8bF~aY`m~wW(;wj|DztKLX4xSvRCBM+x1JL}TY*680(I6snrfik zxIiuCSt4N*$hg)OUrdw*_pOLXGpy&Wm+-z)2coL=S2?7K&8&tv}Tn;?Z8K z5?KL0R*tF5fu<2}z}MAA7BH%3$=>Jrt(d1I0fw==l&cK#gc4X^J*HC`$!Zam^)UON zia2vVK75IjMu*ty(~gzJYl4Hy2`o(piR`Y6GlF=wmdb8`S7u4(#X3D$9M5&PeUseO z2puzHphw^$GXhy=1jgUpKLSg5PLF^mzPQ|a9wX>7>ANRh-aga&T=S>tp0^aHmKO!p zw`d%y$SHxbasHmR38dBhZkh|XJt}Y?4-gs?wM+sd)Ca|m&bMtSes)(s6o2KpQRoI! zag1A*Vk})BjL*$iud^hB>P+gQDnTcyOM5dL!PPOpp3y}EYO-`q3=B@%=1y(f*|OMr z#X2Ic*UGaJ3-cD>Z)z=}>04&T#rxec;tA0me7Qj~f^p|y^~8Wzd`qg|$~)u)M{!&8 z@HPookQZN+R~LPTt4A^tfCXXsg8n^qXMg`bvGoc7oGxen^4n&4Uu^!A z*OP+k2C2@PTgafIJj-kTXL?9w|1uZrbArZURc-ky{KA7^0o5U;8i|`)b(OR+jH$cW z6|dk19+o;8SgqF<{y*N{1u)9uYW&{KZjuESHb??NK%)e2k%~qt5U5FD173m&k;D`M zt%_-C6=4@d2}#_fvOL}D+t#m)$h=L?QWWV2; zXE!7o?Ct-4=;pbdnK^T2=FFLM&YVe`;~-$V$P{^MT@g^YoD}*p9SKU5KE>?2fVIcT zAef!PMmbU9uuo^Y61_b)nW~cIV&U4^bJTt2%{A&C^X6K$#Jssq`J^*JCZI2bj5_-RCDk}>S6B*ST^L?^DS0;Lyp64cUYpT zxJ&!!YUU>vtQ%||p^Zkl%vo_f({onE@fn_>oASu1;`kVsduzz14diXYUHsnN{<0ST z!u@J3oS{_j-j={@s^Y}y$Id)88BGx4UFIndPa8!q+$>rQ{ZkrT-1YFr9db z%$wqWtwW_RP@Q9Xbr_QL0OX_b0@POJ_n7EJm7BTeWD7Ek_NTC;GA`N7~wHuEq4! zD@QXJg${PHWZC`Mc6MLLZkKEa(=KnbiR8)aMEyF^pPkH0c4=g%=+~+Gb+SMEqR8t> z`t_B(_Ghy(Y-}1khq^NvrAmoI+wJ^7<#P;Yl+y+ zSe9$?Uw^{U;^;BZ5SzzoE1KJEGLeoGNetwh4Ot80E6b2g1 z9TbG;Rzk+doL1iCxw5J_&U;yZ=zKNOga$MbEf?hc=95||7*kU`9#54%J`2QZ#^iOM zGq4mH&KbBV0Tpa$T%r1q?c92zcVskrQZwH2jLEWnoOaySnpP{(!X4^YKQl+AXIIE6 z#zo9;8E?5B?e&I$j9R@$n@YghZ-}}=EJna_vSys?2Q{Gu_<4FqVqE*Gx>s`!+(l|! zKdr@Lm03E>R9}8etHDurggM+`sA+pB64Ev@Xnn`So_zTs3V7EQM0@Gi1)K{+Ti#%~$Y~GQ+@@~5)J21Nw505Q`s?!RS%Sv5=*=>1& z8#?oO{R3E-Ze~}txLpaXd@WFAGl_E|F{3EUnB8g2ar$$6Focbf5?ocsXg?G1Hl1s`S<{m%%IcvD)fe||?s^Rf{oKZLaw zC>ymj=68r-)nnV9<2#Hv*CSHECZmjyqMgXlsJ5>Jy`^k_N^hd;pyi$40Thxbio#jQ ztnae!5(Q?fVM7gWEbS@8WVQSsAZ~m z^6;xEP&qQ=O6;D*sjD2G^CP40vZ+(OY1nk!%mUiPWtyXHXc$q-4X1?Mgfy#pEQg%H z5nXloI@p>cf-M%imBj0`8#g3NoUaZH3TTax>`|YGY)FX4@O87Npw{=#??k|U*6Fz@ zd_$(k{;b_|Zhn#4LFmJZ@;EE5FjcdLL1i+V--$>rnQX09aTAbH$hRG;;`QKGEWO&U z_H|EK`EvpbjCN;PYCjxR`<~r4zXyI8C+v{udT_%WN9e)Y4~OYbM?>#RUZeD(G4xA} zIXzulB?PLgY9Zq+I3H7RZ$3V@O!_`d$k?;|)8KTz8tx9h8M7Wqls%tT3Spk15N3`X zNAPi{bPXVeiK#{qIqG*4S-cUiQwwIvfV(Di1z&Nd;mO!u`JT9lNNwClO}r})%7V`2 zZZ_PVAgMp~6wb>F%0l6DS;J^H%nP_TG`KfK^3MzYS}J7Xcq2H*8P_`eRxzgP?Xc{1 z#e|7bqTBV|yM;}}QTbz;v3PragGa))FeGo{E^l6ux^t0c6~P9g=FqLbi1vH-+CwIW zdQ5qHY4U0Gfqqh%d2sX?buES1YBMx58Mu*;3E2Q~Zic9+^>h@38u{nEtOe~|=cNS9p655i16YNIv*Bz!eBx#`6c_vx%(OH%xSn;||7FQ8DOpaArqr8b zLRF=4L0KC9Ulw_m6gkwaY_Tsf{)R`OC7;!{Yo{C z(<%PVhSi*=Z`Uy!7Kz5@&GX&Q-)l|kCO~B^j7KEs+!me@u*ZK*OYFIAoCE@-n?J?w z7A-{sFszuRiwMcVS+JziLBX|=fnw6>|24*G8siCO<0K3+*8;QjTELmA)HEdib7Vk> zPNbCMkhO@FV6`9Hy#G`>uldb(mhxTDiE$^s#FySAW3jjm}d^s|MvW!fx3I0|(+rVs}`86_94vmWP z%;tH<9+TmJVN}5DAdI(DwX;cmy4Y-J(|I4dh_?Urt$B;y&= z6MP1?CXPIKf3Kl~#d2<2Z~y9T!;Gz-g`r$cY+bt^+EUg^bj$m6qABbkkl5Ry_y)I} zcCM;i zq(;{2)94ux4+X&5+oWe8Z6R6Bb_D11#K1t=jQg0~w#Q%Oz#5~o8Q&+HVP-Z*xCGB9 z3FCBb3V(9&QoHDF`uE86CKexCT|cPRtB__^Av_NizeLyUS|}`9hObfsD$Zc1i!v5Q zBKVlZ=AlrIItY#cB#@IrHN;^mK!ks{@{B6vEKWLrUOdE?Y+*o#GWaH3$CEg3o=Q3W zv0XmmS+1bG&6ARsr)>Ho`JlQ=D6#)uw87)1Kufn0t%GPgZpII!yLYe-N3`jzJw#Xd zlZjoh46b10qy*+p0)2m0ijkA*&q|drE?KO(6Yvla52P%d&XWCE$#|jllbg(j4rEP& z>!D%kMxi=8SruoKXKuTU>e-3DS{n_*lEL<-h$whTvb3f9c~TJ+vpPjm%sMKPVpcbp z_U{`=$2bqtLH5#}bq8TOG|NQZrP9gh&(rGVtUaE4o8I8tP81=-MW!Z$HI7(U^$#VB zVc*($g>UPdHkK8N9+r_mcFk}Z?CmXlB!~H;8#kNud$*B5cR#}6OTcr)GX$=gtw7G- zFJObi9LC@)#EqR;rv%NrQ72>VMe}`_FxNkSKZR8v zEB|eu3#x+x!@O)aqb&^| z#4-mBf;ka?VTcCd)ddF0Ed)YX{W#cSNt3Rh( zFF|_fSO&F3^V~^5?h7nocROYbUwr~;rp|9)yvyq{G7E%R~4O2@Ll8s6P>KVef_86ofvV|H?wahK!t z%|@B|(#Lv^hm{QhCXmyq!30Bz^M{4ugKIU}+}-du2H++MW0C75-txJ^obD%i@8AgD zB~KWeYkB|`|KSr~&9Wq2m1Rlcm(6bhzcPM5<=4V5%x~V5EX$wyb@R)gnq_&N-`A#P zS)S*2Nk*1sKfk-DXIXy3Zy&!qXRz$#w}am`Un4JmNmplCrt^D}-%)y$oZ1H^NMABAkq+5Gz2I!uWbF zU}Ir{ni7T7x;t0N?IIx&H#OZHb>)sYrZmpHG`i@QMA2}4w**p`+yz*H`q>rI3L!Z} zU6f9V1?uRBl8zIu`n!)s^jkAOuiyGnO^8jgQT^8cbVznuzx9~tx6Uh#sH=>Ss zkvDrU*Z4&gSj2zRWYbznF+G<5j?cV%CZ(3aOHP271I=Q&r?_GFZ{XvxAQ719JM2dL2VrW#d3Ee;O$ zqilY3hXhgS?{nDc432pZFf_S0JLd#`(@DOy(Sd*N-Z>@WXe{S-#4$nDL7iD@mL}|JX*x}E~R23OSz;F*C z32lH%h;VI4ICdB=Gee#;ZF}wU7(!4Rd5PD+A7VKe1+7;djX7#+nRCTiyc?VbM-Imr zH*fCAsPj1U#8>7LawWg0u1b1}1h*HDOSVCvIhWo++GO_olGpHS{KNc(b^_A}uC@B- z+V$ZEy(WJ&$-eU}zFX~t4NDN;UYIVsm$FVDQHW^iO)6C1r#;z%81~wSuF#g(gP!7{80O1a zc5#vJuZ{GaZRoiizEPk6(1m&~HqtXrxpKPLL}$miqCyyyE>5>DXZawsO*`e?8Bubh z*Xt@xEJ=A{wnfeVv5W)tV@!g@n{sh2S~3-hGgCz6eWCQHr*m7mNnYf+2|*cpX$TYe zlBsKxdE-5hzR$PG!`-kIgQh;FxN$vNN4R#iiftZ*=oiD; z<|>0&-KIfTIZDSU35;DFPP&QHzn@9@2e@4d&@Z2H1TvT0za9OR3-2Y?jF{TxPhtyP!&swZ${0| z*_IejtXfEwr8%GDS|Tb;HBPW%f1J7>r>Rd z1U$7cOo;-Z53bKsu{_bG=-z#c+hN?8ivMz|ol#Lv%#T!uYx9Ig>SARt%=M|*Emo&G zj{GLHP~a+0R8XPS!vLAI5fImdHo8%faol&pzU=a@R^r%soM~^bjrTQJeL<`D7zdKK z;pril1TNcs@7ZdDF`l?1zm)-O!hI-kl)Jc&zjh&}x#?4C7OO7%rNy%Ey@hp~zN4}% z&s<5V4Y5=ByX506?xu71slLnPF8338H;cPw?w*;$O+)PU{QVVa8)Eag8>&HW;#{@_p6hw1v0aVS_2;+)Aj0-#p$slkGV6-~qEd*6;7z8Tx3w=G+& zJD$XnYao@*bY3jGq>sfAyM#Ng_ zJ#T_;^j&hXvg73+pj+YHhDTg_O&y^O7StKpJ=5wuU!_ZYIPHDUg>;MeYE=TSl6dtF zui|+1R_K2gE!N{BEr>1XDpM=t7mzhYoI)RdO`V95anW(g2N(()n5&Y{+vV=dVm$_HiKVBVYIMm9hFLnm{F1wQ%XM z;tV*^_*(XM;j3+btsQu6tR;wXK~eg?QcRd^a%uN3Y&-JXsl@F~QU>W7EF&pjy+e-| zduT2*DGa(D8-{|z28cg^-zNSPZF!tc0(^OcyCYjtOhgfd2pDFS-FY9O%iGqDmLq_~ zw)h&Eu{f!R5KX5?>y90oL51#)3`#?ftfI&O9uXbDGok~S?_WAz$I}XDQxfBK7?;R+ zT_uO7uR0ZS1Xg{9hsY`!pw37c4$Tgim^byaV=Rm7A`gq})<(WYnYauO(24YCZ>AA5 z&FZ~^PIbYwTdm%Usn0m+Xjw7dal9Np?N*x?<%ONTTh;E}X<+WJ3)#qQOpUM6T4#j2 zwlZ8Tp5%3`rmbZ4fyn|}y0*s1`=^!|e2_BUB)hFr#%q-ElCKt{f=oyq7xj}jwX2PK z;5%Y@<+yI&@f4SjN!?OEYv_JU7LThB7pyy%I8eshzJu}NcUk+P%`q!!|Lm%L-hZ%R zWT@e7F;*mpVypIfM(3sZ=6~X8s*wJ@{6Aw#MZHR+e7yH zI7^P#O~l7Osf8&$P?44h-24o5H=7|DKkQ&+JE_YKU#-uOQqIyPG>{>W0|1$X%)Zrf=0) z8Y4BZA7kmr&gK9ploI}m8}JcE!XsUk!eYZ4)UoJj;Y z&i~&;XvZ4rlzF z{Ymy#k8$cS_nqy`#?We`l%_gChVan7aEgAUe+Faw@F-%F;gd}@WNA|t^$<&uQeeM z3Np2{IZejG9<;ukvKYEBU%f83Y=#}Nu` zlnLdW$b{lFClv2C|EN$h%4L=!+=&f?0=csj$XjM8mh|L{dx{^a-L9o}D&eYL2{EHs z!x9UPkLi{5IZg`=xkUY@0`fHbSy5kmmw%XXZ3(MqV_3$}#8>D#!=K*Ir8;}5H(m{U ziPGX&4rj!!eUWcTID(m@8m1*ayxyu@~$rU3hzY8eINNx zL^kYp;Q0k6nCDnAK3yZdl3XQrTWQQ%chA~|pVhlhad=;nKGLkgatRrvH?3XRQ}6za zbLt4lY7H;72j+K|+UDgGfiu4-yy013bkx{NgaQ0w8GT7p+(%ti4@hH}_yzCbo-H-r z5rU#?qr2NPA%bRzW2EO3xY2#Q_C18?{#Do-+4$v~F>5#Do+xu1ag_C{uY2@Lo3A#- zAVQBBB>G42b6KvMeBak(g?kO{WY!~eP#uG|LI&-~buuhjmzYB~N&OImOGNBzdlKXk z`)*T-Gz_r-XbUAFf$^-ArN6jN%Ujja%sV+`0_BaKVcVl$COi$byZvSD>g~v@LKOfS z7vLz9(?h#K?expg22f}hDeHP&R^8LdFu20f#6^%Xev`~-p}36tvUsEZ8TnFb&r`oA z`{Lqf5_tsZ99%&CljWQGVZRTtrDxx?s4jiyOL@r9erF8y3d|$yNb~cvEoJdfOY)Fn zaZ{(>xPY!Rqeo-}7O#H-WpogdVV-O-nIN~YpG}gFmfc}{I@64gmz`gEY6JNZcfCHX zwzivi3T(%ow!vbloa?kykc=~CQru?%SlxsRd$_e|v|rU^3tbgREH;0je9B+pZK z^OqF>N}pJA;QZq?V_9o*>Z2NV7z!>K3$tJ1WV5!+B=p9oq&Kd8h(vFN=`Z~zl4NxX zyGNw(Ybo4lP(K5-4g@kW?~+fbqfmLI!<#e6)r>8sH8P5JGgP6LPy-dBj}@v-0ve$_ z9VSsdak_xu<1!>5d#2OZX2zP(>mHz1o`$OH3zed)P$N}%4GCF{KvaNT7UAejIOB9m zzfKui1H?kvO{2w$zopkqv6;8KR6Vql>5rMzJ5G3QQlBP##CJb2wgG+@w z$r<3ZO`BA#gQ+upAKJlwHA_~v^&+DF_!CNN3n~di?bzGn}C}&V0LPSXQXDE!(ff3kTapOcL-&p3s=HS(G~_< z1KN>DK7CziH8$E|G@0tuG^$-^ENrJWvFS)1w9wU&AffbNy^JOly5fTh10Q27OeD}G zCp39SscTQ8@xN%-wC)x)k2e_!Ox%mpcXoLbGFn!o60#}m!M^AeThL^zDk5$j^Sp8z zX619Jon3!C*_GpT!V`^mQKZjhDfN1S2%L-fdZoT{!vU2D7fkkPU{ z)0&H}+Y-`RtZ|`RGg_CGpjJOWeP`uK`a$`M zVVmUA^|8K$;*7ekkJ%KuHRRGSOrVwM^)uYvEAPMwy@#EuZ_vJZ>ft>?RpeV&RV9U@ zUH6nyh`Z-vym51nhAu2r+japdALff`y9vwt{GPQj+1Fizahz%re?h9a&s9ARB+%Rk z|IFysM8g#xqDgl>r7c-b_18nv_UBVl@H+xE*O`)b(rD1M)+$@xB!oI-Z5Y|7;4EeP zqC+cMFoo&vINiNQ_B)Pm+H3jPSi!S578+CvZ{)dyg-*cl9JW0 zkOk9gRG1vGL7 z@C-+UXLv`b4?c=6Rj#B+0xiu1;|zduossp7XJ4N+%UgW$5b$Ezg=89~}|D%>UkeJB|~$~-k(H?ZufVY$Y#LaObd+vs)>nd`;&6rpS==cR<9S6)Tq<=+y*|hX^3;p zAD4xxp4Vl(9gwMeKw3UbhR~9&*K{c-_*J#{@V zPTOqqdBSEBdQV;1@BLKsy-^q1UR20}m55lWi7Z!%k7m4WtLLB*2Uf-hOIU37nsefh z{5&{{7nR59I~Lc2Z_13&kY4|5(XDejcdt!nue~>w#pU}IVCMSNRlP~>_0rf?{Uh#O zn?H!bOcdt}+5;=>{`f$-omaNy!;iSu4D$sYffYpZ+v5t9JG$!QDaCV}Yx6&BF5h$9 zFLB*7_h?|nQLc*;e8EXvb5i(o_oTpzNxtLqylaVTnyVG}%<^-2YLlm}@-!PCwtL=? z#}0YCCnZomsqDqT3TN<-k&L?oE4l;MNEu(AH|X`rTb}ylEswo=&A+Um)l|!$DkaBH4_(j?t9Ei4tJuu~)__MS{ z)CfsvA~3Z1jyslJa^x4`)JNs(BSyn!8s9=wEki!F*&5kJaeWENQUi13JJ%gNK5{dE z*7ExuzwvK#`b_+~9P8TI)^#~CTB*8Otw`pOc@RUk`X3<=4T_nDxDO|E!1Gxhk%TYX?_6!oJtZ zwUg^nu1C3cbM5BZ!?h=1M*(E9V7=*%ki!T|rStgR%x@__bRA9=G)``(+ikGuiL zeiVTmQP_az@}9uzsXdWKNIl&MLq9w6iyq3|T}mn8u2v{r#VvV7+vK>}CTY?pE#Lx# z06(I*cXD$jzjZmb@o%r4ZSx({)H|%H_gtT>1-A&y>9#r)<2$TdVQnACNBY1~18Nv) zvqLuDVQE>{gN4kfeNvG3T0w~4WBi`t_bk5+{5J7>ogcIw3$4d;<&5};lerS<^I`8&+i5q zoJG7UU(Bm}mSpnh?mYgixP?D!mh$0F-j(0OyYiL1D=%Lf*jPa+fmh}4wccltQg1Nc zuKiG~?V|!LGBh8gyz+R)KI8sc?_u9Tm*)~feqkpcYK-)cg0sR`uOW^?quAG7(gAa3 zU*qjE)89m=jo_~BIGaU)N^4Hro^Nb5Qw&-+a_uOcf&=aP<~hfEq&Rqjc@fb;*6c)h z9;7~oEE$tl$1BB+F-h%{i+zKsa41wwckzgaCmNNf(Ef)mzzi6EnKhwh>Y7yV7}2`j zRKv_x%%Od(kOylhePS##q_HAZJwnftL&!US3Nw<0K4CfQLkEiFpL&6D8Z~T1u43Dw z#qD@UMNGx!)a82UGYWNW9B%9tZPzYWRgmYthGR^`?EFC*a%~)q5sL-ZxUO0~*&U+2 zhGRKy#%jEmX*%{*c`erBm&4qRZ>c=l$#vz0@MUI!ewOC#q-jOrLUub{TlV=>g00TA zF`36wUyXIzF7FnjnSjeWqw2T3Q^)U(WOkWpw$=rci4^W>jF_$k2?us-oH#?Tk*jT& zjiUialWD@Vvt8BSfM!_Zs6^;ja|kAjF<0j6nkz(Q~#u_^RWvP*C=XN^p{r;*qg4a_8*T%D1gH+)Q8=iKKOGip% zE}&we->(~Pbfdt&XWhM4blCH8C`F)I7tiNuTRo#tqYu?ebsh#+)p(Ckd+e6xt9oxR zuqM3j))>r?7s;!bY1_Q7tjm()K$6!j31gX@w$1Zy=(n0^>$V2F-^JcCJ1i758ssnC z-zQN!oq^m=m4FAH=u<_J%pN{8B=JZ(BJ>UYjr3R|ZG=V`{zo7$>K)gM&aBFV0#QNS z15qM(n@Z$}^IbI8&B&1bbG1cseGxPBz_|*&{)_fG6Qt*&yU=-lDq1QQIx-vv1eOjN1wKbKfBk`n_s!YYCdy5n z?=}Av)E))B`=5fwL_uW}`j;bs4%S3q(?12pyTt@O@J~UlQP3E@p!^bYNlQe5Cq#fT zCRfNJcF$5-#P-@xlGTm-dzaKti7FVi#8%RyybvR@sd?F}b)buj)P&8lkp7o-pg;Q; zb)c?lFRWR*S62%iS?f1dA!Ece+!Uz{Y`R8g5#iVb$d!Z=(cOj$^b?G#eN>>lm&z?{ z!(uc?O`@t;Xq+fRi_}WV&1AT#f!zI)&6DDr?nV$mImxd0h-Q?>;lzQ!w#{LlF{@*J z;nX!r>MQ$tsdPUI)?h6?(kR<6`sJhRk|lg~Ic$5BxGbYHC`C1N)6X>o>?V|8JS1FO zPTi&J``W}ODR$jCIic+YQCYh%Tyb)ucL?^!b;H)?hI2xWij!%cBkOYIFfL;ud%JOf zbFH08iNr&6RmqN0ka9hIIX5V8##J1jgs;co#i2=@+i{=AG5scwz0?spT$->rG}sqT z@FoM{#W>7I`}CW`=ji%kiCu-dUl!5CYTP_#wNj5BssfhkdE7> zCWX$PAY;)p3+w_}Pfj20dZiXCo=Wl6G-Wg_pNN9gx7~p@c7!)J!`-=p9UKY1?RM&$ z6pD5I@m*UB=Wesx^Z&7}4(||vY-l?00>0)|Iz#!ft#X|e%7 z#zQz~h*+@_>Ul5Bcz4BkwZ4@GoZoG#Pl5ErqB;)^DYYEi8nXb;VB5Q9^Tzlm@di() zeIZIe-Qel_D$0~LwziA0RUe;gPM;08r?tR9gseKT(P>uh>O)k9Rv*Wqye;bt7F5I84Ppck4^aW2XcSL^iD zC5An9iLb4EiLbjnaC@r5`}N?D8!eVcBI$9^|2NXc2Hm7397k&tXOkYl9Z?oFYN(*F zEwL_uudV8Sho0M*_Y*0*a(ZgHI2S+9J6sMeo#lWyDv!&Zs|w4OMK$rsRrNh?nXTpR zF>cpgpX#bOSmCNJpu4nwtQG@Qaop;SX>Ie(*ny*q#Z?{TU0`SnrpL|WND@qK0g33x z9sNJ5SN2#eUl;rw>LxxNo0U4!;k9Lj(*IT~${|bWHC_#KcsqHHm**Ea@`$a59LwRd z44H*Lg_(E^iKWU$Gd94^a`8`aS!T$sH*N^IdpBVVdD++DF?Qr5n+cI_PIdg`z`YI? z5d5|!6d$aHA`GK z#-^;54<}fF?Arcoi-Qh+{fscmq19zeTt~LgxB~rO`4AL$_$VI`mu%wShaX7Y{1G6u zgmf?oIxYe1Sez8<8$icdG`f2jmOA^=i2UyR=YkdG6nu zX#ZtnW0Ja^y-E=k`i3>2Cl(_nyQ|sX#?gdPJAfl%2WZ_Scr?n6z~gYjjD-&GSvpB* z*xDg8{R>+vjt};3Lo*w-qD0ID&zI=Ax1D_q>_~dIckazIZce?a!M))E*g=CEFGktZ zKpAq`VqR+GLckFt%~+m%d&XpW^qj?66qdY_HLK-B@YSDMEsGZTPFXyY0yA;vxS0Mo zq{cJSn3*zT(iJlc(WuW%<;7VA;b#1AW{xHJQaUC8-!@d`#>_;uhX2r0*-_xGnEUb?L6C>1tIOsq2G&@Y0%j&->~h zhW1z+8cuoy4Ln`KMjWa1n!LPHk!t*LxE&|`kS}b+;^Xk>&WIOxLKw99S+<%y)&56F z?T@3Me1tvHOvzc9WJe7`7VB_Dq*21?%%<+*xXIBf%@(s;3+2t zs!Uiel1-gF@FO!%+P^G~-dwEr?dOW!PcUDTMR{p3O^3~f4 z2=7z!{`*-L<=D@gR~q^F>JI*dh8RMXm~b;bXBl0~KK9M9h&#*TMV>Jwa;Iur%~G(f zmNG+!ljLpWtRG%!p-~jE;D|Xz09I2`q5>-S{bGT;=K=Y<^?>|s(ti)=zm38P3H}$H zh1U_46J1q*Y`o58oe>Qc-)Kq{d;~|v=@5M17JPx|5RVau`rx}@DL2_nmfVajsS$QE z>kiyI*@Y!vg$4L#IB|nS&}#zYhFFU{aJSB#@H27m5v~Et=S_IBgK8R+E2v9&k4VkC zQKERllkL3bMK^8&{<1cI*?!+)JAX4yE-Q-GeQLbtL!M_7_-hZxx@`n@< z7f%H5#SO8#o;*|g%V-|yg6f+hGRd)nvh`}TyscAr-VQT?{L>JYL z87wonKRfjrREC+{j18T~8zTOVy@t>NMFCIh*uec4`Hsh}hL_WG_VnCluAX|GX-23{hN|hIJ7bmbj?kSfNcKV}-QIUP-{S18-%0c1Q!t50!RGxb zPim3+GxtU(=Q$OrXXQ1_SnQ)>9DTv`BzZ|}tgctG?5Urv&9X=7EM97u^e+V&)*vkd(bP>$@dET`9W}CDVpmBU9jcW&0^{7EHbPyfRL`!lum3oS~iaT!HUU zoc6XuAq|}t9>dkjQ^d5=$$GW87^2G%jY8bZBQ03PX4AE{V0mH&o*;9nM7MylVx-iyw0FX+4(24(sJ2R7o-A$}@F z;rWD`OX%l@t)-EAbpdtMngB1FfNu-V(Sbl;eAb6!{M_E`sc7hK2}h3;K#>FtpcxYi z74sMiey6Rwm<6hhyFzsgwH4`$>C6saTaR?+kCb9OK=~u^4-#FVTm@L%C21U!$CXhC?!C^bUu`l1!+vDJ6l$T-R%CT@cT_^w*G8 zBv63=i8lNn>9xt~;?tOTO-zC=M057@52bR1Xs9Xnzo3AgI@4Ze^Ut*FBf@Vu$~PiK zI{kre$*Boy(V2Eb7h_NDiCF)moxC;@9~E{cHZpOj^H;a?a@~yysWCg7Pjt=H%w_GP zUA*)TPP>i+)q+2e4AP5?Q)v%4j?Hx1{D0}-E72JkiWMiUuIjPe7=O{3JO83H*ATwd zj!70nn zbaw5jlHsvl@L}zZQh{noj8DZwIXnddlANYb$J?U$hK%jYFIi`uKGZvcy?Ysr%aa3H z9K$;p0i-d6?@Ep9m5NTZ7PiJL^h9q5swHt+XTW}WaK2>yMcN#j<*-+nw80d3ox>l{ zrN3#uT0Y9eMvAb`&djJ^_9^F03PMc;h-e6koI*=fcn_;n4be^;MA(tH2sEr)Eheec z!$Fa5(v~}H%k9P!W*a@B+emk}K6sc~1})a-PKD$Mh1Tu^Z)t&H{0q3(KGV2|{Ka~VBfC+MVlFg&dT@nRR2}& zv`M%o&!w)lHGGOXZFc90wEtDL7o{n7DI7JeagbiTC>^1NXa^Tzg+8lLy}#12=r zXuu$w4zn;+un}KP^qwIb@iio~LiO8cH2a+LSKW#-pHkg!PBE*+jkDQ0-;uUAqjuR0 zatU3;;=ItsY3gb)l|_XN@I_%3>~oW^!|%1asXUGi#&U;?=0x};I>F$FB2)HpzH|oV zz*5-qv(kJ|6;rI7(TeXYvgtX(qN9F^FvbM9W@Jr$^F2ae^*jl1rTl(#v^9J6gDPK2 zf@Sn|t{W@_Xb3fut9Ax!l5{dDG)n2`OX+&TqukT(l*#I`ZN25T-%SqnYPytLI!M_n zsW~mv!TmiI+)I}#P^)9P)f=jZss%dnAW9C+DNvWZ%@~=(D~}ZHx@DW+y<-VWiM8(c{O(P?#)(ntMV6)!!rG`H0pp%!kV1t%{-Pmk zR>jm5&j}deO7z>yyiIG}ZP8blVja^xy#9vwxwY>n!&6Z56Jcu{3n=KWnHMjG} z0(&OsfO|`xdREugDHC+nRZ?8IqO5JDcgT6Tk{?5e+Z`GtqMXrn9_t@(Gxd8Ebr00` zjtYCXs0mNY(z!;B<4ORkIZy$R57D)VH@Uy;d4Ji4a8jx)K%0&0U)aJ4BFqu)#=Lp> zUf?ILrTfT)628(gFP!vLWTIHbWE=LputjZsiuSnug$*QY%QM`&!=CCb>e<86NKQ>p zv36evG;4D|7q~u^)=bee!q+|0JJ{T`_v~F-n=#nn z@EAf?9P>I}xrIdBm(E(m@;OjV^ev80oA!!M?SDZY8{8Gb{|Sg?3>8MMBZj#fiT4z8 zu%C*sPqa0Wzr5egcn2PvmFagsVpIz0{q7$Uz6muE+2Mi60`Ft)Y@H<~6srEteGb8@ z+%24lyF&YJBx)HCJzCXV=IgK*YYvB(uhdFqb8Fc7Y;1r-o$5#f2in%gN^6JFe#Dln1yi+(4sC{K>W+aFH)xin~Z zP^1sv9S%!TiJd$3+7r?V%n$}_P23^}i@n0%uy=>r$Q9zNoi!Ae+v0Zw%Slr5_(SXf zrezs-C*Uh)^L$mBhrM!?n3os)`YGnz8qaw`tEJ?^83;P(+ao#OtaDBX{TxnMA_f~s z_lnu8{qAR_C)7}5_GP%LUgV}oRZ!_-4)wBiVkNrSRsCHd$jwD65gM`Su@gnhmMRwX zQl}!7U}hzhM!!W}_N%MO00W)6N-`?8b#4;KjLzjZ@sS`te~V7OuIecyp!*f6a5q%0D`kMbsU`+gzZ=vGyUm z-M-uZvO(`5*(M_YZr^H#9I7lCf>%q!`d0H@Ui@W?`ii`WuFhojZPckh6v#xqa2w-) z?rJ{EG;IvM6paqMUng_b8CRb5L_&$9^PvK3Tw?09$mG$xc{)+er^A}6nV;RsoF&Fp|K+7IYU?T!C#OmW!XTCrs_R@C@&$ z)8!SYb|B48vR!#eJarQD_Fa-+?ry(>ph98K*9z1KQge_D$A^fwdAs_yv_fctf2G}j zm4Bt<>HBsQwWb18bRfQVIWF1l@K2GEus_<*NAnrKE_T~$91%cX&XZQ~wgKcTYr(i$ zq!vxgA|os>7Nwx`X0Cx zD{bj8b-`og>YsTjY`NB$c`18zi%N&(DW9lLWYyvMQ-pb|Ywv(&`#dQ{YValqli_wQ zODsKK3e*y&pF-;C^_8-YhsA|n7OsbODn<gJD-W$q)yea5L}*BNi6y*V}4xguMi=3S)R#Ek=|%nWzJ^7PUaPPEEB%2wh6EkB4~ zlJCV#d=ynJF*~JimUoHnhQV1by?x*HzT}V=CRjX zZ_c8Ptls9AL%H!Rj*zX?=#1Cghvt8mh@GBeYz zo{K9_%CxldyvTQsJ<2asZJuZa=LfC}+ulUKF$bR<(W2oNnK4+;nR*l1y@pKy|-a1vS zp%TB@^w~_CrLwl}rx#fKa}sNV36%#WXQNiSj#?~GaPT>7B14njYyW*v#>>BM|Mkuf zwnB&h)E}W*XxQOAfGu|`!brpw!70{yyZSb7=7}SM=i9xm2p98i1_t}9mrra}Ew%jK z`&(1%iPompBfZ`O-vegzQ0YiRGtrI*4W3s{5#_$oh%H`w1US4GibsQ`;y{bX-Wm#R zZ9NovMZLF??lk7t0^|L}w>lNh5b9@H?=9n!{$;3iQhq(^-0|PhGl+oopVISD5zb6{ zE(4?f^c=^V&(pK@g(yAK`qA?=H8V-IS!UV5&^)2$44zj``#d!-j#6{q#7l5P@YJ-n zg|?{gll#9$&%HqQDMh{i{Qon0j_&%;>G|5RUV5GnhW+XJ1~{7Z{A#3s#XVat_0OkiwD}e% zd0&142z~dv0j$|clOUzEq(4ZId^RSaT4V$6?$&w zE_8JBUb%c^zW;9b=if*DvF`qNcxP5H_p?5==cZ0(g7J+@G8(;i9&kJI^Ko@jkD=Hr zE}rALW{zhHFPW@U4#eK~lbN(&LQAc9LIG8pRLZiGT=BdN&Cv-u%cmCqKQv>p*LN@c(B1x)>z>Q-1qbNEYeeF@O4e|Ni}kX#c)m*k%7d&M5CJ_bk$b z-J8|=5tYNWA>tgjgOq`x6?FB@XVdG0O+1^Bqe8n)t})J>o<>g4+~T!o}bbd5qdrc9{u^nLf)AC;-AyA zqaQt2lQJ;$5uxW8q30@||2=v({^4JxXF~t7)M!%vSM>A``OoP&nY0mlegi!E({m_q z2Ijw~KF5Ej1G!mT4g*7_{c@U#Lr9-&)fW6KwAdMGz~A zc8#E&$1_m)$6ji(oe3r{IVZG3y+973^ZUy%CO6v9j~n%7evAZtGFM^z1)?%@Z+ril z*84Z+L09#IBjcxaRr{aTfCHzX^z}bI5KAaBi}pcn<14!|ZyYCJxTr>bPxXw>@*eL|?0HZ9 zrdNB{aU-+hA-(^+pa{hTx*>C}|ASS}!I9~{yU%q0P2aGvIo%V$O{+rIT;c1ES#!38 z&%cOyyU3i=N2wtqyD_KFI}n>vi?$LXXc+)A-UxvkKsFeKY;YrUw#Wu!3e95Nf)%1j zks7U$;^crtc4kI)syPdb`pPKBz=^yE5L3#`+>Vl)=x^3!3DRkT^i})Z359~(!lMV= zMaR!Q&B%l6VR;|0 z51wJc+UI(hp3gEC{pOm9v6d5PE6m(NWcUmn@mR# zQL#+~H{NK1X$;4vQiW*g!#V#{YLeP3*Y%F?5~PEFYkXftg1+NBh0$VqcxxZ?Htsv| zGw;NCdwKI@{_Miz{Kg5K5(Jodo}a+bhV+Hkx%ipOc3X2?o@0*76b9NLe8NA*`J1p1 zdpy1F=X=i61A9g|9$!E0-|k`i?jCF93GrTUJ+vBkea7uYjf`l@*#ibQ#wO@;x5j32 z#UK8)8nC#rmb|xZJ}jK1oA4gM;^3|`_jQb2;utVx7z$U3q-dOsqA zO$46`k8hBz(`-++MDX3r%kZxED7<_832$QLYi5GpAN&scqC6e0E$`U2hWPbPjC3L z<%D*~IoxRO3-izBchd zY%^1_Y@Ru=aEJQY&)HVu-eGQg3SHC{15dMf#vRB`Xg#zy!lPVjHBcr9dMz6tF=FE~ zy+F1K@7G&}#ZN_j_@rnzAxhLuQ0-&5gIe!CrRbszn8JuI6NRQR-zjk)Vg}cE2C&t=wsB+Gy(5vgLQHGQ@z#oj6HSvA)}T9Jo+v1WJv1xr!NXY(Xbw68T-Jiz>>|{m=(X5>!(1g8j(f*;KM4$*c2rR+r8i(zt zqpNb3la85sbLjkagfW#6+B0+rZHY&EasRlgQ;gRo_Q41ZsDXfvmtdtIt#w6%r0U4n zI?8HqxYWik4VU^RTg@-&AAeiIr6Ql{TnM?HzEd977R5;HRx<>*{#2S$QXU+0q3!VCaB^l6?_~zu=Xp-q z)5NUbhNjw|+ic7!@#pT=R!BKczNnz6NSm+r$~>?wnOw)7Mv`C*MMXi00wM;rJGgR? zldp!5ncLQYZp31ScLQGni|y<{kvv6Hj_^BdP}L@YYI zs7UWtB~MZ7De6`({$zSe2fkGu1?p@~F+6A0Y`*wTg*|rce3$vA#CQg)E9KRcp+s=J zM3POBWG{(3NM3${Ket0o5oulAZWn`6o;vswseHZomzn)-!L<>y2YXZS8_XW*itYk>;HOmWWHFmp zeoS8`EaIJ98P4zai@tk$Ppi3kLL8;dj8%i?^U3Bm*0My)>dVUG#Jg?Th1xd1I)z?V zZm(`yHYzPQVGQRF<#NJe;=A8QK2A8`W{P<&^YR`IUL8mzab`==O zoYh3f$2qHf@aoZ(Co_w};bp^1ORHPrY za-hTeklI(1gZ447G#s18$Mr8g!r!jroTprR`(nSBHso~rk{>`JqtU2e-xW@ii|;*~ zjZmI3zM8|f+V!~q(t~R@8z!qMg&P3T^2 zuim%(YT`my)(I+1iF+&)kO(VQ#m@0H_GEfFYiE5|*->1lh6O6`LgwVDlc%X9AX~sg zY2x)*`!A)k;gNw@6v3&mz<)!c`e39LCXdyBeM!Y1PK80U8fplRKEjB+^gP17H}<6p zE=JKn@mvj<#mEuO~;^>UiM|>g&!2#gAGX)<5`?qSQr?vRc#W^*yG%Qq~CH)J% zNpnqcq=Cz^8=rxXN5x3B8b)Mxt0uQ}EA8?c=~hLm{6{pcKBkJkx@+npd-++b?NiTL z?o_j)=|ZoU#@{qG$G&=S`G=KX3*VFZgO%^8^FUwNlln1;YoCw5({r$w=c(tSZ+7W7 z@WSoUH?_Pm7D+7neXH-LlOC@)YO}1k9fr9+tx?$Un7u?~?I7H#+Q*7bR=2Kdnc=3o zyIob&NnND6BAHc9l+4^m*I(>rdq+p!==r!^5#}qBDv4ALvr~Yv1jX|U3;x>Pk75-k zOV30$6Pek0&L=CIyC;%lJ>5Ot_+-7&lGZwAj~s*cNyufy^9-)MPiq2 zi$5NB>LI?G>At#cL~-8}j(n>m{x-vdvn%(mFSXb@Y3#j3URozfW)lry74e~``|7vx z;M=7W@%8#hB1be)vQ9K#CxV4bqGVsa;y_0;5e#3Al0=QwJ6ER(t0JE5>||SQY5e*{ zU8k%!IO&4c8|cQt@Mlc>JIg<11U4-{43MuTo*`TsZ^CgnCZN?dMZU$ZfsvK!_`dVzaasQ!&$yMqA@t3KSR{~fY@65GMg!yMcR2tA}%g-RvtI= zt>MW4(7gjMQyJ=|mh}W6H@XY_Wi|f!jq1HIR?CpB-eGyAx6{zO&8KtOI{SKMt#Boy zzC`$?IRn37ekQ!|4(po15?pV7qlJucOEpd+hWq|T{*qD{ZJ%@t&ytoi+}rq?>6A9V z-PS09iFb_Ht1|g`v3m#I$zE7AX0Mtgz}_9U&Jlal!$l?1I$`hbu(w&&^F?0UyfsB5 z7B*HMdiOSFkK{4$(m8%3sTOXdl$mto^+oiI=_B^Qg#Jf9@Yde%?E~gp8!v6OBlh^+ z&HnkjIrPu-ZFR{A8TR-FzX6OMoj;~e1l*hQ)Ze3T*7C-1Z(474H;YI*eE#l$yM;I) zC(WVhy`JsKbg}qV#OCc@bE)Cp@_EpSfO6gsiFL~6?np{v`!}=VEFDxF;7FR2M}84X zP*41Cw0r5EwP=CJRBtR+XMbPTb6Sd4ZJB0YH8;S{W(-8)*7Osxm``vA z#s5BLNjh)tH%=j3?ZsQhcOriEu=4mB!v9vt{y?0T^$~`#2)Frmy>uMltgsp!|Fn~p zBr(ql%Tv?Ow$f}p$eAzyk9>}v6PBMZf^QMR?oa1x&*LGz`>3rsrZ~p=S>t2_bzyjy zECFEgo@KHa)q+1BxVxCmk+c>CoKtK~`RcJ{v_*F@P{{2)c|`)|2smeRCMkaZ;az}U zinstjccUiz#C54Xm8}-~tT7I#@O9YnX1OUE&%?7z1E=`fI|<8hV`}odoc!_bU8xCd zW+jkeDudrM{cpkQovY4i9h+)6Q!8=Wvs6^#o*XWh{pvTSCi-?-LYGFqn(tf8_j@g& zL;>icEyCsAO|3VlCd*H^ne1>g>I(JA-}^_($=_Am%**%8%M30o@_GN;B<>`z{>c>A zgHOYnh@>0is;U4J*G5i#h)L`A5NU%AB2U%^oVgUnh9Fn? zaB)Q@#9$x>4-7HcL}&;QL(YtlOC#jW$aY2%at?%$LQhQnhmzUQfs5lTD}fjW#IS)O zey$88obCL;h77%9*3^B~aY6K7? z&Wx4pj^#MmjO@fHnGy#=s1`7gMa7w&G;ncGnh+y_7&$ORnTD9l(P7!6&WuozMkqNW zJ2{F_@<0epGK(8cW}^o#ZkP#iHV|hI4ACJn$Huv1fEaUTgz9DZ=ZwwB9veky>_7-T zsWV$Mj?BglTwIw6!KrH5=L`(7z(j~6+Op3*GeVPrDorU)YqfoBdpo1m!BpRhEt#T^Uf@=ZqLYWH-q|{Orm|@a^Gh~M(h5aa{oRsgdEZd#6N)e$G{Lz zYKXZX0P(?@ahLr(MvltJR(;V@17~@?S!j?fg9AfcVnTcf#D@bzI83xcK!nbW)_Wp% z=5%Cacl1T8W8f@b02o?)M3x^73?ch;fj9)jp@AXp)ev(J19AAwXkDk#>deUQ?2A_C zz*%wvo)r2qS$;e)gzVS{;u9b~85m-(hM0Qv^DzoTC}pM_pA9>M4=Cjcbk$ zoacAUQa>fnPX~q&yCmt40dZ_#h-?$DE+D$jjF;a1oYS3=%?h$II#p+P51i#;4Y1}o zSsou4;tdnx1P~_%hWM?9n0pe4lV?V&8Ym;DCnLMZ<28q2580jddGWz}3pDtQtUep? zYc^j`@%7YzUsK^@#C*+0YcsIO;6-pSY8MCpK2(r-KO_77C^GL4nBgvpYbQhD7+*y7 z1-?eP#TUQ+2xLr7aRy{u)%POH7&#wgWPi}NsXm~v0mQ0V08=36e`TM6Q=D%?df z$UfW`t-}MOHPS4!6SU62DUPx%0`V{56gxG zjE0zNa*8wJRR)xib220QWM6Wf92l)Uv(O&U5^gcTsQ8Kr5#<;IKsZgbOs;W8wEltg zKq>s@!aWFC@c*%PF7Q!R*TSD9lQ4t{CqTfcfKh^?KuZlMF$5DJ13tikKthy zdJ)b5Rv?KdqnRA1dRuL6tF4wk>{r{`)(4_ULNEzJ<)PI?NDYeijDs2!lkjNf`>%aw zlAyqMfA{yHnRCwCd#}CrYwfkyUVCl6PhWI|8UUG|_j6{v-=FgL&rH`(6uylgfKyn@ z8R*jO7%}#8h8PP}jCnSTIVkT%=oB3S!aG?Qk#>f51I*WW#W@l>4CubzfW5+lLo5{4vvf0d8$?7>SWPO@5FLaw!IA5zj04-*cozBO*9zxGTRu4>U6po>bFi6ZHeEKG zIV)XL6U1yO`2HBa~^2r&=3gM4}Vx5D{G^rT#Y&LUNvYsMVsp;t{&6&}o zRsT0%p;;_MOwXa58Hf5)dg#n7;WnF&_hA}mVJp|#G0wqOMyVL{Y_@V%O1rQnGd&;X z%=oZBS!Y@HyiR1Q=N!wPr|lT$U@P~l81rnla#pf#Rb+*7W`z2ab(UpMmYwN2mOVr4 z80TOspM9x@fz4LVO4d$dnVwH_W_;40tg|e89#<&Owe0zU9pfBqWwA|`%~sAz)|HB^ zqd7B<_Kr^2%*L~~nr*?>^bqm$(Zj`1DH8+EwJKw;`s3RBru z6a}*O!riu7_KYzwB9R!jTK0@F!~{-z;kuYwcJS#E5`MHElvN(Phd#Vep}b7$zYvR& z;w#r)xE?Y*ac2y@kx)qR#D|~we`3mrVG7+PODS&0ctO0mYcDuLO99CJ8%rB7OWV35 z-_hEf?->1$d`IEFe8)9>&*1xk-T97J_U1b_HRL<~PgB0*vt9X)v3w8Wdl=t~`3~;M zcj(*m9qSwO9rds0J38OUceK^#J3f3Z-*E-s%lY>3J&*4n@62~JlgD4`@*Pd&af&>? z#kW%St81jO!LTm!L+es;YtDjx^{uC0A{}37jqp&3XShTK1?ZRhOKd!&CAy+^ve?;h!&u;!DEuGq#*^eLww3Mu3Q_C#D+ z2WppOa#J}9F}!crCS$^Q(MZ-FW4p8JkRvXxN^du>KL!3VSBCZTIfl)v zo7ebo^Ku-w-O>=8(X(8B|D%3S@e9oq^?zV*X-1Txr5ig&WoUUc=wZ`JEG<=MOXX%6 zO!`u-zul)e1AF9j6*nmz{Elj^H?JpLl zkjP*)9aU3rU;X`d-&kW^YJ%?~GcPSSBk{-Q>lfx;ERVF@OXQJ~>&W|AoSuYV-|bF^ z)orl3SvK=+`~`nFnf}YQJW^xUQ}jczK+>uU7*=M{66Is%_3Ugt#i(}&l~ry|^QzBc zZ>yaI*&9jKsgh#8%fDZ%PUO`%k%)=NZ7wX+@;I^o4a25smdm}4kxsp z6;*tOeO1~29RpMgU`18-k7EGQn}rLjvV$>z$l>7`RoM^40D?07t*Y!F#Q?Pe$f(Lj zMQi6mT1Qx`%6?7&_@-O|S&qn>73HqT{*u7P72$!AyPZ;A`CN7@8=SZF`jc^$)rj5c zPdOsPUZ7O3a4lnFrb8bX;dZUiYS|LqI6-|*u->&lC#%oN)-L;Vn);k(y<&gnsn0y? zPxj|5^*PJ>rTsZaea^8SlFzD*OBQ3xD0wZhHVC9V#rjDW?JkC7=EgF%dN06ZP}FWy ztBTZYnXSB!cqMYo{IZw=V{^Gw5(1+Hq`i~0W4LO0D!`oFG>kj-w5mwDJlzKVL~voU z`zkvDoF$?h?-yC!tH5jR#x{iBNR>cOx%5ME%tsc>)O(R7N0!yKWv=p6Ww|Z8-VNg1 zD39&z$dq;rySa&c#Wy7yrh&fMWv{@L@G4VVs6b*am{nv)w3ZM}aq4uotgW%&E@4yp z6)+j|oDuu#*5yK2Rwp?;2Yk6?SMDl%R$8w$8I(R(lSfsiQA*E_%noc!3v66jK67zt z;C?xx!sAscrpZ$#RcQQfGvqiZ-MA~sO=>%`rYtgiGq_{5I$a{TtpO52Y|aYY0neRq z2G>(knY>5V+-V(`3W=p)N7-RL3^ff9U{~HmX%k%DS()m^T7><&^#Ldak##!>7~y4~ zyu)}uF_Ea7q~^r6-v>pp8e6=ex5g&MYV3+{5Lf253#G=sP*X$y8e?cLYp__Ifqq%T zQ!%8tZuuLz7%2jXl!TUliy|giN7+ZkpJ1FmoR7ou0d*G{xs@2E#`#8+aUL6Q==|6& z(=X$##P<3$m*WXJ?$;`RL?=$pGrG@PbyOUbo6gs&0V!5kbwoO3pH-3a=7PI0`kb<5 z(5mktypWvBqhx5+8V~>_QBqQ(q}Z2mRP_iw+a>@URc%)f+7{ca@&a|=`ks+q_PSD=21D* z)=aShGXSttKZ`)Kexk%FPuSO8)(xKV9Yyo49EAlVbI(^1m zrTK+X6)WnCtT8dL@7}W1j5tS`i*)#)vS|tzmmiA^uY+=BhI*Y?Gta_L^{!gyO*Pdi zE;>MI_Q;#`f%#R(k5S@P|1J#roj~#GCV}3Xr6;YsS2BcRfTGCo9iS5fo8?*mSY~ZT z#*7&^Zyd!W6dAsoa3t|M9Qtm0R=n8OH9 z(lyl03K(%;Sl**$A}W8Ac+(5yp8Dr(ykKF%fS=cIl{V!&9m&SP zNT9@3d0S>>ZGL8EMNNJt@Uh9sfs&~;C6kT%Jg#kcN>Ya#g9Q&_dwmc(ON|Y$(kCvb z>}Ek7G*^$7R~H`Lk!)~zmr#%8{$@L;^@&0uZVx>;I?PTH8a8B<=M`I@%@sVg2w3v(9bB=4lZM2R_mzoILn^Y=u#dxMR|*a5s!Ll#w`jP>;+N zSkxZAKVZ8@k5lz#I+d^VSoKLYomPEcueR`RDKV%+Nen+6-5Vzpw4ks@^9vzwifR0>!@2TzOlxfHg%@E|$e$mL6*cAc^O;Y;k81U4nneIv?YIM|X+=VMKI zsREiAn#OO8_0of2b=EKp0vhO;F9S$lQ*(Ij2ax$_I>$_W|vX;u-=vAnuBiF7j z5Ml6mWOZ&Z?PodrR$aBgI?7oT+e`}|fOg8D^H*NZX^xh}1(JBqrc|;BvziDbB9$TViQN>w%2bEO*EW9YDyLuK8=}^!kJNdjQ@ftMBs?XO zKpP~=#iq0QDZu!l&g)TUMrF!y_Y3ya7F@_tqw|&VoA0mFGVm!n(Dw(D4``enafIXM z8F!>RDyK8FUWW|aDB3YN_VtB=J}1PfLvpUbHL90#IaXT4k+pvYHx-l&rd}{n-WS+-(*pNZ%I<54w)ros9#Q%!baLzN58C z5SX7mH{ItV^QqGY>XSK=cZK#UM-N`ZKZuya4U>vd<@H1o)H93?ub#kHB*7EHuj-Imcb(#>@>w3C1PVE)*}toGsQ*{%aB@#^#hA+~~x0ta3P6*w#-d>$F@wZg!D% zDT_T14k3j&UpP2BuAHMhf4N?@dr2U7q;#K%{<@8#kebq`7g7z*44 zqMn=NLl&S`5>9WUeiavh2+S%y7jCI}-MHfzhQi%gWpA7JQQph1B7R45n)DQZqdu@} z@1`BF|8S{TlSj|V6m(}5Z~+`Qw}_1QEqOU?zo^4I!`o#f&h5yWiz)c2EG$5qbN2WK zymS+|!>Rr^xCo~{We6p#Z%-Z697vJrrE6axMe>nzxkbgVramD))c865UK4Ivp{fW^ zmvH$xQ@Ah<7??w-=w@(5bYGF#Rm$ZesoXACnw{k9jy^jIson8i-hDluB3!0MhRbml z``pacUMqyMz-%eu=-3s~3|L{pdt$L@WIXx>z9UlY0dlh>w}$Y*=xbITN94qHOj*a_ ze8-9iC#yh)>0|&i${>H^+d-ykpZd#s%^SGG!t@j766J_;4y2%C#U@GDKxM87q{wT@ za=Ja&0L_o-5h$#|AtQ4s2iDDdU0JzOn~j`pZz>Q$!eI^wu1+<&d${QMCeCwaxhGk{ zQbf0#+~#bT{k=iH3tXLf91HgEB~75f!ud4kS%L*tVCE@vrWJT!O9XiGF-r1h9r8mxo+zF%*Tt#NH)o8;5i{0h`DHq3g0(EYrLVi{^mxb#p*9tzUOwBZ=2V-tS{#>Q0W}FOZcoV%(3jdI5~VPf4A|svd&RB z-)uEL(3pkSneQ6!SJa0G=##kcnlsuJ`5Zy6$j^`;0p;h(k5_(fm7kTtKqck5!M7K_ zcQyAshn>0>PC$c5Xk75R)Ej)A#`~H+lAw<{B*%$zpw8=oevqIi)x_oB;5)JSmWHka zMnmfOHy4<18t>ci>wPEc!+j~hb8~1JwIrQu><+kyIGVs);>>}gCcS{boNNVZmgb!BqnR6^wB5hO;SAk|0V( zfhvY0Rl;0$m@M(^1my#=b}rU_9rShJV|5uGTU~)7P#%-y=9Fgea1N3D)GIU6PU3Fp z=$C!fhGVnuxXb5TUbW%WckjC6I$u%MhVHxcJMQ$&WvwOg`$a};Ikw~4h?ZNI6z9;# zLmv!~#{hr{4j*~P*?HrCvd&frie9PrG+pd;8{!RJd}Ne+ za|-qjeYw$HpxWcI5jwXP|fI^=Cx_ouLN?*^1xKlp=viQOU)~k|I{Bgj$T^RRd2XQI#9m^9I2 zZb*mTnj|c#AF1nU&TMzCtMSAIJ@Mstc&+u@;K(8-4U^#do}HD4+AHf<*0>t;63{Dz z#NlmLUDXHFP352l1Qig9P=my#koKbNI&k3u&~ggi_@LcrP+l23DzfSZ)pH=qcbP=? z#G5mmX7X4zV;n|f!k}g!CzfHAVGh=I_fUi30gaycZxLj^;o-n5CvXxQaT=k?DU?c4 zrkM^_5OH8pIN-Z$2O8HnwEMS9Ke;1Kgw2;&D|1?wJ8(7@Qk4swV+zv7>|@!dZQE(z z6KS>JO{9EMNohj8_F|pUoxLVLfhhyl>8fFolBPY=O#P>Ut3KpJCG5Egbj)(4oL>3^ zKkJImg0~X9-0$gHb5;2y6u7t4x+;&C>WP)dJ-)=6^f}?r%%vSU1;_L>3CQ*hsBE~V zCOtf`r@qD&PUy))X4{x5T?-G+`o* z)I2d?Uv-{$K_TZwU_8!AHAx=YW|5WCq3}i-?$Sc zcp+zlGpuKjM%4`pI!9gIj-Su%B^`Gqg3F=1kGb)0|y z#^JS|IO!%Go_<{tb@tSPk&=9SLI)$1d?{hW_{M|+ciBQT8#L*3_zSuk<~lt%FFt!i znx4>@RA4SjH)psjr%uu*(wNuZlhpODG*kJCTXNo9?=rXltm~wMk(%89Gr>{h>`e4B z{l_iS(<*Tct(C(N;!yT){X}IFy}{d7+f&7`So<*1kJ0?fD$zJHp-)AH(1AddhCsBz z&0));;M~LWVQcg4bD`5Z1tqM7{fAF(6DQVIuIP^&!@BLsDA{@&FbTtl@f(qIRQ4;4 z4R1{}-=IRq(=WNl;8(mTzZo;3l53L)hTBAg680q2do9lwl8>zU5;>nCjCdp|xG$1! z0n4?zuz_PP5Cx8MTHLuL>hl7zoKaiIkz)2pM$QRx1he3j^#Cgabds!U?M{+rO;S|e z5=gf;pzjU+jBX(3l{TbKU7D_60A8f-VdkPVsJ}*ah5FJa=Ok_!DoCRfM0sf*5?Dnl z-tDbt7&ax0Ax`PXCv-4&uNUY~fO0o-iQPF$6vGmx;(BC=`{wymCXg8Y9PKjL21L(Vd{Lw3^*ww-lbaUn^t85O%yPfHw3RfJ z7=SWt0!i+UbwI>g65+op_ld+-g|Sj z@WS3)N<|&JcK!&Lo%!%q!*O9*Q84pw=%`I5|TD#fEmiSMWid_pqFR@Objgt1+CzTrWlNYq3$6AqMSH~bFv2R89OIWU6OEIklR|EymKyiQU*j94 zy_kTECgr@>ssGb!Jw`Ibyb{B@HJoT=QyON%fWPu2o@e}z@QW*($nXx-5dr^$e9DDE z;?3MqwnDNEY<(D@b$cvxBj^`^?Ug?07rS#bSuZJ;muh2>b>71u@LEY9sFqLAQzOp{ zZtEkWOA&PYJ2Lzj`Erd_PW_tOvQbfvwLH5ZL;hAdiDa^L3a{z>^Uu$_#kY1M_$v7nnC8vt^sV$3N-2%?JuLkxn~HE~-r2?8uPGijkvgg3{lttO(Q=&}~u? zsvumuw2+UYXilNe(2}W=(UY3-dqf8bO;A)lO$NTy?5)qp(-qj55!jd+UKjLN^Gzla zjH>AfH6=CcB2CbLn2ID!ML`o14LgFssJ-a#AP`dr-aeIRJdZ@5A4i|k4gyzbtY$Ug zM5`@(>ytvqi0rMuk>_BO%Jih09_n*sKdK~BKdKgx^Vz7n>VHSol`*Q)14SdVw>}o7 z>hV6R#wn^M^rK25^`q()y2#n6dXljJMO{6v*rDoHMH6DZcpUX#7_Rd3NXI$LC~jK5>N5Psw3l&%=$PNb7Q0!^9A@~7MoZl#&6qC;jOd$MrxTC1RyI+c0s>@1O66% zgZ@c$HerYUg9_NrXCQb`ejja--zVOZ-{<$r@7CS?mOl7sw|WGn-(t{ecg{j=Cc5OYsR8vHl6WV|Ab=RyB99 zLy#rpaGy|jXZ?NnQ}x2knjDCOm{D*UF*_Kz0C05H=jkcdWEFM^Vd3{t%&|A44?{85 zS)ZzJ;EcE2f|Mjz6LC{)`)5XTJlDVy{0BD(d{F^CIw({`U zC>1q;<-kl{WA`Wjz$|i^gM%~T*!A?JkAHoRXb?QOE!lY9`~}6<)D`xe+7g~^?93qF zaG7i+UT8#m^bzJBmabeM*PW>DhgLhN;Y4*mbZ5RZL+9qD!b0ZjN*4OtsS>fC7|XTG zwFR!4xG-z4Ja3@DEdpAxwdeL|MmhM+8W^pXuv2@Xz{Ms?w2N25QTw{MECy8tqsM|R z2mI16(JizDgEhPbo)_*K*eX3L;D1(rpOBsx@JlD9%d21M#R30j^((#BI(`d3e<>8` zGklv0tFZH3EI_zOInQ^y*9u~DAva?mkLc$c$9wcNbD#0Ps)+ZK64Ig-u|+P*?wpZX zq4^&oZNJF%XRWo&O3nXmB8$P(%{*(dbv5?}9#uopuZE&uhEu@*G`}^$&(!a8{8sPO zs-2`TpMRV$E)?ZAFQ6Xi4QfL4wqSnyw8d*R?bUiNYP}Vi!D!b+wlcR0O6}EGnkoUx zzPK}>KxVY^B-rR4pgr&aSR$GJ(g8D2wHZOF!U*p8{7>={t3|tZRlP>*Tk17*BT32G zurhRyVI}CsV`^rYmoYi3wKoQqC+{tma!{7 z{6XdMD}3KX-QNVsc1uhCv{&GOOK>^6TKYG8=ry3G>H*)YOSZcLRGC3ZWz_FYXbz~? z&=bT%t)zNM=wUu2qw#h|3h1x1iMF%V0;?oDyGBA7I&rP9)Xw+zCrhEX?@gc)1rVC9 za9yVtR30zG2thSaiU zgbwqx)7LttU4@c&tF(D#McibZi=tDCCml5v!tYjOT2{aCD`VjwL@J=@hZ4R*tNuR- zY}3B0RsUL^|D{#`T%JCy`bY9yr&ZU=b1^pmJf&)+S4j5>D0Uz8*YNGtUO+)|?*$AG znXjfYzX&v<=8VYm(owCKNN)y(R_2=8xcnNwfCCCr%|QD$;b%%$1zcpYQz*}+QoC1Z z5B)oH?359U;B4KBGzXQ&KqWfn%zMGuo+mDWW~iW^GS;bFD2Pt`YtxzfoZXo9wlN{}9`r~PdF z_I=%bMG4iC2z+ic{9m#i~)OF>Hbf zNYCtS$Y5z37!YPhtFPdpA4uix%CnK!=wYo=u1cm^H%|tnR{cXLG&Q5iWitV?$m$IJ z8K7@S{;8dzz4otRBj)Lr>Rx{fVc&AEr^`%^rIw;~yyzJDPBs z@j;im*V`^*&fbmO4QA9xruXu4Ro^N?r3LEv4 z0#7_nbXL#&nkS6o*&CA*f+Dln8P*IogAz0^{H&?w#$W+Fz=NO;5b7wueigkYv2r@< z`FRlqN8=m5*k&m*%2v?h(xpJ#86p%{h`UYI} z-($Wp$F5B6#W-(yl9;#z{l6jDsE_vsf>PPmCbeuujqkfQTZQRYN6G1*4@o1>OG>Y` zitJ3gi4+FWT-W)25*}x~&Ws_ng~yz!KtbJ zXw>0e>m*(nFekFPLo8Tk&|245WI(@*!-wYf%B_zOs{C&!o56>9S6f)JBI4djSrA#f zxG6fS#5(T_!ZAwPX-0k;$#*>TpL|CHeYwuKhhgV zqv=dTyPP^tma4yG@?wfNuEo#{52pW)O8&%6Ctj+V)H&Oohcz1ZJ{8=QmyG(3#bR7s zc%E^oLri7-2R7!hhv8*yP|R^G?+q3+3kyoo@^K}*F%^BWG5rePFnqLKYkjjf%zvO_ zmw{1NA{%LeB(>r&#vWteO5J+-R3&d&iDIat4^WHor436XV_j7=!J0%ou{ySd96YUaVjM`#bL$`&5U-?zCy)T39`WJ+M>r zBYTbRANb-t0Tq$WDmjFw46e!!BGN~Or-KX=O0{+_>jqRDdD})(=6sZ|O;W;MkXwPI zSiPWh1(Krlf-)6I$nOQ^DbU0HK?@b=k^Z1N73i`4plStryg%qM1$weSXtM(Srax$} z0zKUyWGT=y{XwS`=-K|D)SpPPpX&$Ow3&~x2?Fme(2XkAEB#`Xl_^kNe^8AA?dT7B zT!EVVgElMB?*5?N3iMWg&_M;-+aGj9fm-^5PASmA{vh{Hr9kcdLE{wYaDUJ=1+w~s zZd9Nn{Xok%NjFm(4C(E|9kH&czB1`WsP3FGAR2WQLj|59FgCtrOOty_~A)bgt_4!z#@#d5q552_hqT`G|;3Gc%a_Z@~> zRvr7*Ycz~vE3+AjdHHgi?XlkcjA>t%F;E=7VMW&6@KRBDxXOoEKgZ)uNo2ALj10dM z63G-}Ly2tm6q;PTpr2<{IOFsoXxLi_FSKf|g%w?f;;hNV;hq;~JJz?{0*ByU>5WcK zWks&CBN~masvZ^mJ_d{&eCd7?6S($wNSrIC`3O^1)*BRJv=!iCpVK%d_WoS>?J}nQ z$0qoe@^q^(LzD^}CG%<4H)aZRMzPIGE1Zv6)&;OCbsDBO$#7+zj!nCmrUxb~L}AoB zd!`dJW_`_?84P*WBM{U88r0dCUq_3+tpydBD$dZrbcHQ)mC=-LW9%zf8!nPLv?83p zz!jPNnot}WzB1O(!k#iPYh{mw!#Lq@%l17w?PBaDpCyj?``2$Rk1Mt=zlgk}&dYDY z)hb3o*xg=*gVktM=DKfSS6Ynu@DYj1F7%M>4X4;>z}!p%qJo>3_#egq&{u`qytn(N4d8etkHROTR0MVm4>Sb-=ZEljcbNl zg?-__B0QXDZaAi9v!S5(E|_o4gk+HdI>KWkYn|Q&-uY#5NWhU7M zwn~1+V=nL`1$r#{RjrUodg~rurBUvevgJN2HF9D0V^T&T^j4(!$O{r=d5Kt3BGvcH zC;1L;RFzm^SK=sh0Q6&|!6n{aYpkHpvPP>EQmYlz>IfDm#BocU0bVOk0wt`$$wfA* zg8x=zg|7h`t68KYbwKg~vMVe$bE|3fqR2bOM%ChL)jmD|;_nE_ z%g)&1@0_8<6|A?#e<($-s+a1RA9-i_EsCp`yUWs_f*HQKA7T63P1JQq^#161EA>l^ zjdx;tX})uT>e z!a#3AS}rl0mZ@#$zQYGY%l~6}6Ue(MQBETu(ZgAzTyf%W2+%LZ1W&)fuu}BFb7aSP zX~R=@GPm+5vmYz$$F1rCi8fzhE4sQsn2O67oA(w|2FB06p-qYMF1bX8XEN1>Cm7xT zIUSrK;Ne(;pwBDl=u3bB&uKit<_EHsU0lWnD8`b()#+^ae>_!I721o;II< zjeY@S1cUMszDRpvKHeMZ!YMgTt5X{7*co{_+t+-?ny!}Xdwgw$pbz>_Nk+vyN$r)> z9KT?=M}uhE;@+_0$O}^9LhIxJ;iq{dp=U_UzBsm@foQxpRlH1dm-b@yT*-!$WrHhk z9DIIiZFR~iaEDW$j@O3^BtsxztEnC=RTUmk^SFA+&)Ku8oo#s-df8Aw)`gZUZZA;wmLpTE|vP@~7Mi4VuuT!0P>aK4QS#IN*jB^p=B z8jle;RYu_aJ&eHi2KrccbOheC61{r`Bk(+PZCP~i>0Id}gRhL(4IIGzJu6B3xbxaF z23yV)5pz&8bYhm$@8oljee$`;Dk9I4rzBEfcA2SSlZ>eS&+e+B`a>D2Dc1k#B0)oW zYT05T@)^Viim@Sy? zRo?>eC1Gb~!C`Y{nYb-S6O>gbsb>=g%fOMh3)^9T3ZKM^aEH-wVV0=!3l95+b8k@9 zaaEY)`Bq>G83GP0E<+@g67V4x^4K0tqL=b${=?)*QSSXx=)>3eOy{Nvj9WawZ<-`e zLweYzaq{{`U~ao{JaI#6sX6NgcWJ;mcQWAou%$w(j>`z!kWxGA{Pdct%FQYy;A^ky zk#Vwt9yVG!OwIi@FU@v%!XHLd1;+~D8>T8g*KP~0f|xAyjFQHPk{^=@RReqrp#Z8c zmlkdak6}yCH@fPiow(2nN@DAea0gqCfe}W`Cd>N|`i0_J8U05$70goJ5@+(9sR=A? z$5Li+krfa=%vA_~gJ?uUbB~p)c^NRDbqT zYt2oS8$KoFr~1XUUb%q_&%}6b*&j}l5#`L!d3{YMx^*#NelO^`;3W|dDqXI;>wL#y z2i6D~l{=h)`vqNK8Ai~7jV{GHW9)LHu*=ZPB+Jef#;p%3vhF8U=+A&;hxZSslX+Jb z)wSp_G=6XYq~Lu|%BU$gO#WuGKBYDvcBYTlUcke0UHH7H$ChEW4?IXT*R0Wi^W$db zw5<6M*2hW+nXBONY@^Nv3M1lNwb@+SUPvW0dAL@KVN#4=wqEklhRt&afAk2bmY16G zrGdEMg81Nd@i$?hXHA1-T5UOuM47JUTp8Uw=O_~Q95I?wt#_tF`chYLW?Zgx&9xZ4 zTW00MWW?=ri^F$u9H1LYT*Qa``CjWzg4A{p7Yn$`<7*1KYnC2wEI8pP2`7t_m+r=b zIcKb+lJ>>c5OiPh7~-l$B}cDdXn@(3-w(S&(t{ zle(_S+Aenb_U%ww^>!k>B-#4srs@;Sxf%Gtul^H2PFp|pTb>xJj_ghP07BWo_D*8u6+?P= zjJ`|kOpxm?76Xm!f()P2>kTK_M`DWE_(l2;33hIM!K$qwk1K)Y_j5IGE>+9hqP6J+`1Zlzr{0sY1Mn?=#2%*Ffk6 zo|QSS8EN-bku$TEJgZ-Uz?%0NQPlNRWg_ER`7)K1Y?AjF&z7x6YaeMvCf2#RQVFdV#oAB%-m&oTO^`90*TsHjDH2ce~ZL*(;js`Pf)EQOS32GBfMoR9`~qA{#3M$ zbQM(NRZYSjO0%!lM--Qp^^dUBjv&fi+f4QM2kqSGpR!ynd!2+?2QVF(^9?$Lx;6=8 z)KazPt_#T~Z}~S$N^|Oc6FD1Hnw_qXE!Vuk2PD7pRIjx_(Mg#!e=*BHlf zyFuXUGUMcO{dR%c6%ih79FO-cFuGG$&n;!FVK4ixZzkcXHeFupm6u{QJ*IrZ;?kTJ zt(wjeA+lC|sYp6LbQ|%J0(S@-G30V}JeW%*qt|}e*8y!f5N#KwJ=aIueeS%RMtxW@ zbz*jZ@mnK7Tpgx z==ai+Uh5ApIviqzs=la{LhD%|YWGO17P%laUC2|p6@4FKuSI`$B$2h$?8-fzs^J`emkS0@h)p^1Nup?8-j)LbQqXp{lQjSDSum1u?L6 znW}rymP5*&k>^#lTI12}Qd{N|(t>s`5dL0djZ&Dzko|IwQv8aBDYWhYmgf~lXH$2V ziX;1PiJ^Om5o26STI>OW>0FWd1-CD5yo4jGslf_ox5fhz(qFd(o;BX;+pfUpW&Y%s@eMxeJb;`w43$73o>gVs$0p7I%D3- z)QfSu5?3Z8$C`}YfW7oM$kL-4lT&eBbYqCl26rbp?v3t5H!ABJH49iW_-smxt=ky@ zQbn>Hl3pd^uN)-PN0o_Ej%e2QF1zRJ$xVr~5IhAXIecu{Iec%H9Lt>y7Du7f#EJ> z$uPU@cT9YN4c%5YYHYKG4N$2A6oHPS;A&?nc91#D7Lm1?WebIQOmY8$Sty}wegYA! zZaT$gfpEksI6D)OBv5dy%uB>*gd6@I?FO13g)7UuW5JcFsP!jV|J8}92M$!a_Fi1j z%{dY-O{;T9zD1sPMyy(n#qyB@TtTuT8XDQ$X=J$mXU2wZhi|S?F%orNWG%+O_A1ji zkPqvdmr)BwMY;+@+1?kHZVi(#c@)2(`eo3khPBE4xO_cDh6n6-1h{Ie$f(;hEXM|RV5PM;)DET+nQ z9N0RU5em<_2th2h2&qAMIQ=qoInRVTb5>JYNN&IoFtL}=tpe}M_GM{wxLcN0D7F=9pu71R!{8~&>DGrt6op2EyXvGg*Ty%^=Os5L zU)4Q0+6I#~Rhdmy1ffUrpsw92=fSoIB4eu*HL>E`-XhGYcvb9{Q<;C2d=;l1DFmv- z33a)gId^D=_`MRI_+X+Wu@hp`AgGG1&p&GG^gk&9=6pdu9QEGIe zjEyBLw!U*ZMZQ#-`i0nVicRB8Q+;~4Bi+Vn^dxTlJwlXAMr$cEV6k$PRtoQ1Ap8>%13#CTgxIl0cFXBqWKTY7!oF>oN7{8}Wh>acR zWS4`Vh8Njd^H);3Qe&&oHq%u0@d0rAhLvVN-w6!6hoGPfd@DShw&u-i9l?a7Bnpl* zA65CEKw0He9Z;%>%P&n;V+<}n%{du}c!YPxQXef*=tlaD zjUjNiQ?4FWbx!hpXJGb9mIL_i9Av7_8JO(~4;JU117qJPecZ*7AGs(S%16~_O7tnx z$Z#Br1G{ov41U#H0+>fjH}hJ@G6W_ahpso<8M>UeT(vtljXvBr&wN9^tVUw}%4N346)Aq7^ik+5dHt-j@; zLMgL;B=J}?Zi75-b);dTF>UJ{#2QE8%aW~cY@sC=dzJ*83Jgmg7W8n?fQ$o4xa>^l z@IrW~=~kg~nrCoeSvsn)s(J4CA;Ki{`h1M0mhBZWFKaXOvv++MCzyYKkGj2h!>RIw zWe9XRQ_|V#*-)sQoSDvN8R)Y(0$}JYGQT^Cm~x`Qi8r{zMo-%M%VW_f8!AgNBT$gY zGR8i2Ebo zSS0d`qgd=1y}0(QiQ(C;F7>us6_RY()Y^VENV;j(h;M>85%?NW_bZ}0a%@^-$m)BE zDpI&myC|i>Vidly@_{e)e~NEwFFv&t=9={{7&uWW{o37hG;xV#=5c12jfM_s@0lX6 z<5#z*2iuJQCbp5`u(qmHVlEMSlplZRx_fe_i2uRWcbosJKbdIu82`Sg{@+Qa^9gaq zr@cCBs?%tX({VhP1nKrZi5=ESP@L$07lDW+d3dn3ycat=9CVjh>x)q_YM09)hsGBl zc3k(`V4b3Ygs5@7$t-=BDvGu1d0Ppu6eY!0J_`!f3%$zmq7jMn4eV4Wkl{W?B;Gf& zGjCR$K7!LpBZyia$C<_yNmGK#U}UisC+~FD$LXw$rDXe@8m0$m-HNTH@Y51=PyO*k z3U9iDQgZ5`aaOjI8q&E&{thTr#uuCe=rh)Hb#gjM&*0akUl3X2vfxd^DZ1Db5KbX% zf^kacq)k$PO`H7XIYJJYU$9}sD4ci@toW`J&yMXmxiSc~AQPlLo=oRv24ay6M4zWC z&+Vv$FXRSi{|DvE+QGru3{G7T5NTs{0B$a}UKkI^9)ciHqu7lkI}jnHq-1vZCu&1E zJhyx*${|2zvq~CpZ)U2vS{cVE0BP;vEmk+DL&UDghD_c}IReYDInhT@Y#|U9#J)jb zbYR&?V_s^ncSJS(8?7(@F2i4y{ZS!ZhCjE|X6?Ut(J5iN9IZ8T*D-*_2Th!(a(ae- z0+)Zc=@X}|(l42|RzJ@=HM+Ok&)F%}92yVveK`)!5XSAQu_rFK6RF&mipG$a9&5NKE$hG4bm6P(PtV~x<1jclI7fv(^rE@ zjpmnakLYSv4yec~)jp)7{2*Xdtoa`k6ua`2t3G__kdGr&%@5YZz6#?5M%O9M^HlAr z1Qyoia(G`^FUpMYw+(Bd?lr8zdd?huywGyKVI^t)M5Z|GmFwsM*;s7nk@#v%$0p9G z`gdd-GU^q4WX!1Aqe4bSV`{`C9|TxDlee%_k3YmgEq0CgzeK>ofq=*vq8p6Wc6mZk z*`2IVFdh&&1nq(5uOVuA22Ow$6KiUcei9#ontv5g^;Mo&wo-{IX*oE8- zJS#KJyfHI<5q3y8WS=}E=JU=L(su-AWx7@b#!^+{1#gnM*hTCKS?8N8-Qs>V2ON`) z6Fs^!=kqn+2u@xTT=Mr+b5LN8+ql>1@aiM zXlnqivn$_;O2DyM;&I@Ftj#&DtY+(x^TefDS$brpJHjG1tZRUC>Dh~Lae z5NqBWNpyMS?vatZ(<66}vxY|_;#GT5QE{R9F;2z~WbMbsHWJyV41vv$&7)>LY)OME z6}pq~NaQ01DV0?2SWxyms%5^lFgH#tu4SgYGt;$Tenihqv!0hWgOKemu@#o(G&AOK zYwm@;!}Vvcu}#Qs2$!V0pEhiJh^HAc2)qu=2?iO>8Qc*cYUR^tj^oun>^ZR5dY}2K zghLFoU4a3z>R;{ZKVI$K3fK`P4-`oQog>U@QI1Q^0=imVsW zK73uA7{EpmnLgxx+3%3;>9V^6*gE;*l|@FyGYh>j4o&c>&`#f z;)QW!9JMc|JNWtPDG~9wJuue__*&R?InTNU3>Z??@QBvQO_;{e(`qL1%t;i%Ni#Be zH=B_j%oa0E2@l2x7uA1|g!-&@)&snO$Holx#vR%EpwV+e?wOB{|{Tfk@A+*i)Ko`c;rZ;09*Y)}w@wO(wccU7-D?+KkXU&lSznJtu&xHrUqNr2 z=~PuRdtT*+VUEC}!;Q1j6O;9uqu|0_rQ>o<^Kc1?T~IHNpXV#g7CInl=^b0XEo zLi9_CK9cC^A|x{NP_=T9&6Ekk<~Fc7eU`eNDYS5R10iA+cY?hGI@m_v(>24X&J;>`N(6UTieQ z*Cd7hNMOxi4?}L9T^HqX!Geg_bSk1|tD3M&5fh-Pll8`iBgjvXAC1>JE8RIq9|P9% zl&J+c3?$?5rHx4`rrR!DLBvxt>-@y<&>UZf?|kA(tRcjL=$s9QwfopFiG**UGvYHu z8uR&lRXub@JF@;ZF(EX(k6fd#jWO)B^3!=fmph(3oZ-aU0U(w-;%X=9QixJik8DvO zZaC(Nbhs|b6B3~tBMuI`Rc`J;t>W;F!Zo0A!dWpi=ZjT?=gq(;QZz&lnM)7y$=Py= zNfo48-$|1p#qmZ?FC&3qt><$ld>&pRouRMy&C##MMUs>qxN#zW{g7xN?vrMnKNg_J zIFW#Z6FZ55Ug{bDIrGT7_?;_{TOga+*6;F!Ghzzaf_tic7BKhtE}5Up#F{8-WPvrh zRy`M5z>0fQyFcgj;7LCr61Xval2pl3i(>^kyZ6v8wxYHj| zp3K+c((E{#NTe+GF1KUg*RWAMNXEuV<&Ei1@hK%uWc<4)w1VcRuMefKmnYv`nmvS8 zK68(6!O~26{Bpa;N69j~wHF5nUA9)8{c}0`niRgwENJHj9lHKFg||3f5D!+}Uv^nS zA5x~$z+fpvQ+(*hd_{*rym;M;c5j0E4}`%sOAy&phK~#et@+^(}&N%QgeV!Y_xqsO(I|`E?AzpET@q<@_R#K zlcP0(SA0KxAXa4E-`D(a@{)BR^tL?e!WUR>37=|Z_oeW^tmb1SlOq+`qI=P+B1jck zSI8zErw#)7F1YkS<2tu1aCbUZqSv{d!TdD9P5J5cRrcy!#%)eVAP(VX^TVtr8a8)q zo2`zt;XM!xMJ$g}#84@FuG@zxP52vhu=8bE#N}LsIctW5L$>e4^YCwK{WLWui5=b| zk{EcA#adC^oPbr0{})5kndQNDZPZP^FT&~LkJdUz*NAUAJ?SPn*V6&c_!^wGEWgF~ z-;zd_VCCM%S?D1ahyN;BOqMJz3IBq_Dm~wdb8Na*_U!9em{1MaOB;tfT6eaM%xqhd z>9VAZI~z*1p|djaa6L3Pwbg^izV@Il zZfpFi*Y?)Q%fi<_*OpjdJ^|JiqSo{G5B?4U-^=qu;ElZRBTg6iZ_IR)ZG8fuH~DJ> zG)l4u__hGwBK}9jZQ>oAOFl2v(jsF!sJvYH(Tww0$yL2C?-M(&WzTT?mM8P5*}W52 zPIEX0?XAL4L+bW0A{WU)wd5`G7;ERTuoaR8w!Ks<-oNEmQkH5v_LFgHI7;*}LZtxj z^7kptH@tnXD*B<%wTTVDjsi>RP_V^EaM%6Or%?OpmJ0R|#_vsx9EyX8iSjT`IJ6%g zg4%>;qrJj7R9RJDNhD&olO3oQk8-Gjm%KxkvG)k?4GDGje`NKTW1m#cxG8yd+&xtO zKC*qCY)jsu6p<~JR0G(6?l?h77OV2!s-oYulUNHg-TXGu?BwTF(Hq=?zrOu3)opD zGH^)n#bo;Nn=gGqk7T6Kj;r^jm1-xz_1S?^?Ngp#fO`!+`v%mTS=9-<&ujvf z8ZWsKGSd7HGVpq-qk3LC){AvvicRe5edH(DhmLw!QQwDMVR|VJ_ty!{Rfj|cW1L7` zwTwYLNU)AdRq<`!5xNu=Ai(vCt*nsWjj)c@?_}`OZ8ndE*H`4KO1SUmP^CTaFBy82 z|ABw<61pFlViB}--R6#&s=wAHfbldIMSJW3;rn2IOE9;CL0>>sM;X_`#AvDdF|e;P zkaO^^is?>AXbCD;bFa9Qj^KR6;d@GSI#ut>aFg7=RevaDO#K!q%Amcp5F>1L2eb@L z5#GadVW#tQZQ1KvE+mC=)~ymqoBMwQsP$9nFwx2@-U;moX-*p8ot=1iCPLM5yYaU2 z4!78yK;2hTSI6lzL129i?7IU@cGvrVG_G`=uQaUcBKnvZ23VCc@r6!(KwF~pg@(4o z8hM-{idHQL1ni>3I9)8cRxR62gfUVMGZJ=e`IKH4dI%txs2$pkid(&(O53>KuIEA9 zRpYCHQOU}dh$-vr>P&o=C+)s-%SZ|z62k{VRSyFhO!l<8d^cK`^?kLZ`G2iylFovS z37Ohm=Y8Rz9oK5rAwt#rHeW)k_0`5X147>-nq_-}O@%6T)lpDw8?=x9p;iA3d{T>y z+Shg@L|OW^80?>?>gzPv>I7hIiIq~#RM&p0YrCqh@a@vO`)F0Y(QF<>ZyTB@9c{}6 z(QK}fh+9VS)i=i0j$MVnZpYfu@U5@$szjN(Rb?7SMyk-%02OJzWo(xhm$5yahtv4j z6-djpR%bFC4$B-T{lK`nXaEdcU%Gn@m^XOLHCZ zry|-9kJ4VTc+nVD+bfxGi?Qk9LV9Edc*#e|84ZlTQjg8I^uR|Yb zyWXuoF~Ha!Z*Di*GZN^9#gWZ2tuUo@Go>(vr1AUzeF}k19H%Y2n3nF^PY-3(fAKmL zB2+9!GFZ5aCw#5Ald!{tz0c&xY?UgdXeN9&^mQdH2P%;5{52Roj*5B9gjoLe01<(N zSxxZ0R%ds+E$P&-ElyO6t?HKZ`Bq~rp0BU<4X`OJg7F-f8j;)kFm2}RYnY^yKCOnY znwaY-yG+SN^(tMcS}+K0^ih4dM1IU3Ou<@VCA7%^oo!AM%5Vw zqWeDUWQQNzm8&wUcG_L(E|E1mCZ35*#YbLyE5Vkusy>#!OAhr3S=)R0nI9v@NazNB zg1^ZGvm^R=xY557U{CTVzMR&btw(XfZv(FUr1j%}?Nqz&t=7NlJN>s2ElzjxakO)L zo-e-jKgply@vZHlzcGp|4?|=SXI!uR1e1R~zVn|TI~4v)=xG8&)8Usk*TnD{S<{#WZ)OZF&%r}}cMeN<|+b!W?=URdj))($~&s-^W8@3sHZ zcR_32!IaNICNK~J(^J$gNW*4n!*I7~+Z^GeMaB``JjSn!HIn`Ni#9f3xqlAbNLpK| zt1Zdcp)X^7ml$fG7=1fFl|LAq=o?aMKCuL9D)+=!{=4Vz*M^;?FJC*XH1NbSA@NW0 z`|`ARq2t5Aqj&NVEt=gRdM zT6fy{w0;=P9>AYe#vkte&)(N+UnAq%_I_0CJ-qjD@{X_5V%1Y=EGJtUER3BU;ZA8( znZx8^H5}L~HwPd1ll*r2zsqkPmzJneF(BHl;tnQGraBs0cb+LSE|g?U4dAvA^%D25 z`ZFTU_@5`YyIlr(R&EvCj*1xWN85A?A;p8(Jl%44Je{P_h=X zvEt-5k(>-md7vNi9`Cl zoeYSqI(3R197PDX9TlyIvN~Zs9g*z0X})W+eW||ntyarENtyTqt*w=QnwVZc+Yz!L zRN#^+XZ+GNe=86fW+6(~B@{UhJ-=HW)5lPz;GeDlz z*_Q56CIxLRqQRP&jn97n{e-uE+E$QilatRb0RyE)Ark*i_ue9-JG=<1CErp~_!bk_ zuDR!Eq}ESM_%3PLXEv*>eZ%@nBgcO(VConV#rA_Vfw-iwQ=tdsZCsPXWi66J+xbdC zru0_haFfZc1O=zE6BlB}ft&RyOHgdt{)f$GyylKPPmUO;ZTTJ47v*f%9(o+^%!Vz$ z90u1ON>HEd4RR*r=JDILYFT~bH?N6@VI^wSqN?Xxb~4nrA>aBu!y2gh$1poIaXSW} zrhP;N0%E5q*tCONGBd^k)R$0bV8$H@u&h zk^K_InwHpYc)+85JG?X%_2W=2>>Fe?osibO7)V<|N84yT$C#1dE}Y@`Gk-7gSI6H@ z{{G2d34e$9yPCi8{C&b-Dn&k@zf1U2JgBhfRpulPU`=tnJQ@a7(=?gJEIigUVguYb{S3nZncXr?JD;cF1OCLyOv43)@<(0SXCri{a5Y zi1dXDTX%w@4?(Jx#4Z=>!>?GwDE%|m9*blrxa_f_8EQND+ZV<;mZGHR-o~%nr(DT2 zl4j1~l1%Furrg-4q?+Dw3ruh30xOLwhq|wsr-;!F>(fQv@}9CM$s~HeWYpHi8)Ra# zZ;m9^II*=6E1QUZjj=v+LPSr>(K9EknTVB*>Hd2FRfd?^tYpHSF z8fBA2{}Ph~bI!Dc<|6IId`^FtBpG$-S^E>}i#c(5Ay=kQ z9XUO#24WPH@J7z@Rmn53!OwYf6-bp`POoi~ynv5NUI}gXO`cClk-bdzw88(S?Ooub zs?NRtNoJA^Bwp8SX1?fR^!35N50L35|gHqk&rWzHKa53}$K5Ne;LDaVY^S!#WYLhl6GTEzg=Zg(rbZxy3Aah0KfwzucCFHgoc((S4uTr;Nx=eqH`520XstYu%=8cx{SvQbiL0Y?@GK4Hr!p}>3;pb(A zH5yNj;k#K77S`_|ZS=;OMA*iVv^uQg3OOT5cybDJzm~$8lESr;LMKWIr*pw~POd7Q zFQL?!-7}!Xg9lZA%ufeU{n3MxNpNPkq?E(P9UsVaQR-4pk>gP8IEl@rBv%Zv{%do3 zRdoVa%r}1gBIBb=;_UUEkC6f6jZPWV%3ky7rP4@NrHy<7s-*p!!dDp2les5wMd(&C zmkrL%JkL>WCu+7*B&1wYg!H9jpw1DE>#Co|rzRDkF+s()lp}f`vy>wkKTj^AiP_89xlKjOtDqUcbLju7yER5pk<7C8D0Vt^^}n z?cP{VR*Uak{+#?R&T8=&8JP?TfwbvD#BD6HTcM?lmX3l$lEoA9V=fM_T2y9;o*k;C z3LHeYnPqyrX1IKpBR=b!SmYaRw0$mn0FkvaTvW(>jx?ljPsopXCT~*SC*;RW;!Vo@ zg!}-pLRk?Wml+-?*e64_p0!s*KN7rl<5OhA=^!WgR*R6RQ!;JZfYUcp8%XrUA%q1a zec_ToL8tbkB{n|zXX=GZ0|l>l6fRZriuhctC-(#}Nw6cZ;H@W);Ig;mb=I7xzk2I- ztQ;@Wmc}@3v-oBOGxrG;rBF4!_)s89a1F(qBeC@Gs-%@8Li`u8kBx`_A+$_RFcC?ojFjk`qG2JJqehzMtixAgKk2Iw2oMDRKDDJR+4Ko z?imbjyzy^LWyA<4Q86Xk|0K2CRZlIW`WEL9SWCAV#eKV;zXh!e#ENbY$_#_dQ%Tq7e=-@ z5FSp}#m;rk&T{=2I*NZ)DsS?;WxD)6d?CNN3)~9mSKK}$d^>(e;@ zpo=K^Mn_e=qt;a~ydI-|72f%`{Niyn&ynXtg+w-q`%-uWAT^TQhZCy9{`?T zV)Sf;9-U1ULH1skM8ON_+`1j8*;0@i!^g!(7`Sjm;b zndhO<_`G;TgI_!>_#Xy?i$ZoJiZ?ExQV`T~L=CN6Ku4D*h*+{$4J-|Ks}#i+3`#T2 zXR~@F(&|G^9!}lLB$u!zr*wUb6bb+be(hV-P;8L6uKUj+B~5jO&0;Q)tokHn7)-al z;7IZ}rTrjjYpSziT=&bVI@}Ur8HXLfJk??7#Hyl5fm{!@A`%Az zm(|5qzXl$bfiV~v=m&{lB}&*t=!3&6VdS`$);F6N$GeMHqIG!Sw!EfV@|v<7O<`(MGE~+CWGaC=3C~) z0`XU47;5~y)KLcKK}iFcKPfw0FW0?4BUsLMPyinmui#@v{92QQf~}a-G;&scV{js# z3}@6$<*N$mPqeDiZcm;)v*}?8(KyCRWcExe0j}Q1a8bKa52o-HMPYukx};Y#ag~%> zK3^X%F+=0!&&)CV771)sB=<3KyYBxZ{<^9{Rx72noUVJOFgimI%ePnQYgdCP<60$A zHT^ALhGwev^f=ODILau|TciQR!)gGj`jxJYmqdqzRJ$tg`7|E>R3)mHXtjlOd|ND6 zpjCk!esR|w8<0wG`G+bUuyT)5r%2U-1CTN)YAw^|IXZrLGgx#y+89sq)hdkCLX9T& zJ>k&(;$P_oCWpjC6J9aH1}Rmv{?E(jtXCtoZzwt%4(GkLBG0w)N=s%mpaN9oZBdmU z?M+@>g~G1#WVWc9PnDWu?dRAt@zlIU_Q}-?*u@5eJtjmU7?eb_T9mkIiQZCD7LkWl z@L0p@Y7repmFYR9=1q0GEOsGXz>>KKdE99*m` z(LoC=jvBBzz2@NV#!8A^^37~=GQ4pM^S%Jb`Sp(mw**0)fi&|fY$D_Gn3qSE3suX( z)h@=7?;BA&?M$Vcl5X6u;)@iAQH)bd7abPUnPm;BjtIiojmFXU<;25ILG<{__4r&M zlINkm;*Hf^C3!HEKb&@w*v_~ z&g0}6)$whr1kezh;A=<7>Bi%Fsm&j+b-#yEpoP}Kq}Umr=U6>b2SwGLABZtW%s0HR zkuxSsT2+X;!vaV%Y#$@m6`b1Bm(lJv?df!Ri0VyJAUF+AW6#AGn%H`DOm)CB_tK34Pm3qF*%3 zUfQX~)nfJCVp+|9-mp-oT2+hH-{_s0QOnNuz+VS5zaWzN$1WBrwB>>hN@&EgIcfsY z8$80t?vjc;f1CPUD!)O&2N8A2Cy1j5)0E#0{4x=gThKuelP@vuaatRPl4}FcOH}=N zX`5h!xW#xc@s&jk-w57vjxyRjg{~J6HJ@ii^na$Sc#+mrg$T6*mD7~qo#dI;;%b=1 z%hc;QXV}CxFM<@xd}3ebmigkRauZJw}wY*9i8_6rUpr;DJUt_@AYkM+;S@}U3GOpl}NW* zZ;MYtaMB(v#881oS%6?Vs$W20jN^0QVF4=%p_#-z$F;5p{}qStF|Gds-(6b&T;IQH z{quauT0ht^jeHsCFzYaDkGZpnn5M7Iz07}>{uwJFNoY??FECD}V{8gU4XbA^73@-f zg8o@(4x~a1olTeLkA17f$XT|ySG(#nEs2aygC)7pA$cHxvwwoVVZu6k_v{ap4 zf^_1gkzQear3*QXhboi&fbHc-h zScx$a!fy>Bk2QqNG%LW|;Un5OEMkFJ#*^8Jh66egzf2;cDhX!-eD$Do9<$RaiorkP zs}{bK?txj0DLALR-t4OHW&5IqY17sCxE}a5U$yX$)?T26e~f}~_zt8t@v7Y-1BSDs ztA0GZ!q9wvyi0Ek1zE6idbQ(|1t~)a$K1v=Gfq36<-b7RBJV(Ls==p(W8;c=eV@GE}M3$}QX=Go^7{e6Zm%94v2ZtcMhZ zw@i7=EiuFPiu2EbTfj7 zl>-xJctn%)NOFpN>RnALN~2@ccb6=Z@2^?k;oVF5c5(_*wO?&#t-Qmk{;({4Oa8g4 z&rwOMs;?sHXjz}d`=qLmAUnCo@dvdn(x{A)o0;?4@mtVOI9}jtSRfQYb;hvLxazM| zghAT7-4TDwch}a~*gx10AHye!7A9R4CNdsmFy&fx{QDhSHI(2ZBxnu2>{E(~sb@8; z%+zR>&k_-isn!0fy`8cDSK9lnzQHOc46EV{mEW+T_DD>$y{`+XnG)C{OAIsFH_9qx zsqq$!Jr1JEE;eSQ%J<4RtL@-ZNC)W(X#5oahZ<7`@Ousakr`-!4UH)Covyuv?5J3e9! z!!X(PfJgj~r~5C0bh;Y8&s)w;{Wa}if`As=XYG35_0lzQ`>4B2*_>?+JJ6LP&|tfb zQ7=+8M)>EPXrxaXAIreQ`15b+6R681y+O)m6*NDfUIJ6*d%;KP=GvyGWs_pAjKrKi*TF)%C*b8)EX_ zSo4v-Tl+9Ue`D~|rH9N^*9+U4x>bw~F@qnh;;^z-`s-yY_Y76DDiSK^^lvRHLOl@L zlFd?#MGdA#Rt^6sdUoW77;BL>BdhMoi|Q}XCLT5nvt12x=Cj7Z$suna9$p1wNdcid1I)Mu2{`v(p!^&l_;6BU>NIseoYh?(_t0tP~YO~4O6gH+YvSm<)xXTOA4PC{r zHSQ^AYa z6>$QqONhm(y>@A|*W?n`u_4Ah|C?(6(dW#@=q`x+9Z71-h5RzN7tyk^bDhXjI^!md znYl=j`tc`dRv||psgAnSpP?O}>I&}RO>ek?=(>ee_|!IgK)tsdw3|QDgYpUKfss(z zIXLGVci%vaZGng7gUJS*!`m;TY3nLA31>xgJ=Nl9>2{O`R5BLOo)Jd{=r=1pYcaC+ zG{M=OkJz_ar5V#2>0t{%(JB&VdlbR;UH?rD^TuZ?T`R>9htKf053)NB%OJCgU}adl zMdlA}C}=Z%d$dl#G>7LM`i#0s+rr0FZJQ@;d%3EA%dtq?{#<>#6Kj3awzBny%|x;- z-F9<|<-~xqd4Y=c!{aKJZ)wZZ62?(#m_1ShD_mrmwpvDO?zFc>8$_iz*c8`%Q&Y65 zgd$0Vu7#|BdsE!ZEdWiSQjIi%&q>{thxX}Qfg7HvmSb1__h_5Q*!LG$&3~I}<-Lzv>)Ux&WaAmadt5KL3M1jR`7^&piu{SS zS55NI#3c0{{=B9H>GR#Rr+Kk;EEen$IR|HbEbS(wVr-e2coNBQTb~pdXADST&&!s@ zIJ|=h;1S|x&!5-jPZGGvsXYF?|$$mtNd-n^)WP_k$bym z8K(b#ZnCy+fGwbeV}>J$eIw*Y>R@ih?zdC{zWXL?#B(IwX8hg?tKvj%vd&$nTF7ey&RbHsQA$n< z5e(@^ZY#O4ig3`lx2j#5?f6P>yK$l1fu>cLNSi)iO)=z}u`A%;7r6{gGmh=D8uvU> zi!|;QX#!s+fWYLHhq_wCAXoK03dgj8;?rkwHY%ah5zwT z8qe1-a&{vllSp-?wdZ3t5B&8qW8EJif^UXBc^&@Kj4K9X=pFhy<{XL_EbdpFPSxr~ z*2S&MYVs1}!<{s?x$E0n8ua1?C&W%3SX0ZSv5S7huC`fOs>2KgTli#SD@j;vIrHjB z^Cuhsr99;>+ML!9UVWa`-Yd>lZLPnl9h}f|Fh0_f+&(*{q5WqVs|TYQTaixSs(c(7 zw#}-YCU|AB;FUSSD?5GqDu1Ilb|ENaIlbrjlM=@ZvYAb9g_Q44Yl5AE}ET*DPHW45Q zT`ajGzhy8cu>tZ}KiXbp~%Z$7C(=CHMUwRkIW48$!){np?PQAwJ#4+G> zmGD}kUVRRIz|67wRqKz3Uz(-zmZXitol*>T>|mBfyWYePdx%M-AmDv4YT4?54UrUZ znu*3IDuyao6a;d5<7oXeg<~c>e|VV@MJ7 z7;9f=E`m5Dh6TMBR_6Dp9C z$UH|_8-d*$x86Ew-Bp%|RlaY#-ujZQ8OhN0ob7q-Kyfe#p6@8w3eU+FsNB}uTI;n{ z$X#y1>l7_mu(c#u(8=Fh(4iZ?HY478Q)a{i##jG`*(spxh)1Gn$}kZ;!QCy#;z09` z3||Gi($44&L@+FBmpU_Qhq>29J6ML9@q0;91a34qO!et1NudTZ1od|$<-v&&NjYX% z$}z)Ij>#BIxs}Kqno5jOw72Xk8-&hnvelC20(V2FKe?|}Mza5k+=6}nOVvyts)0h| zq129b-!wDThx(m&eRHg9oDTOl#*zIUS~*I9y#YV$U~bzY(2dWU5b*!Hk@s zzcaksIPw=6O`$DvJ}YnrvIDD;ax}J~kE14+1*YaZjX}?d8EN5Eq_rp5j8BPZ*_fTK ziXnF-`a8ALY(B><%-0cmPu6Y$tGHCaD(v(8U$B8lY;+kfNW^o^SCBe;4JvKfuJh*o zKmh*6`i>*2rw`17Fg!pwps6j%c=KAE=JaW;zWnLu`o;oyfsMS$`hZbQs7R131uy7J zCqS|a;CoLncKn|L-{%{tKKfsZ-YL!TX>T7n;R8r2v0gh z*CE=pNeILNbosPf4k4p~)g<;riav}n$|#oAF;A|P@nJ63MzKynl~f4d0j&nmd_Ztg zCar@UE5K&oc1!Yf+~8u(rUM(Vhe{N}Dze%#E4!m}HI?>ZD`F>MfOUUGIgm+B(`&l5 znnN}pl1Xf>M`5;$y~*%pOeV`f_;RD`_cE|$g_c|`O6fM1$cB*V>5pSCv>i#YlMDl$ zpixC?^!K+$Y39`(LNn7%xtZJP zP)jf~l@H~m#*>Jisp~&5z}uA2Dx)I`qP_%;0wvbWtc`4IBsmCgL^QEDsf=+x*64gS z+6&`}qPHuUC#}ZK?cS=9#-FUO<{EuL8m7c|(lY?F1vLn) zn^k|2l_gC-ik;`v^2Jr)Y>$~7yep=!iavAw zO~Kkvb(f5`Ws6yk1Xvf8#-0YoHW1Dt1Q$hcUK&Aa6$Ixi753}Yk}~5-=8LjNArw3s zLVZ0=Tg@;`EHO?;5yYbao*4{=Y>4KX&j8g64O9`pb}lnsQR%cr2Vf$h7i%3oFpTd}&+@;aMx1KkMwc2rY6WYv z7WHZO(HCv$O6xlm%UjDPG!AVOTPNF&+if%c470?g?IvZEkGBgxfkIe8AA3G13OBr? zy?>(aV;ks`B%ZV&{bR|o>}{|{G9FGx(}ncT>25Z9v&yw-Qu^R0 zK_~G5BCtrnS`L9;BHHDP1YQQs^5JkLlcj=M|4f%QnO-C}0o+;9$Im;>Rjviy#6X{1 zD&Ya7MfAzb4&(Qp9J7ZW;G>q|IqtPcMJc3UAOzJVN3mE|>|Q$|p)+0s2kFD@wB)mHHl3{@v1Cd!@Og zVxak0L3q+^Quceu18s&oPz|)N1qDNM%)%NG9n7n;S|cz#4JuFsmIQ1D3zlRDP%Hxf@^MTZ zOv;{h0=^P_*=kd|th{-%=w&g4US$Y*S~gGP)3>2%2&jfbpfo0RC|rX%3QR-QcKFz$ zo!^OR`PkJ5;>aDxsBW0_N2lhiwj3Q-q@FiO`!c61TE8JaNIa3inLNKGP&qT9qJ47@ zG$3>}b+jn!KT2OaM;1z{#&@fyMPIvcGn)TN`ii))48p%lU-M%n#|VAR|Kb$-Dqs~~ zr?1S~(K8yYqE23|iuaxLwN?dD^!2D}SBt)qGE=ld2q9EkfnX`R`lYlWf8R`3XS=jB zpsP|hMs{S?ct;>bdSYZYE>q=N(aF@2HXA)j+7dU}2;H@4F7A(TL$SVzvYtdxrGW?v z5y>2%Z&hTFuu{mA2x_D)y75;8RoW;@P^A%AQO3O;Y2-IZwAZ5X-A>$pkFZAQsgNXV zQg0=fHoERxY3K^CV4hL#DeG0S~Xj?pJFYNW{0#dJ1%9E81nop9s)YHSb`@v zTa}+2X@t0FBaqDjYR~NV^eLK1Y-ti9%0QcC?&cj@@9D=Km#@n1+08d-^Rf`Bdp@_C zkzGl}U!Y%XjF!D4{<6&UNICc-Xn9)=2->0pcrf;4vr=(_cam2-2{tr~q)WfH?8FTW z5nYi=0+C1%S31*iwEi!N?t|Y>bZ7h{M0Z2WcN5*w$(^drp|sXBu1GbXEG`RZ;xcQ; zHGC{FCQvG+6)jTwnUGRZ7#s4Zv1v{^I9y!Oy(0Ih9}Ii zXZZehdUSuwURU9&smUTMKx%rTOxBB2i;_T%Zn~HAic4F-ulP;HZ^a$r%9pSA^fKTX z7Oyfq_{(H}>ESPPa*s+wwviQ+yN9_uhq;?^Q_c|K_gA^v_d>K}f8=5Bv52v?n_>wH z9%JI-)NIKuvMo9_w++KmeSDaE{V;d!F!!=y?j^(ACBxkLxc`yT(SFd5a!BOGshQF` z*WnYFj*I7HoAqRaUcr8K#jXp%!=timyMm5UtHB0E^gpc=i);d>WCMw9J^4 zo#q*vM5TkUt^B3BtxteUrR?P0@k+H7KjW2UIR0<V&mPa>2IL3FKW9x6?JMSin@`| zj#skz+P2x0v&G>-K(Q3|KF-1Y&r5O=cdN3jmmP<31vB{Gka@0g5sp3E%`-spF`7b` zZZ};P{L26yfFbes1xPK9J?4Rf5nv%aoB3}XkdI)g95@9JDaIcM5Yw@?iqNqa!(o9L zx&ZJFfH_Dh5wr<2l9B*t;Oqki23(^~6}IUwrp?&SoDS{fJ-SC?e%5UjlU=31+OuU5 zUw@^|c&4=w>B|(OoHJytviD^-Pyn)_7z<3!!?1F}DcZl_9&`UGv7?dCGX8sGG;&Ps z(_%C1E2Gp(!%AUz0hDPdIC2%ciQMeXYhYBF)?@*AR zJ6h-DSmP z`;xnGn-^N4r84{Dn!gr$LnQRd_SSN!CODjj3ZhhSeysriwnDJ?*afA^Vs0@GDh{$NFCD^nU6*B@fu(6(Tbu1_ zD>XWKnN?{Tbqs(ILe(H{ZJ~C=8iVr`0E0!t!iE6MjNI${sUb|I10nNTfiT)Tc|8f7 z3U#*BxZMiAa8I)#qTPG88~?829f+d4g^jDNAUVcz319#y1vFA<>2nsH6QsD%xs1I* zY_&F{?oUkTQTT;c;j&8RGzy7f8iH1rv)A}3A9{C1(dtGRnJV-BUA;ioIeXu+5UWDr z|7J`lOMzNOB3ZS^*w+F^mylw4?P`&-P*NGPe{Z}B5^rYmlCf%4oRV)nQ|yZOOx?Ve&}RN@gB7?NH;JjS#;Pgqqf#~mMR5SiQ*W=PYic4fOA=~-d6=Nu3T=$uZ zR5V)|Jt|&C)Jrlo15zLr7mQOdde4X?06_)3wv(`IW4h$A`D0owR0hqKAd`3sa@zX* z6%C}yoTW?RHV{xv>ft@Z9A^B&i+?8F=kUgvr$6KL#c=~y+4hVBk61GvYbkMFdqrg% z`X5?%ti2g%cYWXd`7o%pt&Royt&YHL84kg)xSui)DG8P7E7Hq?v(rk#E1bq1YUM^d z3B{aSng>e6KRDaXx1`|gbV6`zTZ6DiCH%-m+1w~`ztqS-5+R3^c6ItfJU&vYGn>qYrLvfCe<=y z_jgG;jjWb~Rl9(yowt8>dbDa}@U^;q!rfk^ZZF^*tlRbMOo%vGx2OLwST{wLk}#9& z#N0W;Hoa|5-`L&)cZ|=?UC1mVdbAJwLhI?6-ZqE&~ zOsA_}xWQhh;UEZFl;V8JJ}Q%cqr>#E;w718ag ze;F4x!h74?zL-MFus>$cC+~(7){{$@WA=WOmYtX^W84^*(U^?={R@ulp^4G6pko6C z&KYl@Pg0YR6F#uL&@4Z&CugSx_!cuuFF2-kyR>ZxS{EE6=8N_d=w-Ild@pMo_BnbB zjxbqJYKtk{Vf13m4q!!}Q&y2$Tsv;>pXcAVzu*YhVW2Sz3RjwG$FM0@4*6EXe?5EM->Apm8d46H}e#(to?_z`g-o$OH7Z)x@xr2!(&hL{(_W!EwY_YQkR*L2^WFFvQn;$ zrVPRzn0&@BhSDDwNnZx)Q2KI9%{}eVMWe!ytt7W%{pqM1>L)aQ3#uV%`T&b`Q;3kt4RZCC2hV_)9z-y)6#Q;{nTqC{D|R zaV#OYS!8zjlk|8bX!|;Iu!_;`zGS9TkLQCOGw;gB8THv=M0^}kpBBR&@roVtic?+_ z+wd{6Wq@_|w#N7pND@07?%q}hZnP(hlAOJ*&Zyhb+v<+GV|!cEeV~dsM^sR>=p>tB zO|o;XNtVPU`<^7@w1c}*?9^kl?g4FEEHa2!0Mf8GENr#Oz|aEPN12gsz_d7t8l z5yyMdJoe3Dk!m+=zKe@|XBYVri~N~&qlAQ+>3aO6Fmpax2pE=c-13g@NV3p1^OJMN z>M<=wtk#_%u~UnD2}S-h&lziu)#E3&CQE~Y?WmlT6r(;g&SGD}o|z?k&NAcn&n(%0 z){T~|1{FeR9zeq80iLVUj2r(?R1kzodcAr%he=`0hy_gRbZil|YnXmPa zU-OxnpeMa@86Lp2BC)anQVdQj7w-W8!=jk3B1H(%(F@YSm(&X~BC|h}yKkhu3^4;E zmc5L3e7bl zpsY&wk8*8n|DEi${A-}VAX)Xno^;v#4k(}Zz@C?dXj&9iwi+U>&|5Id?Vn)Z9zbGe z=UwsI_846Do!5!K&yXYo3!E>03IVH{_*qpzDP1HfVW_Ia9(m^k=@rOQi25apsw9~c zy`YI&UUF`AZ5(L%)Pea=wyIR3?o+tAw#CwRQ!NXF^XEfsNXNCYU=$d*!GHu{2R+GE z%VvCARiJo)rcsrzL&}gH9o^|qpyg88E?Hg}6%<(z08%Sq5)_Zx+)pc1O?5>&`-3%$kK{^Gv?)YHdaZ zE2+&lQ{+!v|GB_vq7V*Jo`sX=ORSqZ9r_1w(9?nj18$DcEFOrJ_&O&0GBa>Ja?cATTQP)B- zbw|Gkjpxr3d}#0Q;EgfHjs)0wywRc+l(Qb z9P0AhW!b6mJ#H2BH^HSDavmCfKk+sG(|3)x3^j66ORVSk4c2qg66-l-nRVIF!KAaoCM}GfRGC9CoTt z(Q&AZDu3%Z6p=4W7UDa`;TgaAr^lfx=x-vn7fky$h?<8<98Rwb;}Ei>76jjBELezL3~sc!YI=>GV0<(57jJ-GyTU90VT3B=5t zlx@Y@qrE?Y5{7hwcnsf{ zN`DrmTOlfzl<)>?GqY%!<)ea7#>}GpND%o71KlId+|094_z^sjX%m4$xx{xPn;@2L zQbm42p0e~Ip0bEA6|eIhCgSK#R=iZi@+vm{k~D||FTP?^qjFaq#ZBDNGo`w;i~ zXH;G{ASB@77SglfaTRvaSERkZ)^d}-2bnb`JSZ2f!s8b)KV(D}bugN6vK$Q`KkKd< z9As;g{9KwVt9#>XRU?lczuL;5`c|l+W%-X;G>j4dH?&jqsL7Tny_i3L2yc4{J1*mU zy|Q`#4!rI2zZAjmZ^PS8G6LxI!T48r+xrNs68l!X?IeY_y}J$$z_;OT|3W45ZFt*B zutR9;&`7ney4`Q4`&NC@F1xbp{nIp%Z6VZ*i+H)(RHNB;3Vrvz4WhYZq z>l85ih}5yjmr~?QDvEG9;c&)!9qiUO$uSNl=SJ+4iIPPX`}nif9-V^=M>@<@xcc^- zwOu>7K3FIHUD-y$gS@4?ldO;3!I>Ne#9epL$!;cCXJhuN^PF@FMrT1i{S^iIvv6Zd z!&8>hJ?PRj;#H;BaB_N+W*)>t2MpcS0Q(|h*8q5^{S(MmjyZk~v#Q6g5rp&!f{;Fo zPi6D>pDxEB?>OV_zo|Y8{forsB7a~*hc(k*kjl6ozd|>QDNY-EeDV3UU|mk4#t7!4r{#Z>~cuYvx9Zo>*$UNehX-$a!UD6z*$fLyK_jU{uo{To$gak;8!)N=NlpZ(k@n zh-$y>rVZWFzDd%){&?_rCzuWzHO0sy2}?DkaSq3W|A-cYdT?}(4P?VvMA^lt_z#-5 zEw?gl6^x@aVOOkMIl}nr5s7WiCd7OJfG#&C%lTp}fSqCgXu1*>1dVRIO*lQOlfSe#nne4fnq zOr&UoDjtU~JZba~YX-5sQ*$_gZQN#GA}s-$cqpB*u0YeyqeKxkp5?Qxk>=o=8fkAC z#ZOR~Vg~qIg3)vjLom`~mkHqDFL~b#^#K9?bk}`1@Ya;j=(q&a#f&%To~wQ(esi(o zeIRrjE^W0h#(xt%axTiJyQ*@teZcF-UhV%9c1{wnz+81@y|?4|Z1M{(=()bEbbcxN zj5352lwc2PKJ|YiKdq+6=4z0kt```!YqG%tXb>d&YeQlkG!oUz5Fd&w%EPDS`g>dr ze;`_LRXFr6PvwEM!qB(}Pl{Km-6uR5#M0k-@mpo#pZJ0cj$98IInHQ_IvaMn>NiFc zl0!QljdHo89gB0__ZW_#V;XQM_dSkNZ^!aL!_Kv5)1*yv;*K;ras?=)K|U26$}i+= zUhA5_lBwX7797qyzP!%#8X8l>nl;P}^Snq8oGZ4r>Cv%P59GD3x|CL*Yx(*=McFf3 ziVoE~sUe6ll3M%YKu9-78RrkB{U(#DTTQBcYEpFw6C^xCv+v9CU1HpBhS&)y%l)R3W=d1a2CZF>9SB){MBsDdo{ySf#HjX*f;Xy5^ z_(c00Muu`l3f6Kmod7NIxFWabkVs?_+)gS&Zl7l$)#llJA3(8bvwb>vM84fZ>voiR z7nK^XZ3AoL;!;-J7F>`4mie1d>HU#+TB-34SlW6Ii)ybQm8v5&UvQb-8&hW7hnNty ztYMQvyJb18Zf0jzR&HE4UlM_P>S~bHfQ8HWDe~_TuM1^VuZlHC(gu#a_LZ@EkN2W7 zqmZ0s<@RO4&o=JfYQ4D{3=*b2A;e1C>o~6z5C}P03s6?4JX&)cBUu=@M}9()xPeWw zRFa)ic^T0}JyB*nR5DnI->S&x6WQMGVee#^579FVPUtYv`?Gdn0nEO8laF0UV8Ia* z&gl(jUq9afEMIC-M)TZ;@Q?9UTcpfqp$JSwjG=3WgYYw|iCXiT4DobhJxNmoEK^X4 zfC5o~b9`yEB9hR&^(+{so$z_bMKv^6-cg6U5o(#!%djsiGd5gl>8q)6OJ}4SSCDX| zr!_uOS+hv=(tLkK-|qy=KF|ZI<&3M@+k?p_5E6T63bI5e&uN^+o&h)gzU@IN;|Zgg zCsa79iKiV-627V|o86`tKQIDq|;}~D8{{J!*{($gr z>5&-18+YTc+hE2U%WzT7bEcMIKEY{Rz`T(@WLAo`7EHJ@V2tk*NJII&;UV4_t42OI zTryr<4MNGQAH8q3jT)aQF>d~)RDsdw8>RJ+#clzgL;uQ8F5J_4L00p|REw<$qy0`9 zz$C)>oqKCwj%Hv8;TNoDEQPx2Q{}ty8Epj3wfA_M;-@e2PxLM-Hv&ZP zV1L7RS@r+a&$g-b%Z&y`F-0*aOuyK7*6wzER$b%Z+|62IbA47hDzN#R9@dmPe0#E+eK@692ep>+~C^S!JI zNSdw(2WVel4nE_2ONxA#D7b}nu+*TkdOq7QSL02* zY5k|W9<0Ejv|we^Y8=`la33UKw9rp3gDouN^YG^}!MCwEn@W*pw6M?8I~ zqoS|8V^|rl5B*7+!6SyJVrIZbj67+u@e3!7r7eN6My&}wl`L$@NcDg6vSe~ z&naZcE0qPtV3wdRHeSP9UW@C&IXs!AhfwTp%02-!t^Q36Cu98_3(?y8lt$@Son(+fyy~F}k*i}CP2M}|joLA(lF7oB5;ZlOHDu$}%rMyLIc|K0^ z$+x!2UVCV}kVWdXItj>l!HU8)!S$f*Scl3J8(x-VTuuW)>_cbClUrB%$Cs~^x;d*s zEtGn-VV7ZK!C<~d8rqeVx)q0>;7#`s1q?AQAvQd!tUQz`8+MhKh7MUpS7Uwke8%~@YpB-X7(Yy`P*tQMiWuXoCu>LJ z*JTb511^s(G%FG&pZ&?|5n6wu>wzSSW?T$KiL8S^y+VLgl=&(J@h322s`-D1gXWhK z7Wozy`QJ5;IHlz{xq5-qNiuHYRZfYjo;f>nf0FKcxHWv)dREc!72%u`!~3}qbE$8G z2-a{S4?2p;J{-g4Vt!UjOhQO9QN1Y;pp8rUM%O$N>B3m=QpQf`X|8!Ay<&Z!MSTh0 zm{1!ZytdH)@K9-}xsooYqJAd(=~iNqv|>V=h1w6&nWJj-L1%iTKg^Q=phHr{Xz z%_e3R$A$kW!_C-BDOr^$bZ8gBt=+}-ms`7wvYg&rf0_?8B}*sXX_Q&P!9);%>!iGx z6|;&;gB3Bdab_!eK`@CrJ0IyNNE=DWJ`6LV(~hC-Y@`{Hl}MW#oHy`&|9iv^Ixde% z_}(QqE;M5Umw+(=?WGmV^h+cu?W&lS6J_76w>{z=xv=lJ-W8lh8u1{zvkBO{HjWUh z-e0Jn7Pv(FB-XVNQEGtfeg~?zH_)_mrZ`TYvZ&k)*_c4 zAAx|6j}4FTha#c1!`UaDHiZ-wWB#>M2@iBr1=;_U1q!-!He=-&& z7X|vx9HqZlA{YeHrdo4ZIj_frU(vU#Ed0kMlH>=7&KS+tkz<@OlLzCHgE50n zo!^3v0tPdxu#n+ZXBr1f7?nq`Od}^w(NE}zfBki$jx901ypNT-$D_Xa)^)`1-%ncY zPV4>7u-_otvU1oTVk>BaWKEAJ7;~+hJFX?+PV&B5AK)Z7QLn@dQ@569TbZiUI|;z7 zY4Ncf$7vn$oYZOz@3PQMd=E~) z4q*UbMsd3~x~hczaEzI!FObG^)i1qSLTkM*7} zAt~9+&{y)fDb&j&THK||jI8!?wX0sPK(&vtclsa75$~$M7su7UiQ?HHXZv~ce6D%a z{@-wWJs~;vd+!R#`3S~^w%Q2|*|*NAuUAwgUSBUHM9jFJF8w^3{$`-k+p4R>iRL8N z#*viQH-2y=SaZ(FNRZmdNB@Vkjafa<7dOv0!pw*kyVSfa;&ocotJpkeo-cJC7$h`R zN32ZvY}G901<@c_2QVta{zGB^J{G5LP;of)bQ&4(_TiJWzc|erSHO$142ACDhn>S( z9*V^_4%)@$j|DGSd&Lfl9gDW-~fZfsz!p6iLj5urD3S3hT3_?YL{9xOJJjfw^ z{iD1G7NqHI!b~8%Fk;|>xi(G+RQ9_z?rqphLcTln%Kj?t_#|<2XzZum2*l}8jCXXz z76potPdZ`d=lWB8Yox~QRoYb({qal~-b${w&UMZbI3rMK4m`lRic7xQ%z!%UEh* zoR^J?5?m_bQ63g{ia^+KGA%Q90^+5^$@065->dLRgcoy&+S)lbzss9p`~mnOPhjpG zO0rL%J7;lJp9PL>j)-NaBsSNi6v{5XudDA}t;-g`4+#d@)Q^jPOB?z&j&IRpL7K!L zJQlbk$AT^n3~3~&4h=iZ9edQVU@yml&(yJCoH`by4IT?pBF6%EKcVm4zAo)u z+rq^+aze1qBV^?yVRzy-ev|wocz5(2v!v$#D z)T4e4^}8CCF>8eq_HwG>s~_CDG+)H}KbA|ECnQ=RMkJrqT4sg3dMM=22SZBIr-V!& z3VGXLNXgy`i8NLIQ`~-e(-<~0>H(9p`7iXw8y{XpPswRN>X~R1v&9R?NsuU73*xah zgZ%~e%HoYQSY95ne3>rkory1=zm6s&2Z8el{*A^jFO?)%4~Vc6CY1#tRLbbi*;@ki zn6U@)s1EmAAUC;{9NcB|FXDUU`n4&D2j?Z%(v<$ByyW|Nf;%nY#y3(_S3QdxbT;nt zw+n4dl(@?x&r2iEY?dKe z5|AiYrij_e|5iKx3VlXBEv6^0m*28+c}Hu~^4?jKk+)-Adfq#0)AM%JjDy;!i>SOE zYmVf-v#uv^$69CJJ2k+GnIGxbI&a-R-F_`E@*MT!?IO*T_l`d?FS${=;<0A4H81%g zaX#8?ZY-65#ur)YfbY$&ULs@VlT-^3@AW|CTfpLh6B(!kEwbC2VB9!^o|hre$woL( z(5*<^*^p~B99rpG1pv2+ugYhG^64s3;g!$7<71pv1UW9)7EnV%Q-dU|sWB6-PAjGe zZni!ifx>ELXSjOm1fTDTTKYr|q_A7Ipt+~Gk(p6ntd2an22c1uH3Q-N5@Tm2CGb3H zMe<|o@hyg+EtJl0dAadAfjs%3!OM386-!|R$p+2FcdJd_yC58nrk-446iDiU@e;mz zJwM^pMacB#^v;EA=c;cf?Z6Zn-}D^6v_1EJRoV<0NH$;c6NkjJ8Ee0mw+vyl4xX6G zQx-wsLbKu`Vc5x<@m8A$fd(w~UWN6;aJDyG{Sb+;if*&+D2V6QYC2)*@LjhxR$PUU zt#YLei?_@{MC0obPg4=uJap^%4vEPkr<`d4aO<#oYob_yZ6^OdYbeqFC=X2i{>b3AReS55QJBCbQ?(vTR% zRBdU-5htOLB(iJ1ltAMN^j@uG@J%7Kn%8Z9t;okH-}K}S(l+6n{!DFUhM1e6qCGUe-0w69$Zb51X1jbOyEHQ)&R7F~{%#32so4ZUm61ua|dCPWi# zA4tVD=?&qvXOz!3##^5K=4mj>Yd+#Upg6wa@ETMDG6bo$iyA26WrKVL3NkpC!p+7I z1j9M64?UvTiqIgc5*pkm_Wgmz8vpbNkggG!~zR|Ucb5NJqxgODBSDb-1Pr`;Acnp6cnXc ziqgXsBt?lbDImWLu3r46%$Eb)KH+Od>duHegThh3ZsAyRC^X)gP6r8_q^r!RK@7!H zYOLg;7j$`ow`?0^MXdG>3b!b0WMa1IET3W-O zfhdk*#Ga(kRbtGA$Rm|=k{pB*?@)3x>^;W71LMFTu$JpTYBBCJBte-I5w);Cpcq2{HIM>`vVP)e? zLyb{b)?`)8t%Lsz$tvFXjJCD1x>99DPUZSQ)=`X)lC�&r14gN%}@g_?|@iABl9X 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 literal 0 HcmV?d00001 diff --git a/src/deps/tinygltfloader-0.9.2/vcsetup.bat b/src/deps/tinygltfloader-0.9.2/vcsetup.bat new file mode 100644 index 0000000..921c1e9 --- /dev/null +++ b/src/deps/tinygltfloader-0.9.2/vcsetup.bat @@ -0,0 +1 @@ +.\\tools\\windows\\premake5.exe vs2013