diff --git a/.gitmodules b/.gitmodules
index 0e7ea5bab10422bfc1cc1eaf503e081f79aa24d5..0cddf4f46a38208e2b643ffcc50620d0e36cdb5e 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -6,3 +6,11 @@
 	path = external/fx-gltf
 	url = https://github.com/jessey-git/fx-gltf.git
 	branch = master
+[submodule "DTex"]
+	path = external/DTex
+	url = https://github.com/Didgy74/DTex.git
+	branch = master
+[submodule "Vulkan-Headers"]
+	path = external/Vulkan-Headers
+	url = https://github.com/KhronosGroup/Vulkan-Headers.git
+	branch = master
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 77be30049ecb52dcb0bf422d78f06eb7a7ba9c18..df64bf909786302634207b8eddb8a93a1f06920b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,6 @@ endif()
 
 file(GLOB_RECURSE SOURCE_FILES "${CMAKE_SOURCE_DIR}/src/*.cpp" "${CMAKE_SOURCE_DIR}/src/*.hpp" "${CMAKE_SOURCE_DIR}/src/*.inl")
 add_executable(${PROJECT_NAME} ${SOURCE_FILES})
-#target_include_directories(${PROJECT_NAME} PRIVATE include)
 
 add_subdirectory(external)
 target_link_libraries(${PROJECT_NAME} external::external)
diff --git a/CMakeSettings.json b/CMakeSettings.json
index 772c29fc1f196d0fb30a9c4c850905d2ca22d350..01191edd6e86ba6d11e98cc0654d9248c7efb34a 100644
--- a/CMakeSettings.json
+++ b/CMakeSettings.json
@@ -1 +1,28 @@
-{ configurations : [] }
\ No newline at end of file
+{
+  "configurations": [
+    {
+      "name": "x64-Release",
+      "generator": "Ninja",
+      "configurationType": "RelWithDebInfo",
+      "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
+      "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
+      "cmakeCommandArgs": "",
+      "buildCommandArgs": "-v",
+      "ctestCommandArgs": "",
+      "inheritEnvironments": [ "msvc_x64_x64" ],
+      "variables": []
+    },
+    {
+      "name": "x64-Debug",
+      "generator": "Ninja",
+      "configurationType": "Debug",
+      "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
+      "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
+      "cmakeCommandArgs": "",
+      "buildCommandArgs": "-v",
+      "ctestCommandArgs": "",
+      "inheritEnvironments": [ "msvc_x64_x64" ],
+      "variables": []
+    }
+  ]
+}
\ No newline at end of file
diff --git a/Data/Textures/test3.ktx b/Data/Textures/test3.ktx
new file mode 100644
index 0000000000000000000000000000000000000000..ac7933ea6b3c3a99b310b5bbaac13524868a9ff4
Binary files /dev/null and b/Data/Textures/test3.ktx differ
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
index a650411a574bc01a25ef7c3f7880e3bba67507b3..a987f63109bec4993cb057b9c74978a0d2a2f37e 100644
--- a/external/CMakeLists.txt
+++ b/external/CMakeLists.txt
@@ -22,27 +22,10 @@ target_include_directories(
 add_subdirectory(DMath)
 target_link_libraries(${LIB_NAME} INTERFACE DMath::DMath)
 
-# libktx
-set(LIBKTX_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/KTX-Software-master")
-target_include_directories(
-    ${LIB_NAME}
-    INTERFACE
-    $<BUILD_INTERFACE:${LIBKTX_FOLDER}/include>
-    $<INSTALL_INTERFACE:include>
-)
-target_include_directories(
-    ${LIB_NAME}
-    INTERFACE
-    $<BUILD_INTERFACE:${LIBKTX_FOLDER}/other_include>
-    $<INSTALL_INTERFACE:include>
-)
+# DTex
+add_subdirectory(DTex)
+target_link_libraries(${LIB_NAME} INTERFACE DTex::DTex)
 
-set(LIBKTX_LIB_FOLDER "${LIBKTX_FOLDER}/lib")
-set(KTX_SOURCE_FILES 
-	"${LIBKTX_LIB_FOLDER}/texture.c" 
-	"${LIBKTX_LIB_FOLDER}/filestream.c" 
-	"${LIBKTX_LIB_FOLDER}/checkheader.c"
-	"${LIBKTX_LIB_FOLDER}/hashlist.c"
-	"${LIBKTX_LIB_FOLDER}/memstream.c"
-	"${LIBKTX_LIB_FOLDER}/swap.c")
-target_sources(${LIB_NAME} INTERFACE ${KTX_SOURCE_FILES})
\ No newline at end of file
+# Vulkan-headers
+add_subdirectory(Vulkan-Headers)
+target_link_libraries(${LIB_NAME} INTERFACE Vulkan::Headers)
\ No newline at end of file
diff --git a/external/DTex b/external/DTex
new file mode 160000
index 0000000000000000000000000000000000000000..9a0b7e18d9d774e85c8a15a7204b4da7815ba082
--- /dev/null
+++ b/external/DTex
@@ -0,0 +1 @@
+Subproject commit 9a0b7e18d9d774e85c8a15a7204b4da7815ba082
diff --git a/external/KTX-Software-master/BUILDING.md b/external/KTX-Software-master/BUILDING.md
deleted file mode 100644
index dd73a3c757f968b74f7a8ecdc39deaa6cf245dc9..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/BUILDING.md
+++ /dev/null
@@ -1,409 +0,0 @@
-
-Building KTX
-============
-
-This document describes how to build the KTX library `libktx`, the
-portable KTX loader tests `ktxtests` and the KTX tools `ktxtools`.
-
-Status
-------
-
-You can build `libktx` and `ktxtests`for GNU/Linux, iOS, macOS and
-Windows. There are three versions of the tests for the
-OpenGL<sup>&reg;</sup> loader: GL3, ES1 and ES3. There are also tests
-for the Vulkan<sup>&reg;</sup> loader: VK. GL3 can be built on GNU/Linux,
-macOS and Windows. ES1 can be built on iOS and with the PowerVR emulator
-on Windows. ES3 can be built on iOS and with any of the major emulators
-on Windows. VK can be built on GNU/Linux, iOS, macOS and Windows after
-installing a Vulkan SDK.
-
-Android builds will follow.
-
-You can build `ktxtools` for GNU/Linux, macOS and Windows.
-
-Make/Solution/Project Files
----------------------------
-
-The project includes separate cmake/make/project/solution files for the
-KTX library, `libktx`, the KTX loader tests, `ktxtests`, and the KTX
-tools, `ktxtools`. The last 2 have dependencies on the first.
-
-All these make/solution/project files are generated by GYP and should
-not be hand edited. Make changes to the GYP files and regenerate the
-projects.
-
-The current project files include both OpenGL and Vulkan loaders and
-tests. The plan is to offer alternatives in future. 
-
-Building
---------
-
-### GNU/Linux
-
-```bash
-cd build/make/linux
-# Build everything
-make
-# or
-make -f [ktxtests|ktxtools|libktx].Makefile
-```
-
-**Note:** The generated makefiles cannot be used to build `vkloadtests`
-due to a problem with the shader compile code generated by GYP. Use the
-`cmake` files instead.
-
-Alternatively you can use cmake:
-
-```bash
-cd build/cmake/linux/Debug # or .../Release
-cmake .
-make
-```
-
-You can create an Eclipse project with `cmake`.
-
-```bash
-cd build/cmake/linux/Debug # or .../Release
-cmake . -G "Eclipse CDT4 - Unix Makefiles"
-```
-
-You can import this into Eclipse via "Import->Existing Project".
-
-### iOS and macOS
-
-Use the generated projects under `build/xcode/ios` to build the
-library and load tests to run on iOS. The OpenGL tests will use
-OpenGL ES 1.1 and OpenGL ES 3.0. The Vulkan tests will use MoltenVK.
-
-Use the generated projects under `build/xcode/mac` to build the
-library, load tests and tools to run on macOS. The OpenGL tests
-will use OpenGL 3.3. The Vulkan tests will use the macOS Vulkan SDK
-and MoltenVK.
-
-To find the Vulkan validation layers when running the macOS Vulkan
-load tests set the environment variable `VK_LAYER_PATH` to
-`$(VULKAN_SDK)/macOS/etc/vulkan/explicit_layers.d` when running the
-application. Environment variables are set in the Arguments section
-of Xcode's Scheme Editor. Validation is only enabled by the debug
-configuration.
-
-#### Xcode Preferences
-
-You must create the following Custom Path preferences in Xcode:
-[`DEVELOPMENT_TEAM`](#development_team) & [`VULKAN_SDK`](#vulkan_sdk).
-If building for macOS you must also set [`ASSIMP_HOME`](#assimp_home).
-
-##### DEVELOPMENT_TEAM 
-As of Xcode 8.0, Apple, in its wisdom, decided to require selection of a
-Development Team for signing. If you set the Development Team via the
-Xcode GUI, Xcode will store that selection in the `project.pbxproj` file.
-Thereafter `git status` will show the project file as `modified`.
-Instead abuse Xcode's _Custom Paths_ preference to store your
-development team identifier outside the `project.pbxproj` file by
-setting a DEVELOPMENT_TEAM custom path (replace ABCDEFGHIJ with your
-team identifier):
-
-![Image of Xcode Preferences open at the `Locations` tab with
-Custom Paths selected](https://i.stack.imgur.com/WtGcY.png)
-
-(Xcode menu → Preferences… → Locations → Custom Paths)
-
-Note: if you change anything in the project (update a build setting,
-add a new build phase, rename a target etc.) the development team will be
-automatically added to the project.pbxproj file. So, as noted above,
-changes should be made only to the GYP files.
-
-Thanks to [0xced@stackoverflow](http://stackoverflow.com/users/21698/0xced)
-for this solution.
-
-The team identifier, formally known as the Organizational Unit, an
-alphanumeric code (in the case of the author's "personal team"), can be found
-as follows:
-
-- Open Keychain Access (it's in /Applications/Utilities)
-- Select *login* in top left pane
-- Select *My Certificates* in bottom left pane
-- Right click the certificate of the team you wish to use; choose *Get Info*
-  from the context menu.
-- Click the triangle beside *Details* to expand it, if not already expanded
-- Copy the value of the *Organizational Unit* field under *Subject Name*
-
-If you have already manually selected your team in Xcode, you can find the
-Organizational Unit and revert to the original project file by running
-the following in the KTX project root:
-
-```bash
-git diff | grep DEVELOPMENT_TEAM
-git checkout build/xcode
-```
-
-##### VULKAN_SDK
-
-Set this to the location where you have installed the [Vulkan SDK for macOS](#vulkan-sdk).
-
-##### ASSIMP_HOME
-
-Set this to the location where [`libassimp`](#libassimp) is installed. If
-you use the MacPorts version, this will be `/opt/local`.
-
-### Windows
-
-Use the solutions under one of
-`build/msvs/{win32,x64}/vs20{10,10e,13,13e,15,17}` to build the library,
-load tests and tools for Win32 or x64 plaforms. There are separate
-solutions for Win32 and x64 platforms.
-
-**Note:** Builds of the Vulkan loader tests require vs2015+ because they
-use `vulkan.hpp` which needs C++11 & in particular `constexpr`, so solutions
-other than vs2015 and vs2017 do not include a `vkloadtests` project
-and their `appfwSDL` projects do not include Vulkan app support.
-
-Dependencies
-------------
-
-The KTX library, `libktx`, and the KTX loader tests, `ktxtests`, use
-the _GL Extension Wrangler_ (GLEW) library when built for
-OpenGL on Windows.
-
-The MSVS `ktxtests` solutions on Windows include OpenGL ES versions.
-To build a complete solution and run the OpenGL ES versions you need to
-install an OpenGL ES emulator.
-
-The KTX loader tests in `ktxtests` use libSDL 2.0.8+. You do not
-need SDL if you only wish to build `libktx` or `ktxtools`.
-
-Binaries of these dependencies are included in the KTX Git repo.
-
-The KTX vulkan loader tests in `ktxtests` require a [Vulkan SDK](#vulkan-sdk)
-and the Open Asset Import Library [`libassimp`](#libassimp). You must install
-the former. The KTX Git repo has binaries of the latter for iOS and Windows
-but you must install it on GNU/Linux and macOS.
-
-As noted above, the KTX project uses GYP to generate make, project and
-solution files. *You do not need GYP unless you want to re-generate
-the supplied projects or generate additional projects.*
-
-### GL Extension Wrangler
-
-Builds of GLEW are provided in the KTX Git repo.
-
-#### Building GLEW from source
-
-If you want to build GLEW from source you need the OpenGL core profile
-friendly version, i.e, 1.13.0+. You can either clone
-[the master GLEW repo](https://github.com/nigels-com/glew) and, following
-the instructions there, generate the code then build it, or you
-can download a pre-generated snapshot from https://glew.s3.amazonaws.com/index.html
-and build that following the instructions also found in
-[the master GLEW repo](https://github.com/nigels-com/glew).
-The snapshot used for the binary included in this repo came from
-https://glew.s3.amazonaws.com/index.html?prefix=nigels-com/glew/25/25.1/.
-
-### OpenGL ES Emulator for Windows
-
-The generated projects work with the
-[Imagination Technologies PowerVR](https://community.imgtec.com/developers/powervr/graphics-sdk/).
-emulator. Install that before trying to build on Windows.
-
-Projects can be modified to work with any of the major emulators;
-[Qualcomm Adreno](https://developer.qualcomm.com/software/adreno-gpu-sdk/tools),
-[Google ANGLE](https://chromium.googlesource.com/angle/angle/)<sup>*</sup>,
-[ARM Mali](http://malideveloper.arm.com/resources/tools/opengl-es-emulator/)
-or [PowerVR](https://community.imgtec.com/developers/powervr/graphics-sdk/).
-To use a different emulator change the selection at the bottom of
-`gyp_include/config.gypi` and regenerate the projects. If you want to run
-the load tests for OpenGL ES 1.1 you will need to use Imagination
-Technologies' PowerVR emulator as that alone supports OpenGL ES 1.1.
-
-<sup>*</sup>You will need to build ANGLE yourself and copy the libs
-and dlls to the appropriate directories under `other_lib/win`. Note
-that ANGLE's OpenGL ES 3 support is not yet complete.
-
-### SDL
-
-Builds of SDL are provided in the KTX Git repo. These binaries
-were built from a post 2.0.8 changeset given below. This changeset
-includes a fix for an issue with OpenGL applications on macOS Mojave.
-Standard SDL 2.0.8 works fine on all other platforms so you can download
-binaries from [libsdl.org](https://libsdl.org), if you prefer.
-
-#### macOS Notes
-
-If you wish to use the provided version of SDL in other applications
-on your system, you can install the framework. Open a shell and enter
-the following command
-
-```bash
-cp -R other_lib/mac/<configuration>/SDL2.framework /Library/Frameworks
-```
-
-replacing `<configuration>` with your choice of `Debug` or `Release`.
-If you do this, you can modify the projects to use this installed
-SDL framework instead of copying it into every application bundle.
-See`gyp_include/config.gypi` for details. You will have to regenerate
-the xcode project if you wish to do this.
-
-#### Building SDL from source
-
-As noted above, KTX uses a post SDL 2.0.8 changeset, no.
-[12343](https://hg.libsdl.org/SDL/rev/84eaa0636bac) in the canonical
-Mercurial repo at https://hg.libsdl.org/SDL or the automated GitHub
-mirror at https://github.com/spurious/SDL-mirror. Clone the repo,
-checkout changeset [12343](https://hg.libsdl.org/SDL/rev/84eaa0636bac)
-and follow the SDL build instructions.
-
-Copy the results of your build to the appropriate place under the
-`other_lib` directory.
-
-### Vulkan SDK
-
-For GNU/Linux install the Vulkan SDK using the `.tar.gz` file from
-[LunarG](https://vulkan.lunarg.com/). Set the environment variable
-`VULKAN_SDK` as instructed by LunarG.
-
-You will need to build `glslc` whose binary is not included in the
-SDK. To do this:
-
-```bash
-cd $VULKAN_SDK
-./build_tools.sh --shaderc
-```
-
-It takes a while.  10 minutes or more! Add a comment to [issue 671
-at LunarG](https://vulkan.lunarg.com/issue/view/58e4e57be46ffe7e73becd83)
-to apply pressure on them to include this binary.
-
-For Ubuntu Xenial (16.04) & Bionic (18.04) you can install the
-Vulkan SDK from the Ubuntu distribution. Follow the instructions
-give at [LunarG](https://vulkan.lunarg.com/). The `glslc` binary
-is included hence use of this distribution is highly recommended.
-
-For Windows install the Vulkan SDK for Windows from
-[LunarG](https://vulkan.lunarg.com/). Set the environment variable
-`VULKAN_SDK` as instructed by LunarG.
-
-For iOS and macOS, install the Vulkan SDK for macOS from
-[LunarG](https://vulkan.lunarg.com/). Set a `VULKAN_SDK` Custom
-Path in the Xcode preferences to point to the `vulkansdk-macos-*`
-folder you extracted from the download. This SDK contains MoltenVK
-for both iOS and macOS.
-
-### libassimp
-
-Binaries for iOS and Windows are provided in the KTX Git repo.
-
-#### GNU/Linux
-
-Install from your package manager. For example on Ubuntu
-
-```bash
-sudo apt-get install libassimp3v5
-```
-
-macOS
-
-Install via [MacPorts](https://www.macports.org/) or
-[Homebrew](https://brew.sh/). For example
-
-```bash
-sudo port install assimp
-```
-
-Set an `ASSIMP_HOME` Custom Path in the Xcode preferences to the
-parent of the `include` and `lib` folders where `libassimp` is
-installed. For MacPorts this is `/opt/local`.
-
-### GYP
-
-All the builds use cmake, make or project files generated with
-[GYP](https://gyp.gsrc.io/). A modified version, available in the
-`remaster` branch of [this
-fork](https://github.com/msc-/gyp/tree/remaster), is needed to
-generate makefiles and vs2013+ projects. To install GYP, follow the
-[instructions in the
-fork](https://github.com/msc-/gyp/tree/remaster#installing-gyp).
-These work for either version of GYP. There are no install instructions
-at GYP's home.
-
-*You do not need GYP unless you want to re-generate the supplied projects
-or generate additional projects.*
-
-*You can use the standard version of GYP if you do not need to generate
-make projects or Visual Studio 2013 or later projects.*
-
-### GNU make 3.81+
-
-You need this to run the top-level `GNUmakefile` which runs GYP to generate the
-various projects. It is possible to type the GYP commands manually, if you
-really do not want to install GNU `make`. However, if you want to have GYP
-generate makefiles to build the KTX project, you will need GNU `make` and
-a Unix-style shell to run them.
-
-On Linux, GNU make is available through the standard package managers in
-most distributions. A suitable shell is standard.
-
-On OS X, GNU make is included in the Xcode Tools available from
-[developer.apple.com](http://developer.apple.com/tools/download/).
-A suitable shell is standard.
-
-On Windows, if you do not intend to generate makefiles to build KTX, you
-can install a native Windows version of GNU make from
-[GnuWin32](http://gnuwin32.sourceforge.net/packages/make.htm) and run
-`make` in a Command Prompt (`cmd.exe`) window.
-
-To get a Unix-like shell choose one of the following:
-
-* install [Git for Windows](https://msysgit.github.io/) a.k.a `msysgit`
-* install [GitHub for Windows](https://windows.github.com/)
-* install [Cygwin](https://www.cygwin.com/) making sure to include `make` from
-the *development* section.
-
-The first two of these options include a copy of [MinGW](http://www.mingw.org/)
-(Minimalist GNU for Windows). Sadly it is not the *same* copy; installing both
-tools results in two copies of MinGW on your system. Neither copy includes
-GNU `make`. You can download a pre-compiled version from the
-MinGW project [32-bit](http://sourceforge.net/projects/mingw/files/MinGW/Extension/make/make-3.82.90-cvs/make-3.82.90-2-mingw32-cvs-20120902-bin.tar.lzma/download) or
-[64-bit](http://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/make/make-3.82.90-20111115.zip/download).
-Unpack the archive and you'll find a file called `mingw32-make.exe` (32-bit) or `make` (64-bit).
-
-If using the Git for Windows shell (*Git Bash*), copy this to either
-
-`%SystemDrive%\Program Files (x86)\Git\usr\bin\make.exe` (Windows 8.1 and 10)
-
-(omit ` (x86)` if using 64-bit) or
-
-`%USERPROFILE%\AppData\Local\Programs\Git\usr\bin\make.exe` (Windows 7)
-
-:confused: I do not know if the difference in OS caused the different install locations
-or if something else is at play.
-
-If using the GitHub for Windows shell (*Git Shell*) copy this to
-
-`%USERPROFILE%\AppData\Local\GitHub\PortableGit*\usr\bin\make.exe`
-
-### Doxygen
-
-You need this if you want to generate the _libktx_ and _ktxtools_
-documentation. You need a minimum of version 1.8.14 to generate
-the documentation correctly. You can download binaries and
-also find instructions for building it from source at [Doxygen
-downloads](http://www.stack.nl/~dimitri/doxygen/download.html). Make
-sure the directory containing the `doxygen` executable is in your `$PATH`.
-
-
-Generating Projects
--------------------
-
-To (re-)generate the projects run the following commands in a shell:
-
-```bash
-cd <your KTX clone>
-make [cmake|make|msvs|xcode]
-```
-
-All important configuration options are gathered together in the file
-`gyp_include/config.gypi`. Change these as necessary to suit your local
-set up.
-
-
-{# vim: set ai ts=4 sts=4 sw=2 expandtab textwidth=75:}
diff --git a/external/KTX-Software-master/CODE_OF_CONDUCT.md b/external/KTX-Software-master/CODE_OF_CONDUCT.md
deleted file mode 100644
index a11610bd300bc0ad8135cda4ccc581dda85e0e57..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1 +0,0 @@
-A reminder that this issue tracker is managed by the Khronos Group. Interactions here should follow the Khronos Code of Conduct (https://www.khronos.org/developers/code-of-conduct), which prohibits aggressive or derogatory language. Please keep the discussion friendly and civil.
diff --git a/external/KTX-Software-master/CONTRIBUTING.md b/external/KTX-Software-master/CONTRIBUTING.md
deleted file mode 100644
index 34ba7707708f4e1a695de6994884a6029012c55b..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/CONTRIBUTING.md
+++ /dev/null
@@ -1,12 +0,0 @@
-## How to contribute to the KTX library and tools.
-
-1. Make sure you have a GitHub account.
-2. Fork the repository on GitHub.
-3. Make changes to your clone of the repository.
-4. Update or supplement the tests as necessary.
-5. Submit a pull request against the _incoming_ branch.
-
-If you will be generating documentation with or preparing
-distribution archives, you **must** follow
-[these instructions](README.md#kwexpansion) to install a
-smudge/clean filter for expanding keywords.
diff --git a/external/KTX-Software-master/LICENSE.md b/external/KTX-Software-master/LICENSE.md
deleted file mode 100644
index 0a0090d8fd7a16fb656960d7f49a60c1c1ccac1f..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/LICENSE.md
+++ /dev/null
@@ -1,228 +0,0 @@
-License and Attribution Notices           {#license}
-=======================
-
------------------
-
-This file has two names: LICENSE.md and NOTICE.md. The former to tell GiHub users this
-is the license. The latter to tell creators of derived works that they need to distribute this
-with or make it available in a display generated by any Derivative Works, except for any
-parts that do not pertain to the Derivative Work, in accordance with clause 4d of the
-Apache 2.0 license, i.e. this is the "NOTICE" file.
-
------------------
-
-## Default License
-
-With the exception of the files listed explicitly below, the source
-is made available under the Apache License, Version 2.0 (the "License");
-you may not use these files except in compliance with the License.
-You may obtain a copy of the License at
-
-&ensp;&ensp;&ensp;&ensp;http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-libKTX is the work of Mark Callow based on work by Georg Kolling and Jacob
-Ström with contributions borrowed from Troy Hanson and Johannes van Waveren.
-The source contains code
-
-    © 2010 & © 2013 The Khronos Group Inc.
-    © 2008 and © 2010 HI Corporation
-    © 2005 Ericsson AB
-    © 2003-2010, Troy D. Hanson
-    © 2015-2018 Mark Callow
-    © 2016 Oculus VR, LLC.
-
-The KTX load tests are the work of Mark Callow with a few small portions borrowed
-from Sascha Willems' Vulkan examples and use Sam Lantinga's libSDL for portability.
-The source contains code
-
-    © 2013 The Khronos Group Inc.
-    © 2008 and © 2010 HI Corporation
-    © 1997-2018 Sam Lantinga
-    © 2016 Sascha Willems
-    © 2015-2018 Mark Callow
-
------------------
-
-**IMPORTANT:** Due to GitHub Markdown limitations license text has
-been copied into this file from the files named below. In the event
-of a discrepancy, the licenses in the files shall be deemed correct.
-
-## libktx Exceptions
-### etcdec.cxx
-
-etcdec.cxx is made available under the terms and conditions of the following
-License Agreement.
-
-Software License Agreement
-
-PLEASE REVIEW THE FOLLOWING TERMS AND CONDITIONS PRIOR TO USING THE
-ERICSSON TEXTURE COMPRESSION CODEC SOFTWARE (THE "SOFTWARE"). THE USE
-OF THE SOFTWARE IS SUBJECT TO THE TERMS AND CONDITIONS OF THE
-FOLLOWING SOFTWARE LICENSE AGREEMENT (THE "SLA"). IF YOU DO NOT ACCEPT
-SUCH TERMS AND CONDITIONS YOU MAY NOT USE THE SOFTWARE.
-
-Subject to the terms and conditions of the SLA, the licensee of the
-Software (the "Licensee") hereby, receives a non-exclusive,
-non-transferable, limited, free-of-charge, perpetual and worldwide
-license, to copy, use, distribute and modify the Software, but only
-for the purpose of developing, manufacturing, selling, using and
-distributing products including the Software in binary form, which
-products are used for compression and/or decompression according to
-the Khronos standard specifications OpenGL, OpenGL ES and
-WebGL. Notwithstanding anything of the above, Licensee may distribute
-[etcdec.cxx] in source code form provided (i) it is in unmodified
-form; and (ii) it is included in software owned by Licensee.
-
-If Licensee institutes, or threatens to institute, patent litigation
-against Ericsson or Ericsson's affiliates for using the Software for
-developing, having developed, manufacturing, having manufactured,
-selling, offer for sale, importing, using, leasing, operating,
-repairing and/or distributing products (i) within the scope of the
-Khronos framework; or (ii) using software or other intellectual
-property rights owned by Ericsson or its affiliates and provided under
-the Khronos framework, Ericsson shall have the right to terminate this
-SLA with immediate effect. Moreover, if Licensee institutes, or
-threatens to institute, patent litigation against any other licensee
-of the Software for using the Software in products within the scope of
-the Khronos framework, Ericsson shall have the right to terminate this
-SLA with immediate effect. However, should Licensee institute, or
-threaten to institute, patent litigation against any other licensee of
-the Software based on such other licensee's use of any other software
-together with the Software, then Ericsson shall have no right to
-terminate this SLA.
-
-This SLA does not transfer to Licensee any ownership to any Ericsson
-or third party intellectual property rights. All rights not expressly
-granted by Ericsson under this SLA are hereby expressly
-reserved. Furthermore, nothing in this SLA shall be construed as a
-right to use or sell products in a manner which conveys or purports to
-convey whether explicitly, by principles of implied license, or
-otherwise, any rights to any third party, under any patent of Ericsson
-or of Ericsson's affiliates covering or relating to any combination of
-the Software with any other software or product (not licensed
-hereunder) where the right applies specifically to the combination and
-not to the software or product itself.
-
-THE SOFTWARE IS PROVIDED "AS IS". ERICSSON MAKES NO REPRESENTATIONS OF
-ANY KIND, EXTENDS NO WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
-EXPRESS, IMPLIED OR STATUTORY; INCLUDING, BUT NOT LIMITED TO, EXPRESS,
-IMPLIED OR STATUTORY WARRANTIES OR CONDITIONS OF TITLE,
-MERCHANTABILITY, SATISFACTORY QUALITY, SUITABILITY, AND FITNESS FOR A
-PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
-OF THE SOFTWARE IS WITH THE LICENSEE. SHOULD THE SOFTWARE PROVE
-DEFECTIVE, THE LICENSEE ASSUMES THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION. ERICSSON MAKES NO WARRANTY THAT THE MANUFACTURE,
-SALE, OFFERING FOR SALE, DISTRIBUTION, LEASE, USE OR IMPORTATION UNDER
-THE SLA WILL BE FREE FROM INFRINGEMENT OF PATENTS, COPYRIGHTS OR OTHER
-INTELLECTUAL PROPERTY RIGHTS OF OTHERS, AND THE VALIDITY OF THE
-LICENSE AND THE SLA ARE SUBJECT TO LICENSEE'S SOLE RESPONSIBILITY TO
-MAKE SUCH DETERMINATION AND ACQUIRE SUCH LICENSES AS MAY BE NECESSARY
-WITH RESPECT TO PATENTS, COPYRIGHT AND OTHER INTELLECTUAL PROPERTY OF
-THIRD PARTIES.
-
-THE LICENSEE ACKNOWLEDGES AND ACCEPTS THAT THE SOFTWARE (I) IS NOT
-LICENSED FOR; (II) IS NOT DESIGNED FOR OR INTENDED FOR; AND (III) MAY
-NOT BE USED FOR; ANY MISSION CRITICAL APPLICATIONS SUCH AS, BUT NOT
-LIMITED TO OPERATION OF NUCLEAR OR HEALTHCARE COMPUTER SYSTEMS AND/OR
-NETWORKS, AIRCRAFT OR TRAIN CONTROL AND/OR COMMUNICATION SYSTEMS OR
-ANY OTHER COMPUTER SYSTEMS AND/OR NETWORKS OR CONTROL AND/OR
-COMMUNICATION SYSTEMS ALL IN WHICH CASE THE FAILURE OF THE SOFTWARE
-COULD LEAD TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL, MATERIAL OR
-ENVIRONMENTAL DAMAGE. LICENSEE'S RIGHTS UNDER THIS LICENSE WILL
-TERMINATE AUTOMATICALLY AND IMMEDIATELY WITHOUT NOTICE IF LICENSEE
-FAILS TO COMPLY WITH THIS PARAGRAPH.
-
-IN NO EVENT SHALL ERICSSON BE LIABLE FOR ANY DAMAGES WHATSOEVER,
-INCLUDING BUT NOT LIMITED TO PERSONAL INJURY, ANY GENERAL, SPECIAL,
-INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN
-CONNECTION WITH THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING
-BUT NOT LIMITED TO LOSS OF PROFITS, BUSINESS INTERUPTIONS, OR ANY
-OTHER COMMERCIAL DAMAGES OR LOSSES, LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY THE LICENSEE OR THIRD
-PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER
-SOFTWARE) REGARDLESS OF THE THEORY OF LIABILITY (CONTRACT, TORT, OR
-OTHERWISE), EVEN IF THE LICENSEE OR ANY OTHER PARTY HAS BEEN ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGES.
-
-Licensee acknowledges that "ERICSSON ///" is the corporate trademark
-of Telefonaktiebolaget LM Ericsson and that both "Ericsson" and the
-figure "///" are important features of the trade names of
-Telefonaktiebolaget LM Ericsson. Nothing contained in these terms and
-conditions shall be deemed to grant Licensee any right, title or
-interest in the word "Ericsson" or the figure "///". No delay or
-omission by Ericsson to exercise any right or power shall impair any
-such right or power to be construed to be a waiver thereof. Consent by
-Ericsson to, or waiver of, a breach by the Licensee shall not
-constitute consent to, waiver of, or excuse for any other different or
-subsequent breach.
-
-This SLA shall be governed by the substantive law of Sweden. Any
-dispute, controversy or claim arising out of or in connection with
-this SLA, or the breach, termination or invalidity thereof, shall be
-submitted to the exclusive jurisdiction of the Swedish Courts.
-
-### uthash.h
-
-uthash.h is made available under the following revised BSD license.
-
-Copyright &copy; 2003-2010, Troy D. Hanson   http://uthash.sourceforge.net
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-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.
-
-## Load Tests Exceptions
-
-### icons/{ios/CommonIcons*,mac,win}/ktx_{app,document}.*
-
-These KTX application and document icons are &copy; & &trade; The Khronos Group, Inc.
-and may not be used without specific prior written permission from The Khronos Group,
-except that the ktx_app icon may be distributed in a Derived Work as the icon for
-the `glloadtests` and `vkloadtests` applications.
-
-### other_include/SDL2/*
-
-These files are part of the SDL2 source distributed by the [SDL project]
-(http://libsdl.org) under the terms of the [zlib license]
-(http://www.zlib.net/zlib_license.html).
-
-### other_include/glm
-
-OpenGL Mathematics is licensed under the [Happy Bunny (Modified MIT) License](https://github.com/g-truc/glm/blob/master/manual.md#section0)
-
-### testimages/hi_mark{,_sq}.ktx
-
-The HI logo textures are &copy; & &trade; HI Corporation and are
-provided for use only in testing the KTX loader. Any other use requires
-specific prior written permission from HI. Furthermore the name HI may
-not be used to endorse or promote products derived from this software
-without specific prior written permission.
-
-### {VulkanMeshLoader,vulkantextoverlay}.hpp, vulkandebug.*
-
-Copyright &copy; 2016 Sascha Willems - www.saschawillems.de
-
-{VulkanMeshLoader,vulkantextoverlay}.hpp and vulkandebug.* are licensed
-under the [MIT license](http://opensource.org/licenses/MIT)
-
diff --git a/external/KTX-Software-master/NOTICE.md b/external/KTX-Software-master/NOTICE.md
deleted file mode 100644
index f0c4298632f957385e61afc91647f6faeb78e804..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/NOTICE.md
+++ /dev/null
@@ -1 +0,0 @@
-LICENSE.md
\ No newline at end of file
diff --git a/external/KTX-Software-master/README.md b/external/KTX-Software-master/README.md
deleted file mode 100644
index 50953d90cf42246b14bf823188a3fc52fbbea292..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/README.md
+++ /dev/null
@@ -1,72 +0,0 @@
-<img src="https://www.khronos.org/assets/images/api_logos/khronos.svg" width="300"/>
-
-The Official Khronos KTX Software Repository
----
-
-|                      |  master  |  incoming  |
-|----------------------| :------: | :--------: |
-| GNU/Linux, iOS & OSX | [![Build Status](https://travis-ci.org/KhronosGroup/KTX-Software.svg?branch=master)](https://travis-ci.org/KhronosGroup/KTX-Software) | [![Build Status](https://travis-ci.org/KhronosGroup/KTX-Software.svg?branch=incoming)](https://travis-ci.org/KhronosGroup/KTX-Software) |
-| Windows | [![Build status](https://ci.appveyor.com/api/projects/status/rj9bg8g2jphg3rc0/branch/master?svg=true)](https://ci.appveyor.com/project/msc-/ktx/branch/master) | [![Build status](https://ci.appveyor.com/api/projects/status/rj9bg8g2jphg3rc0/branch/incoming?svg=true)](https://ci.appveyor.com/project/msc-/ktx/branch/incoming) |
-| Documentation | [![Build status](https://codedocs.xyz/KhronosGroup/KTX-Software.svg)](https://codedocs.xyz/KhronosGroup/KTX-Software/) | - |
-
-This is the official home of the source code
-for the Khronos KTX library and tools. KTX is a lightweight file format
-for OpenGL textures, designed around how textures are loaded in OpenGL.
-
-See the Doxygen generated live documentation for
-[`master`](https://github.khronos.org/KTX-Software/)
-for API usage information.
-
-See [CONTRIBUTING](CONTRIBUTING.md) for information about contributing.
-
-See [LICENSE](LICENSE.md) for information about licensing.
-
-See [BUILDING](BUILDING.md) for information about building the code.
-
-More information about KTX and links to tools that support it can be
-found on the
-[KTX page](http://www.khronos.org/opengles/sdk/tools/KTX/) of
-the [OpenGL ES SDK](http://www.khronos.org/opengles/sdk) on
-[khronos.org](http://www.khronos.org).
-
-If you need help with using the KTX library or KTX tools, please use the
-[KTX forum](https://forums.khronos.org/forumdisplay.php/103-KTX-file-format-for-OpenGL-OpenGL-ES-and-WebGL-textures).
-To report problems use GitHub [issues](https://github.com/KhronosGroup/KTX/issues).
-
-**IMPORTANT:** you **must** install the [Git LFS](https://github.com/github/git-lfs)
-command line extension in order to fully checkout this repository after cloning. You
-need at least version 1.1.
-
-A few files have `$Date$` keywords. If you care about having the proper
-dates shown or will be generating the documentation or preparing
-distribution archives, you **must** follow the instructions below.
-
-#### <a id="kwexpansion"></a>$Date$ keyword expansion
-
-$Date$ keywords are expanded via a smudge & clean filter. To install
-the filter, issue the following commands in the root of your clone.
-
-On Unix (Linux, Mac OS X, etc.) platforms and Windows using Git for Windows'
-Git Bash or Cygwin's bash terminal:
-
-```bash
-./install-gitconfig.sh
-rm TODO.md include/ktx.h tools/toktx/toktx.cpp
-git checkout TODO.md include/ktx.h tools/toktx/toktx.cpp
-```
-
-On Windows with the Command Prompt (requires `git.exe` in a directory
-on your %PATH%):
-
-```cmd
-install-gitconfig.bat
-del TODO.md include/ktx.h tools/toktx/toktx.cpp
-git checkout TODO.md include/ktx.h tools/toktx/toktx.cpp 
-```
-
-The first command adds an [include] of the repo's `.gitconfig` to the
-local git config file `.git/config`, i.e. the one in your clone of the repo.
-`.gitconfig` contains the config of the "keyworder" filter. The remaining
-commands force a new checkout of the affected files to smudge them with the
-date. These two are unnecessary if you plan to edit these files.
-
diff --git a/external/KTX-Software-master/include/ktx.h b/external/KTX-Software-master/include/ktx.h
deleted file mode 100644
index e6c3f2a74ea9e290304716810a7b1ade761e72db..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/include/ktx.h
+++ /dev/null
@@ -1,845 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-#ifndef KTX_H_A55A6F00956F42F3A137C11929827FE1
-#define KTX_H_A55A6F00956F42F3A137C11929827FE1
-
-/*
- * ©2010-2018 The Khronos Group, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * See the accompanying LICENSE.md for licensing details for all files in
- * the KTX library and KTX loader tests.
- */
-
-/**
- * @file
- * @~English
- *
- * @brief Declares the public functions and structures of the
- *        KTX API.
- *
- * @author Mark Callow, Edgewise Consulting and while at HI Corporation
- * @author Based on original work by Georg Kolling, Imagination Technology
- *
- * @version 3.0
- *
- * @todo Find a way so that applications do not have to define KTX_OPENGL{,_ES*}
- *       when using the library.
- */
-
-#include <stdio.h>
-#include <stdbool.h>
-
-/* To avoid including <KHR/khrplatform.h> define our own types. */
-typedef unsigned char ktx_uint8_t;
-typedef bool ktx_bool_t;
-#ifdef _MSC_VER
-typedef unsigned short ktx_uint16_t;
-typedef   signed short ktx_int16_t;
-typedef unsigned int   ktx_uint32_t;
-typedef   signed int   ktx_int32_t;
-typedef       size_t   ktx_size_t;
-#else
-#include <stdint.h>
-typedef uint16_t ktx_uint16_t;
-typedef  int16_t ktx_int16_t;
-typedef uint32_t ktx_uint32_t;
-typedef  int32_t ktx_int32_t;
-typedef   size_t ktx_size_t;
-#endif
-
-/* This will cause compilation to fail if size of uint32 != 4. */
-typedef unsigned char ktx_uint32_t_SIZE_ASSERT[sizeof(ktx_uint32_t) == 4];
-
-/*
- * This #if allows libktx to be compiled with strict c99. It avoids
- * compiler warnings or even errors when a gl.h is already included.
- * "Redefinition of (type) is a c11 feature". Obviously this doesn't help if
- * gl.h comes after. However nobody has complained about the unguarded typedefs
- * since they were introduced so this is unlikely to be a problem in practice.
- * Presumably everybody is using platform default compilers not c99 or else
- * they are using C++.
- */
-#if !defined(GL_NO_ERROR)
-  /*
-   * To avoid having to including gl.h ...
-   */
-  typedef unsigned char GLboolean;
-  typedef unsigned int GLenum;
-  typedef int GLint;
-  typedef int GLsizei;
-  typedef unsigned int GLuint;
-  typedef unsigned char GLubyte;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @~English
- * @brief Key String for standard orientation value.
- */
-#define KTX_ORIENTATION_KEY "KTXorientation"
-/**
- * @~English
- * @brief Standard format for 2D orientation value.
- */
-#define KTX_ORIENTATION2_FMT "S=%c,T=%c"
-/**
- * @~English
- * @brief Standard format for 3D orientation value.
- */
-#define KTX_ORIENTATION3_FMT "S=%c,T=%c,R=%c"
-/**
- * @~English
- * @brief Required unpack alignment
- */
-#define KTX_GL_UNPACK_ALIGNMENT 4
-    
-#define KTX_TRUE  true
-#define KTX_FALSE false
-
-/**
- * @~English
- * @brief Error codes returned by library functions.
- */
-typedef enum KTX_error_code_t {
-    KTX_SUCCESS = 0,         /*!< Operation was successful. */
-    KTX_FILE_DATA_ERROR,     /*!< The data in the file is inconsistent with the spec. */
-    KTX_FILE_OPEN_FAILED,    /*!< The target file could not be opened. */
-    KTX_FILE_OVERFLOW,       /*!< The operation would exceed the max file size. */
-    KTX_FILE_READ_ERROR,     /*!< An error occurred while reading from the file. */
-    KTX_FILE_SEEK_ERROR,     /*!< An error occurred while seeking in the file. */
-    KTX_FILE_UNEXPECTED_EOF, /*!< File does not have enough data to satisfy request. */
-    KTX_FILE_WRITE_ERROR,    /*!< An error occurred while writing to the file. */
-    KTX_GL_ERROR,            /*!< GL operations resulted in an error. */
-    KTX_INVALID_OPERATION,   /*!< The operation is not allowed in the current state. */
-    KTX_INVALID_VALUE,       /*!< A parameter value was not valid */
-    KTX_NOT_FOUND,           /*!< Requested key was not found */
-    KTX_OUT_OF_MEMORY,       /*!< Not enough memory to complete the operation. */
-    KTX_UNKNOWN_FILE_FORMAT, /*!< The file not a KTX file */
-    KTX_UNSUPPORTED_TEXTURE_TYPE, /*!< The KTX file specifies an unsupported texture type. */
-} KTX_error_code;
-
-#define KTX_IDENTIFIER_REF  { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }
-#define KTX_ENDIAN_REF      (0x04030201)
-#define KTX_ENDIAN_REF_REV  (0x01020304)
-#define KTX_HEADER_SIZE     (64)
-
-/**
- * @~English
- * @brief Result codes returned by library functions.
- */
- typedef enum KTX_error_code_t ktxResult;
-
-/**
- * @class ktxHashList
- * @~English
- * @brief Opaque handle to a ktxHashList.
- */
-typedef struct ktxKVListEntry* ktxHashList;
-
-/**
- * @class ktxTexture
- * @~English
- * @brief Class representing a texture.
- *
- * ktxTextures should be created only by one of the ktxTexture_Create*
- * functions and these fields should be considered read-only.
- */
-typedef struct {
-    ktx_uint32_t glFormat; /*!< Format of the texture data, e.g., GL_RGB. */
-    ktx_uint32_t glInternalformat; /*!< Internal format of the texture data,
-                                        e.g., GL_RGB8. */
-    ktx_uint32_t glBaseInternalformat; /*!< Base format of the texture data,
-                                            e.g., GL_RGB. */
-    ktx_uint32_t glType; /*!< Type of the texture data, e.g, GL_UNSIGNED_BYTE.*/
-      ktx_bool_t isArray; /*!< KTX_TRUE if the texture is an array texture, i.e,
-                               a GL_TEXTURE_*_ARRAY target is to be used. */
-      ktx_bool_t isCubemap; /*!< KTX_TRUE if the texture is a cubemap or
-                                 cubemap array. */
-      ktx_bool_t isCompressed; /*!< KTX_TRUE if @c glInternalFormat is that of
-                                    a compressed texture. */
-      ktx_bool_t generateMipmaps; /*!< KTX_TRUE if mipmaps should be generated
-                                       for the texture by ktxTexture_GLUpload()
-                                       or ktx_Texture_VkUpload(). */
-    ktx_uint32_t baseWidth;  /*!< Width of the base level of the texture. */
-    ktx_uint32_t baseHeight; /*!< Height of the base level of the texture. */
-    ktx_uint32_t baseDepth;  /*!< Depth of the base level of the texture. */
-    ktx_uint32_t numDimensions; /*!< Number of dimensions in the texture: 1, 2
-                                     or 3. */
-    ktx_uint32_t numLevels; /*!< Number of mip levels in the texture. Should be
-                                 1, if @c generateMipmaps is KTX_TRUE. Can be
-                                 less than a full pyramid but always starts at
-                                 the base level. */
-    ktx_uint32_t numLayers; /*!< Number of array layers in the texture. */
-    ktx_uint32_t numFaces; /*!< Number of faces, 6 for cube maps, 1 otherwise.*/
-     ktxHashList kvDataHead; /*!< Head of the hash list of metadata. */
-    ktx_uint32_t kvDataLen; /*!< Length of the metadata, if it has been
-                                 extracted in its raw form, otherwise 0. */
-    ktx_uint8_t* kvData; /*!< Pointer to the metadata, if it has been extracted
-                              in its raw form, otherwise NULL. */
-      ktx_size_t dataSize; /*!< Length of the image data in bytes. */
-    ktx_uint8_t* pData; /*!< Pointer to the image data. */
-} ktxTexture;
-
-    
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Structure for passing texture information to ktxTexture_Create().
- *
- * @sa ktxTexture_Create()
- */
-typedef struct
-{
-    ktx_uint32_t glInternalformat; /*!< Internal format for the texture, e.g.,
-                                        GL_RGB8. */
-    ktx_uint32_t baseWidth;  /*!< Width of the base level of the texture. */
-    ktx_uint32_t baseHeight; /*!< Height of the base level of the texture. */
-    ktx_uint32_t baseDepth;  /*!< Depth of the base level of the texture. */
-    ktx_uint32_t numDimensions; /*!< Number of dimensions in the texture, 1, 2
-                                     or 3. */
-    ktx_uint32_t numLevels; /*!< Number of mip levels in the texture. Should be
-                                 1 if @c generateMipmaps is KTX_TRUE; */
-    ktx_uint32_t numLayers; /*!< Number of array layers in the texture. */
-    ktx_uint32_t numFaces;  /*!< Number of faces: 6 for cube maps, 1 otherwise. */
-    ktx_bool_t   isArray;  /*!< Set to KTX_TRUE if the texture is to be an
-                                array texture. Means OpenGL will use a
-                                GL_TEXTURE_*_ARRAY target. */
-    ktx_bool_t   generateMipmaps; /*!< Set to KTX_TRUE if mipmaps should be
-                                       generated for the texture when loading
-                                       into OpenGL. */
-} ktxTextureCreateInfo;
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Enum for requesting, or not, allocation of storage for images.
- *
- * @sa ktxTexture_Create()
- */
-typedef enum {
-    KTX_TEXTURE_CREATE_NO_STORAGE = 0,  /*!< Don't allocate any image storage. */
-    KTX_TEXTURE_CREATE_ALLOC_STORAGE = 1 /*!< Allocate image storage. */
-} ktxTextureCreateStorageEnum;
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Flags for requesting services during creation.
- *
- * @sa ktxTexture_CreateFrom*
- */
-enum ktxTextureCreateFlagBits {
-    KTX_TEXTURE_CREATE_NO_FLAGS = 0x00,
-    KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT = 0x01,
-                                   /*!< Load the images from the KTX source. */
-    KTX_TEXTURE_CREATE_RAW_KVDATA_BIT = 0x02,
-                                   /*!< Load the raw key-value data instead of
-                                        creating a @c ktxHashList from it. */
-    KTX_TEXTURE_CREATE_SKIP_KVDATA_BIT = 0x04
-                                   /*!< Skip any key-value data. This overrides
-                                        the RAW_KVDATA_BIT. */
-};
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Type for TextureCreateFlags parameters.
- *
- * @sa ktxTexture_CreateFrom*()
- */
-typedef ktx_uint32_t ktxTextureCreateFlags;
-
-#define KTXAPIENTRY
-#define KTXAPIENTRYP KTXAPIENTRY *
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Signature of function called by the <tt>ktxTexture_Iterate*</tt>
- *        functions to receive image data.
- *
- * The function parameters are used to pass values which change for each image.
- * Obtain values which are uniform across all images from the @c ktxTexture
- * object.
- *
- * @param [in] miplevel        MIP level from 0 to the max level which is
- *                             dependent on the texture size.
- * @param [in] face            usually 0; for cube maps, one of the 6 cube
- *                             faces in the order +X, -X, +Y, -Y, +Z, -Z,
- *                             0 to 5.
- * @param [in] width           width of the image.
- * @param [in] height          height of the image or, for 1D textures
- *                             textures, 1.
- * @param [in] depth           depth of the image or, for 1D & 2D
- *                             textures, 1.
- * @param [in] faceLodSize     number of bytes of data pointed at by
- *                             @p pixels.
- * @param [in] pixels          pointer to the image data.
- * @param [in,out] userdata    pointer for the application to pass data to and
- *                             from the callback function.
- */
-/* Don't use KTXAPIENTRYP to avoid a Doxygen bug. */
-typedef KTX_error_code (KTXAPIENTRY* PFNKTXITERCB)(int miplevel, int face,
-                                               int width, int height, int depth,
-                                               ktx_uint32_t faceLodSize,
-                                               void* pixels,
-                                               void* userdata);
-
-/*
- * See the implementation files for the full documentation of the following
- * functions.
- */
-
-/*
- * Creates an empty ktxTexture object with the characteristics described
- * by createInfo.
- */
-KTX_error_code
-ktxTexture_Create(ktxTextureCreateInfo* createInfo,
-                  ktxTextureCreateStorageEnum storageAllocation,
-                  ktxTexture** newTex);
-
-/*
- * Creates a ktxTexture from a stdio stream reading from a KTX source.
- */
-KTX_error_code
-ktxTexture_CreateFromStdioStream(FILE* stdioStream,
-                                 ktxTextureCreateFlags createFlags,
-                                 ktxTexture** newTex);
-
-/*
- * Creates a ktxTexture from a named file containing KTX data.
- */
-KTX_error_code
-ktxTexture_CreateFromNamedFile(const char* const filename,
-                               ktxTextureCreateFlags createFlags,
-                               ktxTexture** newTex);
-
-/*
- * Creates a ktxTexture from a block of memory containing KTX-formatted data.
- */
-KTX_error_code
-ktxTexture_CreateFromMemory(const ktx_uint8_t* bytes, ktx_size_t size,
-                            ktxTextureCreateFlags createFlags,
-                            ktxTexture** newTex);
-/*
- * Destroys a ktxTexture object.
- */
-void
-ktxTexture_Destroy(ktxTexture* This);
-
-/*
- * Returns a pointer to the image data of a ktxTexture object.
- */
-ktx_uint8_t*
-ktxTexture_GetData(ktxTexture* This);
-
-/*
- * Returns the offset of the image for the specified mip level, array layer
- * and face or depth slice within the image data of a ktxTexture object.
- */
-KTX_error_code
-ktxTexture_GetImageOffset(ktxTexture* This, ktx_uint32_t level,
-                          ktx_uint32_t layer, ktx_uint32_t faceSlice,
-                          ktx_size_t* pOffset);
-
-/*
- * Returns the pitch of a row of an image at the specified level.
- * Similar to the rowPitch in a VkSubResourceLayout.
- */
- ktx_uint32_t
- ktxTexture_GetRowPitch(ktxTexture* This, ktx_uint32_t level);
-
- /*
-  * Return the element size of the texture's images.
-  */
- ktx_uint32_t
- ktxTexture_GetElementSize(ktxTexture* This);
-
-/*
- * Returns the size of all the image data of a ktxTexture object in bytes.
- */
-ktx_size_t
-ktxTexture_GetSize(ktxTexture* This);
-    
-/*
- * Returns the size of an image at the specified level.
- */
- ktx_size_t
- ktxTexture_GetImageSize(ktxTexture* This, ktx_uint32_t level);
-
-/*
- * Uploads the image data from a ktxTexture object to an OpenGL {,ES} texture
- * object.
- */
-KTX_error_code
-ktxTexture_GLUpload(ktxTexture* This, GLuint* pTexture, GLenum* pTarget,
-                    GLenum* pGlerror);
-
-/*
- * Loads the image data into a ktxTexture object from the KTX-formatted source.
- * Used when the image data was not loaded during ktxTexture_CreateFrom*.
- */
-KTX_error_code
-ktxTexture_LoadImageData(ktxTexture* This,
-                         ktx_uint8_t* pBuffer,
-                         ktx_size_t bufSize);
-
-/*
- * Iterates over the already loaded level-faces in a ktxTexture object.
- * iterCb is called for each level-face.
- */
-KTX_error_code
-ktxTexture_IterateLevelFaces(ktxTexture* super, PFNKTXITERCB iterCb,
-                             void* userdata);
-
-/*
- * Iterates over the level-faces of a ktxTexture object, loading each from
- * the KTX-formatted source then calling iterCb.
- */
-KTX_error_code
-ktxTexture_IterateLoadLevelFaces(ktxTexture* super, PFNKTXITERCB iterCb,
-                                 void* userdata);
-/*
- * Iterates over the already loaded levels in a ktxTexture object.
- * iterCb is called for each level. The data passed to iterCb
- * includes all faces for each level.
- */
-KTX_error_code
-ktxTexture_IterateLevels(ktxTexture* This, PFNKTXITERCB iterCb,
-                         void* userdata);
-
-/*
- * Sets the image for the specified level, layer & faceSlice within a
- * ktxTexture object from packed image data in memory. The destination image
- * data is padded to the KTX specified row alignment of 4, if necessary.
- */
-KTX_error_code
-ktxTexture_SetImageFromMemory(ktxTexture* This,ktx_uint32_t level,
-                              ktx_uint32_t layer, ktx_uint32_t faceSlice,
-                              const ktx_uint8_t* src, ktx_size_t srcSize);
-
-/*
- * Sets the image for the specified level, layer & faceSlice within a
- * ktxTexture object from a stdio stream reading from a KTX source. The
- * destination image data is padded to the KTX specified row alignment of 4,
- * if necessary.
- */
-KTX_error_code
-ktxTexture_SetImageFromStdioStream(ktxTexture* This, ktx_uint32_t level,
-                                   ktx_uint32_t layer, ktx_uint32_t faceSlice,
-                                   FILE* src, ktx_size_t srcSize);
-
-/*
- * Write a ktxTexture object to a stdio stream in KTX format.
- */
-KTX_error_code
-ktxTexture_WriteToStdioStream(ktxTexture* This, FILE* dstsstr);
-
-/*
- * Write a ktxTexture object to a named file in KTX format.
- */
-KTX_error_code
-ktxTexture_WriteToNamedFile(ktxTexture* This, const char* const dstname);
-
-/*
- * Write a ktxTexture object to a block of memory in KTX format.
- */
-KTX_error_code
-ktxTexture_WriteToMemory(ktxTexture* This,
-                         ktx_uint8_t** bytes, ktx_size_t* size);
-
-/*
- * Returns a string corresponding to a KTX error code.
- */
-const char* const ktxErrorString(KTX_error_code error);
-
-KTX_error_code ktxHashList_Create(ktxHashList** ppHl);
-void ktxHashList_Construct(ktxHashList* pHl);
-void ktxHashList_Destroy(ktxHashList* head);
-void ktxHashList_Destruct(ktxHashList* head);
-/*
- * Adds a key-value pair to a hash list.
- */
-KTX_error_code
-ktxHashList_AddKVPair(ktxHashList* pHead, const char* key,
-                      unsigned int valueLen, const void* value);
-
-/*
- * Looks up a key and returns the value.
- */
-KTX_error_code
-ktxHashList_FindValue(ktxHashList* pHead, const char* key,
-                      unsigned int* pValueLen, void** pValue);
-
-/*
- * Serializes the hash table to a block of memory suitable for
- * writing to a KTX file.
- */
-KTX_error_code
-ktxHashList_Serialize(ktxHashList* pHead,
-                      unsigned int* kvdLen, unsigned char** kvd);
-
-
-/*
- * Creates a hash table from the serialized data read from a
- * a KTX file.
- */
-KTX_error_code
-ktxHashList_Deserialize(ktxHashList* pHead, unsigned int kvdLen, void* kvd);
-    
-
-/*===========================================================*
- * For Versions 1 and 2 compatibility                        *
- *===========================================================*/
-
-/**
- * @~English
- * @deprecated Use struct ktxTexture
- * @brief Structure used by load functions to return texture dimensions
- */
-typedef struct KTX_dimensions {
-    GLsizei width;  /*!< Width in texels. */
-    GLsizei height; /*!< Height in texels. */
-    GLsizei depth;  /*!< Depth in texels. */
-} KTX_dimensions;
-
-/**
- * @~English
- * @brief Structure to pass texture information to ktxWriteKTX.
- * @deprecated Use ktxTexture_Create() and @c ktxTextureCreateInfo
- *
- * Retained for backward compatibility with Versions 1 & 2.
- */
-typedef struct KTX_texture_info
-{
-    ktx_uint32_t glType;
-    ktx_uint32_t glTypeSize;
-    ktx_uint32_t glFormat;
-    ktx_uint32_t glInternalFormat;
-    ktx_uint32_t glBaseInternalFormat;
-    ktx_uint32_t pixelWidth;
-     ktx_uint32_t pixelHeight;
-    ktx_uint32_t pixelDepth;
-    ktx_uint32_t numberOfArrayElements;
-    ktx_uint32_t numberOfFaces;
-    ktx_uint32_t numberOfMipmapLevels;
-} KTX_texture_info;
-
-/**
- * @var KTX_texture_info::glType
- * @~English
- * @brief The type of the image data.
- *
- * Values are the same as in the @p type parameter of
- * glTexImage*D. Must be 0 for compressed images.
- */
-/**
- * @var KTX_texture_info::glTypeSize;
- * @~English
- * @brief The data type size to be used in case of endianness
- *        conversion.
- *
- * This value is used in the event conversion is required when the
- * KTX file is loaded. It should be the size in bytes corresponding
- * to glType. Must be 1 for compressed images.
- */
-/**
- * @var KTX_texture_info::glFormat;
- * @~English
- * @brief The format of the image(s).
- *
- * Values are the same as in the format parameter
- * of glTexImage*D. Must be 0 for compressed images.
- */
-/**
- * @var KTX_texture_info::glInternalFormat;
- * @~English
- * @brief The internalformat of the image(s).
- *
- * Values are the same as for the internalformat parameter of
- * glTexImage*2D. Note: it will not be used when a KTX file
- * containing an uncompressed texture is loaded into OpenGL ES.
- */
-/**
- * @var KTX_texture_info::glBaseInternalFormat;
- * @~English
- * @brief The base internalformat of the image(s)
- *
- * For non-compressed textures, should be the same as glFormat.
- * For compressed textures specifies the base internal, e.g.
- * GL_RGB, GL_RGBA.
- */
-/**
- * @var KTX_texture_info::pixelWidth;
- * @~English
- * @brief Width of the image for texture level 0, in pixels.
- */
-/**
- * @var KTX_texture_info::pixelHeight;
- * @~English
- * @brief Height of the texture image for level 0, in pixels.
- *
- * Must be 0 for 1D textures.
- */
-/**
- * @var KTX_texture_info::pixelDepth;
- * @~English
- * @brief Depth of the texture image for level 0, in pixels.
- *
- * Must be 0 for 1D, 2D and cube textures.
- */
-/**
- * @var KTX_texture_info::numberOfArrayElements;
- * @~English
- * @brief The number of array elements.
- *
- * Must be 0 if not an array texture.
- */
-/**
- * @var KTX_texture_info::numberOfFaces;
- * @~English
- * @brief The number of cubemap faces.
- *
- * Must be 6 for cubemaps and cubemap arrays, 1 otherwise. Cubemap
- * faces must be provided in the order: +X, -X, +Y, -Y, +Z, -Z.
- */
-/**
- * @var KTX_texture_info::numberOfMipmapLevels;
- * @~English
- * @brief The number of mipmap levels.
- *
- * 1 for non-mipmapped texture. 0 indicates that a full mipmap pyramid should
- * be generated from level 0 at load time (this is usually not allowed for
- * compressed formats). Mipmaps must be provided in order from largest size to
- * smallest size. The first mipmap level is always level 0.
- */
-
-/**
- * @~English
- * @deprecated Use ktxTexture_Create() and @c ktxTexture_SetImageFromMemory()
- *             or ktxTexture_SetImageFromStdioStream().
- * @brief Structure used to pass image data to ktxWriteKTX.
- *
- * @sa ktxTextureCreate()
- * @sa ktxTexture_SetImageFromMemory()
- * @sa ktxTexture_SetImageFromStdioStream()
- *
- * Retained for backward compatibility with Versions 1 & 2.
- */
-typedef struct KTX_image_info {
-    GLsizei size;    /*!< Size of the image data in bytes. */
-    GLubyte* data;  /*!< Pointer to the image data. */
-} KTX_image_info;
-
-/*
- * Loads a texture from a stdio FILE.
- */
-KTX_error_code
-ktxLoadTextureF(FILE*, GLuint* pTexture, GLenum* pTarget,
-                KTX_dimensions* pDimensions, GLboolean* pIsMipmapped,
-                GLenum* pGlerror,
-                unsigned int* pKvdLen, unsigned char** ppKvd);
-
-/*
- * Loads a texture from a KTX file on disk.
- */
-KTX_error_code
-ktxLoadTextureN(const char* const filename, GLuint* pTexture, GLenum* pTarget,
-                KTX_dimensions* pDimensions, GLboolean* pIsMipmapped,
-                GLenum* pGlerror,
-                unsigned int* pKvdLen, unsigned char** ppKvd);
-
-/*
- * Loads a texture from a KTX file in memory.
- */
-KTX_error_code
-ktxLoadTextureM(const void* bytes, GLsizei size, GLuint* pTexture,
-                GLenum* pTarget, KTX_dimensions* pDimensions,
-                GLboolean* pIsMipmapped, GLenum* pGlerror,
-                unsigned int* pKvdLen, unsigned char** ppKvd);
-
-/**
- * @class KTX_hash_table
- * @~English
- * @deprecated Use @c ktxHashList.
- * @brief Opaque handle to a hash table.
- */
-typedef ktxHashList* KTX_hash_table;
-
-/*
- * @deprecated Use ktxHashList_Create().
- */
-KTX_hash_table ktxHashTable_Create(void);
-
-/**
- * @~English
- * @deprecated Use ktxHashList_Destroy().
- * @brief Destroy a KTX_hash_table.
- *
- * Should be documented as a member of KTX_hash_table but a doxygen limitation
- * prevents that.
- */
-#define ktxHashTable_Destroy(a) ktxHashList_Destroy(a);
-/**
- * @~English
- * @deprecated Use ktxHashList_AddKVPair().
- * @brief Add a key-value pair to a KTX_hash_table.
- *
- * Should be documented as a member of KTX_hash_table but a doxygen limitation
- * prevents that.
- */
-#define ktxHashTable_AddKVPair(a, b, c, d) ktxHashList_AddKVPair(a, b, c, d)
-/**
- * @~English
- * @deprecated Use ktxHashList_FindValue().
- * @brief Looks up a key and returns its value.
- *
- * Should be documented as a member of KTX_hash_table but a doxygen limitation
- * prevents that.
- */
-#define ktxHashTable_FindValue(a, b, c, d) ktxHashList_FindValue(a, b, c, d)
-
-/*
- * @deprecated Use ktxHashList_Serialize().
- */
-KTX_error_code
-ktxHashTable_Serialize(KTX_hash_table This,
-                       unsigned int* kvdLen, unsigned char** kvd);
-
-/*
- * @deprecated Use ktxHashList_Deserialize().
- */
-KTX_error_code
-ktxHashTable_Deserialize(unsigned int kvdLen, void* pKvd, KTX_hash_table* pHt);
-
-/*
- * Writes a KTX file using supplied data.
- */
-KTX_error_code
-ktxWriteKTXF(FILE* dst, const KTX_texture_info* imageInfo,
-             GLsizei bytesOfKeyValueData, const void* keyValueData,
-             GLuint numImages, KTX_image_info images[]);
-
-/**
- * Writes a KTX file using supplied data.
- */
-KTX_error_code
-ktxWriteKTXN(const char* dstname, const KTX_texture_info* imageInfo,
-             GLsizei bytesOfKeyValueData, const void* keyValueData,
-             GLuint numImages, KTX_image_info images[]);
-
-/*
- * Writes a KTX file into memory using supplied data.
- */
-KTX_error_code
-ktxWriteKTXM(unsigned char** dst, GLsizei* size,
-             const KTX_texture_info* textureInfo, GLsizei bytesOfKeyValueData,
-             const void* keyValueData, GLuint numImages,
-             KTX_image_info images[]);
-
-#ifdef __cplusplus
-}
-#endif
-
-/**
-@~English
-@page libktx_history Revision History
-
-@section v6 Version 3.0
-Added:
-@li new ktxTexture object based API for reading KTX files without an OpenGL context.
-@li Vulkan loader. @#include <ktxvulkan.h> to use it.
-
-Changed:
-@li ktx.h to not depend on KHR/khrplatform.h and GL{,ES*}/gl{corearb,}.h.
-    Applications using OpenGL must now include these files themselves.
-@li ktxLoadTexture[FMN], removing the hack of loading 1D textures as 2D textures
-    when the OpenGL context does not support 1D textures.
-    KTX_UNSUPPORTED_TEXTURE_TYPE is now returned.
-
-@section v5 Version 2.0.2
-Added:
-@li Support for cubemap arrays.
-
-Changed:
-@li New build system
-
-Fixed:
-@li GitHub issue #40: failure to byte-swap key-value lengths.
-@li GitHub issue #33: returning incorrect target when loading cubemaps.
-@li GitHub PR #42: loading of texture arrays.
-@li GitHub PR #41: compilation error when KTX_OPENGL_ES2=1 defined.
-@li GitHub issue #39: stack-buffer-overflow in toktx
-@li Don't use GL_EXTENSIONS on recent OpenGL versions.
-
-@section v4 Version 2.0.1
-Added:
-@li CMake build files. Thanks to Pavel Rotjberg for the initial version.
-
-Changed:
-@li ktxWriteKTXF to check the validity of the type & format combinations
-    passed to it.
-
-Fixed:
-@li Public Bugzilla <a href="http://www.khronos.org/bugzilla/show_bug.cgi?id=999">999</a>: 16-bit luminance texture cannot be written.
-@li compile warnings from compilers stricter than MS Visual C++. Thanks to
-    Pavel Rotjberg.
-
-@section v3 Version 2.0
-Added:
-@li support for decoding ETC2 and EAC formats in the absence of a hardware
-    decoder.
-@li support for converting textures with legacy LUMINANCE, LUMINANCE_ALPHA,
-    etc. formats to the equivalent R, RG, etc. format with an
-    appropriate swizzle, when loading in OpenGL Core Profile contexts.
-@li ktxErrorString function to return a string corresponding to an error code.
-@li tests for ktxLoadTexture[FN] that run under OpenGL ES 3.0 and OpenGL 3.3.
-    The latter includes an EGL on WGL wrapper that makes porting apps between
-    OpenGL ES and OpenGL easier on Windows.
-@li more texture formats to ktxLoadTexture[FN] and toktx tests.
-
-Changed:
-@li ktxLoadTexture[FMN] to discover the capabilities of the GL context at
-    run time and load textures, or not, according to those capabilities.
-
-Fixed:
-@li failure of ktxWriteKTXF to pad image rows to 4 bytes as required by the KTX
-    format.
-@li ktxWriteKTXF exiting with KTX_FILE_WRITE_ERROR when attempting to write
-    more than 1 byte of face-LOD padding.
-
-Although there is only a very minor API change, the addition of ktxErrorString,
-the functional changes are large enough to justify bumping the major revision
-number.
-
-@section v2 Version 1.0.1
-Implemented ktxLoadTextureM.
-Fixed the following:
-@li Public Bugzilla <a href="http://www.khronos.org/bugzilla/show_bug.cgi?id=571">571</a>: crash when null passed for pIsMipmapped.
-@li Public Bugzilla <a href="http://www.khronos.org/bugzilla/show_bug.cgi?id=572">572</a>: memory leak when unpacking ETC textures.
-@li Public Bugzilla <a href="http://www.khronos.org/bugzilla/show_bug.cgi?id=573">573</a>: potential crash when unpacking ETC textures with unused padding pixels.
-@li Public Bugzilla <a href="http://www.khronos.org/bugzilla/show_bug.cgi?id=576">576</a>: various small fixes.
-
-Thanks to Krystian Bigaj for the ktxLoadTextureM implementation and these fixes.
-
-@section v1 Version 1.0
-Initial release.
-
-*/
-
-#endif /* KTX_H_A55A6F00956F42F3A137C11929827FE1 */
diff --git a/external/KTX-Software-master/lib/checkheader.c b/external/KTX-Software-master/lib/checkheader.c
deleted file mode 100644
index e46e7b7f518d879b57081d3084299e62c342261e..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/checkheader.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/* $Id: df002b39ae6b9b3b995e7633ff96acf0d285edcc $ */
-
-/*
- * ©2010-2018 The khronos Group, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @internal
- * @file checkheader.c
- * @~English
- *
- * @brief Function to verify a KTX file header
- *
- * @author Mark Callow, HI Corporation
- */
-
-/*
- * Author: Georg Kolling, Imagination Technology with modifications
- * by Mark Callow, HI Corporation.
- */
-#include <assert.h>
-#include <string.h>
-
-#include "ktx.h"
-#include "ktxint.h"
-
-/**
- * @internal
- * @~English
- * @brief Check a KTX file header.
- *
- * As well as checking that the header identifies a KTX file, the function
- * sanity checks the values and returns information about the texture in a
- * struct KTX_supplementary_info.
- *
- * @param pHeader   pointer to the KTX header to check
- * @param pSuppInfo pointer to a KTX_supplementary_info structure in which to
- *                  return information about the texture.
- * 
- * @author Georg Kolling, Imagination Technology
- * @author Mark Callow, HI Corporation
- */
-KTX_error_code _ktxCheckHeader(KTX_header* pHeader,
-                               KTX_supplemental_info* pSuppInfo)
-{
-    ktx_uint8_t identifier_reference[12] = KTX_IDENTIFIER_REF;
-    ktx_uint32_t max_dim;
-    
-    assert(pHeader != NULL && pSuppInfo != NULL);
-
-    /* Compare identifier, is this a KTX file? */
-    if (memcmp(pHeader->identifier, identifier_reference, 12) != 0)
-    {
-        return KTX_UNKNOWN_FILE_FORMAT;
-    }
-
-    if (pHeader->endianness == KTX_ENDIAN_REF_REV)
-    {
-        /* Convert endianness of pHeader fields. */
-        _ktxSwapEndian32(&pHeader->glType, 12);
-
-        if (pHeader->glTypeSize != 1 &&
-            pHeader->glTypeSize != 2 &&
-            pHeader->glTypeSize != 4)
-        {
-            /* Only 8-, 16-, and 32-bit types supported so far. */
-            return KTX_FILE_DATA_ERROR;
-        }
-    }
-    else if (pHeader->endianness != KTX_ENDIAN_REF)
-    {
-        return KTX_FILE_DATA_ERROR;
-    }
-
-    /* Check glType and glFormat */
-    pSuppInfo->compressed = 0;
-    if (pHeader->glType == 0 || pHeader->glFormat == 0)
-    {
-        if (pHeader->glType + pHeader->glFormat != 0)
-        {
-            /* either both or none of glType, glFormat must be zero */
-            return KTX_FILE_DATA_ERROR;
-        }
-        pSuppInfo->compressed = 1;
-    }
-    
-    if (pHeader->glFormat == pHeader->glInternalformat) {
-        // glInternalFormat is either unsized (which is no longer and should
-        // never have been supported by libktx) or glFormat is sized.
-        return KTX_FILE_DATA_ERROR;
-    }
-
-    /* Check texture dimensions. KTX files can store 8 types of textures:
-       1D, 2D, 3D, cube, and array variants of these. There is currently
-       no GL extension for 3D array textures. */
-    if ((pHeader->pixelWidth == 0) ||
-        (pHeader->pixelDepth > 0 && pHeader->pixelHeight == 0))
-    {
-        /* texture must have width */
-        /* texture must have height if it has depth */
-        return KTX_FILE_DATA_ERROR; 
-    }
-
-    
-    if (pHeader->pixelDepth > 0)
-    {
-        if (pHeader->numberOfArrayElements > 0)
-        {
-            /* No 3D array textures yet. */
-            return KTX_UNSUPPORTED_TEXTURE_TYPE;
-        }
-        pSuppInfo->textureDimension = 3;
-    }
-    else if (pHeader->pixelHeight > 0)
-    {
-        pSuppInfo->textureDimension = 2;
-    }
-    else
-    {
-        pSuppInfo->textureDimension = 1;
-    }
-
-    if (pHeader->numberOfFaces == 6)
-    {
-        if (pSuppInfo->textureDimension != 2)
-        {
-            /* cube map needs 2D faces */
-            return KTX_FILE_DATA_ERROR;
-        }
-    }
-    else if (pHeader->numberOfFaces != 1)
-    {
-        /* numberOfFaces must be either 1 or 6 */
-        return KTX_FILE_DATA_ERROR;
-    }
-    
-    /* Check number of mipmap levels */
-    if (pHeader->numberOfMipmapLevels == 0)
-    {
-        pSuppInfo->generateMipmaps = 1;
-        pHeader->numberOfMipmapLevels = 1;
-    }
-    else
-    {
-        pSuppInfo->generateMipmaps = 0;
-    }
-
-    /* This test works for arrays too because height or depth will be 0. */
-    max_dim = MAX(MAX(pHeader->pixelWidth, pHeader->pixelHeight), pHeader->pixelDepth);
-    if (max_dim < ((ktx_uint32_t)1 << (pHeader->numberOfMipmapLevels - 1)))
-    {
-        /* Can't have more mip levels than 1 + log2(max(width, height, depth)) */
-        return KTX_FILE_DATA_ERROR;
-    }
-
-    return KTX_SUCCESS;
-}
diff --git a/external/KTX-Software-master/lib/errstr.c b/external/KTX-Software-master/lib/errstr.c
deleted file mode 100644
index bf6a695a83455ab8411c91a8f0ea7d133f7e33db..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/errstr.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/* $Id: 11f526c2587823b49cde3b437746e95b57e3200e $ */
-
-/*
- * ©2010-2018 The khronos Group, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file errstr.c
- * @~English
- *
- * @brief Function to return a string corresponding to a KTX error code.
- *
- * @author Mark Callow, HI Corporation
- */
-
-#include "ktx.h"
-
-static const char* const errorStrings[] = {
-    "Operation succeeded",                            /* KTX_SUCCESS */
-    "File data is inconsistent with KTX spec.",       /* KTX_FILE_DATA_ERROR */
-    "File open failed",                               /* KTX_FILE_OPEN_FAILED */
-    "Operation would exceed the max file size",       /* KTX_FILE_OVERFLOW */
-    "File read error",                                /* KTX_FILE_READ_ERROR */
-    "File seek error",                                /* KTX_FILE_SEEK_ERROR */
-    "File does not have enough data for request",     /* KTX_FILE_UNEXPECTED_EOF */
-    "File write error",                               /* KTX_FILE_WRITE_ERROR */
-    "GL error occurred",                              /* KTX_GL_ERROR */
-    "Operation not allowed in the current state",     /* KTX_INVALID_OPERATION */
-    "Invalid parameter value",                        /* KTX_INVALID_VALUE */
-    "Key not found",                                  /* KTX_NOT_FOUND */
-    "Out of memory",                                  /* KTX_OUT_OF_MEMORY */
-    "Not a KTX file",                                 /* KTX_UNKNOWN_FILE_FORMAT */
-    "Texture type not supported by GL context"        /* KTX_UNSUPPORTED_TEXTURE_TYPE */
-};
-static const int lastErrorCode = (sizeof(errorStrings) / sizeof(char*)) - 1;
-
-
-/**
- * @~English
- * @brief Return a string corresponding to a KTX error code.
- *
- * @param error     the error code for which to return a string
- *
- * @return pointer to the message string.
- *
- * @internal Use UTF-8 for translated message strings.
- * 
- * @author Mark Callow, HI Corporation
- */
-const char* const ktxErrorString(KTX_error_code error)
-{
-    if (error > lastErrorCode)
-        return "Unrecognized error code";
-    return errorStrings[error];
-}
diff --git a/external/KTX-Software-master/lib/etcdec.cxx b/external/KTX-Software-master/lib/etcdec.cxx
deleted file mode 100644
index 5731979b42879bed9701f582cdbaaf35674ff47a..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/etcdec.cxx
+++ /dev/null
@@ -1,1845 +0,0 @@
-/*
- 
-@~English
-@page license License
- 
-@section etcdec etcdec.cxx License
- 
-etcdec.cxx is made available under the terms and conditions of the following
-License Agreement.
-
-Software License Agreement
-
-PLEASE REVIEW THE FOLLOWING TERMS AND CONDITIONS PRIOR TO USING THE
-ERICSSON TEXTURE COMPRESSION CODEC SOFTWARE (THE "SOFTWARE"). THE USE
-OF THE SOFTWARE IS SUBJECT TO THE TERMS AND CONDITIONS OF THE
-FOLLOWING SOFTWARE LICENSE AGREEMENT (THE "SLA"). IF YOU DO NOT ACCEPT
-SUCH TERMS AND CONDITIONS YOU MAY NOT USE THE SOFTWARE.
-
-Subject to the terms and conditions of the SLA, the licensee of the
-Software (the "Licensee") hereby, receives a non-exclusive,
-non-transferable, limited, free-of-charge, perpetual and worldwide
-license, to copy, use, distribute and modify the Software, but only
-for the purpose of developing, manufacturing, selling, using and
-distributing products including the Software in binary form, which
-products are used for compression and/or decompression according to
-the Khronos standard specifications OpenGL, OpenGL ES and
-WebGL. Notwithstanding anything of the above, Licensee may distribute
-[etcdec.cxx] in source code form provided (i) it is in unmodified
-form; and (ii) it is included in software owned by Licensee.
-
-If Licensee institutes, or threatens to institute, patent litigation
-against Ericsson or Ericsson's affiliates for using the Software for
-developing, having developed, manufacturing, having manufactured,
-selling, offer for sale, importing, using, leasing, operating,
-repairing and/or distributing products (i) within the scope of the
-Khronos framework; or (ii) using software or other intellectual
-property rights owned by Ericsson or its affiliates and provided under
-the Khronos framework, Ericsson shall have the right to terminate this
-SLA with immediate effect. Moreover, if Licensee institutes, or
-threatens to institute, patent litigation against any other licensee
-of the Software for using the Software in products within the scope of
-the Khronos framework, Ericsson shall have the right to terminate this
-SLA with immediate effect. However, should Licensee institute, or
-threaten to institute, patent litigation against any other licensee of
-the Software based on such other licensee's use of any other software
-together with the Software, then Ericsson shall have no right to
-terminate this SLA.
-
-This SLA does not transfer to Licensee any ownership to any Ericsson
-or third party intellectual property rights. All rights not expressly
-granted by Ericsson under this SLA are hereby expressly
-reserved. Furthermore, nothing in this SLA shall be construed as a
-right to use or sell products in a manner which conveys or purports to
-convey whether explicitly, by principles of implied license, or
-otherwise, any rights to any third party, under any patent of Ericsson
-or of Ericsson's affiliates covering or relating to any combination of
-the Software with any other software or product (not licensed
-hereunder) where the right applies specifically to the combination and
-not to the software or product itself.
-
-THE SOFTWARE IS PROVIDED "AS IS". ERICSSON MAKES NO REPRESENTATIONS OF
-ANY KIND, EXTENDS NO WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
-EXPRESS, IMPLIED OR STATUTORY; INCLUDING, BUT NOT LIMITED TO, EXPRESS,
-IMPLIED OR STATUTORY WARRANTIES OR CONDITIONS OF TITLE,
-MERCHANTABILITY, SATISFACTORY QUALITY, SUITABILITY, AND FITNESS FOR A
-PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
-OF THE SOFTWARE IS WITH THE LICENSEE. SHOULD THE SOFTWARE PROVE
-DEFECTIVE, THE LICENSEE ASSUMES THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION. ERICSSON MAKES NO WARRANTY THAT THE MANUFACTURE,
-SALE, OFFERING FOR SALE, DISTRIBUTION, LEASE, USE OR IMPORTATION UNDER
-THE SLA WILL BE FREE FROM INFRINGEMENT OF PATENTS, COPYRIGHTS OR OTHER
-INTELLECTUAL PROPERTY RIGHTS OF OTHERS, AND THE VALIDITY OF THE
-LICENSE AND THE SLA ARE SUBJECT TO LICENSEE'S SOLE RESPONSIBILITY TO
-MAKE SUCH DETERMINATION AND ACQUIRE SUCH LICENSES AS MAY BE NECESSARY
-WITH RESPECT TO PATENTS, COPYRIGHT AND OTHER INTELLECTUAL PROPERTY OF
-THIRD PARTIES.
-
-THE LICENSEE ACKNOWLEDGES AND ACCEPTS THAT THE SOFTWARE (I) IS NOT
-LICENSED FOR; (II) IS NOT DESIGNED FOR OR INTENDED FOR; AND (III) MAY
-NOT BE USED FOR; ANY MISSION CRITICAL APPLICATIONS SUCH AS, BUT NOT
-LIMITED TO OPERATION OF NUCLEAR OR HEALTHCARE COMPUTER SYSTEMS AND/OR
-NETWORKS, AIRCRAFT OR TRAIN CONTROL AND/OR COMMUNICATION SYSTEMS OR
-ANY OTHER COMPUTER SYSTEMS AND/OR NETWORKS OR CONTROL AND/OR
-COMMUNICATION SYSTEMS ALL IN WHICH CASE THE FAILURE OF THE SOFTWARE
-COULD LEAD TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL, MATERIAL OR
-ENVIRONMENTAL DAMAGE. LICENSEE'S RIGHTS UNDER THIS LICENSE WILL
-TERMINATE AUTOMATICALLY AND IMMEDIATELY WITHOUT NOTICE IF LICENSEE
-FAILS TO COMPLY WITH THIS PARAGRAPH.
-
-IN NO EVENT SHALL ERICSSON BE LIABLE FOR ANY DAMAGES WHATSOEVER,
-INCLUDING BUT NOT LIMITED TO PERSONAL INJURY, ANY GENERAL, SPECIAL,
-INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN
-CONNECTION WITH THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING
-BUT NOT LIMITED TO LOSS OF PROFITS, BUSINESS INTERUPTIONS, OR ANY
-OTHER COMMERCIAL DAMAGES OR LOSSES, LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY THE LICENSEE OR THIRD
-PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER
-SOFTWARE) REGARDLESS OF THE THEORY OF LIABILITY (CONTRACT, TORT, OR
-OTHERWISE), EVEN IF THE LICENSEE OR ANY OTHER PARTY HAS BEEN ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGES.
-
-Licensee acknowledges that "ERICSSON ///" is the corporate trademark
-of Telefonaktiebolaget LM Ericsson and that both "Ericsson" and the
-figure "///" are important features of the trade names of
-Telefonaktiebolaget LM Ericsson. Nothing contained in these terms and
-conditions shall be deemed to grant Licensee any right, title or
-interest in the word "Ericsson" or the figure "///". No delay or
-omission by Ericsson to exercise any right or power shall impair any
-such right or power to be construed to be a waiver thereof. Consent by
-Ericsson to, or waiver of, a breach by the Licensee shall not
-constitute consent to, waiver of, or excuse for any other different or
-subsequent breach.
-
-This SLA shall be governed by the substantive law of Sweden. Any
-dispute, controversy or claim arising out of or in connection with
-this SLA, or the breach, termination or invalidity thereof, shall be
-submitted to the exclusive jurisdiction of the Swedish Courts.
-
-*/
-
-//// etcpack v2.74
-//// 
-//// NO WARRANTY 
-//// 
-//// BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE THE PROGRAM IS PROVIDED
-//// "AS IS". ERICSSON MAKES NO REPRESENTATIONS OF ANY KIND, EXTENDS NO
-//// WARRANTIES OR CONDITIONS OF ANY KIND; EITHER EXPRESS, IMPLIED OR
-//// STATUTORY; INCLUDING, BUT NOT LIMITED TO, EXPRESS, IMPLIED OR
-//// STATUTORY WARRANTIES OR CONDITIONS OF TITLE, MERCHANTABILITY,
-//// SATISFACTORY QUALITY, SUITABILITY AND FITNESS FOR A PARTICULAR
-//// PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-//// PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
-//// THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. ERICSSON
-//// MAKES NO WARRANTY THAT THE MANUFACTURE, SALE, OFFERING FOR SALE,
-//// DISTRIBUTION, LEASE, USE OR IMPORTATION UNDER THE LICENSE WILL BE FREE
-//// FROM INFRINGEMENT OF PATENTS, COPYRIGHTS OR OTHER INTELLECTUAL
-//// PROPERTY RIGHTS OF OTHERS, AND THE VALIDITY OF THE LICENSE IS SUBJECT
-//// TO YOUR SOLE RESPONSIBILITY TO MAKE SUCH DETERMINATION AND ACQUIRE
-//// SUCH LICENSES AS MAY BE NECESSARY WITH RESPECT TO PATENTS, COPYRIGHT
-//// AND OTHER INTELLECTUAL PROPERTY OF THIRD PARTIES.
-//// 
-//// FOR THE AVOIDANCE OF DOUBT THE PROGRAM (I) IS NOT LICENSED FOR; (II)
-//// IS NOT DESIGNED FOR OR INTENDED FOR; AND (III) MAY NOT BE USED FOR;
-//// ANY MISSION CRITICAL APPLICATIONS SUCH AS, BUT NOT LIMITED TO
-//// OPERATION OF NUCLEAR OR HEALTHCARE COMPUTER SYSTEMS AND/OR NETWORKS,
-//// AIRCRAFT OR TRAIN CONTROL AND/OR COMMUNICATION SYSTEMS OR ANY OTHER
-//// COMPUTER SYSTEMS AND/OR NETWORKS OR CONTROL AND/OR COMMUNICATION
-//// SYSTEMS ALL IN WHICH CASE THE FAILURE OF THE PROGRAM COULD LEAD TO
-//// DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL, MATERIAL OR ENVIRONMENTAL
-//// DAMAGE. YOUR RIGHTS UNDER THIS LICENSE WILL TERMINATE AUTOMATICALLY
-//// AND IMMEDIATELY WITHOUT NOTICE IF YOU FAIL TO COMPLY WITH THIS
-//// PARAGRAPH.
-//// 
-//// IN NO EVENT WILL ERICSSON, BE LIABLE FOR ANY DAMAGES WHATSOEVER,
-//// INCLUDING BUT NOT LIMITED TO PERSONAL INJURY, ANY GENERAL, SPECIAL,
-//// INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN
-//// CONNECTION WITH THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
-//// NOT LIMITED TO LOSS OF PROFITS, BUSINESS INTERUPTIONS, OR ANY OTHER
-//// COMMERCIAL DAMAGES OR LOSSES, LOSS OF DATA OR DATA BEING RENDERED
-//// INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
-//// THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) REGARDLESS OF THE
-//// THEORY OF LIABILITY (CONTRACT, TORT OR OTHERWISE), EVEN IF SUCH HOLDER
-//// OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-//// 
-//// (C) Ericsson AB 2013. All Rights Reserved.
-//// 
-
-#include <stdio.h>
-#include <stdlib.h>
-
-// Typedefs
-typedef unsigned char uint8;
-typedef unsigned short uint16;
-typedef short int16;
-
-// Macros to help with bit extraction/insertion
-#define SHIFT(size,startpos) ((startpos)-(size)+1)
-#define MASK(size, startpos) (((2<<(size-1))-1) << SHIFT(size,startpos))
-#define PUTBITS( dest, data, size, startpos) dest = ((dest & ~MASK(size, startpos)) | ((data << SHIFT(size, startpos)) & MASK(size,startpos)))
-#define SHIFTHIGH(size, startpos) (((startpos)-32)-(size)+1)
-#define MASKHIGH(size, startpos) (((1<<(size))-1) << SHIFTHIGH(size,startpos))
-#define PUTBITSHIGH(dest, data, size, startpos) dest = ((dest & ~MASKHIGH(size, startpos)) | ((data << SHIFTHIGH(size, startpos)) & MASKHIGH(size,startpos)))
-#define GETBITS(source, size, startpos)  (( (source) >> ((startpos)-(size)+1) ) & ((1<<(size)) -1))
-#define GETBITSHIGH(source, size, startpos)  (( (source) >> (((startpos)-32)-(size)+1) ) & ((1<<(size)) -1))
-#ifndef PGMOUT
-#define PGMOUT 0
-#endif
-// Thumb macros and definitions
-#define	R_BITS59T 4
-#define G_BITS59T 4
-#define	B_BITS59T 4
-#define	R_BITS58H 4
-#define G_BITS58H 4
-#define	B_BITS58H 4
-#define	MAXIMUM_ERROR (255*255*16*1000)
-#define R 0
-#define G 1
-#define B 2
-#define BLOCKHEIGHT 4
-#define BLOCKWIDTH 4
-#define BINPOW(power) (1<<(power))
-#define	TABLE_BITS_59T 3
-#define	TABLE_BITS_58H 3
-
-// Helper Macros
-#define CLAMP(ll,x,ul) (((x)<(ll)) ? (ll) : (((x)>(ul)) ? (ul) : (x)))
-#define JAS_ROUND(x) (((x) < 0.0 ) ? ((int)((x)-0.5)) : ((int)((x)+0.5)))
-
-#define RED_CHANNEL(img,width,x,y,channels)   img[channels*(y*width+x)+0]
-#define GREEN_CHANNEL(img,width,x,y,channels) img[channels*(y*width+x)+1]
-#define BLUE_CHANNEL(img,width,x,y,channels)  img[channels*(y*width+x)+2]
-#define ALPHA_CHANNEL(img,width,x,y,channels)  img[channels*(y*width+x)+3]
-
-
-// Global tables
-static uint8 table59T[8] = {3,6,11,16,23,32,41,64};  // 3-bit table for the 59 bit T-mode
-static uint8 table58H[8] = {3,6,11,16,23,32,41,64};  // 3-bit table for the 58 bit H-mode
-static int compressParams[16][4] = {{-8, -2,  2, 8}, {-8, -2,  2, 8}, {-17, -5, 5, 17}, {-17, -5, 5, 17}, {-29, -9, 9, 29}, {-29, -9, 9, 29}, {-42, -13, 13, 42}, {-42, -13, 13, 42}, {-60, -18, 18, 60}, {-60, -18, 18, 60}, {-80, -24, 24, 80}, {-80, -24, 24, 80}, {-106, -33, 33, 106}, {-106, -33, 33, 106}, {-183, -47, 47, 183}, {-183, -47, 47, 183}};
-static int unscramble[4] = {2, 3, 1, 0};
-int alphaTableInitialized = 0;
-int alphaTable[256][8];
-int alphaBase[16][4] = {	
-              {-15,-9,-6,-3},
-							{-13,-10,-7,-3},
-							{-13,-8,-5,-2},
-							{-13,-6,-4,-2},
-							{-12,-8,-6,-3},
-							{-11,-9,-7,-3},
-							{-11,-8,-7,-4},
-							{-11,-8,-5,-3},
-							{ -10,-8,-6,-2},
-							{ -10,-8,-5,-2},
-							{ -10,-8,-4,-2},
-							{ -10,-7,-5,-2},
-							{ -10,-7,-4,-3},
-							{ -10,-3,-2, -1},
-							{ -9,-8,-6,-4},
-							{ -9,-7,-5,-3}
-											};
-
-// Global variables
-int formatSigned = 0;
-
-// Enums
- enum{PATTERN_H = 0, 
-      PATTERN_T = 1};
-
-
-// Code used to create the valtab
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void setupAlphaTable() 
-{
-  if(alphaTableInitialized)
-    return;
-  alphaTableInitialized = 1;
-
-	//read table used for alpha compression
-	int buf;
-	for(int i = 16; i<32; i++) 
-	{
-		for(int j=0; j<8; j++) 
-		{
-			buf=alphaBase[i-16][3-j%4];
-			if(j<4)
-				alphaTable[i][j]=buf;
-			else
-				alphaTable[i][j]=(-buf-1);
-		}
-	}
-	
-	//beyond the first 16 values, the rest of the table is implicit.. so calculate that!
-	for(int i=0; i<256; i++) 
-	{
-		//fill remaining slots in table with multiples of the first ones.
-		int mul = i/16;
-		int old = 16+i%16;
-		for(int j = 0; j<8; j++) 
-		{
-			alphaTable[i][j]=alphaTable[old][j]*mul;
-			//note: we don't do clamping here, though we could, because we'll be clamped afterwards anyway.
-		}
-	}
-}
-
-// Read a word in big endian style
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void read_big_endian_2byte_word(unsigned short *blockadr, FILE *f)
-{
-	uint8 bytes[2];
-	unsigned short block;
-	// This is to silence -Wunused-result from GCC 4.8+.
-	size_t numitems; 
-
-	numitems = fread(&bytes[0], 1, 1, f);
-	numitems = fread(&bytes[1], 1, 1, f);
-
-	block = 0;
-	block |= bytes[0];
-	block = block << 8;
-	block |= bytes[1];
-
-	blockadr[0] = block;
-}
-
-// Read a word in big endian style
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void read_big_endian_4byte_word(unsigned int *blockadr, FILE *f)
-{
-	uint8 bytes[4];
-	unsigned int block;
-	// This is to silence -Wunused-result from GCC 4.8+.
-	size_t numitems; 
-
-	numitems = fread(&bytes[0], 1, 1, f);
-	numitems = fread(&bytes[1], 1, 1, f);
-	numitems = fread(&bytes[2], 1, 1, f);
-	numitems = fread(&bytes[3], 1, 1, f);
-
-	block = 0;
-	block |= bytes[0];
-	block = block << 8;
-	block |= bytes[1];
-	block = block << 8;
-	block |= bytes[2];
-	block = block << 8;
-	block |= bytes[3];
-
-	blockadr[0] = block;
-}
-
-// The format stores the bits for the three extra modes in a roundabout way to be able to
-// fit them without increasing the bit rate. This function converts them into something
-// that is easier to work with. 
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void unstuff57bits(unsigned int planar_word1, unsigned int planar_word2, unsigned int &planar57_word1, unsigned int &planar57_word2)
-{
-	// Get bits from twotimer configuration for 57 bits
-	// 
-	// Go to this bit layout:
-	//
-	//      63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 
-	//      -----------------------------------------------------------------------------------------------
-	//     |R0               |G01G02              |B01B02  ;B03     |RH1           |RH2|GH                 |
-	//      -----------------------------------------------------------------------------------------------
-	//
-	//      31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
-	//      -----------------------------------------------------------------------------------------------
-	//     |BH               |RV               |GV                  |BV                | not used          |   
-	//      -----------------------------------------------------------------------------------------------
-	//
-	//  From this:
-	// 
-	//      63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 
-	//      ------------------------------------------------------------------------------------------------
-	//     |//|R0               |G01|/|G02              |B01|/ // //|B02  |//|B03     |RH1           |df|RH2|
-	//      ------------------------------------------------------------------------------------------------
-	//
-	//      31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
-	//      -----------------------------------------------------------------------------------------------
-	//     |GH                  |BH               |RV               |GV                   |BV              |
-	//      -----------------------------------------------------------------------------------------------
-	//
-	//      63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34  33  32 
-	//      ---------------------------------------------------------------------------------------------------
-	//     | base col1    | dcol 2 | base col1    | dcol 2 | base col 1   | dcol 2 | table  | table  |diff|flip|
-	//     | R1' (5 bits) | dR2    | G1' (5 bits) | dG2    | B1' (5 bits) | dB2    | cw 1   | cw 2   |bit |bit |
-	//      ---------------------------------------------------------------------------------------------------
-
-	uint8 RO, GO1, GO2, BO1, BO2, BO3, RH1, RH2, GH, BH, RV, GV, BV;
-
-	RO  = GETBITSHIGH( planar_word1, 6, 62);
-	GO1 = GETBITSHIGH( planar_word1, 1, 56);
-	GO2 = GETBITSHIGH( planar_word1, 6, 54);
-	BO1 = GETBITSHIGH( planar_word1, 1, 48);
-	BO2 = GETBITSHIGH( planar_word1, 2, 44);
-	BO3 = GETBITSHIGH( planar_word1, 3, 41);
-	RH1 = GETBITSHIGH( planar_word1, 5, 38);
-	RH2 = GETBITSHIGH( planar_word1, 1, 32);
-	GH  = GETBITS(     planar_word2, 7, 31);
-	BH  = GETBITS(     planar_word2, 6, 24);
-	RV  = GETBITS(     planar_word2, 6, 18);
-	GV  = GETBITS(     planar_word2, 7, 12);
-	BV  = GETBITS(     planar_word2, 6,  5);
-
-	planar57_word1 = 0; planar57_word2 = 0;
-	PUTBITSHIGH( planar57_word1, RO,  6, 63);
-	PUTBITSHIGH( planar57_word1, GO1, 1, 57);
-	PUTBITSHIGH( planar57_word1, GO2, 6, 56);
-	PUTBITSHIGH( planar57_word1, BO1, 1, 50);
-	PUTBITSHIGH( planar57_word1, BO2, 2, 49);
-	PUTBITSHIGH( planar57_word1, BO3, 3, 47);
-	PUTBITSHIGH( planar57_word1, RH1, 5, 44);
-	PUTBITSHIGH( planar57_word1, RH2, 1, 39);
-	PUTBITSHIGH( planar57_word1, GH, 7, 38);
-	PUTBITS(     planar57_word2, BH, 6, 31);
-	PUTBITS(     planar57_word2, RV, 6, 25);
-	PUTBITS(     planar57_word2, GV, 7, 19);
-	PUTBITS(     planar57_word2, BV, 6, 12);
-}
-
-// The format stores the bits for the three extra modes in a roundabout way to be able to
-// fit them without increasing the bit rate. This function converts them into something
-// that is easier to work with. 
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void unstuff58bits(unsigned int thumbH_word1, unsigned int thumbH_word2, unsigned int &thumbH58_word1, unsigned int &thumbH58_word2)
-{
-	// Go to this layout:
-	//
-	//     |63 62 61 60 59 58|57 56 55 54 53 52 51|50 49|48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33|32   |
-	//     |-------empty-----|part0---------------|part1|part2------------------------------------------|part3|
-	//
-	//  from this:
-	// 
-	//      63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 
-	//      --------------------------------------------------------------------------------------------------|
-	//     |//|part0               |// // //|part1|//|part2                                          |df|part3|
-	//      --------------------------------------------------------------------------------------------------|
-
-	unsigned int part0, part1, part2, part3;
-
-	// move parts
-	part0 = GETBITSHIGH( thumbH_word1, 7, 62);
-	part1 = GETBITSHIGH( thumbH_word1, 2, 52);
-	part2 = GETBITSHIGH( thumbH_word1,16, 49);
-	part3 = GETBITSHIGH( thumbH_word1, 1, 32);
-	thumbH58_word1 = 0;
-	PUTBITSHIGH( thumbH58_word1, part0,  7, 57);
-	PUTBITSHIGH( thumbH58_word1, part1,  2, 50);
-	PUTBITSHIGH( thumbH58_word1, part2, 16, 48);
-	PUTBITSHIGH( thumbH58_word1, part3,  1, 32);
-
-	thumbH58_word2 = thumbH_word2;
-}
-
-// The format stores the bits for the three extra modes in a roundabout way to be able to
-// fit them without increasing the bit rate. This function converts them into something
-// that is easier to work with. 
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void unstuff59bits(unsigned int thumbT_word1, unsigned int thumbT_word2, unsigned int &thumbT59_word1, unsigned int &thumbT59_word2)
-{
-	// Get bits from twotimer configuration 59 bits. 
-	// 
-	// Go to this bit layout:
-	//
-	//     |63 62 61 60 59|58 57 56 55|54 53 52 51|50 49 48 47|46 45 44 43|42 41 40 39|38 37 36 35|34 33 32|
-	//     |----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
-	//
-	//     |31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
-	//     |----------------------------------------index bits---------------------------------------------|
-	//
-	//
-	//  From this:
-	// 
-	//      63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 
-	//      -----------------------------------------------------------------------------------------------
-	//     |// // //|R0a  |//|R0b  |G0         |B0         |R1         |G1         |B1          |da  |df|db|
-	//      -----------------------------------------------------------------------------------------------
-	//
-	//     |31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
-	//     |----------------------------------------index bits---------------------------------------------|
-	//
-	//      63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 
-	//      -----------------------------------------------------------------------------------------------
-	//     | base col1    | dcol 2 | base col1    | dcol 2 | base col 1   | dcol 2 | table  | table  |df|fp|
-	//     | R1' (5 bits) | dR2    | G1' (5 bits) | dG2    | B1' (5 bits) | dB2    | cw 1   | cw 2   |bt|bt|
-	//      ------------------------------------------------------------------------------------------------
-
-	uint8 R0a;
-
-	// Fix middle part
-	thumbT59_word1 = thumbT_word1 >> 1;
-	// Fix db (lowest bit of d)
-	PUTBITSHIGH( thumbT59_word1, thumbT_word1,  1, 32);
-	// Fix R0a (top two bits of R0)
-	R0a = GETBITSHIGH( thumbT_word1, 2, 60);
-	PUTBITSHIGH( thumbT59_word1, R0a,  2, 58);
-
-	// Zero top part (not needed)
-	PUTBITSHIGH( thumbT59_word1, 0,  5, 63);
-
-	thumbT59_word2 = thumbT_word2;
-}
-
-// The color bits are expanded to the full color
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void decompressColor(int R_B, int G_B, int B_B, uint8 (colors_RGB444)[2][3], uint8 (colors)[2][3]) 
-{
-	// The color should be retrieved as:
-	//
-	// c = round(255/(r_bits^2-1))*comp_color
-	//
-	// This is similar to bit replication
-	// 
-	// Note -- this code only work for bit replication from 4 bits and up --- 3 bits needs
-	// two copy operations.
-
- 	colors[0][R] = (colors_RGB444[0][R] << (8 - R_B)) | (colors_RGB444[0][R] >> (R_B - (8-R_B)) );
- 	colors[0][G] = (colors_RGB444[0][G] << (8 - G_B)) | (colors_RGB444[0][G] >> (G_B - (8-G_B)) );
- 	colors[0][B] = (colors_RGB444[0][B] << (8 - B_B)) | (colors_RGB444[0][B] >> (B_B - (8-B_B)) );
- 	colors[1][R] = (colors_RGB444[1][R] << (8 - R_B)) | (colors_RGB444[1][R] >> (R_B - (8-R_B)) );
- 	colors[1][G] = (colors_RGB444[1][G] << (8 - G_B)) | (colors_RGB444[1][G] >> (G_B - (8-G_B)) );
- 	colors[1][B] = (colors_RGB444[1][B] << (8 - B_B)) | (colors_RGB444[1][B] >> (B_B - (8-B_B)) );
-}
-
-void calculatePaintColors59T(uint8 d, uint8 p, uint8 (colors)[2][3], uint8 (possible_colors)[4][3]) 
-{
-	//////////////////////////////////////////////
-	//
-	//		C3      C1		C4----C1---C2
-	//		|		|			  |
-	//		|		|			  |
-	//		|-------|			  |
-	//		|		|			  |
-	//		|		|			  |
-	//		C4      C2			  C3
-	//
-	//////////////////////////////////////////////
-
-	// C4
-	possible_colors[3][R] = CLAMP(0,colors[1][R] - table59T[d],255);
-	possible_colors[3][G] = CLAMP(0,colors[1][G] - table59T[d],255);
-	possible_colors[3][B] = CLAMP(0,colors[1][B] - table59T[d],255);
-	
-	if (p == PATTERN_T) 
-	{
-		// C3
-		possible_colors[0][R] = colors[0][R];
-		possible_colors[0][G] = colors[0][G];
-		possible_colors[0][B] = colors[0][B];
-		// C2
-		possible_colors[1][R] = CLAMP(0,colors[1][R] + table59T[d],255);
-		possible_colors[1][G] = CLAMP(0,colors[1][G] + table59T[d],255);
-		possible_colors[1][B] = CLAMP(0,colors[1][B] + table59T[d],255);
-		// C1
-		possible_colors[2][R] = colors[1][R];
-		possible_colors[2][G] = colors[1][G];
-		possible_colors[2][B] = colors[1][B];
-
-	} 
-	else 
-	{
-		printf("Invalid pattern. Terminating");
-		exit(1);
-	}
-}
-// Decompress a T-mode block (simple packing)
-// Simple 59T packing:
-//|63 62 61 60 59|58 57 56 55|54 53 52 51|50 49 48 47|46 45 44 43|42 41 40 39|38 37 36 35|34 33 32|
-//|----empty-----|---red 0---|--green 0--|--blue 0---|---red 1---|--green 1--|--blue 1---|--dist--|
-//
-//|31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00|
-//|----------------------------------------index bits---------------------------------------------|
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void decompressBlockTHUMB59Tc(unsigned int block_part1, unsigned int block_part2, uint8 *img,int width,int height,int startx,int starty, int channels)
-{
-	uint8 colorsRGB444[2][3];
-	uint8 colors[2][3];
-	uint8 paint_colors[4][3];
-	uint8 distance;
-	uint8 block_mask[4][4];
-
-	// First decode left part of block.
-	colorsRGB444[0][R]= GETBITSHIGH(block_part1, 4, 58);
-	colorsRGB444[0][G]= GETBITSHIGH(block_part1, 4, 54);
-	colorsRGB444[0][B]= GETBITSHIGH(block_part1, 4, 50);
-
-	colorsRGB444[1][R]= GETBITSHIGH(block_part1, 4, 46);
-	colorsRGB444[1][G]= GETBITSHIGH(block_part1, 4, 42);
-	colorsRGB444[1][B]= GETBITSHIGH(block_part1, 4, 38);
-
-	distance   = GETBITSHIGH(block_part1, TABLE_BITS_59T, 34);
-
-	// Extend the two colors to RGB888	
-	decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);	
-	calculatePaintColors59T(distance, PATTERN_T, colors, paint_colors);
-	
-	// Choose one of the four paint colors for each texel
-	for (uint8 x = 0; x < BLOCKWIDTH; ++x) 
-	{
-		for (uint8 y = 0; y < BLOCKHEIGHT; ++y) 
-		{
-			//block_mask[x][y] = GETBITS(block_part2,2,31-(y*4+x)*2);
-			block_mask[x][y] = GETBITS(block_part2,1,(y+x*4)+16)<<1;
-			block_mask[x][y] |= GETBITS(block_part2,1,(y+x*4));
-			img[channels*((starty+y)*width+startx+x)+R] =
-				CLAMP(0,paint_colors[block_mask[x][y]][R],255); // RED
-			img[channels*((starty+y)*width+startx+x)+G] =
-				CLAMP(0,paint_colors[block_mask[x][y]][G],255); // GREEN
-			img[channels*((starty+y)*width+startx+x)+B] =
-				CLAMP(0,paint_colors[block_mask[x][y]][B],255); // BLUE
-		}
-	}
-}
-
-void decompressBlockTHUMB59T(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty)
-{
-  decompressBlockTHUMB59Tc(block_part1, block_part2, img, width, height, startx, starty, 3);
-}
-
-// Calculate the paint colors from the block colors 
-// using a distance d and one of the H- or T-patterns.
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void calculatePaintColors58H(uint8 d, uint8 p, uint8 (colors)[2][3], uint8 (possible_colors)[4][3]) 
-{
-	
-	//////////////////////////////////////////////
-	//
-	//		C3      C1		C4----C1---C2
-	//		|		|			  |
-	//		|		|			  |
-	//		|-------|			  |
-	//		|		|			  |
-	//		|		|			  |
-	//		C4      C2			  C3
-	//
-	//////////////////////////////////////////////
-
-	// C4
-	possible_colors[3][R] = CLAMP(0,colors[1][R] - table58H[d],255);
-	possible_colors[3][G] = CLAMP(0,colors[1][G] - table58H[d],255);
-	possible_colors[3][B] = CLAMP(0,colors[1][B] - table58H[d],255);
-	
-	if (p == PATTERN_H) 
-	{ 
-		// C1
-		possible_colors[0][R] = CLAMP(0,colors[0][R] + table58H[d],255);
-		possible_colors[0][G] = CLAMP(0,colors[0][G] + table58H[d],255);
-		possible_colors[0][B] = CLAMP(0,colors[0][B] + table58H[d],255);
-		// C2
-		possible_colors[1][R] = CLAMP(0,colors[0][R] - table58H[d],255);
-		possible_colors[1][G] = CLAMP(0,colors[0][G] - table58H[d],255);
-		possible_colors[1][B] = CLAMP(0,colors[0][B] - table58H[d],255);
-		// C3
-		possible_colors[2][R] = CLAMP(0,colors[1][R] + table58H[d],255);
-		possible_colors[2][G] = CLAMP(0,colors[1][G] + table58H[d],255);
-		possible_colors[2][B] = CLAMP(0,colors[1][B] + table58H[d],255);
-	} 
-	else 
-	{
-		printf("Invalid pattern. Terminating");
-		exit(1);
-	}
-}
-
-// Decompress an H-mode block 
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void decompressBlockTHUMB58Hc(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty, int channels)
-{
-	unsigned int col0, col1;
-	uint8 colors[2][3];
-	uint8 colorsRGB444[2][3];
-	uint8 paint_colors[4][3];
-	uint8 distance;
-	uint8 block_mask[4][4];
-	
-	// First decode left part of block.
-	colorsRGB444[0][R]= GETBITSHIGH(block_part1, 4, 57);
-	colorsRGB444[0][G]= GETBITSHIGH(block_part1, 4, 53);
-	colorsRGB444[0][B]= GETBITSHIGH(block_part1, 4, 49);
-
-	colorsRGB444[1][R]= GETBITSHIGH(block_part1, 4, 45);
-	colorsRGB444[1][G]= GETBITSHIGH(block_part1, 4, 41);
-	colorsRGB444[1][B]= GETBITSHIGH(block_part1, 4, 37);
-
-	distance = 0;
-	distance = (GETBITSHIGH(block_part1, 2, 33)) << 1;
-
-	col0 = GETBITSHIGH(block_part1, 12, 57);
-	col1 = GETBITSHIGH(block_part1, 12, 45);
-
-	if(col0 >= col1)
-	{
-		distance |= 1;
-	}
-
-	// Extend the two colors to RGB888	
-	decompressColor(R_BITS58H, G_BITS58H, B_BITS58H, colorsRGB444, colors);	
-	
-	calculatePaintColors58H(distance, PATTERN_H, colors, paint_colors);
-	
-	// Choose one of the four paint colors for each texel
-	for (uint8 x = 0; x < BLOCKWIDTH; ++x) 
-	{
-		for (uint8 y = 0; y < BLOCKHEIGHT; ++y) 
-		{
-			//block_mask[x][y] = GETBITS(block_part2,2,31-(y*4+x)*2);
-			block_mask[x][y] = GETBITS(block_part2,1,(y+x*4)+16)<<1;
-			block_mask[x][y] |= GETBITS(block_part2,1,(y+x*4));
-			img[channels*((starty+y)*width+startx+x)+R] =
-				CLAMP(0,paint_colors[block_mask[x][y]][R],255); // RED
-			img[channels*((starty+y)*width+startx+x)+G] =
-				CLAMP(0,paint_colors[block_mask[x][y]][G],255); // GREEN
-			img[channels*((starty+y)*width+startx+x)+B] =
-				CLAMP(0,paint_colors[block_mask[x][y]][B],255); // BLUE
-		}
-	}
-}
-void decompressBlockTHUMB58H(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty)
-{
-  decompressBlockTHUMB58Hc(block_part1, block_part2, img, width, height, startx, starty, 3);
-}
-
-// Decompress the planar mode.
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void decompressBlockPlanar57c(unsigned int compressed57_1, unsigned int compressed57_2, uint8 *img, int width, int height, int startx, int starty, int channels)
-{
-	uint8 colorO[3], colorH[3], colorV[3];
-
-	colorO[0] = GETBITSHIGH( compressed57_1, 6, 63);
-	colorO[1] = GETBITSHIGH( compressed57_1, 7, 57);
-	colorO[2] = GETBITSHIGH( compressed57_1, 6, 50);
-	colorH[0] = GETBITSHIGH( compressed57_1, 6, 44);
-	colorH[1] = GETBITSHIGH( compressed57_1, 7, 38);
-	colorH[2] = GETBITS(     compressed57_2, 6, 31);
-	colorV[0] = GETBITS(     compressed57_2, 6, 25);
-	colorV[1] = GETBITS(     compressed57_2, 7, 19);
-	colorV[2] = GETBITS(     compressed57_2, 6, 12);
-
-	colorO[0] = (colorO[0] << 2) | (colorO[0] >> 4);
-	colorO[1] = (colorO[1] << 1) | (colorO[1] >> 6);
-	colorO[2] = (colorO[2] << 2) | (colorO[2] >> 4);
-
-	colorH[0] = (colorH[0] << 2) | (colorH[0] >> 4);
-	colorH[1] = (colorH[1] << 1) | (colorH[1] >> 6);
-	colorH[2] = (colorH[2] << 2) | (colorH[2] >> 4);
-
-	colorV[0] = (colorV[0] << 2) | (colorV[0] >> 4);
-	colorV[1] = (colorV[1] << 1) | (colorV[1] >> 6);
-	colorV[2] = (colorV[2] << 2) | (colorV[2] >> 4);
-
-	int xx, yy;
-
-	for( xx=0; xx<4; xx++)
-	{
-		for( yy=0; yy<4; yy++)
-		{
-			img[channels*width*(starty+yy) + channels*(startx+xx) + 0] = CLAMP(0, ((xx*(colorH[0]-colorO[0]) + yy*(colorV[0]-colorO[0]) + 4*colorO[0] + 2) >> 2),255);
-			img[channels*width*(starty+yy) + channels*(startx+xx) + 1] = CLAMP(0, ((xx*(colorH[1]-colorO[1]) + yy*(colorV[1]-colorO[1]) + 4*colorO[1] + 2) >> 2),255);
-			img[channels*width*(starty+yy) + channels*(startx+xx) + 2] = CLAMP(0, ((xx*(colorH[2]-colorO[2]) + yy*(colorV[2]-colorO[2]) + 4*colorO[2] + 2) >> 2),255);
-
-			//Equivalent method
-			/*img[channels*width*(starty+yy) + channels*(startx+xx) + 0] = (int)CLAMP(0, JAS_ROUND((xx*(colorH[0]-colorO[0])/4.0 + yy*(colorV[0]-colorO[0])/4.0 + colorO[0])), 255);
-			img[channels*width*(starty+yy) + channels*(startx+xx) + 1] = (int)CLAMP(0, JAS_ROUND((xx*(colorH[1]-colorO[1])/4.0 + yy*(colorV[1]-colorO[1])/4.0 + colorO[1])), 255);
-			img[channels*width*(starty+yy) + channels*(startx+xx) + 2] = (int)CLAMP(0, JAS_ROUND((xx*(colorH[2]-colorO[2])/4.0 + yy*(colorV[2]-colorO[2])/4.0 + colorO[2])), 255);*/
-			
-		}
-	}
-}
-void decompressBlockPlanar57(unsigned int compressed57_1, unsigned int compressed57_2, uint8 *img, int width, int height, int startx, int starty)
-{
-  decompressBlockPlanar57c(compressed57_1, compressed57_2, img, width, height, startx, starty, 3);
-}
-// Decompress an ETC1 block (or ETC2 using individual or differential mode).
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void decompressBlockDiffFlipC(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty, int channels)
-{
-	uint8 avg_color[3], enc_color1[3], enc_color2[3];
-	signed char diff[3];
-	int table;
-	int index,shift;
-	int r,g,b;
-	int diffbit;
-	int flipbit;
-
-	diffbit = (GETBITSHIGH(block_part1, 1, 33));
-	flipbit = (GETBITSHIGH(block_part1, 1, 32));
-
-	if( !diffbit )
-	{
-		// We have diffbit = 0.
-
-		// First decode left part of block.
-		avg_color[0]= GETBITSHIGH(block_part1, 4, 63);
-		avg_color[1]= GETBITSHIGH(block_part1, 4, 55);
-		avg_color[2]= GETBITSHIGH(block_part1, 4, 47);
-
-		// Here, we should really multiply by 17 instead of 16. This can
-		// be done by just copying the four lower bits to the upper ones
-		// while keeping the lower bits.
-		avg_color[0] |= (avg_color[0] <<4);
-		avg_color[1] |= (avg_color[1] <<4);
-		avg_color[2] |= (avg_color[2] <<4);
-
-		table = GETBITSHIGH(block_part1, 3, 39) << 1;
-
-		unsigned int pixel_indices_MSB, pixel_indices_LSB;
-			
-		pixel_indices_MSB = GETBITS(block_part2, 16, 31);
-		pixel_indices_LSB = GETBITS(block_part2, 16, 15);
-
-		if( (flipbit) == 0 )
-		{
-			// We should not flip
-			shift = 0;
-			for(int x=startx; x<startx+2; x++)
-			{
-				for(int y=starty; y<starty+4; y++)
-				{
-					index  = ((pixel_indices_MSB >> shift) & 1) << 1;
-					index |= ((pixel_indices_LSB >> shift) & 1);
-					shift++;
-					index=unscramble[index];
-
- 					r=RED_CHANNEL(img,width,x,y,channels)  =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- 					g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- 					b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
-				}
-			}
-		}
-		else
-		{
-			// We should flip
-			shift = 0;
-			for(int x=startx; x<startx+4; x++)
-			{
-				for(int y=starty; y<starty+2; y++)
-				{
-					index  = ((pixel_indices_MSB >> shift) & 1) << 1;
-					index |= ((pixel_indices_LSB >> shift) & 1);
-					shift++;
-					index=unscramble[index];
-
- 					r=RED_CHANNEL(img,width,x,y,channels)  =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- 					g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- 					b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
-				}
-				shift+=2;
-			}
-		}
-
-		// Now decode other part of block. 
-		avg_color[0]= GETBITSHIGH(block_part1, 4, 59);
-		avg_color[1]= GETBITSHIGH(block_part1, 4, 51);
-		avg_color[2]= GETBITSHIGH(block_part1, 4, 43);
-
-		// Here, we should really multiply by 17 instead of 16. This can
-		// be done by just copying the four lower bits to the upper ones
-		// while keeping the lower bits.
-		avg_color[0] |= (avg_color[0] <<4);
-		avg_color[1] |= (avg_color[1] <<4);
-		avg_color[2] |= (avg_color[2] <<4);
-
-		table = GETBITSHIGH(block_part1, 3, 36) << 1;
-		pixel_indices_MSB = GETBITS(block_part2, 16, 31);
-		pixel_indices_LSB = GETBITS(block_part2, 16, 15);
-
-		if( (flipbit) == 0 )
-		{
-			// We should not flip
-			shift=8;
-			for(int x=startx+2; x<startx+4; x++)
-			{
-				for(int y=starty; y<starty+4; y++)
-				{
-					index  = ((pixel_indices_MSB >> shift) & 1) << 1;
-					index |= ((pixel_indices_LSB >> shift) & 1);
-					shift++;
-					index=unscramble[index];
-
- 					r=RED_CHANNEL(img,width,x,y,channels)  =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- 					g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- 					b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
-				}
-			}
-		}
-		else
-		{
-			// We should flip
-			shift=2;
-			for(int x=startx; x<startx+4; x++)
-			{
-				for(int y=starty+2; y<starty+4; y++)
-				{
-					index  = ((pixel_indices_MSB >> shift) & 1) << 1;
-					index |= ((pixel_indices_LSB >> shift) & 1);
-					shift++;
-					index=unscramble[index];
-
- 					r=RED_CHANNEL(img,width,x,y,channels)  =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- 					g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- 					b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
-				}
-				shift += 2;
-			}
-		}
-	}
-	else
-	{
-		// We have diffbit = 1. 
-
-//      63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34  33  32 
-//      ---------------------------------------------------------------------------------------------------
-//     | base col1    | dcol 2 | base col1    | dcol 2 | base col 1   | dcol 2 | table  | table  |diff|flip|
-//     | R1' (5 bits) | dR2    | G1' (5 bits) | dG2    | B1' (5 bits) | dB2    | cw 1   | cw 2   |bit |bit |
-//      ---------------------------------------------------------------------------------------------------
-// 
-// 
-//     c) bit layout in bits 31 through 0 (in both cases)
-// 
-//      31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3   2   1  0
-//      --------------------------------------------------------------------------------------------------
-//     |       most significant pixel index bits       |         least significant pixel index bits       |  
-//     | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a| p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
-//      --------------------------------------------------------------------------------------------------      
-
-		// First decode left part of block.
-		enc_color1[0]= GETBITSHIGH(block_part1, 5, 63);
-		enc_color1[1]= GETBITSHIGH(block_part1, 5, 55);
-		enc_color1[2]= GETBITSHIGH(block_part1, 5, 47);
-
-		// Expand from 5 to 8 bits
-		avg_color[0] = (enc_color1[0] <<3) | (enc_color1[0] >> 2);
-		avg_color[1] = (enc_color1[1] <<3) | (enc_color1[1] >> 2);
-		avg_color[2] = (enc_color1[2] <<3) | (enc_color1[2] >> 2);
-
-		table = GETBITSHIGH(block_part1, 3, 39) << 1;
-
-		unsigned int pixel_indices_MSB, pixel_indices_LSB;
-			
-		pixel_indices_MSB = GETBITS(block_part2, 16, 31);
-		pixel_indices_LSB = GETBITS(block_part2, 16, 15);
-
-		if( (flipbit) == 0 )
-		{
-			// We should not flip
-			shift = 0;
-			for(int x=startx; x<startx+2; x++)
-			{
-				for(int y=starty; y<starty+4; y++)
-				{
-					index  = ((pixel_indices_MSB >> shift) & 1) << 1;
-					index |= ((pixel_indices_LSB >> shift) & 1);
-					shift++;
-					index=unscramble[index];
-
- 					r=RED_CHANNEL(img,width,x,y,channels)  =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- 					g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- 					b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
-				}
-			}
-		}
-		else
-		{
-			// We should flip
-			shift = 0;
-			for(int x=startx; x<startx+4; x++)
-			{
-				for(int y=starty; y<starty+2; y++)
-				{
-					index  = ((pixel_indices_MSB >> shift) & 1) << 1;
-					index |= ((pixel_indices_LSB >> shift) & 1);
-					shift++;
-					index=unscramble[index];
-
- 					r=RED_CHANNEL(img,width,x,y,channels)  =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- 					g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- 					b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
-				}
-				shift+=2;
-			}
-		}
-
-		// Now decode right part of block. 
-		diff[0]= GETBITSHIGH(block_part1, 3, 58);
-		diff[1]= GETBITSHIGH(block_part1, 3, 50);
-		diff[2]= GETBITSHIGH(block_part1, 3, 42);
-
-		// Extend sign bit to entire byte. 
-		diff[0] = (diff[0] << 5);
-		diff[1] = (diff[1] << 5);
-		diff[2] = (diff[2] << 5);
-		diff[0] = diff[0] >> 5;
-		diff[1] = diff[1] >> 5;
-		diff[2] = diff[2] >> 5;
-
-		//  Calculale second color
-		enc_color2[0]= enc_color1[0] + diff[0];
-		enc_color2[1]= enc_color1[1] + diff[1];
-		enc_color2[2]= enc_color1[2] + diff[2];
-
-		// Expand from 5 to 8 bits
-		avg_color[0] = (enc_color2[0] <<3) | (enc_color2[0] >> 2);
-		avg_color[1] = (enc_color2[1] <<3) | (enc_color2[1] >> 2);
-		avg_color[2] = (enc_color2[2] <<3) | (enc_color2[2] >> 2);
-
-		table = GETBITSHIGH(block_part1, 3, 36) << 1;
-		pixel_indices_MSB = GETBITS(block_part2, 16, 31);
-		pixel_indices_LSB = GETBITS(block_part2, 16, 15);
-
-		if( (flipbit) == 0 )
-		{
-			// We should not flip
-			shift=8;
-			for(int x=startx+2; x<startx+4; x++)
-			{
-				for(int y=starty; y<starty+4; y++)
-				{
-					index  = ((pixel_indices_MSB >> shift) & 1) << 1;
-					index |= ((pixel_indices_LSB >> shift) & 1);
-					shift++;
-					index=unscramble[index];
-
- 					r=RED_CHANNEL(img,width,x,y,channels)  =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- 					g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- 					b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
-				}
-			}
-		}
-		else
-		{
-			// We should flip
-			shift=2;
-			for(int x=startx; x<startx+4; x++)
-			{
-				for(int y=starty+2; y<starty+4; y++)
-				{
-					index  = ((pixel_indices_MSB >> shift) & 1) << 1;
-					index |= ((pixel_indices_LSB >> shift) & 1);
-					shift++;
-					index=unscramble[index];
-
- 					r=RED_CHANNEL(img,width,x,y,channels)  =CLAMP(0,avg_color[0]+compressParams[table][index],255);
- 					g=GREEN_CHANNEL(img,width,x,y,channels)=CLAMP(0,avg_color[1]+compressParams[table][index],255);
- 					b=BLUE_CHANNEL(img,width,x,y,channels) =CLAMP(0,avg_color[2]+compressParams[table][index],255);
-				}
-				shift += 2;
-			}
-		}
-	}
-}
-void decompressBlockDiffFlip(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty)
-{
-  decompressBlockDiffFlipC(block_part1, block_part2, img, width, height, startx, starty, 3);
-}
-
-// Decompress an ETC2 RGB block
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void decompressBlockETC2c(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty, int channels)
-{
-	int diffbit;
-	signed char color1[3];
-	signed char diff[3];
-	signed char red, green, blue;
-
-	diffbit = (GETBITSHIGH(block_part1, 1, 33));
-
-	if( diffbit )
-	{
-		// We have diffbit = 1;
-
-		// Base color
-		color1[0]= GETBITSHIGH(block_part1, 5, 63);
-		color1[1]= GETBITSHIGH(block_part1, 5, 55);
-		color1[2]= GETBITSHIGH(block_part1, 5, 47);
-
-		// Diff color
-		diff[0]= GETBITSHIGH(block_part1, 3, 58);
-		diff[1]= GETBITSHIGH(block_part1, 3, 50);
-		diff[2]= GETBITSHIGH(block_part1, 3, 42);
-
-		// Extend sign bit to entire byte. 
-		diff[0] = (diff[0] << 5);
-		diff[1] = (diff[1] << 5);
-		diff[2] = (diff[2] << 5);
-		diff[0] = diff[0] >> 5;
-		diff[1] = diff[1] >> 5;
-		diff[2] = diff[2] >> 5;
-
-		red   = color1[0] + diff[0];
-		green = color1[1] + diff[1];
-		blue  = color1[2] + diff[2];
-
-		if(red < 0 || red > 31)
-		{
-			unsigned int block59_part1, block59_part2;
-			unstuff59bits(block_part1, block_part2, block59_part1, block59_part2);
-			decompressBlockTHUMB59Tc(block59_part1, block59_part2, img, width, height, startx, starty, channels);
-		}
-		else if (green < 0 || green > 31)
-		{
-			unsigned int block58_part1, block58_part2;
-			unstuff58bits(block_part1, block_part2, block58_part1, block58_part2);
-			decompressBlockTHUMB58Hc(block58_part1, block58_part2, img, width, height, startx, starty, channels);
-		}
-		else if(blue < 0 || blue > 31)
-		{
-			unsigned int block57_part1, block57_part2;
-
-			unstuff57bits(block_part1, block_part2, block57_part1, block57_part2);
-			decompressBlockPlanar57c(block57_part1, block57_part2, img, width, height, startx, starty, channels);
-		}
-		else
-		{
- 			decompressBlockDiffFlipC(block_part1, block_part2, img, width, height, startx, starty, channels);
-		}
-	}
-	else
-	{
-		// We have diffbit = 0;
-		decompressBlockDiffFlipC(block_part1, block_part2, img, width, height, startx, starty, channels);
-	}
-}
-void decompressBlockETC2(unsigned int block_part1, unsigned int block_part2, uint8 *img, int width, int height, int startx, int starty)
-{
-  decompressBlockETC2c(block_part1, block_part2, img, width, height, startx, starty, 3);
-}
-// Decompress an ETC2 block with punchthrough alpha
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void decompressBlockDifferentialWithAlphaC(unsigned int block_part1, unsigned int block_part2, uint8* img, uint8* alpha, int width, int height, int startx, int starty, int channelsRGB)
-{
-	
-	uint8 avg_color[3], enc_color1[3], enc_color2[3];
-	signed char diff[3];
-	int table;
-	int index,shift;
-	int r,g,b;
-	int diffbit;
-	int flipbit;
-  int channelsA;
-
-  if(channelsRGB == 3)
-  {
-    // We will decode the alpha data to a separate memory area. 
-    channelsA = 1;
-  }
-  else
-  {
-    // We will decode the RGB data and the alpha data to the same memory area, 
-    // interleaved as RGBA. 
-    channelsA = 4;
-    alpha = &img[0+3];
-  }
-
-	//the diffbit now encodes whether or not the entire alpha channel is 255.
-	diffbit = (GETBITSHIGH(block_part1, 1, 33));
- 	flipbit = (GETBITSHIGH(block_part1, 1, 32));
-
-	// First decode left part of block.
-	enc_color1[0]= GETBITSHIGH(block_part1, 5, 63);
-	enc_color1[1]= GETBITSHIGH(block_part1, 5, 55);
-	enc_color1[2]= GETBITSHIGH(block_part1, 5, 47);
-
-	// Expand from 5 to 8 bits
-	avg_color[0] = (enc_color1[0] <<3) | (enc_color1[0] >> 2);
-	avg_color[1] = (enc_color1[1] <<3) | (enc_color1[1] >> 2);
-	avg_color[2] = (enc_color1[2] <<3) | (enc_color1[2] >> 2);
-
-	table = GETBITSHIGH(block_part1, 3, 39) << 1;
-
-	unsigned int pixel_indices_MSB, pixel_indices_LSB;
-		
-	pixel_indices_MSB = GETBITS(block_part2, 16, 31);
-	pixel_indices_LSB = GETBITS(block_part2, 16, 15);
-
-	if( (flipbit) == 0 )
-	{
-		// We should not flip
-		shift = 0;
-		for(int x=startx; x<startx+2; x++)
-		{
-			for(int y=starty; y<starty+4; y++)
-			{
-				index  = ((pixel_indices_MSB >> shift) & 1) << 1;
-				index |= ((pixel_indices_LSB >> shift) & 1);
-				shift++;
-				index=unscramble[index];
-
-				int mod = compressParams[table][index];
-				if(diffbit==0&&(index==1||index==2)) 
-				{
-					mod=0;
-				}
-				
-				r=RED_CHANNEL(img,width,x,y,channelsRGB)  =CLAMP(0,avg_color[0]+mod,255);
-				g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=CLAMP(0,avg_color[1]+mod,255);
-				b=BLUE_CHANNEL(img,width,x,y,channelsRGB) =CLAMP(0,avg_color[2]+mod,255);
-				if(diffbit==0&&index==1) 
-				{
-					alpha[(y*width+x)*channelsA]=0;
-					r=RED_CHANNEL(img,width,x,y,channelsRGB)=0;
-					g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=0;
-					b=BLUE_CHANNEL(img,width,x,y,channelsRGB)=0;
-				}
-				else 
-				{
-					alpha[(y*width+x)*channelsA]=255;
-				}
-
-			}
-		}
-	}
-	else
-	{
-		// We should flip
-		shift = 0;
-		for(int x=startx; x<startx+4; x++)
-		{
-			for(int y=starty; y<starty+2; y++)
-			{
-				index  = ((pixel_indices_MSB >> shift) & 1) << 1;
-				index |= ((pixel_indices_LSB >> shift) & 1);
-				shift++;
-				index=unscramble[index];
-				int mod = compressParams[table][index];
-				if(diffbit==0&&(index==1||index==2)) 
-				{
-					mod=0;
-				}
-				r=RED_CHANNEL(img,width,x,y,channelsRGB)  =CLAMP(0,avg_color[0]+mod,255);
-				g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=CLAMP(0,avg_color[1]+mod,255);
-				b=BLUE_CHANNEL(img,width,x,y,channelsRGB) =CLAMP(0,avg_color[2]+mod,255);
-				if(diffbit==0&&index==1) 
-				{
-					alpha[(y*width+x)*channelsA]=0;
-					r=RED_CHANNEL(img,width,x,y,channelsRGB)=0;
-					g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=0;
-					b=BLUE_CHANNEL(img,width,x,y,channelsRGB)=0;
-				}
-				else 
-				{
-					alpha[(y*width+x)*channelsA]=255;
-				}
-			}
-			shift+=2;
-		}
-	}
-	// Now decode right part of block. 
-	diff[0]= GETBITSHIGH(block_part1, 3, 58);
-	diff[1]= GETBITSHIGH(block_part1, 3, 50);
-	diff[2]= GETBITSHIGH(block_part1, 3, 42);
-
-	// Extend sign bit to entire byte. 
-	diff[0] = (diff[0] << 5);
-	diff[1] = (diff[1] << 5);
-	diff[2] = (diff[2] << 5);
-	diff[0] = diff[0] >> 5;
-	diff[1] = diff[1] >> 5;
-	diff[2] = diff[2] >> 5;
-
-	//  Calculate second color
-	enc_color2[0]= enc_color1[0] + diff[0];
-	enc_color2[1]= enc_color1[1] + diff[1];
-	enc_color2[2]= enc_color1[2] + diff[2];
-
-	// Expand from 5 to 8 bits
-	avg_color[0] = (enc_color2[0] <<3) | (enc_color2[0] >> 2);
-	avg_color[1] = (enc_color2[1] <<3) | (enc_color2[1] >> 2);
-	avg_color[2] = (enc_color2[2] <<3) | (enc_color2[2] >> 2);
-
-	table = GETBITSHIGH(block_part1, 3, 36) << 1;
-	pixel_indices_MSB = GETBITS(block_part2, 16, 31);
-	pixel_indices_LSB = GETBITS(block_part2, 16, 15);
-
-	if( (flipbit) == 0 )
-	{
-		// We should not flip
-		shift=8;
-		for(int x=startx+2; x<startx+4; x++)
-		{
-			for(int y=starty; y<starty+4; y++)
-			{
-				index  = ((pixel_indices_MSB >> shift) & 1) << 1;
-				index |= ((pixel_indices_LSB >> shift) & 1);
-				shift++;
-				index=unscramble[index];
-				int mod = compressParams[table][index];
-				if(diffbit==0&&(index==1||index==2)) 
-				{
-					mod=0;
-				}
-				
-				r=RED_CHANNEL(img,width,x,y,channelsRGB)  =CLAMP(0,avg_color[0]+mod,255);
-				g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=CLAMP(0,avg_color[1]+mod,255);
-				b=BLUE_CHANNEL(img,width,x,y,channelsRGB) =CLAMP(0,avg_color[2]+mod,255);
-				if(diffbit==0&&index==1) 
-				{
-					alpha[(y*width+x)*channelsA]=0;
-					r=RED_CHANNEL(img,width,x,y,channelsRGB)=0;
-					g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=0;
-					b=BLUE_CHANNEL(img,width,x,y,channelsRGB)=0;
-				}
-				else 
-				{
-					alpha[(y*width+x)*channelsA]=255;
-				}
-			}
-		}
-	}
-	else
-	{
-		// We should flip
-		shift=2;
-		for(int x=startx; x<startx+4; x++)
-		{
-			for(int y=starty+2; y<starty+4; y++)
-			{
-				index  = ((pixel_indices_MSB >> shift) & 1) << 1;
-				index |= ((pixel_indices_LSB >> shift) & 1);
-				shift++;
-				index=unscramble[index];
-				int mod = compressParams[table][index];
-				if(diffbit==0&&(index==1||index==2)) 
-				{
-					mod=0;
-				}
-				
-				r=RED_CHANNEL(img,width,x,y,channelsRGB)  =CLAMP(0,avg_color[0]+mod,255);
-				g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=CLAMP(0,avg_color[1]+mod,255);
-				b=BLUE_CHANNEL(img,width,x,y,channelsRGB) =CLAMP(0,avg_color[2]+mod,255);
-				if(diffbit==0&&index==1) 
-				{
-					alpha[(y*width+x)*channelsA]=0;
-					r=RED_CHANNEL(img,width,x,y,channelsRGB)=0;
-					g=GREEN_CHANNEL(img,width,x,y,channelsRGB)=0;
-					b=BLUE_CHANNEL(img,width,x,y,channelsRGB)=0;
-				}
-				else 
-				{
-					alpha[(y*width+x)*channelsA]=255;
-				}
-			}
-			shift += 2;
-		}
-	}
-}
-void decompressBlockDifferentialWithAlpha(unsigned int block_part1, unsigned int block_part2, uint8* img, uint8* alpha, int width, int height, int startx, int starty)
-{
-  decompressBlockDifferentialWithAlphaC(block_part1, block_part2, img, alpha, width, height, startx, starty, 3);
-}
-
-
-// similar to regular decompression, but alpha channel is set to 0 if pixel index is 2, otherwise 255.
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void decompressBlockTHUMB59TAlphaC(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alpha, int width, int height, int startx, int starty, int channelsRGB)
-{
-
-	uint8 colorsRGB444[2][3];
-	uint8 colors[2][3];
-	uint8 paint_colors[4][3];
-	uint8 distance;
-	uint8 block_mask[4][4];
-  int channelsA;
-
-  if(channelsRGB == 3)
-  {
-    // We will decode the alpha data to a separate memory area. 
-    channelsA = 1;
-  }
-  else
-  {
-    // We will decode the RGB data and the alpha data to the same memory area, 
-    // interleaved as RGBA. 
-    channelsA = 4;
-    alpha = &img[0+3];
-  }
-
-	// First decode left part of block.
-	colorsRGB444[0][R]= GETBITSHIGH(block_part1, 4, 58);
-	colorsRGB444[0][G]= GETBITSHIGH(block_part1, 4, 54);
-	colorsRGB444[0][B]= GETBITSHIGH(block_part1, 4, 50);
-
-	colorsRGB444[1][R]= GETBITSHIGH(block_part1, 4, 46);
-	colorsRGB444[1][G]= GETBITSHIGH(block_part1, 4, 42);
-	colorsRGB444[1][B]= GETBITSHIGH(block_part1, 4, 38);
-
-	distance   = GETBITSHIGH(block_part1, TABLE_BITS_59T, 34);
-
-	// Extend the two colors to RGB888	
-	decompressColor(R_BITS59T, G_BITS59T, B_BITS59T, colorsRGB444, colors);	
-	calculatePaintColors59T(distance, PATTERN_T, colors, paint_colors);
-	
-	// Choose one of the four paint colors for each texel
-	for (uint8 x = 0; x < BLOCKWIDTH; ++x) 
-	{
-		for (uint8 y = 0; y < BLOCKHEIGHT; ++y) 
-		{
-			//block_mask[x][y] = GETBITS(block_part2,2,31-(y*4+x)*2);
-			block_mask[x][y] = GETBITS(block_part2,1,(y+x*4)+16)<<1;
-			block_mask[x][y] |= GETBITS(block_part2,1,(y+x*4));
-			img[channelsRGB*((starty+y)*width+startx+x)+R] = 
-				CLAMP(0,paint_colors[block_mask[x][y]][R],255); // RED
-			img[channelsRGB*((starty+y)*width+startx+x)+G] =
-				CLAMP(0,paint_colors[block_mask[x][y]][G],255); // GREEN
-			img[channelsRGB*((starty+y)*width+startx+x)+B] =
-				CLAMP(0,paint_colors[block_mask[x][y]][B],255); // BLUE
-			if(block_mask[x][y]==2)  
-			{
-				alpha[channelsA*(x+startx+(y+starty)*width)]=0;
-				img[channelsRGB*((starty+y)*width+startx+x)+R] =0;
-				img[channelsRGB*((starty+y)*width+startx+x)+G] =0;
-				img[channelsRGB*((starty+y)*width+startx+x)+B] =0;
-			}
-			else
-				alpha[channelsA*(x+startx+(y+starty)*width)]=255;
-		}
-	}
-}
-void decompressBlockTHUMB59TAlpha(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alpha, int width, int height, int startx, int starty)
-{
-  decompressBlockTHUMB59TAlphaC(block_part1, block_part2, img, alpha, width, height, startx, starty, 3);
-}
-
-
-// Decompress an H-mode block with alpha
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void decompressBlockTHUMB58HAlphaC(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alpha, int width, int height, int startx, int starty, int channelsRGB)
-{
-	unsigned int col0, col1;
-	uint8 colors[2][3];
-	uint8 colorsRGB444[2][3];
-	uint8 paint_colors[4][3];
-	uint8 distance;
-	uint8 block_mask[4][4];
-  int channelsA;	
-
-  if(channelsRGB == 3)
-  {
-    // We will decode the alpha data to a separate memory area. 
-    channelsA = 1;
-  }
-  else
-  {
-    // We will decode the RGB data and the alpha data to the same memory area, 
-    // interleaved as RGBA. 
-    channelsA = 4;
-    alpha = &img[0+3];
-  }
-
-	// First decode left part of block.
-	colorsRGB444[0][R]= GETBITSHIGH(block_part1, 4, 57);
-	colorsRGB444[0][G]= GETBITSHIGH(block_part1, 4, 53);
-	colorsRGB444[0][B]= GETBITSHIGH(block_part1, 4, 49);
-
-	colorsRGB444[1][R]= GETBITSHIGH(block_part1, 4, 45);
-	colorsRGB444[1][G]= GETBITSHIGH(block_part1, 4, 41);
-	colorsRGB444[1][B]= GETBITSHIGH(block_part1, 4, 37);
-
-  distance = 0;
-	distance = (GETBITSHIGH(block_part1, 2, 33)) << 1;
-
-	col0 = GETBITSHIGH(block_part1, 12, 57);
-	col1 = GETBITSHIGH(block_part1, 12, 45);
-
-	if(col0 >= col1)
-	{
-		distance |= 1;
-	}
-
-	// Extend the two colors to RGB888	
-	decompressColor(R_BITS58H, G_BITS58H, B_BITS58H, colorsRGB444, colors);	
-	
-	calculatePaintColors58H(distance, PATTERN_H, colors, paint_colors);
-	
-	// Choose one of the four paint colors for each texel
-	for (uint8 x = 0; x < BLOCKWIDTH; ++x) 
-	{
-		for (uint8 y = 0; y < BLOCKHEIGHT; ++y) 
-		{
-			//block_mask[x][y] = GETBITS(block_part2,2,31-(y*4+x)*2);
-			block_mask[x][y] = GETBITS(block_part2,1,(y+x*4)+16)<<1;
-			block_mask[x][y] |= GETBITS(block_part2,1,(y+x*4));
-			img[channelsRGB*((starty+y)*width+startx+x)+R] =
-				CLAMP(0,paint_colors[block_mask[x][y]][R],255); // RED
-			img[channelsRGB*((starty+y)*width+startx+x)+G] =
-				CLAMP(0,paint_colors[block_mask[x][y]][G],255); // GREEN
-			img[channelsRGB*((starty+y)*width+startx+x)+B] =
-				CLAMP(0,paint_colors[block_mask[x][y]][B],255); // BLUE
-			
-			if(block_mask[x][y]==2)  
-			{
-				alpha[channelsA*(x+startx+(y+starty)*width)]=0;
-				img[channelsRGB*((starty+y)*width+startx+x)+R] =0;
-				img[channelsRGB*((starty+y)*width+startx+x)+G] =0;
-				img[channelsRGB*((starty+y)*width+startx+x)+B] =0;
-			}
-			else
-				alpha[channelsA*(x+startx+(y+starty)*width)]=255;
-		}
-	}
-}
-void decompressBlockTHUMB58HAlpha(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alpha, int width, int height, int startx, int starty)
-{
-  decompressBlockTHUMB58HAlphaC(block_part1, block_part2, img, alpha, width, height, startx, starty, 3);
-}
-// Decompression function for ETC2_RGBA1 format.
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void decompressBlockETC21BitAlphaC(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alphaimg, int width, int height, int startx, int starty, int channelsRGB)
-{
-	int diffbit;
-	signed char color1[3];
-	signed char diff[3];
-	signed char red, green, blue;
-  int channelsA;	
-
-  if(channelsRGB == 3)
-  {
-    // We will decode the alpha data to a separate memory area. 
-    channelsA = 1;
-  }
-  else
-  {
-    // We will decode the RGB data and the alpha data to the same memory area, 
-    // interleaved as RGBA. 
-    channelsA = 4;
-    alphaimg = &img[0+3];
-  }
-
-	diffbit = (GETBITSHIGH(block_part1, 1, 33));
-
-	if( diffbit )
-	{
-		// We have diffbit = 1, meaning no transparent pixels. regular decompression.
-
-		// Base color
-		color1[0]= GETBITSHIGH(block_part1, 5, 63);
-		color1[1]= GETBITSHIGH(block_part1, 5, 55);
-		color1[2]= GETBITSHIGH(block_part1, 5, 47);
-
-		// Diff color
-		diff[0]= GETBITSHIGH(block_part1, 3, 58);
-		diff[1]= GETBITSHIGH(block_part1, 3, 50);
-		diff[2]= GETBITSHIGH(block_part1, 3, 42);
-
-		// Extend sign bit to entire byte. 
-		diff[0] = (diff[0] << 5);
-		diff[1] = (diff[1] << 5);
-		diff[2] = (diff[2] << 5);
-		diff[0] = diff[0] >> 5;
-		diff[1] = diff[1] >> 5;
-		diff[2] = diff[2] >> 5;
-
-		red   = color1[0] + diff[0];
-		green = color1[1] + diff[1];
-		blue  = color1[2] + diff[2];
-
-		if(red < 0 || red > 31)
-		{
-			unsigned int block59_part1, block59_part2;
-			unstuff59bits(block_part1, block_part2, block59_part1, block59_part2);
-			decompressBlockTHUMB59Tc(block59_part1, block59_part2, img, width, height, startx, starty, channelsRGB);
-		}
-		else if (green < 0 || green > 31)
-		{
-			unsigned int block58_part1, block58_part2;
-			unstuff58bits(block_part1, block_part2, block58_part1, block58_part2);
-			decompressBlockTHUMB58Hc(block58_part1, block58_part2, img, width, height, startx, starty, channelsRGB);
-		}
-		else if(blue < 0 || blue > 31)
-		{
-			unsigned int block57_part1, block57_part2;
-
-			unstuff57bits(block_part1, block_part2, block57_part1, block57_part2);
-			decompressBlockPlanar57c(block57_part1, block57_part2, img, width, height, startx, starty, channelsRGB);
-		}
-		else
-		{
- 			decompressBlockDifferentialWithAlphaC(block_part1, block_part2, img, alphaimg, width, height, startx, starty, channelsRGB);
-		}
-		for(int x=startx; x<startx+4; x++) 
-		{
-			for(int y=starty; y<starty+4; y++) 
-			{
-				alphaimg[channelsA*(x+y*width)]=255;
-			}
-		}
-	}
-	else
-	{
-		// We have diffbit = 0, transparent pixels. Only T-, H- or regular diff-mode possible.
-		
-		// Base color
-		color1[0]= GETBITSHIGH(block_part1, 5, 63);
-		color1[1]= GETBITSHIGH(block_part1, 5, 55);
-		color1[2]= GETBITSHIGH(block_part1, 5, 47);
-
-		// Diff color
-		diff[0]= GETBITSHIGH(block_part1, 3, 58);
-		diff[1]= GETBITSHIGH(block_part1, 3, 50);
-		diff[2]= GETBITSHIGH(block_part1, 3, 42);
-
-		// Extend sign bit to entire byte. 
-		diff[0] = (diff[0] << 5);
-		diff[1] = (diff[1] << 5);
-		diff[2] = (diff[2] << 5);
-		diff[0] = diff[0] >> 5;
-		diff[1] = diff[1] >> 5;
-		diff[2] = diff[2] >> 5;
-
-		red   = color1[0] + diff[0];
-		green = color1[1] + diff[1];
-		blue  = color1[2] + diff[2];
-		if(red < 0 || red > 31)
-		{
-			unsigned int block59_part1, block59_part2;
-			unstuff59bits(block_part1, block_part2, block59_part1, block59_part2);
-			decompressBlockTHUMB59TAlphaC(block59_part1, block59_part2, img, alphaimg, width, height, startx, starty, channelsRGB);
-		}
-		else if(green < 0 || green > 31) 
-		{
-			unsigned int block58_part1, block58_part2;
-			unstuff58bits(block_part1, block_part2, block58_part1, block58_part2);
-			decompressBlockTHUMB58HAlphaC(block58_part1, block58_part2, img, alphaimg, width, height, startx, starty, channelsRGB);
-		}
-		else if(blue < 0 || blue > 31)
-		{
-			unsigned int block57_part1, block57_part2;
-
-			unstuff57bits(block_part1, block_part2, block57_part1, block57_part2);
-			decompressBlockPlanar57c(block57_part1, block57_part2, img, width, height, startx, starty, channelsRGB);
-			for(int x=startx; x<startx+4; x++) 
-			{
-				for(int y=starty; y<starty+4; y++) 
-				{
-					alphaimg[channelsA*(x+y*width)]=255;
-				}
-			}
-		}
-		else
-			decompressBlockDifferentialWithAlphaC(block_part1, block_part2, img,alphaimg, width, height, startx, starty, channelsRGB);
-	}
-}
-void decompressBlockETC21BitAlpha(unsigned int block_part1, unsigned int block_part2, uint8 *img, uint8* alphaimg, int width, int height, int startx, int starty)
-{
-  decompressBlockETC21BitAlphaC(block_part1, block_part2, img, alphaimg, width, height, startx, starty, 3);
-}
-//
-//	Utility functions used for alpha compression
-//
-
-// bit number frompos is extracted from input, and moved to bit number topos in the return value.
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-uint8 getbit(uint8 input, int frompos, int topos) 
-{
-	if(frompos>topos)
-		return ((1<<frompos)&input)>>(frompos-topos);
-	return ((1<<frompos)&input)<<(topos-frompos);
-}
-
-// takes as input a value, returns the value clamped to the interval [0,255].
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-int clamp(int val) 
-{
-	if(val<0)
-		val=0;
-	if(val>255)
-		val=255;
-	return val;
-}
-
-// Decodes tha alpha component in a block coded with GL_COMPRESSED_RGBA8_ETC2_EAC.
-// Note that this decoding is slightly different from that of GL_COMPRESSED_R11_EAC.
-// However, a hardware decoder can share gates between the two formats as explained
-// in the specification under GL_COMPRESSED_R11_EAC.
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void decompressBlockAlphaC(uint8* data, uint8* img, int width, int height, int ix, int iy, int channels) 
-{
-	int alpha = data[0];
-	int table = data[1];
-	
-	int bit=0;
-	int byte=2;
-	//extract an alpha value for each pixel.
-	for(int x=0; x<4; x++) 
-	{
-		for(int y=0; y<4; y++) 
-		{
-			//Extract table index
-			int index=0;
-			for(int bitpos=0; bitpos<3; bitpos++) 
-			{
-				index|=getbit(data[byte],7-bit,2-bitpos);
-				bit++;
-				if(bit>7) 
-				{
-					bit=0;
-					byte++;
-				}
-			}
-			img[(ix+x+(iy+y)*width)*channels]=clamp(alpha +alphaTable[table][index]);
-		}
-	}
-}
-void decompressBlockAlpha(uint8* data, uint8* img, int width, int height, int ix, int iy) 
-{
-  decompressBlockAlphaC(data, img, width, height, ix, iy, 1);
-}
-
-// Does decompression and then immediately converts from 11 bit signed to a 16-bit format.
-// 
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-int16 get16bits11signed(int base, int table, int mul, int index) 
-{
-	int elevenbase = base-128;
-	if(elevenbase==-128)
-		elevenbase=-127;
-	elevenbase*=8;
-	//i want the positive value here
-	int tabVal = -alphaBase[table][3-index%4]-1;
-	//and the sign, please
-	int sign = 1-(index/4);
-	
-	if(sign)
-		tabVal=tabVal+1;
-	int elevenTabVal = tabVal*8;
-
-	if(mul!=0)
-		elevenTabVal*=mul;
-	else
-		elevenTabVal/=8;
-
-	if(sign)
-		elevenTabVal=-elevenTabVal;
-
-	//calculate sum
-	int elevenbits = elevenbase+elevenTabVal;
-
-	//clamp..
-	if(elevenbits>=1024)
-		elevenbits=1023;
-	else if(elevenbits<-1023)
-		elevenbits=-1023;
-	//this is the value we would actually output.. 
-	//but there aren't any good 11-bit file or uncompressed GL formats
-	//so we extend to 15 bits signed.
-	sign = elevenbits<0;
-	elevenbits=abs(elevenbits);
-	int16 fifteenbits = (elevenbits<<5)+(elevenbits>>5);
-	int16 sixteenbits=fifteenbits;
-
-	if(sign)
-		sixteenbits=-sixteenbits;
-	
-	return sixteenbits;
-}
-
-// Does decompression and then immediately converts from 11 bit signed to a 16-bit format 
-// Calculates the 11 bit value represented by base, table, mul and index, and extends it to 16 bits.
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-uint16 get16bits11bits(int base, int table, int mul, int index) 
-{
-	int elevenbase = base*8+4;
-
-	//i want the positive value here
-	int tabVal = -alphaBase[table][3-index%4]-1;
-	//and the sign, please
-	int sign = 1-(index/4);
-	
-	if(sign)
-		tabVal=tabVal+1;
-	int elevenTabVal = tabVal*8;
-
-	if(mul!=0)
-		elevenTabVal*=mul;
-	else
-		elevenTabVal/=8;
-
-	if(sign)
-		elevenTabVal=-elevenTabVal;
-
-	//calculate sum
-	int elevenbits = elevenbase+elevenTabVal;
-
-	//clamp..
-	if(elevenbits>=256*8)
-		elevenbits=256*8-1;
-	else if(elevenbits<0)
-		elevenbits=0;
-	//elevenbits now contains the 11 bit alpha value as defined in the spec.
-
-	//extend to 16 bits before returning, since we don't have any good 11-bit file formats.
-	uint16 sixteenbits = (elevenbits<<5)+(elevenbits>>6);
-
-	return sixteenbits;
-}
-
-// Decompresses a block using one of the GL_COMPRESSED_R11_EAC or GL_COMPRESSED_SIGNED_R11_EAC-formats
-// NO WARRANTY --- SEE STATEMENT IN TOP OF FILE (C) Ericsson AB 2013. All Rights Reserved.
-void decompressBlockAlpha16bitC(uint8* data, uint8* img, int width, int height, int ix, int iy, int channels) 
-{
-	int alpha = data[0];
-	int table = data[1];
-
-	if(formatSigned) 
-	{
-		//if we have a signed format, the base value is given as a signed byte. We convert it to (0-255) here,
-		//so more code can be shared with the unsigned mode.
-		alpha = *((signed char*)(&data[0]));
-		alpha = alpha+128;
-	}
-
-	int bit=0;
-	int byte=2;
-	//extract an alpha value for each pixel.
-	for(int x=0; x<4; x++) 
-	{
-		for(int y=0; y<4; y++) 
-		{
-			//Extract table index
-			int index=0;
-			for(int bitpos=0; bitpos<3; bitpos++) 
-			{
-				index|=getbit(data[byte],7-bit,2-bitpos);
-				bit++;
-				if(bit>7) 
-				{
-					bit=0;
-					byte++;
-				}
-			}
-			int windex = channels*(2*(ix+x+(iy+y)*width));
-#if !PGMOUT
-			if(formatSigned)
-			{
-				*(int16 *)&img[windex] = get16bits11signed(alpha,(table%16),(table/16),index);
-			}
-			else
-			{
-				*(uint16 *)&img[windex] = get16bits11bits(alpha,(table%16),(table/16),index);
-			}
-#else
-			//make data compatible with the .pgm format. See the comment in compressBlockAlpha16() for details.
-			uint16 uSixteen;
-			if (formatSigned)
-			{
-				//the pgm-format only allows unsigned images,
-				//so we add 2^15 to get a 16-bit value.
-				uSixteen = get16bits11signed(alpha,(table%16),(table/16),index) + 256*128;
-			}
-			else
-			{
-				uSixteen = get16bits11bits(alpha,(table%16),(table/16),index);
-			}
-			//byte swap for pgm
-			img[windex] = uSixteen/256;
-			img[windex+1] = uSixteen%256;
-#endif
-
-		}
-	}			
-}
-
-void decompressBlockAlpha16bit(uint8* data, uint8* img, int width, int height, int ix, int iy)
-{
-  decompressBlockAlpha16bitC(data, img, width, height, ix, iy, 1);
-}
diff --git a/external/KTX-Software-master/lib/etcunpack.cxx b/external/KTX-Software-master/lib/etcunpack.cxx
deleted file mode 100644
index 85d0c510d15564c509753d97647d9271f6ce9102..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/etcunpack.cxx
+++ /dev/null
@@ -1,288 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4: */
-
-/* $Id: 764e83ee5c8febe3233114f9ebe9a9ef21d120f1 $ */
-
-/*
- * ©2010 The khronos Group, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* @internal
- * @~English
- * @file
- *
- * Unpack a texture compressed with ETC1
- *
- * @author Mark Callow, HI Corporation.
- */
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include "GL/glcorearb.h"
-// Not defined in glcorearb.h.
-#define GL_ETC1_RGB8_OES                0x8D64
-#include "ktx.h"
-#include "ktxint.h"
-
-#if SUPPORT_SOFTWARE_ETC_UNPACK
-typedef unsigned int uint;
-typedef unsigned char uint8;
-
-extern void decompressBlockETC2c(uint block_part1, uint block_part2, uint8* img,
-								 int width, int height, int startx, int starty, int channels);
-extern void decompressBlockETC21BitAlphaC(uint block_part1, uint block_part2, uint8* img, uint8* alphaimg,
-										  int width, int height, int startx, int starty, int channels);
-extern void decompressBlockAlphaC(uint8* data, uint8* img,
-								  int width, int height, int startx, int starty, int channels);
-extern void decompressBlockAlpha16bitC(uint8* data, uint8* img,
-									   int width, int height, int startx, int starty, int channels);
-
-extern void setupAlphaTable();
-
-// This global variable affects the behaviour of decompressBlockAlpha16bitC.
-extern int formatSigned;
-
-static void
-readBigEndian4byteWord(ktx_uint32_t* pBlock, const GLubyte *s)
-{
-	*pBlock = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
-}
-
-
-/* Unpack an ETC1_RGB8_OES format compressed texture */
-extern "C" KTX_error_code
-_ktxUnpackETC(const GLubyte* srcETC, const GLenum srcFormat,
-			  ktx_uint32_t activeWidth, ktx_uint32_t activeHeight,
-			  GLubyte** dstImage,
-			  GLenum* format, GLenum* internalFormat, GLenum* type,
-			  GLint R16Formats, GLboolean supportsSRGB)
-{
-	unsigned int width, height;
-	unsigned int block_part1, block_part2;
-	unsigned int x, y;
-	/*const*/ GLubyte* src = (GLubyte*)srcETC;
-	// AF_11BIT is used to compress R11 & RG11 though its not alpha data.
-	enum {AF_NONE, AF_1BIT, AF_8BIT, AF_11BIT} alphaFormat = AF_NONE;
-	int dstChannels, dstChannelBytes;
-
-	switch (srcFormat) {
-	  case GL_COMPRESSED_SIGNED_R11_EAC:
-		if (R16Formats & _KTX_R16_FORMATS_SNORM) {
-			dstChannelBytes = sizeof(GLshort);
-			dstChannels = 1;
-			formatSigned = GL_TRUE;
-			*internalFormat = GL_R16_SNORM;
-			*format = GL_RED;
-			*type = GL_SHORT;
-			alphaFormat = AF_11BIT;
-		} else
-			return KTX_UNSUPPORTED_TEXTURE_TYPE; 
-		break;
-
-	  case GL_COMPRESSED_R11_EAC:
-		if (R16Formats & _KTX_R16_FORMATS_NORM) {
-			dstChannelBytes = sizeof(GLshort);
-			dstChannels = 1;
-			formatSigned = GL_FALSE;
-			*internalFormat = GL_R16;
-			*format = GL_RED;
-			*type = GL_UNSIGNED_SHORT;
-			alphaFormat = AF_11BIT;
-		} else
-			return KTX_UNSUPPORTED_TEXTURE_TYPE; 
-        break;
-
-	  case GL_COMPRESSED_SIGNED_RG11_EAC:
-		if (R16Formats & _KTX_R16_FORMATS_SNORM) {
-			dstChannelBytes = sizeof(GLshort);
-			dstChannels = 2;
-			formatSigned = GL_TRUE;
-			*internalFormat = GL_RG16_SNORM;
-			*format = GL_RG;
-			*type = GL_SHORT;
-			alphaFormat = AF_11BIT;
-		} else
-			return KTX_UNSUPPORTED_TEXTURE_TYPE; 
-        break;
-
-	  case GL_COMPRESSED_RG11_EAC:
-		if (R16Formats & _KTX_R16_FORMATS_NORM) {
-			dstChannelBytes = sizeof(GLshort);
-			dstChannels = 2;
-			formatSigned = GL_FALSE;
-			*internalFormat = GL_RG16;
-			*format = GL_RG;
-			*type = GL_UNSIGNED_SHORT;
-			alphaFormat = AF_11BIT;
-		} else
-			return KTX_UNSUPPORTED_TEXTURE_TYPE; 
-        break;
-
-	  case GL_ETC1_RGB8_OES:
-	  case GL_COMPRESSED_RGB8_ETC2:
-	    dstChannelBytes = sizeof(GLubyte);
-		dstChannels = 3;
-		*internalFormat = GL_RGB8;
-		*format = GL_RGB;
-		*type = GL_UNSIGNED_BYTE;
-        break;
-
-	  case GL_COMPRESSED_RGBA8_ETC2_EAC:
-	    dstChannelBytes = sizeof(GLubyte);
-		dstChannels = 4;
-		*internalFormat = GL_RGBA8;
-		*format = GL_RGBA;
-		*type = GL_UNSIGNED_BYTE;
-	    alphaFormat = AF_8BIT;
-		break;
-
-	  case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-	    dstChannelBytes = sizeof(GLubyte);
-		dstChannels = 4;
-		*internalFormat = GL_RGBA8;
-		*format = GL_RGBA;
-		*type = GL_UNSIGNED_BYTE;
-		alphaFormat = AF_1BIT;
-        break;
-
-	  case GL_COMPRESSED_SRGB8_ETC2:
-		if (supportsSRGB) {
-			dstChannelBytes = sizeof(GLubyte);
-			dstChannels = 3;
-			*internalFormat = GL_SRGB8;
-			*format = GL_RGB;
-			*type = GL_UNSIGNED_BYTE;
-		} else
-			return KTX_UNSUPPORTED_TEXTURE_TYPE; 
-        break;
-
-	  case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
-		if (supportsSRGB) {
-			dstChannelBytes = sizeof(GLubyte);
-			dstChannels = 4;
-			*internalFormat = GL_SRGB8_ALPHA8;
- 			*format = GL_RGBA;
-			*type = GL_UNSIGNED_BYTE;
-			alphaFormat = AF_8BIT;
-		} else
-			return KTX_UNSUPPORTED_TEXTURE_TYPE; 
-		break;
-
-	  case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-		if (supportsSRGB) {
-			dstChannelBytes = sizeof(GLubyte);
-			dstChannels = 4;
-			*internalFormat = GL_SRGB8_ALPHA8;
- 			*format = GL_RGBA;
-			*type = GL_UNSIGNED_BYTE;
-			alphaFormat = AF_1BIT;
-		} else
-			return KTX_UNSUPPORTED_TEXTURE_TYPE; 
-        break;
-
-	  default:
-	    assert(0); // Upper levels should pass only one of the above srcFormats.
-        return KTX_UNSUPPORTED_TEXTURE_TYPE; // For Release configurations.
-	}
-
-    /* active_{width,height} show how many pixels contain active data,
-	 * (the rest are just for making sure we have a 2*a x 4*b size).
-	 */
-
-	/* Compute the full width & height. */
-	width = ((activeWidth+3)/4)*4;
-	height = ((activeHeight+3)/4)*4;
-
-	/* printf("Width = %d, Height = %d\n", width, height); */
-	/* printf("active pixel area: top left %d x %d area.\n", activeWidth, activeHeight); */
-
-	*dstImage = (GLubyte*)malloc(dstChannels*dstChannelBytes*width*height);
-	if (!*dstImage) {
-		return KTX_OUT_OF_MEMORY;
-	}
-	
-	if (alphaFormat != AF_NONE)
-		setupAlphaTable();
-
-	// NOTE: none of the decompress functions actually use the <height> parameter
-	if (alphaFormat == AF_11BIT) {
-		// One or two 11-bit alpha channels for R or RG.
-		for (y=0; y < height/4; y++) {
-			for (x=0; x < width/4; x++) {
-				decompressBlockAlpha16bitC(src, *dstImage, width, height, 4*x, 4*y, dstChannels);
-				src += 8;
-				if (srcFormat == GL_COMPRESSED_RG11_EAC || srcFormat == GL_COMPRESSED_SIGNED_RG11_EAC) {
-					decompressBlockAlpha16bitC(src, *dstImage + dstChannelBytes, width, height, 4*x, 4*y, dstChannels);
-					src += 8;
-				}
-			}
-		}
-	} else {
-		for (y=0; y < height/4; y++) {
-			for (x=0; x < width/4; x++) {
-				// Decode alpha channel for RGBA
-				if (alphaFormat == AF_8BIT) {
-					decompressBlockAlphaC(src, *dstImage + 3, width, height, 4*x, 4*y, dstChannels);
-					src += 8;
-				}
-				// Decode color dstChannels
-				readBigEndian4byteWord(&block_part1, src);
-				src += 4;
-				readBigEndian4byteWord(&block_part2, src);
-				src += 4;
-				if (alphaFormat == AF_1BIT)
-				    decompressBlockETC21BitAlphaC(block_part1, block_part2, *dstImage, 0, width, height, 4*x, 4*y, dstChannels);
-				else
-				    decompressBlockETC2c(block_part1, block_part2, *dstImage, width, height, 4*x, 4*y, dstChannels);
-			}
-		}
-	}
-
-	/* Ok, now write out the active pixels to the destination image.
-	 * (But only if the active pixels differ from the total pixels)
-	 */
-
-	if( !(height == activeHeight && width == activeWidth) ) {
-		int dstPixelBytes = dstChannels * dstChannelBytes;
-		int dstRowBytes = dstPixelBytes * width;
-		int activeRowBytes = activeWidth * dstPixelBytes;
-		GLubyte *newimg = (GLubyte*)malloc(dstPixelBytes * activeWidth * activeHeight);
-		unsigned int xx, yy;
-		int zz;
-
-		if (!newimg) {
-			free(*dstImage);
-			return KTX_OUT_OF_MEMORY;
-		}
-		
-		/* Convert from total area to active area: */
-
-		for (yy = 0; yy < activeHeight; yy++) {
-			for (xx = 0; xx < activeWidth; xx++) {
-				for (zz = 0; zz < dstPixelBytes; zz++) {
-					newimg[ yy*activeRowBytes + xx*dstPixelBytes + zz ] = (*dstImage)[ yy*dstRowBytes + xx*dstPixelBytes + zz];
-				}
-			}
-		}
-
-		free(*dstImage);
-		*dstImage = newimg;
-	}
-
-	return KTX_SUCCESS;
-}
-
-#endif /* SUPPORT_SOFTWARE_ETC_UNPACK */
diff --git a/external/KTX-Software-master/lib/filestream.c b/external/KTX-Software-master/lib/filestream.c
deleted file mode 100644
index dd6d09bc44566c25f60f02e831fee48f6c7b20bf..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/filestream.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/*
- * ©2010-2018 The khronos Group, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file
- * @~English
- *
- * @brief Implementation of ktxStream for FILE.
- *
- * @author Maksim Kolesin, Under Development
- * @author Georg Kolling, Imagination Technology
- * @author Mark Callow, HI Corporation
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-/* I need these on Linux. Why? */
-#define __USE_LARGEFILE 1  // For declaration of ftello, etc.
-#define __USE_POSIX 1      // For declaration of fileno.
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-
-#include "ktx.h"
-#include "ktxint.h"
-#include "filestream.h"
-
-#if defined(_MSC_VER)
-  #if defined(_WIN64)
-    #define ftello _ftelli64
-    #define fseeko _fseeki64
-  #else
-    #define ftello ftell
-    #define fseeko fseek
-  #endif
-  #define fileno _fileno
-#endif
-
-#define KTX_FILE_STREAM_MAX (1 << (sizeof(ktx_off_t) - 1) - 1)
-
-/**
- * @internal
- * @~English
- * @brief Read bytes from a ktxFileStream.
- *
- * @param [in]  str     pointer to the ktxStream from which to read.
- * @param [out] dst     pointer to a block of memory with a size
- *                      of at least @p size bytes, converted to a void*.
- * @param [in,out] count   pointer to total count of bytes to be read.
- *                         On completion set to number of bytes read.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p dst is @c NULL or @p src is @c NULL.
- * @exception KTX_FILE_UNEXPECTED_EOF not enough data to satisfy the request.
- */
-static
-KTX_error_code ktxFileStream_read(ktxStream* str, void* dst, const ktx_size_t count)
-{
-    ktx_size_t nread;
-
-    if (!str || !dst)
-        return KTX_INVALID_VALUE;
-
-    assert(str->type == eStreamTypeFile);
-    
-    if ((nread = fread(dst, 1, count, str->data.file)) != count) {
-        if (feof(str->data.file)) {
-            return KTX_FILE_UNEXPECTED_EOF;
-        } else
-            return KTX_FILE_READ_ERROR;
-    }
-
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Skip bytes in a ktxFileStream.
- *
- * @param [in] str           pointer to a ktxStream object.
- * @param [in] count         number of bytes to be skipped.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p str is @c NULL or @p count is less than zero.
- * @exception KTX_INVALID_OPERATION skipping @p count bytes would go beyond EOF.
- * @exception KTX_FILE_UNEXPECTED_EOF not enough data to satisfy the request.
- *                                    @p count is set to the number of bytes
- *                                    skipped.
- */
-static
-KTX_error_code ktxFileStream_skip(ktxStream* str, const ktx_size_t count)
-{
-    ktx_size_t fileSize;
-    ktx_off_t pos, newpos;
-
-    if (!str)
-        return KTX_INVALID_VALUE;
-
-    assert(str->type == eStreamTypeFile);
-    
-    str->getsize(str, &fileSize);
-    str->getpos(str, &pos);
-
-    newpos = pos + count;
-    /* First clause checks for overflow. */
-    if (newpos < pos || pos + count > fileSize)
-        return KTX_FILE_UNEXPECTED_EOF;
-
-    if (fseeko(str->data.file, count, SEEK_CUR) != 0)
-        return KTX_FILE_SEEK_ERROR;
-
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Write bytes to a ktxFileStream.
- *
- * @param [in] str      pointer to the ktxStream that is the destination of the
- *                      write.
- * @param [in] src      pointer to the array of elements to be written,
- *                      converted to a const void*.
- * @param [in] size     size in bytes of each element to be written.
- * @param [in] count    number of elements, each one with a @p size of size
- *                      bytes.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p str is @c NULL or @p src is @c NULL.
- * @exception KTX_FILE_OVERFLOW the requested write would caused the file to
- *                              exceed the maximum supported file size.
- * @exception KTX_FILE_WRITE_ERROR a system error occurred while writing the
- *                                 file.
- */
-static
-KTX_error_code ktxFileStream_write(ktxStream* str, const void *src,
-                                   const ktx_size_t size,
-                                   const ktx_size_t count)
-{
-    if (!str || !src)
-        return KTX_INVALID_VALUE;
-
-    assert(str->type == eStreamTypeFile);
-    
-    if (fwrite(src, size, count, str->data.file) != count) {
-        if (errno == EFBIG || errno == EOVERFLOW)
-            return KTX_FILE_OVERFLOW;
-        else
-            return KTX_FILE_WRITE_ERROR;
-    }
-
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Get the current read/write position in a ktxFileStream.
- *
- * @param [in] str      pointer to the ktxStream to query.
- * @param [in,out] off  pointer to variable to receive the offset value.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p str or @p pos is @c NULL.
- */
-static
-KTX_error_code ktxFileStream_getpos(ktxStream* str, ktx_off_t* pos)
-{
-    if (!str || !pos)
-        return KTX_INVALID_VALUE;
-    
-    assert(str->type == eStreamTypeFile);
-
-    /* The cast quiets an Xcode warning when building for "Generic iOS Device".
-     * For some reason, even when ARCHS is arm64, size_t is only a long. */
-    *pos = (ktx_off_t)ftello(str->data.file);
-    
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Set the current read/write position in a ktxFileStream.
- *
- * Offset of 0 is the start of the file. This function operates
- * like Linux > 3.1's @c lseek() when it is passed a @c whence
- * of @c SEEK_DATA is it returns and error if the seek would
- * go beyond the end of the file.
- *
- * @param [in] str    pointer to the ktxStream whose r/w position is to be set.
- * @param [in] off    pointer to the offset value to set.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p str is @c NULL.
- * @exception KTX_INVALID_OPERATION @p pos is > the size of the file or an
- *                                  fseek error occurred.
- */
-static
-KTX_error_code ktxFileStream_setpos(ktxStream* str, ktx_off_t pos)
-{
-    ktx_size_t fileSize;
-    
-    if (!str)
-        return KTX_INVALID_VALUE;
-
-    assert(str->type == eStreamTypeFile);
-    
-    str->getsize(str, &fileSize);
-    if (pos > fileSize)
-        return KTX_INVALID_OPERATION;
-
-    if (fseeko(str->data.file, pos, SEEK_SET) < 0)
-        return KTX_FILE_SEEK_ERROR;
-    
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Get the size of a ktxFileStream in bytes.
- *
- * @param [in] str       pointer to the ktxStream whose size is to be queried.
- * @param [in,out] size  pointer to a variable in which size will be written.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p str or @p size is @c NULL.
- * @exception KTX_FILE_WRITE_ERROR a system error occurred while getting the
- *                                 size.
- */
-static
-KTX_error_code ktxFileStream_getsize(ktxStream* str, ktx_size_t* size)
-{
-    struct stat statbuf;
-
-    if (!str || !size)
-        return KTX_INVALID_VALUE;
-    
-    assert(str->type == eStreamTypeFile);
- 
-    if (fstat(fileno(str->data.file), &statbuf) < 0)
-        return KTX_FILE_READ_ERROR;
-    *size = (ktx_size_t)statbuf.st_size; /* See _getpos for why this cast. */
-    
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Initialize a ktxFileStream.
- *
- * @param [in] str      pointer to the ktxStream to initialize.
- * @param [in] file     pointer to the underlying FILE object.
- *
- * @return      KTX_SUCCESS on success, KTX_INVALID_VALUE on error.
- *
- * @exception KTX_INVALID_VALUE @p stream is @c NULL or @p file is @c NULL.
- */
-KTX_error_code ktxFileStream_construct(ktxStream* str, FILE* file,
-                                       ktx_bool_t closeFileOnDestruct)
-{
-    if (!str || !file)
-        return KTX_INVALID_VALUE;
-
-    str->data.file = file;
-    str->type = eStreamTypeFile;
-    str->read = ktxFileStream_read;
-    str->skip = ktxFileStream_skip;
-    str->write = ktxFileStream_write;
-    str->getpos = ktxFileStream_getpos;
-    str->setpos = ktxFileStream_setpos;
-    str->getsize = ktxFileStream_getsize;
-    str->destruct = ktxFileStream_destruct;
-    str->closeOnDestruct = closeFileOnDestruct;
-
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Destruct the stream, potentially closing the underlying FILE.
- *
- * This only closes the underyling FILE if the @c closeOnDestruct parameter to
- * ktxFileStream_construct() was not @c KTX_FALSE.
- *
- * @param [in] str pointer to the ktxStream whose FILE is to potentially
- *             be closed.
- */
-void
-ktxFileStream_destruct(ktxStream* str)
-{
-    assert(str && str->type == eStreamTypeFile);
-    
-    if (str->closeOnDestruct)
-        fclose(str->data.file);
-    str->data.file = 0;
-}
diff --git a/external/KTX-Software-master/lib/filestream.h b/external/KTX-Software-master/lib/filestream.h
deleted file mode 100644
index 3359cb24a25300a840071842665ee36ee289388e..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/filestream.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/*
- * ©2010-2018 The khronos Group, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Author: Maksim Kolesin from original code
- * by Mark Callow and Georg Kolling
- */
-
-#ifndef FILESTREAM_H
-#define FILESTREAM_H
-
-#include "ktx.h"
-#include "stream.h"
-
-/*
- * ktxFileInit: Initialize a ktxStream to a ktxFileStream with a FILE object
- */
-KTX_error_code ktxFileStream_construct(ktxStream* str, FILE* file,
-                                       ktx_bool_t closeFileOnDestruct);
-
-void ktxFileStream_destruct(ktxStream* str);
-
-#endif /* FILESTREAM_H */
diff --git a/external/KTX-Software-master/lib/gl_format.h b/external/KTX-Software-master/lib/gl_format.h
deleted file mode 100644
index 2a781244e6ac52155c65351818066e04ad05ced4..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/gl_format.h
+++ /dev/null
@@ -1,2456 +0,0 @@
-/*
-================================================================================================
-
-Description	:	OpenGL formats/types and properties.
-Author		:	J.M.P. van Waveren
-Date		:	07/17/2016
-Language	:	C99
-Format		:	Real tabs with the tab size equal to 4 spaces.
-Copyright	:	Copyright (c) 2016 Oculus VR, LLC. All Rights reserved.
-
-
-LICENSE
-=======
-
-Copyright (c) 2016 Oculus VR, LLC.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-
-DESCRIPTION
-===========
-
-This header stores the OpenGL formats/types and two simple routines
-to derive the format/type from an internal format. These routines
-are useful to verify the data in a KTX container files. The OpenGL
-constants are generally useful to convert files like KTX and glTF
-to different graphics APIs.
-
-This header stores the OpenGL formats/types that are used as parameters
-to the following OpenGL functions:
-
-void glTexImage2D( GLenum target, GLint level, GLint internalFormat,
-	GLsizei width, GLsizei height, GLint border,
-	GLenum format, GLenum type, const GLvoid * data );
-void glTexImage3D( GLenum target, GLint level, GLint internalFormat,
-	GLsizei width, GLsizei height, GLsizei depth, GLint border,
-	GLenum format, GLenum type, const GLvoid * data );
-void glCompressedTexImage2D( GLenum target, GLint level, GLenum internalformat,
-	GLsizei width, GLsizei height, GLint border,
-	GLsizei imageSize, const GLvoid * data );
-void glCompressedTexImage3D( GLenum target, GLint level, GLenum internalformat,
-	GLsizei width, GLsizei height, GLsizei depth, GLint border,
-	GLsizei imageSize, const GLvoid * data );
-void glTexStorage2D( GLenum target, GLsizei levels, GLenum internalformat,
-	GLsizei width, GLsizei height );
-void glTexStorage3D( GLenum target, GLsizei levels, GLenum internalformat,
-	GLsizei width, GLsizei height, GLsizei depth );
-void glVertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized,
-	GLsizei stride, const GLvoid * pointer);
-
-
-IMPLEMENTATION
-==============
-
-This file does not include OpenGL / OpenGL ES headers because:
-
-  1. Including OpenGL / OpenGL ES headers is platform dependent and
-     may require a separate installation of an OpenGL SDK.
-  2. The OpenGL format/type constants are the same between extensions and core.
-  3. The OpenGL format/type constants are the same between OpenGL and OpenGL ES.
-  4. The OpenGL constants in this header are also used to derive Vulkan formats
-     from the OpenGL formats/types stored in files like KTX and glTF. These file
-     formats may use OpenGL formats/types that are not supported by the OpenGL
-     implementation on the platform but are supported by the Vulkan implementation.
-
-
-ENTRY POINTS
-============
-
-static inline GLenum glGetFormatFromInternalFormat( const GLenum internalFormat );
-static inline GLenum glGetTypeFromInternalFormat( const GLenum internalFormat );
-static inline void glGetFormatSize( const GLenum internalFormat, GlFormatSize * pFormatSize );
-static inline unsigned int glGetTypeSizeFromType( const GLenum type );
- 
-MODIFICATIONS for use in libktx
-===============================
- 
-2018.3.23 Added glGetTypeSizeFromType. Mark Callow, Edgewise Consulting.
-2019.3.09 #if 0 around GL type declarations. Mark Callow,     〃
-
-================================================================================================
-*/
-
-#if !defined( GL_FORMAT_H )
-#define GL_FORMAT_H
-
-#include <assert.h>
-
-#if defined(_WIN32)
-#define NOMINMAX
-#ifndef __cplusplus
-#undef inline
-#define inline __inline
-#endif // __cplusplus
-#endif
-
-/*
-===========================================================================
-Avoid warnings or even errors when using strict C99. "Redefinition of
-(type) is a C11 feature." All includers in libktx also include ktx.h where
-they are also defined.
-===========================================================================
-*/
-#if 0
-typedef unsigned int GLenum;
-typedef unsigned char GLboolean;
-typedef unsigned int GLuint;
-#endif
-
-#if !defined( GL_INVALID_VALUE )
-#define GL_INVALID_VALUE								0x0501
-#endif
-
-/*
-================================================================================================================================
-
-Format to glTexImage2D and glTexImage3D.
-
-================================================================================================================================
-*/
-
-#if !defined( GL_RED )
-#define GL_RED											0x1903	// same as GL_RED_EXT
-#endif
-#if !defined( GL_GREEN )
-#define GL_GREEN										0x1904	// deprecated
-#endif
-#if !defined( GL_BLUE )
-#define GL_BLUE											0x1905	// deprecated
-#endif
-#if !defined( GL_ALPHA )
-#define GL_ALPHA										0x1906	// deprecated
-#endif
-#if !defined( GL_LUMINANCE )
-#define GL_LUMINANCE									0x1909	// deprecated
-#endif
-#if !defined( GL_SLUMINANCE )
-#define GL_SLUMINANCE									0x8C46	// deprecated, same as GL_SLUMINANCE_EXT
-#endif
-#if !defined( GL_LUMINANCE_ALPHA )
-#define GL_LUMINANCE_ALPHA								0x190A	// deprecated
-#endif
-#if !defined( GL_SLUMINANCE_ALPHA )
-#define GL_SLUMINANCE_ALPHA								0x8C44	// deprecated, same as GL_SLUMINANCE_ALPHA_EXT
-#endif
-#if !defined( GL_INTENSITY )
-#define GL_INTENSITY									0x8049	// deprecated, same as GL_INTENSITY_EXT
-#endif
-#if !defined( GL_RG )
-#define GL_RG											0x8227	// same as GL_RG_EXT
-#endif
-#if !defined( GL_RGB )
-#define GL_RGB											0x1907
-#endif
-#if !defined( GL_BGR )
-#define GL_BGR											0x80E0	// same as GL_BGR_EXT
-#endif
-#if !defined( GL_RGBA )
-#define GL_RGBA											0x1908
-#endif
-#if !defined( GL_BGRA )
-#define GL_BGRA											0x80E1	// same as GL_BGRA_EXT
-#endif
-#if !defined( GL_RED_INTEGER )
-#define GL_RED_INTEGER									0x8D94	// same as GL_RED_INTEGER_EXT
-#endif
-#if !defined( GL_GREEN_INTEGER )
-#define GL_GREEN_INTEGER								0x8D95	// deprecated, same as GL_GREEN_INTEGER_EXT
-#endif
-#if !defined( GL_BLUE_INTEGER )
-#define GL_BLUE_INTEGER									0x8D96	// deprecated, same as GL_BLUE_INTEGER_EXT
-#endif
-#if !defined( GL_ALPHA_INTEGER )
-#define GL_ALPHA_INTEGER								0x8D97	// deprecated, same as GL_ALPHA_INTEGER_EXT
-#endif
-#if !defined( GL_LUMINANCE_INTEGER )
-#define GL_LUMINANCE_INTEGER							0x8D9C	// deprecated, same as GL_LUMINANCE_INTEGER_EXT
-#endif
-#if !defined( GL_LUMINANCE_ALPHA_INTEGER )
-#define GL_LUMINANCE_ALPHA_INTEGER						0x8D9D	// deprecated, same as GL_LUMINANCE_ALPHA_INTEGER_EXT
-#endif
-#if !defined( GL_RG_INTEGER )
-#define GL_RG_INTEGER									0x8228	// same as GL_RG_INTEGER_EXT
-#endif
-#if !defined( GL_RGB_INTEGER )
-#define GL_RGB_INTEGER									0x8D98	// same as GL_RGB_INTEGER_EXT
-#endif
-#if !defined( GL_BGR_INTEGER )
-#define GL_BGR_INTEGER									0x8D9A	// same as GL_BGR_INTEGER_EXT
-#endif
-#if !defined( GL_RGBA_INTEGER )
-#define GL_RGBA_INTEGER									0x8D99	// same as GL_RGBA_INTEGER_EXT
-#endif
-#if !defined( GL_BGRA_INTEGER )
-#define GL_BGRA_INTEGER									0x8D9B	// same as GL_BGRA_INTEGER_EXT
-#endif
-#if !defined( GL_COLOR_INDEX )
-#define GL_COLOR_INDEX									0x1900	// deprecated
-#endif
-#if !defined( GL_STENCIL_INDEX )
-#define GL_STENCIL_INDEX								0x1901
-#endif
-#if !defined( GL_DEPTH_COMPONENT )
-#define GL_DEPTH_COMPONENT								0x1902
-#endif
-#if !defined( GL_DEPTH_STENCIL )
-#define GL_DEPTH_STENCIL								0x84F9	// same as GL_DEPTH_STENCIL_NV and GL_DEPTH_STENCIL_EXT and GL_DEPTH_STENCIL_OES
-#endif
-
-/*
-================================================================================================================================
-
-Type to glTexImage2D, glTexImage3D and glVertexAttribPointer.
-
-================================================================================================================================
-*/
-
-#if !defined( GL_BYTE )
-#define GL_BYTE											0x1400
-#endif
-#if !defined( GL_UNSIGNED_BYTE )
-#define GL_UNSIGNED_BYTE								0x1401
-#endif
-#if !defined( GL_SHORT )
-#define GL_SHORT										0x1402
-#endif
-#if !defined( GL_UNSIGNED_SHORT )
-#define GL_UNSIGNED_SHORT								0x1403
-#endif
-#if !defined( GL_INT )
-#define GL_INT											0x1404
-#endif
-#if !defined( GL_UNSIGNED_INT )
-#define GL_UNSIGNED_INT									0x1405
-#endif
-#if !defined( GL_INT64 )
-#define GL_INT64										0x140E	// same as GL_INT64_NV and GL_INT64_ARB
-#endif
-#if !defined( GL_UNSIGNED_INT64 )
-#define GL_UNSIGNED_INT64								0x140F	// same as GL_UNSIGNED_INT64_NV and GL_UNSIGNED_INT64_ARB
-#endif
-#if !defined( GL_HALF_FLOAT )
-#define GL_HALF_FLOAT									0x140B	// same as GL_HALF_FLOAT_NV and GL_HALF_FLOAT_ARB
-#endif
-#if !defined( GL_HALF_FLOAT_OES )
-#define GL_HALF_FLOAT_OES								0x8D61	// Note that this different from GL_HALF_FLOAT.
-#endif
-#if !defined( GL_FLOAT )
-#define GL_FLOAT										0x1406
-#endif
-#if !defined( GL_DOUBLE )
-#define GL_DOUBLE										0x140A	// same as GL_DOUBLE_EXT
-#endif
-#if !defined( GL_UNSIGNED_BYTE_3_3_2 )
-#define GL_UNSIGNED_BYTE_3_3_2							0x8032	// same as GL_UNSIGNED_BYTE_3_3_2_EXT
-#endif
-#if !defined( GL_UNSIGNED_BYTE_2_3_3_REV )
-#define GL_UNSIGNED_BYTE_2_3_3_REV						0x8362	// same as GL_UNSIGNED_BYTE_2_3_3_REV_EXT
-#endif
-#if !defined( GL_UNSIGNED_SHORT_5_6_5 )
-#define GL_UNSIGNED_SHORT_5_6_5							0x8363	// same as GL_UNSIGNED_SHORT_5_6_5_EXT
-#endif
-#if !defined( GL_UNSIGNED_SHORT_5_6_5_REV )
-#define GL_UNSIGNED_SHORT_5_6_5_REV						0x8364	// same as GL_UNSIGNED_SHORT_5_6_5_REV_EXT
-#endif
-#if !defined( GL_UNSIGNED_SHORT_4_4_4_4 )
-#define GL_UNSIGNED_SHORT_4_4_4_4						0x8033	// same as GL_UNSIGNED_SHORT_4_4_4_4_EXT
-#endif
-#if !defined( GL_UNSIGNED_SHORT_4_4_4_4_REV )
-#define GL_UNSIGNED_SHORT_4_4_4_4_REV					0x8365	// same as GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG and GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT
-#endif
-#if !defined( GL_UNSIGNED_SHORT_5_5_5_1 )
-#define GL_UNSIGNED_SHORT_5_5_5_1						0x8034	// same as GL_UNSIGNED_SHORT_5_5_5_1_EXT
-#endif
-#if !defined( GL_UNSIGNED_SHORT_1_5_5_5_REV )
-#define GL_UNSIGNED_SHORT_1_5_5_5_REV					0x8366	// same as GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT
-#endif
-#if !defined( GL_UNSIGNED_INT_8_8_8_8 )
-#define GL_UNSIGNED_INT_8_8_8_8							0x8035	// same as GL_UNSIGNED_INT_8_8_8_8_EXT
-#endif
-#if !defined( GL_UNSIGNED_INT_8_8_8_8_REV )
-#define GL_UNSIGNED_INT_8_8_8_8_REV						0x8367	// same as GL_UNSIGNED_INT_8_8_8_8_REV_EXT
-#endif
-#if !defined( GL_UNSIGNED_INT_10_10_10_2 )
-#define GL_UNSIGNED_INT_10_10_10_2						0x8036	// same as GL_UNSIGNED_INT_10_10_10_2_EXT
-#endif
-#if !defined( GL_UNSIGNED_INT_2_10_10_10_REV )
-#define GL_UNSIGNED_INT_2_10_10_10_REV					0x8368	// same as GL_UNSIGNED_INT_2_10_10_10_REV_EXT
-#endif
-#if !defined( GL_UNSIGNED_INT_10F_11F_11F_REV )
-#define GL_UNSIGNED_INT_10F_11F_11F_REV					0x8C3B	// same as GL_UNSIGNED_INT_10F_11F_11F_REV_EXT
-#endif
-#if !defined( GL_UNSIGNED_INT_5_9_9_9_REV )
-#define GL_UNSIGNED_INT_5_9_9_9_REV						0x8C3E	// same as GL_UNSIGNED_INT_5_9_9_9_REV_EXT
-#endif
-#if !defined( GL_UNSIGNED_INT_24_8 )
-#define GL_UNSIGNED_INT_24_8							0x84FA	// same as GL_UNSIGNED_INT_24_8_NV and GL_UNSIGNED_INT_24_8_EXT and GL_UNSIGNED_INT_24_8_OES
-#endif
-#if !defined( GL_FLOAT_32_UNSIGNED_INT_24_8_REV )
-#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV				0x8DAD	// same as GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV and GL_FLOAT_32_UNSIGNED_INT_24_8_REV_ARB
-#endif
-
-/*
-================================================================================================================================
-
-Internal format to glTexImage2D, glTexImage3D, glCompressedTexImage2D, glCompressedTexImage3D, glTexStorage2D, glTexStorage3D
-
-================================================================================================================================
-*/
-
-//
-// 8 bits per component
-//
-
-#if !defined( GL_R8 )
-#define GL_R8											0x8229	// same as GL_R8_EXT
-#endif
-#if !defined( GL_RG8 )
-#define GL_RG8											0x822B	// same as GL_RG8_EXT
-#endif
-#if !defined( GL_RGB8 )
-#define GL_RGB8											0x8051	// same as GL_RGB8_EXT and GL_RGB8_OES
-#endif
-#if !defined( GL_RGBA8 )
-#define GL_RGBA8										0x8058	// same as GL_RGBA8_EXT and GL_RGBA8_OES
-#endif
-
-#if !defined( GL_R8_SNORM )
-#define GL_R8_SNORM										0x8F94
-#endif
-#if !defined( GL_RG8_SNORM )
-#define GL_RG8_SNORM									0x8F95
-#endif
-#if !defined( GL_RGB8_SNORM )
-#define GL_RGB8_SNORM									0x8F96
-#endif
-#if !defined( GL_RGBA8_SNORM )
-#define GL_RGBA8_SNORM									0x8F97
-#endif
-
-#if !defined( GL_R8UI )
-#define GL_R8UI											0x8232
-#endif
-#if !defined( GL_RG8UI )
-#define GL_RG8UI										0x8238
-#endif
-#if !defined( GL_RGB8UI )
-#define GL_RGB8UI										0x8D7D	// same as GL_RGB8UI_EXT
-#endif
-#if !defined( GL_RGBA8UI )
-#define GL_RGBA8UI										0x8D7C	// same as GL_RGBA8UI_EXT
-#endif
-
-#if !defined( GL_R8I )
-#define GL_R8I											0x8231
-#endif
-#if !defined( GL_RG8I )
-#define GL_RG8I											0x8237
-#endif
-#if !defined( GL_RGB8I )
-#define GL_RGB8I										0x8D8F	// same as GL_RGB8I_EXT
-#endif
-#if !defined( GL_RGBA8I )
-#define GL_RGBA8I										0x8D8E	// same as GL_RGBA8I_EXT
-#endif
-
-#if !defined( GL_SR8 )
-#define GL_SR8											0x8FBD	// same as GL_SR8_EXT
-#endif
-#if !defined( GL_SRG8 )
-#define GL_SRG8											0x8FBE	// same as GL_SRG8_EXT
-#endif
-#if !defined( GL_SRGB8 )
-#define GL_SRGB8										0x8C41	// same as GL_SRGB8_EXT
-#endif
-#if !defined( GL_SRGB8_ALPHA8 )
-#define GL_SRGB8_ALPHA8									0x8C43	// same as GL_SRGB8_ALPHA8_EXT
-#endif
-
-//
-// 16 bits per component
-//
-
-#if !defined( GL_R16 )
-#define GL_R16											0x822A	// same as GL_R16_EXT
-#endif
-#if !defined( GL_RG16 )
-#define GL_RG16											0x822C	// same as GL_RG16_EXT
-#endif
-#if !defined( GL_RGB16 )
-#define GL_RGB16										0x8054	// same as GL_RGB16_EXT
-#endif
-#if !defined( GL_RGBA16 )
-#define GL_RGBA16										0x805B	// same as GL_RGBA16_EXT
-#endif
-
-#if !defined( GL_R16_SNORM )
-#define GL_R16_SNORM									0x8F98	// same as GL_R16_SNORM_EXT
-#endif
-#if !defined( GL_RG16_SNORM )
-#define GL_RG16_SNORM									0x8F99	// same as GL_RG16_SNORM_EXT
-#endif
-#if !defined( GL_RGB16_SNORM )
-#define GL_RGB16_SNORM									0x8F9A	// same as GL_RGB16_SNORM_EXT
-#endif
-#if !defined( GL_RGBA16_SNORM )
-#define GL_RGBA16_SNORM									0x8F9B	// same as GL_RGBA16_SNORM_EXT
-#endif
-
-#if !defined( GL_R16UI )
-#define GL_R16UI										0x8234
-#endif
-#if !defined( GL_RG16UI )
-#define GL_RG16UI										0x823A
-#endif
-#if !defined( GL_RGB16UI )
-#define GL_RGB16UI										0x8D77	// same as GL_RGB16UI_EXT
-#endif
-#if !defined( GL_RGBA16UI )
-#define GL_RGBA16UI										0x8D76	// same as GL_RGBA16UI_EXT
-#endif
-
-#if !defined( GL_R16I )
-#define GL_R16I											0x8233
-#endif
-#if !defined( GL_RG16I )
-#define GL_RG16I										0x8239
-#endif
-#if !defined( GL_RGB16I )
-#define GL_RGB16I										0x8D89	// same as GL_RGB16I_EXT
-#endif
-#if !defined( GL_RGBA16I )
-#define GL_RGBA16I										0x8D88	// same as GL_RGBA16I_EXT
-#endif
-
-#if !defined( GL_R16F )
-#define GL_R16F											0x822D	// same as GL_R16F_EXT
-#endif
-#if !defined( GL_RG16F )
-#define GL_RG16F										0x822F	// same as GL_RG16F_EXT
-#endif
-#if !defined( GL_RGB16F )
-#define GL_RGB16F										0x881B	// same as GL_RGB16F_EXT and GL_RGB16F_ARB
-#endif
-#if !defined( GL_RGBA16F )
-#define GL_RGBA16F										0x881A	// sama as GL_RGBA16F_EXT and GL_RGBA16F_ARB
-#endif
-
-//
-// 32 bits per component
-//
-
-#if !defined( GL_R32UI )
-#define GL_R32UI										0x8236
-#endif
-#if !defined( GL_RG32UI )
-#define GL_RG32UI										0x823C
-#endif
-#if !defined( GL_RGB32UI )
-#define GL_RGB32UI										0x8D71	// same as GL_RGB32UI_EXT
-#endif
-#if !defined( GL_RGBA32UI )
-#define GL_RGBA32UI										0x8D70	// same as GL_RGBA32UI_EXT
-#endif
-
-#if !defined( GL_R32I )
-#define GL_R32I											0x8235
-#endif
-#if !defined( GL_RG32I )
-#define GL_RG32I										0x823B
-#endif
-#if !defined( GL_RGB32I )
-#define GL_RGB32I										0x8D83	// same as GL_RGB32I_EXT 
-#endif
-#if !defined( GL_RGBA32I )
-#define GL_RGBA32I										0x8D82	// same as GL_RGBA32I_EXT
-#endif
-
-#if !defined( GL_R32F )
-#define GL_R32F											0x822E	// same as GL_R32F_EXT
-#endif
-#if !defined( GL_RG32F )
-#define GL_RG32F										0x8230	// same as GL_RG32F_EXT
-#endif
-#if !defined( GL_RGB32F )
-#define GL_RGB32F										0x8815	// same as GL_RGB32F_EXT and GL_RGB32F_ARB
-#endif
-#if !defined( GL_RGBA32F )
-#define GL_RGBA32F										0x8814	// same as GL_RGBA32F_EXT and GL_RGBA32F_ARB
-#endif
-
-//
-// Packed
-//
-
-#if !defined( GL_R3_G3_B2 )
-#define GL_R3_G3_B2										0x2A10
-#endif
-#if !defined( GL_RGB4 )
-#define GL_RGB4											0x804F	// same as GL_RGB4_EXT
-#endif
-#if !defined( GL_RGB5 )
-#define GL_RGB5											0x8050	// same as GL_RGB5_EXT
-#endif
-#if !defined( GL_RGB565 )
-#define GL_RGB565										0x8D62	// same as GL_RGB565_EXT and GL_RGB565_OES
-#endif
-#if !defined( GL_RGB10 )
-#define GL_RGB10										0x8052	// same as GL_RGB10_EXT
-#endif
-#if !defined( GL_RGB12 )
-#define GL_RGB12										0x8053	// same as GL_RGB12_EXT
-#endif
-#if !defined( GL_RGBA2 )
-#define GL_RGBA2										0x8055	// same as GL_RGBA2_EXT
-#endif
-#if !defined( GL_RGBA4 )
-#define GL_RGBA4										0x8056	// same as GL_RGBA4_EXT and GL_RGBA4_OES
-#endif
-#if !defined( GL_RGBA12 )
-#define GL_RGBA12										0x805A	// same as GL_RGBA12_EXT
-#endif
-#if !defined( GL_RGB5_A1 )
-#define GL_RGB5_A1										0x8057	// same as GL_RGB5_A1_EXT and GL_RGB5_A1_OES
-#endif
-#if !defined( GL_RGB10_A2 )
-#define GL_RGB10_A2										0x8059	// same as GL_RGB10_A2_EXT
-#endif
-#if !defined( GL_RGB10_A2UI )
-#define GL_RGB10_A2UI									0x906F
-#endif
-#if !defined( GL_R11F_G11F_B10F )
-#define GL_R11F_G11F_B10F								0x8C3A	// same as GL_R11F_G11F_B10F_APPLE and GL_R11F_G11F_B10F_EXT
-#endif
-#if !defined( GL_RGB9_E5 )
-#define GL_RGB9_E5										0x8C3D	// same as GL_RGB9_E5_APPLE and GL_RGB9_E5_EXT
-#endif
-
-//
-// Alpha
-//
-
-#if !defined( GL_ALPHA4 )
-#define GL_ALPHA4										0x803B	// deprecated, same as GL_ALPHA4_EXT
-#endif
-#if !defined( GL_ALPHA8 )
-#define GL_ALPHA8										0x803C	// deprecated, same as GL_ALPHA8_EXT
-#endif
-#if !defined( GL_ALPHA8_SNORM )
-#define GL_ALPHA8_SNORM									0x9014	// deprecated
-#endif
-#if !defined( GL_ALPHA8UI_EXT )
-#define GL_ALPHA8UI_EXT									0x8D7E	// deprecated
-#endif
-#if !defined( GL_ALPHA8I_EXT )
-#define GL_ALPHA8I_EXT									0x8D90	// deprecated
-#endif
-#if !defined( GL_ALPHA12 )
-#define GL_ALPHA12										0x803D	// deprecated, same as GL_ALPHA12_EXT
-#endif
-#if !defined( GL_ALPHA16 )
-#define GL_ALPHA16										0x803E	// deprecated, same as GL_ALPHA16_EXT
-#endif
-#if !defined( GL_ALPHA16_SNORM )
-#define GL_ALPHA16_SNORM								0x9018	// deprecated
-#endif
-#if !defined( GL_ALPHA16UI_EXT )
-#define GL_ALPHA16UI_EXT								0x8D78	// deprecated
-#endif
-#if !defined( GL_ALPHA16I_EXT )
-#define GL_ALPHA16I_EXT									0x8D8A	// deprecated
-#endif
-#if !defined( GL_ALPHA16F_ARB )
-#define GL_ALPHA16F_ARB									0x881C	// deprecated, same as GL_ALPHA_FLOAT16_APPLE and GL_ALPHA_FLOAT16_ATI
-#endif
-#if !defined( GL_ALPHA32UI_EXT )
-#define GL_ALPHA32UI_EXT								0x8D72	// deprecated
-#endif
-#if !defined( GL_ALPHA32I_EXT )
-#define GL_ALPHA32I_EXT									0x8D84	// deprecated
-#endif
-#if !defined( GL_ALPHA32F_ARB )
-#define GL_ALPHA32F_ARB									0x8816	// deprecated, same as GL_ALPHA_FLOAT32_APPLE and GL_ALPHA_FLOAT32_ATI
-#endif
-
-//
-// Luminance
-//
-
-#if !defined( GL_LUMINANCE4 )
-#define GL_LUMINANCE4									0x803F	// deprecated, same as GL_LUMINANCE4_EXT
-#endif
-#if !defined( GL_LUMINANCE8 )
-#define GL_LUMINANCE8									0x8040	// deprecated, same as GL_LUMINANCE8_EXT
-#endif
-#if !defined( GL_LUMINANCE8_SNORM )
-#define GL_LUMINANCE8_SNORM								0x9015	// deprecated
-#endif
-#if !defined( GL_SLUMINANCE8 )
-#define GL_SLUMINANCE8									0x8C47	// deprecated, same as GL_SLUMINANCE8_EXT
-#endif
-#if !defined( GL_LUMINANCE8UI_EXT )
-#define GL_LUMINANCE8UI_EXT								0x8D80	// deprecated
-#endif
-#if !defined( GL_LUMINANCE8I_EXT )
-#define GL_LUMINANCE8I_EXT								0x8D92	// deprecated
-#endif
-#if !defined( GL_LUMINANCE12 )
-#define GL_LUMINANCE12									0x8041	// deprecated, same as GL_LUMINANCE12_EXT
-#endif
-#if !defined( GL_LUMINANCE16 )
-#define GL_LUMINANCE16									0x8042	// deprecated, same as GL_LUMINANCE16_EXT
-#endif
-#if !defined( GL_LUMINANCE16_SNORM )
-#define GL_LUMINANCE16_SNORM							0x9019	// deprecated
-#endif
-#if !defined( GL_LUMINANCE16UI_EXT )
-#define GL_LUMINANCE16UI_EXT							0x8D7A	// deprecated
-#endif
-#if !defined( GL_LUMINANCE16I_EXT )
-#define GL_LUMINANCE16I_EXT								0x8D8C	// deprecated
-#endif
-#if !defined( GL_LUMINANCE16F_ARB )
-#define GL_LUMINANCE16F_ARB								0x881E	// deprecated, same as GL_LUMINANCE_FLOAT16_APPLE and GL_LUMINANCE_FLOAT16_ATI
-#endif
-#if !defined( GL_LUMINANCE32UI_EXT )
-#define GL_LUMINANCE32UI_EXT							0x8D74	// deprecated
-#endif
-#if !defined( GL_LUMINANCE32I_EXT )
-#define GL_LUMINANCE32I_EXT								0x8D86	// deprecated
-#endif
-#if !defined( GL_LUMINANCE32F_ARB )
-#define GL_LUMINANCE32F_ARB								0x8818	// deprecated, same as GL_LUMINANCE_FLOAT32_APPLE and GL_LUMINANCE_FLOAT32_ATI
-#endif
-
-//
-// Luminance/Alpha
-//
-
-#if !defined( GL_LUMINANCE4_ALPHA4 )
-#define GL_LUMINANCE4_ALPHA4							0x8043	// deprecated, same as GL_LUMINANCE4_ALPHA4_EXT
-#endif
-#if !defined( GL_LUMINANCE6_ALPHA2 )
-#define GL_LUMINANCE6_ALPHA2							0x8044	// deprecated, same as GL_LUMINANCE6_ALPHA2_EXT
-#endif
-#if !defined( GL_LUMINANCE8_ALPHA8 )
-#define GL_LUMINANCE8_ALPHA8							0x8045	// deprecated, same as GL_LUMINANCE8_ALPHA8_EXT
-#endif
-#if !defined( GL_LUMINANCE8_ALPHA8_SNORM )
-#define GL_LUMINANCE8_ALPHA8_SNORM						0x9016	// deprecated
-#endif
-#if !defined( GL_SLUMINANCE8_ALPHA8 )
-#define GL_SLUMINANCE8_ALPHA8							0x8C45	// deprecated, same as GL_SLUMINANCE8_ALPHA8_EXT
-#endif
-#if !defined( GL_LUMINANCE_ALPHA8UI_EXT )
-#define GL_LUMINANCE_ALPHA8UI_EXT						0x8D81	// deprecated
-#endif
-#if !defined( GL_LUMINANCE_ALPHA8I_EXT )
-#define GL_LUMINANCE_ALPHA8I_EXT						0x8D93	// deprecated
-#endif
-#if !defined( GL_LUMINANCE12_ALPHA4 )
-#define GL_LUMINANCE12_ALPHA4							0x8046	// deprecated, same as GL_LUMINANCE12_ALPHA4_EXT
-#endif
-#if !defined( GL_LUMINANCE12_ALPHA12 )
-#define GL_LUMINANCE12_ALPHA12							0x8047	// deprecated, same as GL_LUMINANCE12_ALPHA12_EXT
-#endif
-#if !defined( GL_LUMINANCE16_ALPHA16 )
-#define GL_LUMINANCE16_ALPHA16							0x8048	// deprecated, same as GL_LUMINANCE16_ALPHA16_EXT
-#endif
-#if !defined( GL_LUMINANCE16_ALPHA16_SNORM )
-#define GL_LUMINANCE16_ALPHA16_SNORM					0x901A	// deprecated
-#endif
-#if !defined( GL_LUMINANCE_ALPHA16UI_EXT )
-#define GL_LUMINANCE_ALPHA16UI_EXT						0x8D7B	// deprecated
-#endif
-#if !defined( GL_LUMINANCE_ALPHA16I_EXT )
-#define GL_LUMINANCE_ALPHA16I_EXT						0x8D8D	// deprecated
-#endif
-#if !defined( GL_LUMINANCE_ALPHA16F_ARB )
-#define GL_LUMINANCE_ALPHA16F_ARB						0x881F	// deprecated, same as GL_LUMINANCE_ALPHA_FLOAT16_APPLE and GL_LUMINANCE_ALPHA_FLOAT16_ATI
-#endif
-#if !defined( GL_LUMINANCE_ALPHA32UI_EXT )
-#define GL_LUMINANCE_ALPHA32UI_EXT						0x8D75	// deprecated
-#endif
-#if !defined( GL_LUMINANCE_ALPHA32I_EXT )
-#define GL_LUMINANCE_ALPHA32I_EXT						0x8D87	// deprecated
-#endif
-#if !defined( GL_LUMINANCE_ALPHA32F_ARB )
-#define GL_LUMINANCE_ALPHA32F_ARB						0x8819	// deprecated, same as GL_LUMINANCE_ALPHA_FLOAT32_APPLE and GL_LUMINANCE_ALPHA_FLOAT32_ATI
-#endif
-
-//
-// Intensity
-//
-
-#if !defined( GL_INTENSITY4 )
-#define GL_INTENSITY4									0x804A	// deprecated, same as GL_INTENSITY4_EXT
-#endif
-#if !defined( GL_INTENSITY8 )
-#define GL_INTENSITY8									0x804B	// deprecated, same as GL_INTENSITY8_EXT
-#endif
-#if !defined( GL_INTENSITY8_SNORM )
-#define GL_INTENSITY8_SNORM								0x9017	// deprecated
-#endif
-#if !defined( GL_INTENSITY8UI_EXT )
-#define GL_INTENSITY8UI_EXT								0x8D7F	// deprecated
-#endif
-#if !defined( GL_INTENSITY8I_EXT )
-#define GL_INTENSITY8I_EXT								0x8D91	// deprecated
-#endif
-#if !defined( GL_INTENSITY12 )
-#define GL_INTENSITY12									0x804C	// deprecated, same as GL_INTENSITY12_EXT
-#endif
-#if !defined( GL_INTENSITY16 )
-#define GL_INTENSITY16									0x804D	// deprecated, same as GL_INTENSITY16_EXT
-#endif
-#if !defined( GL_INTENSITY16_SNORM )
-#define GL_INTENSITY16_SNORM							0x901B	// deprecated
-#endif
-#if !defined( GL_INTENSITY16UI_EXT )
-#define GL_INTENSITY16UI_EXT							0x8D79	// deprecated
-#endif
-#if !defined( GL_INTENSITY16I_EXT )
-#define GL_INTENSITY16I_EXT								0x8D8B	// deprecated
-#endif
-#if !defined( GL_INTENSITY16F_ARB )
-#define GL_INTENSITY16F_ARB								0x881D	// deprecated, same as GL_INTENSITY_FLOAT16_APPLE and GL_INTENSITY_FLOAT16_ATI
-#endif
-#if !defined( GL_INTENSITY32UI_EXT )
-#define GL_INTENSITY32UI_EXT							0x8D73	// deprecated
-#endif
-#if !defined( GL_INTENSITY32I_EXT )
-#define GL_INTENSITY32I_EXT								0x8D85	// deprecated
-#endif
-#if !defined( GL_INTENSITY32F_ARB )
-#define GL_INTENSITY32F_ARB								0x8817	// deprecated, same as GL_INTENSITY_FLOAT32_APPLE and GL_INTENSITY_FLOAT32_ATI
-#endif
-
-//
-// Generic compression
-//
-
-#if !defined( GL_COMPRESSED_RED )
-#define GL_COMPRESSED_RED								0x8225
-#endif
-#if !defined( GL_COMPRESSED_ALPHA )
-#define GL_COMPRESSED_ALPHA								0x84E9	// deprecated, same as GL_COMPRESSED_ALPHA_ARB
-#endif
-#if !defined( GL_COMPRESSED_LUMINANCE )
-#define GL_COMPRESSED_LUMINANCE							0x84EA	// deprecated, same as GL_COMPRESSED_LUMINANCE_ARB
-#endif
-#if !defined( GL_COMPRESSED_SLUMINANCE )
-#define GL_COMPRESSED_SLUMINANCE						0x8C4A	// deprecated, same as GL_COMPRESSED_SLUMINANCE_EXT
-#endif
-#if !defined( GL_COMPRESSED_LUMINANCE_ALPHA )
-#define GL_COMPRESSED_LUMINANCE_ALPHA					0x84EB	// deprecated, same as GL_COMPRESSED_LUMINANCE_ALPHA_ARB
-#endif
-#if !defined( GL_COMPRESSED_SLUMINANCE_ALPHA )
-#define GL_COMPRESSED_SLUMINANCE_ALPHA					0x8C4B	// deprecated, same as GL_COMPRESSED_SLUMINANCE_ALPHA_EXT
-#endif
-#if !defined( GL_COMPRESSED_INTENSITY )
-#define GL_COMPRESSED_INTENSITY							0x84EC	// deprecated, same as GL_COMPRESSED_INTENSITY_ARB
-#endif
-#if !defined( GL_COMPRESSED_RG )
-#define GL_COMPRESSED_RG								0x8226
-#endif
-#if !defined( GL_COMPRESSED_RGB )
-#define GL_COMPRESSED_RGB								0x84ED	// same as GL_COMPRESSED_RGB_ARB
-#endif
-#if !defined( GL_COMPRESSED_RGBA )
-#define GL_COMPRESSED_RGBA								0x84EE	// same as GL_COMPRESSED_RGBA_ARB
-#endif
-#if !defined( GL_COMPRESSED_SRGB )
-#define GL_COMPRESSED_SRGB								0x8C48	// same as GL_COMPRESSED_SRGB_EXT
-#endif
-#if !defined( GL_COMPRESSED_SRGB_ALPHA )
-#define GL_COMPRESSED_SRGB_ALPHA						0x8C49	// same as GL_COMPRESSED_SRGB_ALPHA_EXT
-#endif
-
-//
-// FXT1
-//
-
-#if !defined( GL_COMPRESSED_RGB_FXT1_3DFX )
-#define GL_COMPRESSED_RGB_FXT1_3DFX						0x86B0	// deprecated
-#endif
-#if !defined( GL_COMPRESSED_RGBA_FXT1_3DFX )
-#define GL_COMPRESSED_RGBA_FXT1_3DFX					0x86B1	// deprecated
-#endif
-
-//
-// S3TC/DXT/BC
-//
-
-#if !defined( GL_COMPRESSED_RGB_S3TC_DXT1_EXT )
-#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT					0x83F0
-#endif
-#if !defined( GL_COMPRESSED_RGBA_S3TC_DXT1_EXT )
-#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT				0x83F1
-#endif
-#if !defined( GL_COMPRESSED_RGBA_S3TC_DXT3_EXT )
-#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT				0x83F2
-#endif
-#if !defined( GL_COMPRESSED_RGBA_S3TC_DXT5_EXT )
-#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT				0x83F3
-#endif
-
-#if !defined( GL_COMPRESSED_SRGB_S3TC_DXT1_EXT )
-#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT				0x8C4C
-#endif
-#if !defined( GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT )
-#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT			0x8C4D
-#endif
-#if !defined( GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT )
-#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT			0x8C4E
-#endif
-#if !defined( GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT )
-#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT			0x8C4F
-#endif
-
-#if !defined( GL_COMPRESSED_LUMINANCE_LATC1_EXT )
-#define GL_COMPRESSED_LUMINANCE_LATC1_EXT				0x8C70
-#endif
-#if !defined( GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT )
-#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT			0x8C72
-#endif
-#if !defined( GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT )
-#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT		0x8C71
-#endif
-#if !defined( GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT )
-#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT	0x8C73
-#endif
-
-#if !defined( GL_COMPRESSED_RED_RGTC1 )
-#define GL_COMPRESSED_RED_RGTC1							0x8DBB	// same as GL_COMPRESSED_RED_RGTC1_EXT
-#endif
-#if !defined( GL_COMPRESSED_RG_RGTC2 )
-#define GL_COMPRESSED_RG_RGTC2							0x8DBD	// same as GL_COMPRESSED_RG_RGTC2_EXT
-#endif
-#if !defined( GL_COMPRESSED_SIGNED_RED_RGTC1 )
-#define GL_COMPRESSED_SIGNED_RED_RGTC1					0x8DBC	// same as GL_COMPRESSED_SIGNED_RED_RGTC1_EXT
-#endif
-#if !defined( GL_COMPRESSED_SIGNED_RG_RGTC2 )
-#define GL_COMPRESSED_SIGNED_RG_RGTC2					0x8DBE	// same as GL_COMPRESSED_SIGNED_RG_RGTC2_EXT
-#endif
-
-#if !defined( GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT )
-#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT				0x8E8E	// same as GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB
-#endif
-#if !defined( GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT )
-#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT			0x8E8F	// same as GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB
-#endif
-#if !defined( GL_COMPRESSED_RGBA_BPTC_UNORM )
-#define GL_COMPRESSED_RGBA_BPTC_UNORM					0x8E8C	// same as GL_COMPRESSED_RGBA_BPTC_UNORM_ARB	
-#endif
-#if !defined( GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM )
-#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM				0x8E8D	// same as GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB
-#endif
-
-//
-// ETC
-//
-
-#if !defined( GL_ETC1_RGB8_OES )
-#define GL_ETC1_RGB8_OES								0x8D64
-#endif
-
-#if !defined( GL_COMPRESSED_RGB8_ETC2 )
-#define GL_COMPRESSED_RGB8_ETC2							0x9274
-#endif
-#if !defined( GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 )
-#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2		0x9276
-#endif
-#if !defined( GL_COMPRESSED_RGBA8_ETC2_EAC )
-#define GL_COMPRESSED_RGBA8_ETC2_EAC					0x9278
-#endif
-
-#if !defined( GL_COMPRESSED_SRGB8_ETC2 )
-#define GL_COMPRESSED_SRGB8_ETC2						0x9275
-#endif
-#if !defined( GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 )
-#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2	0x9277
-#endif
-#if !defined( GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC )
-#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC				0x9279
-#endif
-
-#if !defined( GL_COMPRESSED_R11_EAC )
-#define GL_COMPRESSED_R11_EAC							0x9270
-#endif
-#if !defined( GL_COMPRESSED_RG11_EAC )
-#define GL_COMPRESSED_RG11_EAC							0x9272
-#endif
-#if !defined( GL_COMPRESSED_SIGNED_R11_EAC )
-#define GL_COMPRESSED_SIGNED_R11_EAC					0x9271
-#endif
-#if !defined( GL_COMPRESSED_SIGNED_RG11_EAC )
-#define GL_COMPRESSED_SIGNED_RG11_EAC					0x9273
-#endif
-
-//
-// PVRTC
-//
-
-#if !defined( GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG )
-#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG				0x8C01
-#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG				0x8C00
-#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG				0x8C03
-#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG				0x8C02
-#endif
-#if !defined( GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG )
-#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG				0x9137
-#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG				0x9138
-#endif
-#if !defined( GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT )
-#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT				0x8A54
-#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT				0x8A55
-#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT		0x8A56
-#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT		0x8A57
-#endif
-#if !defined( GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG )
-#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG		0x93F0
-#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG		0x93F1
-#endif
-
-//
-// ASTC
-//
-
-#if !defined( GL_COMPRESSED_RGBA_ASTC_4x4_KHR )
-#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR					0x93B0
-#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR					0x93B1
-#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR					0x93B2
-#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR					0x93B3
-#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR					0x93B4
-#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR					0x93B5
-#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR					0x93B6
-#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR					0x93B7
-#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR				0x93B8
-#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR				0x93B9
-#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR				0x93BA
-#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR				0x93BB
-#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR				0x93BC
-#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR				0x93BD
-#endif
-
-#if !defined( GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR )
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR			0x93D0
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR			0x93D1
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR			0x93D2
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR			0x93D3
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR			0x93D4
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR			0x93D5
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR			0x93D6
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR			0x93D7
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR		0x93D8
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR		0x93D9
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR		0x93DA
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR		0x93DB
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR		0x93DC
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR		0x93DD
-#endif
-
-#if !defined( GL_COMPRESSED_RGBA_ASTC_3x3x3_OES )
-#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES				0x93C0
-#define GL_COMPRESSED_RGBA_ASTC_4x3x3_OES				0x93C1
-#define GL_COMPRESSED_RGBA_ASTC_4x4x3_OES				0x93C2
-#define GL_COMPRESSED_RGBA_ASTC_4x4x4_OES				0x93C3
-#define GL_COMPRESSED_RGBA_ASTC_5x4x4_OES				0x93C4
-#define GL_COMPRESSED_RGBA_ASTC_5x5x4_OES				0x93C5
-#define GL_COMPRESSED_RGBA_ASTC_5x5x5_OES				0x93C6
-#define GL_COMPRESSED_RGBA_ASTC_6x5x5_OES				0x93C7
-#define GL_COMPRESSED_RGBA_ASTC_6x6x5_OES				0x93C8
-#define GL_COMPRESSED_RGBA_ASTC_6x6x6_OES				0x93C9
-#endif
-
-#if !defined( GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES )
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES		0x93E0
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES		0x93E1
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES		0x93E2
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES		0x93E3
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES		0x93E4
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES		0x93E5
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES		0x93E6
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES		0x93E7
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES		0x93E8
-#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES		0x93E9
-#endif
-
-//
-// ATC
-//
-
-#if !defined( GL_ATC_RGB_AMD )
-#define GL_ATC_RGB_AMD									0x8C92
-#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD					0x8C93
-#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD				0x87EE
-#endif
-
-//
-// Palletized (combined palette)
-//
-
-#if !defined( GL_PALETTE4_RGB8_OES )
-#define GL_PALETTE4_RGB8_OES							0x8B90
-#define GL_PALETTE4_RGBA8_OES							0x8B91
-#define GL_PALETTE4_R5_G6_B5_OES						0x8B92
-#define GL_PALETTE4_RGBA4_OES							0x8B93
-#define GL_PALETTE4_RGB5_A1_OES							0x8B94
-#define GL_PALETTE8_RGB8_OES							0x8B95
-#define GL_PALETTE8_RGBA8_OES							0x8B96
-#define GL_PALETTE8_R5_G6_B5_OES						0x8B97
-#define GL_PALETTE8_RGBA4_OES							0x8B98
-#define GL_PALETTE8_RGB5_A1_OES							0x8B99
-#endif
-
-//
-// Palletized (separate palette)
-//
-
-#if !defined( GL_COLOR_INDEX1_EXT )
-#define GL_COLOR_INDEX1_EXT								0x80E2	// deprecated
-#define GL_COLOR_INDEX2_EXT								0x80E3	// deprecated
-#define GL_COLOR_INDEX4_EXT								0x80E4	// deprecated
-#define GL_COLOR_INDEX8_EXT								0x80E5	// deprecated
-#define GL_COLOR_INDEX12_EXT							0x80E6	// deprecated
-#define GL_COLOR_INDEX16_EXT							0x80E7	// deprecated
-#endif
-
-//
-// Depth/stencil
-//
-
-#if !defined( GL_DEPTH_COMPONENT16 )
-#define GL_DEPTH_COMPONENT16							0x81A5	// same as GL_DEPTH_COMPONENT16_SGIX and GL_DEPTH_COMPONENT16_ARB
-#endif
-#if !defined( GL_DEPTH_COMPONENT24 )
-#define GL_DEPTH_COMPONENT24							0x81A6	// same as GL_DEPTH_COMPONENT24_SGIX and GL_DEPTH_COMPONENT24_ARB
-#endif
-#if !defined( GL_DEPTH_COMPONENT32 )
-#define GL_DEPTH_COMPONENT32							0x81A7	// same as GL_DEPTH_COMPONENT32_SGIX and GL_DEPTH_COMPONENT32_ARB and GL_DEPTH_COMPONENT32_OES
-#endif
-#if !defined( GL_DEPTH_COMPONENT32F )
-#define GL_DEPTH_COMPONENT32F							0x8CAC	// same as GL_DEPTH_COMPONENT32F_ARB
-#endif
-#if !defined( GL_DEPTH_COMPONENT32F_NV )
-#define GL_DEPTH_COMPONENT32F_NV						0x8DAB	// note that this is different from GL_DEPTH_COMPONENT32F
-#endif
-#if !defined( GL_STENCIL_INDEX1 )
-#define GL_STENCIL_INDEX1								0x8D46	// same as GL_STENCIL_INDEX1_EXT
-#endif
-#if !defined( GL_STENCIL_INDEX4 )
-#define GL_STENCIL_INDEX4								0x8D47	// same as GL_STENCIL_INDEX4_EXT
-#endif
-#if !defined( GL_STENCIL_INDEX8 )
-#define GL_STENCIL_INDEX8								0x8D48	// same as GL_STENCIL_INDEX8_EXT
-#endif
-#if !defined( GL_STENCIL_INDEX16 )
-#define GL_STENCIL_INDEX16								0x8D49	// same as GL_STENCIL_INDEX16_EXT
-#endif
-#if !defined( GL_DEPTH24_STENCIL8 )
-#define GL_DEPTH24_STENCIL8								0x88F0	// same as GL_DEPTH24_STENCIL8_EXT and GL_DEPTH24_STENCIL8_OES
-#endif
-#if !defined( GL_DEPTH32F_STENCIL8 )
-#define GL_DEPTH32F_STENCIL8							0x8CAD	// same as GL_DEPTH32F_STENCIL8_ARB
-#endif
-#if !defined( GL_DEPTH32F_STENCIL8_NV )
-#define GL_DEPTH32F_STENCIL8_NV							0x8DAC	// note that this is different from GL_DEPTH32F_STENCIL8
-#endif
-
-static inline GLenum glGetFormatFromInternalFormat( const GLenum internalFormat )
-{
-	switch ( internalFormat )
-	{
-		//
-		// 8 bits per component
-		//
-		case GL_R8:												return GL_RED;		// 1-component, 8-bit unsigned normalized
-		case GL_RG8:											return GL_RG;		// 2-component, 8-bit unsigned normalized
-		case GL_RGB8:											return GL_RGB;		// 3-component, 8-bit unsigned normalized
-		case GL_RGBA8:											return GL_RGBA;		// 4-component, 8-bit unsigned normalized
-
-		case GL_R8_SNORM:										return GL_RED;		// 1-component, 8-bit signed normalized
-		case GL_RG8_SNORM:										return GL_RG;		// 2-component, 8-bit signed normalized
-		case GL_RGB8_SNORM:										return GL_RGB;		// 3-component, 8-bit signed normalized
-		case GL_RGBA8_SNORM:									return GL_RGBA;		// 4-component, 8-bit signed normalized
-
-		case GL_R8UI:											return GL_RED;		// 1-component, 8-bit unsigned integer
-		case GL_RG8UI:											return GL_RG;		// 2-component, 8-bit unsigned integer
-		case GL_RGB8UI:											return GL_RGB;		// 3-component, 8-bit unsigned integer
-		case GL_RGBA8UI:										return GL_RGBA;		// 4-component, 8-bit unsigned integer
-
-		case GL_R8I:											return GL_RED;		// 1-component, 8-bit signed integer
-		case GL_RG8I:											return GL_RG;		// 2-component, 8-bit signed integer
-		case GL_RGB8I:											return GL_RGB;		// 3-component, 8-bit signed integer
-		case GL_RGBA8I:											return GL_RGBA;		// 4-component, 8-bit signed integer
-
-		case GL_SR8:											return GL_RED;		// 1-component, 8-bit sRGB
-		case GL_SRG8:											return GL_RG;		// 2-component, 8-bit sRGB
-		case GL_SRGB8:											return GL_RGB;		// 3-component, 8-bit sRGB
-		case GL_SRGB8_ALPHA8:									return GL_RGBA;		// 4-component, 8-bit sRGB
-
-		//
-		// 16 bits per component
-		//
-		case GL_R16:											return GL_RED;		// 1-component, 16-bit unsigned normalized
-		case GL_RG16:											return GL_RG;		// 2-component, 16-bit unsigned normalized
-		case GL_RGB16:											return GL_RGB;		// 3-component, 16-bit unsigned normalized
-		case GL_RGBA16:											return GL_RGBA;		// 4-component, 16-bit unsigned normalized
-
-		case GL_R16_SNORM:										return GL_RED;		// 1-component, 16-bit signed normalized
-		case GL_RG16_SNORM:										return GL_RG;		// 2-component, 16-bit signed normalized
-		case GL_RGB16_SNORM:									return GL_RGB;		// 3-component, 16-bit signed normalized
-		case GL_RGBA16_SNORM:									return GL_RGBA;		// 4-component, 16-bit signed normalized
-
-		case GL_R16UI:											return GL_RED;		// 1-component, 16-bit unsigned integer
-		case GL_RG16UI:											return GL_RG;		// 2-component, 16-bit unsigned integer
-		case GL_RGB16UI:										return GL_RGB;		// 3-component, 16-bit unsigned integer
-		case GL_RGBA16UI:										return GL_RGBA;		// 4-component, 16-bit unsigned integer
-
-		case GL_R16I:											return GL_RED;		// 1-component, 16-bit signed integer
-		case GL_RG16I:											return GL_RG;		// 2-component, 16-bit signed integer
-		case GL_RGB16I:											return GL_RGB;		// 3-component, 16-bit signed integer
-		case GL_RGBA16I:										return GL_RGBA;		// 4-component, 16-bit signed integer
-
-		case GL_R16F:											return GL_RED;		// 1-component, 16-bit floating-point
-		case GL_RG16F:											return GL_RG;		// 2-component, 16-bit floating-point
-		case GL_RGB16F:											return GL_RGB;		// 3-component, 16-bit floating-point
-		case GL_RGBA16F:										return GL_RGBA;		// 4-component, 16-bit floating-point
-
-		//
-		// 32 bits per component
-		//
-		case GL_R32UI:											return GL_RED;		// 1-component, 32-bit unsigned integer
-		case GL_RG32UI:											return GL_RG;		// 2-component, 32-bit unsigned integer
-		case GL_RGB32UI:										return GL_RGB;		// 3-component, 32-bit unsigned integer
-		case GL_RGBA32UI:										return GL_RGBA;		// 4-component, 32-bit unsigned integer
-
-		case GL_R32I:											return GL_RED;		// 1-component, 32-bit signed integer
-		case GL_RG32I:											return GL_RG;		// 2-component, 32-bit signed integer
-		case GL_RGB32I:											return GL_RGB;		// 3-component, 32-bit signed integer
-		case GL_RGBA32I:										return GL_RGBA;		// 4-component, 32-bit signed integer
-
-		case GL_R32F:											return GL_RED;		// 1-component, 32-bit floating-point
-		case GL_RG32F:											return GL_RG;		// 2-component, 32-bit floating-point
-		case GL_RGB32F:											return GL_RGB;		// 3-component, 32-bit floating-point
-		case GL_RGBA32F:										return GL_RGBA;		// 4-component, 32-bit floating-point
-
-		//
-		// Packed
-		//
-		case GL_R3_G3_B2:										return GL_RGB;		// 3-component 3:3:2,       unsigned normalized
-		case GL_RGB4:											return GL_RGB;		// 3-component 4:4:4,       unsigned normalized
-		case GL_RGB5:											return GL_RGB;		// 3-component 5:5:5,       unsigned normalized
-		case GL_RGB565:											return GL_RGB;		// 3-component 5:6:5,       unsigned normalized
-		case GL_RGB10:											return GL_RGB;		// 3-component 10:10:10,    unsigned normalized
-		case GL_RGB12:											return GL_RGB;		// 3-component 12:12:12,    unsigned normalized
-		case GL_RGBA2:											return GL_RGBA;		// 4-component 2:2:2:2,     unsigned normalized
-		case GL_RGBA4:											return GL_RGBA;		// 4-component 4:4:4:4,     unsigned normalized
-		case GL_RGBA12:											return GL_RGBA;		// 4-component 12:12:12:12, unsigned normalized
-		case GL_RGB5_A1:										return GL_RGBA;		// 4-component 5:5:5:1,     unsigned normalized
-		case GL_RGB10_A2:										return GL_RGBA;		// 4-component 10:10:10:2,  unsigned normalized
-		case GL_RGB10_A2UI:										return GL_RGBA;		// 4-component 10:10:10:2,  unsigned integer
-		case GL_R11F_G11F_B10F:									return GL_RGB;		// 3-component 11:11:10,    floating-point
-		case GL_RGB9_E5:										return GL_RGB;		// 3-component/exp 9:9:9/5, floating-point
-
-		//
-		// S3TC/DXT/BC
-		//
-
-		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:					return GL_RGB;		// line through 3D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:					return GL_RGBA;		// line through 3D space plus 1-bit alpha, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:					return GL_RGBA;		// line through 3D space plus line through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:					return GL_RGBA;		// line through 3D space plus 4-bit alpha, 4x4 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:					return GL_RGB;		// line through 3D space, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:			return GL_RGBA;		// line through 3D space plus 1-bit alpha, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:			return GL_RGBA;		// line through 3D space plus line through 1D space, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:			return GL_RGBA;		// line through 3D space plus 4-bit alpha, 4x4 blocks, sRGB
-
-		case GL_COMPRESSED_LUMINANCE_LATC1_EXT:					return GL_RED;		// line through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:			return GL_RG;		// two lines through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:			return GL_RED;		// line through 1D space, 4x4 blocks, signed normalized
-		case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:	return GL_RG;		// two lines through 1D space, 4x4 blocks, signed normalized
-
-		case GL_COMPRESSED_RED_RGTC1:							return GL_RED;		// line through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RG_RGTC2:							return GL_RG;		// two lines through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_RED_RGTC1:					return GL_RED;		// line through 1D space, 4x4 blocks, signed normalized
-		case GL_COMPRESSED_SIGNED_RG_RGTC2:						return GL_RG;		// two lines through 1D space, 4x4 blocks, signed normalized
-
-		case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:				return GL_RGB;		// 3-component, 4x4 blocks, unsigned floating-point
-		case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:				return GL_RGB;		// 3-component, 4x4 blocks, signed floating-point
-		case GL_COMPRESSED_RGBA_BPTC_UNORM:						return GL_RGBA;		// 4-component, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:				return GL_RGBA;		// 4-component, 4x4 blocks, sRGB
-
-		//
-		// ETC
-		//
-		case GL_ETC1_RGB8_OES:									return GL_RGB;		// 3-component ETC1, 4x4 blocks, unsigned normalized
-
-		case GL_COMPRESSED_RGB8_ETC2:							return GL_RGB;		// 3-component ETC2, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:		return GL_RGBA;		// 4-component ETC2 with 1-bit alpha, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA8_ETC2_EAC:						return GL_RGBA;		// 4-component ETC2, 4x4 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB8_ETC2:							return GL_RGB;		// 3-component ETC2, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:		return GL_RGBA;		// 4-component ETC2 with 1-bit alpha, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:				return GL_RGBA;		// 4-component ETC2, 4x4 blocks, sRGB
-
-		case GL_COMPRESSED_R11_EAC:								return GL_RED;		// 1-component ETC, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RG11_EAC:							return GL_RG;		// 2-component ETC, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_R11_EAC:						return GL_RED;		// 1-component ETC, 4x4 blocks, signed normalized
-		case GL_COMPRESSED_SIGNED_RG11_EAC:						return GL_RG;		// 2-component ETC, 4x4 blocks, signed normalized
-
-		//
-		// PVRTC
-		//
-		case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:				return GL_RGB;		// 3-component PVRTC, 16x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:				return GL_RGB;		// 3-component PVRTC,  8x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:				return GL_RGBA;		// 4-component PVRTC, 16x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:				return GL_RGBA;		// 4-component PVRTC,  8x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG:				return GL_RGBA;		// 4-component PVRTC,  8x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG:				return GL_RGBA;		// 4-component PVRTC,  4x4 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:				return GL_RGB;		// 3-component PVRTC, 16x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:				return GL_RGB;		// 3-component PVRTC,  8x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:			return GL_RGBA;		// 4-component PVRTC, 16x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:			return GL_RGBA;		// 4-component PVRTC,  8x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG:			return GL_RGBA;		// 4-component PVRTC,  8x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG:			return GL_RGBA;		// 4-component PVRTC,  4x4 blocks, sRGB
-
-		//
-		// ASTC
-		//
-		case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:					return GL_RGBA;		// 4-component ASTC, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:					return GL_RGBA;		// 4-component ASTC, 5x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:					return GL_RGBA;		// 4-component ASTC, 5x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:					return GL_RGBA;		// 4-component ASTC, 6x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:					return GL_RGBA;		// 4-component ASTC, 6x6 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:					return GL_RGBA;		// 4-component ASTC, 8x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:					return GL_RGBA;		// 4-component ASTC, 8x6 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:					return GL_RGBA;		// 4-component ASTC, 8x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:					return GL_RGBA;		// 4-component ASTC, 10x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:					return GL_RGBA;		// 4-component ASTC, 10x6 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:					return GL_RGBA;		// 4-component ASTC, 10x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:					return GL_RGBA;		// 4-component ASTC, 10x10 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:					return GL_RGBA;		// 4-component ASTC, 12x10 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:					return GL_RGBA;		// 4-component ASTC, 12x12 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:			return GL_RGBA;		// 4-component ASTC, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:			return GL_RGBA;		// 4-component ASTC, 5x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:			return GL_RGBA;		// 4-component ASTC, 5x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:			return GL_RGBA;		// 4-component ASTC, 6x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:			return GL_RGBA;		// 4-component ASTC, 6x6 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:			return GL_RGBA;		// 4-component ASTC, 8x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:			return GL_RGBA;		// 4-component ASTC, 8x6 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:			return GL_RGBA;		// 4-component ASTC, 8x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:			return GL_RGBA;		// 4-component ASTC, 10x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:			return GL_RGBA;		// 4-component ASTC, 10x6 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:			return GL_RGBA;		// 4-component ASTC, 10x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:			return GL_RGBA;		// 4-component ASTC, 10x10 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:			return GL_RGBA;		// 4-component ASTC, 12x10 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:			return GL_RGBA;		// 4-component ASTC, 12x12 blocks, sRGB
-
-		case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES:					return GL_RGBA;		// 4-component ASTC, 3x3x3 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES:					return GL_RGBA;		// 4-component ASTC, 4x3x3 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES:					return GL_RGBA;		// 4-component ASTC, 4x4x3 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES:					return GL_RGBA;		// 4-component ASTC, 4x4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES:					return GL_RGBA;		// 4-component ASTC, 5x4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES:					return GL_RGBA;		// 4-component ASTC, 5x5x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES:					return GL_RGBA;		// 4-component ASTC, 5x5x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES:					return GL_RGBA;		// 4-component ASTC, 6x5x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES:					return GL_RGBA;		// 4-component ASTC, 6x6x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES:					return GL_RGBA;		// 4-component ASTC, 6x6x6 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:			return GL_RGBA;		// 4-component ASTC, 3x3x3 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:			return GL_RGBA;		// 4-component ASTC, 4x3x3 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:			return GL_RGBA;		// 4-component ASTC, 4x4x3 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:			return GL_RGBA;		// 4-component ASTC, 4x4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:			return GL_RGBA;		// 4-component ASTC, 5x4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:			return GL_RGBA;		// 4-component ASTC, 5x5x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:			return GL_RGBA;		// 4-component ASTC, 5x5x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:			return GL_RGBA;		// 4-component ASTC, 6x5x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:			return GL_RGBA;		// 4-component ASTC, 6x6x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES:			return GL_RGBA;		// 4-component ASTC, 6x6x6 blocks, sRGB
-
-		//
-		// ATC
-		//
-		case GL_ATC_RGB_AMD:									return GL_RGB;		// 3-component, 4x4 blocks, unsigned normalized
-		case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:					return GL_RGBA;		// 4-component, 4x4 blocks, unsigned normalized
-		case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:				return GL_RGBA;		// 4-component, 4x4 blocks, unsigned normalized
-
-		//
-		// Palletized
-		//
-		case GL_PALETTE4_RGB8_OES:								return GL_RGB;		// 3-component 8:8:8,   4-bit palette, unsigned normalized
-		case GL_PALETTE4_RGBA8_OES:								return GL_RGBA;		// 4-component 8:8:8:8, 4-bit palette, unsigned normalized
-		case GL_PALETTE4_R5_G6_B5_OES:							return GL_RGB;		// 3-component 5:6:5,   4-bit palette, unsigned normalized
-		case GL_PALETTE4_RGBA4_OES:								return GL_RGBA;		// 4-component 4:4:4:4, 4-bit palette, unsigned normalized
-		case GL_PALETTE4_RGB5_A1_OES:							return GL_RGBA;		// 4-component 5:5:5:1, 4-bit palette, unsigned normalized
-		case GL_PALETTE8_RGB8_OES:								return GL_RGB;		// 3-component 8:8:8,   8-bit palette, unsigned normalized
-		case GL_PALETTE8_RGBA8_OES:								return GL_RGBA;		// 4-component 8:8:8:8, 8-bit palette, unsigned normalized
-		case GL_PALETTE8_R5_G6_B5_OES:							return GL_RGB;		// 3-component 5:6:5,   8-bit palette, unsigned normalized
-		case GL_PALETTE8_RGBA4_OES:								return GL_RGBA;		// 4-component 4:4:4:4, 8-bit palette, unsigned normalized
-		case GL_PALETTE8_RGB5_A1_OES:							return GL_RGBA;		// 4-component 5:5:5:1, 8-bit palette, unsigned normalized
-
-		//
-		// Depth/stencil
-		//
-		case GL_DEPTH_COMPONENT16:								return GL_DEPTH_COMPONENT;
-		case GL_DEPTH_COMPONENT24:								return GL_DEPTH_COMPONENT;
-		case GL_DEPTH_COMPONENT32:								return GL_DEPTH_COMPONENT;
-		case GL_DEPTH_COMPONENT32F:								return GL_DEPTH_COMPONENT;
-		case GL_DEPTH_COMPONENT32F_NV:							return GL_DEPTH_COMPONENT;
-		case GL_STENCIL_INDEX1:									return GL_STENCIL_INDEX;
-		case GL_STENCIL_INDEX4:									return GL_STENCIL_INDEX;
-		case GL_STENCIL_INDEX8:									return GL_STENCIL_INDEX;
-		case GL_STENCIL_INDEX16:								return GL_STENCIL_INDEX;
-		case GL_DEPTH24_STENCIL8:								return GL_DEPTH_STENCIL;
-		case GL_DEPTH32F_STENCIL8:								return GL_DEPTH_STENCIL;
-		case GL_DEPTH32F_STENCIL8_NV:							return GL_DEPTH_STENCIL;
-
-		default:												return GL_INVALID_VALUE;
-	}
-}
-
-static inline GLenum glGetTypeFromInternalFormat( const GLenum internalFormat )
-{
-	switch ( internalFormat )
-	{
-		//
-		// 8 bits per component
-		//
-		case GL_R8:												return GL_UNSIGNED_BYTE;				// 1-component, 8-bit unsigned normalized
-		case GL_RG8:											return GL_UNSIGNED_BYTE;				// 2-component, 8-bit unsigned normalized
-		case GL_RGB8:											return GL_UNSIGNED_BYTE;				// 3-component, 8-bit unsigned normalized
-		case GL_RGBA8:											return GL_UNSIGNED_BYTE;				// 4-component, 8-bit unsigned normalized
-
-		case GL_R8_SNORM:										return GL_BYTE;							// 1-component, 8-bit signed normalized
-		case GL_RG8_SNORM:										return GL_BYTE;							// 2-component, 8-bit signed normalized
-		case GL_RGB8_SNORM:										return GL_BYTE;							// 3-component, 8-bit signed normalized
-		case GL_RGBA8_SNORM:									return GL_BYTE;							// 4-component, 8-bit signed normalized
-
-		case GL_R8UI:											return GL_UNSIGNED_BYTE;				// 1-component, 8-bit unsigned integer
-		case GL_RG8UI:											return GL_UNSIGNED_BYTE;				// 2-component, 8-bit unsigned integer
-		case GL_RGB8UI:											return GL_UNSIGNED_BYTE;				// 3-component, 8-bit unsigned integer
-		case GL_RGBA8UI:										return GL_UNSIGNED_BYTE;				// 4-component, 8-bit unsigned integer
-
-		case GL_R8I:											return GL_BYTE;							// 1-component, 8-bit signed integer
-		case GL_RG8I:											return GL_BYTE;							// 2-component, 8-bit signed integer
-		case GL_RGB8I:											return GL_BYTE;							// 3-component, 8-bit signed integer
-		case GL_RGBA8I:											return GL_BYTE;							// 4-component, 8-bit signed integer
-
-		case GL_SR8:											return GL_UNSIGNED_BYTE;				// 1-component, 8-bit sRGB
-		case GL_SRG8:											return GL_UNSIGNED_BYTE;				// 2-component, 8-bit sRGB
-		case GL_SRGB8:											return GL_UNSIGNED_BYTE;				// 3-component, 8-bit sRGB
-		case GL_SRGB8_ALPHA8:									return GL_UNSIGNED_BYTE;				// 4-component, 8-bit sRGB
-
-		//
-		// 16 bits per component
-		//
-		case GL_R16:											return GL_UNSIGNED_SHORT;				// 1-component, 16-bit unsigned normalized
-		case GL_RG16:											return GL_UNSIGNED_SHORT;				// 2-component, 16-bit unsigned normalized
-		case GL_RGB16:											return GL_UNSIGNED_SHORT;				// 3-component, 16-bit unsigned normalized
-		case GL_RGBA16:											return GL_UNSIGNED_SHORT;				// 4-component, 16-bit unsigned normalized
-
-		case GL_R16_SNORM:										return GL_SHORT;						// 1-component, 16-bit signed normalized
-		case GL_RG16_SNORM:										return GL_SHORT;						// 2-component, 16-bit signed normalized
-		case GL_RGB16_SNORM:									return GL_SHORT;						// 3-component, 16-bit signed normalized
-		case GL_RGBA16_SNORM:									return GL_SHORT;						// 4-component, 16-bit signed normalized
-
-		case GL_R16UI:											return GL_UNSIGNED_SHORT;				// 1-component, 16-bit unsigned integer
-		case GL_RG16UI:											return GL_UNSIGNED_SHORT;				// 2-component, 16-bit unsigned integer
-		case GL_RGB16UI:										return GL_UNSIGNED_SHORT;				// 3-component, 16-bit unsigned integer
-		case GL_RGBA16UI:										return GL_UNSIGNED_SHORT;				// 4-component, 16-bit unsigned integer
-
-		case GL_R16I:											return GL_SHORT;						// 1-component, 16-bit signed integer
-		case GL_RG16I:											return GL_SHORT;						// 2-component, 16-bit signed integer
-		case GL_RGB16I:											return GL_SHORT;						// 3-component, 16-bit signed integer
-		case GL_RGBA16I:										return GL_SHORT;						// 4-component, 16-bit signed integer
-
-		case GL_R16F:											return GL_HALF_FLOAT;					// 1-component, 16-bit floating-point
-		case GL_RG16F:											return GL_HALF_FLOAT;					// 2-component, 16-bit floating-point
-		case GL_RGB16F:											return GL_HALF_FLOAT;					// 3-component, 16-bit floating-point
-		case GL_RGBA16F:										return GL_HALF_FLOAT;					// 4-component, 16-bit floating-point
-
-		//
-		// 32 bits per component
-		//
-		case GL_R32UI:											return GL_UNSIGNED_INT;					// 1-component, 32-bit unsigned integer
-		case GL_RG32UI:											return GL_UNSIGNED_INT;					// 2-component, 32-bit unsigned integer
-		case GL_RGB32UI:										return GL_UNSIGNED_INT;					// 3-component, 32-bit unsigned integer
-		case GL_RGBA32UI:										return GL_UNSIGNED_INT;					// 4-component, 32-bit unsigned integer
-
-		case GL_R32I:											return GL_INT;							// 1-component, 32-bit signed integer
-		case GL_RG32I:											return GL_INT;							// 2-component, 32-bit signed integer
-		case GL_RGB32I:											return GL_INT;							// 3-component, 32-bit signed integer
-		case GL_RGBA32I:										return GL_INT;							// 4-component, 32-bit signed integer
-
-		case GL_R32F:											return GL_FLOAT;						// 1-component, 32-bit floating-point
-		case GL_RG32F:											return GL_FLOAT;						// 2-component, 32-bit floating-point
-		case GL_RGB32F:											return GL_FLOAT;						// 3-component, 32-bit floating-point
-		case GL_RGBA32F:										return GL_FLOAT;						// 4-component, 32-bit floating-point
-
-		//
-		// Packed
-		//
-		case GL_R3_G3_B2:										return GL_UNSIGNED_BYTE_2_3_3_REV;		// 3-component 3:3:2,       unsigned normalized
-		case GL_RGB4:											return GL_UNSIGNED_SHORT_4_4_4_4;		// 3-component 4:4:4,       unsigned normalized
-		case GL_RGB5:											return GL_UNSIGNED_SHORT_5_5_5_1;		// 3-component 5:5:5,       unsigned normalized
-		case GL_RGB565:											return GL_UNSIGNED_SHORT_5_6_5;			// 3-component 5:6:5,       unsigned normalized
-		case GL_RGB10:											return GL_UNSIGNED_INT_10_10_10_2;		// 3-component 10:10:10,    unsigned normalized
-		case GL_RGB12:											return GL_UNSIGNED_SHORT;				// 3-component 12:12:12,    unsigned normalized
-		case GL_RGBA2:											return GL_UNSIGNED_BYTE;				// 4-component 2:2:2:2,     unsigned normalized
-		case GL_RGBA4:											return GL_UNSIGNED_SHORT_4_4_4_4;		// 4-component 4:4:4:4,     unsigned normalized
-		case GL_RGBA12:											return GL_UNSIGNED_SHORT;				// 4-component 12:12:12:12, unsigned normalized
-		case GL_RGB5_A1:										return GL_UNSIGNED_SHORT_5_5_5_1;		// 4-component 5:5:5:1,     unsigned normalized
-		case GL_RGB10_A2:										return GL_UNSIGNED_INT_2_10_10_10_REV;	// 4-component 10:10:10:2,  unsigned normalized
-		case GL_RGB10_A2UI:										return GL_UNSIGNED_INT_2_10_10_10_REV;	// 4-component 10:10:10:2,  unsigned integer
-		case GL_R11F_G11F_B10F:									return GL_UNSIGNED_INT_10F_11F_11F_REV;	// 3-component 11:11:10,    floating-point
-		case GL_RGB9_E5:										return GL_UNSIGNED_INT_5_9_9_9_REV;		// 3-component/exp 9:9:9/5, floating-point
-
-		//
-		// S3TC/DXT/BC
-		//
-
-		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:					return GL_UNSIGNED_BYTE;				// line through 3D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:					return GL_UNSIGNED_BYTE;				// line through 3D space plus 1-bit alpha, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:					return GL_UNSIGNED_BYTE;				// line through 3D space plus line through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:					return GL_UNSIGNED_BYTE;				// line through 3D space plus 4-bit alpha, 4x4 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:					return GL_UNSIGNED_BYTE;				// line through 3D space, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:			return GL_UNSIGNED_BYTE;				// line through 3D space plus 1-bit alpha, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:			return GL_UNSIGNED_BYTE;				// line through 3D space plus line through 1D space, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:			return GL_UNSIGNED_BYTE;				// line through 3D space plus 4-bit alpha, 4x4 blocks, sRGB
-
-		case GL_COMPRESSED_LUMINANCE_LATC1_EXT:					return GL_UNSIGNED_BYTE;				// line through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:			return GL_UNSIGNED_BYTE;				// two lines through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:			return GL_UNSIGNED_BYTE;				// line through 1D space, 4x4 blocks, signed normalized
-		case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:	return GL_UNSIGNED_BYTE;				// two lines through 1D space, 4x4 blocks, signed normalized
-
-		case GL_COMPRESSED_RED_RGTC1:							return GL_UNSIGNED_BYTE;				// line through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RG_RGTC2:							return GL_UNSIGNED_BYTE;				// two lines through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_RED_RGTC1:					return GL_UNSIGNED_BYTE;				// line through 1D space, 4x4 blocks, signed normalized
-		case GL_COMPRESSED_SIGNED_RG_RGTC2:						return GL_UNSIGNED_BYTE;				// two lines through 1D space, 4x4 blocks, signed normalized
-
-		case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:				return GL_FLOAT;						// 3-component, 4x4 blocks, unsigned floating-point
-		case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:				return GL_FLOAT;						// 3-component, 4x4 blocks, signed floating-point
-		case GL_COMPRESSED_RGBA_BPTC_UNORM:						return GL_UNSIGNED_BYTE;				// 4-component, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:				return GL_UNSIGNED_BYTE;				// 4-component, 4x4 blocks, sRGB
-
-		//
-		// ETC
-		//
-		case GL_ETC1_RGB8_OES:									return GL_UNSIGNED_BYTE;				// 3-component ETC1, 4x4 blocks, unsigned normalized" ),
-
-		case GL_COMPRESSED_RGB8_ETC2:							return GL_UNSIGNED_BYTE;				// 3-component ETC2, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:		return GL_UNSIGNED_BYTE;				// 4-component ETC2 with 1-bit alpha, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA8_ETC2_EAC:						return GL_UNSIGNED_BYTE;				// 4-component ETC2, 4x4 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB8_ETC2:							return GL_UNSIGNED_BYTE;				// 3-component ETC2, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:		return GL_UNSIGNED_BYTE;				// 4-component ETC2 with 1-bit alpha, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:				return GL_UNSIGNED_BYTE;				// 4-component ETC2, 4x4 blocks, sRGB
-
-		case GL_COMPRESSED_R11_EAC:								return GL_UNSIGNED_BYTE;				// 1-component ETC, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RG11_EAC:							return GL_UNSIGNED_BYTE;				// 2-component ETC, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_R11_EAC:						return GL_UNSIGNED_BYTE;				// 1-component ETC, 4x4 blocks, signed normalized
-		case GL_COMPRESSED_SIGNED_RG11_EAC:						return GL_UNSIGNED_BYTE;				// 2-component ETC, 4x4 blocks, signed normalized
-
-		//
-		// PVRTC
-		//
-		case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:				return GL_UNSIGNED_BYTE;				// 3-component PVRTC, 16x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:				return GL_UNSIGNED_BYTE;				// 3-component PVRTC,  8x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:				return GL_UNSIGNED_BYTE;				// 4-component PVRTC, 16x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:				return GL_UNSIGNED_BYTE;				// 4-component PVRTC,  8x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG:				return GL_UNSIGNED_BYTE;				// 4-component PVRTC,  8x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG:				return GL_UNSIGNED_BYTE;				// 4-component PVRTC,  4x4 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:				return GL_UNSIGNED_BYTE;				// 3-component PVRTC, 16x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:				return GL_UNSIGNED_BYTE;				// 3-component PVRTC,  8x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:			return GL_UNSIGNED_BYTE;				// 4-component PVRTC, 16x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:			return GL_UNSIGNED_BYTE;				// 4-component PVRTC,  8x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG:			return GL_UNSIGNED_BYTE;				// 4-component PVRTC,  8x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG:			return GL_UNSIGNED_BYTE;				// 4-component PVRTC,  4x4 blocks, sRGB
-
-		//
-		// ASTC
-		//
-		case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 5x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 5x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 6x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 6x6 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 8x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 8x6 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 8x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 10x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 10x6 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 10x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 10x10 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 12x10 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 12x12 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 5x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 5x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 6x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 6x6 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 8x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 8x6 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 8x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 10x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 10x6 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 10x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 10x10 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 12x10 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 12x12 blocks, sRGB
-
-		case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 3x3x3 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 4x3x3 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 4x4x3 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 4x4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 5x4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 5x5x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 5x5x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 6x5x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 6x6x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES:					return GL_UNSIGNED_BYTE;				// 4-component ASTC, 6x6x6 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 3x3x3 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 4x3x3 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 4x4x3 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 4x4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 5x4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 5x5x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 5x5x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 6x5x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 6x6x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES:			return GL_UNSIGNED_BYTE;				// 4-component ASTC, 6x6x6 blocks, sRGB
-
-		//
-		// ATC
-		//
-		case GL_ATC_RGB_AMD:									return GL_UNSIGNED_BYTE;				// 3-component, 4x4 blocks, unsigned normalized
-		case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:					return GL_UNSIGNED_BYTE;				// 4-component, 4x4 blocks, unsigned normalized
-		case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:				return GL_UNSIGNED_BYTE;				// 4-component, 4x4 blocks, unsigned normalized
-
-		//
-		// Palletized
-		//
-		case GL_PALETTE4_RGB8_OES:								return GL_UNSIGNED_BYTE;				// 3-component 8:8:8,   4-bit palette, unsigned normalized
-		case GL_PALETTE4_RGBA8_OES:								return GL_UNSIGNED_BYTE;				// 4-component 8:8:8:8, 4-bit palette, unsigned normalized
-		case GL_PALETTE4_R5_G6_B5_OES:							return GL_UNSIGNED_SHORT_5_6_5;			// 3-component 5:6:5,   4-bit palette, unsigned normalized
-		case GL_PALETTE4_RGBA4_OES:								return GL_UNSIGNED_SHORT_4_4_4_4;		// 4-component 4:4:4:4, 4-bit palette, unsigned normalized
-		case GL_PALETTE4_RGB5_A1_OES:							return GL_UNSIGNED_SHORT_5_5_5_1;		// 4-component 5:5:5:1, 4-bit palette, unsigned normalized
-		case GL_PALETTE8_RGB8_OES:								return GL_UNSIGNED_BYTE;				// 3-component 8:8:8,   8-bit palette, unsigned normalized
-		case GL_PALETTE8_RGBA8_OES:								return GL_UNSIGNED_BYTE;				// 4-component 8:8:8:8, 8-bit palette, unsigned normalized
-		case GL_PALETTE8_R5_G6_B5_OES:							return GL_UNSIGNED_SHORT_5_6_5;			// 3-component 5:6:5,   8-bit palette, unsigned normalized
-		case GL_PALETTE8_RGBA4_OES:								return GL_UNSIGNED_SHORT_4_4_4_4;		// 4-component 4:4:4:4, 8-bit palette, unsigned normalized
-		case GL_PALETTE8_RGB5_A1_OES:							return GL_UNSIGNED_SHORT_5_5_5_1;		// 4-component 5:5:5:1, 8-bit palette, unsigned normalized
-
-		//
-		// Depth/stencil
-		//
-		case GL_DEPTH_COMPONENT16:								return GL_UNSIGNED_SHORT;
-		case GL_DEPTH_COMPONENT24:								return GL_UNSIGNED_INT_24_8;
-		case GL_DEPTH_COMPONENT32:								return GL_UNSIGNED_INT;
-		case GL_DEPTH_COMPONENT32F:								return GL_FLOAT;
-		case GL_DEPTH_COMPONENT32F_NV:							return GL_FLOAT;
-		case GL_STENCIL_INDEX1:									return GL_UNSIGNED_BYTE;
-		case GL_STENCIL_INDEX4:									return GL_UNSIGNED_BYTE;
-		case GL_STENCIL_INDEX8:									return GL_UNSIGNED_BYTE;
-		case GL_STENCIL_INDEX16:								return GL_UNSIGNED_SHORT;
-		case GL_DEPTH24_STENCIL8:								return GL_UNSIGNED_INT_24_8;
-		case GL_DEPTH32F_STENCIL8:								return GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
-		case GL_DEPTH32F_STENCIL8_NV:							return GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
-
-		default:												return GL_INVALID_VALUE;
-	}
-}
-
-static inline unsigned int glGetTypeSizeFromType(GLenum type)
-{
-    switch (type) {
-        case GL_BYTE:
-        case GL_UNSIGNED_BYTE:
-        case GL_UNSIGNED_BYTE_3_3_2:
-        case GL_UNSIGNED_BYTE_2_3_3_REV:
-            return 1;
-            
-        case GL_SHORT:
-        case GL_UNSIGNED_SHORT:
-        case GL_UNSIGNED_SHORT_5_6_5:
-        case GL_UNSIGNED_SHORT_4_4_4_4:
-        case GL_UNSIGNED_SHORT_5_5_5_1:
-        case GL_UNSIGNED_SHORT_5_6_5_REV:
-        case GL_UNSIGNED_SHORT_4_4_4_4_REV:
-        case GL_UNSIGNED_SHORT_1_5_5_5_REV:
-        case GL_HALF_FLOAT:
-            return 2;
-            
-        case GL_INT:
-        case GL_UNSIGNED_INT:
-        case GL_UNSIGNED_INT_8_8_8_8:
-        case GL_UNSIGNED_INT_8_8_8_8_REV:
-        case GL_UNSIGNED_INT_10_10_10_2:
-        case GL_UNSIGNED_INT_2_10_10_10_REV:
-        case GL_UNSIGNED_INT_24_8:
-        case GL_UNSIGNED_INT_10F_11F_11F_REV:
-        case GL_UNSIGNED_INT_5_9_9_9_REV:
-        case GL_FLOAT:
-        case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
-            return 4;
-
-        default:
-            return GL_INVALID_VALUE;
-    }
-}
-
-typedef enum GlFormatSizeFlagBits {
-	GL_FORMAT_SIZE_PACKED_BIT				= 0x00000001,
-	GL_FORMAT_SIZE_COMPRESSED_BIT			= 0x00000002,
-	GL_FORMAT_SIZE_PALETTIZED_BIT			= 0x00000004,
-	GL_FORMAT_SIZE_DEPTH_BIT				= 0x00000008,
-	GL_FORMAT_SIZE_STENCIL_BIT				= 0x00000010,
-} GlFormatSizeFlagBits;
-
-typedef unsigned int GlFormatSizeFlags;
-
-typedef struct GlFormatSize {
-	GlFormatSizeFlags	flags;
-	unsigned int		paletteSizeInBits;
-	unsigned int		blockSizeInBits;
-	unsigned int		blockWidth;			// in texels
-	unsigned int		blockHeight;		// in texels
-	unsigned int		blockDepth;			// in texels
-} GlFormatSize;
-
-static inline void glGetFormatSize( const GLenum internalFormat, GlFormatSize * pFormatSize )
-{
-	switch ( internalFormat )
-	{
-		//
-		// 8 bits per component
-		//
-		case GL_R8:												// 1-component, 8-bit unsigned normalized
-		case GL_R8_SNORM:										// 1-component, 8-bit signed normalized
-		case GL_R8UI:											// 1-component, 8-bit unsigned integer
-		case GL_R8I:											// 1-component, 8-bit signed integer
-		case GL_SR8:											// 1-component, 8-bit sRGB
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 1 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RG8:											// 2-component, 8-bit unsigned normalized
-		case GL_RG8_SNORM:										// 2-component, 8-bit signed normalized
-		case GL_RG8UI:											// 2-component, 8-bit unsigned integer
-		case GL_RG8I:											// 2-component, 8-bit signed integer
-		case GL_SRG8:											// 2-component, 8-bit sRGB
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 2 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGB8:											// 3-component, 8-bit unsigned normalized
-		case GL_RGB8_SNORM:										// 3-component, 8-bit signed normalized
-		case GL_RGB8UI:											// 3-component, 8-bit unsigned integer
-		case GL_RGB8I:											// 3-component, 8-bit signed integer
-		case GL_SRGB8:											// 3-component, 8-bit sRGB
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 3 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGBA8:											// 4-component, 8-bit unsigned normalized
-		case GL_RGBA8_SNORM:									// 4-component, 8-bit signed normalized
-		case GL_RGBA8UI:										// 4-component, 8-bit unsigned integer
-		case GL_RGBA8I:											// 4-component, 8-bit signed integer
-		case GL_SRGB8_ALPHA8:									// 4-component, 8-bit sRGB
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 4 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		//
-		// 16 bits per component
-		//
-		case GL_R16:											// 1-component, 16-bit unsigned normalized
-		case GL_R16_SNORM:										// 1-component, 16-bit signed normalized
-		case GL_R16UI:											// 1-component, 16-bit unsigned integer
-		case GL_R16I:											// 1-component, 16-bit signed integer
-		case GL_R16F:											// 1-component, 16-bit floating-point
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 2 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RG16:											// 2-component, 16-bit unsigned normalized
-		case GL_RG16_SNORM:										// 2-component, 16-bit signed normalized
-		case GL_RG16UI:											// 2-component, 16-bit unsigned integer
-		case GL_RG16I:											// 2-component, 16-bit signed integer
-		case GL_RG16F:											// 2-component, 16-bit floating-point
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 4 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGB16:											// 3-component, 16-bit unsigned normalized
-		case GL_RGB16_SNORM:									// 3-component, 16-bit signed normalized
-		case GL_RGB16UI:										// 3-component, 16-bit unsigned integer
-		case GL_RGB16I:											// 3-component, 16-bit signed integer
-		case GL_RGB16F:											// 3-component, 16-bit floating-point
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 6 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGBA16:											// 4-component, 16-bit unsigned normalized
-		case GL_RGBA16_SNORM:									// 4-component, 16-bit signed normalized
-		case GL_RGBA16UI:										// 4-component, 16-bit unsigned integer
-		case GL_RGBA16I:										// 4-component, 16-bit signed integer
-		case GL_RGBA16F:										// 4-component, 16-bit floating-point
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 8 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		//
-		// 32 bits per component
-		//
-		case GL_R32UI:											// 1-component, 32-bit unsigned integer
-		case GL_R32I:											// 1-component, 32-bit signed integer
-		case GL_R32F:											// 1-component, 32-bit floating-point
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 4 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RG32UI:											// 2-component, 32-bit unsigned integer
-		case GL_RG32I:											// 2-component, 32-bit signed integer
-		case GL_RG32F:											// 2-component, 32-bit floating-point
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 8 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGB32UI:										// 3-component, 32-bit unsigned integer
-		case GL_RGB32I:											// 3-component, 32-bit signed integer
-		case GL_RGB32F:											// 3-component, 32-bit floating-point
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 12 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGBA32UI:										// 4-component, 32-bit unsigned integer
-		case GL_RGBA32I:										// 4-component, 32-bit signed integer
-		case GL_RGBA32F:										// 4-component, 32-bit floating-point
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		//
-		// Packed
-		//
-		case GL_R3_G3_B2:										// 3-component 3:3:2, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGB4:											// 3-component 4:4:4, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 12;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGB5:											// 3-component 5:5:5, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGB565:											// 3-component 5:6:5, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGB10:											// 3-component 10:10:10, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 32;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGB12:											// 3-component 12:12:12, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 36;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGBA2:											// 4-component 2:2:2:2, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGBA4:											// 4-component 4:4:4:4, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGBA12:											// 4-component 12:12:12:12, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 48;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGB5_A1:										// 4-component 5:5:5:1, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 32;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGB10_A2:										// 4-component 10:10:10:2, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 32;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_RGB10_A2UI:										// 4-component 10:10:10:2, unsigned integer
-			pFormatSize->flags = GL_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 32;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_R11F_G11F_B10F:									// 3-component 11:11:10, floating-point
-		case GL_RGB9_E5:										// 3-component/exp 9:9:9/5, floating-point
-			pFormatSize->flags = GL_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 32;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		//
-		// S3TC/DXT/BC
-		//
-		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:					// line through 3D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:					// line through 3D space plus 1-bit alpha, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:					// line through 3D space, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:			// line through 3D space plus 1-bit alpha, 4x4 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 64;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:					// line through 3D space plus line through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:					// line through 3D space plus 4-bit alpha, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:			// line through 3D space plus line through 1D space, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:			// line through 3D space plus 4-bit alpha, 4x4 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		case GL_COMPRESSED_LUMINANCE_LATC1_EXT:					// line through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:			// line through 1D space, 4x4 blocks, signed normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 64;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:			// two lines through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:	// two lines through 1D space, 4x4 blocks, signed normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		case GL_COMPRESSED_RED_RGTC1:							// line through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_RED_RGTC1:					// line through 1D space, 4x4 blocks, signed normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 64;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RG_RGTC2:							// two lines through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_RG_RGTC2:						// two lines through 1D space, 4x4 blocks, signed normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:				// 3-component, 4x4 blocks, unsigned floating-point
-		case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:				// 3-component, 4x4 blocks, signed floating-point
-		case GL_COMPRESSED_RGBA_BPTC_UNORM:						// 4-component, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:				// 4-component, 4x4 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		//
-		// ETC
-		//
-		case GL_ETC1_RGB8_OES:									// 3-component ETC1, 4x4 blocks, unsigned normalized" ),
-		case GL_COMPRESSED_RGB8_ETC2:							// 3-component ETC2, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ETC2:							// 3-component ETC2, 4x4 blocks, sRGB
-		case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:		// 4-component ETC2 with 1-bit alpha, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:		// 4-component ETC2 with 1-bit alpha, 4x4 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 64;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA8_ETC2_EAC:						// 4-component ETC2, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:				// 4-component ETC2, 4x4 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		case GL_COMPRESSED_R11_EAC:								// 1-component ETC, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_R11_EAC:						// 1-component ETC, 4x4 blocks, signed normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 64;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RG11_EAC:							// 2-component ETC, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_RG11_EAC:						// 2-component ETC, 4x4 blocks, signed normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		//
-		// PVRTC
-		//
-		case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:				// 3-component PVRTC, 16x8 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:				// 3-component PVRTC, 16x8 blocks, sRGB
-		case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:				// 4-component PVRTC, 16x8 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:			// 4-component PVRTC, 16x8 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 64;
-			pFormatSize->blockWidth = 16;
-			pFormatSize->blockHeight = 8;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:				// 3-component PVRTC, 8x8 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:				// 3-component PVRTC, 8x8 blocks, sRGB
-		case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:				// 4-component PVRTC, 8x8 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:			// 4-component PVRTC, 8x8 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 64;
-			pFormatSize->blockWidth = 8;
-			pFormatSize->blockHeight = 8;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG:				// 4-component PVRTC, 8x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG:			// 4-component PVRTC, 8x4 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 64;
-			pFormatSize->blockWidth = 8;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG:				// 4-component PVRTC, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG:			// 4-component PVRTC, 4x4 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 64;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		//
-		// ASTC
-		//
-		case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:					// 4-component ASTC, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:			// 4-component ASTC, 4x4 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:					// 4-component ASTC, 5x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:			// 4-component ASTC, 5x4 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 5;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:					// 4-component ASTC, 5x5 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:			// 4-component ASTC, 5x5 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 5;
-			pFormatSize->blockHeight = 5;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:					// 4-component ASTC, 6x5 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:			// 4-component ASTC, 6x5 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 6;
-			pFormatSize->blockHeight = 5;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:					// 4-component ASTC, 6x6 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:			// 4-component ASTC, 6x6 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 6;
-			pFormatSize->blockHeight = 6;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:					// 4-component ASTC, 8x5 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:			// 4-component ASTC, 8x5 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 8;
-			pFormatSize->blockHeight = 5;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:					// 4-component ASTC, 8x6 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:			// 4-component ASTC, 8x6 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 8;
-			pFormatSize->blockHeight = 6;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:					// 4-component ASTC, 8x8 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:			// 4-component ASTC, 8x8 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 8;
-			pFormatSize->blockHeight = 8;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:					// 4-component ASTC, 10x5 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:			// 4-component ASTC, 10x5 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 10;
-			pFormatSize->blockHeight = 5;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:					// 4-component ASTC, 10x6 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:			// 4-component ASTC, 10x6 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 10;
-			pFormatSize->blockHeight = 6;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:					// 4-component ASTC, 10x8 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:			// 4-component ASTC, 10x8 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 10;
-			pFormatSize->blockHeight = 8;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:					// 4-component ASTC, 10x10 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:			// 4-component ASTC, 10x10 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 10;
-			pFormatSize->blockHeight = 10;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:					// 4-component ASTC, 12x10 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:			// 4-component ASTC, 12x10 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 12;
-			pFormatSize->blockHeight = 10;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:					// 4-component ASTC, 12x12 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:			// 4-component ASTC, 12x12 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 12;
-			pFormatSize->blockHeight = 12;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES:					// 4-component ASTC, 3x3x3 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:			// 4-component ASTC, 3x3x3 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 3;
-			pFormatSize->blockHeight = 3;
-			pFormatSize->blockDepth = 3;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES:					// 4-component ASTC, 4x3x3 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:			// 4-component ASTC, 4x3x3 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 3;
-			pFormatSize->blockDepth = 3;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES:					// 4-component ASTC, 4x4x3 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:			// 4-component ASTC, 4x4x3 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 3;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES:					// 4-component ASTC, 4x4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:			// 4-component ASTC, 4x4x4 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 4;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES:					// 4-component ASTC, 5x4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:			// 4-component ASTC, 5x4x4 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 5;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 4;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES:					// 4-component ASTC, 5x5x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:			// 4-component ASTC, 5x5x4 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 5;
-			pFormatSize->blockHeight = 5;
-			pFormatSize->blockDepth = 4;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES:					// 4-component ASTC, 5x5x5 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:			// 4-component ASTC, 5x5x5 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 5;
-			pFormatSize->blockHeight = 5;
-			pFormatSize->blockDepth = 5;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES:					// 4-component ASTC, 6x5x5 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:			// 4-component ASTC, 6x5x5 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 6;
-			pFormatSize->blockHeight = 5;
-			pFormatSize->blockDepth = 5;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES:					// 4-component ASTC, 6x6x5 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:			// 4-component ASTC, 6x6x5 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 6;
-			pFormatSize->blockHeight = 6;
-			pFormatSize->blockDepth = 5;
-			break;
-		case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES:					// 4-component ASTC, 6x6x6 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES:			// 4-component ASTC, 6x6x6 blocks, sRGB
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 6;
-			pFormatSize->blockHeight = 6;
-			pFormatSize->blockDepth = 6;
-			break;
-
-		//
-		// ATC
-		//
-		case GL_ATC_RGB_AMD:									// 3-component, 4x4 blocks, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 64;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:					// 4-component, 4x4 blocks, unsigned normalized
-		case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:				// 4-component, 4x4 blocks, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 128;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		//
-		// Palletized
-		//
-		case GL_PALETTE4_RGB8_OES:								// 3-component 8:8:8,   4-bit palette, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PALETTIZED_BIT;
-			pFormatSize->paletteSizeInBits = 16 * 24;
-			pFormatSize->blockSizeInBits = 4;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_PALETTE4_RGBA8_OES:								// 4-component 8:8:8:8, 4-bit palette, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PALETTIZED_BIT;
-			pFormatSize->paletteSizeInBits = 16 * 32;
-			pFormatSize->blockSizeInBits = 4;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_PALETTE4_R5_G6_B5_OES:							// 3-component 5:6:5,   4-bit palette, unsigned normalized
-		case GL_PALETTE4_RGBA4_OES:								// 4-component 4:4:4:4, 4-bit palette, unsigned normalized
-		case GL_PALETTE4_RGB5_A1_OES:							// 4-component 5:5:5:1, 4-bit palette, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PALETTIZED_BIT;
-			pFormatSize->paletteSizeInBits = 16 * 16;
-			pFormatSize->blockSizeInBits = 4;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_PALETTE8_RGB8_OES:								// 3-component 8:8:8,   8-bit palette, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PALETTIZED_BIT;
-			pFormatSize->paletteSizeInBits = 256 * 24;
-			pFormatSize->blockSizeInBits = 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_PALETTE8_RGBA8_OES:								// 4-component 8:8:8:8, 8-bit palette, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PALETTIZED_BIT;
-			pFormatSize->paletteSizeInBits = 256 * 32;
-			pFormatSize->blockSizeInBits = 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_PALETTE8_R5_G6_B5_OES:							// 3-component 5:6:5,   8-bit palette, unsigned normalized
-		case GL_PALETTE8_RGBA4_OES:								// 4-component 4:4:4:4, 8-bit palette, unsigned normalized
-		case GL_PALETTE8_RGB5_A1_OES:							// 4-component 5:5:5:1, 8-bit palette, unsigned normalized
-			pFormatSize->flags = GL_FORMAT_SIZE_PALETTIZED_BIT;
-			pFormatSize->paletteSizeInBits = 256 * 16;
-			pFormatSize->blockSizeInBits = 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		//
-		// Depth/stencil
-		//
-		case GL_DEPTH_COMPONENT16:
-			pFormatSize->flags = GL_FORMAT_SIZE_DEPTH_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_DEPTH_COMPONENT24:
-		case GL_DEPTH_COMPONENT32:
-		case GL_DEPTH_COMPONENT32F:
-		case GL_DEPTH_COMPONENT32F_NV:
-			pFormatSize->flags = GL_FORMAT_SIZE_DEPTH_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 32;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_STENCIL_INDEX1:
-			pFormatSize->flags = GL_FORMAT_SIZE_STENCIL_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 1;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_STENCIL_INDEX4:
-			pFormatSize->flags = GL_FORMAT_SIZE_STENCIL_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 4;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_STENCIL_INDEX8:
-			pFormatSize->flags = GL_FORMAT_SIZE_STENCIL_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_STENCIL_INDEX16:
-			pFormatSize->flags = GL_FORMAT_SIZE_STENCIL_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_DEPTH24_STENCIL8:
-			pFormatSize->flags = GL_FORMAT_SIZE_DEPTH_BIT | GL_FORMAT_SIZE_STENCIL_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 32;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case GL_DEPTH32F_STENCIL8:
-		case GL_DEPTH32F_STENCIL8_NV:
-			pFormatSize->flags = GL_FORMAT_SIZE_DEPTH_BIT | GL_FORMAT_SIZE_STENCIL_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 64;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-
-		default:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-	}
-}
-
-#endif // !GL_FORMAT_H
diff --git a/external/KTX-Software-master/lib/gl_funcptrs.h b/external/KTX-Software-master/lib/gl_funcptrs.h
deleted file mode 100644
index a9c644abbda7b600873dd7201d419954d3890208..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/gl_funcptrs.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/* $Id: c29f4818e74655d62754e26efdab99cb2d2ca638 $ */
-
-/*
- * ©2010-2017 The khronos Group, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Author: Mark Callow based on code from Georg Kolling
- */
-
-#ifndef GL_FUNCPTRS_H
-#define GL_FUNCPTRS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if KTX_USE_GETPROC
-  // Not defined in glew.h.
-  typedef void (GL_APIENTRY* PFNGLTEXIMAGE1DPROC) (
-                    GLenum target, GLint level, GLint internalformat,
-                    GLsizei width, GLint border, GLenum format, GLenum type,
-                    const GLvoid *pixels
-                                                  );
-#endif
-
-extern PFNGLTEXIMAGE1DPROC pfGlTexImage1D;
-extern PFNGLTEXIMAGE3DPROC pfGlTexImage3D;
-extern PFNGLCOMPRESSEDTEXIMAGE1DPROC pfGlCompressedTexImage1D;
-extern PFNGLCOMPRESSEDTEXIMAGE3DPROC pfGlCompressedTexImage3D;
-extern PFNGLGENERATEMIPMAPPROC pfGlGenerateMipmap;
-extern PFNGLGETSTRINGIPROC pfGlGetStringi;
-
-#define DECLARE_GL_FUNCPTRS \
-    PFNGLTEXIMAGE1DPROC pfGlTexImage1D; \
-    PFNGLTEXIMAGE3DPROC pfGlTexImage3D; \
-    PFNGLCOMPRESSEDTEXIMAGE1DPROC pfGlCompressedTexImage1D; \
-    PFNGLCOMPRESSEDTEXIMAGE3DPROC pfGlCompressedTexImage3D; \
-    PFNGLGENERATEMIPMAPPROC pfGlGenerateMipmap; \
-    PFNGLGETSTRINGIPROC pfGlGetStringi;
-
-#define INITIALIZE_GL_FUNCPTRS \
-    pfGlTexImage1D = glTexImage1D; \
-    pfGlTexImage3D = glTexImage3D; \
-    pfGlCompressedTexImage1D = glCompressedTexImage1D; \
-    pfGlCompressedTexImage3D = glCompressedTexImage3D; \
-    pfGlGenerateMipmap = glGenerateMipmap; \
-    pfGlGetStringi = glGetStringi;
-    
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GL_FUNCPTRS_H */
diff --git a/external/KTX-Software-master/lib/gles1_funcptrs.h b/external/KTX-Software-master/lib/gles1_funcptrs.h
deleted file mode 100644
index 4b96da9914d73c9a9e5f910813c72249fac77f4f..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/gles1_funcptrs.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/* $Id: a9dea3dfe7b8266c56bd790f15e03e8e7e1baa8e $ */
-
-/*
- * ©2010-2017 The khronos Group, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Author: Mark Callow based on code from Georg Kolling
- */
-
-#ifndef GLES1_FUNCPTRS_H
-#define GLES1_FUNCPTRS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* remove these where already defined as typedefs (GCC 4 complains of duplicate definitions) */
-typedef void (GL_APIENTRY* PFNGLTEXIMAGE1DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
-typedef void (GL_APIENTRY* PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
-typedef void (GL_APIENTRY* PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
-typedef void (GL_APIENTRY* PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
-typedef void (GL_APIENTRY* PFNGLGENERATEMIPMAPPROC) (GLenum target);
-typedef const GLubyte* (GL_APIENTRY* PFNGLGETSTRINGIPROC) (GLenum name, GLint index);
-
-extern PFNGLTEXIMAGE1DPROC pfGlTexImage1D;
-extern PFNGLTEXIMAGE3DPROC pfGlTexImage3D;
-extern PFNGLCOMPRESSEDTEXIMAGE1DPROC pfGlCompressedTexImage1D;
-extern PFNGLCOMPRESSEDTEXIMAGE3DPROC pfGlCompressedTexImage3D;
-extern PFNGLGENERATEMIPMAPPROC pfGlGenerateMipmap;
-extern PFNGLGETSTRINGIPROC pfGlGetStringi;
-
-#define DECLARE_GL_FUNCPTRS \
-    PFNGLTEXIMAGE1DPROC pfGlTexImage1D; \
-    PFNGLTEXIMAGE3DPROC pfGlTexImage3D; \
-    PFNGLCOMPRESSEDTEXIMAGE1DPROC pfGlCompressedTexImage1D; \
-    PFNGLCOMPRESSEDTEXIMAGE3DPROC pfGlCompressedTexImage3D; \
-    PFNGLGENERATEMIPMAPPROC pfGlGenerateMipmap; \
-    PFNGLGETSTRINGIPROC pfGlGetStringi;
-
-#define INITIALIZE_GL_FUNCPTRS \
-    pfGlTexImage1D = 0; \
-    pfGlTexImage3D = 0; \
-    pfGlCompressedTexImage1D = 0; \
-    pfGlCompressedTexImage3D = 0; \
-    pfGlGenerateMipmap = 0; \
-    pfGlGetStringi = 0;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GLES1_FUNCPTRS_H */
diff --git a/external/KTX-Software-master/lib/gles2_funcptrs.h b/external/KTX-Software-master/lib/gles2_funcptrs.h
deleted file mode 100644
index 149469590370271936917b31ee04eb17849ad8e7..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/gles2_funcptrs.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/* $Id: f780b88290b1aa6df0104020b75e21904e53ff1c $ */
-
-/*
- * ©2010-2017 The khronos Group, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Author: Mark Callow based on code from Georg Kolling
- */
-
-#ifndef GLES2_FUNCPTRS_H
-#define GLES2_FUNCPTRS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* remove these where already defined as typedefs (GCC 4 complains of duplicate definitions) */
-typedef void (GL_APIENTRY* PFNGLTEXIMAGE1DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
-typedef void (GL_APIENTRY* PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
-typedef void (GL_APIENTRY* PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
-typedef void (GL_APIENTRY* PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
-typedef const GLubyte* (GL_APIENTRY* PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
-
-extern PFNGLTEXIMAGE1DPROC pfGlTexImage1D;
-extern PFNGLTEXIMAGE3DPROC pfGlTexImage3D;
-extern PFNGLCOMPRESSEDTEXIMAGE1DPROC pfGlCompressedTexImage1D;
-extern PFNGLCOMPRESSEDTEXIMAGE3DPROC pfGlCompressedTexImage3D;
-extern PFNGLGENERATEMIPMAPPROC pfGlGenerateMipmap;
-extern PFNGLGETSTRINGIPROC pfGlGetStringi;
-
-#define DECLARE_GL_FUNCPTRS \
-    PFNGLTEXIMAGE1DPROC pfGlTexImage1D; \
-    PFNGLTEXIMAGE3DPROC pfGlTexImage3D; \
-    PFNGLCOMPRESSEDTEXIMAGE1DPROC pfGlCompressedTexImage1D; \
-    PFNGLCOMPRESSEDTEXIMAGE3DPROC pfGlCompressedTexImage3D; \
-    PFNGLGENERATEMIPMAPPROC pfGlGenerateMipmap; \
-    PFNGLGETSTRINGIPROC pfGlGetStringi;
-
-#define INITIALIZE_GL_FUNCPTRS \
-    pfGlTexImage1D = 0; \
-    pfGlTexImage3D = 0; \
-    pfGlCompressedTexImage1D = 0; \
-    pfGlCompressedTexImage3D = 0; \
-    pfGlGenerateMipmap = glGenerateMipmap; \
-    pfGlGetStringi = 0;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GLES2_FUNCPTRS_H */
diff --git a/external/KTX-Software-master/lib/gles3_funcptrs.h b/external/KTX-Software-master/lib/gles3_funcptrs.h
deleted file mode 100644
index b7ea291c40e32d37665fa8047fc65d2365673d30..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/gles3_funcptrs.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/* $Id: 81315679d0a7bf28f92251adeb0cfea199e013fe $ */
-
-/*
- * ©2010-2017 The khronos Group, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Author: Mark Callow based on code from Georg Kolling
- */
-
-#ifndef GLES3_FUNCPTRS_H
-#define GLES3_FUNCPTRS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* remove these where already defined as typedefs */
-typedef void (GL_APIENTRY* PFNGLTEXIMAGE1DPROC) (
-                        GLenum target, GLint level, GLint internalformat,
-                        GLsizei width, GLint border, GLenum format,
-                        GLenum type, const GLvoid *pixels
-                                                );
-typedef void (GL_APIENTRY* PFNGLCOMPRESSEDTEXIMAGE1DPROC) (
-                        GLenum target, GLint level, GLenum internalformat,
-                        GLsizei width, GLint border, GLsizei imageSize,
-                        const GLvoid *data
-                                                          );
-
-extern PFNGLTEXIMAGE1DPROC pfGlTexImage1D;
-extern PFNGLTEXIMAGE3DPROC pfGlTexImage3D;
-extern PFNGLCOMPRESSEDTEXIMAGE1DPROC pfGlCompressedTexImage1D;
-extern PFNGLCOMPRESSEDTEXIMAGE3DPROC pfGlCompressedTexImage3D;
-extern PFNGLGENERATEMIPMAPPROC pfGlGenerateMipmap;
-extern PFNGLGETSTRINGIPROC pfGlGetStringi;
-    
-#define DECLARE_GL_FUNCPTRS \
-    PFNGLTEXIMAGE1DPROC pfGlTexImage1D; \
-    PFNGLTEXIMAGE3DPROC pfGlTexImage3D; \
-    PFNGLCOMPRESSEDTEXIMAGE1DPROC pfGlCompressedTexImage1D; \
-    PFNGLCOMPRESSEDTEXIMAGE3DPROC pfGlCompressedTexImage3D; \
-    PFNGLGENERATEMIPMAPPROC pfGlGenerateMipmap; \
-    PFNGLGETSTRINGIPROC pfGlGetStringi;
-
-#define INITIALIZE_GL_FUNCPTRS \
-    pfGlTexImage1D = 0; \
-    pfGlTexImage3D = glTexImage3D; \
-    pfGlCompressedTexImage1D = 0; \
-    pfGlCompressedTexImage3D = glCompressedTexImage3D; \
-    pfGlGenerateMipmap = glGenerateMipmap; \
-    pfGlGetStringi = glGetStringi;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GLES3_FUNCPTRS_H */
diff --git a/external/KTX-Software-master/lib/glloader.c b/external/KTX-Software-master/lib/glloader.c
deleted file mode 100644
index 1089898dc99763f3d5fad4cacfa02024ec10af66..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/glloader.c
+++ /dev/null
@@ -1,1115 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/*
- * ©2010-2018 Mark Callow.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @internal
- * @file
- * @~English
- *
- * @brief Functions for instantiating GL or GLES textures from KTX files.
- *
- * @author Georg Kolling, Imagination Technology
- * @author Mark Callow, HI Corporation & Edgewise Consulting
- */
-
-#ifdef _WIN32
-#define _CRT_SECURE_NO_WARNINGS
-#endif
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-
-#if KTX_OPENGL
-
-  #ifdef _WIN32
-    #include <windows.h>
-    #undef KTX_USE_GETPROC  /* Must use GETPROC on Windows */
-    #define KTX_USE_GETPROC 1
-  #else
-    #if !defined(KTX_USE_GETPROC)
-      #define KTX_USE_GETPROC 0
-    #endif
-  #endif
-  #if KTX_USE_GETPROC
-    #include <GL/glew.h>
-  #else
-    #define GL_GLEXT_PROTOTYPES
-    #include <GL/glcorearb.h>
-  #endif
-
-  #define GL_APIENTRY APIENTRY
-  #include "gl_funcptrs.h"
-
-#elif KTX_OPENGL_ES1
-
-  #include <GLES/gl.h>
-  #include <GLES/glext.h>
-  #include "gles1_funcptrs.h"
-
-#elif KTX_OPENGL_ES2
-
-  #define GL_GLEXT_PROTOTYPES
-  #include <GLES2/gl2.h>
-  #include <GLES2/gl2ext.h>
-  #include "gles2_funcptrs.h"
-
-#elif KTX_OPENGL_ES3
-
-  #define GL_GLEXT_PROTOTYPES
-  #include <GLES3/gl3.h>
-  #include <GLES2/gl2ext.h>
-  #include "gles3_funcptrs.h"
-
-#else
-  #error Please #define one of KTX_OPENGL, KTX_OPENGL_ES1, KTX_OPENGL_ES2 or KTX_OPENGL_ES3 as 1
-#endif
-
-#include "ktx.h"
-#include "ktxint.h"
-#include "ktxgl.h"
-
-DECLARE_GL_FUNCPTRS
-
-/**
- * @defgroup ktx_glloader OpenGL Texture Image Loader
- * @brief Create texture objects in current OpenGL context.
- * @{
- */
-
-/**
- * @example glloader.c
- * This is an example of using the low-level ktxTexture API to create and load
- * an OpenGL texture. It is a fragment of the code used by
- * @ref ktxTexture_GLUpload which underpins the @c ktxLoadTexture* functions.
- *
- * @code
- * #include <ktx.h>
- * @endcode
- *
- * This structure is used to pass to a callback function data that is uniform
- * across all images.
- * @snippet this cbdata
- *
- * One of these callbacks, selected by @ref ktxTexture_GLUpload based on the
- * dimensionality and arrayness of the texture, is called from
- * @ref ktxTexture_IterateLevelFaces to upload the texture data to OpenGL.
- * @snippet this imageCallbacks
- *
- * This function creates the GL texture object and sets up the callbacks to
- * load the image data into it.
- * @snippet this loadGLTexture
- */
-
-/**
- * @internal
- * @~English
- * @brief Additional contextProfile bit indicating an OpenGL ES context.
- *
- * This is the same value NVIDIA returns when using an OpenGL ES profile
- * of their desktop drivers. However it is not specified in any official
- * specification as OpenGL ES does not support the GL_CONTEXT_PROFILE_MASK
- * query.
- */
-#define _CONTEXT_ES_PROFILE_BIT 0x4
-
-/**
- * @internal
- * @~English
- * @name Supported Sized Format Macros
- *
- * These macros describe values that may be used with the sizedFormats
- * variable.
- */
-/**@{*/
-#define _NON_LEGACY_FORMATS 0x1 /*< @internal Non-legacy sized formats are supported. */
-#define _LEGACY_FORMATS 0x2  /*< @internal Legacy sized formats are supported. */
-/**
- * @internal
- * @~English
- * @brief All sized formats are supported
- */
-#define _ALL_SIZED_FORMATS (_NON_LEGACY_FORMATS | _LEGACY_FORMATS)
-#define _NO_SIZED_FORMATS 0 /*< @internal No sized formats are supported. */
-/**@}*/
-
-/**
- * @internal
- * @~English
- * @brief indicates the profile of the current context.
- */
-static GLint contextProfile = 0;
-/**
- * @internal
- * @~English
- * @brief Indicates what sized texture formats are supported
- *        by the current context.
- */
-static GLint sizedFormats = _ALL_SIZED_FORMATS;
-static GLboolean supportsSwizzle = GL_TRUE;
-/**
- * @internal
- * @~English
- * @brief Indicates which R16 & RG16 formats are supported by the current
- *        context.
- */
-static GLint R16Formats = _KTX_ALL_R16_FORMATS;
-/**
- * @internal
- * @~English
- * @brief Indicates if the current context supports sRGB textures.
- */
-static GLboolean supportsSRGB = GL_TRUE;
-/**
- * @internal
- * @~English
- * @brief Indicates if the current context supports cube map arrays.
- */
-static GLboolean supportsCubeMapArrays = GL_FALSE;
-
-/**
- * @internal
- * @~English
- * @brief Workaround mismatch of glGetString declaration and standard string
- *        function parameters.
- */
-#define glGetString(x) (const char*)glGetString(x)
-
-/**
- * @internal
- * @~English
- * @brief Workaround mismatch of glGetStringi declaration and standard string
- *        function parameters.
- */
-#define pfGlGetStringi(x,y) (const char*)pfGlGetStringi(x,y)
-
-/**
- * @internal
- * @~English
- * @brief Check for existence of OpenGL extension
- */
-static GLboolean
-hasExtension(const char* extension) 
-{
-    if (pfGlGetStringi == NULL) {
-        if (strstr(glGetString(GL_EXTENSIONS), extension) != NULL)
-            return GL_TRUE;
-        else
-            return GL_FALSE;
-    } else {
-        int i, n;
-
-        glGetIntegerv(GL_NUM_EXTENSIONS, &n);
-        for (i = 0; i < n; i++) {
-            if (strcmp(pfGlGetStringi(GL_EXTENSIONS, i), extension) == 0)
-                return GL_TRUE;
-        }
-        return GL_FALSE;
-    }
-}
-
-/**
- * @internal
- * @~English
- * @brief Discover the capabilities of the current GL context.
- *
- * Queries the context and sets several the following internal variables
- * indicating the capabilities of the context:
- *
- * @li sizedFormats
- * @li supportsSwizzle
- * @li supportsSRGB
- * @li b16Formats
- */
-static void
-discoverContextCapabilities(void)
-{
-    GLint majorVersion = 1;
-    GLint minorVersion = 0;
-
-    // Done here so things will work when GLEW, or equivalent, is being used
-    // and GL function names are defined as pointers. Initialization at
-    // declaration would happen before these pointers have been initialized.
-    INITIALIZE_GL_FUNCPTRS
-
-    if (strstr(glGetString(GL_VERSION), "GL ES") != NULL)
-        contextProfile = _CONTEXT_ES_PROFILE_BIT;
-    // MAJOR & MINOR only introduced in GL {,ES} 3.0
-    glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
-    glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
-    if (glGetError() != GL_NO_ERROR) {
-        // < v3.0; resort to the old-fashioned way.
-        if (contextProfile & _CONTEXT_ES_PROFILE_BIT)
-            sscanf(glGetString(GL_VERSION), "OpenGL ES %d.%d ",
-                   &majorVersion, &minorVersion);
-        else
-            sscanf(glGetString(GL_VERSION), "OpenGL %d.%d ",
-                   &majorVersion, &minorVersion);
-    }
-    if (contextProfile & _CONTEXT_ES_PROFILE_BIT) {
-        if (majorVersion < 3) {
-            supportsSwizzle = GL_FALSE;
-            sizedFormats = _NO_SIZED_FORMATS;
-            R16Formats = _KTX_NO_R16_FORMATS;
-            supportsSRGB = GL_FALSE;
-        } else {
-            sizedFormats = _NON_LEGACY_FORMATS;
-            if (hasExtension("GL_EXT_texture_cube_map_array")) {
-                supportsCubeMapArrays = GL_TRUE;
-            }
-        }
-        if (hasExtension("GL_OES_required_internalformat")) {
-            sizedFormats |= _ALL_SIZED_FORMATS;
-        }
-        // There are no OES extensions for sRGB textures or R16 formats.
-    } else {
-        // PROFILE_MASK was introduced in OpenGL 3.2.
-        // Profiles: CONTEXT_CORE_PROFILE_BIT 0x1,
-        //           CONTEXT_COMPATIBILITY_PROFILE_BIT 0x2.
-        glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &contextProfile);
-        if (glGetError() == GL_NO_ERROR) {
-            // >= 3.2
-            if (majorVersion == 3 && minorVersion < 3)
-                supportsSwizzle = GL_FALSE;
-            if ((contextProfile & GL_CONTEXT_CORE_PROFILE_BIT))
-                sizedFormats &= ~_LEGACY_FORMATS;
-            if (majorVersion >= 4)
-                supportsCubeMapArrays = GL_TRUE;
-        } else {
-            // < 3.2
-            contextProfile = GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
-            supportsSwizzle = GL_FALSE;
-            // sRGB textures introduced in 2.0
-            if (majorVersion < 2 && hasExtension("GL_EXT_texture_sRGB")) {
-                supportsSRGB = GL_FALSE;
-            }
-            // R{,G]16 introduced in 3.0; R{,G}16_SNORM introduced in 3.1.
-            if (majorVersion == 3) {
-                if (minorVersion == 0)
-                    R16Formats &= ~_KTX_R16_FORMATS_SNORM;
-            } else if (hasExtension("GL_ARB_texture_rg")) {
-                R16Formats &= ~_KTX_R16_FORMATS_SNORM;
-            } else {
-                R16Formats = _KTX_NO_R16_FORMATS;
-            }
-        }
-        if (!supportsCubeMapArrays) {
-            if (hasExtension("GL_ARB_texture_cube_map_array")) {
-                supportsCubeMapArrays = GL_TRUE;
-            }
-        }
-    }
-}
-
-#if SUPPORT_LEGACY_FORMAT_CONVERSION
-/**
- * @internal
- * @~English
- * @brief Convert deprecated legacy-format texture to modern format.
- *
- * The function sets the GL_TEXTURE_SWIZZLEs necessary to get the same
- * behavior as the legacy format.
- *
- * @param[in] target       texture target on which the swizzle will
- *                          be set.
- * @param[in,out] pFormat  pointer to variable holding the base format of the
- *                          texture. The new base format is written here.
- * @param[in,out] pInternalformat  pointer to variable holding the
- *                                  internalformat of the texture. The new
- *                                  internalformat is written here.
- * @return void unrecognized formats will be passed on to OpenGL. Any loading
- *              error that arises will be handled in the usual way.
- */
-static void convertFormat(GLenum target, GLenum* pFormat, GLenum* pInternalformat) {
-    switch (*pFormat) {
-      case GL_ALPHA:
-        {
-          GLint swizzle[] = {GL_ZERO, GL_ZERO, GL_ZERO, GL_RED};
-          *pFormat = GL_RED;
-          glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
-          switch (*pInternalformat) {
-            case GL_ALPHA:
-            case GL_ALPHA4:
-            case GL_ALPHA8:
-              *pInternalformat = GL_R8;
-              break;
-            case GL_ALPHA12:
-            case GL_ALPHA16:
-              *pInternalformat = GL_R16;
-              break;
-          }
-        }
-      case GL_LUMINANCE:
-        {
-          GLint swizzle[] = {GL_RED, GL_RED, GL_RED, GL_ONE};
-          *pFormat = GL_RED;
-          glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
-          switch (*pInternalformat) {
-            case GL_LUMINANCE:
-            case GL_LUMINANCE4:
-            case GL_LUMINANCE8:
-              *pInternalformat = GL_R8;
-              break;
-            case GL_LUMINANCE12:
-            case GL_LUMINANCE16:
-              *pInternalformat = GL_R16;
-              break;
-#if 0
-            // XXX Must avoid setting TEXTURE_SWIZZLE in these cases
-            // XXX Must manually swizzle.
-            case GL_SLUMINANCE:
-            case GL_SLUMINANCE8:
-              *pInternalformat = GL_SRGB8;
-              break;
-#endif
-          }
-          break;
-        }
-      case GL_LUMINANCE_ALPHA:
-        {
-          GLint swizzle[] = {GL_RED, GL_RED, GL_RED, GL_GREEN};
-          *pFormat = GL_RG;
-          glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
-          switch (*pInternalformat) {
-            case GL_LUMINANCE_ALPHA:
-            case GL_LUMINANCE4_ALPHA4:
-            case GL_LUMINANCE6_ALPHA2:
-            case GL_LUMINANCE8_ALPHA8:
-              *pInternalformat = GL_RG8;
-              break;
-            case GL_LUMINANCE12_ALPHA4:
-            case GL_LUMINANCE12_ALPHA12:
-            case GL_LUMINANCE16_ALPHA16:
-              *pInternalformat = GL_RG16;
-              break;
-#if 0
-            // XXX Must avoid setting TEXTURE_SWIZZLE in these cases
-            // XXX Must manually swizzle.
-            case GL_SLUMINANCE_ALPHA:
-            case GL_SLUMINANCE8_ALPHA8:
-              *pInternalformat = GL_SRGB8_ALPHA8;
-              break;
-#endif
-          }
-          break;
-        }
-      case GL_INTENSITY:
-        {
-          GLint swizzle[] = {GL_RED, GL_RED, GL_RED, GL_RED};
-          *pFormat = GL_RED;
-          glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
-          switch (*pInternalformat) {
-            case GL_INTENSITY:
-            case GL_INTENSITY4:
-            case GL_INTENSITY8:
-              *pInternalformat = GL_R8;
-              break;
-            case GL_INTENSITY12:
-            case GL_INTENSITY16:
-              *pInternalformat = GL_R16;
-              break;
-          }
-          break;
-        }
-      default:
-        break;
-    }
-}
-#endif /* SUPPORT_LEGACY_FORMAT_CONVERSION */
-
-/* [cbdata] */
-typedef struct ktx_cbdata {
-    GLenum glTarget;
-    GLenum glFormat;
-    GLenum glInternalformat;
-    GLenum glType;
-    GLenum glError;
-    GLuint numLayers;
-} ktx_cbdata;
-/* [cbdata] */
-
-/* [imageCallbacks] */
-
-KTX_error_code KTXAPIENTRY
-texImage1DCallback(int miplevel, int face,
-                   int width, int height,
-                   int depth,
-                   ktx_uint32_t faceLodSize,
-                   void* pixels, void* userdata)
-{
-    ktx_cbdata* cbData = (ktx_cbdata*)userdata;
-    
-    assert(pfGlTexImage1D != NULL);
-    pfGlTexImage1D(cbData->glTarget + face, miplevel,
-                   cbData->glInternalformat, width, 0,
-                   cbData->glFormat, cbData->glType, pixels);
-    
-    if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
-        return KTX_SUCCESS;
-    } else {
-        return KTX_GL_ERROR;
-    }
-}
-
-KTX_error_code KTXAPIENTRY
-compressedTexImage1DCallback(int miplevel, int face,
-                             int width, int height,
-                             int depth,
-                             ktx_uint32_t faceLodSize,
-                             void* pixels, void* userdata)
-{
-    ktx_cbdata* cbData = (ktx_cbdata*)userdata;
-    
-    assert(pfGlCompressedTexImage1D != NULL);
-    pfGlCompressedTexImage1D(cbData->glTarget + face, miplevel,
-                             cbData->glInternalformat, width, 0,
-                             faceLodSize, pixels);
-    
-    if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
-        return KTX_SUCCESS;
-    } else {
-        return KTX_GL_ERROR;
-    }
-}
-
-KTX_error_code KTXAPIENTRY
-texImage2DCallback(int miplevel, int face,
-                   int width, int height,
-                   int depth,
-                   ktx_uint32_t faceLodSize,
-                   void* pixels, void* userdata)
-{
-    ktx_cbdata* cbData = (ktx_cbdata*)userdata;
- 
-    glTexImage2D(cbData->glTarget + face, miplevel,
-                 cbData->glInternalformat, width,
-                 cbData->numLayers == 0 ? height : cbData->numLayers, 0,
-                 cbData->glFormat, cbData->glType, pixels);
-
-    if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
-        return KTX_SUCCESS;
-    } else {
-        return KTX_GL_ERROR;
-    }
-}
-
-
-KTX_error_code KTXAPIENTRY
-compressedTexImage2DCallback(int miplevel, int face,
-                             int width, int height,
-                             int depth,
-                             ktx_uint32_t faceLodSize,
-                             void* pixels, void* userdata)
-{
-    ktx_cbdata* cbData = (ktx_cbdata*)userdata;
-    GLenum glerror;
-    KTX_error_code result;
-    
-    // It is simpler to just attempt to load the format, rather than divine
-    // which formats are supported by the implementation. In the event of an
-    // error, software unpacking can be attempted.
-    glCompressedTexImage2D(cbData->glTarget + face, miplevel,
-                           cbData->glInternalformat, width,
-                           cbData->numLayers == 0 ? height : cbData->numLayers,
-                           0,
-                           faceLodSize, pixels);
-    
-    glerror = glGetError();
-#if SUPPORT_SOFTWARE_ETC_UNPACK
-    // Renderion is returning INVALID_VALUE. Oops!!
-    if ((glerror == GL_INVALID_ENUM || glerror == GL_INVALID_VALUE)
-        && (cbData->glInternalformat == GL_ETC1_RGB8_OES
-            || (cbData->glInternalformat >= GL_COMPRESSED_R11_EAC
-                && cbData->glInternalformat <= GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC)
-            ))
-    {
-        GLubyte* unpacked;
-        GLenum format, internalformat, type;
-        
-        result = _ktxUnpackETC((GLubyte*)pixels, cbData->glInternalformat,
-                                  width, height, &unpacked,
-                                  &format, &internalformat,
-                                  &type, R16Formats, supportsSRGB);
-        if (result != KTX_SUCCESS) {
-            return result;
-        }
-        if (!(sizedFormats & _NON_LEGACY_FORMATS)) {
-            if (internalformat == GL_RGB8)
-                internalformat = GL_RGB;
-            else if (internalformat == GL_RGBA8)
-                internalformat = GL_RGBA;
-        }
-        glTexImage2D(cbData->glTarget + face, miplevel,
-                     internalformat, width,
-                     cbData->numLayers == 0 ? height : cbData->numLayers, 0,
-                     format, type, unpacked);
-        
-        free(unpacked);
-        glerror = glGetError();
-    }
-#endif
-    
-    if ((cbData->glError = glerror) == GL_NO_ERROR) {
-        return KTX_SUCCESS;
-    } else {
-        return KTX_GL_ERROR;
-    }
-}
-
-KTX_error_code KTXAPIENTRY
-texImage3DCallback(int miplevel, int face,
-                   int width, int height,
-                   int depth,
-                   ktx_uint32_t faceLodSize,
-                   void* pixels, void* userdata)
-{
-    ktx_cbdata* cbData = (ktx_cbdata*)userdata;
-    
-    assert(pfGlTexImage3D != NULL);
-    pfGlTexImage3D(cbData->glTarget + face, miplevel,
-                   cbData->glInternalformat,
-                   width, height,
-                   cbData->numLayers == 0 ? depth : cbData->numLayers,
-                   0,
-                   cbData->glFormat, cbData->glType, pixels);
-    
-    if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
-        return KTX_SUCCESS;
-    } else {
-        return KTX_GL_ERROR;
-    }
-}
-
-KTX_error_code KTXAPIENTRY
-compressedTexImage3DCallback(int miplevel, int face,
-                             int width, int height,
-                             int depth,
-                             ktx_uint32_t faceLodSize,
-                             void* pixels, void* userdata)
-{
-    ktx_cbdata* cbData = (ktx_cbdata*)userdata;
-    
-    assert(pfGlCompressedTexImage3D != NULL);
-    pfGlCompressedTexImage3D(cbData->glTarget + face, miplevel,
-                             cbData->glInternalformat,
-                             width, height,
-                             cbData->numLayers == 0 ? depth : cbData->numLayers,
-                             0,
-                             faceLodSize, pixels);
-    
-    if ((cbData->glError = glGetError()) == GL_NO_ERROR) {
-        return KTX_SUCCESS;
-    } else {
-        return KTX_GL_ERROR;
-    }
-}
-/* [imageCallbacks] */
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Create a GL texture object from a ktxTexture object.
- *
- * Sets the texture object's GL_TEXTURE_MAX_LEVEL parameter according to the
- * number of levels in the KTX data, provided the library has been compiled
- * with a version of gl.h where GL_TEXTURE_MAX_LEVEL is defined.
- *
- * Unpacks compressed GL_ETC1_RGB8_OES and GL_ETC2_* format
- * textures in software when the format is not supported by the GL context,
- * provided the library has been compiled with SUPPORT_SOFTWARE_ETC_UNPACK
- * defined as 1.
- *
- * It will also convert textures with legacy formats to their modern equivalents
- * when the format is not supported by the GL context, provided the library
- * has been compiled with SUPPORT_LEGACY_FORMAT_CONVERSION defined as 1.
- *
- * @param[in] This          handle of the ktxTexture to upload.
- * @param[in,out] pTexture  name of the GL texture object to load. If NULL or if
- *                          <tt>*pTexture == 0</tt> the function will generate
- *                          a texture name. The function binds either the
- *                          generated name or the name given in @p *pTexture
- *                          to the texture target returned in @p *pTarget,
- *                          before loading the texture data. If @p pTexture
- *                          is not NULL and a name was generated, the generated
- *                          name will be returned in *pTexture.
- * @param[out] pTarget      @p *pTarget is set to the texture target used. The
- *                          target is chosen based on the file contents.
- * @param[out] pGlerror     @p *pGlerror is set to the value returned by
- *                          glGetError when this function returns the error
- *                          KTX_GL_ERROR. glerror can be NULL.
- *
- * @return  KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p This or @p target is @c NULL or the size of
- *                              a mip level is greater than the size of the
- *                              preceding level.
- * @exception KTX_GL_ERROR      A GL error was raised by glBindTexture,
- *                              glGenTextures or gl*TexImage*. The GL error
- *                              will be returned in @p *glerror, if glerror
- *                              is not @c NULL.
- * @exception KTX_UNSUPPORTED_TEXTURE_TYPE The type of texture is not supported
- *                                         by the current OpenGL context.
- */
-/* [loadGLTexture] */
-KTX_error_code
-ktxTexture_GLUpload(ktxTexture* This, GLuint* pTexture, GLenum* pTarget,
-                    GLenum* pGlerror)
-{
-    GLint                 previousUnpackAlignment;
-    GLuint                texname;
-    GLenum                target = GL_TEXTURE_2D;
-    int                   texnameUser;
-    KTX_error_code        result = KTX_SUCCESS;
-    PFNKTXITERCB          iterCb = NULL;
-    ktx_cbdata            cbData;
-    int                   dimensions;
-
-    if (pGlerror)
-        *pGlerror = GL_NO_ERROR;
-
-    if (!This) {
-        return KTX_INVALID_VALUE;
-    }
-
-    if (!pTarget) {
-        return KTX_INVALID_VALUE;
-    }
-
-    if (contextProfile == 0)
-        discoverContextCapabilities();
-
-    /* KTX files require an unpack alignment of 4 */
-    glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousUnpackAlignment);
-    if (previousUnpackAlignment != KTX_GL_UNPACK_ALIGNMENT) {
-        glPixelStorei(GL_UNPACK_ALIGNMENT, KTX_GL_UNPACK_ALIGNMENT);
-    }
-
-    cbData.glFormat = This->glFormat;
-    cbData.glInternalformat = This->glInternalformat;
-    cbData.glType = This->glType;
-
-    texnameUser = pTexture && *pTexture;
-    if (texnameUser) {
-        texname = *pTexture;
-    } else {
-        glGenTextures(1, &texname);
-    }
-
-    dimensions = This->numDimensions;
-    if (This->isArray) {
-        dimensions += 1;
-        if (This->numFaces == 6) {
-            /* _ktxCheckHeader should have caught this. */
-            assert(This->numDimensions == 2);
-            target = GL_TEXTURE_CUBE_MAP_ARRAY;
-        } else {
-            switch (This->numDimensions) {
-              case 1: target = GL_TEXTURE_1D_ARRAY_EXT; break;
-              case 2: target = GL_TEXTURE_2D_ARRAY_EXT; break;
-              /* _ktxCheckHeader should have caught this. */
-              default: assert(KTX_TRUE);
-            }
-        }
-        cbData.numLayers = This->numLayers;
-    } else {
-        if (This->numFaces == 6) {
-            /* _ktxCheckHeader should have caught this. */
-            assert(This->numDimensions == 2);
-            target = GL_TEXTURE_CUBE_MAP;
-        } else {
-            switch (This->numDimensions) {
-              case 1: target = GL_TEXTURE_1D; break;
-              case 2: target = GL_TEXTURE_2D; break;
-              case 3: target = GL_TEXTURE_3D; break;
-              /* _ktxCheckHeader shold have caught this. */
-              default: assert(KTX_TRUE);
-            }
-        }
-        cbData.numLayers = 0;
-    }
-    
-    if (target == GL_TEXTURE_1D &&
-        ((This->isCompressed && (pfGlCompressedTexImage1D == NULL)) ||
-         (!This->isCompressed && (pfGlTexImage1D == NULL))))
-    {
-        return KTX_UNSUPPORTED_TEXTURE_TYPE;
-    }
-    
-    /* Reject 3D texture if unsupported. */
-    if (target == GL_TEXTURE_3D &&
-        ((This->isCompressed && (pfGlCompressedTexImage3D == NULL)) ||
-         (!This->isCompressed && (pfGlTexImage3D == NULL))))
-    {
-        return KTX_UNSUPPORTED_TEXTURE_TYPE;
-    }
-    
-    /* Reject cube map arrays if not supported. */
-    if (target == GL_TEXTURE_CUBE_MAP_ARRAY && !supportsCubeMapArrays) {
-        return KTX_UNSUPPORTED_TEXTURE_TYPE;
-    }
-    
-    /* XXX Need to reject other array textures & cube maps if not supported. */
-    
-    switch (dimensions) {
-      case 1:
-        iterCb = This->isCompressed
-                  ? compressedTexImage1DCallback : texImage1DCallback;
-        break;
-      case 2:
-        iterCb = This->isCompressed
-                  ? compressedTexImage2DCallback : texImage2DCallback;
-            break;
-      case 3:
-        iterCb = This->isCompressed
-                  ? compressedTexImage3DCallback : texImage3DCallback;
-        break;
-      default:
-            assert(KTX_TRUE);
-    }
-   
-    glBindTexture(target, texname);
-    
-    // Prefer glGenerateMipmaps over GL_GENERATE_MIPMAP
-    if (This->generateMipmaps && (pfGlGenerateMipmap == NULL)) {
-        glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
-    }
-#ifdef GL_TEXTURE_MAX_LEVEL
-    if (!This->generateMipmaps)
-        glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, This->numLevels - 1);
-#endif
-
-    if (target == GL_TEXTURE_CUBE_MAP) {
-        cbData.glTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
-    } else {
-        cbData.glTarget = target;
-    }
-    
-    cbData.glInternalformat = This->glInternalformat;
-    cbData.glFormat = This->glFormat;
-    if (!This->isCompressed) {
-#if SUPPORT_LEGACY_FORMAT_CONVERSION
-        // If sized legacy formats are supported there is no need to convert.
-        // If only unsized formats are supported, there is no point in
-        // converting as the modern formats aren't supported either.
-        if (sizedFormats == _NON_LEGACY_FORMATS && supportsSwizzle) {
-            convertFormat(target, &cbData.glFormat, &cbData.glInternalformat);
-        } else if (sizedFormats == _NO_SIZED_FORMATS)
-            cbData.glInternalformat = This->glBaseInternalformat;
-#else
-        // When no sized formats are supported, or legacy sized formats are not
-        // supported, must change internal format.
-        if (sizedFormats == _NO_SIZED_FORMATS
-            || (!(sizedFormats & _LEGACY_FORMATS) &&
-                (This->glBaseInternalformat == GL_ALPHA
-                || This->glBaseInternalformat == GL_LUMINANCE
-                || This->glBaseInternalformat == GL_LUMINANCE_ALPHA
-                || This->glBaseInternalformat == GL_INTENSITY))) {
-            cbData.glInternalformat = This->glBaseInternalformat;
-        }
-#endif
-    }
-
-    if (ktxTexture_isActiveStream(This))
-        result = ktxTexture_IterateLoadLevelFaces(This, iterCb, &cbData);
-    else
-        result = ktxTexture_IterateLevelFaces(This, iterCb, &cbData);
-
-    /* GL errors are the only reason for failure. */
-    if (result != KTX_SUCCESS && cbData.glError != GL_NO_ERROR) {
-        if (pGlerror)
-            *pGlerror = cbData.glError;
-    }
-
-    /* restore previous GL state */
-    if (previousUnpackAlignment != KTX_GL_UNPACK_ALIGNMENT) {
-        glPixelStorei(GL_UNPACK_ALIGNMENT, previousUnpackAlignment);
-    }
-
-    if (result == KTX_SUCCESS)
-    {
-        // Prefer glGenerateMipmaps over GL_GENERATE_MIPMAP
-        if (This->generateMipmaps && pfGlGenerateMipmap) {
-            pfGlGenerateMipmap(target);
-        }
-        *pTarget = target;
-        if (pTexture) {
-            *pTexture = texname;
-        }
-    } else if (!texnameUser) {
-        glDeleteTextures(1, &texname);
-    }
-    return result;
-}
-/* [loadGLTexture] */
-
-/**
- * @~English
- * @deprecated Use ktxTexture_CreateFromStdioStream() and ktxTexture_GLUpload().
- * @brief Create a GL texture object from KTX data in a stdio FILE stream.
- *
- * Sets the texture object's GL_TEXTURE_MAX_LEVEL parameter according to the
- * number of levels in the ktxStream, provided the library has been compiled
- * with a version of gl.h where GL_TEXTURE_MAX_LEVEL is defined.
- *
- * Unpacks compressed GL_ETC1_RGB8_OES and GL_ETC2_* format textures in
- * software when the format is not supported by the GL context, provided the
- * library has been compiled with SUPPORT_SOFTWARE_ETC_UNPACK defined as 1.
- *
- * Also converts texture with legacy formats to their modern equivalents
- * when the format is not supported by the GL context, provided the library
- * has been compiled with SUPPORT_LEGACY_FORMAT_CONVERSION defined as 1.
- *
- * @param[in] file         stdio stream FILE pointer
- * @param[in,out] pTexture name of the GL texture object to load. If NULL or if
- *                         <tt>*pTexture == 0</tt> the function will generate
- *                         a texture name. The function binds either the
- *                         generated name or the name given in @p *pTexture
- *                         to the texture target returned in @p *pTarget,
- *                         before loading the texture data. If @p pTexture
- *                         is not NULL and a name was generated, the generated
- *                         name will be returned in *pTexture.
- * @param[out] pTarget     @p *pTarget is set to the texture target used. The
- *                         target is chosen based on the file contents.
- * @param[out] pDimensions If @p pDimensions is not NULL, the width, height and
- *                         depth of the texture's base level are returned in
- *                         the fields of the KTX_dimensions structure to which
- *                         it points.
- * @param[out] pIsMipmapped
- *                         If @p pIsMipmapped is not NULL, @p *pIsMipmapped is
- *                         set to GL_TRUE if the KTX texture is mipmapped,
- *                         GL_FALSE otherwise.
- * @param[out] pGlerror    @p *pGlerror is set to the value returned by
- *                         glGetError when this function returns the error
- *                         KTX_GL_ERROR. glerror can be NULL.
- * @param[in,out] pKvdLen  If not NULL, @p *pKvdLen is set to the number of
- *                         bytes of key-value data pointed at by @p *ppKvd.
- *                         Must not be NULL, if @p ppKvd is not NULL.
- * @param[in,out] ppKvd    If not NULL, @p *ppKvd is set to the point to a
- *                         block of memory containing key-value data read from
- *                         the file. The application is responsible for freeing
- *                         the memory.
- *
- * @return  KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p target is @c NULL or the size of a mip
- *                              level is greater than the size of the
- *                              preceding level.
- * @exception KTX_INVALID_OPERATION @p ppKvd is not NULL but pKvdLen is NULL.
- * @exception KTX_UNEXPECTED_END_OF_FILE the file does not contain the
- *                                       expected amount of data.
- * @exception KTX_OUT_OF_MEMORY Sufficient memory could not be allocated for the
- *                              underlying ktxTexture object or to store the
- *                              requested key-value data.
- * @exception KTX_GL_ERROR      A GL error was raised by glBindTexture,
- *                              glGenTextures or gl*TexImage*. The GL error
- *                              will be returned in @p *glerror, if glerror
- *                              is not @c NULL.
- * @exception KTX_UNSUPPORTED_TEXTURE_TYPE The type of texture is not supported
- *                                         by the current OpenGL context.
- */
-KTX_error_code
-ktxLoadTextureF(FILE* file, GLuint* pTexture, GLenum* pTarget,
-                KTX_dimensions* pDimensions, GLboolean* pIsMipmapped,
-                GLenum* pGlerror,
-                unsigned int* pKvdLen, unsigned char** ppKvd)
-{
-    ktxTexture* texture;
-    KTX_error_code result = KTX_SUCCESS;
-    
-    if (ppKvd != NULL && pKvdLen == NULL)
-        return KTX_INVALID_VALUE;
-
-    result = ktxTexture_CreateFromStdioStream(file,
-                                              KTX_TEXTURE_CREATE_RAW_KVDATA_BIT,
-                                              &texture);
-    if (result != KTX_SUCCESS)
-        return result;
-
-    result = ktxTexture_GLUpload(texture, pTexture, pTarget, pGlerror);
-    
-    if (result == KTX_SUCCESS) {
-        if (ppKvd != NULL) {
-            *ppKvd = texture->kvData;
-            *pKvdLen = texture->kvDataLen;
-            /* Remove to avoid it being freed when texture is destroyed. */
-            texture->kvData = NULL;
-            texture->kvDataLen = 0;
-        }
-        if (pDimensions) {
-            pDimensions->width = texture->baseWidth;
-            pDimensions->height = texture->baseHeight;
-            pDimensions->depth = texture->baseDepth;
-        }
-        if (pIsMipmapped) {
-            if (texture->generateMipmaps || texture->numLevels > 1)
-                *pIsMipmapped = GL_TRUE;
-            else
-                *pIsMipmapped = GL_FALSE;
-        }
-    }
-
-    ktxTexture_Destroy(texture);
-
-    return result;
-}
-
-/**
- * @~English
- * @deprecated Use ktxTexture_CreateFromNamedFile() and ktxTexture_GLUpload().
- * @brief Create a GL texture object from KTX data in a named file on disk.
- *
- * @param[in] filename      pointer to a C string that contains the path of
- *                          the file to load.
- * @param[in,out] pTexture  name of the GL texture object to load. See
- *                          ktxLoadTextureF() for details.
- * @param[out] pTarget      @p *pTarget is set to the texture target used. See
- *                          ktxLoadTextureF() for details.
- * @param[out] pDimensions  @p the texture's base level width depth and height
- *                          are returned in structure to which this points.
- *                          See ktxLoadTextureF() for details.
- * @param[out] pIsMipmapped @p pIsMipMapped is set to indicate if the loaded
- *                          texture is mipmapped. See ktxLoadTextureF() for
- *                          details.
- * @param[out] pGlerror     @p *pGlerror is set to the value returned by
- *                          glGetError when this function returns the error
- *                          KTX_GL_ERROR. glerror can be NULL.
- * @param[in,out] pKvdLen   If not NULL, @p *pKvdLen is set to the number of
- *                          bytes of key-value data pointed at by @p *ppKvd.
- *                          Must not be NULL, if @p ppKvd is not NULL.
- * @param[in,out] ppKvd     If not NULL, @p *ppKvd is set to the point to a
- *                          block of memory containing key-value data read from
- *                          the file. The application is responsible for freeing
- *                          the memory.
- *
- * @return  KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_FILE_OPEN_FAILED  The specified file could not be opened.
- * @exception KTX_INVALID_VALUE     See ktxLoadTextureF() for causes.
- * @exception KTX_INVALID_OPERATION See ktxLoadTextureF() for causes.
- * @exception KTX_UNEXPECTED_END_OF_FILE See ktxLoadTextureF() for causes.
- * @exception KTX_GL_ERROR          See ktxLoadTextureF() for causes.
- * @exception KTX_UNSUPPORTED_TEXTURE_TYPE See ktxLoadTextureF() for causes.
- */
-KTX_error_code
-ktxLoadTextureN(const char* const filename, GLuint* pTexture, GLenum* pTarget,
-                KTX_dimensions* pDimensions, GLboolean* pIsMipmapped,
-                GLenum* pGlerror,
-                unsigned int* pKvdLen, unsigned char** ppKvd)
-{
-    KTX_error_code result;
-
-    FILE* file = fopen(filename, "rb");
-    if (file) {
-        result = ktxLoadTextureF(file, pTexture, pTarget, pDimensions,
-                                 pIsMipmapped, pGlerror, pKvdLen, ppKvd);
-        fclose(file);
-    } else
-        result = KTX_FILE_OPEN_FAILED;
-
-    return result;
-}
-
-/**
- * @~English
- * @deprecated Use ktxTexture_CreateFromMemory() and ktxTexture_GLUpload().
- * @brief Create a GL texture object from KTX formatted data in memory.
- *
- * @param[in] bytes         pointer to the array of bytes containing
- *                          the KTX data to load.
- * @param[in] size          size of the memory array containing the
- *                          KTX format data.
- * @param[in,out] pTexture  name of the GL texture object to load. See
- *                          ktxLoadTextureF() for details.
- * @param[out] pTarget      @p *pTarget is set to the texture target used. See
- *                          ktxLoadTextureF() for details.
- * @param[out] pDimensions  @p the texture's base level width depth and height
- *                          are returned in structure to which this points.
- *                          See ktxLoadTextureF() for details.
- * @param[out] pIsMipmapped @p *pIsMipMapped is set to indicate if the loaded
- *                          texture is mipmapped. See ktxLoadTextureF() for
- *                          details.
- * @param[out] pGlerror     @p *pGlerror is set to the value returned by
- *                          glGetError when this function returns the error
- *                          KTX_GL_ERROR. glerror can be NULL.
- * @param[in,out] pKvdLen   If not NULL, @p *pKvdLen is set to the number of
- *                          bytes of key-value data pointed at by @p *ppKvd.
- *                          Must not be NULL, if @p ppKvd is not NULL.
- * @param[in,out] ppKvd     If not NULL, @p *ppKvd is set to the point to a
- *                          block of memory containing key-value data read from
- *                          the file. The application is responsible for freeing
- *                          the memory.
- *
- * @return  KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_FILE_OPEN_FAILED  The specified memory could not be opened as
- *                                  a file.
- * @exception KTX_INVALID_VALUE     See ktxLoadTextureF() for causes.
- * @exception KTX_INVALID_OPERATION See ktxLoadTextureF() for causes.
- * @exception KTX_UNEXPECTED_END_OF_FILE See ktxLoadTextureF() for causes.
- *
- * @exception KTX_GL_ERROR          See ktxLoadTextureF() for causes.
- * @exception KTX_UNSUPPORTED_TEXTURE_TYPE See ktxLoadTextureF() for causes.
- */
-KTX_error_code
-ktxLoadTextureM(const void* bytes, GLsizei size, GLuint* pTexture,
-                GLenum* pTarget, KTX_dimensions* pDimensions,
-                GLboolean* pIsMipmapped, GLenum* pGlerror,
-                unsigned int* pKvdLen, unsigned char** ppKvd)
-{
-    ktxTexture* texture;
-    KTX_error_code result = KTX_SUCCESS;
-
-    if (ppKvd != NULL && pKvdLen == NULL)
-        return KTX_INVALID_VALUE;
-    
-    result = ktxTexture_CreateFromMemory(bytes, size,
-                                         KTX_TEXTURE_CREATE_RAW_KVDATA_BIT,
-                                         &texture);
-
-    if (result != KTX_SUCCESS)
-        return result;
-
-    result = ktxTexture_GLUpload(texture, pTexture, pTarget, pGlerror);
-    if (result == KTX_SUCCESS) {
-        if (ppKvd != NULL) {
-            *ppKvd = texture->kvData;
-            *pKvdLen = texture->kvDataLen;
-            /* Remove to avoid it being freed when texture is destroyed. */
-            texture->kvData = NULL;
-            texture->kvDataLen = 0;
-        }
-        if (pDimensions) {
-            pDimensions->width = texture->baseWidth;
-            pDimensions->height = texture->baseHeight;
-            pDimensions->depth = texture->baseDepth;
-        }
-        if (pIsMipmapped) {
-            if (texture->generateMipmaps || texture->numLevels > 1)
-                *pIsMipmapped = GL_TRUE;
-            else
-                *pIsMipmapped = GL_FALSE;
-        }
-    }
-    
-    ktxTexture_Destroy(texture);
-
-    return result;
-}
-
-/** @} */
diff --git a/external/KTX-Software-master/lib/hashlist.c b/external/KTX-Software-master/lib/hashlist.c
deleted file mode 100644
index 2afb20c67041494842b123aa5f0810f33104ea2e..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/hashlist.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/*
- * Copyright (c) 2010-2018 The Khronos Group Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @internal
- * @file hashlist.c
- * @~English
- *
- * @brief Functions for creating and using a hash list of key-value
- *        pairs.
- *
- * @author Mark Callow, HI Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-// This is to avoid compile warnings. strlen is defined as returning
-// size_t and is used by the uthash macros. This avoids having to
-// make changes to uthash and a bunch of casts in this file. The
-// casts would be required because the key and value lengths in KTX
-// are specified as 4 byte quantities so we can't change _keyAndValue
-// below to use size_t.
-#define strlen(x) ((unsigned int)strlen(x))
-
-#include "uthash.h"
-
-#include "ktx.h"
-#include "ktxint.h"
-
-
-/**
- * @internal
- * @struct ktxKVListEntry
- * @brief Hash list entry structure
- */
-typedef struct ktxKVListEntry {
-    unsigned int keyLen;    /*!< Length of the key */
-    char* key;              /*!< Pointer to key string */
-    unsigned int valueLen;  /*!< Length of the value */
-    void* value;            /*!< Pointer to the value */
-    UT_hash_handle hh;      /*!< handle used by UT hash */
-} ktxKVListEntry;
-
-
-/**
- * @memberof ktxHashList @public
- * @~English
- * @brief Construct an empty hash list for storing key-value pairs.
- *
- * @param [in] pHead pointer to the location to write the list head.
- */
-void
-ktxHashList_Construct(ktxHashList* pHead)
-{
-    *pHead = NULL;
-}
-
-
-/**
- * @memberof ktxHashList @public
- * @~English
- * @brief Destruct a hash list.
- *
- * All memory associated with the hash list's keys and values
- * is freed.
- *
- * @param [in] pHead pointer to the hash list to be destroyed.
- */
-void
-ktxHashList_Destruct(ktxHashList* pHead)
-{
-    ktxKVListEntry* kv;
-    ktxKVListEntry* head = *pHead;
-    
-    for(kv = head; kv != NULL;) {
-        ktxKVListEntry* tmp = (ktxKVListEntry*)kv->hh.next;
-        HASH_DELETE(hh, head, kv);
-        free(kv);
-        kv = tmp;
-    }
-}
-/**
- * @memberof ktxHashList @public
- * @~English
- * @brief Create an empty hash list for storing key-value pairs.
- *
- * @param [in,out] ppHl address of a variable in which to set a pointer to
- *                 the newly created hash list.
- *
- * @return KTX_SUCCESS or one of the following error codes.
- * @exception KTX_OUT_OF_MEMORY if not enough memory.
- */
-KTX_error_code
-ktxHashList_Create(ktxHashList** ppHl)
-{
-    ktxHashList* hl = (ktxHashList*)malloc(sizeof (ktxKVListEntry*));
-    if (hl == NULL)
-        return KTX_OUT_OF_MEMORY;
-    
-    ktxHashList_Construct(hl);
-    *ppHl = hl;
-    return KTX_SUCCESS;
-}
-
-
-/**
- * @memberof ktxHashList @public
- * @~English
- * @brief Destroy a hash list.
- *
- * All memory associated with the hash list's keys and values
- * is freed. The hash list is also freed.
- *
- * @param [in] pHead pointer to the hash list to be destroyed.
- */
-void
-ktxHashList_Destroy(ktxHashList* pHead)
-{
-    ktxHashList_Destruct(pHead);
-    free(pHead);
-}
-
-
-/**
- * @memberof ktxHashList @public
- * @~English
- * @brief Add a key value pair to a hash list.
- *
- * @param [in] pHead    pointer to the head of the target hash list.
- * @param [in] key      pointer to the UTF8 NUL-terminated string to be used as the key.
- * @param [in] valueLen the number of bytes of data in @p value.
- * @param [in] value    pointer to the bytes of data constituting the value.
- *
- * @return KTX_SUCCESS or one of the following error codes.
- * @exception KTX_INVALID_VALUE if @p This, @p key or @p value are NULL, @p key is an
- *            empty string or @p valueLen == 0.
- */
-KTX_error_code
-ktxHashList_AddKVPair(ktxHashList* pHead, const char* key, unsigned int valueLen, const void* value)
-{
-    if (pHead && key && value && valueLen != 0) {
-        unsigned int keyLen = (unsigned int)strlen(key) + 1;
-        /* ktxKVListEntry* head = *(ktxKVListEntry**)This; */
-        ktxKVListEntry* kv;
-
-        if (keyLen == 1)
-            return KTX_INVALID_VALUE;   /* Empty string */
-
-        /* Allocate all the memory as a block */
-        kv = (ktxKVListEntry*)malloc(sizeof(ktxKVListEntry) + keyLen + valueLen);
-        /* Put key first */
-        kv->key = (char *)kv + sizeof(ktxKVListEntry);
-        kv->keyLen = keyLen;
-        /* then value */
-        kv->value = kv->key + keyLen;
-        kv->valueLen = valueLen;
-        memcpy(kv->key, key, keyLen);
-        memcpy(kv->value, value, valueLen);
-
-        HASH_ADD_KEYPTR( hh, *pHead, kv->key, kv->keyLen-1, kv);
-        return KTX_SUCCESS;
-    } else
-        return KTX_INVALID_VALUE;
-}
-
-
-/**
- * @memberof ktxHashList @public
- * @~English
- * @brief Looks up a key in a hash list and returns the value.
- *
- * @param [in]     pHead        pointer to the head of the target hash list.
- * @param [in]     key          pointer to a UTF8 NUL-terminated string to find.
- * @param [in,out] pValueLen    @p *pValueLen is set to the number of bytes of
- *                              data in the returned value.
- * @param [in,out] ppValue      @p *ppValue is set to the point to the value for
- *                              @p key.
- *
- * @return KTX_SUCCESS or one of the following error codes.
- *
- * @exception KTX_INVALID_VALUE if @p This, @p key or @p pValueLen or @p ppValue
- *                              is NULL.
- * @exception KTX_NOT_FOUND     an entry matching @p key was not found.
- */
-KTX_error_code
-ktxHashList_FindValue(ktxHashList *pHead, const char* key, unsigned int* pValueLen, void** ppValue)
-{
-    if (pHead && key && pValueLen && ppValue) {
-        ktxKVListEntry* kv;
-        /* ktxKVListEntry* head = *(ktxKVListEntry**)This; */
-
-        HASH_FIND_STR( *pHead, key, kv );  /* kv: output pointer */
-
-        if (kv) {
-            *pValueLen = kv->valueLen;
-            *ppValue = kv->value;
-            return KTX_SUCCESS;
-        } else
-            return KTX_NOT_FOUND;
-    } else
-        return KTX_INVALID_VALUE;
-}
-
-
-/**
- * @memberof ktxHashList @public
- * @~English
- * @brief Serialize a hash list to a block of data suitable for writing
- *        to a file.
- *
- * The caller is responsible for freeing the data block returned by this
- * function.
- *
- * @param [in]     pHead        pointer to the head of the target hash list.
- * @param [in,out] pKvdLen      @p *pKvdLen is set to the number of bytes of
- *                              data in the returned data block.
- * @param [in,out] ppKvd        @p *ppKvd is set to the point to the block of
- *                              memory containing the serialized data.
- *
- * @return KTX_SUCCESS or one of the following error codes.
- *
- * @exception KTX_INVALID_VALUE if @p This, @p pKvdLen or @p ppKvd is NULL.
- * @exception KTX_OUT_OF_MEMORY there was not enough memory to serialize the
- *                              data.
- */
-KTX_error_code
-ktxHashList_Serialize(ktxHashList* pHead,
-                      unsigned int* pKvdLen, unsigned char** ppKvd)
-{
-
-    if (pHead && pKvdLen && ppKvd) {
-        ktxKVListEntry* kv;
-        unsigned int bytesOfKeyValueData = 0;
-        unsigned int keyValueLen;
-        unsigned char* sd;
-        char padding[4] = {0, 0, 0, 0};
-
-        for (kv = *pHead; kv != NULL; kv = kv->hh.next) {
-            /* sizeof(sd) is to make space to write keyAndValueByteSize */
-            keyValueLen = kv->keyLen + kv->valueLen + sizeof(ktx_uint32_t);
-            /* Add valuePadding */
-            keyValueLen = _KTX_PAD4(keyValueLen);
-            bytesOfKeyValueData += keyValueLen;
-        }
-        sd = malloc(bytesOfKeyValueData);
-        if (!sd)
-            return KTX_OUT_OF_MEMORY;
-
-        *pKvdLen = bytesOfKeyValueData;
-        *ppKvd = sd;
-
-        for (kv = *pHead; kv != NULL; kv = kv->hh.next) {
-            int padLen;
-
-            keyValueLen = kv->keyLen + kv->valueLen;
-            *(ktx_uint32_t*)sd = keyValueLen;
-            sd += sizeof(ktx_uint32_t);
-            memcpy(sd, kv->key, kv->keyLen);
-            sd += kv->keyLen;
-            memcpy(sd, kv->value, kv->valueLen);
-            sd += kv->valueLen;
-            padLen = _KTX_PAD4_LEN(keyValueLen);
-            memcpy(sd, padding, padLen);
-            sd += padLen;
-        }
-        return KTX_SUCCESS;
-    } else
-        return KTX_INVALID_VALUE;
-}
-
-
-/**
- * @memberof ktxHashList @public
- * @~English
- * @brief Construct a hash list from a block of serialized key-value
- *        data read from a file.
- * @note The bytes of the 32-bit key-value lengths within the serialized data
- *       are expected to be in native endianness.
- *
- * @param [in]      pHead       pointer to the head of the target hash list.
- * @param [in]      kvdLen      the length of the serialized key-value data.
- * @param [in]      pKvd        pointer to the serialized key-value data.
- *                              table.
- *
- * @return KTX_SUCCESS or one of the following error codes.
- *
- * @exception KTX_INVALID_OPERATION if @p pHead does not point to an empty list.
- * @exception KTX_INVALID_VALUE if @p pKvd or @p pHt is NULL or kvdLen == 0.
- * @exception KTX_OUT_OF_MEMORY there was not enough memory to create the hash
- *                              table.
- */
-KTX_error_code
-ktxHashList_Deserialize(ktxHashList* pHead, unsigned int kvdLen, void* pKvd)
-{
-    char* src = pKvd;
-    KTX_error_code result;
-
-    if (kvdLen == 0 || pKvd == NULL || pHead == NULL)
-        return KTX_INVALID_VALUE;
-    
-    if (*pHead != NULL)
-        return KTX_INVALID_OPERATION;
-
-    result = KTX_SUCCESS;
-    while (result == KTX_SUCCESS && src < (char *)pKvd + kvdLen) {
-        char* key;
-        unsigned int keyLen;
-        void* value;
-        ktx_uint32_t keyAndValueByteSize = *((ktx_uint32_t*)src);
-
-        src += sizeof(keyAndValueByteSize);
-        key = src;
-        keyLen = (unsigned int)strlen(key) + 1;
-        value = key + keyLen;
-
-        result = ktxHashList_AddKVPair(pHead, key, keyAndValueByteSize - keyLen,
-                                       value);
-        if (result == KTX_SUCCESS) {
-            src += _KTX_PAD4(keyAndValueByteSize);
-        }
-    }
-    return result;
-}
-
-
diff --git a/external/KTX-Software-master/lib/hashtable.c b/external/KTX-Software-master/lib/hashtable.c
deleted file mode 100644
index e9a42f1746756662066cab56fecedcf84316920c..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/hashtable.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/**
- * @internal
- * @file hashtable.c
- * @~English
- *
- * @brief Functions for backward compatibility with libktx v1
- *        hashtable API.
- *
- * @author Mark Callow, www.edgewise-consulting.com
- */
-
-/*
- * ©2018 Mark Callow.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include "ktx.h"
-
-/**
- * @memberof KTX_hash_table
- * @~English
- * @deprecated Use ktxHashList_Create().
- */
-KTX_hash_table
-ktxHashTable_Create(void) {
-    ktxHashList* hl;
-    (void)ktxHashList_Create(&hl);
-    return hl;
-}
-
-/**
- * @memberof KTX_hash_table
- * @~English
- * @deprecated Use ktxHashList_Serialize().
- * @brief Serializes the hash table to a block of memory suitable for
- *        writing to a KTX file.
- */
-KTX_error_code
-ktxHashTable_Serialize(KTX_hash_table This,
-                      unsigned int* kvdLen, unsigned char** kvd)
-{
-    return ktxHashList_Serialize(This, kvdLen, kvd);
-}
-
-/**
- * @memberof KTX_hash_table
- * @deprecated Use ktxHashList_Deserialize().
- * @~English
- * @brief Create a new hash table from a block of serialized key-value
- *        data read from a file.
- *
- * The caller is responsible for freeing the returned hash table.
- *
- * @note The bytes of the 32-bit key-value lengths within the serialized data
- *       are expected to be in native endianness.
- *
- * @param[in]        kvdLen      the length of the serialized key-value data.
- * @param[in]        pKvd        pointer to the serialized key-value data.
- * @param[in,out]    pHt         @p *pHt is set to point to the created hash
- *                               table.
- *
- * @return KTX_SUCCESS or one of the following error codes.
- *
- * @exception KTX_INVALID_VALUE if @p pKvd or @p pHt is NULL or kvdLen == 0.
- * @exception KTX_OUT_OF_MEMORY there was not enough memory to create the hash
- *                              table.
- */
-KTX_error_code
-ktxHashTable_Deserialize(unsigned int kvdLen, void* pKvd, KTX_hash_table* pHt)
-{
-    ktxHashList* pHl;
-    KTX_error_code result;
-    result = ktxHashList_Create(&pHl);
-    if (result != KTX_SUCCESS)
-        return result;
-
-    result = ktxHashList_Deserialize(pHl, kvdLen, pKvd);
-    if (result == KTX_SUCCESS)
-        *pHt = pHl;
-    return result;
-}  
-
diff --git a/external/KTX-Software-master/lib/ktxgl.h b/external/KTX-Software-master/lib/ktxgl.h
deleted file mode 100644
index c4674d4c1babd34bd844a5194172d25d66b301e5..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/ktxgl.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/* $Id: 94277b50a14992fc9e5a6e011ef5f9cdf28f0d89 $ */
-
-/*
- * Copyright (c) 2010-2018 The Khronos Group Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/* 
- * Author: Mark Callow from original code by Georg Kolling
- */
-
-#ifndef KTXGL_H
-#define KTXGL_H
-
-#ifndef SUPPORT_LEGACY_FORMAT_CONVERSION
-  #if KTX_OPENGL
-    #define SUPPORT_LEGACY_FORMAT_CONVERSION 1
-  #elif KTX_OPENGL_ES1
-    /* ES1, ES2 & ES3 support the legacy formats */
-    #define SUPPORT_LEGACY_FORMAT_CONVERSION 0
-  #endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * These defines are needed to compile the KTX library. When
- * these things are not available in the GL header in use at
- * compile time, the library provides its own support, handles
- * the expected run-time errors or just needs the token value.
- */
-#ifndef GL_LUMINANCE
-#define GL_ALPHA                        0x1906
-#define GL_LUMINANCE                    0x1909
-#define GL_LUMINANCE_ALPHA              0x190A
-#endif
-#ifndef GL_INTENSITY
-#define GL_INTENSITY                    0x8049
-#endif
-#if SUPPORT_LEGACY_FORMAT_CONVERSION
-/* For loading legacy KTX files. */
-#ifndef GL_LUMINANCE4
-#define GL_ALPHA4                       0x803B
-#define GL_ALPHA8                       0x803C
-#define GL_ALPHA12                      0x803D
-#define GL_ALPHA16                      0x803E
-#define GL_LUMINANCE4                   0x803F
-#define GL_LUMINANCE8                   0x8040
-#define GL_LUMINANCE12                  0x8041
-#define GL_LUMINANCE16                  0x8042
-#define GL_LUMINANCE4_ALPHA4            0x8043
-#define GL_LUMINANCE6_ALPHA2            0x8044
-#define GL_LUMINANCE8_ALPHA8            0x8045
-#define GL_LUMINANCE12_ALPHA4           0x8046
-#define GL_LUMINANCE12_ALPHA12          0x8047
-#define GL_LUMINANCE16_ALPHA16          0x8048
-#endif
-#ifndef GL_INTENSITY4
-#define GL_INTENSITY4                   0x804A
-#define GL_INTENSITY8                   0x804B
-#define GL_INTENSITY12                  0x804C
-#define GL_INTENSITY16                  0x804D
-#endif
-#ifndef GL_SLUMINANCE
-#define GL_SLUMINANCE_ALPHA             0x8C44
-#define GL_SLUMINANCE8_ALPHA8           0x8C45
-#define GL_SLUMINANCE                   0x8C46
-#define GL_SLUMINANCE8                  0x8C47
-#endif
-#endif /* SUPPORT_LEGACY_FORMAT_CONVERSION */
-#ifndef GL_TEXTURE_1D
-#define GL_TEXTURE_1D                   0x0DE0
-#endif
-#ifndef GL_TEXTURE_3D
-#define GL_TEXTURE_3D                   0x806F
-#endif
-#ifndef GL_TEXTURE_CUBE_MAP
-#define GL_TEXTURE_CUBE_MAP             0x8513
-#define GL_TEXTURE_CUBE_MAP_POSITIVE_X  0x8515
-#endif
-#ifndef GL_TEXTURE_CUBE_MAP_ARRAY
-#define GL_TEXTURE_CUBE_MAP_ARRAY       0x9009
-#endif
-/* from GL_EXT_texture_array */
-#ifndef GL_TEXTURE_1D_ARRAY_EXT
-#define GL_TEXTURE_1D_ARRAY_EXT         0x8C18
-#define GL_TEXTURE_2D_ARRAY_EXT         0x8C1A
-#endif
-#ifndef GL_GENERATE_MIPMAP
-#define GL_GENERATE_MIPMAP              0x8191
-#endif
-
-/* For writer.c */
-#if !defined(GL_BGR)
-#define GL_BGR                          0x80E0
-#define GL_BGRA                         0x80E1
-#endif
-#if !defined(GL_RED_INTEGER)
-#define GL_RED_INTEGER                  0x8D94
-#define GL_RGB_INTEGER                  0x8D98
-#define GL_RGBA_INTEGER                 0x8D99
-#endif
-#if !defined(GL_GREEN_INTEGER)
-#define GL_GREEN_INTEGER                0x8D95
-#define GL_BLUE_INTEGER                 0x8D96
-#endif
-#if !defined(GL_ALPHA_INTEGER)
-#define GL_ALPHA_INTEGER                0x8D97
-#endif
-#if !defined (GL_BGR_INTEGER)
-#define GL_BGR_INTEGER                  0x8D9A
-#define GL_BGRA_INTEGER                 0x8D9B
-#endif
-#if !defined(GL_INT)
-#define GL_INT 0x1404
-#define GL_UNSIGNED_INT 0x1405
-#endif
-#if !defined(GL_HALF_FLOAT)
-typedef unsigned short GLhalf;
-#define GL_HALF_FLOAT                   0x140B
-#endif
-#if !defined(GL_UNSIGNED_BYTE_3_3_2)
-#define GL_UNSIGNED_BYTE_3_3_2          0x8032
-#define GL_UNSIGNED_INT_8_8_8_8         0x8035
-#define GL_UNSIGNED_INT_10_10_10_2      0x8036
-#endif
-#if !defined(GL_UNSIGNED_BYTE_2_3_3_REV)
-#define GL_UNSIGNED_BYTE_2_3_3_REV      0x8362
-#define GL_UNSIGNED_SHORT_5_6_5         0x8363
-#define GL_UNSIGNED_SHORT_5_6_5_REV     0x8364
-#define GL_UNSIGNED_SHORT_4_4_4_4_REV   0x8365
-#define GL_UNSIGNED_SHORT_1_5_5_5_REV   0x8366
-#define GL_UNSIGNED_INT_8_8_8_8_REV     0x8367
-#define GL_UNSIGNED_INT_2_10_10_10_REV  0x8368
-#endif
-#if !defined(GL_UNSIGNED_INT_24_8)
-#define GL_DEPTH_STENCIL                0x84F9
-#define GL_UNSIGNED_INT_24_8            0x84FA
-#endif
-#if !defined(GL_UNSIGNED_INT_5_9_9_9_REV)
-#define GL_UNSIGNED_INT_5_9_9_9_REV     0x8C3E
-#endif
-#if !defined(GL_UNSIGNED_INT_10F_11F_11F_REV)
-#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
-#endif
-#if !defined (GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
-#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV   0x8DAD
-#endif
-
-#ifndef GL_ETC1_RGB8_OES
-#define GL_ETC1_RGB8_OES                0x8D64
-#endif
-
-#if SUPPORT_SOFTWARE_ETC_UNPACK
-#ifndef GL_COMPRESSED_R11_EAC
-#define GL_COMPRESSED_R11_EAC                            0x9270
-#define GL_COMPRESSED_SIGNED_R11_EAC                     0x9271
-#define GL_COMPRESSED_RG11_EAC                           0x9272
-#define GL_COMPRESSED_SIGNED_RG11_EAC                    0x9273
-#define GL_COMPRESSED_RGB8_ETC2                          0x9274
-#define GL_COMPRESSED_SRGB8_ETC2                         0x9275
-#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2      0x9276
-#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2     0x9277
-#define GL_COMPRESSED_RGBA8_ETC2_EAC                     0x9278
-#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC              0x9279
-#endif
-#ifndef GL_R16_SNORM
-#define GL_R16_SNORM                    0x8F98
-#define GL_RG16_SNORM                   0x8F99
-#endif
-#ifndef GL_RED
-#define GL_RED                          0x1903
-#define GL_GREEN                        0x1904
-#define GL_BLUE                         0x1905
-#define GL_RG                           0x8227
-#define GL_RG_INTEGER                   0x8228
-#endif
-#ifndef GL_R16
-#define GL_R16                          0x822A
-#define GL_RG16                         0x822C
-#endif
-#ifndef GL_RGB8
-#define GL_RGB8                         0x8051
-#define GL_RGBA8                        0x8058
-#endif
-#ifndef GL_SRGB8
-#define GL_SRGB8                        0x8C41
-#define GL_SRGB8_ALPHA8                 0x8C43
-#endif
-#endif
-
-#ifndef GL_MAJOR_VERSION
-#define GL_MAJOR_VERSION                0x821B
-#define GL_MINOR_VERSION                0x821C
-#endif
-
-#ifndef GL_CONTEXT_PROFILE_MASK
-#define GL_CONTEXT_PROFILE_MASK              0x9126
-#define GL_CONTEXT_CORE_PROFILE_BIT          0x00000001
-#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
-#endif
-    
-#ifndef GL_NUM_EXTENSIONS
-#define GL_NUM_EXTENSIONS              0x821D
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* KTXGL_H */
diff --git a/external/KTX-Software-master/lib/ktxint.h b/external/KTX-Software-master/lib/ktxint.h
deleted file mode 100644
index a7e27fb418ff416ae2244f98cfde2b11fc93729c..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/ktxint.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/* $Id: 3dd768b381113d67ca7e4bde10e6252900bff845 $ */
-
-/*
- * Copyright (c) 2010-2018 The Khronos Group Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/* 
- * Author: Mark Callow from original code by Georg Kolling
- */
-
-#ifndef KTXINT_H
-#define KTXINT_H
-
-/* Define this to include the ETC unpack software in the library. */
-#ifndef SUPPORT_SOFTWARE_ETC_UNPACK
-  /* Include for all GL versions because have seen OpenGL ES 3
-   * implementaions that do not support ETC1 (ARM Mali emulator v1.0)!
-   */
-  #define SUPPORT_SOFTWARE_ETC_UNPACK 1
-#endif
-
-#ifndef MAX
-#define MAX(x, y) (((x) > (y)) ? (x) : (y))
-#endif
-
-#define KTX2_IDENTIFIER_REF  { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x32, 0x30, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }
-#define KTX2_HEADER_SIZE     (64)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @internal
- * @brief used to pass GL context capabilites to subroutines.
- */
-#define _KTX_NO_R16_FORMATS     0x0
-#define _KTX_R16_FORMATS_NORM   0x1
-#define _KTX_R16_FORMATS_SNORM  0x2
-#define _KTX_ALL_R16_FORMATS (_KTX_R16_FORMATS_NORM | _KTX_R16_FORMATS_SNORM)
-extern GLint _ktxR16Formats;
-extern GLboolean _ktxSupportsSRGB;
-
-/**
- * @internal
- * @~English
- * @brief KTX file header
- *
- * See the KTX specification for descriptions
- */
-typedef struct KTX_header {
-    ktx_uint8_t  identifier[12];
-    ktx_uint32_t endianness;
-    ktx_uint32_t glType;
-    ktx_uint32_t glTypeSize;
-    ktx_uint32_t glFormat;
-    ktx_uint32_t glInternalformat;
-    ktx_uint32_t glBaseInternalformat;
-    ktx_uint32_t pixelWidth;
-    ktx_uint32_t pixelHeight;
-    ktx_uint32_t pixelDepth;
-    ktx_uint32_t numberOfArrayElements;
-    ktx_uint32_t numberOfFaces;
-    ktx_uint32_t numberOfMipmapLevels;
-    ktx_uint32_t bytesOfKeyValueData;
-} KTX_header;
-
-/* This will cause compilation to fail if the struct size doesn't match */
-typedef int KTX_header_SIZE_ASSERT [sizeof(KTX_header) == KTX_HEADER_SIZE];
-
-/**
- * @internal
- * @~English
- * @brief Structure for supplemental information about the texture.
- *
- * _ktxCheckHeader returns supplemental information about the texture in this
- * structure that is derived during checking of the file header.
- */
-typedef struct KTX_supplemental_info
-{
-    ktx_uint8_t compressed;
-    ktx_uint8_t generateMipmaps;
-    ktx_uint16_t textureDimension;
-} KTX_supplemental_info;
-/**
- * @internal
- * @var ktx_uint8_t KTX_supplemental_info::compressed
- * @~English
- * @brief KTX_TRUE, if this a compressed texture, KTX_FALSE otherwise?
- */
-/**
- * @internal
- * @var ktx_uint8_t KTX_supplemental_info::generateMipmaps
- * @~English
- * @brief KTX_TRUE, if mipmap generation is required, KTX_FALSE otherwise.
- */
-/**
- * @internal
- * @var ktx_uint16_t KTX_supplemental_info::textureDimension
- * @~English
- * @brief The number of dimensions, 1, 2 or 3, of data in the texture image.
- */
-
-/*
- * @internal
- * CheckHeader
- * 
- * Reads the KTX file header and performs some sanity checking on the values
- */
-KTX_error_code _ktxCheckHeader(KTX_header* pHeader,
-                               KTX_supplemental_info* pSuppInfo);
-
-/*
- * SwapEndian16: Swaps endianness in an array of 16-bit values
- */
-void _ktxSwapEndian16(ktx_uint16_t* pData16, int count);
-
-/*
- * SwapEndian32: Swaps endianness in an array of 32-bit values
- */
-void _ktxSwapEndian32(ktx_uint32_t* pData32, int count);
-
-/*
- * UnpackETC: uncompresses an ETC compressed texture image
- */
-KTX_error_code _ktxUnpackETC(const GLubyte* srcETC, const GLenum srcFormat,
-                             ktx_uint32_t active_width, ktx_uint32_t active_height,
-                             GLubyte** dstImage,
-                             GLenum* format, GLenum* internalFormat, GLenum* type,
-                             GLint R16Formats, GLboolean supportsSRGB);
-
-/*
- * Pad nbytes to next multiple of n
- */
-/* Equivalent to n * ceil(nbytes / n) */
-#define _KTX_PADN(n, nbytes) (nbytes + (n-1) & ~(ktx_uint32_t)(n-1))
-/*
- * Calculate bytes of of padding needed to reach next multiple of n.
- */
-/* Equivalent to (n * ceil(nbytes / n)) - nbytes */
-#define _KTX_PADN_LEN(n, nbytes) ((n-1) - (nbytes + (n-1) & (n-1)))
-
-/*
- * Pad nbytes to next multiple of 4
- */
-#define _KTX_PAD4(nbytes) _KTX_PADN(4, nbytes)
-/*
- * Calculate bytes of of padding needed to reach next multiple of 4.
- */
-#define _KTX_PAD4_LEN(nbytes) _KTX_PADN_LEN(4, nbytes)
-
-/*
- * Pad nbytes to KTX_GL_UNPACK_ALIGNMENT
- */
-#define _KTX_PAD_UNPACK_ALIGN(nbytes)  \
-        _KTX_PADN(KTX_GL_UNPACK_ALIGNMENT, nbytes)
-/*
- * Calculate bytes of of padding needed to reach KTX_GL_UNPACK_ALIGNMENT.
- */
-#define _KTX_PAD_UNPACK_ALIGN_LEN(nbytes)  \
-        _KTX_PADN_LEN(KTX_GL_UNPACK_ALIGNMENT, nbytes)
-
-/*
- ======================================
-     Internal ktxTexture functions
- ======================================
-*/
-
-KTX_error_code
-ktxTexture_iterateLoadedImages(ktxTexture* This, PFNKTXITERCB iterCb,
-                               void* userdata);
-KTX_error_code
-ktxTexture_iterateSourceImages(ktxTexture* This, PFNKTXITERCB iterCb,
-                               void* userdata);
-    
-ktx_uint32_t ktxTexture_glTypeSize(ktxTexture* This);
-ktx_size_t ktxTexture_imageSize(ktxTexture* This, ktx_uint32_t level);
-ktx_bool_t ktxTexture_isActiveStream(ktxTexture* This);
-ktx_size_t ktxTexture_levelSize(ktxTexture* This, ktx_uint32_t level);
-ktx_size_t ktxTexture_faceLodSize(ktxTexture* This, ktx_uint32_t level);
-void ktxTexture_rowInfo(ktxTexture* This, ktx_uint32_t level,
-                        ktx_uint32_t* numRows, ktx_uint32_t* rowBytes,
-                        ktx_uint32_t* rowPadding);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* KTXINT_H */
diff --git a/external/KTX-Software-master/lib/libktx.gypi b/external/KTX-Software-master/lib/libktx.gypi
deleted file mode 100644
index 06c019b62200a4ecf29a55d7e00ff5440ec3ea30..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/libktx.gypi
+++ /dev/null
@@ -1,226 +0,0 @@
-##
-# @internal
-# @copyright © 2015, Mark Callow. For license see LICENSE.md.
-#
-# @brief Generate project to build KTX library for OpenGL.
-#
-{
-  'variables': {
-    'sources': [
-      # .h files are included so they will appear in IDEs' file lists.
-      '../include/ktx.h',
-      'checkheader.c',
-      'errstr.c',
-      'etcdec.cxx',
-      'etcunpack.cxx',
-      'filestream.c',
-      'filestream.h',
-      'gl_format.h',
-      'gl_funcptrs.h',
-      'gles1_funcptrs.h',
-      'gles2_funcptrs.h',
-      'gles3_funcptrs.h',
-      'glloader.c',
-      'hashlist.c',
-      'hashtable.c',
-      'ktxgl.h',
-      'ktxint.h',
-      'memstream.c',
-      'memstream.h',
-      'stream.h',
-      'swap.c',
-      'texture.c',
-      'uthash.h',
-      'writer.c',
-      'writer_v1.c'
-    ],
-    # Use _files to get the names relativized
-    'vksource_files': [
-      '../include/ktxvulkan.h',
-      'vk_format.h',
-      'vkloader.c',
-      'vk_funclist.inl',
-      'vk_funcs.c',
-      'vk_funcs.h'
-    ],
-    'include_dirs': [
-      '../include',
-      '../other_include',
-    ],
-  }, # variables
-
-  'includes': [
-      '../gyp_include/libgl.gypi',
-      '../gyp_include/libvulkan.gypi',
-  ],
-  'targets': [
-    {
-      'target_name': 'libktx.gl',
-      'type': '<(library)',
-      'cflags': [ '-std=c99' ],
-      'defines': [ 'KTX_OPENGL=1' ],
-      'direct_dependent_settings': {
-         'include_dirs': [ '<@(include_dirs)' ],
-      },
-      'include_dirs': [ '<@(include_dirs)' ],
-      'mac_bundle': 0,
-      'dependencies': [ 'vulkan_headers' ],
-      'sources': [
-        '<@(sources)',
-        '<@(vksource_files)',
-      ],
-      'conditions': [
-        ['_type == "shared_library"', {
-          'dependencies': [ 'libgl', 'libvulkan.lazy' ],
-          'conditions': [
-            ['OS == "mac" or OS == "ios"', {
-              'direct_dependent_settings': {
-                'target_conditions': [
-                  ['_mac_bundle == 1', {
-                    'copies': [{
-                      'xcode_code_sign': 1,
-                      'destination': '<(PRODUCT_DIR)/$(FRAMEWORKS_FOLDER_PATH)',
-                      'files': [ '<(PRODUCT_DIR)/<(_target_name)<(SHARED_LIB_SUFFIX)' ],
-                    }], # copies
-                    'xcode_settings': {
-                      # Tell DYLD where to search for this dylib.
-                      # "man dyld" for more information.
-                      'LD_RUNPATH_SEARCH_PATHS': [ '@executable_path/../Frameworks' ],
-                    },
-                  }, {
-                    'xcode_settings': {
-                      'LD_RUNPATH_SEARCH_PATHS': [ '@executable_path' ],
-                    },
-                  }], # _mac_bundle == 1
-                ], # target_conditions
-              }, # direct_dependent_settings
-              'sources!': [
-                'vk_funclist.inl',
-                'vk_funcs.c',
-                'vk_funcs.h',
-              ],
-              'xcode_settings': {
-                # This is so dyld can find the dylib when it is installed by
-                # the copy command above.
-                'INSTALL_PATH': '@rpath',
-              },
-            }, 'OS == "linux"', {
-              'defines': [ 'KTX_USE_FUNCPTRS_FOR_VULKAN' ],
-              'dependencies!': [ 'libvulkan.lazy' ],
-            }] # OS == "mac or OS == "ios"
-          ], # conditions
-        }] # _type == "shared_library"
-      ], # conditions
-    }, # libktx.gl target
-    {
-      'target_name': 'libktx.es1',
-      'type': 'static_library',
-      'cflags': [ '-std=c99' ],
-      'defines': [ 'KTX_OPENGL_ES1=1' ],
-      'direct_dependent_settings': {
-        'include_dirs': [ '<@(include_dirs)' ],
-      },
-      'sources': [ '<@(sources)' ],
-      'include_dirs': [ '<@(include_dirs)' ],
-    }, # libktx.es1
-    {
-      'target_name': 'libktx.es3',
-      'type': 'static_library',
-      'cflags': [ '-std=c99' ],
-      'defines': [ 'KTX_OPENGL_ES3=1' ],
-      'dependencies': [ 'vulkan_headers' ],
-      'direct_dependent_settings': {
-         'include_dirs': [ '<@(include_dirs)' ],
-      },
-      'sources': [
-        '<@(sources)',
-        '<@(vksource_files)',
-      ],
-      'include_dirs': [ '<@(include_dirs)' ],
-    }, # libktx.es3
-  ], # targets
-  'conditions': [
-    ['OS == "linux" or OS == "mac" or OS == "win"', {
-      # Can only build doc on desktops
-      'targets': [
-        {
-          'target_name': 'libktx.doc',
-          'type': 'none',
-          'variables': {
-            'variables': { # level 2
-              'output_dir': '../build/docs',
-            },
-            'output_dir': '<(output_dir)',
-            'doxyConfig': 'libktx.doxy',
-            'timestamp': '<(output_dir)/.libktx_gentimestamp',
-          },
-          'actions': [
-            {
-              'action_name': 'buildLibktxDoc',
-              'message': 'Generating libktx documentation with Doxygen',
-              'inputs': [
-                '../<(doxyConfig)',
-                '../runDoxygen',
-                '../lib/mainpage.md',
-                '../LICENSE.md',
-                '../TODO.md',
-                '<@(sources)',
-                '<@(vksource_files)',
-              ],
-              # If other partial Doxygen outputs are included, e.g.
-              # (<(output_dir)/html/libktx), CMake's make generator
-              # on Linux (at least), makes timestamp dependent on
-              # those other outputs. If those outputs exist, then
-              # neither timestamp nor the document is updated.
-              'outputs': [ '<(timestamp)' ],
-              # doxygen must be run in the top-level project directory
-              # so that ancestors of that directory will be removed
-              # from paths displayed in the documentation. That is
-              # the directory where the .doxy and .gyp files are stored.
-              #
-              # With Xcode, the current directory during project
-              # build is one we need so we're good to go. However
-              # we need to spawn another shell with -l so the
-              # startup (.bashrc, etc) files will be read.
-              #
-              # With MSVS the working directory will be the
-              # location of the vcxproj file. However when the
-              # action is using bash ('msvs_cygwin_shell': '1',
-              # the default, is set) no path relativization is
-              # performed on any command arguments. If forced, by
-              # using variable names such as '*_dir', paths will be
-              # made relative to the location of the .gyp file.
-              #
-              # A setup_env.bat file is run before the command.
-              # Apparently that .bat file is expected to be in the
-              # same location as the .gyp and to cd to
-              # its directory. That makes things work.
-              #
-              # Note that the same setup_env.bat is run by
-              # rules but rules relativize paths to the vcxproj
-              # location so cd to the .gyp home breaks rules.
-              # Therefore in rules set 'msvs_cygwin_shell': '0.
-              #
-              # If using cmd.exe ('msvs_cygwin_shell': '0')
-              # the MSVS generator will relativize to the vcxproj
-              # location *all* command arguments, that do not look
-              # like options.
-              #
-              # With `make`, cmake, etc, like Xcode,  the current
-              # directory during project build is the one we need.
-              'msvs_cygwin_shell': 1,
-              'action': [
-                './runDoxygen',
-                '-t', '<(timestamp)',
-                '-o', '<(output_dir)/html',
-                '<(doxyConfig)',
-              ],
-            }, # buildDoc action
-          ], # actions
-        }, # libktx.doc
-      ], # targets
-    }], # 'OS == "linux" or OS == "mac" or OS == "win"'
-  ], # conditions
-}
-
-# vim:ai:ts=4:sts=4:sw=2:expandtab:textwidth=70
diff --git a/external/KTX-Software-master/lib/mainpage.md b/external/KTX-Software-master/lib/mainpage.md
deleted file mode 100644
index b50ba9ec714d411ca07315065227788055334988..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/mainpage.md
+++ /dev/null
@@ -1,214 +0,0 @@
-Introduction             {#mainpage}
-=========
-
-libktx is a small library of functions for creating and reading KTX (Khronos
-TeXture) files and instantiating OpenGL&reg; and OpenGL&reg; ES
-textures and Vulkan images from them.
-
-For information about the KTX format see the
-<a href="http://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/">
-formal specification.</a>
-
-The library is open source software. Source code is available at
-<a href="https://github.com/KhronosGroup/KTX">GitHub</a>. Most of the source
-code and the documentation is licensed under the Apache 2.0 license. See @ref license
-for details. When distributing the library, whether in source or binary form, this
-documentation must be included in the distribution or otherwise made available to
-recipients.
-
-See @ref libktx_history for the list of changes.
-
-See @ref todo for the current To Do list.
-
-@authors
-Mark Callow, <a href="http://www.edgewise-consulting.com">Edgewise Consulting</a>,
-             formerly at <a href="http://www.hicorp.co.jp">HI Corporation</a>\n
-Georg Kolling, <a href="http://www.imgtec.com">Imagination Technology</a>\n
-Jacob Str&ouml;m, <a href="http://www.ericsson.com">Ericsson AB</a>
-
-@version 3.0.0
-
-$Date$
-
-# Usage Overview                              {#overview}
-
-## Reading a KTX file for non-GL and non-Vulkan Use  {#readktx}
-
-~~~~~~~~~~~~~~~~{.c}
-#include <ktx.h>
-
-ktxTexture* texture;
-KTX_error_code result;
-ktx_size_t offset;
-ktx_uint8_t* image;
-ktx_uint32_t level, layer, faceSlice;
-
-result = ktxTexture_CreateFromNamedFile("mytex3d.ktx",
-                                        KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT,
-                                        &texture);
-
-// Retrieve information about the texture from fields in the ktxTexture
-// such as:
-ktx_uint32 numLevels = texture->numLevels;
-ktx_uint32 baseWidth = texture->baseWidth;
-ktx_bool_t isArray = texture->isArray;
-
-// Retrieve a pointer to the image for a specific mip level, array layer
-// & face or depth slice.
-level = 1; layer = 0; faceSlice = 3;
-result = ktxTexture_GetImageOffset(texture, level, layer, faceSlice, &offset);
-image = ktxTexture_GetData(texture) + offset;
-// ...
-// Do something with the texture image.
-// ...
-ktxTexture_Destroy(texture);
-~~~~~~~~~~~~~~~~
-
-## Creating a GL texture object from a KTX file.   {#createGL}
-
-~~~~~~~~~~~~~~~~{.c}
-#include <ktx.h>
-
-ktxTexture* kTexture;
-KTX_error_code result;
-ktx_size_t offset;
-ktx_uint8_t* image;
-ktx_uint32_t level, layer, faceSlice;
-GLuint texture = 0;
-GLenum target, glerror;
-
-result = ktxTexture_CreateFromNamedFile("mytex3d.ktx",
-                                        KTX_TEXTURE_CREATE_NO_FLAGS,
-                                        &kTexture);
-glGenTextures(1, &texture); // Optional. GLUpload can generate a texture.
-result = ktxtexture_GLUpload(kTexture, &texture, &target, &glerror);
-ktxTexture_Destroy(texture);
-// ...
-// GL rendering using the texture
-// ...
-~~~~~~~~~~~~~~~~
-
-## Creating a Vulkan image object from a KTX file.  {#createVulkan}
-
-~~~~~~~~~~~~~~~~{.c}
-#include <ktxvulkan.h>
-
-ktxTexture* kTexture;
-KTX_error_code result;
-ktx_size_t offset;
-ktx_uint8_t* image;
-ktx_uint32_t level, layer, faceSlice;
-ktxVulkanDeviceInfo vdi;
-ktxVulkanTexture texture;
-
-// Set up Vulkan physical device (gpu), logical device (device), queue
-// and command pool. Save the handles to these in a struct called vkctx.
-// ktx VulkanDeviceInfo is used to pass these with the expectation that
-// apps are likely to upload a large number of textures.
-ktxVulkanDeviceInfo_Construct(&vdi, vkctx.gpu, vkctx.device,
-                              vkctx.queue, vkctx.commandPool, nullptr);
-
-ktxresult = ktxTexture_CreateFromNamedFile("mytex3d.ktx",
-                                           KTX_TEXTURE_CREATE_NO_FLAGS,
-                                           &kTexture);
-
-ktxresult = ktxTexture_VkUploadEx(kTexture, &vdi, &texture,
-                                  VK_IMAGE_TILING_OPTIMAL,
-                                  VK_IMAGE_USAGE_SAMPLED_BIT,
-                                  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
-
-ktxTexture_Destroy(kTexture);
-ktxVulkanDeviceInfo_Destruct(&vdi);
-// ...
-// Vulkan rendering using the texture
-// ...
-// When done using the image in Vulkan...
-ktxVulkanTexture_Destruct(&texture, vkctx.device, nullptr);
-~~~~~~~~~~~~~~~~
-
-## Extracting Metadata        {#subsection}
-
-Once a ktxTexture object has been created, metadata can be easily found
-and extracted. The following can be added to any of the above.
-
-~~~~~~~~~~~~~~~~{.c}
-char* pValue;
-uint32_t valueLen;
-if (KTX_SUCCESS == ktxHashList_FindValue(&kTexture->kvDataHead,
-                                          KTX_ORIENTATION_KEY,
-                                          &valueLen, (void**)&pValue))
- {
-      char s, t;
-
-      if (sscanf(pValue, KTX_ORIENTATION2_FMT, &s, &t) == 2) {
-         ...
-      }
- }
-~~~~~~~~~~~~~~~~
-
-## Writing a KTX file         {#writektx}
-
-~~~~~~~~~~~~~~~~{.c}
-#include <ktx.h>
-
-ktxTexture* texture;
-ktxTextureCreateInfo createInfo;
-KTX_error_code result;
-ktx_uint32_t level, layer, faceSlice;
-FILE* src;
-ktx_size_t srcSize;
-
-createInfo.glInternalformat = GL_RGB8;
-createInfo.baseWidth = 2048;
-createInfo.baseHeight = 1024;
-createInfo.baseDepth = 16;
-createInfo.numDimensions = 3.
-// Note: it is not necessary to provide a full mipmap pyramid.
-createInfo.numLevels = log2(createInfo.baseWidth) + 1
-createInfo.numLayers = 1;
-createInfo.numFaces = 1;
-createInfo.isArray = KTX_FALSE;
-createInfo.generateMipmaps = KTX_FALSE;
-
-result = ktxTexture_Create(createInfo,
-                           KTX_TEXTURE_CREATE_ALLOC_STORAGE,
-                           &texture);
-
-src = // Open a stdio FILE* on the baseLevel image, slice 0.
-srcSize = // Query size of the file.
-level = 0;
-layer = 0;
-faceSlice = 0;                           
-result = ktxTexture_SetImageFromMemory(texture, level, layer, faceSlice,
-                                       src, srcSize);
-// Repeat for the other 15 slices of the base level and all other levels
-// up to createInfo.numLevels.
-
-ktxTexture_WriteToNamedFile(texture, "mytex3d.ktx");
-ktxTexture_Destroy(texture);
-~~~~~~~~~~~~~~~~
-
-## Modifying a KTX file         {#modifyktx}
-
-~~~~~~~~~~~~~~~~{.c}
-#include <ktx.h>
-
-ktxTexture* texture;
-KTX_error_code result;
-ktx_size_t offset;
-ktx_uint8_t* image;
-ktx_uint32_t level, layer, faceSlice;
-
-result = ktxTexture_CreateFromNamedFile("mytex3d.ktx",
-                                        KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT,
-                                        &texture);
-// The file is closed after all the data has been read.
-
-// It is the responsibilty of the application to make sure its
-// modifications are valid.
-texture->generateMipmaps = KTX_TRUE;
-
-ktxTexture_WriteToNamedFile(texture, "mytex3d.ktx");
-ktxTexture_Destroy(texture);
-~~~~~~~~~~~~~~~~
-
diff --git a/external/KTX-Software-master/lib/memstream.c b/external/KTX-Software-master/lib/memstream.c
deleted file mode 100644
index 523b55191954405d8cb7e98f101f519dc671cbb9..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/memstream.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/*
- * Copyright (c) 2010-2018 The Khronos Group Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @internal
- * @file
- * @~English
- *
- * @brief Implementation of ktxStream for memory.
- *
- * @author Maksim Kolesin, Under Development
- * @author Georg Kolling, Imagination Technology
- * @author Mark Callow, HI Corporation
- */
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "ktx.h"
-#include "ktxint.h"
-#include "memstream.h"
-
-/**
-* @brief Default allocation size for a ktxMemStream.
-*/
-#define KTX_MEM_DEFAULT_ALLOCATED_SIZE 256
-
-/**
- * @internal
- * @brief Structure to store information about data allocated for ktxMemStream.
- */
-struct ktxMem
-{
-    const ktx_uint8_t* robytes;/*!< pointer to read-only data */
-    ktx_uint8_t* bytes;        /*!< pointer to rw data. */
-    ktx_size_t alloc_size;       /*!< allocated size of the memory block. */
-    ktx_size_t used_size;        /*!< bytes used. Effectively the write position. */
-    ktx_off_t pos;               /*!< read position. */
-};
-
-static KTX_error_code ktxMem_expand(ktxMem* pMem, const ktx_size_t size);
-
-/**
- * @internal
- * @brief Initialize a ktxMem struct for read-write.
- *
- * Memory for the stream data is allocated internally but the
- * caller is responsible for freeing the memory. A pointer to
- * the memory can be obtained with ktxMem_getdata().
- *
- * @sa ktxMem_getdata.
- *
- * @param [in] pMem pointer to the @c ktxMem to initialize.
- */
-static KTX_error_code
-ktxMem_construct(ktxMem* pMem)
-{
-    pMem->pos = 0;
-    pMem->alloc_size = 0;
-    pMem->robytes = 0;
-    pMem->bytes = 0;
-    pMem->used_size = 0;
-    return ktxMem_expand(pMem, KTX_MEM_DEFAULT_ALLOCATED_SIZE);
-}
-
-/**
- * @internal
- * @brief Create & initialize a ktxMem struct for read-write.
- *
- * @sa ktxMem_construct.
- *
- * @param [in,out] ppMem pointer to the location in which to return
- *                       a pointer to the newly created @c ktxMem.
- *
- * @return     KTX_SUCCESS on success, KTX_OUT_OF_MEMORY on error.
- *
- * @exception  KTX_OUT_OF_MEMORY    System failed to allocate sufficient pMemory.
- */
-static KTX_error_code
-ktxMem_create(ktxMem** ppMem)
-{
-    ktxMem* pNewMem = (ktxMem*)malloc(sizeof(ktxMem));
-    if (pNewMem) {
-        KTX_error_code result = ktxMem_construct(pNewMem);
-        if (result == KTX_SUCCESS)
-            *ppMem = pNewMem;
-        return result;
-    }
-    else {
-        return KTX_OUT_OF_MEMORY;
-    }
-}
-
-/**
- * @internal
- * @brief Initialize a ktxMem struct for read-only.
- *
- * @param [in] pMem     pointer to the @c ktxMem to initialize.
- * @param [in] bytes    pointer to the data to be read.
- * @param [in] numBytes number of bytes of data.
- */
-static void
-ktxMem_construct_ro(ktxMem* pMem, const void* bytes, ktx_size_t numBytes)
-{
-    pMem->pos = 0;
-    pMem->robytes = bytes;
-    pMem->bytes = 0;
-    pMem->used_size = numBytes;
-    pMem->alloc_size = numBytes;
-}
-
-/**
- * @internal
- * @brief Create & initialize a ktxMem struct for read-only.
- *
- * @sa ktxMem_construct.
- *
- * @param [in,out] ppMem    pointer to the location in which to return
- *                          a pointer to the newly created @c ktxMem.
- * @param [in]     bytes    pointer to the data to be read.
- * @param [in]     numBytes number of bytes of data.
- *
- * @return     KTX_SUCCESS on success, KTX_OUT_OF_MEMORY on error.
- *
- * @exception  KTX_OUT_OF_MEMORY    System failed to allocate sufficient pMemory.
- */
-static KTX_error_code
-ktxMem_create_ro(ktxMem** ppMem, const void* bytes, ktx_size_t numBytes)
-{
-    ktxMem* pNewMem = (ktxMem*)malloc(sizeof(ktxMem));
-    if (pNewMem) {
-        ktxMem_construct_ro(pNewMem, bytes, numBytes);
-        *ppMem = pNewMem;
-        return KTX_SUCCESS;
-    }
-    else {
-        return KTX_OUT_OF_MEMORY;
-    }
-}
-
-/*
- * ktxMem_destruct not needed as ktxMem_construct caller is reponsible
- * for freeing the data written.
- */
-
-/**
- * @internal
- * @brief Free the memory of a struct ktxMem.
- *
- * @param pMem pointer to ktxMem to free.
- */
-static void
-ktxMem_destroy(ktxMem* pMem, ktx_bool_t freeData)
-{
-    assert(pMem != NULL);
-    if (freeData) {
-        free(pMem->bytes);
-    }
-    free(pMem);
-}
-
-#ifdef KTXMEM_CLEAR_USED
-/**
- * @internal
- * @brief Clear the data of a memory stream.
- *
- * @param pMem pointer to ktxMem to clear.
- */
-static void
-ktxMem_clear(ktxMem* pMem)
-{
-    assert(pMem != NULL);
-    memset(pMem, 0, sizeof(ktxMem));
-}
-#endif
-
-/**
- * @internal
- * @~English
- * @brief Expand a ktxMem to fit to a new size.
- *
- * @param [in] pMem          pointer to ktxMem struct to expand.
- * @param [in] newsize       minimum new size required.
- *
- * @return     KTX_SUCCESS on success, KTX_OUT_OF_MEMORY on error.
- *
- * @exception  KTX_OUT_OF_MEMORY    System failed to allocate sufficient pMemory.
- */
-static KTX_error_code
-ktxMem_expand(ktxMem *pMem, const ktx_size_t newsize)
-{
-    ktx_size_t new_alloc_size;
-    
-    assert(pMem != NULL && newsize != 0);
-
-    new_alloc_size = pMem->alloc_size == 0 ?
-                     KTX_MEM_DEFAULT_ALLOCATED_SIZE : pMem->alloc_size;
-    while (new_alloc_size < newsize) {
-        ktx_size_t alloc_size = new_alloc_size;
-        new_alloc_size <<= 1;
-        if (new_alloc_size < alloc_size) {
-            /* Overflow. Set to maximum size. newsize can't be larger. */
-            new_alloc_size = (ktx_size_t)-1L;
-        }
-    }
-
-    if (new_alloc_size == pMem->alloc_size)
-        return KTX_SUCCESS;
-
-    if (!pMem->bytes)
-        pMem->bytes = (ktx_uint8_t*)malloc(new_alloc_size);
-    else
-        pMem->bytes = (ktx_uint8_t*)realloc(pMem->bytes, new_alloc_size);
-
-    if (!pMem->bytes)
-    {
-        pMem->alloc_size = 0;
-        pMem->used_size = 0;
-        return KTX_OUT_OF_MEMORY;
-    }
-
-    pMem->alloc_size = new_alloc_size;
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Read bytes from a ktxMemStream.
- *
- * @param [in]     str      pointer to ktxMem struct, converted to a void*, that
- *                          specifies an input stream.
- * @param [in,out] dst      pointer to memory where to copy read bytes.
- * @param [in,out] count    pointer to number of bytes to read.
- *
- * @return      KTX_SUCCESS on success, KTX_INVALID_VALUE on error.
- *
- * @exception KTX_INVALID_VALUE     @p str or @p dst is @c NULL or @p str->data is
- *                                  @c NULL.
- * @exception KTX_FILE_UNEXPECTED_EOF not enough data to satisfy the request.
- */
-static
-KTX_error_code ktxMemStream_read(ktxStream* str, void* dst, const ktx_size_t count)
-{
-    ktxMem* mem;
-    ktx_off_t newpos;
-    const ktx_uint8_t* bytes;
-    
-
-    if (!str || !(mem = str->data.mem))
-        return KTX_INVALID_VALUE;
-
-    newpos = mem->pos + count;
-    /* The first clause checks for overflow. */
-    if (newpos < mem->pos || newpos > mem->used_size)
-        return KTX_FILE_UNEXPECTED_EOF;
-
-    bytes = mem->robytes ? mem->robytes : mem->bytes;
-    memcpy(dst, bytes + mem->pos, count);
-    mem->pos = newpos;
-
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Skip bytes in a ktxMemStream.
- *
- * @param [in] str      pointer to the ktxStream on which to operate.
- * @param [in] count    number of bytes to skip.
- *
- * @return      KTX_SUCCESS on success, KTX_INVALID_VALUE on error.
- *
- * @exception KTX_INVALID_VALUE     @p str or @p mem is @c NULL or sufficient
- *                                  data is not available in ktxMem.
- * @exception KTX_FILE_UNEXPECTED_EOF not enough data to satisfy the request.
- */
-static
-KTX_error_code ktxMemStream_skip(ktxStream* str, const ktx_size_t count)
-{
-    ktxMem* mem;
-    ktx_off_t newpos;
-    
-    if (!str || !(mem = str->data.mem))
-        return KTX_INVALID_VALUE;
-    
-    newpos = mem->pos + count;
-    /* The first clause checks for overflow. */
-    if (newpos < mem->pos || newpos > mem->used_size)
-        return KTX_FILE_UNEXPECTED_EOF;
-
-    mem->pos = newpos;
-
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Write bytes to a ktxMemStream.
- *
- * @param [out] str    pointer to the ktxStream that specifies the destination.
- * @param [in] src     pointer to the array of elements to be written,
- *                     converted to a const void*.
- * @param [in] size    size in bytes of each element to be written.
- * @param [in] count   number of elements, each one with a @p size of size
- *                     bytes.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_FILE_OVERFLOW        write would result in file exceeding the
- *                                     maximum permissible size.
- * @exception KTX_INVALID_OPERATION    @p str is a read-only stream.
- * @exception KTX_INVALID_VALUE        @p dst is @c NULL or @p mem is @c NULL.
- * @exception KTX_OUT_OF_MEMORY        See ktxMem_expand() for causes.
- */
-static
-KTX_error_code ktxMemStream_write(ktxStream* str, const void* src,
-                                  const ktx_size_t size, const ktx_size_t count)
-{
-    ktxMem* mem;
-    KTX_error_code rc = KTX_SUCCESS;
-    ktx_size_t new_size;
-
-    if (!str || !(mem = str->data.mem))
-        return KTX_INVALID_VALUE;
-
-    if (mem->robytes)
-        return KTX_INVALID_OPERATION; /* read-only */
-
-    new_size = mem->used_size + size*count;
-    if (new_size < mem->used_size)
-        return KTX_FILE_OVERFLOW;
-
-    if (mem->alloc_size < new_size) {
-        rc = ktxMem_expand(mem, new_size);
-        if (rc != KTX_SUCCESS)
-            return rc;
-    }
-
-    memcpy(mem->bytes + mem->used_size, src, size*count);
-    mem->used_size += size*count;
-
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Get the current read/write position in a ktxMemStream.
- *
- * @param [in] str      pointer to the ktxStream to query.
- * @param [in,out] off  pointer to variable to receive the offset value.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p str or @p pos is @c NULL.
- */
-static
-KTX_error_code ktxMemStream_getpos(ktxStream* str, ktx_off_t* const pos)
-{
-    if (!str || !pos)
-        return KTX_INVALID_VALUE;
-    
-    assert(str->type == eStreamTypeMemory);
-    
-    *pos = str->data.mem->pos;
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Set the current read/write position in a ktxMemStream.
- *
- * Offset of 0 is the start of the file.
- *
- * @param [in] str    pointer to the ktxStream whose r/w position is to be set.
- * @param [in] off    pointer to the offset value to set.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p str is @c NULL.
- * @exception KTX_INVALID_OPERATION @p pos > size of the allocated memory.
- */
-static
-KTX_error_code ktxMemStream_setpos(ktxStream* str, ktx_off_t pos)
-{
-    if (!str)
-        return KTX_INVALID_VALUE;
-    
-    assert(str->type == eStreamTypeMemory);
-    
-    if (pos > str->data.mem->alloc_size)
-        return KTX_INVALID_OPERATION;
-    
-    str->data.mem->pos = pos;
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Get a pointer to a ktxMemStream's data.
- *
- * Gets a pointer to data that has been written to the stream. Returned
- * pointer will be 0 if stream is read-only.
- *
- * @param [in] str       pointer to the ktxStream whose data pointer is to
- *                       be queried.
- * @param [in,out] size  pointer to a variable in which the data pointer
- *                       will be written.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p str or @p ppBytes is @c NULL.
- */
-KTX_error_code ktxMemStream_getdata(ktxStream* str, ktx_uint8_t** ppBytes)
-{
-    if (!str || !ppBytes)
-        return KTX_INVALID_VALUE;
-
-    assert(str->type == eStreamTypeMemory);
-
-    *ppBytes = str->data.mem->bytes;
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Get the size of a ktxMemStream in bytes.
- *
- * @param [in] str       pointer to the ktxStream whose size is to be queried.
- * @param [in,out] size  pointer to a variable in which size will be written.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p str or @p pSize is @c NULL.
- */
-static
-KTX_error_code ktxMemStream_getsize(ktxStream* str, ktx_size_t* pSize)
-{
-    if (!str || !pSize)
-        return KTX_INVALID_VALUE;
-    
-    assert(str->type == eStreamTypeMemory);
-    
-    *pSize = str->data.mem->used_size;
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Setup ktxMemStream function pointers.
- */
-void
-ktxMemStream_setup(ktxStream* str)
-{
-    str->type = eStreamTypeMemory;
-    str->read = ktxMemStream_read;
-    str->skip = ktxMemStream_skip;
-    str->write = ktxMemStream_write;
-    str->getpos = ktxMemStream_getpos;
-    str->setpos = ktxMemStream_setpos;
-    str->getsize = ktxMemStream_getsize;
-    str->destruct = ktxMemStream_destruct;
-}
-
-/**
- * @internal
- * @~English
- * @brief Initialize a read-write ktxMemStream.
- *
- * Memory is allocated as data is written. The caller of this is
- * responsible for freeing this memory unless @a freeOnDestruct
- * is not KTX_FALSE.
- *
- * @param [in] str             pointer to a ktxStream struct to initialize.
- * @param [in] freeOnDestruct  If not KTX_FALSE memory holding the data will
- *                             be freed by the destructor.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE     @p str is @c NULL.
- * @exception KTX_OUT_OF_MEMORY     system failed to allocate sufficient memory.
- */
-KTX_error_code ktxMemStream_construct(ktxStream* str,
-                                      ktx_bool_t freeOnDestruct)
-{
-    ktxMem* mem;
-    KTX_error_code result = KTX_SUCCESS;
-
-    if (!str)
-        return KTX_INVALID_VALUE;
-
-    result = ktxMem_create(&mem);
-
-    if (KTX_SUCCESS == result) {
-        str->data.mem = mem;
-        ktxMemStream_setup(str);
-        str->closeOnDestruct = freeOnDestruct;
-    }
-
-    return result;
-}
-
-/**
- * @internal
- * @~English
- * @brief Initialize a read-only ktxMemStream.
- *
- * @param [in] str      pointer to a ktxStream struct to initialize.
- * @param [in] bytes    pointer to an array of bytes containing the data.
- * @param [in] size     size of array of data for ktxMemStream.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE     @p str or @p mem is @c NULL or @p numBytes
- *                                  is 0.
- *                                  or @p size is less than 0.
- * @exception KTX_OUT_OF_MEMORY     system failed to allocate sufficient memory.
- */
-KTX_error_code ktxMemStream_construct_ro(ktxStream* str,
-                                         const ktx_uint8_t* bytes,
-                                         const ktx_size_t numBytes)
-{
-    ktxMem* mem;
-    KTX_error_code result = KTX_SUCCESS;
-
-    if (!str || !bytes || numBytes == 0)
-        return KTX_INVALID_VALUE;
-
-    result = ktxMem_create_ro(&mem, bytes, numBytes);
-
-    if (KTX_SUCCESS == result) {
-        str->data.mem = mem;
-        ktxMemStream_setup(str);
-        str->closeOnDestruct = KTX_FALSE;
-    }
-
-    return result;
-}
-
-/**
- * @internal
- * @~English
- * @brief Free the memory used by a ktxMemStream.
- *
- * This only frees the memory used to store the data written to the stream,
- * if the @c freeOnDestruct parameter to ktxMemStream_construct() was not
- * @c KTX_FALSE. Otherwise it is the responsibility of the caller of
- * ktxMemStream_construct() and a pointer to this memory should be retrieved
- * using ktxMemStream_getdata() before calling this function.
- *
- * @sa ktxMemStream_construct, ktxMemStream_getdata.
- *
- * @param [in] str pointer to the ktxStream whose memory is
- *                 to be freed.
- */
-void
-ktxMemStream_destruct(ktxStream* str)
-{
-    assert(str && str->type == eStreamTypeMemory);
-
-    ktxMem_destroy(str->data.mem, str->closeOnDestruct);
-    str->data.mem = NULL;
-}
-
diff --git a/external/KTX-Software-master/lib/memstream.h b/external/KTX-Software-master/lib/memstream.h
deleted file mode 100644
index 3cd4e03f77a92342c42852f9688102bae79f61e9..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/memstream.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/*
- * Copyright (c) 2010-2018 The Khronos Group Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @internal
- * @file
- * @~English
- *
- * @brief Interface of ktxStream for memory.
- *
- * @author Maksim Kolesin
- * @author Georg Kolling, Imagination Technology
- * @author Mark Callow, HI Corporation
- */
-
-#ifndef MEMSTREAM_H
-#define MEMSTREAM_H
-
-#include "ktx.h"
-#include "stream.h"
-
-/*
- * Initialize a ktxStream to a ktxMemStream with internally
- * allocated memory. Can be read or written.
- */
-KTX_error_code ktxMemStream_construct(ktxStream* str,
-                                      ktx_bool_t freeOnDestruct);
-/*
- * Initialize a ktxStream to a read-only ktxMemStream reading
- * from an array of bytes.
- */
-KTX_error_code ktxMemStream_construct_ro(ktxStream* str,
-                                         const ktx_uint8_t* pBytes,
-                                         const ktx_size_t size);
-void ktxMemStream_destruct(ktxStream* str);
-
-KTX_error_code ktxMemStream_getdata(ktxStream* str, ktx_uint8_t** ppBytes);
-
-#endif /* MEMSTREAM_H */
diff --git a/external/KTX-Software-master/lib/stream.h b/external/KTX-Software-master/lib/stream.h
deleted file mode 100644
index 9b9a7272d31acd5510056a8203020c441f835a1f..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/stream.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/*
- * Copyright (c) 2010-2018 The Khronos Group Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @internal
- * @file
- * @~English
- *
- * @brief Interface of ktxStream.
- *
- * @author Maksim Kolesin
- * @author Georg Kolling, Imagination Technology
- * @author Mark Callow, HI Corporation
- */
-
-#ifndef KTXSTREAM_H
-#define KTXSTREAM_H
-
-#include <sys/types.h>
-#include "ktx.h"
-
-/* 
- * This is unsigned to allow ktxmemstreams to use the
- * full amount of memory available. Platforms will
- * limit the size of ktxfilestreams to, e.g, MAX_LONG
- * on 32-bit and ktxfilestreams raises errors if
- * offset values exceed the limits. This choice may
- * need to be revisited if we ever start needing -ve
- * offsets.
- *
- * Should the 2GB file size handling limit on 32-bit
- * platforms become a problem, ktxfilestream will have
- * to be changed to explicitly handle large files by
- * using the 64-bit stream functions.
- */
-#if defined(_MSC_VER) && defined(_WIN64)
-  typedef unsigned __int64 ktx_off_t;
-#else
-  typedef   size_t ktx_off_t;
-#endif
-typedef struct ktxMem ktxMem;
-typedef struct ktxStream ktxStream;
-
-enum streamType { eStreamTypeFile = 1, eStreamTypeMemory = 2 };
-
-/**
- * @internal
- * @~English
- * @brief type for a pointer to a stream reading function
- */
-typedef KTX_error_code (*ktxStream_read)(ktxStream* str, void* dst,
-                                         const ktx_size_t count);
-/**
- * @internal
- * @~English
- * @brief type for a pointer to a stream skipping function
- */
-typedef KTX_error_code (*ktxStream_skip)(ktxStream* str,
-                                         const ktx_size_t count);
-
-/**
- * @internal
- * @~English
- * @brief type for a pointer to a stream reading function
- */
-typedef KTX_error_code (*ktxStream_write)(ktxStream* str, const void *src,
-                                          const ktx_size_t size,
-                                          const ktx_size_t count);
-
-/**
- * @internal
- * @~English
- * @brief type for a pointer to a stream position query function
- */
-typedef KTX_error_code (*ktxStream_getpos)(ktxStream* str, ktx_off_t* const offset);
-
-/**
- * @internal
- * @~English
- * @brief type for a pointer to a stream position query function
- */
-typedef KTX_error_code (*ktxStream_setpos)(ktxStream* str, const ktx_off_t offset);
-
-/**
- * @internal
- * @~English
- * @brief type for a pointer to a stream size query function
- */
-typedef KTX_error_code (*ktxStream_getsize)(ktxStream* str, ktx_size_t* const size);
-
-/**
- * @internal
- * @~English
- * @brief Destruct a stream
- */
-typedef void (*ktxStream_destruct)(ktxStream* str);
-
-/**
- * @internal
- * @~English
- * @brief KTX stream class
- */
-struct ktxStream
-{
-    ktxStream_read read;   /*!< @internal pointer to function for reading bytes. */
-    ktxStream_skip skip;   /*!< @internal pointer to function for skipping bytes. */
-    ktxStream_write write; /*!< @internal pointer to function for writing bytes. */
-    ktxStream_getpos getpos; /*!< @internal pointer to function for getting current position in stream. */
-    ktxStream_setpos setpos; /*!< @internal pointer to function for setting current position in stream. */
-    ktxStream_getsize getsize; /*!< @internal pointer to function for querying size. */
-    ktxStream_destruct destruct; /*!< @internal destruct the stream. */
-
-    enum streamType type;
-    union {
-        FILE* file;
-        ktxMem* mem;
-    } data;                /**< @internal pointer to the stream data. */
-    ktx_bool_t closeOnDestruct; /**< @internal Close FILE* or dispose of memory on destruct. */
-};
-
-#endif /* KTXSTREAM_H */
diff --git a/external/KTX-Software-master/lib/swap.c b/external/KTX-Software-master/lib/swap.c
deleted file mode 100644
index bb2579e41b6f86fe576f1db7bd7394814fc0e25e..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/swap.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/* $Id: d858975c68f39438233f78cbf217f70fc5ddd316 $ */
-
-/*
- * Copyright (c) 2010 The Khronos Group Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "KHR/khrplatform.h"
-
-/*
- * SwapEndian16: Swaps endianness in an array of 16-bit values
- */
-void
-_ktxSwapEndian16(khronos_uint16_t* pData16, int count)
-{
-    int i;
-    for (i = 0; i < count; ++i)
-    {
-        khronos_uint16_t x = *pData16;
-        *pData16++ = (x << 8) | (x >> 8);
-    }
-}
-
-/*
- * SwapEndian32: Swaps endianness in an array of 32-bit values
- */
-void 
-_ktxSwapEndian32(khronos_uint32_t* pData32, int count)
-{
-    int i;
-    for (i = 0; i < count; ++i)
-    {
-        khronos_uint32_t x = *pData32;
-        *pData32++ = (x << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | (x >> 24);
-    }
-}
-
-
diff --git a/external/KTX-Software-master/lib/texture.c b/external/KTX-Software-master/lib/texture.c
deleted file mode 100644
index 0bfa703714c825437683c9c1e91474ea85065cd9..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/texture.c
+++ /dev/null
@@ -1,1636 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/*
- * ©2018 Mark Callow.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @internal
- * @file writer.c
- * @~English
- *
- * @brief ktxTexture implementation.
- *
- * @author Mark Callow, www.edgewise-consulting.com
- */
-
-#ifdef _WIN32
-#define _CRT_SECURE_NO_WARNINGS
-#endif
-
-#include <stdlib.h>
-
-#include "ktx.h"
-#include "ktxint.h"
-#include "stream.h"
-#include "filestream.h"
-#include "memstream.h"
-#include "gl_format.h"
-#include "uthash.h"
-
-/**
- * @internal
- * @~English
- * @brief Internal ktxTexture structure.
- *
- * This is kept hidden to avoid burdening applications with the definitions
- * of GlFormatSize and ktxStream.
- */
-typedef struct _ktxTextureInt {
-    ktxTexture super;         /*!< Base ktxTexture class. */
-    GlFormatSize formatInfo;  /*!< Info about the image data format. */
-    // The following are needed because image data reading can be delayed.
-    ktx_uint32_t glTypeSize;  /*!< Size of the image data type in bytes. */
-    ktxStream stream;         /*!< Stream connected to KTX source. */
-    ktx_bool_t needSwap;   /*!< If KTX_TRUE, image data needs byte swapping. */
-} ktxTextureInt;
-
-ktx_size_t ktxTexture_GetSize(ktxTexture* This);
-KTX_error_code ktxTexture_LoadImageData(ktxTexture* This,
-                                        ktx_uint8_t* pBuffer,
-                                        ktx_size_t bufSize);
-
-static ktx_size_t ktxTexture_calcDataSize(ktxTexture* This);
-static ktx_uint32_t padRow(ktx_uint32_t* rowBytes);
-
-
-/**
- * @memberof ktxTexture @private
- * @brief Construct (initialize) a ktxTexture.
- *
- * @param[in] This pointer to a ktxTextureInt-sized block of memory to
- *                 initialize.
- * @param[in] createInfo pointer to a ktxTextureCreateInfo struct with
- *                       information describing the texture.
- * @param[in] storageAllocation
- *                       enum indicating whether or not to allocation storage
- *                       for the texture images.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @c glInternalFormat in @p createInfo is not a
- *                              valid OpenGL internal format value.
- * @exception KTX_INVALID_VALUE @c numDimensions in @p createInfo is not 1, 2
- *                              or 3.
- * @exception KTX_INVALID_VALUE One of <tt>base{Width,Height,Depth}</tt> in
- *                              @p createInfo is 0.
- * @exception KTX_INVALID_VALUE @c numFaces in @p createInfo is not 1 or 6.
- * @exception KTX_INVALID_VALUE @c numLevels in @p createInfo is 0.
- * @exception KTX_INVALID_OPERATION
- *                              The <tt>base{Width,Height,Depth}</tt> specified
- *                              in @p createInfo are inconsistent with
- *                              @c numDimensions.
- * @exception KTX_INVALID_OPERATION
- *                              @p createInfo is requesting a 3D array or
- *                              3D cubemap texture.
- * @exception KTX_INVALID_OPERATION
- *                              @p createInfo is requesting a cubemap with
- *                              non-square or non-2D images.
- * @exception KTX_INVALID_OPERATION
- *                              @p createInfo is requesting more mip levels
- *                              than needed for the specified
- *                              <tt>base{Width,Height,Depth}</tt>.
- * @exception KTX_OUT_OF_MEMORY Not enough memory for the texture's images.
- */
-static KTX_error_code
-ktxTextureInt_construct(ktxTextureInt* This, ktxTextureCreateInfo* createInfo,
-                        ktxTextureCreateStorageEnum storageAllocation)
-{
-    ktxTexture* super = (ktxTexture*)This;
-    GLuint typeSize;
-    GLenum glFormat;
-    
-    memset(This, 0, sizeof(*This));
-
-    super->glInternalformat = createInfo->glInternalformat;
-    glGetFormatSize(super->glInternalformat, &This->formatInfo);;
-    glFormat= glGetFormatFromInternalFormat(createInfo->glInternalformat);
-    if (glFormat == GL_INVALID_VALUE)
-        return KTX_INVALID_VALUE;
-    super->isCompressed
-                    = (This->formatInfo.flags & GL_FORMAT_SIZE_COMPRESSED_BIT);
-    if (super->isCompressed) {
-        super->glFormat = 0;
-        super->glBaseInternalformat = glFormat;
-        super->glType = 0;
-        This->glTypeSize = 0;
-    } else {
-        super->glBaseInternalformat = super->glFormat = glFormat;
-        super->glType
-                = glGetTypeFromInternalFormat(createInfo->glInternalformat);
-        if (super->glType == GL_INVALID_VALUE)
-            return KTX_INVALID_VALUE;
-        typeSize = glGetTypeSizeFromType(super->glType);
-        assert(typeSize != GL_INVALID_VALUE);
-    
-        /* Do some sanity checking */
-        if (typeSize != 1 &&
-            typeSize != 2 &&
-            typeSize != 4)
-        {
-            /* Only 8, 16, and 32-bit types are supported for byte-swapping.
-             * See UNPACK_SWAP_BYTES & table 8.4 in the OpenGL 4.4 spec.
-             */
-            return KTX_INVALID_VALUE;
-        }
-        This->glTypeSize = typeSize;
-    }
-    
-    /* Check texture dimensions. KTX files can store 8 types of textures:
-     * 1D, 2D, 3D, cube, and array variants of these.
-     */
-    if (createInfo->numDimensions < 1 || createInfo->numDimensions > 3)
-        return KTX_INVALID_VALUE;
-
-    if (createInfo->baseWidth == 0 || createInfo->baseHeight == 0
-        || createInfo->baseDepth == 0)
-        return KTX_INVALID_VALUE;
-
-    super->baseWidth = createInfo->baseWidth;
-    switch (createInfo->numDimensions) {
-      case 1:
-        if (createInfo->baseHeight > 1 || createInfo->baseDepth > 1)
-            return KTX_INVALID_OPERATION;
-        break;
-            
-      case 2:
-        if (createInfo->baseDepth > 1)
-            return KTX_INVALID_OPERATION;
-        super->baseHeight = createInfo->baseHeight;
-        break;
-            
-      case 3:
-        /* 3D array textures and 3D cubemaps are not supported by either
-         * OpenGL or Vulkan.
-         */
-        if (createInfo->isArray || createInfo->numFaces != 1
-            || createInfo->numLayers != 1)
-            return KTX_INVALID_OPERATION;
-        super->baseDepth = createInfo->baseDepth;
-        super->baseHeight = createInfo->baseHeight;
-        break;
-    }
-    super->numDimensions = createInfo->numDimensions;
-
-    if (createInfo->numLayers == 0)
-        return KTX_INVALID_VALUE;
-    super->numLayers = createInfo->numLayers;
-
-    if (createInfo->numFaces == 6) {
-        if (super->numDimensions != 2) {
-            /* cube map needs 2D faces */
-            return KTX_INVALID_OPERATION;
-        }
-        if (createInfo->baseWidth != createInfo->baseHeight) {
-            /* cube maps require square images */
-            return KTX_INVALID_OPERATION;
-        }
-        super->isCubemap = KTX_TRUE;
-    } else if (createInfo->numFaces != 1) {
-        /* numFaces must be either 1 or 6 */
-        return KTX_INVALID_VALUE;
-    }
-    super->numFaces = createInfo->numFaces;
-
-
-    /* Check number of mipmap levels */
-    if (createInfo->numLevels == 0)
-        return KTX_INVALID_VALUE;
-    super->numLevels = createInfo->numLevels;
-    super->generateMipmaps = createInfo->generateMipmaps;
- 
-    if (createInfo->numLevels > 1) {
-        GLuint max_dim = MAX(MAX(createInfo->baseWidth, createInfo->baseHeight), createInfo->baseDepth);
-        if (max_dim < ((GLuint)1 << (super->numLevels - 1)))
-        {
-            /* Can't have more mip levels than 1 + log2(max(width, height, depth)) */
-            return KTX_INVALID_OPERATION;
-        }
-    }
-    
-    super->numLayers = createInfo->numLayers;
-    super->isArray = createInfo->isArray;
-    
-    ktxHashList_Construct(&super->kvDataHead);
-    if (storageAllocation == KTX_TEXTURE_CREATE_ALLOC_STORAGE) {
-        super->dataSize = ktxTexture_calcDataSize(super);
-        super->pData = malloc(super->dataSize);
-        if (super->pData == NULL)
-            return KTX_OUT_OF_MEMORY;
-    }
-    return KTX_SUCCESS;
-}
-
-/**
- * @memberof ktxTexture @private
- * @brief Construct a ktxTexture from a ktxStream reading from a KTX source.
- *
- * The caller constructs the stream inside the ktxTextureInt before calling
- * this.
- *
- * The create flag KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT should not be set,
- * if the ktxTexture is ultimately to be uploaded to OpenGL or Vulkan. This
- * will minimize memory usage by allowing, for example, loading the images
- * directly from the source into a Vulkan staging buffer.
- *
- * The create flag KTX_TEXTURE_CREATE_RAW_KVDATA_BIT should not be used. It is
- * provided solely to enable implementation of the @e libktx v1 API on top of
- * ktxTexture.
- *
- * @param[in] This pointer to a ktxTextureInt-sized block of memory to
- *                 initialize.
- * @param[in] createFlags bitmask requesting specific actions during creation.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_FILE_DATA_ERROR
- *                              Source data is inconsistent with the KTX
- *                              specification.
- * @exception KTX_FILE_READ_ERROR
- *                              An error occurred while reading the source.
- * @exception KTX_FILE_UNEXPECTED_EOF
- *                              Not enough data in the source.
- * @exception KTX_OUT_OF_MEMORY Not enough memory to load either the images or
- *                              the key-value data.
- * @exception KTX_UNKNOWN_FILE_FORMAT
- *                              The source is not in KTX format.
- * @exception KTX_UNSUPPORTED_TEXTURE_TYPE
- *                              The source describes a texture type not
- *                              supported by OpenGL or Vulkan, e.g, a 3D array.
- */
-static KTX_error_code
-ktxTextureInt_constructFromStream(ktxTextureInt* This,
-                                  ktxTextureCreateFlags createFlags)
-{
-    ktxTexture* super = (ktxTexture*)This;
-    KTX_error_code result;
-    KTX_header header;
-    KTX_supplemental_info suppInfo;
-    ktxStream* stream;
-    ktx_off_t pos;
-    ktx_size_t size;
-    
-    assert(This != NULL);
-    assert(This->stream.data.mem != NULL);
-    assert(This->stream.type == eStreamTypeFile
-           || This->stream.type == eStreamTypeMemory);
-    stream = &This->stream;
-  
-    // Read header.
-    result = stream->read(stream, &header, KTX_HEADER_SIZE);
-    if (result != KTX_SUCCESS)
-        return result;
-    
-    result = _ktxCheckHeader(&header, &suppInfo);
-    if (result != KTX_SUCCESS)
-        return result;
-    
-    /*
-     * Initialize from header info.
-     */
-    super->glFormat = header.glFormat;
-    super->glInternalformat = header.glInternalformat;
-    super->glType = header.glType;
-    glGetFormatSize(super->glInternalformat, &This->formatInfo);
-    super->glBaseInternalformat = header.glBaseInternalformat;
-    super->numDimensions = suppInfo.textureDimension;
-    super->baseWidth = header.pixelWidth;
-    assert(suppInfo.textureDimension > 0 && suppInfo.textureDimension < 4);
-    switch (suppInfo.textureDimension) {
-      case 1:
-        super->baseHeight = super->baseDepth = 1;
-        break;
-      case 2:
-        super->baseHeight = header.pixelHeight;
-        super->baseDepth = 1;
-        break;
-      case 3:
-        super->baseHeight = header.pixelHeight;
-        super->baseDepth = header.pixelDepth;
-        break;
-    }
-    if (header.numberOfArrayElements > 0) {
-        super->numLayers = header.numberOfArrayElements;
-        super->isArray = KTX_TRUE;
-    } else {
-        super->numLayers = 1;
-        super->isArray = KTX_FALSE;
-    }
-    super->numFaces = header.numberOfFaces;
-    if (header.numberOfFaces == 6)
-        super->isCubemap = KTX_TRUE;
-    else
-        super->isCubemap = KTX_FALSE;
-    super->numLevels = header.numberOfMipmapLevels;
-    super->isCompressed = suppInfo.compressed;
-    super->generateMipmaps = suppInfo.generateMipmaps;
-    if (header.endianness == KTX_ENDIAN_REF_REV)
-        This->needSwap = KTX_TRUE;
-    This->glTypeSize = header.glTypeSize;
-
-    /*
-     * Make an empty hash list.
-     */
-    ktxHashList_Construct(&super->kvDataHead);
-    /*
-     * Load KVData.
-     */
-    if (header.bytesOfKeyValueData > 0) {
-        if (!(createFlags & KTX_TEXTURE_CREATE_SKIP_KVDATA_BIT)) {
-            ktx_uint32_t kvdLen = header.bytesOfKeyValueData;
-            ktx_uint8_t* pKvd;
-
-            pKvd = malloc(kvdLen);
-            if (pKvd == NULL)
-                return KTX_OUT_OF_MEMORY;
-            
-            result = stream->read(stream, pKvd, kvdLen);
-            if (result != KTX_SUCCESS)
-                return result;
-
-            if (This->needSwap) {
-                /* Swap the counts inside the key & value data. */
-                ktx_uint8_t* src = pKvd;
-                ktx_uint8_t* end = pKvd + kvdLen;
-                while (src < end) {
-                    ktx_uint32_t keyAndValueByteSize = *((ktx_uint32_t*)src);
-                    _ktxSwapEndian32(&keyAndValueByteSize, 1);
-                    src += _KTX_PAD4(keyAndValueByteSize);
-                }
-            }
-            
-            if (!(createFlags & KTX_TEXTURE_CREATE_RAW_KVDATA_BIT)) {
-                result = ktxHashList_Deserialize(&super->kvDataHead,
-                                                 kvdLen, pKvd);
-                if (result != KTX_SUCCESS) {
-                    free(pKvd);
-                    return result;
-                }
-            } else {
-                super->kvDataLen = kvdLen;
-                super->kvData = pKvd;
-            }
-        } else {
-            stream->skip(stream, header.bytesOfKeyValueData);
-        }
-    }
-    
-    /*
-     * Get the size of the image data.
-     */
-    result = stream->getsize(stream, &size);
-    if (result == KTX_SUCCESS) {
-        result = stream->getpos(stream, &pos);
-        if (result == KTX_SUCCESS)
-            super->dataSize = size - pos
-                                 /* Remove space for faceLodSize fields */
-                                 - super->numLevels * sizeof(ktx_uint32_t);
-    }
-
-    /*
-     * Load the images, if requested.
-     */
-    if (result == KTX_SUCCESS
-        && (createFlags & KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT)) {
-        result = ktxTexture_LoadImageData((ktxTexture*)super, NULL, 0);
-    }
-    return result;
-}
-
-/**
- * @memberof ktxTexture @private
- * @brief Construct a ktxTexture from a stdio stream reading from a KTX source.
- *
- * See ktxTextureInt_constructFromStream for details.
- *
- * @note Do not close the stdio stream until you are finished with the texture
- *       object.
- *
- * @param[in] This pointer to a ktxTextureInt-sized block of memory to
- *                 initialize.
- * @param[in] stdioStream a stdio FILE pointer opened on the source.
- * @param[in] createFlags bitmask requesting specific actions during creation.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE Either @p stdiostream or @p This is null.
- *
- * For other exceptions, see ktxTexture_constructFromStream().
- */
-static KTX_error_code
-ktxTextureInt_constructFromStdioStream(ktxTextureInt* This, FILE* stdioStream,
-                                       ktxTextureCreateFlags createFlags)
-{
-    KTX_error_code result;
-
-    if (stdioStream == NULL || This == NULL)
-        return KTX_INVALID_VALUE;
-    
-    memset(This, 0, sizeof(*This));
-    
-    result = ktxFileStream_construct(&This->stream, stdioStream, KTX_FALSE);
-    if (result == KTX_SUCCESS)
-        result = ktxTextureInt_constructFromStream(This, createFlags);
-    return result;
-}
-
-/**
- * @memberof ktxTexture @private
- * @brief Construct a ktxTexture from a named KTX file.
- *
- * See ktxTextureInt_constructFromStream for details.
- *
- * @param[in] This pointer to a ktxTextureInt-sized block of memory to
- *                 initialize.
- * @param[in] filename    pointer to a char array containing the file name.
- * @param[in] createFlags bitmask requesting specific actions during creation.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_FILE_OPEN_FAILED The file could not be opened.
- * @exception KTX_INVALID_VALUE @p filename is @c NULL.
- *
- * For other exceptions, see ktxTexture_constructFromStream().
- */
-static KTX_error_code
-ktxTextureInt_constructFromNamedFile(ktxTextureInt* This,
-                                     const char* const filename,
-                                     ktxTextureCreateFlags createFlags)
-{
-    KTX_error_code result;
-    FILE* file;
-    
-    if (This == NULL || filename == NULL)
-        return KTX_INVALID_VALUE;
-    
-    memset(This, 0, sizeof(*This));
-
-    file = fopen(filename, "rb");
-    if (!file)
-       return KTX_FILE_OPEN_FAILED;
-    
-    result = ktxFileStream_construct(&This->stream, file, KTX_TRUE);
-    if (result == KTX_SUCCESS)
-        result = ktxTextureInt_constructFromStream(This, createFlags);
-    
-    return result;
-}
-
-/**
- * @memberof ktxTexture @private
- * @brief Construct a ktxTexture from KTX-formatted data in memory.
- *
- * See ktxTextureInt_constructFromStream for details.
- *
- * @param[in] This  pointer to a ktxTextureInt-sized block of memory to
- *                  initialize.
- * @param[in] bytes pointer to the memory containing the serialized KTX data.
- * @param[in] size  length of the KTX data in bytes.
- * @param[in] createFlags bitmask requesting specific actions during creation.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE Either @p bytes is NULL or @p size is 0.
- *
- * For other exceptions, see ktxTexture_constructFromStream().
- */
-static KTX_error_code
-ktxTextureInt_constructFromMemory(ktxTextureInt* This,
-                                  const ktx_uint8_t* bytes, ktx_size_t size,
-                                  ktxTextureCreateFlags createFlags)
-{
-    KTX_error_code result;
-    
-    if (bytes == NULL || size == 0)
-        return KTX_INVALID_VALUE;
-    
-    memset(This, 0, sizeof(*This));
-    
-    result = ktxMemStream_construct_ro(&This->stream, bytes, size);
-    if (result == KTX_SUCCESS)
-        result = ktxTextureInt_constructFromStream(This, createFlags);
-    
-    return result;
-}
-
-/**
- * @memberof ktxTexture @private
- * @~English
- * @brief Free the memory associated with the texture contents
- *
- * @param[in] This pointer to the ktxTextureInt whose texture contents are
- *                 to be freed.
- */
-void
-ktxTextureInt_destruct(ktxTextureInt* This)
-{
-    ktxTexture* super = (ktxTexture*)This;
-    if (This->stream.data.file != NULL)
-        This->stream.destruct(&This->stream);
-    if (super->kvDataHead != NULL)
-        ktxHashList_Destruct(&super->kvDataHead);
-    if (super->kvData != NULL)
-        free(super->kvData);
-    if (super->pData != NULL)
-        free(super->pData);
-}
-
-/**
- * @memberof ktxTexture
- * @ingroup writer
- * @brief Create a new empty ktxTexture.
- *
- * The address of the newly created ktxTexture is written to the location
- * pointed at by @p newTex.
- *
- * @param[in] createInfo pointer to a ktxTextureCreateInfo struct with
- *                       information describing the texture.
- * @param[in] storageAllocation
- *                       enum indicating whether or not to allocate storage
- *                       for the texture images.
- * @param[in,out] newTex pointer to a location in which store the address of
- *                       the newly created texture.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @c glInternalFormat in @p createInfo is not a
- *                              valid OpenGL internal format value.
- * @exception KTX_INVALID_VALUE @c numDimensions in @p createInfo is not 1, 2
- *                              or 3.
- * @exception KTX_INVALID_VALUE One of <tt>base{Width,Height,Depth}</tt> in
- *                              @p createInfo is 0.
- * @exception KTX_INVALID_VALUE @c numFaces in @p createInfo is not 1 or 6.
- * @exception KTX_INVALID_VALUE @c numLevels in @p createInfo is 0.
- * @exception KTX_INVALID_OPERATION
- *                              The <tt>base{Width,Height,Depth}</tt> specified
- *                              in @p createInfo are inconsistent with
- *                              @c numDimensions.
- * @exception KTX_INVALID_OPERATION
- *                              @p createInfo is requesting a 3D array or
- *                              3D cubemap texture.
- * @exception KTX_INVALID_OPERATION
- *                              @p createInfo is requesting a cubemap with
- *                              non-square or non-2D images.
- * @exception KTX_INVALID_OPERATION
- *                              @p createInfo is requesting more mip levels
- *                              than needed for the specified
- *                              <tt>base{Width,Height,Depth}</tt>.
- * @exception KTX_OUT_OF_MEMORY Not enough memory for the texture's images.
- */
-KTX_error_code
-ktxTexture_Create(ktxTextureCreateInfo* createInfo,
-                  ktxTextureCreateStorageEnum storageAllocation,
-                  ktxTexture** newTex)
-{
-    KTX_error_code result;
-    
-    if (newTex == NULL)
-        return KTX_INVALID_VALUE;
-    
-    ktxTextureInt* tex = (ktxTextureInt*)malloc(sizeof(ktxTextureInt));
-    if (tex == NULL)
-        return KTX_OUT_OF_MEMORY;
-    
-    result = ktxTextureInt_construct(tex, createInfo, storageAllocation);
-    if (result == KTX_SUCCESS)
-        *newTex = (ktxTexture*)tex;
-    else {
-        free(tex);
-        *newTex = NULL;
-    }
-    return result;
-}
-
-/**
- * @defgroup reader Reader
- * @brief Read KTX-formatted data.
- * @{
- */
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Create a ktxTexture from a stdio stream reading from a KTX source.
- *
- * The address of a newly created ktxTexture reflecting the contents of the
- * stdio stream is written to the location pointed at by @p newTex.
- *
- * The create flag KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT should not be set,
- * if the ktxTexture is ultimately to be uploaded to OpenGL or Vulkan. This
- * will minimize memory usage by allowing, for example, loading the images
- * directly from the source into a Vulkan staging buffer.
- *
- * The create flag KTX_TEXTURE_CREATE_RAW_KVDATA_BIT should not be used. It is
- * provided solely to enable implementation of the @e libktx v1 API on top of
- * ktxTexture.
- *
- * @param[in] stdioStream stdio FILE pointer created from the desired file.
- * @param[in] createFlags bitmask requesting specific actions during creation.
- * @param[in,out] newTex  pointer to a location in which store the address of
- *                        the newly created texture.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p newTex is @c NULL.
- * @exception KTX_FILE_DATA_ERROR
- *                              Source data is inconsistent with the KTX
- *                              specification.
- * @exception KTX_FILE_READ_ERROR
- *                              An error occurred while reading the source.
- * @exception KTX_FILE_UNEXPECTED_EOF
- *                              Not enough data in the source.
- * @exception KTX_OUT_OF_MEMORY Not enough memory to create the texture object,
- *                              load the images or load the key-value data.
- * @exception KTX_UNKNOWN_FILE_FORMAT
- *                              The source is not in KTX format.
- * @exception KTX_UNSUPPORTED_TEXTURE_TYPE
- *                              The source describes a texture type not
- *                              supported by OpenGL or Vulkan, e.g, a 3D array.
- */
-KTX_error_code
-ktxTexture_CreateFromStdioStream(FILE* stdioStream,
-                                 ktxTextureCreateFlags createFlags,
-                                 ktxTexture** newTex)
-{
-    KTX_error_code result;
-    if (newTex == NULL)
-        return KTX_INVALID_VALUE;
-    
-    ktxTextureInt* tex = (ktxTextureInt*)malloc(sizeof(ktxTextureInt));
-    if (tex == NULL)
-        return KTX_OUT_OF_MEMORY;
-    
-    result = ktxTextureInt_constructFromStdioStream(tex, stdioStream,
-                                                    createFlags);
-    if (result == KTX_SUCCESS)
-        *newTex = (ktxTexture*)tex;
-    else {
-        free(tex);
-        *newTex = NULL;
-    }
-    return result;
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Create a ktxTexture from a named KTX file.
- *
- * The address of a newly created ktxTexture reflecting the contents of the
- * file is written to the location pointed at by @p newTex.
- *
- * The create flag KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT should not be set,
- * if the ktxTexture is ultimately to be uploaded to OpenGL or Vulkan. This
- * will minimize memory usage by allowing, for example, loading the images
- * directly from the source into a Vulkan staging buffer.
- *
- * The create flag KTX_TEXTURE_CREATE_RAW_KVDATA_BIT should not be used. It is
- * provided solely to enable implementation of the @e libktx v1 API on top of
- * ktxTexture.
- *
- * @param[in] filename    pointer to a char array containing the file name.
- * @param[in] createFlags bitmask requesting specific actions during creation.
- * @param[in,out] newTex  pointer to a location in which store the address of
- *                        the newly created texture.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
-
- * @exception KTX_FILE_OPEN_FAILED The file could not be opened.
- * @exception KTX_INVALID_VALUE @p filename is @c NULL.
- *
- * For other exceptions, see ktxTexture_CreateFromStdioStream().
- */
-KTX_error_code
-ktxTexture_CreateFromNamedFile(const char* const filename,
-                               ktxTextureCreateFlags createFlags,
-                               ktxTexture** newTex)
-{
-    KTX_error_code result;
-
-    if (newTex == NULL)
-        return KTX_INVALID_VALUE;
-
-    ktxTextureInt* tex = (ktxTextureInt*)malloc(sizeof(ktxTextureInt));
-    if (tex == NULL)
-        return KTX_OUT_OF_MEMORY;
-    
-    result = ktxTextureInt_constructFromNamedFile(tex, filename, createFlags);
-    if (result == KTX_SUCCESS)
-        *newTex = (ktxTexture*)tex;
-    else {
-        free(tex);
-        *newTex = NULL;
-    }
-    return result;
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Create a ktxTexture from KTX-formatted data in memory.
- *
- * The address of a newly created ktxTexture reflecting the contents of the
- * serialized KTX data is written to the location pointed at by @p newTex.
- *
- * The create flag KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT should not be set,
- * if the ktxTexture is ultimately to be uploaded to OpenGL or Vulkan. This
- * will minimize memory usage by allowing, for example, loading the images
- * directly from the source into a Vulkan staging buffer.
- *
- * The create flag KTX_TEXTURE_CREATE_RAW_KVDATA_BIT should not be used. It is
- * provided solely to enable implementation of the @e libktx v1 API on top of
- * ktxTexture.
- *
- * @param[in] bytes pointer to the memory containing the serialized KTX data.
- * @param[in] size  length of the KTX data in bytes.
- * @param[in] createFlags bitmask requesting specific actions during creation.
- * @param[in,out] newTex  pointer to a location in which store the address of
- *                        the newly created texture.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE Either @p bytes is NULL or @p size is 0.
- *
- * For other exceptions, see ktxTexture_CreateFromStdioStream().
- */
-KTX_error_code
-ktxTexture_CreateFromMemory(const ktx_uint8_t* bytes, ktx_size_t size,
-                            ktxTextureCreateFlags createFlags,
-                            ktxTexture** newTex)
-{
-    KTX_error_code result;
-    if (newTex == NULL)
-        return KTX_INVALID_VALUE;
-    
-    ktxTextureInt* tex = (ktxTextureInt*)malloc(sizeof(ktxTextureInt));
-    if (tex == NULL)
-        return KTX_OUT_OF_MEMORY;
-    
-    result = ktxTextureInt_constructFromMemory(tex, bytes, size,
-                                               createFlags);
-    if (result == KTX_SUCCESS)
-        *newTex = (ktxTexture*)tex;
-    else {
-        free(tex);
-        *newTex = NULL;
-    }
-    return result;
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Destroy a ktxTexture object.
- *
- * This frees the memory associated with the texture contents and the memory
- * of the ktxTexture object. This does @e not delete any OpenGL or Vulkan
- * texture objects created by ktxTexture_GLUpload or ktxTexture_VkUpload.
- *
- * @param[in] This pointer to the ktxTexture object to destroy
- */
-void
-ktxTexture_Destroy(ktxTexture* This)
-{
-    ktxTextureInt_destruct((ktxTextureInt*)This);
-    free(This);
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Return a pointer to the texture image data.
- *
- * @param[in] This pointer to the ktxTexture object of interest.
- */
-ktx_uint8_t*
-ktxTexture_GetData(ktxTexture* This)
-{
-    return This->pData;
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Return the total size of the texture image data in bytes.
- *
- * @param[in] This pointer to the ktxTexture object of interest.
- */
-ktx_size_t
-ktxTexture_GetSize(ktxTexture* This)
-{
-    assert(This != NULL);
-    return This->dataSize;
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Return the size in bytes of an elements of a texture's
- *        images.
- *
- * For uncompressed textures an element is one texel. For compressed
- * textures it is one block.
- *
- * @param[in]     This     pointer to the ktxTexture object of interest.
- */
-ktx_uint32_t
-ktxTexture_GetElementSize(ktxTexture* This)
-{
-    GlFormatSize* formatInfo;
-
-    assert (This != NULL);
-
-    formatInfo = &((ktxTextureInt*)This)->formatInfo;
-    return (formatInfo->blockSizeInBits / 8);
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Calculate & return the size in bytes of an image at the specified
- *        mip level.
- *
- * For arrays, this is the size of layer, for cubemaps, the size of a face
- * and for 3D textures, the size of a depth slice.
- *
- * The size reflects the padding of each row to KTX_GL_UNPACK_ALIGNMENT.
- *
- * @param[in]     This     pointer to the ktxTexture object of interest.
- * @param[in]     level    level of interest. *
- */
-ktx_size_t
-ktxTexture_GetImageSize(ktxTexture* This, ktx_uint32_t level)
-{
-    GlFormatSize* formatInfo;
-    struct blockCount {
-        ktx_uint32_t x, y, z;
-    } blockCount;
-    ktx_uint32_t blockSizeInBytes;
-    ktx_uint32_t rowBytes;
-
-    assert (This != NULL);
-
-    formatInfo = &((ktxTextureInt*)This)->formatInfo;
-    blockCount.x = MAX(1, (This->baseWidth / formatInfo->blockWidth)  >> level);
-    blockCount.y = MAX(1, (This->baseHeight / formatInfo->blockHeight)  >> level);
-    blockSizeInBytes = formatInfo->blockSizeInBits / 8;
-
-    if (formatInfo->flags & GL_FORMAT_SIZE_COMPRESSED_BIT) {
-        assert(This->isCompressed);
-        return blockCount.x * blockCount.y * blockSizeInBytes;
-    } else {
-        assert(formatInfo->blockWidth == formatInfo->blockHeight == formatInfo->blockDepth == 1);
-        rowBytes = blockCount.x * blockSizeInBytes;
-        (void)padRow(&rowBytes);
-        return rowBytes * blockCount.y;
-    }
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Load all the image data from the ktxTexture's source.
- *
- * The data is loaded into the provided buffer or to an internally allocated
- * buffer, if @p pBuffer is @c NULL.
- *
- * @param[in] This pointer to the ktxTexture object of interest.
- * @param[in] pBuffer pointer to the buffer in which to load the image data.
- * @param[in] bufSize size of the buffer pointed at by @p pBuffer.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p This is NULL.
- * @exception KTX_INVALID_VALUE @p bufSize is less than the the image data size.
- * @exception KTX_INVALID_OPERATION
- *                              The data has already been loaded or the
- *                              ktxTexture was not created from a KTX source.
- * @exception KTX_OUT_OF_MEMORY Insufficient memory for the image data.
- */
-KTX_error_code
-ktxTexture_LoadImageData(ktxTexture* This,
-                         ktx_uint8_t* pBuffer, ktx_size_t bufSize)
-{
-    ktxTextureInt*  subthis = (ktxTextureInt*)This;
-    ktx_uint32_t    miplevel;
-    ktx_uint8_t*    pDest;
-    KTX_error_code  result = KTX_SUCCESS;
-
-    if (This == NULL)
-        return KTX_INVALID_VALUE;
-    
-    if (subthis->stream.data.file == NULL)
-        // This Texture not created from a stream or images already loaded;
-        return KTX_INVALID_OPERATION;
-
-    if (pBuffer == NULL) {
-        This->pData = malloc(This->dataSize);
-        if (This->pData == NULL)
-            return KTX_OUT_OF_MEMORY;
-        pDest = This->pData;
-    } else if (bufSize < This->dataSize) {
-        return KTX_INVALID_VALUE;
-    } else {
-        pDest = pBuffer;
-    }
-
-    // Need to loop through for correct byte swapping
-    for (miplevel = 0; miplevel < This->numLevels; ++miplevel)
-    {
-        ktx_uint32_t faceLodSize;
-        ktx_uint32_t faceLodSizePadded;
-        ktx_uint32_t face;
-        ktx_uint32_t innerIterations;
-
-        result = subthis->stream.read(&subthis->stream, &faceLodSize,
-                                      sizeof(ktx_uint32_t));
-        if (result != KTX_SUCCESS) {
-            goto cleanup;
-        }
-        if (subthis->needSwap) {
-            _ktxSwapEndian32(&faceLodSize, 1);
-        }
-#if (KTX_GL_UNPACK_ALIGNMENT != 4)
-        faceLodSizePadded = _KTX_PAD4(faceLodSize);
-#else
-        faceLodSizePadded = faceLodSize;
-#endif
-        
-        if (This->isCubemap && !This->isArray)
-            innerIterations = This->numFaces;
-        else
-            innerIterations = 1;
-        for (face = 0; face < innerIterations; ++face)
-        {
-            result = subthis->stream.read(&subthis->stream, pDest,
-                                          faceLodSizePadded);
-            if (result != KTX_SUCCESS) {
-                goto cleanup;
-            }
-            
-            /* Perform endianness conversion on texture data */
-            if (subthis->needSwap) {
-                if (subthis->glTypeSize == 2)
-                    _ktxSwapEndian16((ktx_uint16_t*)pDest, faceLodSize / 2);
-                else if (subthis->glTypeSize == 4)
-                    _ktxSwapEndian32((ktx_uint32_t*)pDest, faceLodSize / 4);
-            }
-            
-            pDest += faceLodSizePadded;
-        }
-    }
-
-cleanup:
-    // No further need for This->
-    subthis->stream.destruct(&subthis->stream);
-    return result;
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Iterate over the images in a ktxTexture object.
- *
- * Blocks of image data are passed to an application-supplied callback
- * function. This is not a strict per-image iteration. Rather it reflects how
- * OpenGL needs the images. For most textures the block of data includes all
- * images of a mip level which implies all layers of an array. However, for
- * non-array cube map textures the block is a single face of the mip level,
- * i.e the callback is called once for each face.
- *
- * This function works even if @p This->pData == 0 so it can be used to
- * obtain offsets and sizes for each level by callers who have loaded the data
- * externally.
- *
- * @param[in]     This      pointer to the ktxTexture object of interest.
- * @param[in,out] iterCb    the address of a callback function which is called
- *                          with the data for each image block.
- * @param[in,out] userdata  the address of application-specific data which is
- *                          passed to the callback along with the image data.
- *
- * @return  KTX_SUCCESS on success, other KTX_* enum values on error. The
- *          following are returned directly by this function. @p iterCb may
- *          return these for other causes or may return additional errors.
- *
- * @exception KTX_FILE_DATA_ERROR   Mip level sizes are increasing not
- *                                  decreasing
- * @exception KTX_INVALID_VALUE     @p This is @c NULL or @p iterCb is @c NULL.
- *
- */
-KTX_error_code
-ktxTexture_IterateLevelFaces(ktxTexture* This, PFNKTXITERCB iterCb,
-                             void* userdata)
-{
-    ktx_uint32_t    miplevel;
-    KTX_error_code  result = KTX_SUCCESS;
-    
-    if (This == NULL)
-        return KTX_INVALID_VALUE;
-    
-    if (iterCb == NULL)
-        return KTX_INVALID_VALUE;
-    
-    for (miplevel = 0; miplevel < This->numLevels; ++miplevel)
-    {
-        ktx_uint32_t faceLodSize;
-        ktx_uint32_t face;
-        ktx_uint32_t innerIterations;
-        GLsizei      width, height, depth;
-        
-        /* Array textures have the same number of layers at each mip level. */
-        width = MAX(1, This->baseWidth  >> miplevel);
-        height = MAX(1, This->baseHeight >> miplevel);
-        depth = MAX(1, This->baseDepth  >> miplevel);
-
-        faceLodSize = (ktx_uint32_t)ktxTexture_faceLodSize(This, miplevel);
-
-        /* All array layers are passed in a group because that is how
-         * GL & Vulkan need them. Hence no
-         *    for (layer = 0; layer < This->numLayers)
-         */
-        if (This->isCubemap && !This->isArray)
-            innerIterations = This->numFaces;
-        else
-            innerIterations = 1;
-        for (face = 0; face < innerIterations; ++face)
-        {
-            /* And all z_slices are also passed as a group hence no
-             *    for (slice = 0; slice < This->depth)
-             */
-            ktx_size_t offset;
-
-            ktxTexture_GetImageOffset(This, miplevel, 0, face, &offset);
-            result = iterCb(miplevel, face,
-                             width, height, depth,
-                             faceLodSize, This->pData + offset, userdata);
-            
-            if (result != KTX_SUCCESS)
-                break;
-        }
-    }
-    
-    return result;
-}
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Iterate over the images in a ktxTexture object while loading the
- *        image data.
- *
- * This operates similarly to ktxTexture_IterateLevelFaces() except that it
- * loads the images from the ktxTexture's source to a temporary buffer
- * while iterating. The callback function must copy the image data if it
- * wishes to preserve it as the temporary buffer is reused for each level and
- * is freed when this function exits.
- *
- * This function is helpful for reducing memory usage when uploading the data
- * to a graphics API.
- *
- * @param[in]     This     pointer to the ktxTexture object of interest.
- * @param[in,out] iterCb   the address of a callback function which is called
- *                         with the data for each image.
- * @param[in,out] userdata the address of application-specific data which is
- *                         passed to the callback along with the image data.
- *
- * @return  KTX_SUCCESS on success, other KTX_* enum values on error. The
- *          following are returned directly by this function. @p iterCb may
- *          return these for other causes or may return additional errors.
- *
- * @exception KTX_FILE_DATA_ERROR   mip level sizes are increasing not
- *                                  decreasing
- * @exception KTX_INVALID_OPERATION the ktxTexture was not created from a
- *                                  stream, i.e there is no data to load, or
- *                                  this ktxTexture's images have already
- *                                  been loaded.
- * @exception KTX_INVALID_VALUE     @p This is @c NULL or @p iterCb is @c NULL.
- * @exception KTX_OUT_OF_MEMORY     not enough memory to allocate a block to
- *                                  hold the base level image.
- */
-KTX_error_code
-ktxTexture_IterateLoadLevelFaces(ktxTexture* This, PFNKTXITERCB iterCb,
-                                 void* userdata)
-{
-    ktxTextureInt*  subthis = (ktxTextureInt*)This;
-    ktx_uint32_t    dataSize = 0;
-    ktx_uint32_t    miplevel;
-    KTX_error_code  result = KTX_SUCCESS;
-    void*           data = NULL;
-    
-    if (This == NULL)
-        return KTX_INVALID_VALUE;
-    
-    if (iterCb == NULL)
-        return KTX_INVALID_VALUE;
-    
-    if (subthis->stream.data.file == NULL)
-        // This Texture not created from a stream or images are already loaded.
-        return KTX_INVALID_OPERATION;
-    
-    for (miplevel = 0; miplevel < This->numLevels; ++miplevel)
-    {
-        ktx_uint32_t faceLodSize;
-        ktx_uint32_t faceLodSizePadded;
-        ktx_uint32_t face;
-        ktx_uint32_t innerIterations;
-        GLsizei      width, height, depth;
-        
-        /* Array textures have the same number of layers at each mip level. */
-        width = MAX(1, This->baseWidth  >> miplevel);
-        height = MAX(1, This->baseHeight >> miplevel);
-        depth = MAX(1, This->baseDepth  >> miplevel);
-        
-        result = subthis->stream.read(&subthis->stream, &faceLodSize,
-                                      sizeof(ktx_uint32_t));
-        if (result != KTX_SUCCESS) {
-            goto cleanup;
-        }
-        if (subthis->needSwap) {
-            _ktxSwapEndian32(&faceLodSize, 1);
-        }
-#if (KTX_GL_UNPACK_ALIGNMENT != 4)
-        faceLodSizePadded = _KTX_PAD4(faceLodSize);
-#else
-        faceLodSizePadded = faceLodSize;
-#endif
-        if (!data) {
-            /* allocate memory sufficient for the base miplevel */
-            data = malloc(faceLodSizePadded);
-            if (!data) {
-                result = KTX_OUT_OF_MEMORY;
-                goto cleanup;
-            }
-            dataSize = faceLodSizePadded;
-        }
-        else if (dataSize < faceLodSizePadded) {
-            /* subsequent miplevels cannot be larger than the base miplevel */
-            result = KTX_FILE_DATA_ERROR;
-            goto cleanup;
-        }
-        
-        /* All array layers are passed in a group because that is how
-         * GL & Vulkan need them. Hence no
-         *    for (layer = 0; layer < This->numLayers)
-         */
-        if (This->isCubemap && !This->isArray)
-            innerIterations = This->numFaces;
-        else
-            innerIterations = 1;
-        for (face = 0; face < innerIterations; ++face)
-        {
-            /* And all z_slices are also passed as a group hence no
-             *    for (z_slice = 0; z_slice < This->depth)
-             */
-            result = subthis->stream.read(&subthis->stream, data,
-                                          faceLodSizePadded);
-            if (result != KTX_SUCCESS) {
-                goto cleanup;
-            }
-            
-            /* Perform endianness conversion on texture data */
-            if (subthis->needSwap) {
-                if (subthis->glTypeSize == 2)
-                    _ktxSwapEndian16((ktx_uint16_t*)data, faceLodSize / 2);
-                else if (subthis->glTypeSize == 4)
-                    _ktxSwapEndian32((ktx_uint32_t*)data, faceLodSize / 4);
-            }
-            
-            result = iterCb(miplevel, face,
-                             width, height, depth,
-                             faceLodSize, data, userdata);
-            
-            if (result != KTX_SUCCESS)
-                goto cleanup;
-        }
-    }
-    
-cleanup:
-    free(data);
-    // No further need for this.
-    subthis->stream.destruct(&subthis->stream);
-
-    return result;
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Iterate over the mip levels in a ktxTexture object.
- *
- * This is almost identical to ktxTexture_IterateLevelFaces(). The difference is
- * that the blocks of image data for non-array cube maps include all faces of
- * a mip level.
- *
- * This function works even if @p This->pData == 0 so it can be used to
- * obtain offsets and sizes for each level by callers who have loaded the data
- * externally.
- *
- * @param[in]     This     handle of the ktxTexture opened on the data.
- * @param[in,out] iterCb   the address of a callback function which is called
- *                         with the data for each image block.
- * @param[in,out] userdata the address of application-specific data which is
- *                         passed to the callback along with the image data.
- *
- * @return  KTX_SUCCESS on success, other KTX_* enum values on error. The
- *          following are returned directly by this function. @p iterCb may
- *          return these for other causes or may return additional errors.
- *
- * @exception KTX_FILE_DATA_ERROR   Mip level sizes are increasing not
- *                                  decreasing
- * @exception KTX_INVALID_VALUE     @p This is @c NULL or @p iterCb is @c NULL.
- *
- */
-KTX_error_code
-ktxTexture_IterateLevels(ktxTexture* This, PFNKTXITERCB iterCb, void* userdata)
-{
-    ktx_uint32_t    miplevel;
-    KTX_error_code  result = KTX_SUCCESS;
-    
-    if (This == NULL)
-        return KTX_INVALID_VALUE;
-    
-    if (iterCb == NULL)
-        return KTX_INVALID_VALUE;
-    
-    for (miplevel = 0; miplevel < This->numLevels; ++miplevel)
-    {
-        GLsizei width, height, depth;
-        ktx_uint32_t levelSize;
-        ktx_size_t offset;
-        
-        /* Array textures have the same number of layers at each mip level. */
-        width = MAX(1, This->baseWidth  >> miplevel);
-        height = MAX(1, This->baseHeight >> miplevel);
-        depth = MAX(1, This->baseDepth  >> miplevel);
-
-        levelSize = (ktx_uint32_t)ktxTexture_levelSize(This, miplevel);
-
-        /* All array layers are passed in a group because that is how
-         * GL & Vulkan need them. Hence no
-         *    for (layer = 0; layer < This->numLayers)
-         */
-        ktxTexture_GetImageOffset(This, miplevel, 0, 0, &offset);
-        result = iterCb(miplevel, 0, width, height, depth,
-                         levelSize, This->pData + offset, userdata);
-        if (result != KTX_SUCCESS)
-            break;
-    }
-    
-    return result;
-}
-
-/**
- * @internal
- * @brief  Calculate and apply the padding needed to comply with
- *         KTX_GL_UNPACK_ALIGNMENT.
- *
- * For uncompressed textures, KTX format specifies KTX_GL_UNPACK_ALIGNMENT = 4.
- *
- * @param[in,out] rowBytes    pointer to variable containing the packed no. of
- *                            bytes in a row. The no. of bytes after padding
- *                            is written into this location.
- * @return the no. of bytes of padding.
- */
-static ktx_uint32_t
-padRow(ktx_uint32_t* rowBytes)
-{
-    ktx_uint32_t rowPadding;
-
-    assert (rowBytes != NULL);
-
-    rowPadding = _KTX_PAD_UNPACK_ALIGN_LEN(*rowBytes);
-    *rowBytes += rowPadding;
-    return rowPadding;
-}
-
-/**
- * @memberof ktxTexture @private
- * @~English
- * @brief Calculate the size of an array layer at the specified mip level.
- *
- * The size of a layer is the size of an image * either the number of faces
- * or the number of depth slices. This is the size of a layer as needed to
- * find the offset within the array of images of a level and layer so the size
- * reflects any @c cubePadding.
- *
- * @param[in]  This     pointer to the ktxTexture object of interest.
- * @param[in] level     level whose layer size to return.
- *
- * @return the layer size in bytes.
- */
-static inline ktx_size_t
-ktxTexture_layerSize(ktxTexture* This, ktx_uint32_t level)
-{
-    /*
-     * As there are no 3D cubemaps, the image's z block count will always be
-     * 1 for cubemaps and numFaces will always be 1 for 3D textures so the
-     * multiply is safe. 3D cubemaps, if they existed, would require
-     * imageSize * (blockCount.z + This->numFaces);
-     */
-    GlFormatSize* formatInfo;
-    ktx_uint32_t blockCountZ;
-    ktx_size_t imageSize, layerSize;
-
-    assert (This != NULL);
-    
-    formatInfo = &((ktxTextureInt*)This)->formatInfo;
-    blockCountZ = MAX(1, (This->baseDepth / formatInfo->blockDepth)  >> level);
-    imageSize = ktxTexture_GetImageSize(This, level);
-    layerSize = imageSize * blockCountZ;
-#if (KTX_GL_UNPACK_ALIGNMENT != 4)
-    if (This->isCubemap && !This->isArray) {
-        /* cubePadding. NOTE: this adds padding after the last face too. */
-        _KTX_PAD4(layerSize);
-    }
-#endif
-    return layerSize * This->numFaces;
-}
-
-/**
- * @memberof ktxTexture @private
- * @~English
- * @brief Calculate the size of the specified mip level.
- *
- * The size of a level is the size of a layer * the number of layers.
- *
- * @param[in]  This     pointer to the ktxTexture object of interest.
- * @param[in] level     level whose layer size to return.
- *
- * @return the level size in bytes.
- */
-ktx_size_t
-ktxTexture_levelSize(ktxTexture* This, ktx_uint32_t level)
-{
-    assert (This != NULL);
-    return ktxTexture_layerSize(This, level) * This->numLayers;
-}
-
-/**
- * @memberof ktxTexture @private
- * @~English
- * @brief Calculate the faceLodSize of the specified mip level.
- *
- * The faceLodSize of a level for most textures is the size of a level. For
- * non-array cube map textures is the size of a face. This is the size that
- * must be provided to OpenGL when uploading textures. Faces get uploaded 1
- * at a time while all layers of an array or all slices of a 3D texture are
- * uploaded together.
- *
- * @param[in]  This     pointer to the ktxTexture object of interest.
- * @param[in] level     level whose layer size to return.
- *
- * @return the faceLodSize size in bytes.
- */
-ktx_size_t
-ktxTexture_faceLodSize(ktxTexture* This, ktx_uint32_t level)
-{
-    /*
-     * For non-array cubemaps this is the size of a face. For everything
-     * else it is the size of the level.
-     */
-    if (This->isCubemap && !This->isArray)
-        return ktxTexture_GetImageSize(This, level);
-    else
-        return ktxTexture_levelSize(This, level);
-}
-
-/**
- * @memberof ktxTexture @private
- * @~English
- * @brief Calculate the size of the image data for the specified number
- *        of levels.
- *
- * The data size is the sum of the sizes of each level up to the number
- * specified and includes any @c mipPadding.
- *
- * @param[in] This     pointer to the ktxTexture object of interest.
- * @param[in] levels   number of levels whose data size to return.
- *
- * @return the data size in bytes.
- */
-static inline ktx_size_t
-ktxTexture_dataSize(ktxTexture* This, ktx_uint32_t levels)
-{
-    ktx_uint32_t i;
-    ktx_size_t dataSize = 0;
-
-    assert (This != NULL);
-    for (i = 0; i < levels; i++) {
-        ktx_size_t levelSize = ktxTexture_levelSize(This, i);
-#if (KTX_GL_UNPACK_ALIGNMENT != 4)
-        /* mipPadding. NOTE: this adds padding after the last level too. */
-        dataSize += _KTX_PAD4(levelSize);
-#else
-        dataSize += levelSize;
-#endif
-    }
-    return dataSize;
-}
-
-/**
- * @memberof ktxTexture @private
- * @~English
- * @brief Return the number of bytes needed to store all the image data for
- *        a ktxTexture.
- *
- * The caclulated size does not include space for storing the @c imageSize
- * fields of each mip level.
- *
- * @param[in]     This       pointer to the ktxTexture object of interest.
- *
- * @return the data size in bytes.
- */
-static ktx_size_t
-ktxTexture_calcDataSize(ktxTexture* This)
-{
-    assert (This != NULL);
-    return ktxTexture_dataSize(This, This->numLevels);
-}
-
-/**
- * @memberof ktxTexture @private
- * @~English
- * @brief Return the size of the primitive type of a single color component
- *
- * @param[in]     This       pointer to the ktxTexture object of interest.
- *
- * @return the type size in bytes.
- */
-ktx_uint32_t
-ktxTexture_glTypeSize(ktxTexture* This)
-{
-    assert(This != NULL);
-    return ((ktxTextureInt*)This)->glTypeSize;
-}
-
-/**
- * @memberof ktxTexture @private
- * @~English
- * @brief Get information about rows of an uncompresssed texture image at a
- *        specified level.
- *
- * For an image at @p level of a ktxTexture provide the number of rows, the
- * packed (unpadded) number of bytes in a row and the padding necessary to
- * comply with KTX_GL_UNPACK_ALIGNMENT.
- *
- * @param[in]     This     pointer to the ktxTexture object of interest.
- * @param[in]     level    level of interest.
- * @param[in,out] numRows  pointer to location to store the number of rows.
- * @param[in,out] pRowLengthBytes pointer to location to store number of bytes
- *                                in a row.
- * @param[in.out] pRowPadding pointer to location to store the number of bytes
- *                            of padding.
- */
-void
-ktxTexture_rowInfo(ktxTexture* This, ktx_uint32_t level,
-                   ktx_uint32_t* numRows, ktx_uint32_t* pRowLengthBytes,
-                   ktx_uint32_t* pRowPadding)
-{
-    GlFormatSize* formatInfo;
-    struct blockCount {
-        ktx_uint32_t x;
-    } blockCount;
-
-    assert (This != NULL);
-    
-    formatInfo = &((ktxTextureInt*)This)->formatInfo;
-    assert(!This->isCompressed);
-    assert(formatInfo->blockWidth == formatInfo->blockHeight == formatInfo->blockDepth == 1);
-
-    blockCount.x = MAX(1, (This->baseWidth / formatInfo->blockWidth)  >> level);
-    *numRows = MAX(1, (This->baseHeight / formatInfo->blockHeight)  >> level);
-
-    *pRowLengthBytes = blockCount.x * formatInfo->blockSizeInBits / 8;
-    *pRowPadding = padRow(pRowLengthBytes);
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Return pitch betweeb rows of a texture image level in bytes.
- *
- * For uncompressed textures the pitch is the number of bytes between
- * rows of texels. For compressed textures it is the number of bytes
- * between rows of blocks. The value is padded to GL_UNPACK_ALIGNMENT,
- * if necessary. For all currently known compressed formats padding
- * will not be necessary.
- *
- * @param[in]     This     pointer to the ktxTexture object of interest.
- * @param[in]     level    level of interest.
- *
- * @return  the row pitch in bytes.
- */
- ktx_uint32_t
- ktxTexture_GetRowPitch(ktxTexture* This, ktx_uint32_t level)
- {
-    GlFormatSize* formatInfo;
-    struct blockCount {
-        ktx_uint32_t x;
-    } blockCount;
-    ktx_uint32_t pitch;
-
-    formatInfo = &((ktxTextureInt*)This)->formatInfo;
-    blockCount.x = MAX(1, (This->baseWidth / formatInfo->blockWidth)  >> level);
-    pitch = blockCount.x * formatInfo->blockSizeInBits / 8;
-    (void)padRow(&pitch);
-
-    return pitch;
- }
-
-/**
- * @memberof ktxTexture @private
- * @~English
- * @brief Query if a ktxTexture has an active stream.
- *
- * Tests if a ktxTexture has unread image data. The internal stream is closed
- * once all the images have been read.
- *
- * @param[in]     This     pointer to the ktxTexture object of interest.
- *
- * @return KTX_TRUE if there is an active stream, KTX_FALSE otherwise.
- */
-ktx_bool_t
-ktxTexture_isActiveStream(ktxTexture* This)
-{
-    assert(This != NULL);
-    return ((ktxTextureInt*)This)->stream.data.file != NULL;
-}
-
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Find the offset of an image within a ktxTexture's image data.
- *
- * As there is no such thing as a 3D cubemap we make the 3rd location parameter
- * do double duty.
- *
- * @param[in]     This      pointer to the ktxTexture object of interest.
- * @param[in]     level     mip level of the image.
- * @param[in]     layer     array layer of the image.
- * @param[in]     faceSlice cube map face or depth slice of the image.
- * @param[in,out] pOffset   pointer to location to store the offset.
- *
- * @return  KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_OPERATION
- *                         @p level, @p layer or @p faceSlice exceed the
- *                         dimensions of the texture.
- * @exception KTX_INVALID_VALID @p This is NULL.
- */
-KTX_error_code
-ktxTexture_GetImageOffset(ktxTexture* This, ktx_uint32_t level,
-                          ktx_uint32_t layer, ktx_uint32_t faceSlice,
-                          ktx_size_t* pOffset)
-{
-    if (This == NULL)
-        return KTX_INVALID_VALUE;
-
-    if (level >= This->numLevels || layer >= This->numLayers)
-        return KTX_INVALID_OPERATION;
-    
-    if (This->isCubemap) {
-        if (faceSlice >= This->numFaces)
-            return KTX_INVALID_OPERATION;
-    } else {
-        ktx_uint32_t maxSlice = MAX(1, This->baseDepth >> level);
-        if (faceSlice >= maxSlice)
-            return KTX_INVALID_OPERATION;
-    }
-    
-    // Get the size of the data up to the start of the indexed level.
-    *pOffset = ktxTexture_dataSize(This, level);
-    
-    // All layers, faces & slices within a level are the same size.
-    if (layer != 0) {
-        ktx_size_t layerSize;
-        layerSize = ktxTexture_layerSize(This, level);
-        *pOffset += layer * layerSize;
-    }
-    if (faceSlice != 0) {
-        ktx_size_t imageSize;
-        imageSize = ktxTexture_GetImageSize(This, level);
-#if (KTX_GL_UNPACK_ALIGNMENT != 4)
-        if (This->isCubemap)
-            _KTX_PAD4(imageSize); // Account for cubePadding.
-#endif
-        *pOffset += faceSlice * imageSize;
-    }
-
-    return KTX_SUCCESS;
-}
-
-/** @} */
-
diff --git a/external/KTX-Software-master/lib/uthash.h b/external/KTX-Software-master/lib/uthash.h
deleted file mode 100644
index ddd50a77bbe0f5a1f4781d380f9ba8e2ea217ad7..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/uthash.h
+++ /dev/null
@@ -1,960 +0,0 @@
-/*
-Copyright (c) 2003-2010, Troy D. Hanson     http://uthash.sourceforge.net
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef UTHASH_H
-#define UTHASH_H 
-
-#include <string.h>   /* memcmp,strlen */
-#include <stddef.h>   /* ptrdiff_t */
-
-/* These macros use decltype or the earlier __typeof GNU extension.
-   As decltype is only available in newer compilers (VS2010 or gcc 4.3+
-   when compiling c++ source) this code uses whatever method is needed
-   or, for VS2008 where neither is available, uses casting workarounds. */
-#ifdef _MSC_VER         /* MS compiler */
-#if _MSC_VER >= 1600 && __cplusplus  /* VS2010 or newer in C++ mode */
-#define DECLTYPE(x) (decltype(x))
-#else                   /* VS2008 or older (or VS2010 in C mode) */
-#define NO_DECLTYPE
-#define DECLTYPE(x)
-#endif
-#else                   /* GNU, Sun and other compilers */
-#define DECLTYPE(x) (__typeof(x))
-#endif
-
-#ifdef NO_DECLTYPE
-#define DECLTYPE_ASSIGN(dst,src)                                                 \
-do {                                                                             \
-  char **_da_dst = (char**)(&(dst));                                             \
-  *_da_dst = (char*)(src);                                                       \
-} while(0)
-#else 
-#define DECLTYPE_ASSIGN(dst,src)                                                 \
-do {                                                                             \
-  (dst) = DECLTYPE(dst)(src);                                                    \
-} while(0)
-#endif
-
-/* a number of the hash function use uint32_t which isn't defined on win32 */
-#ifdef _MSC_VER
-typedef unsigned int uint32_t;
-#else
-#include <inttypes.h>   /* uint32_t */
-#endif
-
-#define UTHASH_VERSION 1.9.1
-
-#define uthash_fatal(msg) exit(-1)        /* fatal error (out of memory,etc) */
-#define uthash_malloc(sz) malloc(sz)      /* malloc fcn                      */
-#define uthash_free(ptr) free(ptr)        /* free fcn                        */
-
-#define uthash_noexpand_fyi(tbl)          /* can be defined to log noexpand  */
-#define uthash_expand_fyi(tbl)            /* can be defined to log expands   */
-
-/* initial number of buckets */
-#define HASH_INITIAL_NUM_BUCKETS 32      /* initial number of buckets        */
-#define HASH_INITIAL_NUM_BUCKETS_LOG2 5  /* lg2 of initial number of buckets */
-#define HASH_BKT_CAPACITY_THRESH 10      /* expand when bucket count reaches */
-
-/* calculate the element whose hash handle address is hhe */
-#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
-
-#define HASH_FIND(hh,head,keyptr,keylen,out)                                     \
-do {                                                                             \
-  unsigned _hf_bkt,_hf_hashv;                                                    \
-  out=NULL;                                                                      \
-  if (head) {                                                                    \
-     HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt);   \
-     if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) {                           \
-       HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ],  \
-                        keyptr,keylen,out);                                      \
-     }                                                                           \
-  }                                                                              \
-} while (0)
-
-#ifdef HASH_BLOOM
-#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM)
-#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0)
-#define HASH_BLOOM_MAKE(tbl)                                                     \
-do {                                                                             \
-  (tbl)->bloom_nbits = HASH_BLOOM;                                               \
-  (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN);                 \
-  if (!((tbl)->bloom_bv))  { uthash_fatal( "out of memory"); }                   \
-  memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN);                                \
-  (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE;                                       \
-} while (0);
-
-#define HASH_BLOOM_FREE(tbl)                                                     \
-do {                                                                             \
-  uthash_free((tbl)->bloom_bv);                                                  \
-} while (0);
-
-#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8)))
-#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8)))
-
-#define HASH_BLOOM_ADD(tbl,hashv)                                                \
-  HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
-
-#define HASH_BLOOM_TEST(tbl,hashv)                                               \
-  HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
-
-#else
-#define HASH_BLOOM_MAKE(tbl) 
-#define HASH_BLOOM_FREE(tbl) 
-#define HASH_BLOOM_ADD(tbl,hashv) 
-#define HASH_BLOOM_TEST(tbl,hashv) (1)
-#endif
-
-#define HASH_MAKE_TABLE(hh,head)                                                 \
-do {                                                                             \
-  (head)->hh.tbl = (UT_hash_table*)uthash_malloc(                                \
-                  sizeof(UT_hash_table));                                        \
-  if (!((head)->hh.tbl))  { uthash_fatal( "out of memory"); }                    \
-  memset((head)->hh.tbl, 0, sizeof(UT_hash_table));                              \
-  (head)->hh.tbl->tail = &((head)->hh);                                          \
-  (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS;                        \
-  (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2;              \
-  (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head);                    \
-  (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc(                      \
-          HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket));               \
-  if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); }             \
-  memset((head)->hh.tbl->buckets, 0,                                             \
-          HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket));               \
-  HASH_BLOOM_MAKE((head)->hh.tbl);                                               \
-  (head)->hh.tbl->signature = HASH_SIGNATURE;                                    \
-} while(0)
-
-#define HASH_ADD(hh,head,fieldname,keylen_in,add)                                \
-        HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add)
- 
-#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add)                            \
-do {                                                                             \
- unsigned _ha_bkt;                                                               \
- (add)->hh.next = NULL;                                                          \
- (add)->hh.key = (char*)keyptr;                                                  \
- (add)->hh.keylen = keylen_in;                                                   \
- if (!(head)) {                                                                  \
-    head = (add);                                                                \
-    (head)->hh.prev = NULL;                                                      \
-    HASH_MAKE_TABLE(hh,head);                                                    \
- } else {                                                                        \
-    (head)->hh.tbl->tail->next = (add);                                          \
-    (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail);         \
-    (head)->hh.tbl->tail = &((add)->hh);                                         \
- }                                                                               \
- (head)->hh.tbl->num_items++;                                                    \
- (add)->hh.tbl = (head)->hh.tbl;                                                 \
- HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets,                         \
-         (add)->hh.hashv, _ha_bkt);                                              \
- HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh);                   \
- HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv);                                 \
- HASH_EMIT_KEY(hh,head,keyptr,keylen_in);                                        \
- HASH_FSCK(hh,head);                                                             \
-} while(0)
-
-#define HASH_TO_BKT( hashv, num_bkts, bkt )                                      \
-do {                                                                             \
-  bkt = ((hashv) & ((num_bkts) - 1));                                            \
-} while(0)
-
-/* delete "delptr" from the hash table.
- * "the usual" patch-up process for the app-order doubly-linked-list.
- * The use of _hd_hh_del below deserves special explanation.
- * These used to be expressed using (delptr) but that led to a bug
- * if someone used the same symbol for the head and deletee, like
- *  HASH_DELETE(hh,users,users);
- * We want that to work, but by changing the head (users) below
- * we were forfeiting our ability to further refer to the deletee (users)
- * in the patch-up process. Solution: use scratch space to
- * copy the deletee pointer, then the latter references are via that
- * scratch pointer rather than through the repointed (users) symbol.
- */
-#define HASH_DELETE(hh,head,delptr)                                              \
-do {                                                                             \
-    unsigned _hd_bkt;                                                            \
-    struct UT_hash_handle *_hd_hh_del;                                           \
-    if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) )  {         \
-        uthash_free((head)->hh.tbl->buckets );                                   \
-        HASH_BLOOM_FREE((head)->hh.tbl);                                         \
-        uthash_free((head)->hh.tbl);                                             \
-        head = NULL;                                                             \
-    } else {                                                                     \
-        _hd_hh_del = &((delptr)->hh);                                            \
-        if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) {     \
-            (head)->hh.tbl->tail =                                               \
-                (UT_hash_handle*)((char*)((delptr)->hh.prev) +                   \
-                (head)->hh.tbl->hho);                                            \
-        }                                                                        \
-        if ((delptr)->hh.prev) {                                                 \
-            ((UT_hash_handle*)((char*)((delptr)->hh.prev) +                      \
-                    (head)->hh.tbl->hho))->next = (delptr)->hh.next;             \
-        } else {                                                                 \
-            DECLTYPE_ASSIGN(head,(delptr)->hh.next);                             \
-        }                                                                        \
-        if (_hd_hh_del->next) {                                                  \
-            ((UT_hash_handle*)((char*)_hd_hh_del->next +                         \
-                    (head)->hh.tbl->hho))->prev =                                \
-                    _hd_hh_del->prev;                                            \
-        }                                                                        \
-        HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt);   \
-        HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del);        \
-        (head)->hh.tbl->num_items--;                                             \
-    }                                                                            \
-    HASH_FSCK(hh,head);                                                          \
-} while (0)
-
-
-/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
-#define HASH_FIND_STR(head,findstr,out)                                          \
-    HASH_FIND(hh,head,findstr,strlen(findstr),out)
-#define HASH_ADD_STR(head,strfield,add)                                          \
-    HASH_ADD(hh,head,strfield,strlen(add->strfield),add)
-#define HASH_FIND_INT(head,findint,out)                                          \
-    HASH_FIND(hh,head,findint,sizeof(int),out)
-#define HASH_ADD_INT(head,intfield,add)                                          \
-    HASH_ADD(hh,head,intfield,sizeof(int),add)
-#define HASH_FIND_PTR(head,findptr,out)                                          \
-    HASH_FIND(hh,head,findptr,sizeof(void *),out)
-#define HASH_ADD_PTR(head,ptrfield,add)                                          \
-    HASH_ADD(hh,head,ptrfield,sizeof(void *),add)
-#define HASH_DEL(head,delptr)                                                    \
-    HASH_DELETE(hh,head,delptr)
-
-/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.
- * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
- */
-#ifdef HASH_DEBUG
-#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
-#define HASH_FSCK(hh,head)                                                       \
-do {                                                                             \
-    unsigned _bkt_i;                                                             \
-    unsigned _count, _bkt_count;                                                 \
-    char *_prev;                                                                 \
-    struct UT_hash_handle *_thh;                                                 \
-    if (head) {                                                                  \
-        _count = 0;                                                              \
-        for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) {       \
-            _bkt_count = 0;                                                      \
-            _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head;                      \
-            _prev = NULL;                                                        \
-            while (_thh) {                                                       \
-               if (_prev != (char*)(_thh->hh_prev)) {                            \
-                   HASH_OOPS("invalid hh_prev %p, actual %p\n",                  \
-                    _thh->hh_prev, _prev );                                      \
-               }                                                                 \
-               _bkt_count++;                                                     \
-               _prev = (char*)(_thh);                                            \
-               _thh = _thh->hh_next;                                             \
-            }                                                                    \
-            _count += _bkt_count;                                                \
-            if ((head)->hh.tbl->buckets[_bkt_i].count !=  _bkt_count) {          \
-               HASH_OOPS("invalid bucket count %d, actual %d\n",                 \
-                (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count);              \
-            }                                                                    \
-        }                                                                        \
-        if (_count != (head)->hh.tbl->num_items) {                               \
-            HASH_OOPS("invalid hh item count %d, actual %d\n",                   \
-                (head)->hh.tbl->num_items, _count );                             \
-        }                                                                        \
-        /* traverse hh in app order; check next/prev integrity, count */         \
-        _count = 0;                                                              \
-        _prev = NULL;                                                            \
-        _thh =  &(head)->hh;                                                     \
-        while (_thh) {                                                           \
-           _count++;                                                             \
-           if (_prev !=(char*)(_thh->prev)) {                                    \
-              HASH_OOPS("invalid prev %p, actual %p\n",                          \
-                    _thh->prev, _prev );                                         \
-           }                                                                     \
-           _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh);                    \
-           _thh = ( _thh->next ?  (UT_hash_handle*)((char*)(_thh->next) +        \
-                                  (head)->hh.tbl->hho) : NULL );                 \
-        }                                                                        \
-        if (_count != (head)->hh.tbl->num_items) {                               \
-            HASH_OOPS("invalid app item count %d, actual %d\n",                  \
-                (head)->hh.tbl->num_items, _count );                             \
-        }                                                                        \
-    }                                                                            \
-} while (0)
-#else
-#define HASH_FSCK(hh,head) 
-#endif
-
-/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to 
- * the descriptor to which this macro is defined for tuning the hash function.
- * The app can #include <unistd.h> to get the prototype for write(2). */
-#ifdef HASH_EMIT_KEYS
-#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)                                   \
-do {                                                                             \
-    unsigned _klen = fieldlen;                                                   \
-    write(HASH_EMIT_KEYS, &_klen, sizeof(_klen));                                \
-    write(HASH_EMIT_KEYS, keyptr, fieldlen);                                     \
-} while (0)
-#else 
-#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)                    
-#endif
-
-/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
-#ifdef HASH_FUNCTION 
-#define HASH_FCN HASH_FUNCTION
-#else
-#define HASH_FCN HASH_JEN
-#endif
-
-/* The Bernstein hash function, used in Perl prior to v5.6 */
-#define HASH_BER(key,keylen,num_bkts,hashv,bkt)                                  \
-do {                                                                             \
-  unsigned _hb_keylen=keylen;                                                    \
-  char *_hb_key=(char*)key;                                                      \
-  (hashv) = 0;                                                                   \
-  while (_hb_keylen--)  { (hashv) = ((hashv) * 33) + *_hb_key++; }               \
-  bkt = (hashv) & (num_bkts-1);                                                  \
-} while (0)
-
-
-/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at 
- * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
-#define HASH_SAX(key,keylen,num_bkts,hashv,bkt)                                  \
-do {                                                                             \
-  unsigned _sx_i;                                                                \
-  char *_hs_key=(char*)key;                                                      \
-  hashv = 0;                                                                     \
-  for(_sx_i=0; _sx_i < keylen; _sx_i++)                                          \
-      hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i];                     \
-  bkt = hashv & (num_bkts-1);                                                    \
-} while (0)
-
-#define HASH_FNV(key,keylen,num_bkts,hashv,bkt)                                  \
-do {                                                                             \
-  unsigned _fn_i;                                                                \
-  char *_hf_key=(char*)key;                                                      \
-  hashv = 2166136261UL;                                                          \
-  for(_fn_i=0; _fn_i < keylen; _fn_i++)                                          \
-      hashv = (hashv * 16777619) ^ _hf_key[_fn_i];                               \
-  bkt = hashv & (num_bkts-1);                                                    \
-} while(0);
- 
-#define HASH_OAT(key,keylen,num_bkts,hashv,bkt)                                  \
-do {                                                                             \
-  unsigned _ho_i;                                                                \
-  char *_ho_key=(char*)key;                                                      \
-  hashv = 0;                                                                     \
-  for(_ho_i=0; _ho_i < keylen; _ho_i++) {                                        \
-      hashv += _ho_key[_ho_i];                                                   \
-      hashv += (hashv << 10);                                                    \
-      hashv ^= (hashv >> 6);                                                     \
-  }                                                                              \
-  hashv += (hashv << 3);                                                         \
-  hashv ^= (hashv >> 11);                                                        \
-  hashv += (hashv << 15);                                                        \
-  bkt = hashv & (num_bkts-1);                                                    \
-} while(0)
-
-#define HASH_JEN_MIX(a,b,c)                                                      \
-do {                                                                             \
-  a -= b; a -= c; a ^= ( c >> 13 );                                              \
-  b -= c; b -= a; b ^= ( a << 8 );                                               \
-  c -= a; c -= b; c ^= ( b >> 13 );                                              \
-  a -= b; a -= c; a ^= ( c >> 12 );                                              \
-  b -= c; b -= a; b ^= ( a << 16 );                                              \
-  c -= a; c -= b; c ^= ( b >> 5 );                                               \
-  a -= b; a -= c; a ^= ( c >> 3 );                                               \
-  b -= c; b -= a; b ^= ( a << 10 );                                              \
-  c -= a; c -= b; c ^= ( b >> 15 );                                              \
-} while (0)
-
-#define HASH_JEN(key,keylen,num_bkts,hashv,bkt)                                  \
-do {                                                                             \
-  unsigned _hj_i,_hj_j,_hj_k;                                                    \
-  char *_hj_key=(char*)key;                                                      \
-  hashv = 0xfeedbeef;                                                            \
-  _hj_i = _hj_j = 0x9e3779b9;                                                    \
-  _hj_k = keylen;                                                                \
-  while (_hj_k >= 12) {                                                          \
-    _hj_i +=    (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 )                      \
-        + ( (unsigned)_hj_key[2] << 16 )                                         \
-        + ( (unsigned)_hj_key[3] << 24 ) );                                      \
-    _hj_j +=    (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 )                      \
-        + ( (unsigned)_hj_key[6] << 16 )                                         \
-        + ( (unsigned)_hj_key[7] << 24 ) );                                      \
-    hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 )                         \
-        + ( (unsigned)_hj_key[10] << 16 )                                        \
-        + ( (unsigned)_hj_key[11] << 24 ) );                                     \
-                                                                                 \
-     HASH_JEN_MIX(_hj_i, _hj_j, hashv);                                          \
-                                                                                 \
-     _hj_key += 12;                                                              \
-     _hj_k -= 12;                                                                \
-  }                                                                              \
-  hashv += keylen;                                                               \
-  switch ( _hj_k ) {                                                             \
-     case 11: hashv += ( (unsigned)_hj_key[10] << 24 );                          \
-     case 10: hashv += ( (unsigned)_hj_key[9] << 16 );                           \
-     case 9:  hashv += ( (unsigned)_hj_key[8] << 8 );                            \
-     case 8:  _hj_j += ( (unsigned)_hj_key[7] << 24 );                           \
-     case 7:  _hj_j += ( (unsigned)_hj_key[6] << 16 );                           \
-     case 6:  _hj_j += ( (unsigned)_hj_key[5] << 8 );                            \
-     case 5:  _hj_j += _hj_key[4];                                               \
-     case 4:  _hj_i += ( (unsigned)_hj_key[3] << 24 );                           \
-     case 3:  _hj_i += ( (unsigned)_hj_key[2] << 16 );                           \
-     case 2:  _hj_i += ( (unsigned)_hj_key[1] << 8 );                            \
-     case 1:  _hj_i += _hj_key[0];                                               \
-  }                                                                              \
-  HASH_JEN_MIX(_hj_i, _hj_j, hashv);                                             \
-  bkt = hashv & (num_bkts-1);                                                    \
-} while(0)
-
-/* The Paul Hsieh hash function */
-#undef get16bits
-#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__)             \
-  || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
-#define get16bits(d) (*((const uint16_t *) (d)))
-#endif
-
-#if !defined (get16bits)
-#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)             \
-                       +(uint32_t)(((const uint8_t *)(d))[0]) )
-#endif
-#define HASH_SFH(key,keylen,num_bkts,hashv,bkt)                                  \
-do {                                                                             \
-  char *_sfh_key=(char*)key;                                                     \
-  uint32_t _sfh_tmp, _sfh_len = keylen;                                          \
-                                                                                 \
-  int _sfh_rem = _sfh_len & 3;                                                   \
-  _sfh_len >>= 2;                                                                \
-  hashv = 0xcafebabe;                                                            \
-                                                                                 \
-  /* Main loop */                                                                \
-  for (;_sfh_len > 0; _sfh_len--) {                                              \
-    hashv    += get16bits (_sfh_key);                                            \
-    _sfh_tmp       = (get16bits (_sfh_key+2) << 11) ^ hashv;                     \
-    hashv     = (hashv << 16) ^ _sfh_tmp;                                        \
-    _sfh_key += 2*sizeof (uint16_t);                                             \
-    hashv    += hashv >> 11;                                                     \
-  }                                                                              \
-                                                                                 \
-  /* Handle end cases */                                                         \
-  switch (_sfh_rem) {                                                            \
-    case 3: hashv += get16bits (_sfh_key);                                       \
-            hashv ^= hashv << 16;                                                \
-            hashv ^= _sfh_key[sizeof (uint16_t)] << 18;                          \
-            hashv += hashv >> 11;                                                \
-            break;                                                               \
-    case 2: hashv += get16bits (_sfh_key);                                       \
-            hashv ^= hashv << 11;                                                \
-            hashv += hashv >> 17;                                                \
-            break;                                                               \
-    case 1: hashv += *_sfh_key;                                                  \
-            hashv ^= hashv << 10;                                                \
-            hashv += hashv >> 1;                                                 \
-  }                                                                              \
-                                                                                 \
-    /* Force "avalanching" of final 127 bits */                                  \
-    hashv ^= hashv << 3;                                                         \
-    hashv += hashv >> 5;                                                         \
-    hashv ^= hashv << 4;                                                         \
-    hashv += hashv >> 17;                                                        \
-    hashv ^= hashv << 25;                                                        \
-    hashv += hashv >> 6;                                                         \
-    bkt = hashv & (num_bkts-1);                                                  \
-} while(0);
-
-#ifdef HASH_USING_NO_STRICT_ALIASING
-/* The MurmurHash exploits some CPU's (e.g. x86) tolerance for unaligned reads.
- * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
- * So MurmurHash comes in two versions, the faster unaligned one and the slower
- * aligned one. We only use the faster one on CPU's where we know it's safe. 
- *
- * Note the preprocessor built-in defines can be emitted using:
- *
- *   gcc -m64 -dM -E - < /dev/null                  (on gcc)
- *   cc -## a.c (where a.c is a simple test file)   (Sun Studio)
- */
-#if (defined(__i386__) || defined(__x86_64__)) 
-#define HASH_MUR HASH_MUR_UNALIGNED
-#else
-#define HASH_MUR HASH_MUR_ALIGNED
-#endif
-
-/* Appleby's MurmurHash fast version for unaligned-tolerant archs like i386 */
-#define HASH_MUR_UNALIGNED(key,keylen,num_bkts,hashv,bkt)                        \
-do {                                                                             \
-  const unsigned int _mur_m = 0x5bd1e995;                                        \
-  const int _mur_r = 24;                                                         \
-  hashv = 0xcafebabe ^ keylen;                                                   \
-  char *_mur_key = (char *)key;                                                  \
-  uint32_t _mur_tmp, _mur_len = keylen;                                          \
-                                                                                 \
-  for (;_mur_len >= 4; _mur_len-=4) {                                            \
-    _mur_tmp = *(uint32_t *)_mur_key;                                            \
-    _mur_tmp *= _mur_m;                                                          \
-    _mur_tmp ^= _mur_tmp >> _mur_r;                                              \
-    _mur_tmp *= _mur_m;                                                          \
-    hashv *= _mur_m;                                                             \
-    hashv ^= _mur_tmp;                                                           \
-    _mur_key += 4;                                                               \
-  }                                                                              \
-                                                                                 \
-  switch(_mur_len)                                                               \
-  {                                                                              \
-    case 3: hashv ^= _mur_key[2] << 16;                                          \
-    case 2: hashv ^= _mur_key[1] << 8;                                           \
-    case 1: hashv ^= _mur_key[0];                                                \
-            hashv *= _mur_m;                                                     \
-  };                                                                             \
-                                                                                 \
-  hashv ^= hashv >> 13;                                                          \
-  hashv *= _mur_m;                                                               \
-  hashv ^= hashv >> 15;                                                          \
-                                                                                 \
-  bkt = hashv & (num_bkts-1);                                                    \
-} while(0)
-
-/* Appleby's MurmurHash version for alignment-sensitive archs like Sparc */
-#define HASH_MUR_ALIGNED(key,keylen,num_bkts,hashv,bkt)                          \
-do {                                                                             \
-  const unsigned int _mur_m = 0x5bd1e995;                                        \
-  const int _mur_r = 24;                                                         \
-  hashv = 0xcafebabe ^ keylen;                                                   \
-  char *_mur_key = (char *)key;                                                  \
-  uint32_t _mur_len = keylen;                                                    \
-  int _mur_align = (int)_mur_key & 3;                                            \
-                                                                                 \
-  if (_mur_align && (_mur_len >= 4)) {                                           \
-    unsigned _mur_t = 0, _mur_d = 0;                                             \
-    switch(_mur_align) {                                                         \
-      case 1: _mur_t |= _mur_key[2] << 16;                                       \
-      case 2: _mur_t |= _mur_key[1] << 8;                                        \
-      case 3: _mur_t |= _mur_key[0];                                             \
-    }                                                                            \
-    _mur_t <<= (8 * _mur_align);                                                 \
-    _mur_key += 4-_mur_align;                                                    \
-    _mur_len -= 4-_mur_align;                                                    \
-    int _mur_sl = 8 * (4-_mur_align);                                            \
-    int _mur_sr = 8 * _mur_align;                                                \
-                                                                                 \
-    for (;_mur_len >= 4; _mur_len-=4) {                                          \
-      _mur_d = *(unsigned *)_mur_key;                                            \
-      _mur_t = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl);                        \
-      unsigned _mur_k = _mur_t;                                                  \
-      _mur_k *= _mur_m;                                                          \
-      _mur_k ^= _mur_k >> _mur_r;                                                \
-      _mur_k *= _mur_m;                                                          \
-      hashv *= _mur_m;                                                           \
-      hashv ^= _mur_k;                                                           \
-      _mur_t = _mur_d;                                                           \
-      _mur_key += 4;                                                             \
-    }                                                                            \
-    _mur_d = 0;                                                                  \
-    if(_mur_len >= _mur_align) {                                                 \
-      switch(_mur_align) {                                                       \
-        case 3: _mur_d |= _mur_key[2] << 16;                                     \
-        case 2: _mur_d |= _mur_key[1] << 8;                                      \
-        case 1: _mur_d |= _mur_key[0];                                           \
-      }                                                                          \
-      unsigned _mur_k = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl);               \
-      _mur_k *= _mur_m;                                                          \
-      _mur_k ^= _mur_k >> _mur_r;                                                \
-      _mur_k *= _mur_m;                                                          \
-      hashv *= _mur_m;                                                           \
-      hashv ^= _mur_k;                                                           \
-      _mur_k += _mur_align;                                                      \
-      _mur_len -= _mur_align;                                                    \
-                                                                                 \
-      switch(_mur_len)                                                           \
-      {                                                                          \
-        case 3: hashv ^= _mur_key[2] << 16;                                      \
-        case 2: hashv ^= _mur_key[1] << 8;                                       \
-        case 1: hashv ^= _mur_key[0];                                            \
-                hashv *= _mur_m;                                                 \
-      }                                                                          \
-    } else {                                                                     \
-      switch(_mur_len)                                                           \
-      {                                                                          \
-        case 3: _mur_d ^= _mur_key[2] << 16;                                     \
-        case 2: _mur_d ^= _mur_key[1] << 8;                                      \
-        case 1: _mur_d ^= _mur_key[0];                                           \
-        case 0: hashv ^= (_mur_t >> _mur_sr) | (_mur_d << _mur_sl);              \
-        hashv *= _mur_m;                                                         \
-      }                                                                          \
-    }                                                                            \
-                                                                                 \
-    hashv ^= hashv >> 13;                                                        \
-    hashv *= _mur_m;                                                             \
-    hashv ^= hashv >> 15;                                                        \
-  } else {                                                                       \
-    for (;_mur_len >= 4; _mur_len-=4) {                                          \
-      unsigned _mur_k = *(unsigned*)_mur_key;                                    \
-      _mur_k *= _mur_m;                                                          \
-      _mur_k ^= _mur_k >> _mur_r;                                                \
-      _mur_k *= _mur_m;                                                          \
-      hashv *= _mur_m;                                                           \
-      hashv ^= _mur_k;                                                           \
-      _mur_key += 4;                                                             \
-    }                                                                            \
-    switch(_mur_len)                                                             \
-    {                                                                            \
-      case 3: hashv ^= _mur_key[2] << 16;                                        \
-      case 2: hashv ^= _mur_key[1] << 8;                                         \
-      case 1: hashv ^= _mur_key[0];                                              \
-      hashv *= _mur_m;                                                           \
-    }                                                                            \
-                                                                                 \
-    hashv ^= hashv >> 13;                                                        \
-    hashv *= _mur_m;                                                             \
-    hashv ^= hashv >> 15;                                                        \
-  }                                                                              \
-  bkt = hashv & (num_bkts-1);                                                    \
-} while(0)
-#endif  /* HASH_USING_NO_STRICT_ALIASING */
-
-/* key comparison function; return 0 if keys equal */
-#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) 
-
-/* iterate over items in a known bucket to find desired item */
-#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out)                       \
-do {                                                                             \
- if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head));          \
- else out=NULL;                                                                  \
- while (out) {                                                                   \
-    if (out->hh.keylen == keylen_in) {                                           \
-        if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break;             \
-    }                                                                            \
-    if (out->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,out->hh.hh_next)); \
-    else out = NULL;                                                             \
- }                                                                               \
-} while(0)
-
-/* add an item to a bucket  */
-#define HASH_ADD_TO_BKT(head,addhh)                                              \
-do {                                                                             \
- head.count++;                                                                   \
- (addhh)->hh_next = head.hh_head;                                                \
- (addhh)->hh_prev = NULL;                                                        \
- if (head.hh_head) { (head).hh_head->hh_prev = (addhh); }                        \
- (head).hh_head=addhh;                                                           \
- if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH)             \
-     && (addhh)->tbl->noexpand != 1) {                                           \
-       HASH_EXPAND_BUCKETS((addhh)->tbl);                                        \
- }                                                                               \
-} while(0)
-
-/* remove an item from a given bucket */
-#define HASH_DEL_IN_BKT(hh,head,hh_del)                                          \
-    (head).count--;                                                              \
-    if ((head).hh_head == hh_del) {                                              \
-      (head).hh_head = hh_del->hh_next;                                          \
-    }                                                                            \
-    if (hh_del->hh_prev) {                                                       \
-        hh_del->hh_prev->hh_next = hh_del->hh_next;                              \
-    }                                                                            \
-    if (hh_del->hh_next) {                                                       \
-        hh_del->hh_next->hh_prev = hh_del->hh_prev;                              \
-    }                                                                
-
-/* Bucket expansion has the effect of doubling the number of buckets
- * and redistributing the items into the new buckets. Ideally the
- * items will distribute more or less evenly into the new buckets
- * (the extent to which this is true is a measure of the quality of
- * the hash function as it applies to the key domain). 
- * 
- * With the items distributed into more buckets, the chain length
- * (item count) in each bucket is reduced. Thus by expanding buckets
- * the hash keeps a bound on the chain length. This bounded chain 
- * length is the essence of how a hash provides constant time lookup.
- * 
- * The calculation of tbl->ideal_chain_maxlen below deserves some
- * explanation. First, keep in mind that we're calculating the ideal
- * maximum chain length based on the *new* (doubled) bucket count.
- * In fractions this is just n/b (n=number of items,b=new num buckets).
- * Since the ideal chain length is an integer, we want to calculate 
- * ceil(n/b). We don't depend on floating point arithmetic in this
- * hash, so to calculate ceil(n/b) with integers we could write
- * 
- *      ceil(n/b) = (n/b) + ((n%b)?1:0)
- * 
- * and in fact a previous version of this hash did just that.
- * But now we have improved things a bit by recognizing that b is
- * always a power of two. We keep its base 2 log handy (call it lb),
- * so now we can write this with a bit shift and logical AND:
- * 
- *      ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
- * 
- */
-#define HASH_EXPAND_BUCKETS(tbl)                                                 \
-do {                                                                             \
-    unsigned _he_bkt;                                                            \
-    unsigned _he_bkt_i;                                                          \
-    struct UT_hash_handle *_he_thh, *_he_hh_nxt;                                 \
-    UT_hash_bucket *_he_new_buckets, *_he_newbkt;                                \
-    _he_new_buckets = (UT_hash_bucket*)uthash_malloc(                            \
-             2 * tbl->num_buckets * sizeof(struct UT_hash_bucket));              \
-    if (!_he_new_buckets) { uthash_fatal( "out of memory"); }                    \
-    memset(_he_new_buckets, 0,                                                   \
-            2 * tbl->num_buckets * sizeof(struct UT_hash_bucket));               \
-    tbl->ideal_chain_maxlen =                                                    \
-       (tbl->num_items >> (tbl->log2_num_buckets+1)) +                           \
-       ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0);                    \
-    tbl->nonideal_items = 0;                                                     \
-    for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++)                \
-    {                                                                            \
-        _he_thh = tbl->buckets[ _he_bkt_i ].hh_head;                             \
-        while (_he_thh) {                                                        \
-           _he_hh_nxt = _he_thh->hh_next;                                        \
-           HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt);            \
-           _he_newbkt = &(_he_new_buckets[ _he_bkt ]);                           \
-           if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) {                \
-             tbl->nonideal_items++;                                              \
-             _he_newbkt->expand_mult = _he_newbkt->count /                       \
-                                        tbl->ideal_chain_maxlen;                 \
-           }                                                                     \
-           _he_thh->hh_prev = NULL;                                              \
-           _he_thh->hh_next = _he_newbkt->hh_head;                               \
-           if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev =               \
-                _he_thh;                                                         \
-           _he_newbkt->hh_head = _he_thh;                                        \
-           _he_thh = _he_hh_nxt;                                                 \
-        }                                                                        \
-    }                                                                            \
-    tbl->num_buckets *= 2;                                                       \
-    tbl->log2_num_buckets++;                                                     \
-    uthash_free( tbl->buckets );                                                 \
-    tbl->buckets = _he_new_buckets;                                              \
-    tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ?         \
-        (tbl->ineff_expands+1) : 0;                                              \
-    if (tbl->ineff_expands > 1) {                                                \
-        tbl->noexpand=1;                                                         \
-        uthash_noexpand_fyi(tbl);                                                \
-    }                                                                            \
-    uthash_expand_fyi(tbl);                                                      \
-} while(0)
-
-
-/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
-/* Note that HASH_SORT assumes the hash handle name to be hh. 
- * HASH_SRT was added to allow the hash handle name to be passed in. */
-#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)
-#define HASH_SRT(hh,head,cmpfcn)                                                 \
-do {                                                                             \
-  unsigned _hs_i;                                                                \
-  unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize;               \
-  struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail;            \
-  if (head) {                                                                    \
-      _hs_insize = 1;                                                            \
-      _hs_looping = 1;                                                           \
-      _hs_list = &((head)->hh);                                                  \
-      while (_hs_looping) {                                                      \
-          _hs_p = _hs_list;                                                      \
-          _hs_list = NULL;                                                       \
-          _hs_tail = NULL;                                                       \
-          _hs_nmerges = 0;                                                       \
-          while (_hs_p) {                                                        \
-              _hs_nmerges++;                                                     \
-              _hs_q = _hs_p;                                                     \
-              _hs_psize = 0;                                                     \
-              for ( _hs_i = 0; _hs_i  < _hs_insize; _hs_i++ ) {                  \
-                  _hs_psize++;                                                   \
-                  _hs_q = (UT_hash_handle*)((_hs_q->next) ?                      \
-                          ((void*)((char*)(_hs_q->next) +                        \
-                          (head)->hh.tbl->hho)) : NULL);                         \
-                  if (! (_hs_q) ) break;                                         \
-              }                                                                  \
-              _hs_qsize = _hs_insize;                                            \
-              while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) {           \
-                  if (_hs_psize == 0) {                                          \
-                      _hs_e = _hs_q;                                             \
-                      _hs_q = (UT_hash_handle*)((_hs_q->next) ?                  \
-                              ((void*)((char*)(_hs_q->next) +                    \
-                              (head)->hh.tbl->hho)) : NULL);                     \
-                      _hs_qsize--;                                               \
-                  } else if ( (_hs_qsize == 0) || !(_hs_q) ) {                   \
-                      _hs_e = _hs_p;                                             \
-                      _hs_p = (UT_hash_handle*)((_hs_p->next) ?                  \
-                              ((void*)((char*)(_hs_p->next) +                    \
-                              (head)->hh.tbl->hho)) : NULL);                     \
-                      _hs_psize--;                                               \
-                  } else if ((                                                   \
-                      cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \
-                             DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \
-                             ) <= 0) {                                           \
-                      _hs_e = _hs_p;                                             \
-                      _hs_p = (UT_hash_handle*)((_hs_p->next) ?                  \
-                              ((void*)((char*)(_hs_p->next) +                    \
-                              (head)->hh.tbl->hho)) : NULL);                     \
-                      _hs_psize--;                                               \
-                  } else {                                                       \
-                      _hs_e = _hs_q;                                             \
-                      _hs_q = (UT_hash_handle*)((_hs_q->next) ?                  \
-                              ((void*)((char*)(_hs_q->next) +                    \
-                              (head)->hh.tbl->hho)) : NULL);                     \
-                      _hs_qsize--;                                               \
-                  }                                                              \
-                  if ( _hs_tail ) {                                              \
-                      _hs_tail->next = ((_hs_e) ?                                \
-                            ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL);          \
-                  } else {                                                       \
-                      _hs_list = _hs_e;                                          \
-                  }                                                              \
-                  _hs_e->prev = ((_hs_tail) ?                                    \
-                     ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL);              \
-                  _hs_tail = _hs_e;                                              \
-              }                                                                  \
-              _hs_p = _hs_q;                                                     \
-          }                                                                      \
-          _hs_tail->next = NULL;                                                 \
-          if ( _hs_nmerges <= 1 ) {                                              \
-              _hs_looping=0;                                                     \
-              (head)->hh.tbl->tail = _hs_tail;                                   \
-              DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list));      \
-          }                                                                      \
-          _hs_insize *= 2;                                                       \
-      }                                                                          \
-      HASH_FSCK(hh,head);                                                        \
- }                                                                               \
-} while (0)
-
-/* This function selects items from one hash into another hash. 
- * The end result is that the selected items have dual presence 
- * in both hashes. There is no copy of the items made; rather 
- * they are added into the new hash through a secondary hash 
- * hash handle that must be present in the structure. */
-#define HASH_SELECT(hh_dst, dst, hh_src, src, cond)                              \
-do {                                                                             \
-  unsigned _src_bkt, _dst_bkt;                                                   \
-  void *_last_elt=NULL, *_elt;                                                   \
-  UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL;                         \
-  ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst));                 \
-  if (src) {                                                                     \
-    for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) {     \
-      for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head;                \
-          _src_hh;                                                               \
-          _src_hh = _src_hh->hh_next) {                                          \
-          _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh);                       \
-          if (cond(_elt)) {                                                      \
-            _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho);               \
-            _dst_hh->key = _src_hh->key;                                         \
-            _dst_hh->keylen = _src_hh->keylen;                                   \
-            _dst_hh->hashv = _src_hh->hashv;                                     \
-            _dst_hh->prev = _last_elt;                                           \
-            _dst_hh->next = NULL;                                                \
-            if (_last_elt_hh) { _last_elt_hh->next = _elt; }                     \
-            if (!dst) {                                                          \
-              DECLTYPE_ASSIGN(dst,_elt);                                         \
-              HASH_MAKE_TABLE(hh_dst,dst);                                       \
-            } else {                                                             \
-              _dst_hh->tbl = (dst)->hh_dst.tbl;                                  \
-            }                                                                    \
-            HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt);    \
-            HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh);            \
-            (dst)->hh_dst.tbl->num_items++;                                      \
-            _last_elt = _elt;                                                    \
-            _last_elt_hh = _dst_hh;                                              \
-          }                                                                      \
-      }                                                                          \
-    }                                                                            \
-  }                                                                              \
-  HASH_FSCK(hh_dst,dst);                                                         \
-} while (0)
-
-#define HASH_CLEAR(hh,head)                                                      \
-do {                                                                             \
-  if (head) {                                                                    \
-    uthash_free((head)->hh.tbl->buckets );                                       \
-    uthash_free((head)->hh.tbl);                                                 \
-    (head)=NULL;                                                                 \
-  }                                                                              \
-} while(0)
-
-/* obtain a count of items in the hash */
-#define HASH_COUNT(head) HASH_CNT(hh,head) 
-#define HASH_CNT(hh,head) (head?(head->hh.tbl->num_items):0)
-
-typedef struct UT_hash_bucket {
-   struct UT_hash_handle *hh_head;
-   unsigned count;
-
-   /* expand_mult is normally set to 0. In this situation, the max chain length
-    * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If
-    * the bucket's chain exceeds this length, bucket expansion is triggered). 
-    * However, setting expand_mult to a non-zero value delays bucket expansion
-    * (that would be triggered by additions to this particular bucket)
-    * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.
-    * (The multiplier is simply expand_mult+1). The whole idea of this
-    * multiplier is to reduce bucket expansions, since they are expensive, in
-    * situations where we know that a particular bucket tends to be overused.
-    * It is better to let its chain length grow to a longer yet-still-bounded
-    * value, than to do an O(n) bucket expansion too often. 
-    */
-   unsigned expand_mult;
-
-} UT_hash_bucket;
-
-/* random signature used only to find hash tables in external analysis */
-#define HASH_SIGNATURE 0xa0111fe1
-#define HASH_BLOOM_SIGNATURE 0xb12220f2
-
-typedef struct UT_hash_table {
-   UT_hash_bucket *buckets;
-   unsigned num_buckets, log2_num_buckets;
-   unsigned num_items;
-   struct UT_hash_handle *tail; /* tail hh in app order, for fast append    */
-   ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
-
-   /* in an ideal situation (all buckets used equally), no bucket would have
-    * more than ceil(#items/#buckets) items. that's the ideal chain length. */
-   unsigned ideal_chain_maxlen;
-
-   /* nonideal_items is the number of items in the hash whose chain position
-    * exceeds the ideal chain maxlen. these items pay the penalty for an uneven
-    * hash distribution; reaching them in a chain traversal takes >ideal steps */
-   unsigned nonideal_items;
-
-   /* ineffective expands occur when a bucket doubling was performed, but 
-    * afterward, more than half the items in the hash had nonideal chain
-    * positions. If this happens on two consecutive expansions we inhibit any
-    * further expansion, as it's not helping; this happens when the hash
-    * function isn't a good fit for the key domain. When expansion is inhibited
-    * the hash will still work, albeit no longer in constant time. */
-   unsigned ineff_expands, noexpand;
-
-   uint32_t signature; /* used only to find hash tables in external analysis */
-#ifdef HASH_BLOOM
-   uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
-   uint8_t *bloom_bv;
-   char bloom_nbits;
-#endif
-
-} UT_hash_table;
-
-typedef struct UT_hash_handle {
-   struct UT_hash_table *tbl;
-   void *prev;                       /* prev element in app order      */
-   void *next;                       /* next element in app order      */
-   struct UT_hash_handle *hh_prev;   /* previous hh in bucket order    */
-   struct UT_hash_handle *hh_next;   /* next hh in bucket order        */
-   void *key;                        /* ptr to enclosing struct's key  */
-   unsigned keylen;                  /* enclosing struct's key len     */
-   unsigned hashv;                   /* result of hash-fcn(key)        */
-} UT_hash_handle;
-
-#endif /* UTHASH_H */
diff --git a/external/KTX-Software-master/lib/vk_format.h b/external/KTX-Software-master/lib/vk_format.h
deleted file mode 100644
index a13b705d14a11bbe1d46dd1e5feff024c1a00d84..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/vk_format.h
+++ /dev/null
@@ -1,1371 +0,0 @@
-/*
-================================================================================================
-
-Description	:	Vulkan format properties and conversion from OpenGL.
-Author		:	J.M.P. van Waveren
-Date		:	07/17/2016
-Language	:	C99
-Format		:	Real tabs with the tab size equal to 4 spaces.
-Copyright	:	Copyright (c) 2016 Oculus VR, LLC. All Rights reserved.
-
-
-LICENSE
-=======
-
-Copyright (c) 2016 Oculus VR, LLC.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-
-DESCRIPTION
-===========
-
-This header implements several support routines to convert OpenGL formats/types
-to Vulkan formats. These routines are particularly useful for loading file
-formats that store OpenGL formats/types such as KTX and glTF.
-
-The functions in this header file convert the format, internalFormat and type
-that are used as parameters to the following OpenGL functions:
-
-void glTexImage2D( GLenum target, GLint level, GLint internalFormat,
-	GLsizei width, GLsizei height, GLint border,
-	GLenum format, GLenum type, const GLvoid * data );
-void glTexImage3D( GLenum target, GLint level, GLint internalFormat,
-	GLsizei width, GLsizei height, GLsizei depth, GLint border,
-	GLenum format, GLenum type, const GLvoid * data );
-void glCompressedTexImage2D( GLenum target, GLint level, GLenum internalformat,
-	GLsizei width, GLsizei height, GLint border,
-	GLsizei imageSize, const GLvoid * data );
-void glCompressedTexImage3D( GLenum target, GLint level, GLenum internalformat,
-	GLsizei width, GLsizei height, GLsizei depth, GLint border,
-	GLsizei imageSize, const GLvoid * data );
-void glTexStorage2D( GLenum target, GLsizei levels, GLenum internalformat,
-	GLsizei width, GLsizei height );
-void glTexStorage3D( GLenum target, GLsizei levels, GLenum internalformat,
-	GLsizei width, GLsizei height, GLsizei depth );
-void glVertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized,
-	GLsizei stride, const GLvoid * pointer);
-
-
-IMPLEMENTATION
-==============
-
-This file does not include OpenGL / OpenGL ES headers because:
-
-  1. Including OpenGL / OpenGL ES headers is platform dependent and
-     may require a separate installation of an OpenGL SDK.
-  2. The OpenGL format/type constants are the same between extensions and core.
-  3. The OpenGL format/type constants are the same between OpenGL and OpenGL ES.
-  4. File formats like KTX and glTF may use OpenGL formats and types that
-     are not supported by the OpenGL implementation on the platform but are
-     supported by the Vulkan implementation.
-
-
-ENTRY POINTS
-============
-
-static inline VkFormat vkGetFormatFromOpenGLFormat( const GLenum format, const GLenum type );
-static inline VkFormat vkGetFormatFromOpenGLType( const GLenum type, const GLuint numComponents, const GLboolean normalized );
-static inline VkFormat vkGetFormatFromOpenGLInternalFormat( const GLenum internalFormat );
-static inline void vkGetFormatSize( const VkFormat format, VkFormatSize * pFormatSize );
-
-================================================================================================
-*/
-
-#if !defined( VK_FORMAT_H )
-#define VK_FORMAT_H
-
-#include "gl_format.h"
-
-static inline VkFormat vkGetFormatFromOpenGLFormat( const GLenum format, const GLenum type )
-{
-	switch ( type )
-	{
-		//
-		// 8 bits per component
-		//
-		case GL_UNSIGNED_BYTE:
-		{
-			switch ( format )
-			{
-				case GL_RED:					return VK_FORMAT_R8_UNORM;
-				case GL_RG:						return VK_FORMAT_R8G8_UNORM;
-				case GL_RGB:					return VK_FORMAT_R8G8B8_UNORM;
-				case GL_BGR:					return VK_FORMAT_B8G8R8_UNORM;
-				case GL_RGBA:					return VK_FORMAT_R8G8B8A8_UNORM;
-				case GL_BGRA:					return VK_FORMAT_B8G8R8A8_UNORM;
-				case GL_RED_INTEGER:			return VK_FORMAT_R8_UINT;
-				case GL_RG_INTEGER:				return VK_FORMAT_R8G8_UINT;
-				case GL_RGB_INTEGER:			return VK_FORMAT_R8G8B8_UINT;
-				case GL_BGR_INTEGER:			return VK_FORMAT_B8G8R8_UINT;
-				case GL_RGBA_INTEGER:			return VK_FORMAT_R8G8B8A8_UINT;
-				case GL_BGRA_INTEGER:			return VK_FORMAT_B8G8R8A8_UINT;
-				case GL_STENCIL_INDEX:			return VK_FORMAT_S8_UINT;
-				case GL_DEPTH_COMPONENT:		return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_STENCIL:			return VK_FORMAT_UNDEFINED;
-			}
-			break;
-		}
-		case GL_BYTE:
-		{
-			switch ( format )
-			{
-				case GL_RED:					return VK_FORMAT_R8_SNORM;
-				case GL_RG:						return VK_FORMAT_R8G8_SNORM;
-				case GL_RGB:					return VK_FORMAT_R8G8B8_SNORM;
-				case GL_BGR:					return VK_FORMAT_B8G8R8_SNORM;
-				case GL_RGBA:					return VK_FORMAT_R8G8B8A8_SNORM;
-				case GL_BGRA:					return VK_FORMAT_B8G8R8A8_SNORM;
-				case GL_RED_INTEGER:			return VK_FORMAT_R8_SINT;
-				case GL_RG_INTEGER:				return VK_FORMAT_R8G8_SINT;
-				case GL_RGB_INTEGER:			return VK_FORMAT_R8G8B8_SINT;
-				case GL_BGR_INTEGER:			return VK_FORMAT_B8G8R8_SINT;
-				case GL_RGBA_INTEGER:			return VK_FORMAT_R8G8B8A8_SINT;
-				case GL_BGRA_INTEGER:			return VK_FORMAT_B8G8R8A8_SINT;
-				case GL_STENCIL_INDEX:			return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_COMPONENT:		return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_STENCIL:			return VK_FORMAT_UNDEFINED;
-			}
-			break;
-		}
-
-		//
-		// 16 bits per component
-		//
-		case GL_UNSIGNED_SHORT:
-		{
-			switch ( format )
-			{
-				case GL_RED:					return VK_FORMAT_R16_UNORM;
-				case GL_RG:						return VK_FORMAT_R16G16_UNORM;
-				case GL_RGB:					return VK_FORMAT_R16G16B16_UNORM;
-				case GL_BGR:					return VK_FORMAT_UNDEFINED;
-				case GL_RGBA:					return VK_FORMAT_R16G16B16A16_UNORM;
-				case GL_BGRA:					return VK_FORMAT_UNDEFINED;
-				case GL_RED_INTEGER:			return VK_FORMAT_R16_UINT;
-				case GL_RG_INTEGER:				return VK_FORMAT_R16G16_UINT;
-				case GL_RGB_INTEGER:			return VK_FORMAT_R16G16B16_UINT;
-				case GL_BGR_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_RGBA_INTEGER:			return VK_FORMAT_R16G16B16A16_UINT;
-				case GL_BGRA_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_STENCIL_INDEX:			return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_COMPONENT:		return VK_FORMAT_D16_UNORM;
-				case GL_DEPTH_STENCIL:			return VK_FORMAT_D16_UNORM_S8_UINT;
-			}
-			break;
-		}
-		case GL_SHORT:
-		{
-			switch ( format )
-			{
-				case GL_RED:					return VK_FORMAT_R16_SNORM;
-				case GL_RG:						return VK_FORMAT_R16G16_SNORM;
-				case GL_RGB:					return VK_FORMAT_R16G16B16_SNORM;
-				case GL_BGR:					return VK_FORMAT_UNDEFINED;
-				case GL_RGBA:					return VK_FORMAT_R16G16B16A16_SNORM;
-				case GL_BGRA:					return VK_FORMAT_UNDEFINED;
-				case GL_RED_INTEGER:			return VK_FORMAT_R16_SINT;
-				case GL_RG_INTEGER:				return VK_FORMAT_R16G16_SINT;
-				case GL_RGB_INTEGER:			return VK_FORMAT_R16G16B16_SINT;
-				case GL_BGR_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_RGBA_INTEGER:			return VK_FORMAT_R16G16B16A16_SINT;
-				case GL_BGRA_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_STENCIL_INDEX:			return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_COMPONENT:		return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_STENCIL:			return VK_FORMAT_UNDEFINED;
-			}
-			break;
-		}
-		case GL_HALF_FLOAT:
-		case GL_HALF_FLOAT_OES:
-		{
-			switch ( format )
-			{
-				case GL_RED:					return VK_FORMAT_R16_SFLOAT;
-				case GL_RG:						return VK_FORMAT_R16G16_SFLOAT;
-				case GL_RGB:					return VK_FORMAT_R16G16B16_SFLOAT;
-				case GL_BGR:					return VK_FORMAT_UNDEFINED;
-				case GL_RGBA:					return VK_FORMAT_R16G16B16A16_SFLOAT;
-				case GL_BGRA:					return VK_FORMAT_UNDEFINED;
-				case GL_RED_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_RG_INTEGER:				return VK_FORMAT_UNDEFINED;
-				case GL_RGB_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_BGR_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_RGBA_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_BGRA_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_STENCIL_INDEX:			return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_COMPONENT:		return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_STENCIL:			return VK_FORMAT_UNDEFINED;
-			}
-			break;
-		}
-
-		//
-		// 32 bits per component
-		//
-		case GL_UNSIGNED_INT:
-		{
-			switch ( format )
-			{
-				case GL_RED:					return VK_FORMAT_R32_UINT;
-				case GL_RG:						return VK_FORMAT_R32G32_UINT;
-				case GL_RGB:					return VK_FORMAT_R32G32B32_UINT;
-				case GL_BGR:					return VK_FORMAT_UNDEFINED;
-				case GL_RGBA:					return VK_FORMAT_R32G32B32A32_UINT;
-				case GL_BGRA:					return VK_FORMAT_UNDEFINED;
-				case GL_RED_INTEGER:			return VK_FORMAT_R32_UINT;
-				case GL_RG_INTEGER:				return VK_FORMAT_R32G32_UINT;
-				case GL_RGB_INTEGER:			return VK_FORMAT_R32G32B32_UINT;
-				case GL_BGR_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_RGBA_INTEGER:			return VK_FORMAT_R32G32B32A32_UINT;
-				case GL_BGRA_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_STENCIL_INDEX:			return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_COMPONENT:		return VK_FORMAT_X8_D24_UNORM_PACK32;
-				case GL_DEPTH_STENCIL:			return VK_FORMAT_D24_UNORM_S8_UINT;
-			}
-			break;
-		}
-		case GL_INT:
-		{
-			switch ( format )
-			{
-				case GL_RED:					return VK_FORMAT_R32_SINT;
-				case GL_RG:						return VK_FORMAT_R32G32_SINT;
-				case GL_RGB:					return VK_FORMAT_R32G32B32_SINT;
-				case GL_BGR:					return VK_FORMAT_UNDEFINED;
-				case GL_RGBA:					return VK_FORMAT_R32G32B32A32_SINT;
-				case GL_BGRA:					return VK_FORMAT_UNDEFINED;
-				case GL_RED_INTEGER:			return VK_FORMAT_R32_SINT;
-				case GL_RG_INTEGER:				return VK_FORMAT_R32G32_SINT;
-				case GL_RGB_INTEGER:			return VK_FORMAT_R32G32B32_SINT;
-				case GL_BGR_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_RGBA_INTEGER:			return VK_FORMAT_R32G32B32A32_SINT;
-				case GL_BGRA_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_STENCIL_INDEX:			return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_COMPONENT:		return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_STENCIL:			return VK_FORMAT_UNDEFINED;
-			}
-			break;
-		}
-		case GL_FLOAT:
-		{
-			switch ( format )
-			{
-				case GL_RED:					return VK_FORMAT_R32_SFLOAT;
-				case GL_RG:						return VK_FORMAT_R32G32_SFLOAT;
-				case GL_RGB:					return VK_FORMAT_R32G32B32_SFLOAT;
-				case GL_BGR:					return VK_FORMAT_UNDEFINED;
-				case GL_RGBA:					return VK_FORMAT_R32G32B32A32_SFLOAT;
-				case GL_BGRA:					return VK_FORMAT_UNDEFINED;
-				case GL_RED_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_RG_INTEGER:				return VK_FORMAT_UNDEFINED;
-				case GL_RGB_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_BGR_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_RGBA_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_BGRA_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_STENCIL_INDEX:			return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_COMPONENT:		return VK_FORMAT_D32_SFLOAT;
-				case GL_DEPTH_STENCIL:			return VK_FORMAT_D32_SFLOAT_S8_UINT;
-			}
-			break;
-		}
-
-		//
-		// 64 bits per component
-		//
-		case GL_UNSIGNED_INT64:
-		{
-			switch ( format )
-			{
-				case GL_RED:					return VK_FORMAT_R64_UINT;
-				case GL_RG:						return VK_FORMAT_R64G64_UINT;
-				case GL_RGB:					return VK_FORMAT_R64G64B64_UINT;
-				case GL_BGR:					return VK_FORMAT_UNDEFINED;
-				case GL_RGBA:					return VK_FORMAT_R64G64B64A64_UINT;
-				case GL_BGRA:					return VK_FORMAT_UNDEFINED;
-				case GL_RED_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_RG_INTEGER:				return VK_FORMAT_UNDEFINED;
-				case GL_RGB_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_BGR_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_RGBA_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_BGRA_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_STENCIL_INDEX:			return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_COMPONENT:		return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_STENCIL:			return VK_FORMAT_UNDEFINED;
-			}
-			break;
-		}
-		case GL_INT64:
-		{
-			switch ( format )
-			{
-				case GL_RED:					return VK_FORMAT_R64_SINT;
-				case GL_RG:						return VK_FORMAT_R64G64_SINT;
-				case GL_RGB:					return VK_FORMAT_R64G64B64_SINT;
-				case GL_BGR:					return VK_FORMAT_UNDEFINED;
-				case GL_RGBA:					return VK_FORMAT_R64G64B64A64_SINT;
-				case GL_BGRA:					return VK_FORMAT_UNDEFINED;
-				case GL_RED_INTEGER:			return VK_FORMAT_R64_SINT;
-				case GL_RG_INTEGER:				return VK_FORMAT_R64G64_SINT;
-				case GL_RGB_INTEGER:			return VK_FORMAT_R64G64B64_SINT;
-				case GL_BGR_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_RGBA_INTEGER:			return VK_FORMAT_R64G64B64A64_SINT;
-				case GL_BGRA_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_STENCIL_INDEX:			return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_COMPONENT:		return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_STENCIL:			return VK_FORMAT_UNDEFINED;
-			}
-			break;
-		}
-		case GL_DOUBLE:
-		{
-			switch ( format )
-			{
-				case GL_RED:					return VK_FORMAT_R64_SFLOAT;
-				case GL_RG:						return VK_FORMAT_R64G64_SFLOAT;
-				case GL_RGB:					return VK_FORMAT_R64G64B64_SFLOAT;
-				case GL_BGR:					return VK_FORMAT_UNDEFINED;
-				case GL_RGBA:					return VK_FORMAT_R64G64B64A64_SFLOAT;
-				case GL_BGRA:					return VK_FORMAT_UNDEFINED;
-				case GL_RED_INTEGER:			return VK_FORMAT_R64_SFLOAT;
-				case GL_RG_INTEGER:				return VK_FORMAT_R64G64_SFLOAT;
-				case GL_RGB_INTEGER:			return VK_FORMAT_R64G64B64_SFLOAT;
-				case GL_BGR_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_RGBA_INTEGER:			return VK_FORMAT_R64G64B64A64_SFLOAT;
-				case GL_BGRA_INTEGER:			return VK_FORMAT_UNDEFINED;
-				case GL_STENCIL_INDEX:			return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_COMPONENT:		return VK_FORMAT_UNDEFINED;
-				case GL_DEPTH_STENCIL:			return VK_FORMAT_UNDEFINED;
-			}
-			break;
-		}
-
-		//
-		// Packed
-		//
-		case GL_UNSIGNED_BYTE_3_3_2:
-			assert( format == GL_RGB || format == GL_RGB_INTEGER );
-			return VK_FORMAT_UNDEFINED;
-		case GL_UNSIGNED_BYTE_2_3_3_REV:
-			assert( format == GL_BGR || format == GL_BGR_INTEGER );
-			return VK_FORMAT_UNDEFINED;
-		case GL_UNSIGNED_SHORT_5_6_5:
-			assert( format == GL_RGB || format == GL_RGB_INTEGER );
-			return VK_FORMAT_R5G6B5_UNORM_PACK16;
-		case GL_UNSIGNED_SHORT_5_6_5_REV:
-			assert( format == GL_BGR || format == GL_BGR_INTEGER );
-			return VK_FORMAT_B5G6R5_UNORM_PACK16;
-		case GL_UNSIGNED_SHORT_4_4_4_4:
-			assert( format == GL_RGB || format == GL_BGRA || format == GL_RGB_INTEGER || format == GL_BGRA_INTEGER );
-			return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
-		case GL_UNSIGNED_SHORT_4_4_4_4_REV:
-			assert( format == GL_RGB || format == GL_BGRA || format == GL_RGB_INTEGER || format == GL_BGRA_INTEGER );
-			return VK_FORMAT_B4G4R4A4_UNORM_PACK16;
-		case GL_UNSIGNED_SHORT_5_5_5_1:
-			assert( format == GL_RGB || format == GL_BGRA || format == GL_RGB_INTEGER || format == GL_BGRA_INTEGER );
-			return VK_FORMAT_R5G5B5A1_UNORM_PACK16;
-		case GL_UNSIGNED_SHORT_1_5_5_5_REV:
-			assert( format == GL_RGB || format == GL_BGRA || format == GL_RGB_INTEGER || format == GL_BGRA_INTEGER );
-			return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
-		case GL_UNSIGNED_INT_8_8_8_8:
-			assert( format == GL_RGB || format == GL_BGRA || format == GL_RGB_INTEGER || format == GL_BGRA_INTEGER );
-			return ( format == GL_RGB_INTEGER || format == GL_BGRA_INTEGER ) ? VK_FORMAT_R8G8B8A8_UINT : VK_FORMAT_R8G8B8A8_UNORM;
-		case GL_UNSIGNED_INT_8_8_8_8_REV:
-			assert( format == GL_RGB || format == GL_BGRA || format == GL_RGB_INTEGER || format == GL_BGRA_INTEGER );
-			return ( format == GL_RGB_INTEGER || format == GL_BGRA_INTEGER ) ? VK_FORMAT_A8B8G8R8_UINT_PACK32 : VK_FORMAT_A8B8G8R8_UNORM_PACK32;
-		case GL_UNSIGNED_INT_10_10_10_2:
-			assert( format == GL_RGB || format == GL_BGRA || format == GL_RGB_INTEGER || format == GL_BGRA_INTEGER );
-			return ( format == GL_RGB_INTEGER || format == GL_BGRA_INTEGER ) ? VK_FORMAT_A2R10G10B10_UINT_PACK32 : VK_FORMAT_A2R10G10B10_UNORM_PACK32;
-		case GL_UNSIGNED_INT_2_10_10_10_REV:
-			assert( format == GL_RGB || format == GL_BGRA || format == GL_RGB_INTEGER || format == GL_BGRA_INTEGER );
-			return ( format == GL_RGB_INTEGER || format == GL_BGRA_INTEGER ) ? VK_FORMAT_A2B10G10R10_UINT_PACK32 : VK_FORMAT_A2B10G10R10_UNORM_PACK32;
-		case GL_UNSIGNED_INT_10F_11F_11F_REV:
-			assert( format == GL_RGB || format == GL_BGR );
-			return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
-		case GL_UNSIGNED_INT_5_9_9_9_REV:
-			assert( format == GL_RGB || format == GL_BGR );
-			return VK_FORMAT_E5B9G9R9_UFLOAT_PACK32;
-		case GL_UNSIGNED_INT_24_8:
-			assert( format == GL_DEPTH_STENCIL );
-			return VK_FORMAT_D24_UNORM_S8_UINT;
-		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
-			assert( format == GL_DEPTH_STENCIL );
-			return VK_FORMAT_D32_SFLOAT_S8_UINT;
-	}
-
-	return VK_FORMAT_UNDEFINED;
-}
-
-static inline VkFormat vkGetFormatFromOpenGLType( const GLenum type, const GLuint numComponents, const GLboolean normalized )
-{
-	switch ( type )
-	{
-		//
-		// 8 bits per component
-		//
-		case GL_UNSIGNED_BYTE:
-		{
-			switch ( numComponents )
-			{
-				case 1:							return normalized ? VK_FORMAT_R8_UNORM : VK_FORMAT_R8_UINT;
-				case 2:							return normalized ? VK_FORMAT_R8G8_UNORM : VK_FORMAT_R8G8_UINT;
-				case 3:							return normalized ? VK_FORMAT_R8G8B8_UNORM : VK_FORMAT_R8G8B8_UINT;
-				case 4:							return normalized ? VK_FORMAT_R8G8B8A8_UNORM : VK_FORMAT_R8G8B8A8_UINT;
-			}
-			break;
-		}
-		case GL_BYTE:
-		{
-			switch ( numComponents )
-			{
-				case 1:							return normalized ? VK_FORMAT_R8_SNORM : VK_FORMAT_R8_SINT;
-				case 2:							return normalized ? VK_FORMAT_R8G8_SNORM : VK_FORMAT_R8G8_SINT;
-				case 3:							return normalized ? VK_FORMAT_R8G8B8_SNORM : VK_FORMAT_R8G8B8_SINT;
-				case 4:							return normalized ? VK_FORMAT_R8G8B8A8_SNORM : VK_FORMAT_R8G8B8A8_SINT;
-			}
-			break;
-		}
-
-		//
-		// 16 bits per component
-		//
-		case GL_UNSIGNED_SHORT:
-		{
-			switch ( numComponents )
-			{
-				case 1:							return normalized ? VK_FORMAT_R16_UNORM : VK_FORMAT_R16_UINT;
-				case 2:							return normalized ? VK_FORMAT_R16G16_UNORM : VK_FORMAT_R16G16_UINT;
-				case 3:							return normalized ? VK_FORMAT_R16G16B16_UNORM : VK_FORMAT_R16G16B16_UINT;
-				case 4:							return normalized ? VK_FORMAT_R16G16B16A16_UNORM : VK_FORMAT_R16G16B16A16_UINT;
-			}
-			break;
-		}
-		case GL_SHORT:
-		{
-			switch ( numComponents )
-			{
-				case 1:							return normalized ? VK_FORMAT_R16_SNORM : VK_FORMAT_R16_SINT;
-				case 2:							return normalized ? VK_FORMAT_R16G16_SNORM : VK_FORMAT_R16G16_SINT;
-				case 3:							return normalized ? VK_FORMAT_R16G16B16_SNORM : VK_FORMAT_R16G16B16_SINT;
-				case 4:							return normalized ? VK_FORMAT_R16G16B16A16_SNORM : VK_FORMAT_R16G16B16A16_SINT;
-			}
-			break;
-		}
-		case GL_HALF_FLOAT:
-		case GL_HALF_FLOAT_OES:
-		{
-			switch ( numComponents )
-			{
-				case 1:							return VK_FORMAT_R16_SFLOAT;
-				case 2:							return VK_FORMAT_R16G16_SFLOAT;
-				case 3:							return VK_FORMAT_R16G16B16_SFLOAT;
-				case 4:							return VK_FORMAT_R16G16B16A16_SFLOAT;
-			}
-			break;
-		}
-
-		//
-		// 32 bits per component
-		//
-		case GL_UNSIGNED_INT:
-		{
-			switch ( numComponents )
-			{
-				case 1:							return VK_FORMAT_R32_UINT;
-				case 2:							return VK_FORMAT_R32G32_UINT;
-				case 3:							return VK_FORMAT_R32G32B32_UINT;
-				case 4:							return VK_FORMAT_R32G32B32A32_UINT;
-			}
-			break;
-		}
-		case GL_INT:
-		{
-			switch ( numComponents )
-			{
-				case 1:							return VK_FORMAT_R32_SINT;
-				case 2:							return VK_FORMAT_R32G32_SINT;
-				case 3:							return VK_FORMAT_R32G32B32_SINT;
-				case 4:							return VK_FORMAT_R32G32B32A32_SINT;
-			}
-			break;
-		}
-		case GL_FLOAT:
-		{
-			switch ( numComponents )
-			{
-				case 1:							return VK_FORMAT_R32_SFLOAT;
-				case 2:							return VK_FORMAT_R32G32_SFLOAT;
-				case 3:							return VK_FORMAT_R32G32B32_SFLOAT;
-				case 4:							return VK_FORMAT_R32G32B32A32_SFLOAT;
-			}
-			break;
-		}
-
-		//
-		// 64 bits per component
-		//
-		case GL_UNSIGNED_INT64:
-		{
-			switch ( numComponents )
-			{
-				case 1:							return VK_FORMAT_R64_UINT;
-				case 2:							return VK_FORMAT_R64G64_UINT;
-				case 3:							return VK_FORMAT_R64G64B64_UINT;
-				case 4:							return VK_FORMAT_R64G64B64A64_UINT;
-			}
-			break;
-		}
-		case GL_INT64:
-		{
-			switch ( numComponents )
-			{
-				case 1:							return VK_FORMAT_R64_SINT;
-				case 2:							return VK_FORMAT_R64G64_SINT;
-				case 3:							return VK_FORMAT_R64G64B64_SINT;
-				case 4:							return VK_FORMAT_R64G64B64A64_SINT;
-			}
-			break;
-		}
-		case GL_DOUBLE:
-		{
-			switch ( numComponents )
-			{
-				case 1:							return VK_FORMAT_R64_SFLOAT;
-				case 2:							return VK_FORMAT_R64G64_SFLOAT;
-				case 3:							return VK_FORMAT_R64G64B64_SFLOAT;
-				case 4:							return VK_FORMAT_R64G64B64A64_SFLOAT;
-			}
-			break;
-		}
-
-		//
-		// Packed
-		//
-		case GL_UNSIGNED_BYTE_3_3_2:			return VK_FORMAT_UNDEFINED;
-		case GL_UNSIGNED_BYTE_2_3_3_REV:		return VK_FORMAT_UNDEFINED;
-		case GL_UNSIGNED_SHORT_5_6_5:			return VK_FORMAT_R5G6B5_UNORM_PACK16;
-		case GL_UNSIGNED_SHORT_5_6_5_REV:		return VK_FORMAT_B5G6R5_UNORM_PACK16;
-		case GL_UNSIGNED_SHORT_4_4_4_4:			return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
-		case GL_UNSIGNED_SHORT_4_4_4_4_REV:		return VK_FORMAT_B4G4R4A4_UNORM_PACK16;
-		case GL_UNSIGNED_SHORT_5_5_5_1:			return VK_FORMAT_R5G5B5A1_UNORM_PACK16;
-		case GL_UNSIGNED_SHORT_1_5_5_5_REV:		return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
-		case GL_UNSIGNED_INT_8_8_8_8:			return normalized ? VK_FORMAT_R8G8B8A8_UNORM : VK_FORMAT_R8G8B8A8_UINT;
-		case GL_UNSIGNED_INT_8_8_8_8_REV:		return normalized ? VK_FORMAT_A8B8G8R8_UNORM_PACK32 : VK_FORMAT_A8B8G8R8_UINT_PACK32;
-		case GL_UNSIGNED_INT_10_10_10_2:		return normalized ? VK_FORMAT_A2R10G10B10_UNORM_PACK32 : VK_FORMAT_A2R10G10B10_UINT_PACK32;
-		case GL_UNSIGNED_INT_2_10_10_10_REV:	return normalized ? VK_FORMAT_A2B10G10R10_UNORM_PACK32 : VK_FORMAT_A2B10G10R10_UINT_PACK32;
-		case GL_UNSIGNED_INT_10F_11F_11F_REV:	return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
-		case GL_UNSIGNED_INT_5_9_9_9_REV:		return VK_FORMAT_E5B9G9R9_UFLOAT_PACK32;
-		case GL_UNSIGNED_INT_24_8:				return VK_FORMAT_D24_UNORM_S8_UINT;
-		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:	return VK_FORMAT_D32_SFLOAT_S8_UINT;
-	}
-
-	return VK_FORMAT_UNDEFINED;
-}
-
-static inline VkFormat vkGetFormatFromOpenGLInternalFormat( const GLenum internalFormat )
-{
-	switch ( internalFormat )
-	{
-		//
-		// 8 bits per component
-		//
-		case GL_R8:												return VK_FORMAT_R8_UNORM;					// 1-component, 8-bit unsigned normalized
-		case GL_RG8:											return VK_FORMAT_R8G8_UNORM;				// 2-component, 8-bit unsigned normalized
-		case GL_RGB8:											return VK_FORMAT_R8G8B8_UNORM;				// 3-component, 8-bit unsigned normalized
-		case GL_RGBA8:											return VK_FORMAT_R8G8B8A8_UNORM;			// 4-component, 8-bit unsigned normalized
-
-		case GL_R8_SNORM:										return VK_FORMAT_R8_SNORM;					// 1-component, 8-bit signed normalized
-		case GL_RG8_SNORM:										return VK_FORMAT_R8G8_SNORM;				// 2-component, 8-bit signed normalized
-		case GL_RGB8_SNORM:										return VK_FORMAT_R8G8B8_SNORM;				// 3-component, 8-bit signed normalized
-		case GL_RGBA8_SNORM:									return VK_FORMAT_R8G8B8A8_SNORM;			// 4-component, 8-bit signed normalized
-
-		case GL_R8UI:											return VK_FORMAT_R8_UINT;					// 1-component, 8-bit unsigned integer
-		case GL_RG8UI:											return VK_FORMAT_R8G8_UINT;					// 2-component, 8-bit unsigned integer
-		case GL_RGB8UI:											return VK_FORMAT_R8G8B8_UINT;				// 3-component, 8-bit unsigned integer
-		case GL_RGBA8UI:										return VK_FORMAT_R8G8B8A8_UINT;				// 4-component, 8-bit unsigned integer
-
-		case GL_R8I:											return VK_FORMAT_R8_SINT;					// 1-component, 8-bit signed integer
-		case GL_RG8I:											return VK_FORMAT_R8G8_SINT;					// 2-component, 8-bit signed integer
-		case GL_RGB8I:											return VK_FORMAT_R8G8B8_SINT;				// 3-component, 8-bit signed integer
-		case GL_RGBA8I:											return VK_FORMAT_R8G8B8A8_SINT;				// 4-component, 8-bit signed integer
-
-		case GL_SR8:											return VK_FORMAT_R8_SRGB;					// 1-component, 8-bit sRGB
-		case GL_SRG8:											return VK_FORMAT_R8G8_SRGB;					// 2-component, 8-bit sRGB
-		case GL_SRGB8:											return VK_FORMAT_R8G8B8_SRGB;				// 3-component, 8-bit sRGB
-		case GL_SRGB8_ALPHA8:									return VK_FORMAT_R8G8B8A8_SRGB;				// 4-component, 8-bit sRGB
-
-		//
-		// 16 bits per component
-		//
-		case GL_R16:											return VK_FORMAT_R16_UNORM;					// 1-component, 16-bit unsigned normalized
-		case GL_RG16:											return VK_FORMAT_R16G16_UNORM;				// 2-component, 16-bit unsigned normalized
-		case GL_RGB16:											return VK_FORMAT_R16G16B16_UNORM;			// 3-component, 16-bit unsigned normalized
-		case GL_RGBA16:											return VK_FORMAT_R16G16B16A16_UNORM;		// 4-component, 16-bit unsigned normalized
-
-		case GL_R16_SNORM:										return VK_FORMAT_R16_SNORM;					// 1-component, 16-bit signed normalized
-		case GL_RG16_SNORM:										return VK_FORMAT_R16G16_SNORM;				// 2-component, 16-bit signed normalized
-		case GL_RGB16_SNORM:									return VK_FORMAT_R16G16B16_SNORM;			// 3-component, 16-bit signed normalized
-		case GL_RGBA16_SNORM:									return VK_FORMAT_R16G16B16A16_SNORM;		// 4-component, 16-bit signed normalized
-
-		case GL_R16UI:											return VK_FORMAT_R16_UINT;					// 1-component, 16-bit unsigned integer
-		case GL_RG16UI:											return VK_FORMAT_R16G16_UINT;				// 2-component, 16-bit unsigned integer
-		case GL_RGB16UI:										return VK_FORMAT_R16G16B16_UINT;			// 3-component, 16-bit unsigned integer
-		case GL_RGBA16UI:										return VK_FORMAT_R16G16B16A16_UINT;			// 4-component, 16-bit unsigned integer
-
-		case GL_R16I:											return VK_FORMAT_R16_SINT;					// 1-component, 16-bit signed integer
-		case GL_RG16I:											return VK_FORMAT_R16G16_SINT;				// 2-component, 16-bit signed integer
-		case GL_RGB16I:											return VK_FORMAT_R16G16B16_SINT;			// 3-component, 16-bit signed integer
-		case GL_RGBA16I:										return VK_FORMAT_R16G16B16A16_SINT;			// 4-component, 16-bit signed integer
-
-		case GL_R16F:											return VK_FORMAT_R16_SFLOAT;				// 1-component, 16-bit floating-point
-		case GL_RG16F:											return VK_FORMAT_R16G16_SFLOAT;				// 2-component, 16-bit floating-point
-		case GL_RGB16F:											return VK_FORMAT_R16G16B16_SFLOAT;			// 3-component, 16-bit floating-point
-		case GL_RGBA16F:										return VK_FORMAT_R16G16B16A16_SFLOAT;		// 4-component, 16-bit floating-point
-
-		//
-		// 32 bits per component
-		//
-		case GL_R32UI:											return VK_FORMAT_R32_UINT;					// 1-component, 32-bit unsigned integer
-		case GL_RG32UI:											return VK_FORMAT_R32G32_UINT;				// 2-component, 32-bit unsigned integer
-		case GL_RGB32UI:										return VK_FORMAT_R32G32B32_UINT;			// 3-component, 32-bit unsigned integer
-		case GL_RGBA32UI:										return VK_FORMAT_R32G32B32A32_UINT;			// 4-component, 32-bit unsigned integer
-
-		case GL_R32I:											return VK_FORMAT_R32_SINT;					// 1-component, 32-bit signed integer
-		case GL_RG32I:											return VK_FORMAT_R32G32_SINT;				// 2-component, 32-bit signed integer
-		case GL_RGB32I:											return VK_FORMAT_R32G32B32_SINT;			// 3-component, 32-bit signed integer
-		case GL_RGBA32I:										return VK_FORMAT_R32G32B32A32_SINT;			// 4-component, 32-bit signed integer
-
-		case GL_R32F:											return VK_FORMAT_R32_SFLOAT;				// 1-component, 32-bit floating-point
-		case GL_RG32F:											return VK_FORMAT_R32G32_SFLOAT;				// 2-component, 32-bit floating-point
-		case GL_RGB32F:											return VK_FORMAT_R32G32B32_SFLOAT;			// 3-component, 32-bit floating-point
-		case GL_RGBA32F:										return VK_FORMAT_R32G32B32A32_SFLOAT;		// 4-component, 32-bit floating-point
-
-		//
-		// Packed
-		//
-		case GL_R3_G3_B2:										return VK_FORMAT_UNDEFINED;					// 3-component 3:3:2,       unsigned normalized
-		case GL_RGB4:											return VK_FORMAT_UNDEFINED;					// 3-component 4:4:4,       unsigned normalized
-		case GL_RGB5:											return VK_FORMAT_R5G5B5A1_UNORM_PACK16;		// 3-component 5:5:5,       unsigned normalized
-		case GL_RGB565:											return VK_FORMAT_R5G6B5_UNORM_PACK16;		// 3-component 5:6:5,       unsigned normalized
-		case GL_RGB10:											return VK_FORMAT_A2R10G10B10_UNORM_PACK32;	// 3-component 10:10:10,    unsigned normalized
-		case GL_RGB12:											return VK_FORMAT_UNDEFINED;					// 3-component 12:12:12,    unsigned normalized
-		case GL_RGBA2:											return VK_FORMAT_UNDEFINED;					// 4-component 2:2:2:2,     unsigned normalized
-		case GL_RGBA4:											return VK_FORMAT_R4G4B4A4_UNORM_PACK16;		// 4-component 4:4:4:4,     unsigned normalized
-		case GL_RGBA12:											return VK_FORMAT_UNDEFINED;					// 4-component 12:12:12:12, unsigned normalized
-		case GL_RGB5_A1:										return VK_FORMAT_A1R5G5B5_UNORM_PACK16;		// 4-component 5:5:5:1,     unsigned normalized
-		case GL_RGB10_A2:										return VK_FORMAT_A2R10G10B10_UNORM_PACK32;	// 4-component 10:10:10:2,  unsigned normalized
-		case GL_RGB10_A2UI:										return VK_FORMAT_A2R10G10B10_UINT_PACK32;	// 4-component 10:10:10:2,  unsigned integer
-		case GL_R11F_G11F_B10F:									return VK_FORMAT_B10G11R11_UFLOAT_PACK32;	// 3-component 11:11:10,    floating-point
-		case GL_RGB9_E5:										return VK_FORMAT_E5B9G9R9_UFLOAT_PACK32;	// 3-component/exp 9:9:9/5, floating-point
-
-		//
-		// S3TC/DXT/BC
-		//
-
-		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:					return VK_FORMAT_BC1_RGB_UNORM_BLOCK;		// line through 3D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:					return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;		// line through 3D space plus 1-bit alpha, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:					return VK_FORMAT_BC2_UNORM_BLOCK;			// line through 3D space plus line through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:					return VK_FORMAT_BC3_UNORM_BLOCK;			// line through 3D space plus 4-bit alpha, 4x4 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:					return VK_FORMAT_BC1_RGB_SRGB_BLOCK;		// line through 3D space, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:			return VK_FORMAT_BC1_RGBA_SRGB_BLOCK;		// line through 3D space plus 1-bit alpha, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:			return VK_FORMAT_BC2_SRGB_BLOCK;			// line through 3D space plus line through 1D space, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:			return VK_FORMAT_BC3_SRGB_BLOCK;			// line through 3D space plus 4-bit alpha, 4x4 blocks, sRGB
-
-		case GL_COMPRESSED_LUMINANCE_LATC1_EXT:					return VK_FORMAT_BC4_UNORM_BLOCK;			// line through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:			return VK_FORMAT_BC5_UNORM_BLOCK;			// two lines through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:			return VK_FORMAT_BC4_SNORM_BLOCK;			// line through 1D space, 4x4 blocks, signed normalized
-		case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:	return VK_FORMAT_BC5_SNORM_BLOCK;			// two lines through 1D space, 4x4 blocks, signed normalized
-
-		case GL_COMPRESSED_RED_RGTC1:							return VK_FORMAT_BC4_UNORM_BLOCK;			// line through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RG_RGTC2:							return VK_FORMAT_BC5_UNORM_BLOCK;			// two lines through 1D space, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_RED_RGTC1:					return VK_FORMAT_BC4_SNORM_BLOCK;			// line through 1D space, 4x4 blocks, signed normalized
-		case GL_COMPRESSED_SIGNED_RG_RGTC2:						return VK_FORMAT_BC5_SNORM_BLOCK;			// two lines through 1D space, 4x4 blocks, signed normalized
-
-		case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:				return VK_FORMAT_BC6H_UFLOAT_BLOCK;			// 3-component, 4x4 blocks, unsigned floating-point
-		case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:				return VK_FORMAT_BC6H_SFLOAT_BLOCK;			// 3-component, 4x4 blocks, signed floating-point
-		case GL_COMPRESSED_RGBA_BPTC_UNORM:						return VK_FORMAT_BC7_UNORM_BLOCK;			// 4-component, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:				return VK_FORMAT_BC7_SRGB_BLOCK;			// 4-component, 4x4 blocks, sRGB
-
-		//
-		// ETC
-		//
-		case GL_ETC1_RGB8_OES:									return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;	// 3-component ETC1, 4x4 blocks, unsigned normalized
-
-		case GL_COMPRESSED_RGB8_ETC2:							return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;	// 3-component ETC2, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:		return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;	// 4-component ETC2 with 1-bit alpha, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA8_ETC2_EAC:						return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;	// 4-component ETC2, 4x4 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB8_ETC2:							return VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;	// 3-component ETC2, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:		return VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;	// 4-component ETC2 with 1-bit alpha, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:				return VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;	// 4-component ETC2, 4x4 blocks, sRGB
-
-		case GL_COMPRESSED_R11_EAC:								return VK_FORMAT_EAC_R11_UNORM_BLOCK;		// 1-component ETC, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RG11_EAC:							return VK_FORMAT_EAC_R11G11_UNORM_BLOCK;	// 2-component ETC, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_SIGNED_R11_EAC:						return VK_FORMAT_EAC_R11_SNORM_BLOCK;		// 1-component ETC, 4x4 blocks, signed normalized
-		case GL_COMPRESSED_SIGNED_RG11_EAC:						return VK_FORMAT_EAC_R11G11_SNORM_BLOCK;	// 2-component ETC, 4x4 blocks, signed normalized
-
-		//
-		// PVRTC
-		//
-		case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:				return VK_FORMAT_UNDEFINED;					// 3-component PVRTC, 16x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:				return VK_FORMAT_UNDEFINED;					// 3-component PVRTC,  8x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:				return VK_FORMAT_UNDEFINED;					// 4-component PVRTC, 16x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:				return VK_FORMAT_UNDEFINED;					// 4-component PVRTC,  8x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG:				return VK_FORMAT_UNDEFINED;					// 4-component PVRTC,  8x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG:				return VK_FORMAT_UNDEFINED;					// 4-component PVRTC,  4x4 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:				return VK_FORMAT_UNDEFINED;					// 3-component PVRTC, 16x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:				return VK_FORMAT_UNDEFINED;					// 3-component PVRTC,  8x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:			return VK_FORMAT_UNDEFINED;					// 4-component PVRTC, 16x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:			return VK_FORMAT_UNDEFINED;					// 4-component PVRTC,  8x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG:			return VK_FORMAT_UNDEFINED;					// 4-component PVRTC,  8x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG:			return VK_FORMAT_UNDEFINED;					// 4-component PVRTC,  4x4 blocks, sRGB
-
-		//
-		// ASTC
-		//
-		case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:					return VK_FORMAT_ASTC_4x4_UNORM_BLOCK;		// 4-component ASTC, 4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:					return VK_FORMAT_ASTC_5x4_UNORM_BLOCK;		// 4-component ASTC, 5x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:					return VK_FORMAT_ASTC_5x5_UNORM_BLOCK;		// 4-component ASTC, 5x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:					return VK_FORMAT_ASTC_6x5_UNORM_BLOCK;		// 4-component ASTC, 6x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:					return VK_FORMAT_ASTC_6x6_UNORM_BLOCK;		// 4-component ASTC, 6x6 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:					return VK_FORMAT_ASTC_8x5_UNORM_BLOCK;		// 4-component ASTC, 8x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:					return VK_FORMAT_ASTC_8x6_UNORM_BLOCK;		// 4-component ASTC, 8x6 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:					return VK_FORMAT_ASTC_8x8_UNORM_BLOCK;		// 4-component ASTC, 8x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:					return VK_FORMAT_ASTC_10x5_UNORM_BLOCK;		// 4-component ASTC, 10x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:					return VK_FORMAT_ASTC_10x6_UNORM_BLOCK;		// 4-component ASTC, 10x6 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:					return VK_FORMAT_ASTC_10x8_UNORM_BLOCK;		// 4-component ASTC, 10x8 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:					return VK_FORMAT_ASTC_10x10_UNORM_BLOCK;	// 4-component ASTC, 10x10 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:					return VK_FORMAT_ASTC_12x10_UNORM_BLOCK;	// 4-component ASTC, 12x10 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:					return VK_FORMAT_ASTC_12x12_UNORM_BLOCK;	// 4-component ASTC, 12x12 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:			return VK_FORMAT_ASTC_4x4_SRGB_BLOCK;		// 4-component ASTC, 4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:			return VK_FORMAT_ASTC_5x4_SRGB_BLOCK;		// 4-component ASTC, 5x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:			return VK_FORMAT_ASTC_5x5_SRGB_BLOCK;		// 4-component ASTC, 5x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:			return VK_FORMAT_ASTC_6x5_SRGB_BLOCK;		// 4-component ASTC, 6x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:			return VK_FORMAT_ASTC_6x6_SRGB_BLOCK;		// 4-component ASTC, 6x6 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:			return VK_FORMAT_ASTC_8x5_SRGB_BLOCK;		// 4-component ASTC, 8x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:			return VK_FORMAT_ASTC_8x6_SRGB_BLOCK;		// 4-component ASTC, 8x6 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:			return VK_FORMAT_ASTC_8x8_SRGB_BLOCK;		// 4-component ASTC, 8x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:			return VK_FORMAT_ASTC_10x5_SRGB_BLOCK;		// 4-component ASTC, 10x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:			return VK_FORMAT_ASTC_10x6_SRGB_BLOCK;		// 4-component ASTC, 10x6 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:			return VK_FORMAT_ASTC_10x8_SRGB_BLOCK;		// 4-component ASTC, 10x8 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:			return VK_FORMAT_ASTC_10x10_SRGB_BLOCK;		// 4-component ASTC, 10x10 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:			return VK_FORMAT_ASTC_12x10_SRGB_BLOCK;		// 4-component ASTC, 12x10 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:			return VK_FORMAT_ASTC_12x12_SRGB_BLOCK;		// 4-component ASTC, 12x12 blocks, sRGB
-
-		case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES:					return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 3x3x3 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES:					return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 4x3x3 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES:					return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 4x4x3 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES:					return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 4x4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES:					return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 5x4x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES:					return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 5x5x4 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES:					return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 5x5x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES:					return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 6x5x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES:					return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 6x6x5 blocks, unsigned normalized
-		case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES:					return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 6x6x6 blocks, unsigned normalized
-
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:			return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 3x3x3 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:			return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 4x3x3 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:			return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 4x4x3 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:			return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 4x4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:			return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 5x4x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:			return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 5x5x4 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:			return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 5x5x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:			return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 6x5x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:			return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 6x6x5 blocks, sRGB
-		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES:			return VK_FORMAT_UNDEFINED;					// 4-component ASTC, 6x6x6 blocks, sRGB
-
-		//
-		// ATC
-		//
-		case GL_ATC_RGB_AMD:									return VK_FORMAT_UNDEFINED;					// 3-component, 4x4 blocks, unsigned normalized
-		case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:					return VK_FORMAT_UNDEFINED;					// 4-component, 4x4 blocks, unsigned normalized
-		case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:				return VK_FORMAT_UNDEFINED;					// 4-component, 4x4 blocks, unsigned normalized
-
-		//
-		// Palletized
-		//
-		case GL_PALETTE4_RGB8_OES:								return VK_FORMAT_UNDEFINED;					// 3-component 8:8:8,   4-bit palette, unsigned normalized
-		case GL_PALETTE4_RGBA8_OES:								return VK_FORMAT_UNDEFINED;					// 4-component 8:8:8:8, 4-bit palette, unsigned normalized
-		case GL_PALETTE4_R5_G6_B5_OES:							return VK_FORMAT_UNDEFINED;					// 3-component 5:6:5,   4-bit palette, unsigned normalized
-		case GL_PALETTE4_RGBA4_OES:								return VK_FORMAT_UNDEFINED;					// 4-component 4:4:4:4, 4-bit palette, unsigned normalized
-		case GL_PALETTE4_RGB5_A1_OES:							return VK_FORMAT_UNDEFINED;					// 4-component 5:5:5:1, 4-bit palette, unsigned normalized
-		case GL_PALETTE8_RGB8_OES:								return VK_FORMAT_UNDEFINED;					// 3-component 8:8:8,   8-bit palette, unsigned normalized
-		case GL_PALETTE8_RGBA8_OES:								return VK_FORMAT_UNDEFINED;					// 4-component 8:8:8:8, 8-bit palette, unsigned normalized
-		case GL_PALETTE8_R5_G6_B5_OES:							return VK_FORMAT_UNDEFINED;					// 3-component 5:6:5,   8-bit palette, unsigned normalized
-		case GL_PALETTE8_RGBA4_OES:								return VK_FORMAT_UNDEFINED;					// 4-component 4:4:4:4, 8-bit palette, unsigned normalized
-		case GL_PALETTE8_RGB5_A1_OES:							return VK_FORMAT_UNDEFINED;					// 4-component 5:5:5:1, 8-bit palette, unsigned normalized
-
-		//
-		// Depth/stencil
-		//
-		case GL_DEPTH_COMPONENT16:								return VK_FORMAT_D16_UNORM;
-		case GL_DEPTH_COMPONENT24:								return VK_FORMAT_X8_D24_UNORM_PACK32;
-		case GL_DEPTH_COMPONENT32:								return VK_FORMAT_UNDEFINED;
-		case GL_DEPTH_COMPONENT32F:								return VK_FORMAT_D32_SFLOAT;
-		case GL_DEPTH_COMPONENT32F_NV:							return VK_FORMAT_D32_SFLOAT;
-		case GL_STENCIL_INDEX1:									return VK_FORMAT_UNDEFINED;
-		case GL_STENCIL_INDEX4:									return VK_FORMAT_UNDEFINED;
-		case GL_STENCIL_INDEX8:									return VK_FORMAT_S8_UINT;
-		case GL_STENCIL_INDEX16:								return VK_FORMAT_UNDEFINED;
-		case GL_DEPTH24_STENCIL8:								return VK_FORMAT_D24_UNORM_S8_UINT;
-		case GL_DEPTH32F_STENCIL8:								return VK_FORMAT_D32_SFLOAT_S8_UINT;
-		case GL_DEPTH32F_STENCIL8_NV:							return VK_FORMAT_D32_SFLOAT_S8_UINT;
-
-		default:												return VK_FORMAT_UNDEFINED;
-	}
-}
-
-typedef enum VkFormatSizeFlagBits {
-	VK_FORMAT_SIZE_PACKED_BIT				= 0x00000001,
-	VK_FORMAT_SIZE_COMPRESSED_BIT			= 0x00000002,
-	VK_FORMAT_SIZE_PALETTIZED_BIT			= 0x00000004,
-	VK_FORMAT_SIZE_DEPTH_BIT				= 0x00000008,
-	VK_FORMAT_SIZE_STENCIL_BIT				= 0x00000010,
-} VkFormatSizeFlagBits;
-
-typedef VkFlags VkFormatSizeFlags;
-
-typedef struct VkFormatSize {
-	VkFormatSizeFlags	flags;
-	unsigned int		paletteSizeInBits;
-	unsigned int		blockSizeInBits;
-	unsigned int		blockWidth;			// in texels
-	unsigned int		blockHeight;		// in texels
-	unsigned int		blockDepth;			// in texels
-} VkFormatSize;
-
-static inline void vkGetFormatSize( const VkFormat format, VkFormatSize * pFormatSize )
-{
-	switch ( format )
-	{
-		case VK_FORMAT_R4G4_UNORM_PACK8:
-			pFormatSize->flags = VK_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 1 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
-		case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
-		case VK_FORMAT_R5G6B5_UNORM_PACK16:
-		case VK_FORMAT_B5G6R5_UNORM_PACK16:
-		case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
-		case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
-		case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
-			pFormatSize->flags = VK_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 2 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R8_UNORM:
-		case VK_FORMAT_R8_SNORM:
-		case VK_FORMAT_R8_USCALED:
-		case VK_FORMAT_R8_SSCALED:
-		case VK_FORMAT_R8_UINT:
-		case VK_FORMAT_R8_SINT:
-		case VK_FORMAT_R8_SRGB:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 1 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R8G8_UNORM:
-		case VK_FORMAT_R8G8_SNORM:
-		case VK_FORMAT_R8G8_USCALED:
-		case VK_FORMAT_R8G8_SSCALED:
-		case VK_FORMAT_R8G8_UINT:
-		case VK_FORMAT_R8G8_SINT:
-		case VK_FORMAT_R8G8_SRGB:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 2 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R8G8B8_UNORM:
-		case VK_FORMAT_R8G8B8_SNORM:
-		case VK_FORMAT_R8G8B8_USCALED:
-		case VK_FORMAT_R8G8B8_SSCALED:
-		case VK_FORMAT_R8G8B8_UINT:
-		case VK_FORMAT_R8G8B8_SINT:
-		case VK_FORMAT_R8G8B8_SRGB:
-		case VK_FORMAT_B8G8R8_UNORM:
-		case VK_FORMAT_B8G8R8_SNORM:
-		case VK_FORMAT_B8G8R8_USCALED:
-		case VK_FORMAT_B8G8R8_SSCALED:
-		case VK_FORMAT_B8G8R8_UINT:
-		case VK_FORMAT_B8G8R8_SINT:
-		case VK_FORMAT_B8G8R8_SRGB:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 3 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R8G8B8A8_UNORM:
-		case VK_FORMAT_R8G8B8A8_SNORM:
-		case VK_FORMAT_R8G8B8A8_USCALED:
-		case VK_FORMAT_R8G8B8A8_SSCALED:
-		case VK_FORMAT_R8G8B8A8_UINT:
-		case VK_FORMAT_R8G8B8A8_SINT:
-		case VK_FORMAT_R8G8B8A8_SRGB:
-		case VK_FORMAT_B8G8R8A8_UNORM:
-		case VK_FORMAT_B8G8R8A8_SNORM:
-		case VK_FORMAT_B8G8R8A8_USCALED:
-		case VK_FORMAT_B8G8R8A8_SSCALED:
-		case VK_FORMAT_B8G8R8A8_UINT:
-		case VK_FORMAT_B8G8R8A8_SINT:
-		case VK_FORMAT_B8G8R8A8_SRGB:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 4 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
-		case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
-		case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
-		case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
-		case VK_FORMAT_A8B8G8R8_UINT_PACK32:
-		case VK_FORMAT_A8B8G8R8_SINT_PACK32:
-		case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
-			pFormatSize->flags = VK_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 4 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
-		case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
-		case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
-		case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
-		case VK_FORMAT_A2R10G10B10_UINT_PACK32:
-		case VK_FORMAT_A2R10G10B10_SINT_PACK32:
-		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
-		case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
-		case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
-		case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
-		case VK_FORMAT_A2B10G10R10_UINT_PACK32:
-		case VK_FORMAT_A2B10G10R10_SINT_PACK32:
-			pFormatSize->flags = VK_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 4 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R16_UNORM:
-		case VK_FORMAT_R16_SNORM:
-		case VK_FORMAT_R16_USCALED:
-		case VK_FORMAT_R16_SSCALED:
-		case VK_FORMAT_R16_UINT:
-		case VK_FORMAT_R16_SINT:
-		case VK_FORMAT_R16_SFLOAT:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 2 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R16G16_UNORM:
-		case VK_FORMAT_R16G16_SNORM:
-		case VK_FORMAT_R16G16_USCALED:
-		case VK_FORMAT_R16G16_SSCALED:
-		case VK_FORMAT_R16G16_UINT:
-		case VK_FORMAT_R16G16_SINT:
-		case VK_FORMAT_R16G16_SFLOAT:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 4 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R16G16B16_UNORM:
-		case VK_FORMAT_R16G16B16_SNORM:
-		case VK_FORMAT_R16G16B16_USCALED:
-		case VK_FORMAT_R16G16B16_SSCALED:
-		case VK_FORMAT_R16G16B16_UINT:
-		case VK_FORMAT_R16G16B16_SINT:
-		case VK_FORMAT_R16G16B16_SFLOAT:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 6 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R16G16B16A16_UNORM:
-		case VK_FORMAT_R16G16B16A16_SNORM:
-		case VK_FORMAT_R16G16B16A16_USCALED:
-		case VK_FORMAT_R16G16B16A16_SSCALED:
-		case VK_FORMAT_R16G16B16A16_UINT:
-		case VK_FORMAT_R16G16B16A16_SINT:
-		case VK_FORMAT_R16G16B16A16_SFLOAT:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 8 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R32_UINT:
-		case VK_FORMAT_R32_SINT:
-		case VK_FORMAT_R32_SFLOAT:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 4 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R32G32_UINT:
-		case VK_FORMAT_R32G32_SINT:
-		case VK_FORMAT_R32G32_SFLOAT:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 8 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R32G32B32_UINT:
-		case VK_FORMAT_R32G32B32_SINT:
-		case VK_FORMAT_R32G32B32_SFLOAT:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 12 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R32G32B32A32_UINT:
-		case VK_FORMAT_R32G32B32A32_SINT:
-		case VK_FORMAT_R32G32B32A32_SFLOAT:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R64_UINT:
-		case VK_FORMAT_R64_SINT:
-		case VK_FORMAT_R64_SFLOAT:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 8 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R64G64_UINT:
-		case VK_FORMAT_R64G64_SINT:
-		case VK_FORMAT_R64G64_SFLOAT:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R64G64B64_UINT:
-		case VK_FORMAT_R64G64B64_SINT:
-		case VK_FORMAT_R64G64B64_SFLOAT:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 24 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_R64G64B64A64_UINT:
-		case VK_FORMAT_R64G64B64A64_SINT:
-		case VK_FORMAT_R64G64B64A64_SFLOAT:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 32 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
-		case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
-			pFormatSize->flags = VK_FORMAT_SIZE_PACKED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 4 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_D16_UNORM:
-			pFormatSize->flags = VK_FORMAT_SIZE_DEPTH_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 2 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_X8_D24_UNORM_PACK32:
-			pFormatSize->flags = VK_FORMAT_SIZE_PACKED_BIT | VK_FORMAT_SIZE_DEPTH_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 4 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_D32_SFLOAT:
-			pFormatSize->flags = VK_FORMAT_SIZE_DEPTH_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 4 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_S8_UINT:
-			pFormatSize->flags = VK_FORMAT_SIZE_STENCIL_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 1 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_D16_UNORM_S8_UINT:
-			pFormatSize->flags = VK_FORMAT_SIZE_DEPTH_BIT | VK_FORMAT_SIZE_STENCIL_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 3 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_D24_UNORM_S8_UINT:
-			pFormatSize->flags = VK_FORMAT_SIZE_DEPTH_BIT | VK_FORMAT_SIZE_STENCIL_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 4 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_D32_SFLOAT_S8_UINT:
-			pFormatSize->flags = VK_FORMAT_SIZE_DEPTH_BIT | VK_FORMAT_SIZE_STENCIL_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 8 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
-		case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
-		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
-		case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 8 * 8;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_BC2_UNORM_BLOCK:
-		case VK_FORMAT_BC2_SRGB_BLOCK:
-		case VK_FORMAT_BC3_UNORM_BLOCK:
-		case VK_FORMAT_BC3_SRGB_BLOCK:
-		case VK_FORMAT_BC4_UNORM_BLOCK:
-		case VK_FORMAT_BC4_SNORM_BLOCK:
-		case VK_FORMAT_BC5_UNORM_BLOCK:
-		case VK_FORMAT_BC5_SNORM_BLOCK:
-		case VK_FORMAT_BC6H_UFLOAT_BLOCK:
-		case VK_FORMAT_BC6H_SFLOAT_BLOCK:
-		case VK_FORMAT_BC7_UNORM_BLOCK:
-		case VK_FORMAT_BC7_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
-		case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
-		case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
-		case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 8 * 8;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
-		case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
-		case VK_FORMAT_EAC_R11_UNORM_BLOCK:
-		case VK_FORMAT_EAC_R11_SNORM_BLOCK:
-		case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
-		case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
-		case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 4;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
-		case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 5;
-			pFormatSize->blockHeight = 4;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
-		case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 5;
-			pFormatSize->blockHeight = 5;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
-		case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 6;
-			pFormatSize->blockHeight = 5;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
-		case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 6;
-			pFormatSize->blockHeight = 6;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
-		case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 8;
-			pFormatSize->blockHeight = 5;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
-		case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 8;
-			pFormatSize->blockHeight = 6;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
-		case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 8;
-			pFormatSize->blockHeight = 8;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
-		case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 10;
-			pFormatSize->blockHeight = 5;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
-		case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 10;
-			pFormatSize->blockHeight = 6;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: 
-		case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 10;
-			pFormatSize->blockHeight = 8;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
-		case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 10;
-			pFormatSize->blockHeight = 10;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
-		case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 12;
-			pFormatSize->blockHeight = 10;
-			pFormatSize->blockDepth = 1;
-			break;
-		case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
-		case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
-			pFormatSize->flags = VK_FORMAT_SIZE_COMPRESSED_BIT;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 16 * 8;
-			pFormatSize->blockWidth = 12;
-			pFormatSize->blockHeight = 12;
-			pFormatSize->blockDepth = 1;
-			break;
-		default:
-			pFormatSize->flags = 0;
-			pFormatSize->paletteSizeInBits = 0;
-			pFormatSize->blockSizeInBits = 0 * 8;
-			pFormatSize->blockWidth = 1;
-			pFormatSize->blockHeight = 1;
-			pFormatSize->blockDepth = 1;
-			break;
-	}
-}
-
-#endif // !VK_FORMAT_H
diff --git a/external/KTX-Software-master/lib/vk_funclist.inl b/external/KTX-Software-master/lib/vk_funclist.inl
deleted file mode 100644
index 80c23c97163489aed2bc0dd56d06cb6255110e79..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/vk_funclist.inl
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab textwidth=70: */
-
-/*
- * ©2017 Mark Callow.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @internal
- * @file vk_funclist.h
- * @~English
- *
- * @brief List of Vulkan functions used by libktx.
- */
-
-VK_FUNCTION(vkAllocateCommandBuffers)
-VK_FUNCTION(vkAllocateMemory)
-VK_FUNCTION(vkBeginCommandBuffer)
-VK_FUNCTION(vkBindBufferMemory)
-VK_FUNCTION(vkBindImageMemory)
-VK_FUNCTION(vkCmdBlitImage)
-VK_FUNCTION(vkCmdCopyBufferToImage)
-VK_FUNCTION(vkCmdPipelineBarrier)
-VK_FUNCTION(vkCreateBuffer)
-VK_FUNCTION(vkCreateFence)
-VK_FUNCTION(vkCreateImage)
-VK_FUNCTION(vkDestroyBuffer)
-VK_FUNCTION(vkDestroyFence)
-VK_FUNCTION(vkDestroyImage)
-VK_FUNCTION(vkEndCommandBuffer)
-VK_FUNCTION(vkFreeCommandBuffers)
-VK_FUNCTION(vkFreeMemory)
-VK_FUNCTION(vkGetBufferMemoryRequirements)
-VK_FUNCTION(vkGetImageMemoryRequirements)
-VK_FUNCTION(vkGetImageSubresourceLayout)
-VK_FUNCTION(vkGetPhysicalDeviceImageFormatProperties)
-VK_FUNCTION(vkGetPhysicalDeviceFormatProperties)
-VK_FUNCTION(vkGetPhysicalDeviceMemoryProperties)
-VK_FUNCTION(vkMapMemory)
-VK_FUNCTION(vkQueueSubmit)
-VK_FUNCTION(vkQueueWaitIdle)
-VK_FUNCTION(vkUnmapMemory)
-VK_FUNCTION(vkWaitForFences)
diff --git a/external/KTX-Software-master/lib/vk_funcs.c b/external/KTX-Software-master/lib/vk_funcs.c
deleted file mode 100644
index 7d75053d741a70ab2d8e9b0a029c0018be55caff..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/vk_funcs.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab textwidth=70: */
-
-/*
- * ©2017 Mark Callow.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @internal
- * @file vk_funcs.c
- * @~English
- *
- * @brief Retrieve Vulkan function pointers needed by libktx
- */
-
-#if defined(KTX_USE_FUNCPTRS_FOR_VULKAN)
-
-#define UNIX 0
-#define MACOS 0
-#define WINDOWS 0
-
-#if defined(_WIN32)
-#undef WINDOWS
-#define WINDOWS 1
-#endif
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__)
-#undef UNIX
-#define UNIX 1
-#endif
-#if defined(linux) || defined(__linux) || defined(__linux__)
-#undef UNIX
-#define UNIX 1
-#endif
-#if defined(__APPLE__) && defined(__x86_64__)
-#undef MACOS
-#define MACOS 1
-#endif
-
-#if (IOS + MACOS + UNIX + WINDOWS) > 1
-#error "Multiple OS\'s defined"
-#endif 
-
-#if WINDOWS
-#define WINDOWS_LEAN_AND_MEAN
-#include <windows.h>
-#else
-#include <dlfcn.h>
-#endif
-#include "ktx.h"
-#include "vk_funcs.h"
-
-#if WINDOWS
-HMODULE ktxVulkanLibary;
-#define LoadLibrary LoadLibrary
-#define LoadProcAddr GetProcAddress
-#elif MACOS || UNIX
-#define LoadLibrary dlopen
-#define LoadProcAddr dlsym
-void* ktxVulkanLibrary;
-#else
-#error "Don\'t know how to load symbols on this OS."
-#endif
-
-#if WINDOWS
-#define VULKANLIB "vulkan-1.dll"
-#elif MACOS
-#define VULKANLIB "vulkan.framework/vulkan"
-#elif UNIX
-#define VULKANLIB "libvulkan.so"
-#endif
-
-static PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
-
-/* Define pointers for functions libktx is using. */
-#define VK_FUNCTION(fun) PFN_##fun ktx_##fun;
-
-#include "vk_funclist.inl"
-
-#undef VK_FUNCTION
-
-#if 0
-// The Vulkan spec. recommends using vkGetInstanceProcAddr over dlsym
-// (or whatever). Doing so would require a backward incompatible
-// change to the libktx API to provide the VkInstance. We have no
-// choice but dlsym. We can't use vkGetDeviceProcAddr because libktx
-// also uses none-device-level functions.
-#define VK_FUNCTION(fun)                                                     \
-  if ( !(ktx_##fun = (PFN_##fun)vkGetInstanceProcAddr(instance, #fun )) ) {  \
-    fprintf(stderr, "Could not load Vulkan command: %s!\n", #fun);          \
-    return KTX_FALSE;                                             \
-  }
-#else
-#if defined(__GNUC__)
-// This strange casting is because dlsym returns a void* thus is not
-// compatible with ISO C which forbids conversion of object pointers
-// to function pointers. The cast masks the conversion from the
-// compiler thus no warning even though -pedantic is set. Since the
-// platform supports dlsym, conversion to function pointers must
-// work, despite the mandated ISO C warning.
-#define VK_FUNCTION(fun)                                                   \
-  if ( !(*(void **)(&ktx_##fun) = LoadProcAddr(ktxVulkanLibrary, #fun)) ) {\
-    fprintf(stderr, "Could not load Vulkan command: %s!\n", #fun);         \
-    return KTX_FALSE;                                                      \
-  }
-#else
-#define VK_FUNCTION(fun)                                                   \
-  if ( !(ktx_##fun = (PFN_##fun)LoadProcAddr(ktxVulkanLibrary, #fun)) ) {  \
-    fprintf(stderr, "Could not load Vulkan command: %s!\n", #fun);         \
-    return KTX_FALSE;                                                      \
-  }
-#endif
-#endif
-
-ktx_bool_t
-ktxVulkanLoadLibrary(void)
-{
-    if (ktxVulkanLibrary)
-        return KTX_TRUE;
-
-    ktxVulkanLibrary = LoadLibrary(VULKANLIB, RTLD_LAZY);
-    if (ktxVulkanLibrary == NULL) {
-        fprintf(stderr, "Could not load Vulkan library.\n");
-        return(KTX_FALSE);
-    }
-
-#if 0
-    vkGetInstanceProcAddr =
-            (PFN_vkGetInstanceProcAddr)LoadProcAddr(ktxVulkanLibrary,
-                                                  "vkGetInstanceProcAddr");
-    if (!vkGetInstanceProcAddr) {
-       fprintf(stderr, "Could not load Vulkan command: %s!\n",
-               "vkGetInstanceProcAddr");
-       return(KTX_FALSE);
-    }
-#endif
-
-#include "vk_funclist.inl"
-
-    return KTX_TRUE;
-}
-
-#undef VK_FUNCTION
-
-#else
-
-extern
-#if defined(__GNUC__)
-__attribute__((unused))
-#endif
-int keepISOCompilersHappy;
-
-#endif /* KTX_USE_FUNCPTRS_FOR_VULKAN */
diff --git a/external/KTX-Software-master/lib/vk_funcs.h b/external/KTX-Software-master/lib/vk_funcs.h
deleted file mode 100644
index 07ea0c2b455e20958527fd3c03411bd15337cfa3..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/vk_funcs.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab textwidth=70: */
-
-/*
- * ©2017 Mark Callow.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @internal
- * @file vk_funcs.h
- * @~English
- *
- * @brief Declare pointers for Vulkan functions.
- *
- * Dynamically retrieving pointers avoids apps having to make sure a
- * Vulkan library is availablei when using a shared libktx, even if
- * not using libktx's Vulkan loader.
- */
-
-#ifndef _VK_FUNCS_H_
-#define _VK_FUNCS_H_
-
-#if defined(KTX_USE_FUNCPTRS_FOR_VULKAN)
-#define VK_NO_PROTOTYPES
-#endif
-
-#include <vulkan/vulkan.h>
-#include "ktx.h"
-
-#if defined(KTX_USE_FUNCPTRS_FOR_VULKAN)
-
-#if defined(_WIN32)
-extern HMODULE ktxVulkanLibary;
-#else
-extern void* ktxVulkanLibrary;
-#endif
-
-extern ktx_bool_t ktxVulkanLoadLibrary(void);
-
-/* Declare pointers for functions libktx is using. */
-#define VK_FUNCTION(fun) extern PFN_##fun ktx_##fun;
-
-#include "vk_funclist.inl"
-
-#undef VK_FUNCTION
-
-/*
- * Define prefixed names to prevent collisions with other libraries or apps
- * finding our pointers when searching the module for function addresses.
- */
-#define vkAllocateCommandBuffers ktx_vkAllocateCommandBuffers
-#define vkAllocateMemory ktx_vkAllocateMemory
-#define vkBeginCommandBuffer ktx_vkBeginCommandBuffer
-#define vkBindBufferMemory ktx_vkBindBufferMemory
-#define vkBindImageMemory ktx_vkBindImageMemory
-#define vkCmdBlitImage ktx_vkCmdBlitImage
-#define vkCmdCopyBufferToImage ktx_vkCmdCopyBufferToImage
-#define vkCmdPipelineBarrier ktx_vkCmdPipelineBarrier
-#define vkCreateBuffer ktx_vkCreateBuffer
-#define vkCreateFence ktx_vkCreateFence
-#define vkCreateImage ktx_vkCreateImage
-#define vkDestroyBuffer ktx_vkDestroyBuffer
-#define vkDestroyFence ktx_vkDestroyFence
-#define vkDestroyImage ktx_vkDestroyImage
-#define vkEndCommandBuffer ktx_vkEndCommandBuffer
-#define vkFreeCommandBuffers ktx_vkFreeCommandBuffers
-#define vkFreeMemory ktx_vkFreeMemory
-#define vkGetBufferMemoryRequirements ktx_vkGetBufferMemoryRequirements
-#define vkGetImageMemoryRequirements ktx_vkGetImageMemoryRequirements
-#define vkGetImageSubresourceLayout ktx_vkGetImageSubresourceLayout
-#define vkGetPhysicalDeviceImageFormatProperties ktx_vkGetPhysicalDeviceImageFormatProperties
-#define vkGetPhysicalDeviceFormatProperties ktx_vkGetPhysicalDeviceFormatProperties
-#define vkGetPhysicalDeviceMemoryProperties ktx_vkGetPhysicalDeviceMemoryProperties
-#define vkMapMemory ktx_vkMapMemory
-#define vkQueueSubmit ktx_vkQueueSubmit
-#define vkQueueWaitIdle ktx_vkQueueWaitIdle
-#define vkUnmapMemory ktx_vkUnmapMemory
-#define vkWaitForFences ktx_vkWaitForFences
-
-#undef VK_FUNCTION
-
-#endif /* KTX_USE_FUNCPTRS_FOR_VULKAN */
-
-#endif /* _VK_FUNCS_H_ */
-
diff --git a/external/KTX-Software-master/lib/vkloader.c b/external/KTX-Software-master/lib/vkloader.c
deleted file mode 100644
index 9916ce2b5c1ad6cbb64fc19242d84f65a83a0e93..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/vkloader.c
+++ /dev/null
@@ -1,1444 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/*
- * ©2018 Mark Callow.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- 
-/**
- * @internal
- * @file
- * @~English
- *
- * @brief Functions for instantiating Vulkan textures from KTX files.
- *
- * @author Mark Callow, Edgewise Consulting
- */
-
-#ifdef _WIN32
-#define _CRT_SECURE_NO_WARNINGS
-#endif
-
-#include <assert.h>
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if defined(KTX_USE_FUNCPTRS_FOR_VULKAN)
-#include "vk_funcs.h"   // Must be included before ktxvulkan.h.
-#endif
-#include "ktxvulkan.h"
-#include "ktxint.h"
-#include "vk_format.h"
-
-// Macro to check and display Vulkan return results.
-// Use when the only possible errors are caused by invalid usage by this loader.
-#if defined(_DEBUG)
-#define VK_CHECK_RESULT(f)                                                  \
-{                                                                           \
-    VkResult res = (f);                                                     \
-    if (res != VK_SUCCESS)                                                  \
-    {                                                                       \
-        /* XXX Find an errorString function. */                             \
-        fprintf(stderr, "Fatal error in ktxLoadVkTexture*: "                \
-                "VkResult is \"%d\" in %s at line %d\n",                    \
-                res, __FILE__, __LINE__);                                   \
-        assert(res == VK_SUCCESS);                                          \
-    }                                                                       \
-}
-#else
-#define VK_CHECK_RESULT(f) ((void)f)
-#endif
-
-#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
-
-#define DEFAULT_FENCE_TIMEOUT 100000000000
-#define VK_FLAGS_NONE 0
-
-static void
-setImageLayout(
-    VkCommandBuffer cmdBuffer,
-    VkImage image,
-    VkImageLayout oldLayout,
-    VkImageLayout newLayout,
-    VkImageSubresourceRange subresourceRange);
-
-static void
-generateMipmaps(ktxVulkanTexture* vkTexture, ktxVulkanDeviceInfo* vdi,
-                VkFilter filter, VkImageLayout initialLayout);
-
-/**
- * @defgroup ktx_vkloader Vulkan Texture Image Loader
- * @brief Create texture images on a Vulkan device.
- * @{
- */
-
-/**
- * @example vkload.cpp
- * This shows how to create and load a Vulkan image using the Vulkan texture
- * image loading functions.
- */
-
-/**
- * @memberof ktxVulkanDeviceInfo
- * @~English
- * @brief Create a ktxVulkanDeviceInfo object.
- * 
- * Allocates CPU memory for a ktxVulkanDeviceInfo object then calls
- * ktxVulkanDeviceInfo_construct(). See it for documentation of the
- * parameters.
- *
- * @return a pointer to the constructed ktxVulkanDeviceInfo.
- *
- * @sa ktxVulkanDeviceInfo_construct(), ktxVulkanDeviceInfo_destroy()
- */
-ktxVulkanDeviceInfo*
-ktxVulkanDeviceInfo_Create(VkPhysicalDevice physicalDevice, VkDevice device,
-                           VkQueue queue, VkCommandPool cmdPool,
-                           const VkAllocationCallbacks* pAllocator)
-{
-    ktxVulkanDeviceInfo* newvdi;
-    newvdi = (ktxVulkanDeviceInfo*)malloc(sizeof(ktxVulkanDeviceInfo));
-    if (newvdi != NULL) {
-        if (ktxVulkanDeviceInfo_Construct(newvdi, physicalDevice, device,
-                                    queue, cmdPool, pAllocator) != KTX_SUCCESS)
-        {
-            free(newvdi);
-            newvdi = 0;
-        }
-    }
-    return newvdi;
-}
-
-/**
- * @memberof ktxVulkanDeviceInfo
- * @~English
- * @brief Construct a ktxVulkanDeviceInfo object.
- *
- * Records the device information, allocates a command buffer that will be
- * used to transfer image data to the Vulkan device and retrieves the physical
- * device memory properties for ease of use when allocating device memory for
- * the images.
- *
- * Pass a valid ktxVulkanDeviceInfo* to any Vulkan KTX image loading
- * function to provide it with the information.
- *
- * @param  This            pointer to the ktxVulkanDeviceInfo object to
- *                        initialize.
- * @param  physicalDevice handle of the Vulkan physical device.
- * @param  device         handle of the Vulkan logical device.
- * @param  queue          handle of the Vulkan queue.
- * @param  cmdPool        handle of the Vulkan command pool.
- * @param  pAllocator     pointer to the allocator to use for the image
- *                        memory. If NULL, the default allocator will be used.
- *
- * @returns KTX_SUCCESS on success, KTX_OUT_OF_MEMORY if a command buffer could
- *          not be allocated.
- *
- * @sa ktxVulkanDeviceInfo_destruct()
- */
-KTX_error_code
-ktxVulkanDeviceInfo_Construct(ktxVulkanDeviceInfo* This,
-                              VkPhysicalDevice physicalDevice, VkDevice device,
-                              VkQueue queue, VkCommandPool cmdPool,
-                              const VkAllocationCallbacks* pAllocator)
-{
-    VkCommandBufferAllocateInfo cmdBufInfo = {
-        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO
-    };
-    VkResult result;
-
-#if defined(KTX_USE_FUNCPTRS_FOR_VULKAN)
-    // Delay loading not supported so must do it ourselves.
-    if (!ktxVulkanLibrary) {
-        if (!ktxVulkanLoadLibrary())
-            // Normal use is for this constructor to be called by an application
-            // that has completed Vulkan initialization. In that case the only
-            // cause for failure would be an incompatible in the version of libvulkan
-            // that is loaded. The only other cause would be an application calling
-            // Vulkan functions without having initialized Vulkan.
-            //
-            // In these cases, an abort along with the messages sent to stderr by
-            // ktxVulkanLoadLibrary is sufficient as released applications should
-            // never suffer these.
-            abort();
-    }
-#endif
-
-    This->physicalDevice = physicalDevice;
-    This->device = device;
-    This->queue = queue;
-    This->cmdPool = cmdPool;
-    This->pAllocator = pAllocator;
-    vkGetPhysicalDeviceMemoryProperties(physicalDevice,
-                                        &This->deviceMemoryProperties);
-
-    // Use a separate command buffer for texture loading. Needed for
-    // submitting image barriers and converting tilings.
-    cmdBufInfo.commandPool = cmdPool;
-    cmdBufInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    cmdBufInfo.commandBufferCount = 1;
-    result = vkAllocateCommandBuffers(device, &cmdBufInfo, &This->cmdBuffer);
-    if (result != VK_SUCCESS) {
-        return KTX_OUT_OF_MEMORY; // XXX Consider an equivalent to pGlError
-    }
-    return KTX_SUCCESS;
-}
-
-/**
- * @memberof ktxVulkanDeviceInfo
- * @~English
- * @brief Destruct a ktxVulkanDeviceInfo object.
- *
- * Frees the command buffer.
- *
- * @param This pointer to the ktxVulkanDeviceInfo to destruct.
- */
-void
-ktxVulkanDeviceInfo_Destruct(ktxVulkanDeviceInfo* This)
-{
-    vkFreeCommandBuffers(This->device, This->cmdPool, 1,
-                         &This->cmdBuffer);
-}
-
-/**
- * @memberof ktxVulkanDeviceInfo
- * @~English
- * @brief Destroy a ktxVulkanDeviceInfo object.
- *
- * Calls ktxVulkanDeviceInfo_destruct() then frees the ktxVulkanDeviceInfo.
- *
- * @param This pointer to the ktxVulkanDeviceInfo to destroy.
- */
-void
-ktxVulkanDeviceInfo_Destroy(ktxVulkanDeviceInfo* This)
-{
-    assert(This != NULL);
-    ktxVulkanDeviceInfo_Destruct(This);
-    free(This);
-}
-
-/* Get appropriate memory type index for a memory allocation. */
-static uint32_t
-ktxVulkanDeviceInfo_getMemoryType(ktxVulkanDeviceInfo* This,
-                                  uint32_t typeBits, VkFlags properties)
-{
-    for (uint32_t i = 0; i < 32; i++)
-    {
-        if ((typeBits & 1) == 1)
-        {
-            if ((This->deviceMemoryProperties.memoryTypes[i].propertyFlags & properties) == properties)
-            {
-                return i;
-            }
-        }
-        typeBits >>= 1;
-    }
-
-    // XXX : throw error
-    return 0;
-}
-
-//======================================================================
-//  ReadImages callbacks
-//======================================================================
-
-typedef struct user_cbdata_optimal {
-    VkBufferImageCopy* region; // Specify destination region in final image.
-    VkDeviceSize offset;       // Offset of current level in staging buffer
-    ktx_uint32_t numFaces;
-    ktx_uint32_t numLayers;
-    // The following are used only by optimalTilingPadCallback
-    ktx_uint8_t* dest;         // Pointer to mapped staging buffer.
-    ktx_uint32_t elementSize;
-    ktx_uint32_t numDimensions;
-#if defined(_DEBUG)
-    VkBufferImageCopy* regionsArrayEnd;
-#endif
-} user_cbdata_optimal;
-
-/**
- * @internal
- * @~English
- * @brief Callback for optimally tiled textures with no source row padding.
- *
- * Images must be preloaded into the staging buffer. Each iteration, i.e.
- * the value of @p faceLodSize must be for a complete mip level, regardless of
- * texture type. This should be used only with @c ktx_Texture_IterateLevels.
- *
- * Sets up a region to copy the data from the staging buffer to the final
- * image.
- *
- * @note @p pixels is not used.
- *
- * @copydetails PFNKTXITERCB
- */
-static KTX_error_code KTXAPIENTRY
-optimalTilingCallback(int miplevel, int face,
-                      int width, int height, int depth,
-                      ktx_uint32_t faceLodSize,
-                      void* pixels, void* userdata)
-{
-    user_cbdata_optimal* ud = (user_cbdata_optimal*)userdata;
-
-    // Set up copy to destination region in final image
-    assert(ud->region < ud->regionsArrayEnd);
-    ud->region->bufferOffset = ud->offset;
-    ud->offset += faceLodSize;
-    // These 2 are expressed in texels.
-    ud->region->bufferRowLength = 0;
-    ud->region->bufferImageHeight = 0;
-    ud->region->imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-    ud->region->imageSubresource.mipLevel = miplevel;
-    ud->region->imageSubresource.baseArrayLayer = face;
-    ud->region->imageSubresource.layerCount = ud->numLayers * ud->numFaces;
-    ud->region->imageOffset.x = 0;
-    ud->region->imageOffset.y = 0;
-    ud->region->imageOffset.z = 0;
-    ud->region->imageExtent.width = width;
-    ud->region->imageExtent.height = height;
-    ud->region->imageExtent.depth = depth;
-
-    ud->region += 1;
-
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Callback for optimally tiled textures with possible source row
- *        padding.
- *
- * Copies data to the staging buffer removing row padding, if necessary.
- * Increments the offset for destination of the next copy increasing it to an
- * appropriate common multiple of the element size and 4 to comply with Vulkan
- * valid usage. Finally sets up a region to copy the face/lod from the staging
- * buffer to the final image.
- *
- * This longer method is needed because row padding is different between
- * KTX (pad to 4) and Vulkan (none). Also region->bufferOffset, i.e. the start
- * of each image, has to be a multiple of 4 and also a multiple of the
- * element size.
- *
- * This should be used with @c ktx_Texture_IterateFaceLevels or
- * @c ktx_Texture_IterateLoadFaceLevels. Face-level iteration has been
- * selected to minimize the buffering needed between reading the file and
- * copying the data into the staging buffer. Obviously when
- * @c ktx_Texture_IterateFaceLevels is being used, this is a moot point.
-*
- * @copydetails PFNKTXITERCB
- */
-KTX_error_code KTXAPIENTRY
-optimalTilingPadCallback(int miplevel, int face,
-                         int width, int height, int depth,
-                         ktx_uint32_t faceLodSize,
-                         void* pixels, void* userdata)
-{
-    user_cbdata_optimal* ud = (user_cbdata_optimal*)userdata;
-    ktx_uint32_t rowPitch = width * ud->elementSize;
-
-    // Set bufferOffset in destination region in final image
-    assert(ud->region < ud->regionsArrayEnd);
-    ud->region->bufferOffset = ud->offset;
-
-    // Copy data into staging buffer
-    if (_KTX_PAD_UNPACK_ALIGN_LEN(rowPitch) == 0) {
-        // No padding. Can copy in bulk.
-        memcpy(ud->dest + ud->offset, pixels, faceLodSize);
-        ud->offset += faceLodSize;
-    } else {
-        // Must remove padding. Copy a row at a time.
-		ktx_uint32_t image, imageIterations;
-		ktx_int32_t row;
-        ktx_uint32_t rowPitch, paddedRowPitch;
-
-        if (ud->numDimensions == 3)
-            imageIterations = depth;
-        else if (ud->numLayers > 1)
-            imageIterations = ud->numLayers * ud->numFaces;
-        else
-            imageIterations = 1;
-        rowPitch = paddedRowPitch = width * ud->elementSize;
-        paddedRowPitch = _KTX_PAD_UNPACK_ALIGN(paddedRowPitch);
-        for (image = 0; image < imageIterations; image++) {
-            for (row = 0; row < height; row++) {
-                memcpy(ud->dest + ud->offset, pixels, rowPitch);
-                ud->offset += rowPitch;
-                pixels = (ktx_uint8_t*)pixels + paddedRowPitch;
-            }
-        }
-    }
-
-    // Round to needed multiples for next region, if necessary.
-    if (ud->offset % ud->elementSize != 0 || ud->offset % 4 != 0) {
-        // Only elementSizes of 1,2 and 3 will bring us here.
-        assert(ud->elementSize < 4 && ud->elementSize > 0);
-        ktx_uint32_t lcm = ud->elementSize == 3 ? 12 : 4;
-        // Can't use _KTX_PADN shortcut because 12 is not power of 2.
-        ud->offset = (ktx_uint32_t)(lcm * ceil((float)ud->offset / lcm));
-    }
-    // These 2 are expressed in texels; not suitable for dealing with padding.
-    ud->region->bufferRowLength = 0;
-    ud->region->bufferImageHeight = 0;
-    ud->region->imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-    ud->region->imageSubresource.mipLevel = miplevel;
-    ud->region->imageSubresource.baseArrayLayer = face;
-    ud->region->imageSubresource.layerCount = ud->numLayers * ud->numFaces;
-    ud->region->imageOffset.x = 0;
-    ud->region->imageOffset.y = 0;
-    ud->region->imageOffset.z = 0;
-    ud->region->imageExtent.width = width;
-    ud->region->imageExtent.height = height;
-    ud->region->imageExtent.depth = depth;
-
-    ud->region += 1;
-
-    return KTX_SUCCESS;
-}
-
-typedef struct user_cbdata_linear {
-    VkImage destImage;
-    VkDevice device;
-    uint8_t* dest;   // Pointer to mapped Image memory
-    ktxTexture* texture;
-} user_cbdata_linear;
-
-/**
- * @internal
- * @~English
- * @brief Callback for linear tiled textures with no source row padding.
- *
- * Copy the image data into the mapped Vulkan image.
- */
-KTX_error_code KTXAPIENTRY
-linearTilingCallback(int miplevel, int face,
-                      int width, int height, int depth,
-                      ktx_uint32_t faceLodSize,
-                      void* pixels, void* userdata)
-{
-    user_cbdata_linear* ud = (user_cbdata_linear*)userdata;
-    VkSubresourceLayout subResLayout;
-    VkImageSubresource subRes = {
-      .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-      .mipLevel = miplevel,
-      .arrayLayer = face
-    };
-
-    // Get sub resources layout. Includes row pitch, size,
-    // offsets, etc.
-    vkGetImageSubresourceLayout(ud->device, ud->destImage, &subRes,
-                                &subResLayout);
-    // Copies all images of the miplevel (for array & 3d) or a single face.
-    memcpy(ud->dest + subResLayout.offset, pixels, faceLodSize);
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Callback for linear tiled textures with possible source row
- *        padding.
- *
- * Need to use this long method as row padding is different
- * between KTX (pad to 4) and Vulkan (none).
- *
- * In theory this should work for the no-padding case too but it is much
- * clearer and a bit faster to use the simple callback above. It also avoids
- * potential Vulkan implementation bugs.
- *
- * I have seen weird subResLayout results with a BC2_UNORM texture in the only
- * real Vulkan implementation I have available (Mesa). The reported row & image
- * strides appears to be for an R8G8B8A8_UNORM of the same texel size.
- */
-KTX_error_code KTXAPIENTRY
-linearTilingPadCallback(int miplevel, int face,
-                      int width, int height, int depth,
-                      ktx_uint32_t faceLodSize,
-                      void* pixels, void* userdata)
-{
-    user_cbdata_linear* ud = (user_cbdata_linear*)userdata;
-    VkSubresourceLayout subResLayout;
-    VkImageSubresource subRes = {
-      .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-      .mipLevel = miplevel,
-      .arrayLayer = face
-    };
-    VkDeviceSize offset;
-    ktx_size_t   imageSize = 0;
-    VkDeviceSize imagePitch = 0;
-    ktx_uint32_t srcRowPitch;
-    ktx_uint32_t rowIterations;
-    ktx_uint32_t imageIterations;
-    ktx_uint32_t row, image;
-    ktx_uint8_t* pSrc;
-    ktx_size_t   copySize;
-
-    // Get sub resources layout. Includes row pitch, size,
-    // offsets, etc.
-    vkGetImageSubresourceLayout(ud->device, ud->destImage, &subRes,
-                                &subResLayout);
-
-    srcRowPitch = ktxTexture_GetRowPitch(ud->texture, miplevel);
-
-    if (subResLayout.rowPitch != srcRowPitch)
-        rowIterations = height;
-    else
-        rowIterations = 1;
-
-    // Arrays, including cube map arrays, or 3D textures
-    // Note from the Vulkan spec:
-    //  *  arrayPitch is undefined for images that were not
-    //     created as arrays.
-    //  *  depthPitch is defined only for 3D images.
-    if (ud->texture->numLayers > 1 || ud->texture->numDimensions == 3) {
-        imageSize = ktxTexture_GetImageSize(ud->texture, miplevel);
-        if (ud->texture->numLayers > 1) {
-            imagePitch = subResLayout.arrayPitch;
-            if (imagePitch != imageSize)
-                imageIterations
-                        = ud->texture->numLayers * ud->texture->numFaces;
-        } else {
-            imagePitch = subResLayout.depthPitch;
-            if (imagePitch != imageSize)
-                imageIterations = depth;
-        }
-        assert(imageSize <= imagePitch);
-    } else
-        imageIterations = 1;
-
-    if (rowIterations > 1) {
-        // Copy the minimum of srcRowPitch, the GL_UNPACK_ALIGNMENT padded size,
-        // and subResLayout.rowPitch.
-        if (subResLayout.rowPitch < srcRowPitch)
-            copySize = subResLayout.rowPitch;
-        else
-            copySize = srcRowPitch;
-    } else if (imageIterations > 1)
-        copySize = faceLodSize / imageIterations;
-    else
-        copySize = faceLodSize;
-
-    offset = subResLayout.offset;
-    // Copy image data to destImage via its mapped memory.
-    for (image = 0; image < imageIterations; image++) {
-        pSrc = (ktx_uint8_t*)pixels + imageSize * image;
-        for (row = 0; row < rowIterations; row++) {
-            memcpy(ud->dest + offset, pSrc, copySize);
-            offset += subResLayout.rowPitch;
-            pSrc += srcRowPitch;
-          }
-        offset += imagePitch;
-    }
-    return KTX_SUCCESS;
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Create a Vulkan image object from a ktxTexture object.
- *
- * Creates a VkImage with @c VkFormat etc. matching the KTX data and uploads
- * the images. Also creates a VkImageView object for accessing the image.
- * Mipmaps will be generated if the @c ktxTexture's @c generateMipmaps
- * flag is set. Returns the handles of the created objects and information
- * about the texture in the @c ktxVulkanTexture pointed at by @p vkTexture.
- *
- * @p usageFlags and thus acceptable usage of the created image may be
- * augmented as follows:
- * - with @c VK_IMAGE_USAGE_TRANSFER_DST_BIT if @p tiling is
- *   @c VK_IMAGE_TILING_OPTIMAL
- * - with <code>VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT</code>
- *   if @c generateMipmaps is set in the @c ktxTexture.
- *
- * Most Vulkan implementations support VK_IMAGE_TILING_LINEAR only for a very
- * limited number of formats and features. Generally VK_IMAGE_TILING_OPTIMAL is
- * preferred. The latter requires a staging buffer so will use more memory
- * during loading.
- *
- * @param[in] This          pointer to the ktxTexture from which to upload.
- * @param [in] vdi          pointer to a ktxVulkanDeviceInfo structure providing
- *                          information about the Vulkan device onto which to
- *                          load the texture.
- * @param [in,out] vkTexture pointer to a ktxVulkanTexture structure into which
- *                           the function writes information about the created
- *                           VkImage.
- * @param [in] tiling       type of tiling to use in the destination image
- *                          on the Vulkan device.
- * @param [in] usageFlags   a set of VkImageUsageFlags bits indicating the
- *                          intended usage of the destination image.
- * @param [in] finalLayout  a VkImageLayout value indicating the desired
- *                          final layout of the created image.
- *
- * @return  KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p This, @p vdi or @p vkTexture is @c NULL.
- * @exception KTX_INVALID_OPERATION The ktxTexture contains neither images nor
- *                                  an active stream from which to read them.
- * @exception KTX_INVALID_OPERATION The combination of the ktxTexture's format,
- *                                  @p tiling and @p usageFlags is not supported
- *                                  by the physical device.
- * @exception KTX_INVALID_OPERATION Requested mipmap generation is not supported
- *                                  by the physical device for the combination
- *                                  of the ktxTexture's format and @p tiling.
- * @exception KTX_OUT_OF_MEMORY Sufficient memory could not be allocated
- *                              on either the CPU or the Vulkan device.
- */
-KTX_error_code
-ktxTexture_VkUploadEx(ktxTexture* This, ktxVulkanDeviceInfo* vdi,
-                      ktxVulkanTexture* vkTexture,
-                      VkImageTiling tiling,
-                      VkImageUsageFlags usageFlags,
-                      VkImageLayout finalLayout)
-{
-    KTX_error_code           kResult;
-    VkFilter                 blitFilter;
-    VkFormat                 vkFormat;
-    VkImageType              imageType;
-    VkImageViewType          viewType;
-    VkImageCreateFlags       createFlags = 0;
-    VkImageFormatProperties  imageFormatProperties;
-    VkResult                 vResult;
-    VkCommandBufferBeginInfo cmdBufBeginInfo = {
-        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
-        .pNext = NULL
-    };
-    VkImageCreateInfo        imageCreateInfo = {
-         .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
-         .pNext = NULL
-    };
-    VkMemoryAllocateInfo     memAllocInfo = {
-        .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
-        .pNext = NULL,
-        .allocationSize = 0,
-        .memoryTypeIndex = 0
-    };
-    VkMemoryRequirements     memReqs;
-    ktx_uint32_t             numImageLayers, numImageLevels;
-    ktx_uint32_t elementSize = ktxTexture_GetElementSize(This);
-    ktx_bool_t               canUseFasterPath;
-
-    if (!vdi || !This || !vkTexture) {
-        return KTX_INVALID_VALUE;
-    }
-
-    if (!This->pData && !ktxTexture_isActiveStream(This)) {
-        /* Nothing to upload. */
-        return KTX_INVALID_OPERATION;
-    }
-
-    /* _ktxCheckHeader should have caught this. */
-    assert(This->numFaces == 6 ? This->numDimensions == 2 : VK_TRUE);
-
-    numImageLayers = This->numLayers;
-    if (This->isCubemap) {
-        numImageLayers *= 6;
-        createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
-    }
-
-    switch (This->numDimensions) {
-      case 1:
-        imageType = VK_IMAGE_TYPE_1D;
-        viewType = This->isArray ?
-                        VK_IMAGE_VIEW_TYPE_1D_ARRAY : VK_IMAGE_VIEW_TYPE_1D;
-        break;
-      case 2:
-        imageType = VK_IMAGE_TYPE_2D;
-        if (This->isCubemap)
-            viewType = This->isArray ?
-                        VK_IMAGE_VIEW_TYPE_CUBE_ARRAY : VK_IMAGE_VIEW_TYPE_CUBE;
-        else
-            viewType = This->isArray ?
-                        VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
-        break;
-      case 3:
-        imageType = VK_IMAGE_TYPE_3D;
-        /* 3D array textures not supported in Vulkan. Attempts to create or
-         * load them should have been trapped long before this.
-         */
-        assert(!This->isArray);
-        viewType = VK_IMAGE_VIEW_TYPE_3D;
-        break;
-    }
-
-    vkFormat = vkGetFormatFromOpenGLInternalFormat(This->glInternalformat);
-    if (vkFormat == VK_FORMAT_UNDEFINED)
-        vkFormat = vkGetFormatFromOpenGLFormat(This->glFormat, This->glType);
-    if (vkFormat == VK_FORMAT_UNDEFINED) {
-        return KTX_INVALID_OPERATION;
-    }
-
-    /* Get device properties for the requested image format */
-    if (tiling == VK_IMAGE_TILING_OPTIMAL) {
-        // Ensure we can copy from staging buffer to image.
-        usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
-    }
-    if (This->generateMipmaps) {
-        // Ensure we can blit between levels.
-        usageFlags |= (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
-    }
-    vResult = vkGetPhysicalDeviceImageFormatProperties(vdi->physicalDevice,
-                                                      vkFormat,
-                                                      imageType,
-                                                      tiling,
-                                                      usageFlags,
-                                                      createFlags,
-                                                      &imageFormatProperties);
-    if (vResult == VK_ERROR_FORMAT_NOT_SUPPORTED) {
-        return KTX_INVALID_OPERATION;
-    }
-
-    if (This->generateMipmaps) {
-        uint32_t max_dim;
-        VkFormatProperties    formatProperties;
-        VkFormatFeatureFlags  formatFeatureFlags;
-        VkFormatFeatureFlags  neededFeatures
-            = VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT;
-        vkGetPhysicalDeviceFormatProperties(vdi->physicalDevice,
-                                            vkFormat,
-                                            &formatProperties);
-        assert(vResult == VK_SUCCESS);
-        if (tiling == VK_IMAGE_TILING_OPTIMAL)
-            formatFeatureFlags = formatProperties.optimalTilingFeatures;
-        else
-            formatFeatureFlags = formatProperties.linearTilingFeatures;
-
-        if ((formatFeatureFlags & neededFeatures) != neededFeatures)
-            return KTX_INVALID_OPERATION;
-
-        if (formatFeatureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)
-            blitFilter = VK_FILTER_LINEAR;
-        else
-            blitFilter = VK_FILTER_NEAREST; // XXX INVALID_OP?
-
-        max_dim = MAX(MAX(This->baseWidth, This->baseHeight), This->baseDepth);
-        numImageLevels = (uint32_t)floor(log2(max_dim)) + 1;
-    } else {
-        numImageLevels = This->numLevels;
-    }
-
-    {
-        ktx_uint32_t actualRowPitch = ktxTexture_GetRowPitch(This, 0);
-        ktx_uint32_t tightRowPitch = elementSize * This->baseWidth;
-        // If the texture's images do not have any row padding, we can use a
-        // faster path. Only uncompressed textures might have padding.
-        //
-        // The first test in the if will match compressed textures, because
-        // they all have a block size that is a multiple of 4, as well as
-        // a class of uncompressed textures that will never need padding.
-        //
-        // The second test matches textures whose level 0 has no padding. Any
-        // texture whose block size is not a multiple of 4 will need padding
-        // at some miplevel even if level 0 does not. So, if more than 1 level
-        // exists, we must use the slower path.
-        //
-        // Note all elementSizes > 4 Will be a multiple of 4, so only
-        // elementSizes of 1, 2 & 3 are a concern here.
-        if (elementSize % 4 == 0  /* There'll be no padding at any level. */
-               /* There is no padding at level 0 and no other levels. */
-            || (This->numLevels == 1 && actualRowPitch == tightRowPitch))
-            canUseFasterPath = KTX_TRUE;
-        else
-            canUseFasterPath = KTX_FALSE;
-    }
-
-    vkTexture->width = This->baseWidth;
-    vkTexture->height = This->baseHeight;
-    vkTexture->depth = This->baseDepth;
-    vkTexture->imageLayout = finalLayout;
-    vkTexture->imageFormat = vkFormat;
-    vkTexture->levelCount = numImageLevels;
-    vkTexture->layerCount = numImageLayers;
-    vkTexture->viewType = viewType;
-
-    VK_CHECK_RESULT(vkBeginCommandBuffer(vdi->cmdBuffer, &cmdBufBeginInfo));
-
-    if (tiling == VK_IMAGE_TILING_OPTIMAL)
-    {
-        // Create a host-visible staging buffer that contains the raw image data
-        VkBuffer stagingBuffer;
-        VkDeviceMemory stagingMemory;
-        VkBufferImageCopy* copyRegions;
-        VkDeviceSize textureSize;
-        VkBufferCreateInfo bufferCreateInfo = {
-          .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
-          .pNext = NULL
-        };
-        VkImageSubresourceRange subresourceRange;
-        VkFence copyFence;
-        VkFenceCreateInfo fenceCreateInfo = {
-            .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
-            .pNext = NULL,
-            .flags = VK_FLAGS_NONE
-        };
-        VkSubmitInfo submitInfo = {
-            .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
-            .pNext = NULL
-        };
-        ktx_uint8_t* pMappedStagingBuffer;
-        ktx_uint32_t numCopyRegions;
-        user_cbdata_optimal cbData;
-
-
-        textureSize = ktxTexture_GetSize(This);
-        bufferCreateInfo.size = textureSize;
-        if (canUseFasterPath) {
-            /*
-             * Because all array layers and faces are the same size they can
-             * be copied in a single operation so there'll be 1 copy per mip
-             * level.
-             */
-            numCopyRegions = This->numLevels;
-        } else {
-            /*
-             * Have to copy all images individually into the staging
-             * buffer so we can place them at correct multiples of
-             * elementSize and 4 and also need a copy region per image
-             * in case they end up with padding between them.
-             */
-            numCopyRegions = This->isArray ? This->numLevels
-                                  : This->numLevels * This->numFaces;
-            /* 
-             * Add extra space to allow for possible padding described
-             * above. A bit ad-hoc but it's only a small amount of
-             * memory.
-             */
-            bufferCreateInfo.size += numCopyRegions * elementSize * 4;
-        }
-        copyRegions = (VkBufferImageCopy*)malloc(sizeof(VkBufferImageCopy)
-                                                   * numCopyRegions);
-        if (copyRegions == NULL) {
-            return KTX_OUT_OF_MEMORY;
-        }
-
-        // This buffer is used as a transfer source for the buffer copy
-        bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
-        bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-
-        VK_CHECK_RESULT(vkCreateBuffer(vdi->device, &bufferCreateInfo,
-                                       vdi->pAllocator, &stagingBuffer));
-
-        // Get memory requirements for the staging buffer (alignment,
-        // memory type bits)
-        vkGetBufferMemoryRequirements(vdi->device, stagingBuffer, &memReqs);
-
-        memAllocInfo.allocationSize = memReqs.size;
-        // Get memory type index for a host visible buffer
-        memAllocInfo.memoryTypeIndex = ktxVulkanDeviceInfo_getMemoryType(
-                vdi,
-                memReqs.memoryTypeBits,
-                VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
-              | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
-        );
-
-        vResult = vkAllocateMemory(vdi->device, &memAllocInfo,
-                                  vdi->pAllocator, &stagingMemory);
-        if (vResult != VK_SUCCESS) {
-            return KTX_OUT_OF_MEMORY;
-        }
-        VK_CHECK_RESULT(vkBindBufferMemory(vdi->device, stagingBuffer,
-                                           stagingMemory, 0));
-
-        VK_CHECK_RESULT(vkMapMemory(vdi->device, stagingMemory, 0,
-                                    memReqs.size, 0,
-                                    (void **)&pMappedStagingBuffer));
-
-        cbData.offset = 0;
-        cbData.region = copyRegions;
-        cbData.numFaces = This->numFaces;
-        cbData.numLayers = This->numLayers;
-        cbData.dest = pMappedStagingBuffer;
-        cbData.elementSize = elementSize;
-        cbData.numDimensions = This->numDimensions;
-#if defined(_DEBUG)
-        cbData.regionsArrayEnd = copyRegions + numCopyRegions;
-#endif
-        if (canUseFasterPath) {
-            // Bulk load the data to the staging buffer and iterate
-            // over levels.
-
-            if (This->pData) {
-                // Image data has already been loaded. Copy to staging
-                // buffer.
-                assert(This->dataSize <= memAllocInfo.allocationSize);
-                memcpy(pMappedStagingBuffer, This->pData, This->dataSize);
-            } else {
-                /* Load the image data directly into the staging buffer. */
-                /* The strange cast quiets an Xcode warning when building
-                 * for the Generic iOS Device where size_t is 32-bit even
-                 * when building for arm64. */
-                kResult = ktxTexture_LoadImageData(This,
-                                      pMappedStagingBuffer,
-                                      (ktx_size_t)memAllocInfo.allocationSize);
-                if (kResult != KTX_SUCCESS)
-                    return kResult;
-            }
-
-            // Iterate over mip levels to set up the copy regions.
-            kResult = ktxTexture_IterateLevels(This,
-                                               optimalTilingCallback,
-                                               &cbData);
-            // XXX Check for possible errors.
-        } else {
-            // Iterate over face-levels with callback that copies the
-            // face-levels to Vulkan-valid offsets in the staging buffer while
-            // removing padding. Using face-levels minimizes pre-staging-buffer
-            // buffering, in the event the data is not already loaded.
-            if (This->pData) {
-                kResult = ktxTexture_IterateLevelFaces(
-                                            This,
-                                            optimalTilingPadCallback,
-                                            &cbData);
-            } else {
-                kResult = ktxTexture_IterateLoadLevelFaces(
-                                            This,
-                                            optimalTilingPadCallback,
-                                            &cbData);
-                // XXX Check for possible errors.
-            }
-        }
-
-        vkUnmapMemory(vdi->device, stagingMemory);
-
-        // Create optimal tiled target image
-        imageCreateInfo.imageType = imageType;
-        imageCreateInfo.flags = createFlags;
-        imageCreateInfo.format = vkFormat;
-        // numImageLevels ensures enough levels for generateMipmaps.
-        imageCreateInfo.mipLevels = numImageLevels;
-        imageCreateInfo.arrayLayers = numImageLayers;
-        imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
-        imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
-        imageCreateInfo.usage = usageFlags;
-        imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-        imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
-        imageCreateInfo.extent.width = vkTexture->width;
-        imageCreateInfo.extent.height = vkTexture->height;
-        imageCreateInfo.extent.depth = vkTexture->depth;
-
-        VK_CHECK_RESULT(vkCreateImage(vdi->device, &imageCreateInfo,
-                                      vdi->pAllocator, &vkTexture->image));
-
-        vkGetImageMemoryRequirements(vdi->device, vkTexture->image, &memReqs);
-
-        memAllocInfo.allocationSize = memReqs.size;
-
-        memAllocInfo.memoryTypeIndex = ktxVulkanDeviceInfo_getMemoryType(
-                                          vdi, memReqs.memoryTypeBits,
-                                          VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
-        VK_CHECK_RESULT(vkAllocateMemory(vdi->device, &memAllocInfo,
-                                         vdi->pAllocator,
-                                         &vkTexture->deviceMemory));
-        VK_CHECK_RESULT(vkBindImageMemory(vdi->device, vkTexture->image,
-                                          vkTexture->deviceMemory, 0));
-
-        subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-        subresourceRange.baseMipLevel = 0;
-        subresourceRange.levelCount = This->numLevels;
-        subresourceRange.baseArrayLayer = 0;
-        subresourceRange.layerCount = numImageLayers;
-
-        // Image barrier to transition, possibly only the base level, image
-        // layout to TRANSFER_DST_OPTIMAL so it can be used as the copy
-        // destination.
-        setImageLayout(
-            vdi->cmdBuffer,
-            vkTexture->image,
-            VK_IMAGE_LAYOUT_UNDEFINED,
-            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-            subresourceRange);
-
-        // Copy mip levels from staging buffer
-        vkCmdCopyBufferToImage(
-            vdi->cmdBuffer, stagingBuffer,
-            vkTexture->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-            numCopyRegions, copyRegions
-            );
-
-        if (This->generateMipmaps) {
-            generateMipmaps(vkTexture, vdi,
-                            blitFilter, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
-        } else {
-            // Transition image layout to finalLayout after all mip levels
-            // have been copied.
-            // In this case numImageLevels == This->numLevels
-            //subresourceRange.levelCount = numImageLevels;
-            setImageLayout(
-                vdi->cmdBuffer,
-                vkTexture->image,
-                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                finalLayout,
-                subresourceRange);
-        }
-
-        // Submit command buffer containing copy and image layout commands
-        VK_CHECK_RESULT(vkEndCommandBuffer(vdi->cmdBuffer));
-
-        // Create a fence to make sure that the copies have finished before
-        // continuing
-        VK_CHECK_RESULT(vkCreateFence(vdi->device, &fenceCreateInfo,
-                                      vdi->pAllocator, &copyFence));
-
-        submitInfo.commandBufferCount = 1;
-        submitInfo.pCommandBuffers = &vdi->cmdBuffer;
-
-        VK_CHECK_RESULT(vkQueueSubmit(vdi->queue, 1, &submitInfo, copyFence));
-
-        VK_CHECK_RESULT(vkWaitForFences(vdi->device, 1, &copyFence,
-                                        VK_TRUE, DEFAULT_FENCE_TIMEOUT));
-
-        vkDestroyFence(vdi->device, copyFence, vdi->pAllocator);
-
-        // Clean up staging resources
-        vkFreeMemory(vdi->device, stagingMemory, vdi->pAllocator);
-        vkDestroyBuffer(vdi->device, stagingBuffer, vdi->pAllocator);
-    }
-    else
-    {
-        VkImage mappableImage;
-        VkDeviceMemory mappableMemory;
-        VkFence nullFence = { VK_NULL_HANDLE };
-        VkSubmitInfo submitInfo = {
-            .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
-            .pNext = NULL
-        };
-        user_cbdata_linear cbData;
-        PFNKTXITERCB callback;
-
-        imageCreateInfo.imageType = imageType;
-        imageCreateInfo.flags = createFlags;
-        imageCreateInfo.format = vkFormat;
-        imageCreateInfo.extent.width = vkTexture->width;
-        imageCreateInfo.extent.height = vkTexture->height;
-        imageCreateInfo.extent.depth = vkTexture->depth;
-        // numImageLevels ensures enough levels for generateMipmaps.
-        imageCreateInfo.mipLevels = numImageLevels;
-        imageCreateInfo.arrayLayers = numImageLayers;
-        imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
-        imageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
-        imageCreateInfo.usage = usageFlags;
-        imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-        imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
-
-        // Load mip map level 0 to linear tiling image
-        VK_CHECK_RESULT(vkCreateImage(vdi->device, &imageCreateInfo,
-                                      vdi->pAllocator, &mappableImage));
-
-        // Get memory requirements for this image
-        // like size and alignment
-        vkGetImageMemoryRequirements(vdi->device, mappableImage, &memReqs);
-        // Set memory allocation size to required memory size
-        memAllocInfo.allocationSize = memReqs.size;
-
-        // Get memory type that can be mapped to host memory
-        memAllocInfo.memoryTypeIndex = ktxVulkanDeviceInfo_getMemoryType(
-                vdi,
-                memReqs.memoryTypeBits,
-                VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
-
-        // Allocate host memory
-        vResult = vkAllocateMemory(vdi->device, &memAllocInfo, vdi->pAllocator,
-                                  &mappableMemory);
-        if (vResult != VK_SUCCESS) {
-            return KTX_OUT_OF_MEMORY;
-        }
-        VK_CHECK_RESULT(vkBindImageMemory(vdi->device, mappableImage,
-                                          mappableMemory, 0));
-
-        cbData.destImage = mappableImage;
-        cbData.device = vdi->device;
-        cbData.texture = This;
-        callback = canUseFasterPath ?
-                         linearTilingCallback : linearTilingPadCallback;
-
-        // Map image memory
-        VK_CHECK_RESULT(vkMapMemory(vdi->device, mappableMemory, 0,
-                        memReqs.size, 0, (void **)&cbData.dest));
-
-        // Iterate over images to copy texture data into mapped image memory.
-        if (ktxTexture_isActiveStream(This)) {
-            kResult = ktxTexture_IterateLoadLevelFaces(This,
-                                                       callback,
-                                                       &cbData);
-        } else {
-            kResult = ktxTexture_IterateLevelFaces(This,
-                                                   callback,
-                                                   &cbData);
-        }
-        // XXX Check for possible errors
-
-        vkUnmapMemory(vdi->device, mappableMemory);
-
-        // Linear tiled images can be directly used as textures.
-        vkTexture->image = mappableImage;
-        vkTexture->deviceMemory = mappableMemory;
-
-        if (This->generateMipmaps) {
-            generateMipmaps(vkTexture, vdi,
-                            blitFilter,
-                            VK_IMAGE_LAYOUT_PREINITIALIZED);
-        } else {
-            VkImageSubresourceRange subresourceRange;
-            subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-            subresourceRange.baseMipLevel = 0;
-            subresourceRange.levelCount = numImageLevels;
-            subresourceRange.baseArrayLayer = 0;
-            subresourceRange.layerCount = numImageLayers;
-
-           // Transition image layout to finalLayout.
-            setImageLayout(
-                vdi->cmdBuffer,
-                vkTexture->image,
-                VK_IMAGE_LAYOUT_PREINITIALIZED,
-                finalLayout,
-                subresourceRange);
-        }
-
-        // Submit command buffer containing image layout commands
-        VK_CHECK_RESULT(vkEndCommandBuffer(vdi->cmdBuffer));
-
-        submitInfo.waitSemaphoreCount = 0;
-        submitInfo.commandBufferCount = 1;
-        submitInfo.pCommandBuffers = &vdi->cmdBuffer;
-
-        VK_CHECK_RESULT(vkQueueSubmit(vdi->queue, 1, &submitInfo, nullFence));
-        VK_CHECK_RESULT(vkQueueWaitIdle(vdi->queue));
-    }
-    return KTX_SUCCESS;
-}
-
-/** @memberof ktxTexture
- * @~English
- * @brief Create a Vulkan image object from a ktxTexture object.
- *
- * Calls ktxTexture_VkUploadEx() with the most commonly used options:
- * VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT and
- * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.
- * 
- * @sa ktxTexture_VkUploadEx() for details and use that for complete
- *     control.
- */
-KTX_error_code
-ktxTexture_VkUpload(ktxTexture* texture, ktxVulkanDeviceInfo* vdi,
-                    ktxVulkanTexture *vkTexture)
-{
-    return ktxTexture_VkUploadEx(texture, vdi, vkTexture,
-                                 VK_IMAGE_TILING_OPTIMAL,
-                                 VK_IMAGE_USAGE_SAMPLED_BIT,
-                                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
-}
-
-/** @memberof ktxTexture
- * @~English
- * @brief Return the VkFormat enum of a ktxTexture object.
- *
- * @return The VkFormat of the ktxTexture. May return VK_FORMAT_UNDEFINED if
- *         there is no mapping from the GL internalformat and format.
- */
-VkFormat
-ktxTexture_GetVkFormat(ktxTexture* This)
-{
-    VkFormat vkFormat;
-
-    vkFormat = vkGetFormatFromOpenGLInternalFormat(This->glInternalformat);
-    if (vkFormat == VK_FORMAT_UNDEFINED)
-        vkFormat = vkGetFormatFromOpenGLFormat(This->glFormat, This->glType);
-    return vkFormat;
-}
-
-//======================================================================
-//  Utilities
-//======================================================================
-
-/**
- * @internal
- * @~English
- * @brief Create an image memory barrier for changing the layout of an image.
- *
- * The barrier is placed in the passed command buffer. See the Vulkan spec.
- * chapter 11.4 "Image Layout" for details.
- */
-static void
-setImageLayout(
-    VkCommandBuffer cmdBuffer,
-    VkImage image,
-    VkImageLayout oldLayout,
-    VkImageLayout newLayout,
-    VkImageSubresourceRange subresourceRange)
-{
-    // Create an image barrier object
-    VkImageMemoryBarrier imageMemoryBarrier = {
-        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
-        .pNext = NULL,
-         // Some default values
-        .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-        .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED
-    };
-
-    imageMemoryBarrier.oldLayout = oldLayout;
-    imageMemoryBarrier.newLayout = newLayout;
-    imageMemoryBarrier.image = image;
-    imageMemoryBarrier.subresourceRange = subresourceRange;
-
-    // Source layouts (old)
-    // The source access mask controls actions to be finished on the old
-    // layout before it will be transitioned to the new layout.
-    switch (oldLayout)
-    {
-    case VK_IMAGE_LAYOUT_UNDEFINED:
-        // Image layout is undefined (or does not matter).
-        // Only valid as initial layout. No flags required.
-        imageMemoryBarrier.srcAccessMask = 0;
-        break;
-
-    case VK_IMAGE_LAYOUT_PREINITIALIZED:
-        // Image is preinitialized.
-        // Only valid as initial layout for linear images; preserves memory
-        // contents. Make sure host writes have finished.
-        imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
-        break;
-
-    case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
-        // Image is a color attachment.
-        // Make sure writes to the color buffer have finished
-        imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
-        break;
-
-    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
-        // Image is a depth/stencil attachment.
-        // Make sure any writes to the depth/stencil buffer have finished.
-        imageMemoryBarrier.srcAccessMask
-                                = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
-        break;
-
-    case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
-        // Image is a transfer source.
-        // Make sure any reads from the image have finished
-        imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
-        break;
-
-    case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
-        // Image is a transfer destination.
-        // Make sure any writes to the image have finished.
-        imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
-        break;
-
-    case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
-        // Image is read by a shader.
-        // Make sure any shader reads from the image have finished
-        imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
-        break;
-
-    default:
-        /* Value not used by callers, so not supported. */
-        assert(KTX_FALSE);
-    }
-
-    // Target layouts (new)
-    // The destination access mask controls the dependency for the new image
-    // layout.
-    switch (newLayout)
-    {
-    case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
-        // Image will be used as a transfer destination.
-        // Make sure any writes to the image have finished.
-        imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
-        break;
-
-    case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
-        // Image will be used as a transfer source.
-        // Make sure any reads from and writes to the image have finished.
-        imageMemoryBarrier.srcAccessMask |= VK_ACCESS_TRANSFER_READ_BIT;
-        imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
-        break;
-
-    case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
-        // Image will be used as a color attachment.
-        // Make sure any writes to the color buffer have finished.
-        imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
-        imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
-        break;
-
-    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
-        // Image layout will be used as a depth/stencil attachment.
-        // Make sure any writes to depth/stencil buffer have finished.
-        imageMemoryBarrier.dstAccessMask
-                                = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
-        break;
-
-    case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
-        // Image will be read in a shader (sampler, input attachment).
-        // Make sure any writes to the image have finished.
-        if (imageMemoryBarrier.srcAccessMask == 0)
-        {
-            imageMemoryBarrier.srcAccessMask
-                    = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
-        }
-        imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
-        break;
-    default:
-        /* Value not used by callers, so not supported. */
-        assert(KTX_FALSE);
-    }
-
-    // Put barrier on top of pipeline.
-    VkPipelineStageFlags srcStageFlags = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
-    VkPipelineStageFlags destStageFlags = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
-
-    // Add the barrier to the passed command buffer
-    vkCmdPipelineBarrier(
-        cmdBuffer,
-        srcStageFlags,
-        destStageFlags,
-        0,
-        0, NULL,
-        0, NULL,
-        1, &imageMemoryBarrier);
-}
-
-/** @internal
- * @~English
- * @brief Generate mipmaps from base using @c VkCmdBlitImage.
- *
- * Mipmaps are generated by blitting level n from level n-1 as it should
- * be faster than the alternative of blitting all levels from the base level.
- *
- * After generation, the image is transitioned to the layout indicated by
- * @c vkTexture->imageLayout.
- *
- * @param[in] vkTexture     pointer to an object with information about the
- *                          image for which to generate mipmaps.
- * @param[in] vdi           pointer to an object with information about the
- *                          Vulkan device and command buffer to use.
- * @param[in] blitFilter    the type of filter to use in the @c VkCmdBlitImage.
- * @param[in] initialLayout the layout of the image on entry to the function.
- */
-static void
-generateMipmaps(ktxVulkanTexture* vkTexture, ktxVulkanDeviceInfo* vdi,
-                VkFilter blitFilter, VkImageLayout initialLayout)
-{
-    VkImageSubresourceRange subresourceRange;
-    memset(&subresourceRange, 0, sizeof(subresourceRange));
-    subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-    subresourceRange.baseMipLevel = 0;
-    subresourceRange.levelCount = 1;
-    subresourceRange.baseArrayLayer = 0;
-    subresourceRange.layerCount = vkTexture->layerCount;
-
-    // Transition base level to SRC_OPTIMAL for blitting.
-    setImageLayout(
-        vdi->cmdBuffer,
-        vkTexture->image,
-        initialLayout,
-        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-        subresourceRange);
-
-    // Generate the mip chain
-    // ----------------------
-    // Blit level n from level n-1.
-    for (uint32_t i = 1; i < vkTexture->levelCount; i++)
-    {
-        VkImageBlit imageBlit;
-        memset(&imageBlit, 0, sizeof(imageBlit));
-
-        // Source
-        imageBlit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-        imageBlit.srcSubresource.layerCount = vkTexture->layerCount;
-        imageBlit.srcSubresource.mipLevel = i-1;
-        imageBlit.srcOffsets[1].x = MAX(1, vkTexture->width >> (i - 1));
-        imageBlit.srcOffsets[1].y = MAX(1, vkTexture->height >> (i - 1));
-        imageBlit.srcOffsets[1].z = MAX(1, vkTexture->depth >> (i - 1));;
-
-        // Destination
-        imageBlit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-        imageBlit.dstSubresource.layerCount = 1;
-        imageBlit.dstSubresource.mipLevel = i;
-        imageBlit.dstOffsets[1].x = MAX(1, vkTexture->width >> i);
-        imageBlit.dstOffsets[1].y = MAX(1, vkTexture->height >> i);
-        imageBlit.dstOffsets[1].z = MAX(1, vkTexture->depth >> i);
-
-        VkImageSubresourceRange mipSubRange;
-        memset(&mipSubRange, 0, sizeof(mipSubRange));
-
-        mipSubRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-        mipSubRange.baseMipLevel = i;
-        mipSubRange.levelCount = 1;
-        mipSubRange.layerCount = vkTexture->layerCount;
-
-        // Transiton current mip level to transfer dest
-        setImageLayout(
-            vdi->cmdBuffer,
-            vkTexture->image,
-            VK_IMAGE_LAYOUT_UNDEFINED,
-            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-            mipSubRange);
-
-        // Blit from previous level
-        vkCmdBlitImage(
-            vdi->cmdBuffer,
-            vkTexture->image,
-            VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-            vkTexture->image,
-            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-            1,
-            &imageBlit,
-            blitFilter);
-
-        // Transiton current mip level to transfer source for read in
-        // next iteration.
-        setImageLayout(
-            vdi->cmdBuffer,
-            vkTexture->image,
-            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-            VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-            mipSubRange);
-    }
-
-    // After the loop, all mip layers are in TRANSFER_SRC layout.
-    // Transition all to final layout.
-    subresourceRange.levelCount = vkTexture->levelCount;
-    setImageLayout(
-        vdi->cmdBuffer,
-        vkTexture->image,
-        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-        vkTexture->imageLayout,
-        subresourceRange);
-}
-
-//======================================================================
-//  ktxVulkanTexture utilities
-//======================================================================
-
-/**
- * @memberof ktxVulkanTexture
- * @~English
- * @brief Destructor for the object returned when loading a texture image.
- *
- * Frees the Vulkan resources created when the texture image was loaded.
- *
- * @param vkTexture  pointer to the ktxVulkanTexture to be destructed.
- * @param device     handle to the Vulkan logical device to which the texture was
- *                   loaded.
- * @param pAllocator pointer to the allocator used during loading.
- */
-void
-ktxVulkanTexture_Destruct(ktxVulkanTexture* vkTexture, VkDevice device,
-                          const VkAllocationCallbacks* pAllocator)
-{
-    vkDestroyImage(device, vkTexture->image, pAllocator);
-    vkFreeMemory(device, vkTexture->deviceMemory, pAllocator);
-}
-
-/** @} */
diff --git a/external/KTX-Software-master/lib/writer.c b/external/KTX-Software-master/lib/writer.c
deleted file mode 100644
index 6c5166e7efaa86c8b4b060052d9870f9cc2f78ff..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/writer.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/**
- * @internal
- * @file writer.c
- * @~English
- *
- * @brief Functions for creating KTX-format files from a set of images.
- *
- * @author Mark Callow, HI Corporation
- */
-
-/*
- * ©2018 Mark Callow.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifdef _WIN32
-#define _CRT_SECURE_NO_WARNINGS
-#endif
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "ktx.h"
-#include "ktxint.h"
-#include "stream.h"
-#include "filestream.h"
-#include "memstream.h"
-
-/**
- * @defgroup writer Writer
- * @brief Write KTX-formatted data.
- * @{
- */
-
-/**
- * @internal
- * @memberof ktxTexture @private
- * @~English
- * @brief Set image for level, layer, faceSlice from a ktxStream source.
- *
- * @param[in] This      pointer to the target ktxTexture object.
- * @param[in] level     mip level of the image to set.
- * @param[in] layer     array layer of the image to set.
- * @param[in] faceSlice cube map face or depth slice of the image to set.
- * @param[in] src       ktxStream pointer to the source.
- * @param[in] srcSize   size of the source image in bytes.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p This or @p src is NULL.
- * @exception KTX_INVALID_VALUE @p srcSize != the expected image size for the
- *                              specified level, layer & faceSlice.
- * @exception KTX_INVALID_OPERATION
- *                              No storage was allocated when the texture was
- *                              created.
- */
-KTX_error_code
-ktxTexture_setImageFromStream(ktxTexture* This, ktx_uint32_t level,
-                              ktx_uint32_t layer, ktx_uint32_t faceSlice,
-                              ktxStream* src, ktx_size_t srcSize)
-{
-    ktx_uint32_t packedRowBytes, rowBytes, rowPadding, numRows;
-    ktx_size_t packedBytes, unpackedBytes;
-    ktx_size_t imageOffset;
-#if (KTX_GL_UNPACK_ALIGNMENT != 4)
-    ktx_uint32_t faceLodPadding;
-#endif
-    
-    if (!This || !src)
-        return KTX_INVALID_VALUE;
-    
-    if (!This->pData)
-        return KTX_INVALID_OPERATION;
-    
-    ktxTexture_GetImageOffset(This, level, layer, faceSlice, &imageOffset);
-
-    if (This->isCompressed) {
-        packedBytes = ktxTexture_GetImageSize(This, level);
-        rowPadding = 0;
-        // These 2 are not used when rowPadding == 0. Quiets compiler warning.
-        packedRowBytes = 0;
-        rowBytes = 0;
-    } else {
-        ktxTexture_rowInfo(This, level, &numRows, &rowBytes, &rowPadding);
-        unpackedBytes = rowBytes * numRows;
-        if (rowPadding) {
-            packedRowBytes = rowBytes - rowPadding;
-            packedBytes = packedRowBytes * numRows;
-        } else {
-            packedRowBytes = rowBytes;
-            packedBytes = unpackedBytes;
-        }
-    }
-    
-    if (srcSize != packedBytes)
-        return KTX_INVALID_OPERATION;
-    // The above will catch a flagrantly invalid srcSize. This is an
-    // additional check of the internal calculations.
-    assert (imageOffset + srcSize <= This->dataSize);
-    
-#if (KTX_GL_UNPACK_ALIGNMENT != 4)
-    faceLodPadding = _KTX_PAD4_LEN(faceLodSize);
-#endif
-    
-    if (rowPadding == 0) {
-        /* Can copy whole image at once */
-        src->read(src, This->pData + imageOffset, srcSize);
-    } else {
-        /* Copy the rows individually, padding each one */
-        ktx_uint32_t row;
-        ktx_uint8_t* dst = This->pData + imageOffset;
-        ktx_uint8_t pad[4] = { 0, 0, 0, 0 };
-        for (row = 0; row < numRows; row++) {
-            ktx_uint32_t rowOffset = rowBytes * row;
-            src->read(src, dst + rowOffset, packedRowBytes);
-            memcpy(dst + rowOffset + packedRowBytes, pad, rowPadding);
-        }
-    }
-#if (KTX_GL_UNPACK_ALIGNMENT != 4)
-    /*
-     * When KTX_GL_UNPACK_ALIGNMENT == 4, rows, and therefore everything else,
-     * are always 4-byte aligned and faceLodPadding is always 0. It is always
-     * 0 for compressed formats too because they all have multiple-of-4 block
-     * sizes.
-     */
-    if (faceLodPadding)
-        memcpy(This->pData + faceLodSize, pad, faceLodPadding);
-#endif
-    return KTX_SUCCESS;
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Set image for level, layer, faceSlice from a stdio stream source.
- *
- * Uncompressed images read from the stream are expected to have their rows
- * tightly packed as is the norm for most image file formats. The copied image
- * is padded as necessary to achieve the KTX-specified row alignment. No
- * padding is done if the ktxTexture's @c isCompressed field is @c KTX_TRUE.
- *
- * Level, layer, faceSlice rather than offset are specified to enable some
- * validation.
- *
- * @param[in] This      pointer to the target ktxTexture object.
- * @param[in] level     mip level of the image to set.
- * @param[in] layer     array layer of the image to set.
- * @param[in] faceSlice cube map face or depth slice of the image to set.
- * @param[in] src       stdio stream pointer to the source.
- * @param[in] srcSize   size of the source image in bytes.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p This or @p src is NULL.
- * @exception KTX_INVALID_VALUE @p srcSize != the expected image size for the
- *                              specified level, layer & faceSlice.
- * @exception KTX_INVALID_OPERATION
- *                              No storage was allocated when the texture was
- *                              created.
- */
-KTX_error_code
-ktxTexture_SetImageFromStdioStream(ktxTexture* This, ktx_uint32_t level,
-                                   ktx_uint32_t layer, ktx_uint32_t faceSlice,
-                                   FILE* src, ktx_size_t srcSize)
-{
-    ktxStream srcstr;
-    KTX_error_code result;
-    
-    result = ktxFileStream_construct(&srcstr, src, KTX_FALSE);
-    if (result != KTX_SUCCESS)
-        return result;
-    result = ktxTexture_setImageFromStream(This, level, layer, faceSlice,
-                                           &srcstr, srcSize);
-    ktxFileStream_destruct(&srcstr);
-    return result;
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Set image for level, layer, faceSlice from an image in memory.
- *
- * Uncompressed images in memory are expected to have their rows tightly packed
- * as is the norm for most image file formats. The copied image is padded as
- * necessary to achieve the KTX-specified row alignment. No padding is done if
- * the ktxTexture's @c isCompressed field is @c KTX_TRUE.
- *
- * Level, layer, faceSlice rather than offset are specified to enable some
- * validation.
- *
- * @warning Do not use @c memcpy for this as it will not pad when necessary.
- *
- * @param[in] This      pointer to the target ktxTexture object.
- * @param[in] level     mip level of the image to set.
- * @param[in] layer     array layer of the image to set.
- * @param[in] faceSlice cube map face or depth slice of the image to set.
- * @param[in] src       pointer to the image source in memory.
- * @param[in] srcSize   size of the source image in bytes.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p This or @p src is NULL.
- * @exception KTX_INVALID_VALUE @p srcSize != the expected image size for the
- *                              specified level, layer & faceSlice.
- * @exception KTX_INVALID_OPERATION
- *                              No storage was allocated when the texture was
- *                              created.
- */
-KTX_error_code
-ktxTexture_SetImageFromMemory(ktxTexture* This, ktx_uint32_t level,
-                              ktx_uint32_t layer, ktx_uint32_t faceSlice,
-                              const ktx_uint8_t* src, ktx_size_t srcSize)
-{
-    ktxStream srcstr;
-    KTX_error_code result;
-    
-    result = ktxMemStream_construct_ro(&srcstr, src, srcSize);
-    if (result != KTX_SUCCESS)
-        return result;
-    result = ktxTexture_setImageFromStream(This, level, layer, faceSlice,
-                                           &srcstr, srcSize);
-    ktxMemStream_destruct(&srcstr);
-    return result;
-}
-
-/**
- * @internal
- * @memberof ktxTexture @private
- * @~English
- * @brief Write a ktxTexture object to a ktxStream in KTX format.
- *
- * @param[in] This      pointer to the target ktxTexture object.
- * @param[in] dststr    destination ktxStream.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p This or @p dststr is NULL.
- * @exception KTX_INVALID_OPERATION
- *                              The ktxTexture does not contain any image data.
- * @exception KTX_FILE_OVERFLOW The file exceeded the maximum size supported by
- *                              the system.
- * @exception KTX_FILE_WRITE_ERROR
- *                              An error occurred while writing the file.
- */
-static KTX_error_code
-ktxTexture_writeToStream(ktxTexture* This, ktxStream* dststr)
-{
-    KTX_header header = KTX_IDENTIFIER_REF;
-    KTX_error_code result = KTX_SUCCESS;
-    ktx_uint32_t kvdLen;
-    ktx_uint8_t* pKvd;
-    ktx_uint32_t level, levelOffset;
-    
-    if (!dststr) {
-        return KTX_INVALID_VALUE;
-    }
-    
-    if (This->pData == NULL)
-        return KTX_INVALID_OPERATION;
-
-    //endianess int.. if this comes out reversed, all of the other ints will too.
-    header.endianness = KTX_ENDIAN_REF;
-    header.glInternalformat = This->glInternalformat;
-    header.glFormat = This->glFormat;
-    header.glBaseInternalformat = This->glBaseInternalformat;
-    header.glType = This->glType;
-    header.glTypeSize = ktxTexture_glTypeSize(This);
-    header.pixelWidth = This->baseWidth;
-    header.pixelHeight = This->baseHeight;
-    header.pixelDepth = This->baseDepth;
-    header.numberOfArrayElements = This->isArray ? This->numLayers : 0;
-    assert (This->isCubemap ? This->numFaces == 6 : This->numFaces == 1);
-    header.numberOfFaces = This->numFaces;
-    assert (This->generateMipmaps ? This->numLevels == 1 : This->numLevels >= 1);
-    header.numberOfMipmapLevels = This->generateMipmaps ? 0 : This->numLevels;
-    
-    ktxHashList_Serialize(&This->kvDataHead, &kvdLen, &pKvd);
-    header.bytesOfKeyValueData = kvdLen;
-
-    //write header
-    result = dststr->write(dststr, &header, sizeof(KTX_header), 1);
-    if (result != KTX_SUCCESS)
-        return result;
-    
-    //write keyValueData
-    if (kvdLen != 0) {
-        assert(pKvd != NULL);
-
-        result = dststr->write(dststr, pKvd, 1, kvdLen);
-        free(pKvd);
-        if (result != KTX_SUCCESS)
-            return result;
-    }
-    
-    /* Write the image data */
-    for (level = 0, levelOffset=0; level < This->numLevels; ++level)
-    {
-        ktx_uint32_t faceLodSize, layer, levelDepth, numImages;
-        ktx_size_t imageSize;
-        
-        faceLodSize = (ktx_uint32_t)ktxTexture_faceLodSize(This, level);
-        imageSize = ktxTexture_GetImageSize(This, level);
-        levelDepth = MAX(1, This->baseDepth >> level);
-        if (This->isCubemap && !This->isArray)
-            numImages = This->numFaces;
-        else
-            numImages = This->isCubemap ? This->numFaces : levelDepth;
-        
-        result = dststr->write(dststr, &faceLodSize, sizeof(faceLodSize), 1);
-        if (result != KTX_SUCCESS)
-            goto cleanup;
-
-        for (layer = 0; layer < This->numLayers; layer++) {
-            ktx_uint32_t faceSlice;
-            
-            for (faceSlice = 0; faceSlice < numImages; faceSlice++) {
-                result = dststr->write(dststr, This->pData + levelOffset,
-                                       imageSize, 1);
-                levelOffset += (ktx_uint32_t)imageSize;
-            }
-        }
-    }
-    
-cleanup:
-    return result;
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Write a ktxTexture object to a stdio stream in KTX format.
- *
- * @param[in] This      pointer to the target ktxTexture object.
- * @param[in] dstsstr   destination stdio stream.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p This or @p dstsstr is NULL.
- * @exception KTX_INVALID_OPERATION
- *                              The ktxTexture does not contain any image data.
- * @exception KTX_FILE_OVERFLOW The file exceeded the maximum size supported by
- *                              the system.
- * @exception KTX_FILE_WRITE_ERROR
- *                              An error occurred while writing the file.
- */
-KTX_error_code
-ktxTexture_WriteToStdioStream(ktxTexture* This, FILE* dstsstr)
-{
-    ktxStream stream;
-    KTX_error_code result = KTX_SUCCESS;
-    
-    if (!This)
-        return KTX_INVALID_VALUE;
-    
-    result = ktxFileStream_construct(&stream, dstsstr, KTX_FALSE);
-    if (result != KTX_SUCCESS)
-        return result;
-    
-    return ktxTexture_writeToStream(This, &stream);
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Write a ktxTexture object to a named file in KTX format.
- *
- * @param[in] This      pointer to the target ktxTexture object.
- * @param[in] dstname   destination file name.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p This or @p dstname is NULL.
- * @exception KTX_INVALID_OPERATION
- *                              The ktxTexture does not contain any image data.
- * @exception KTX_FILE_OVERFLOW The file exceeded the maximum size supported by
- *                              the system.
- * @exception KTX_FILE_WRITE_ERROR
- *                              An error occurred while writing the file.
- */
-KTX_error_code
-ktxTexture_WriteToNamedFile(ktxTexture* This, const char* const dstname)
-{
-    KTX_error_code result;
-    FILE* dst;
-
-    if (!This)
-        return KTX_INVALID_VALUE;
-
-    dst = fopen(dstname, "wb");
-    if (dst) {
-        result = ktxTexture_WriteToStdioStream(This, dst);
-        fclose(dst);
-    } else
-        result = KTX_FILE_OPEN_FAILED;
-    
-    return result;
-}
-
-/**
- * @memberof ktxTexture
- * @~English
- * @brief Write a ktxTexture object to block of memory in KTX format.
- *
- * Memory is allocated by the function and the caller is responsible for
- * freeing it.
- *
- * @param[in]     This       pointer to the target ktxTexture object.
- * @param[in,out] ppDstBytes pointer to location to write the address of
- *                           the destination memory. The Application is
- *                           responsible for freeing this memory.
- * @param[in,out] pSize      pointer to location to write the size in bytes of
- *                           the KTX data.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p This, @p ppDstBytes or @p pSize is NULL.
- * @exception KTX_INVALID_OPERATION
- *                              The ktxTexture does not contain any image data.
- * @exception KTX_FILE_OVERFLOW The file exceeded the maximum size supported by
- *                              the system.
- * @exception KTX_FILE_WRITE_ERROR
- *                              An error occurred while writing the file.
- */
-KTX_error_code
-ktxTexture_WriteToMemory(ktxTexture* This,
-                         ktx_uint8_t** ppDstBytes, ktx_size_t* pSize)
-{
-    struct ktxStream dststr;
-    KTX_error_code result;
-    ktx_size_t strSize;
-
-    if (!This || !ppDstBytes || !pSize)
-        return KTX_INVALID_VALUE;
-
-    *ppDstBytes = NULL;
-    
-    result = ktxMemStream_construct(&dststr, KTX_FALSE);
-    if (result != KTX_SUCCESS)
-        return result;
-    
-    result = ktxTexture_writeToStream(This, &dststr);
-    if(result != KTX_SUCCESS)
-    {
-        ktxMemStream_destruct(&dststr);
-        return result;
-    }
-    
-    ktxMemStream_getdata(&dststr, ppDstBytes);
-    dststr.getsize(&dststr, &strSize);
-    *pSize = (GLsizei)strSize;
-    /* This function does not free the memory pointed at by the
-     * value obtained from ktxMemStream_getdata() thanks to the
-     * KTX_FALSE passed to the constructor above.
-     */
-    ktxMemStream_destruct(&dststr);
-    return KTX_SUCCESS;
-
-}
-
-/** @} */
-
diff --git a/external/KTX-Software-master/lib/writer_v1.c b/external/KTX-Software-master/lib/writer_v1.c
deleted file mode 100644
index 50856587bd07952dd4a721ce6d1cf19a66ef2bbe..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/lib/writer_v1.c
+++ /dev/null
@@ -1,708 +0,0 @@
-/* -*- tab-width: 4; -*- */
-/* vi: set sw=2 ts=4 expandtab: */
-
-/* $Id: 687889ad2b1bee58a6d439ef4d6c10830a733418 $ */
-
-/*
- * ©2010-2018 Mark Callow.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @internal
- * @file writer.c
- * @~English
- *
- * @brief V1 API functions for creating KTX-format files from a set of images.
- *
- * Keep the v1 API implementation as is because reimplementing it in terms
- * of the v2 API would use too much memory. This is because this API expects
- * all the images to already be loaded in memory and the v2 api would load
- * them into another memory buffer prior to writing the file.
- *
- * @author Mark Callow, when at HI Corporation
- */
-
-#ifdef _WIN32
-#define _CRT_SECURE_NO_WARNINGS
-#endif
-
-#include <assert.h>
-#include <limits.h>
-
-#include "GL/glcorearb.h"
-#include "ktx.h"
-#include "ktxint.h"
-#include "stream.h"
-#include "filestream.h"
-#include "memstream.h"
-#include "gl_format.h"
-
-static GLenum getFormatFromInternalFormatLegacy(GLenum internalFormat);
-static GLenum getTypeFromInternalFormatLegacy(GLenum internalFormat);
-static void getFormatSizeLegacy(GLenum internalFormat,
-                                GlFormatSize* formatSize);
-
-/**
- * @internal
- * @ingroup writer
- * @~English
- * @deprecated Use ktxTexture_writeToStream().
- * @brief Write image(s) in a KTX-format to a ktxStream.
- *
- * @param [in] stream       pointer to the ktxStream from which to load.
- * @param [in] textureInfo  pointer to a KTX_texture_info structure providing
- *                          information about the images to be included in
- *                          the KTX file.
- * @param [in] bytesOfKeyValueData
- *                          specifies the number of bytes of key-value data.
- * @param [in] keyValueData a pointer to the keyValue data.
- * @param [in] numImages    number of images in the following array
- * @param [in] images       array of KTX_image_info providing image size and
- *                          data.
- *
- * @return  KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @c glTypeSize in @p textureInfo is not 1, 2, or
- *                              4 or is different from the size of the type
- *                              specified in @c glType.
- * @exception KTX_INVALID_VALUE @c pixelWidth in @p textureInfo is 0 or
- *                              pixelDepth != 0 && pixelHeight == 0.
- * @exception KTX_INVALID_VALUE In @p textureInfo, @c numberOfFaces != 1 or
- *                              numberOfFaces != 6 or numberOfArrayElements
- *                              or numberOfMipmapLevels are < 0.
- * @exception KTX_INVALID_VALUE @c glType in @p textureInfo is an unrecognized
- *                              type.
- * @exception KTX_INVALID_OPERATION
- *                              In @p textureInfo, numberOfFaces == 6 and
- *                              images are either not 2D or are not square.
- * @exception KTX_INVALID_OPERATION
- *                              @p numImages is insufficient for the specified
- *                              number of mipmap levels and faces.
- * @exception KTX_INVALID_OPERATION
- *                              The size of a provided image is different than
- *                              that required for the specified width, height
- *                              or depth or for the mipmap level being
- *                              processed.
- * @exception KTX_INVALID_OPERATION
- *                              @c glType and @c glFormat in @p textureInfo are
- *                              mismatched. See OpenGL 4.4 specification
- *                              section 8.4.4 and table 8.5.
- * @exception KTX_FILE_WRITE_ERROR
- *                              A system error occurred while writing the file.
- * @exception KTX_OUT_OF_MEMORY System failed to allocate sufficient memory.
- */
-static
-KTX_error_code
-ktxWriteKTXS(struct ktxStream *stream, const KTX_texture_info* textureInfo,
-             GLsizei bytesOfKeyValueData, const void* keyValueData,
-             GLuint numImages, KTX_image_info images[])
-{
-    KTX_header header = KTX_IDENTIFIER_REF;
-    GLuint i, level, dimension, cubemap = 0;
-    GLuint numMipmapLevels, numArrayElements;
-    GLbyte pad[4] = { 0, 0, 0, 0 };
-    KTX_error_code result = KTX_SUCCESS;
-    GLboolean compressed = GL_FALSE;
-    GLuint groupBytes;
-
-    if (!stream) {
-        return KTX_INVALID_VALUE;
-    }
-
-    /* endianess int.. if this comes out reversed, all of the other ints will
-     * too.
-     */
-    header.endianness = KTX_ENDIAN_REF;
-    header.glType = textureInfo->glType;
-    header.glTypeSize = textureInfo->glTypeSize;
-    header.glFormat = textureInfo->glFormat;
-    header.glInternalformat = textureInfo->glInternalFormat;
-    header.glBaseInternalformat = textureInfo->glBaseInternalFormat;
-    header.pixelWidth = textureInfo->pixelWidth;
-    header.pixelHeight = textureInfo->pixelHeight;
-    header.pixelDepth = textureInfo->pixelDepth;
-    header.numberOfArrayElements = textureInfo->numberOfArrayElements;
-    header.numberOfFaces = textureInfo->numberOfFaces;
-    header.numberOfMipmapLevels = textureInfo->numberOfMipmapLevels;
-    header.bytesOfKeyValueData = bytesOfKeyValueData;
-
-    /* Do some sanity checking */
-    if (header.glTypeSize != 1 &&
-        header.glTypeSize != 2 &&
-        header.glTypeSize != 4)
-    {
-        /* Only 8, 16, and 32-bit types are supported for byte-swapping.
-         * See UNPACK_SWAP_BYTES & table 8.4 in the OpenGL 4.4 spec.
-         */
-        return KTX_INVALID_VALUE;
-    }
-
-    if (header.glType == 0 || header.glFormat == 0)
-    {
-        if (header.glType + header.glFormat != 0) {
-            /* either both or neither of glType & glFormat must be zero */
-            return KTX_INVALID_VALUE;
-        } else
-            compressed = GL_TRUE;
-    }
-    else
-    {
-        GlFormatSize formatInfo;
-        GLenum expectedFormat, expectedType;
-        
-        expectedFormat = getFormatFromInternalFormatLegacy(header.glInternalformat);
-        if (expectedFormat == GL_INVALID_VALUE
-            || expectedFormat != header.glFormat)
-            return KTX_INVALID_OPERATION;
-        expectedType = getTypeFromInternalFormatLegacy(header.glInternalformat);
-        if (expectedType == GL_INVALID_VALUE
-            || expectedType != header.glType)
-            return KTX_INVALID_OPERATION;
-        getFormatSizeLegacy(header.glInternalformat, &formatInfo);
-        groupBytes = formatInfo.blockSizeInBits / CHAR_BIT;
-    }
-
-
-    /* Check texture dimensions. KTX files can store 8 types of textures:
-     * 1D, 2D, 3D, cube, and array variants of these. There is currently
-     * no GL extension that would accept 3D array array textures but we'll
-     * let such files be created.
-     */
-    if ((header.pixelWidth == 0) ||
-        (header.pixelDepth > 0 && header.pixelHeight == 0))
-    {
-        /* texture must have width */
-        /* texture must have height if it has depth */
-        return KTX_INVALID_VALUE;
-    }
-    if (header.pixelHeight > 0 && header.pixelDepth > 0)
-        dimension = 3;
-    else if (header.pixelHeight > 0)
-        dimension = 2;
-    else
-        dimension = 1;
-
-    if (header.numberOfFaces != 1 && header.pixelDepth != 0)
-    {
-        /* No 3D cubemaps so either faces or depth must be 1. */
-            return KTX_INVALID_OPERATION;
-    }
-
-    if (header.numberOfFaces == 6)
-    {
-        if (dimension != 2)
-        {
-            /* cube map needs 2D faces */
-            return KTX_INVALID_OPERATION;
-        }
-        if (header.pixelWidth != header.pixelHeight)
-        {
-            /* cube maps require square images */
-            return KTX_INVALID_OPERATION;
-        }
-    }
-    else if (header.numberOfFaces != 1)
-    {
-        /* numberOfFaces must be either 1 or 6 */
-        return KTX_INVALID_VALUE;
-    }
- 
-    if (header.numberOfArrayElements == 0)
-        numArrayElements = 1;
-    else
-        numArrayElements = header.numberOfArrayElements;
-    
-    if (header.numberOfFaces == 6)
-        cubemap = 1;
-
-    /* Check number of mipmap levels */
-    if (header.numberOfMipmapLevels == 0)
-    {
-        numMipmapLevels = 1;
-    }
-    else
-        numMipmapLevels = header.numberOfMipmapLevels;
-    if (numMipmapLevels > 1) {
-        GLuint max_dim = MAX(MAX(header.pixelWidth, header.pixelHeight), header.pixelDepth);
-        if (max_dim < ((GLuint)1 << (header.numberOfMipmapLevels - 1)))
-        {
-            /* Can't have more mip levels than 1 + log2(max(width, height, depth)) */
-            return KTX_INVALID_VALUE;
-        }
-    }
-
-    if (numImages < numMipmapLevels * header.numberOfFaces)
-    {
-        /* Not enough images */
-        return KTX_INVALID_OPERATION;
-    }
-
-    //write header
-    result = stream->write(stream, &header, sizeof(KTX_header), 1);
-    if (result != KTX_SUCCESS)
-        return result;
-
-    //write keyValueData
-    if (bytesOfKeyValueData != 0) {
-        if (keyValueData == NULL)
-            return KTX_INVALID_OPERATION;
-
-        result = stream->write(stream, keyValueData, 1, bytesOfKeyValueData);
-        if (result != KTX_SUCCESS)
-            return result;
-    }
-
-    /* Write the image data */
-    for (level = 0, i = 0; level < numMipmapLevels; ++level)
-    {
-        GLuint faceSlice, faceLodSize;
-#if (KTX_GL_UNPACK_ALIGNMENT != 4)
-        GLuint faceLodPadding;
-#endif
-        GLuint pixelWidth, pixelHeight, pixelDepth;
-        GLsizei imageBytes, packedImageBytes;
-        GLsizei packedRowBytes, rowBytes, rowPadding;
-        GLuint numImages;
-
-        pixelWidth  = MAX(1, header.pixelWidth  >> level);
-        pixelHeight = MAX(1, header.pixelHeight >> level);
-        pixelDepth  = MAX(1, header.pixelDepth  >> level);
-
-        /* Calculate face sizes for this LoD based on glType, glFormat, width & height */
-        packedImageBytes = groupBytes
-                           * pixelWidth
-                           * pixelHeight;
-
-        rowPadding = 0;
-        packedRowBytes = groupBytes * pixelWidth;
-        /* KTX format specifies UNPACK_ALIGNMENT==4 */
-        /* GL spec: rows are not to be padded when elementBytes != 1, 2, 4 or 8.
-         * As GL currently has no such elements, no test is necessary.
-         */
-        if (!compressed) {
-            rowBytes = _KTX_PAD_UNPACK_ALIGN(packedRowBytes);
-            rowPadding = rowBytes - packedRowBytes;
-        }
-        if (rowPadding == 0) {
-            imageBytes = packedImageBytes;
-        } else {
-            /* Need to pad the rows to meet the required UNPACK_ALIGNMENT */
-            imageBytes = rowBytes * pixelHeight;
-        }
-
-        if (textureInfo->numberOfArrayElements == 0 && cubemap) {
-            /* Non-array cubemap. */
-            numImages = 6;
-            faceLodSize = imageBytes;
-        } else {
-            numImages = cubemap ? 6 : pixelDepth;
-            numImages *= numArrayElements;
-            faceLodSize = imageBytes * numImages;
-        }
-#if (KTX_GL_UNPACK_ALIGNMENT != 4)
-        faceLodPadding = _KTX_PAD4_LEN(faceLodSize);
-#endif
- 
-        result = stream->write(stream, &faceLodSize, sizeof(faceLodSize), 1);
-        if (result != KTX_SUCCESS)
-            goto cleanup;
-
-        for (faceSlice = 0; faceSlice < numImages; ++faceSlice, ++i) {
-            if (!compressed) {
-                /* Sanity check. */
-                if (images[i].size != packedImageBytes) {
-                    result = KTX_INVALID_OPERATION;
-                    goto cleanup;
-                }
-            }
-            if (rowPadding == 0) {
-                /* Can write whole face at once */
-                result = stream->write(stream, images[i].data, images[i].size,
-                                       1);
-                if (result != KTX_SUCCESS)
-                    goto cleanup;
-            } else {
-                /* Write the rows individually, padding each one */
-                GLuint row;
-                GLuint numRows = pixelHeight;
-                for (row = 0; row < numRows; row++) {
-                    result = stream->write(stream,
-                                            &images[i].data[row*packedRowBytes],
-                                            packedRowBytes, 1);
-                    if (result != KTX_SUCCESS)
-                        goto cleanup;
-
-                    result = stream->write(stream, pad, sizeof(GLbyte),
-                                              rowPadding);
-                    if (result != KTX_SUCCESS)
-                        goto cleanup;
-                }
-            }
-#if (KTX_GL_UNPACK_ALIGNMENT != 4)
-            /*
-             * When KTX_GL_UNPACK_ALIGNMENT == 4, rows, and therefore everything
-             * else, are always 4-byte aligned and faceLodPadding is always 0.
-             * It is always 0 for compressed formats too because they all have
-             * multiple-of-4 block sizes.
-             */
-            if (faceLodPadding) {
-                result = stream->write(stream, pad, sizeof(GLbyte),
-                                       faceLodPadding);
-                if (result != KTX_SUCCESS)
-                    goto cleanup;
-            }
-#endif
-        }
-    }
-
-cleanup:
-    return result;
-}
-
-/**
- * @~English
- * @ingroup writer
- * @deprecated Use ktxTexture_WriteToStdioStream().
- * @brief Write image(s) in KTX format to a stdio FILE stream.
- *
- * @note textureInfo directly reflects what is written to the KTX file
- *       header. That is @c numberOfArrayElements should be 0 for non arrays;
- *       @c numMipmapLevels should be 0 to request generateMipmaps and @c type,
- *       @c format & @c typesize should be 0 for compressed textures.
- *
- * @param[in] file         pointer to the FILE stream to write to.
- * @param[in] textureInfo  pointer to a KTX_texture_info structure providing
- *                         information about the images to be included in
- *                         the KTX file.
- * @param[in] bytesOfKeyValueData
- *                         specifies the number of bytes of key-value data.
- * @param[in] keyValueData a pointer to the keyValue data.
- * @param[in] numImages    number of images in the following array
- * @param[in] images       array of KTX_image_info providing image size and
- *                         data.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @c glTypeSize in @p textureInfo is not 1, 2, or
- *                              4 or is different from the size of the type
- *                              specified in @c glType.
- * @exception KTX_INVALID_VALUE @c pixelWidth in @p textureInfo is 0 or
- *                              pixelDepth != 0 && pixelHeight == 0.
- * @exception KTX_INVALID_VALUE In @p textureInfo, @c numberOfFaces != 1 or
- *                              numberOfFaces != 6 or numberOfArrayElements
- *                              or numberOfMipmapLevels are < 0.
- * @exception KTX_INVALID_VALUE @c glType in @p textureInfo is an unrecognized
- *                              type.
- * @exception KTX_INVALID_OPERATION
- *                              In @p textureInfo, numberOfFaces == 6 and
- *                              images are either not 2D or are not square.
- * @exception KTX_INVALID_OPERATION
- *                              @p numImages is insufficient for the specified
- *                              number of mipmap levels and faces.
- * @exception KTX_INVALID_OPERATION
- *                              The size of a provided image is different than
- *                              that required for the specified width, height
- *                              or depth or for the mipmap level being
- *                              processed.
- * @exception KTX_INVALID_OPERATION
- *                              @c glType and @c glFormat in @p textureInfo are
- *                              mismatched. See OpenGL 4.4 specification
- *                              section 8.4.4 and table 8.5.
- * @exception KTX_FILE_WRITE_ERROR
- *                              A system error occurred while writing the file.
- * @exception KTX_OUT_OF_MEMORY System failed to allocate sufficient memory.
- */
-KTX_error_code
-ktxWriteKTXF(FILE *file, const KTX_texture_info* textureInfo,
-                         GLsizei bytesOfKeyValueData, const void* keyValueData,
-                         GLuint numImages, KTX_image_info images[])
-{
-    struct ktxStream stream;
-    KTX_error_code result;
-    
-    result = ktxFileStream_construct(&stream, file, KTX_FALSE);
-    if (result != KTX_SUCCESS)
-        return result;
-    result = ktxWriteKTXS(&stream, textureInfo, bytesOfKeyValueData, keyValueData,
-                          numImages, images);
-    stream.destruct(&stream);
-    return result;
-}
-
-/**
- * @~English
- * @ingroup writer
- * @deprecated Use ktxTexture_WriteToNamedFile().
- * @brief Write image(s) in KTX format to a file on disk.
- *
- * @note textureInfo directly reflects what is written to the KTX file
- *       header. That is @c numberOfArrayElements should be 0 for non arrays;
- *       @c numMipmapLevels should be 0 to request generateMipmaps and @c type,
- *       @c format & @c typesize should be 0 for compressed textures.
- *
- * @param[in] dstname      pointer to a C string that contains the path of
- *                         the file to load.
- * @param[in] textureInfo  pointer to a KTX_texture_info structure providing
- *                         information about the images to be included in
- *                         the KTX file.
- * @param[in] bytesOfKeyValueData
- *                         specifies the number of bytes of key-value data.
- * @param[in] keyValueData a pointer to the keyValue data.
- * @param[in] numImages    number of images in the following array.
- * @param[in] images       array of KTX_image_info providing image size and
- *                         data.
- *
- * @return  KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_FILE_OPEN_FAILED Unable to open the specified file for
- *                                 writing.
- *
- * For other exceptions, see ktxWriteKTXF().
- */
-KTX_error_code
-ktxWriteKTXN(const char* dstname, const KTX_texture_info* textureInfo,
-             GLsizei bytesOfKeyValueData, const void* keyValueData,
-             GLuint numImages, KTX_image_info images[])
-{
-    struct ktxStream stream;
-    KTX_error_code result;
-    FILE* dst = fopen(dstname, "wb");
-
-    if (dst) {
-        result = ktxWriteKTXS(&stream, textureInfo, bytesOfKeyValueData,
-                              keyValueData, numImages, images);
-        fclose(dst);
-    } else
-        result = KTX_FILE_OPEN_FAILED;
-
-    return result;
-}
-
-/**
- * @~English
- * @ingroup writer
- * @deprecated Use ktxTexture_WriteToMemory().
- * @brief Write image(s) in KTX format to memory.
- *
- * Memory is allocated by the function and the caller is responsible for
- * freeing it.
- *
- * @note textureInfo directly reflects what is written to the KTX file
- *       header. That is @c numberOfArrayElements should be 0 for non arrays;
- *       @c numMipmapLevels should be 0 to request generateMipmaps and @c type,
- *       @c format & @c typesize should be 0 for compressed textures.
- *
- * @param[out] ppDstBytes  pointer to location to write the address of
- *                         the destination memory. The Application is
-                           responsible for freeing this memory.
- * @param[out] pSize       pointer to location to write the size in bytes of
- *                         the KTX data.
- * @param[in] textureInfo  pointer to a KTX_texture_info structure providing
- *                         information about the images to be included in
- *                         the KTX file.
- * @param[in] bytesOfKeyValueData
- *                         specifies the number of bytes of key-value data.
- * @param[in] keyValueData a pointer to the keyValue data.
- * @param[in] numImages    number of images in the following array.
- * @param[in] images       array of KTX_image_info providing image size and
- *                         data.
- *
- * @return      KTX_SUCCESS on success, other KTX_* enum values on error.
- *
- * @exception KTX_INVALID_VALUE @p dst or @p size is NULL.
- * @exception KTX_INVALID_VALUE @c glTypeSize in @p textureInfo is not 1, 2, or
- *                              4 or is different from the size of the type
- *                              specified in @c glType.
- * @exception KTX_INVALID_VALUE @c pixelWidth in @p textureInfo is 0 or
- *                              pixelDepth != 0 && pixelHeight == 0.
- * @exception KTX_INVALID_VALUE In @p textureInfo, @c numberOfFaces != 1 or
- *                              numberOfFaces != 6 or numberOfArrayElements
- *                              or numberOfMipmapLevels are < 0.
- * @exception KTX_INVALID_VALUE @c glType in @p textureInfo is an unrecognized
- *                              type.
- * @exception KTX_INVALID_OPERATION
- *                              In @p textureInfo, numberOfFaces == 6 and
- *                              images are either not 2D or are not square.
- * @exception KTX_INVALID_OPERATION
- *                              @p numImages is insufficient for the specified
- *                              number of mipmap levels and faces.
- * @exception KTX_INVALID_OPERATION
- *                              The size of a provided image is different than
- *                              that required for the specified width, height
- *                              or depth or for the mipmap level being
- *                              processed.
- * @exception KTX_INVALID_OPERATION
- *                              @c glType and @c glFormat in @p textureInfo are
- *                              mismatched. See OpenGL 4.4 specification
- *                              section 8.4.4 and table 8.5.
- * @exception KTX_FILE_WRITE_ERROR
- *                              A system error occurred while writing the file.
- * @exception KTX_OUT_OF_MEMORY System failed to allocate sufficient memory.
- */
-KTX_error_code
-ktxWriteKTXM(unsigned char** ppDstBytes, GLsizei* pSize,
-             const KTX_texture_info* textureInfo,
-             GLsizei bytesOfKeyValueData, const void* keyValueData,
-             GLuint numImages, KTX_image_info images[])
-{
-    struct ktxStream stream;
-    KTX_error_code rc;
-    ktx_size_t strSize;
-
-    if (ppDstBytes == NULL || pSize == NULL)
-        return KTX_INVALID_VALUE;
-
-    *ppDstBytes = NULL;
-
-    rc = ktxMemStream_construct(&stream, KTX_FALSE);
-    if (rc != KTX_SUCCESS)
-        return rc;
-
-    rc = ktxWriteKTXS(&stream, textureInfo, bytesOfKeyValueData, keyValueData,
-                      numImages, images);
-    if(rc != KTX_SUCCESS)
-    {
-        ktxMemStream_destruct(&stream);
-        return rc;
-    }
-
-    ktxMemStream_getdata(&stream, ppDstBytes);
-    stream.getsize(&stream, &strSize);
-    *pSize = (GLsizei)strSize;
-    /* This function does not free the memory pointed at by the
-     * value obtained from ktxMemStream_getdata().
-     */
-    stream.destruct(&stream);
-    return KTX_SUCCESS;
-}
-
-/**
- * @internal
- * @~English
- * @brief Get the matching format for an internalformat.
- *
- * Adds support for deprecated legacy formats needed to create textures for
- * use with OpenGL ES 1 & 2 to glGetFormatFromInternalFormat.
- *
- * @param[in] internalFormat  the internal format of the image data
- *
- * @return    the matching glFormat enum or GL_INVALID_VALUE if format is
- *            unrecognized.
- */
-GLenum
-getFormatFromInternalFormatLegacy(GLenum internalFormat)
-{
-    switch (internalFormat) {
-      case GL_LUMINANCE8:
-      case GL_LUMINANCE16:
-        return GL_LUMINANCE;
-            
-      case GL_ALPHA8:
-      case GL_ALPHA16:
-        return GL_ALPHA;
-            
-      case GL_LUMINANCE8_ALPHA8:
-      case GL_LUMINANCE16_ALPHA16:
-        return GL_LUMINANCE_ALPHA;
-
-      default:
-        return glGetFormatFromInternalFormat(internalFormat);
-    }
-}
-
-/**
- * @internal
- * @~English
- * @brief Get the GL data type for an internalformat.
- *
- * Adds support for deprecated legacy formats needed to create textures for
- * use with OpenGL ES 1 & 2 to glGetTypeFromInternalFormat.
- *
- * @param[in] internalFormat  the internal format of the image data
- *
- * @return    the matching glFormat enum or GL_INVALID_VALUE if format is
- *            unrecognized.
- */
-GLenum
-getTypeFromInternalFormatLegacy(GLenum internalFormat)
-{
-    switch (internalFormat) {
-      case GL_LUMINANCE8:
-      case GL_ALPHA8:
-        return GL_UNSIGNED_BYTE;
-            
-      case GL_LUMINANCE16:
-      case GL_ALPHA16:
-      case GL_LUMINANCE8_ALPHA8:
-        return GL_UNSIGNED_SHORT;
-            
-      case GL_LUMINANCE16_ALPHA16:
-        return GL_UNSIGNED_INT;
-            
-      default:
-        return glGetTypeFromInternalFormat(internalFormat);
-    }
-}
-        
-/**
- * @internal
- * @~English
- * @brief Get size information for an internalformat.
- *
- * Adds support for deprecated legacy formats needed to create textures for
- * use with OpenGL ES 1 & 2 to glGetTypeFromInternalFormat.
- *
- * @param[in] internalFormat  the internal format of the image data
- * @param[in,out] formatSize  pointer to a formatSize struct in which the
- *                            information is returned.
- */
-void
-getFormatSizeLegacy(GLenum internalFormat, GlFormatSize* pFormatSize)
-{
-    switch (internalFormat) {
-      case GL_LUMINANCE8:
-      case GL_ALPHA8:
-        pFormatSize->flags = 0;
-        pFormatSize->paletteSizeInBits = 0;
-        pFormatSize->blockSizeInBits = 1 * 8;
-        pFormatSize->blockWidth = 1;
-        pFormatSize->blockHeight = 1;
-        pFormatSize->blockDepth = 1;
-        break;
-
-      case GL_LUMINANCE16:
-      case GL_ALPHA16:
-      case GL_LUMINANCE8_ALPHA8:
-        pFormatSize->flags = 0;
-        pFormatSize->paletteSizeInBits = 0;
-        pFormatSize->blockSizeInBits = 2 * 8;
-        pFormatSize->blockWidth = 1;
-        pFormatSize->blockHeight = 1;
-        pFormatSize->blockDepth = 1;
-        break;
-
-      case GL_LUMINANCE16_ALPHA16:
-        pFormatSize->flags = 0;
-        pFormatSize->paletteSizeInBits = 0;
-        pFormatSize->blockSizeInBits = 4 * 8;
-        pFormatSize->blockWidth = 1;
-        pFormatSize->blockHeight = 1;
-        pFormatSize->blockDepth = 1;
-        break;
-
-      default:
-        glGetFormatSize(internalFormat, pFormatSize);
-    }
-}
diff --git a/external/KTX-Software-master/other_include/KHR/khrplatform.h b/external/KTX-Software-master/other_include/KHR/khrplatform.h
deleted file mode 100644
index c9e6f17d3434177459142f05e81285bd68103535..0000000000000000000000000000000000000000
--- a/external/KTX-Software-master/other_include/KHR/khrplatform.h
+++ /dev/null
@@ -1,282 +0,0 @@
-#ifndef __khrplatform_h_
-#define __khrplatform_h_
-
-/*
-** Copyright (c) 2008-2009 The Khronos Group Inc.
-**
-** Permission is hereby granted, free of charge, to any person obtaining a
-** copy of this software and/or associated documentation files (the
-** "Materials"), to deal in the Materials without restriction, including
-** without limitation the rights to use, copy, modify, merge, publish,
-** distribute, sublicense, and/or sell copies of the Materials, and to
-** permit persons to whom the Materials are furnished to do so, subject to
-** the following conditions:
-**
-** The above copyright notice and this permission notice shall be included
-** in all copies or substantial portions of the Materials.
-**
-** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
-*/
-
-/* Khronos platform-specific types and definitions.
- *
- * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $
- *
- * Adopters may modify this file to suit their platform. Adopters are
- * encouraged to submit platform specific modifications to the Khronos
- * group so that they can be included in future versions of this file.
- * Please submit changes by sending them to the public Khronos Bugzilla
- * (http://khronos.org/bugzilla) by filing a bug against product
- * "Khronos (general)" component "Registry".
- *
- * A predefined template which fills in some of the bug fields can be
- * reached using http://tinyurl.com/khrplatform-h-bugreport, but you
- * must create a Bugzilla login first.
- *
- *
- * See the Implementer's Guidelines for information about where this file
- * should be located on your system and for more details of its use:
- *    http://www.khronos.org/registry/implementers_guide.pdf
- *
- * This file should be included as
- *        #include <KHR/khrplatform.h>
- * by Khronos client API header files that use its types and defines.
- *
- * The types in khrplatform.h should only be used to define API-specific types.
- *
- * Types defined in khrplatform.h:
- *    khronos_int8_t              signed   8  bit
- *    khronos_uint8_t             unsigned 8  bit
- *    khronos_int16_t             signed   16 bit
- *    khronos_uint16_t            unsigned 16 bit
- *    khronos_int32_t             signed   32 bit
- *    khronos_uint32_t            unsigned 32 bit
- *    khronos_int64_t             signed   64 bit
- *    khronos_uint64_t            unsigned 64 bit
- *    khronos_intptr_t            signed   same number of bits as a pointer
- *    khronos_uintptr_t           unsigned same number of bits as a pointer
- *    khronos_ssize_t             signed   size
- *    khronos_usize_t             unsigned size
- *    khronos_float_t             signed   32 bit floating point
- *    khronos_time_ns_t           unsigned 64 bit time in nanoseconds
- *    khronos_utime_nanoseconds_t unsigned time interval or absolute time in
- *                                         nanoseconds
- *    khronos_stime_nanoseconds_t signed time interval in nanoseconds
- *    khronos_boolean_enum_t      enumerated boolean type. This should
- *      only be used as a base type when a client API's boolean type is
- *      an enum. Client APIs which use an integer or other type for
- *      booleans cannot use this as the base type for their boolean.
- *
- * Tokens defined in khrplatform.h:
- *
- *    KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
- *
- *    KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
- *    KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
- *
- * Calling convention macros defined in this file:
- *    KHRONOS_APICALL
- *    KHRONOS_APIENTRY
- *    KHRONOS_APIATTRIBUTES
- *
- * These may be used in function prototypes as:
- *
- *      KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
- *                                  int arg1,
- *                                  int arg2) KHRONOS_APIATTRIBUTES;
- */
-
-/*-------------------------------------------------------------------------
- * Definition of KHRONOS_APICALL
- *-------------------------------------------------------------------------
- * This precedes the return type of the function in the function prototype.
- */
-#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
-#   define KHRONOS_APICALL __declspec(dllimport)
-#elif defined (__SYMBIAN32__)
-#   define KHRONOS_APICALL IMPORT_C
-#else
-#   define KHRONOS_APICALL
-#endif
-
-/*-------------------------------------------------------------------------
- * Definition of KHRONOS_APIENTRY
- *-------------------------------------------------------------------------
- * This follows the return type of the function  and precedes the function
- * name in the function prototype.
- */
-#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
-    /* Win32 but not WinCE */
-#   define KHRONOS_APIENTRY __stdcall
-#else
-#   define KHRONOS_APIENTRY
-#endif
-
-/*-------------------------------------------------------------------------
- * Definition of KHRONOS_APIATTRIBUTES
- *-------------------------------------------------------------------------
- * This follows the closing parenthesis of the function prototype arguments.
- */
-#if defined (__ARMCC_2__)
-#define KHRONOS_APIATTRIBUTES __softfp
-#else
-#define KHRONOS_APIATTRIBUTES
-#endif
-
-/*-------------------------------------------------------------------------
- * basic type definitions
- *-----------------------------------------------------------------------*/
-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
-
-
-/*
- * Using <stdint.h>
- */
-#include <stdint.h>
-typedef int32_t                 khronos_int32_t;
-typedef uint32_t                khronos_uint32_t;
-typedef int64_t                 khronos_int64_t;
-typedef uint64_t                khronos_uint64_t;
-#define KHRONOS_SUPPORT_INT64   1
-#define KHRONOS_SUPPORT_FLOAT   1
-
-#elif defined(__VMS ) || defined(__sgi)
-
-/*
- * Using <inttypes.h>
- */
-#include <inttypes.h>
-typedef int32_t                 khronos_int32_t;
-typedef uint32_t                khronos_uint32_t;
-typedef int64_t                 khronos_int64_t;
-typedef uint64_t                khronos_uint64_t;
-#define KHRONOS_SUPPORT_INT64   1
-#define KHRONOS_SUPPORT_FLOAT   1
-
-#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
-
-/*
- * Win32
- */
-typedef __int32                 khronos_int32_t;
-typedef unsigned __int32        khronos_uint32_t;
-typedef __int64                 khronos_int64_t;
-typedef unsigned __int64        khronos_uint64_t;
-#define KHRONOS_SUPPORT_INT64   1
-#define KHRONOS_SUPPORT_FLOAT   1
-
-#elif defined(__sun__) || defined(__digital__)
-
-/*
- * Sun or Digital
- */
-typedef int                     khronos_int32_t;
-typedef unsigned int            khronos_uint32_t;
-#if defined(__arch64__) || defined(_LP64)
-typedef long int                khronos_int64_t;
-typedef unsigned long int       khronos_uint64_t;
-#else
-typedef long long int           khronos_int64_t;
-typedef unsigned long long int  khronos_uint64_t;
-#endif /* __arch64__ */
-#define KHRONOS_SUPPORT_INT64   1
-#define KHRONOS_SUPPORT_FLOAT   1
-
-#elif 0
-
-/*
- * Hypothetical platform with no float or int64 support
- */
-typedef int                     khronos_int32_t;
-typedef unsigned int            khronos_uint32_t;
-#define KHRONOS_SUPPORT_INT64   0
-#define KHRONOS_SUPPORT_FLOAT   0
-
-#else
-
-/*
- * Generic fallback
- */
-#include <stdint.h>
-typedef int32_t                 khronos_int32_t;
-typedef uint32_t                khronos_uint32_t;
-typedef int64_t                 khronos_int64_t;
-typedef uint64_t                khronos_uint64_t;
-#define KHRONOS_SUPPORT_INT64   1
-#define KHRONOS_SUPPORT_FLOAT   1
-
-#endif
-
-
-/*
- * Types that are (so far) the same on all platforms
- */
-typedef signed   char          khronos_int8_t;
-typedef unsigned char          khronos_uint8_t;
-typedef signed   short int     khronos_int16_t;
-typedef unsigned short int     khronos_uint16_t;
-
-/*
- * Types that differ between LLP64 and LP64 architectures - in LLP64, 
- * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
- * to be the only LLP64 architecture in current use.
- */
-#ifdef _WIN64
-typedef signed   long long int khronos_intptr_t;
-typedef unsigned long long int khronos_uintptr_t;
-typedef signed   long long int khronos_ssize_t;
-typedef unsigned long long int khronos_usize_t;
-#else
-typedef signed   long  int     khronos_intptr_t;
-typedef unsigned long  int     khronos_uintptr_t;
-typedef signed   long  int     khronos_ssize_t;
-typedef unsigned long  int     khronos_usize_t;
-#endif
-
-#if KHRONOS_SUPPORT_FLOAT
-/*
- * Float type
- */
-typedef          float         khronos_float_t;
-#endif
-
-#if KHRONOS_SUPPORT_INT64
-/* Time types
- *
- * These types can be used to represent a time interval in nanoseconds or
- * an absolute Unadjusted System Time.  Unadjusted System Time is the number
- * of nanoseconds since some arbitrary system event (e.g. since the last
- * time the system booted).  The Unadjusted System Time is an unsigned
- * 64 bit value that wraps back to 0 every 584 years.  Time intervals
- * may be either signed or unsigned.
- */
-typedef khronos_uint64_t       khronos_utime_nanoseconds_t;
-typedef khronos_int64_t        khronos_stime_nanoseconds_t;
-#endif
-
-/*
- * Dummy value used to pad enum types to 32 bits.
- */
-#ifndef KHRONOS_MAX_ENUM
-#define KHRONOS_MAX_ENUM 0x7FFFFFFF
-#endif
-
-/*
- * Enumerated boolean type
- *
- * Values other than zero should be considered to be true.  Therefore
- * comparisons should not be made against KHRONOS_TRUE.
- */
-typedef enum {
-    KHRONOS_FALSE = 0,
-    KHRONOS_TRUE  = 1,
-    KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
-} khronos_boolean_enum_t;
-
-#endif /* __khrplatform_h_ */
diff --git a/external/Vulkan-Headers b/external/Vulkan-Headers
new file mode 160000
index 0000000000000000000000000000000000000000..7dbd74f04430f3a811a8fbd3c94f2684e38d9152
--- /dev/null
+++ b/external/Vulkan-Headers
@@ -0,0 +1 @@
+Subproject commit 7dbd74f04430f3a811a8fbd3c94f2684e38d9152
diff --git a/src/Engine/Application.hpp b/src/Engine/Application.hpp
index fe15414b3de96fec455a87858b2b4ccafa95f43b..391151e5147d63eb4aacbab44ab40ebbd2d4538a 100644
--- a/src/Engine/Application.hpp
+++ b/src/Engine/Application.hpp
@@ -10,7 +10,7 @@ namespace Engine
 {
 	namespace Application
 	{
-		constexpr Utility::ImgDim defaultWindowSize = { 1800, 900 };
+		constexpr Utility::ImgDim defaultWindowSize = { 1900, 1000 };
 		constexpr Utility::ImgDim minimumWindowSize = { 800, 600 };
 		constexpr float narrowestAspectRatio = minimumWindowSize.GetAspectRatio();
 		constexpr std::string_view defaultApplicationName = "VulkanProject1";
diff --git a/src/Engine/AssManRendererConnect.cpp b/src/Engine/AssManRendererConnect.cpp
index ca38cc3f4002258274d4d1e071111ba380bb8cc4..a01e693b16367a0844f4109cfac29e7f591535b5 100644
--- a/src/Engine/AssManRendererConnect.cpp
+++ b/src/Engine/AssManRendererConnect.cpp
@@ -30,35 +30,4 @@ namespace Engine
 
 		return std::optional<Renderer::MeshDocument>{ Renderer::MeshDocument(std::move(newInfo)) };
 	}
-
-	std::optional<Renderer::TextureDocument> LoadTexture(size_t i)
-	{
-		auto path = AssMan::GetTexturePath(i);
-		if (path == "")
-			return {};
-
-		auto assManTexOpt = AssMan::LoadTextureDocument(path);
-		if (assManTexOpt.has_value() == false)
-			return {};
-
-		auto oldInfo = AssMan::TextureDocument::ToCreateInfo(std::move(assManTexOpt.value()));
-
-		Renderer::TextureDocument::CreateInfo newInfo{};
-
-		newInfo.byteArray = std::move(oldInfo.byteArray);
-
-		newInfo.isCompressed = oldInfo.isCompressed;
-		newInfo.baseInternalFormat = Renderer::TextureDocument::Format(oldInfo.baseInternalFormat);
-		newInfo.internalFormat = Renderer::TextureDocument::Format(oldInfo.internalFormat);
-
-		newInfo.type = Renderer::TextureDocument::Type(oldInfo.type);
-
-		newInfo.numDimensions = oldInfo.numDimensions;
-		newInfo.dimensions = oldInfo.dimensions;
-
-		newInfo.numLayers = oldInfo.numLayers;
-		newInfo.numLevels = oldInfo.numLevels;
-
-		return std::optional<Renderer::TextureDocument>{ Renderer::TextureDocument(std::move(newInfo)) };
-	}
 }
diff --git a/src/Engine/AssManRendererConnect.hpp b/src/Engine/AssManRendererConnect.hpp
index a34d987597602c0797adab53d5e7932724a0085d..c7060cd9fdca918f8c79162f52143663f94dfe30 100644
--- a/src/Engine/AssManRendererConnect.hpp
+++ b/src/Engine/AssManRendererConnect.hpp
@@ -1,14 +1,10 @@
 #pragma once
 
 #include "AssetManager/MeshDocument.hpp"
-#include "AssetManager/TextureDocument.hpp"
 
 #include "Renderer/MeshDocument.hpp"
-#include "Renderer/TextureDocument.hpp"
 
 namespace Engine
 {
 	std::optional<Renderer::MeshDocument> LoadMesh(size_t i);
-
-	std::optional<Renderer::TextureDocument> LoadTexture(size_t i);
 }
\ No newline at end of file
diff --git a/src/Engine/AssetManager/AssetManager.cpp b/src/Engine/AssetManager/AssetManager.cpp
index 161be7d7101465569324622587172eb230088024..3795ea6ecffd2ef3a90513249b76608ff8412178 100644
--- a/src/Engine/AssetManager/AssetManager.cpp
+++ b/src/Engine/AssetManager/AssetManager.cpp
@@ -1,6 +1,5 @@
 #include "AssetManager.hpp"
 #include "MeshDocument.hpp"
-#include "TextureDocument.hpp"
 
 #include <cassert>
 #include <map>
@@ -16,7 +15,7 @@ struct AssetManagerInfo
 
 static const std::map<size_t, AssetManagerInfo> textureInfos
 {
-	{ size_t(Engine::AssetManager::Sprite::Test), {"Test", "test2.ktx"} },
+	{ size_t(Engine::AssetManager::Sprite::Test), {"Test", "test3.ktx"} },
 };
 
 static const std::map<size_t, AssetManagerInfo> meshInfos
@@ -51,5 +50,4 @@ namespace Engine
 	}
 }
 
-#include "MeshDocument.inl"
-#include "TextureDocument.inl"
\ No newline at end of file
+#include "MeshDocument.inl"
\ No newline at end of file
diff --git a/src/Engine/AssetManager/AssetManager.hpp b/src/Engine/AssetManager/AssetManager.hpp
index 74368254498f920cb61ff956236c44e876b02de7..bdf33bac024f8bd5eaab8249e392a9ad84c3841d 100644
--- a/src/Engine/AssetManager/AssetManager.hpp
+++ b/src/Engine/AssetManager/AssetManager.hpp
@@ -2,14 +2,12 @@
 
 #include "Typedefs.hpp"
 #include "MeshDocument.hpp"
-#include "TextureDocument.hpp"
 
 #include <string>
 #include <string_view>
 #include <optional>
 
 #include "../Renderer/MeshDocument.hpp"
-#include "../Renderer/TextureDocument.hpp"
 
 namespace Engine
 {
@@ -22,7 +20,6 @@ namespace Engine
 		std::string GetTexturePath(size_t i);
 
 		std::optional<Renderer::MeshDocument> LoadMesh(size_t i);
-		std::optional<Renderer::TextureDocument> LoadTexture(size_t i);
 	}
 
 	namespace AssMan = AssetManager;
diff --git a/src/Engine/AssetManager/TextureDocument.hpp b/src/Engine/AssetManager/TextureDocument.hpp
deleted file mode 100644
index 0ce9d92356c46569ac3c2278131b3cfe91bbd8e8..0000000000000000000000000000000000000000
--- a/src/Engine/AssetManager/TextureDocument.hpp
+++ /dev/null
@@ -1,91 +0,0 @@
-#pragma once
-
-#include <array>
-#include <vector>
-#include <optional>
-#include <string>
-#include <memory>
-
-namespace Engine
-{
-	namespace AssetManager
-	{
-		class TextureDocument
-		{
-		public:
-			enum class Format;
-			enum class Type;
-			struct CreateInfo;
-
-			TextureDocument() = delete;
-			explicit TextureDocument(CreateInfo&&);
-			explicit TextureDocument(TextureDocument&&) = default;
-			TextureDocument(const TextureDocument&) = delete;
-			~TextureDocument();
-
-			const std::vector<uint8_t>& GetByteArray() const;
-			const uint8_t* GetData() const;
-			size_t GetByteLength() const;
-
-			const std::array<uint32_t, 3>& GetDimensions() const;
-
-			Format GetBaseInternalFormat() const;
-			Format GetInternalFormat() const;
-			Type GetType() const;
-
-			bool IsCompressed() const;
-
-			static CreateInfo ToCreateInfo(TextureDocument&& texDoc);
-
-		private:
-			std::vector<uint8_t> byteArray;
-			Format internalFormat{};
-			Format baseInternalFormat{};
-			Type type{};
-			uint8_t numDimensions = 0;
-			std::array<uint32_t, 3> dimensions{};
-			size_t numLayers = 0;
-			size_t numLevels = 0;
-			bool isCompressed = false;
-		};
-
-		struct TextureDocument::CreateInfo
-		{
-			std::vector<uint8_t> byteArray;
-			Format internalFormat{};
-			Format baseInternalFormat{};
-			Type type{};
-			uint8_t numDimensions = 0;
-			std::array<uint32_t, 3> dimensions{};
-			size_t numLayers = 0;
-			size_t numLevels = 0;
-			bool isCompressed = false;
-		};
-
-		enum class TextureDocument::Format
-		{
-			Invalid,
-			RGBA,
-			RGB,
-			R8G8B8A8,
-			Compressed_RGB_S3TC_DXT1_ANGLE,
-			Compressed_RGBA_S3TC_DXT1_ANGLE,
-			Compressed_RGBA_S3TC_DXT3_ANGLE,
-			Compressed_RGBA_S3TC_DXT5_ANGLE,
-			Compressed_RGBA_BPTC_UNORM,
-			Compressed_SRGB_ALPHA_BPTC_UNORM,
-			Compressed_RGB_BPTC_SIGNED_FLOAT,
-			Compressed_RGB_BPTC_UNSIGNED_FLOAT,
-		};
-
-		enum class TextureDocument::Type
-		{
-			Invalid,
-			UnsignedByte,
-		};
-
-		std::optional<TextureDocument> LoadTextureDocument(std::string path);
-	}
-
-	namespace AssMan = AssetManager;
-}
\ No newline at end of file
diff --git a/src/Engine/AssetManager/TextureDocument.inl b/src/Engine/AssetManager/TextureDocument.inl
deleted file mode 100644
index 1f04cc22192cc2808e290a39ef8bedd9b1e4c4f1..0000000000000000000000000000000000000000
--- a/src/Engine/AssetManager/TextureDocument.inl
+++ /dev/null
@@ -1,201 +0,0 @@
-#pragma once
-
-#include "TextureDocument.hpp"
-
-#include <string>
-#include <optional>
-
-#include "ktx.h"
-
-namespace Engine
-{
-	namespace AssetManager
-	{
-		TextureDocument::Format ConvertGLFormat(uint32_t glFormat);
-		TextureDocument::Type ConvertGLType(uint32_t glType);
-
-		TextureDocument::TextureDocument(CreateInfo&& info) :
-			byteArray(std::move(info.byteArray)),
-			baseInternalFormat(info.baseInternalFormat),
-			internalFormat(info.internalFormat),
-			type(info.type),
-			numDimensions(info.numDimensions),
-			dimensions(info.dimensions),
-			numLayers(info.numLayers),
-			numLevels(info.numLevels),
-			isCompressed(info.isCompressed)
-		{
-
-		}
-
-		TextureDocument::~TextureDocument()
-		{
-			
-		}
-
-		const std::vector<uint8_t>& TextureDocument::GetByteArray() const
-		{
-			return byteArray;
-		}
-
-		const uint8_t* TextureDocument::GetData() const
-		{
-			return byteArray.data();
-		}
-
-		size_t TextureDocument::GetByteLength() const
-		{
-			return byteArray.size();
-		}
-
-		const std::array<uint32_t, 3>& TextureDocument::GetDimensions() const
-		{
-			return dimensions;
-		}
-
-		bool TextureDocument::IsCompressed() const
-		{
-			return isCompressed;
-		}
-
-		TextureDocument::Format TextureDocument::GetBaseInternalFormat() const
-		{
-			return baseInternalFormat;
-		}
-
-		TextureDocument::Format TextureDocument::GetInternalFormat() const
-		{
-			return internalFormat;
-		}
-
-		TextureDocument::Type TextureDocument::GetType() const
-		{
-			return type;
-		}
-
-		TextureDocument::CreateInfo TextureDocument::ToCreateInfo(TextureDocument&& texDoc)
-		{
-			CreateInfo info{};
-
-			info.byteArray = std::move(texDoc.byteArray);
-			info.isCompressed = texDoc.isCompressed;
-			info.baseInternalFormat = texDoc.baseInternalFormat;
-			info.internalFormat = texDoc.internalFormat;
-			info.type = texDoc.type;
-			info.numDimensions = texDoc.numDimensions;
-			info.dimensions = texDoc.dimensions;
-			info.numLayers = texDoc.numLayers;
-			info.numLevels = texDoc.numLevels;
-
-			return info;
-		}
-
-		std::optional<TextureDocument> LoadTextureDocument(std::string path)
-		{
-			if (path == "")
-				return {};
-
-			ktxTexture* texture = nullptr;
-			KTX_error_code result = ktxTexture_CreateFromNamedFile(path.c_str(), KTX_TEXTURE_CREATE_NO_FLAGS, &texture);
-			if (result != KTX_SUCCESS)
-				return  {};
-
-			TextureDocument::CreateInfo createInfo{};
-
-			createInfo.byteArray.resize(texture->dataSize);
-
-			result = ktxTexture_LoadImageData(texture, createInfo.byteArray.data(), createInfo.byteArray.size());
-
-			createInfo.numDimensions = texture->numDimensions;
-			createInfo.dimensions = { texture->baseWidth, texture->baseHeight, texture->baseDepth };
-
-			createInfo.numLayers = texture->numLayers;
-			createInfo.numLevels = texture->numLevels;
-
-			createInfo.isCompressed = texture->isCompressed;
-			createInfo.type = ConvertGLType(texture->glType);
-			createInfo.baseInternalFormat = ConvertGLFormat(texture->glBaseInternalformat);
-			createInfo.internalFormat = ConvertGLFormat(texture->glInternalformat);
-
-			ktxTexture_Destroy(texture);
-
-			return std::optional<TextureDocument>( std::move(TextureDocument(std::move(createInfo))) );
-		}
-	}
-}
-
-namespace Engine
-{
-	namespace AssetManager
-	{
-		TextureDocument::Type ConvertGLType(uint32_t glType)
-		{
-			using Type = TextureDocument::Type;
-
-			constexpr auto GL_UNSIGNED_BYTE = 0x1401;
-
-			switch (glType)
-			{
-			case GL_UNSIGNED_BYTE:
-				return Type::UnsignedByte;
-			default:
-				return Type::Invalid;
-			}
-		}
-
-		TextureDocument::Format ConvertGLFormat(uint32_t glFormat)
-		{
-			using Format = TextureDocument::Format;
-
-			// Uncompressed
-			constexpr auto GL_RGB = 0x1907;
-			constexpr auto GL_RGBA = 0x1908;
-			constexpr auto GL_RGBA8 = 0x8058;
-			switch (glFormat)
-			{
-			case GL_RGB:
-				return Format::RGB;
-			case GL_RGBA:
-				return Format::RGBA;
-			case GL_RGBA8:
-				return Format::R8G8B8A8;
-			};
-
-			// DXT
-			constexpr auto GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE = 0x83F0;
-			constexpr auto GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE = 0x83F1;
-			constexpr auto GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE = 0x83F2;
-			constexpr auto GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE = 0x83F3;
-			switch (glFormat)
-			{
-			case GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE:
-				return Format::Compressed_RGB_S3TC_DXT1_ANGLE;
-			case GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE:
-				return Format::Compressed_RGBA_S3TC_DXT1_ANGLE;
-			case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
-				return Format::Compressed_RGBA_S3TC_DXT3_ANGLE;
-			case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
-				return Format::Compressed_RGBA_S3TC_DXT5_ANGLE;
-			}
-
-			// BPTC
-			constexpr auto GL_COMPRESSED_RGBA_BPTC_UNORM = 0x8E8C;
-			constexpr auto GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM = 0x8E8D;
-			constexpr auto GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT = 0x8E8E;
-			constexpr auto GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 0x8E8F;
-			switch (glFormat)
-			{
-			case GL_COMPRESSED_RGBA_BPTC_UNORM:
-				return Format::Compressed_RGBA_BPTC_UNORM;
-			case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
-				return Format::Compressed_SRGB_ALPHA_BPTC_UNORM;
-			case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
-				return Format::Compressed_RGB_BPTC_SIGNED_FLOAT;
-			case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
-				return Format::Compressed_RGB_BPTC_UNSIGNED_FLOAT;
-			}
-
-			return Format::Invalid;
-		}
-	}
-}
\ No newline at end of file
diff --git a/src/Engine/Engine.cpp b/src/Engine/Engine.cpp
index bf310ddf48862215c4a4a51f59c19686152dac08..d613028c63212708726193c0037e1d69ead83fbb 100644
--- a/src/Engine/Engine.cpp
+++ b/src/Engine/Engine.cpp
@@ -42,7 +42,7 @@ namespace Engine
 		rendererInitInfo.surfaceHandle = Application::Core::GetMainWindowHandle();
 
 		rendererInitInfo.assetLoadCreateInfo.meshLoader = &LoadMesh;
-		rendererInitInfo.assetLoadCreateInfo.textureLoader = &LoadTexture;
+		//rendererInitInfo.assetLoadCreateInfo.textureLoader = &LoadTexture;
 
 		rendererInitInfo.openGLInitInfo.glSwapBuffers = &Application::Core::GL_SwapWindow;
 		Renderer::Core::Initialize(rendererInitInfo);
@@ -106,7 +106,7 @@ void Engine::Core::Run()
 	while (Application::Core::UpdateEvents(), Application::IsRunning())
 	{
 		// Handles origin movement for camera
-		const float speed = 2.5f;
+		const float speed = 5.f;
 		auto cross = Math::Vector3D::Cross(camera.forward, camera.up);
 		if (Input::Raw::GetValue(Input::Raw::Button::A))
 			camera.positionOffset -= cross * speed * scene1.GetTimeData().GetDeltaTime();
diff --git a/src/Engine/Renderer/OpenGL.cpp b/src/Engine/Renderer/OpenGL.cpp
index 3e71b04c9ed81f45e3be27ff6d60f3dfe1eb66e1..945f90bd46d9c896655bf3339dfbc0f484a90fa0 100644
--- a/src/Engine/Renderer/OpenGL.cpp
+++ b/src/Engine/Renderer/OpenGL.cpp
@@ -1,9 +1,11 @@
 #include "Renderer.hpp"
 #include "RendererData.hpp"
 #include "MeshDocument.hpp"
-#include "TextureDocument.hpp"
 #include "OpenGL.hpp"
 
+#define DTEX_IMPLEMENTATION
+#include "DTex/DTex.hpp"
+
 #include "GL/glew.h"
 
 #include <cassert>
@@ -43,11 +45,9 @@ namespace Engine
 			void LoadSpriteShader(Data& data);
 			void LoadMeshShader(Data& data);
 
-			void GLDebugOutputCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam);
+            void GLAPIENTRY GLDebugOutputCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam);
 
 			GLint ToGLType(MeshDocument::IndexType indexType);
-			GLint ToGLFormat(TextureDocument::Format format);
-			GLint ToGLType(TextureDocument::Type type);
 		}
 	}
 
@@ -264,12 +264,12 @@ namespace Engine
 		glBindBufferRange(GL_UNIFORM_BUFFER, 1, data.lightDataUBO, 0, sizeof(LightDataUBO));
 	}
 
-	void Renderer::OpenGL::GLDebugOutputCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam)
+	void GLAPIENTRY Renderer::OpenGL::GLDebugOutputCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam)
 	{
 		LogDebugMessage(message);
 	}
 
-	void Renderer::OpenGL::Initialize(std::any& apiData, const InitInfo& createInfo)
+    void Renderer::OpenGL::Initialize(std::any& apiData, const InitInfo& createInfo)
 	{
 		auto glInitResult = glewInit();
 		assert(glInitResult == 0);
@@ -279,6 +279,7 @@ namespace Engine
 
 		data.glSwapBuffers = std::move(createInfo.glSwapBuffers);
 
+
 		// Initialize debug stuff
 		if constexpr (Setup::enableDebugging)
 		{
@@ -304,8 +305,9 @@ namespace Engine
 		glGenSamplers(1, &data.samplerObject);
 		glSamplerParameteri(data.samplerObject, GL_TEXTURE_WRAP_S, GL_REPEAT);
 		glSamplerParameteri(data.samplerObject, GL_TEXTURE_WRAP_T, GL_REPEAT);
-		glSamplerParameteri(data.samplerObject, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 		glSamplerParameteri(data.samplerObject, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+		glSamplerParameteri(data.samplerObject, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+		glSamplerParameteri(data.samplerObject, GL_TEXTURE_LOD_BIAS, 0);
 		glBindSampler(0, data.samplerObject);
 
 		glEnable(GL_DEPTH_TEST);
@@ -428,7 +430,7 @@ namespace Engine
 			glUseProgram(data.spriteProgram);
 
 			glProgramUniform1ui(data.spriteProgram, data.spriteSamplerUniform, 0);
-			glBindSampler(0, data.samplerObject);
+			glBindSampler(GL_TEXTURE0, data.samplerObject);
 
 			const auto& spriteVBO = data.quadVBO;
 			glBindVertexArray(spriteVBO.vertexArrayObject);
@@ -499,28 +501,39 @@ namespace Engine
 
 	std::optional<Renderer::OpenGL::IBO> Renderer::OpenGL::GetIBOFromID(size_t id)
 	{
-		auto texDocumentOpt = Core::GetData().assetLoadData.textureLoader(id);
-		assert(texDocumentOpt.has_value());
+		//auto texDocumentOpt = Core::GetData().assetLoadData.textureLoader(id);
+		//assert(texDocumentOpt.has_value());
 
-		auto& texDoc = texDocumentOpt.value();
+		auto texDocOpt = DTex::LoadFromFile("Data/Textures/test.ktx");
+		auto& texDoc = texDocOpt.value();
 
 		IBO ibo;
 
 		glGenTextures(1, &ibo.texture);
-		glBindTexture(GL_TEXTURE_2D, ibo.texture);
-
-		GLint internalFormat = ToGLFormat(texDoc.GetInternalFormat());
-		GLint baseInternalFormat = ToGLFormat(texDoc.GetBaseInternalFormat());
-		GLsizei width = texDoc.GetDimensions()[0];
-		GLsizei height = texDoc.GetDimensions()[1];
-		GLint type = ToGLType(texDoc.GetType());
-		GLsizei byteLength = texDoc.GetByteLength();
-		const uint8_t* data = texDoc.GetData();
-
-		if (texDoc.IsCompressed())
-			glCompressedTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, byteLength, data);
-		else
-			glTexImage2D(GL_TEXTURE_2D, 0, baseInternalFormat, width, height, 0, baseInternalFormat, type, data);
+
+		GLenum target = texDoc.GetGLTarget();
+
+		glBindTexture(target, ibo.texture);
+
+
+		GLint format = texDoc.GetGLFormat();
+		GLenum type = texDoc.GetGLType();
+
+		for (size_t level = 0; level < texDoc.GetMipLevels(); level++)
+		{
+			GLsizei width = texDoc.GetDimensions(level)[0];
+			GLsizei height = texDoc.GetDimensions(level)[1];
+			auto data = texDoc.GetData(level);
+			GLsizei dataLength = texDoc.GetByteLength(level);
+
+			if (texDoc.IsCompressed())
+				glCompressedTexImage2D(target, level, format, width, height, 0, dataLength, data);
+			else
+				glTexImage2D(target, level, format, width, height, 0, format, type, data);
+		}
+
+		glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
+		glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texDoc.GetMipLevels() - 1);
 
 		return ibo;
 	}
@@ -588,59 +601,4 @@ namespace Engine
 			return 0;
 		}
 	}
-
-	GLint Renderer::OpenGL::ToGLFormat(TextureDocument::Format format)
-	{
-		using Format = TextureDocument::Format;
-
-		// Uncompressed
-		switch (format)
-		{
-		case Format::RGB:
-			return GL_RGB;
-		case Format::RGBA:
-			return GL_RGBA;
-		case Format::R8G8B8A8:
-			return GL_RGBA8;
-		};
-
-		// DXT
-		switch (format)
-		{
-		case Format::Compressed_RGB_S3TC_DXT1_ANGLE:
-			return GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE;
-		case Format::Compressed_RGBA_S3TC_DXT1_ANGLE:
-			return GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE;
-		case Format::Compressed_RGBA_S3TC_DXT3_ANGLE:
-			return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
-		case Format::Compressed_RGBA_S3TC_DXT5_ANGLE:
-			return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
-		}
-
-		switch (format)
-		{
-		case Format::Compressed_RGBA_BPTC_UNORM:
-			return GL_COMPRESSED_RGBA_BPTC_UNORM;
-		case Format::Compressed_SRGB_ALPHA_BPTC_UNORM:
-			return GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM;
-		case Format::Compressed_RGB_BPTC_SIGNED_FLOAT:
-			return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT;
-		case Format::Compressed_RGB_BPTC_UNSIGNED_FLOAT:
-			return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
-		}
-
-		return 0;
-	}
-
-	GLint Renderer::OpenGL::ToGLType(TextureDocument::Type type)
-	{
-		using Type = TextureDocument::Type;
-		switch (type)
-		{
-		case Type::UnsignedByte:
-			return GL_UNSIGNED_BYTE;
-		default:
-			return 0;
-		}
-	}
 }
\ No newline at end of file
diff --git a/src/Engine/Renderer/Renderer.cpp b/src/Engine/Renderer/Renderer.cpp
index 9029ffca80840caa0be8757125899722ec6de8ea..849109634254744d36b8f2c514a0fe88097f45f3 100644
--- a/src/Engine/Renderer/Renderer.cpp
+++ b/src/Engine/Renderer/Renderer.cpp
@@ -374,5 +374,4 @@ namespace Engine
 	}
 }
 
-#include "MeshDocument.inl"
-#include "TextureDocument.inl"
\ No newline at end of file
+#include "MeshDocument.inl"
\ No newline at end of file
diff --git a/src/Engine/Renderer/TextureDocument.hpp b/src/Engine/Renderer/TextureDocument.hpp
deleted file mode 100644
index fbc3d38063b2d700329fff6c01e0243551dec903..0000000000000000000000000000000000000000
--- a/src/Engine/Renderer/TextureDocument.hpp
+++ /dev/null
@@ -1,86 +0,0 @@
-#pragma once
-
-#include <array>
-#include <vector>
-#include <cstddef>
-
-namespace Engine
-{
-	namespace Renderer
-	{
-		class TextureDocument
-		{
-		public:
-			enum class Format;
-			enum class Type;
-			struct CreateInfo;
-
-			TextureDocument() = delete;
-			explicit TextureDocument(CreateInfo&&);
-			explicit TextureDocument(TextureDocument&&) = default;
-			TextureDocument(const TextureDocument&) = delete;
-			~TextureDocument();
-
-			const std::vector<uint8_t>& GetByteArray() const;
-			const uint8_t* GetData() const;
-			size_t GetByteLength() const;
-
-			const std::array<uint32_t, 3>& GetDimensions() const;
-
-
-			Format GetBaseInternalFormat() const;
-			Format GetInternalFormat() const;
-			Type GetType() const;
-
-			bool IsCompressed() const;
-
-			static CreateInfo ToCreateInfo(TextureDocument&& texDoc);
-
-		private:
-			std::vector<uint8_t> byteArray;
-			Format internalFormat{};
-			Format baseInternalFormat{};
-			Type type{};
-			uint8_t numDimensions = 0;
-			std::array<uint32_t, 3> dimensions{};
-			size_t numLayers = 0;
-			size_t numLevels = 0;
-			bool isCompressed = false;
-		};
-
-		struct TextureDocument::CreateInfo
-		{
-			std::vector<uint8_t> byteArray;
-			Format internalFormat{};
-			Format baseInternalFormat{};
-			Type type{};
-			uint8_t numDimensions = 0;
-			std::array<uint32_t, 3> dimensions{};
-			size_t numLayers = 0;
-			size_t numLevels = 0;
-			bool isCompressed = false;
-		};
-
-		enum class TextureDocument::Format
-		{
-			Invalid,
-			RGBA,
-			RGB,
-			R8G8B8A8,
-			Compressed_RGB_S3TC_DXT1_ANGLE,
-			Compressed_RGBA_S3TC_DXT1_ANGLE,
-			Compressed_RGBA_S3TC_DXT3_ANGLE,
-			Compressed_RGBA_S3TC_DXT5_ANGLE,
-			Compressed_RGBA_BPTC_UNORM,
-			Compressed_SRGB_ALPHA_BPTC_UNORM,
-			Compressed_RGB_BPTC_SIGNED_FLOAT,
-			Compressed_RGB_BPTC_UNSIGNED_FLOAT,
-		};
-
-		enum class TextureDocument::Type
-		{
-			Invalid,
-			UnsignedByte,
-		};
-	}
-}
\ No newline at end of file
diff --git a/src/Engine/Renderer/TextureDocument.inl b/src/Engine/Renderer/TextureDocument.inl
deleted file mode 100644
index c2ebeca8e64a275b1eb10eb52685d23e4b78eb41..0000000000000000000000000000000000000000
--- a/src/Engine/Renderer/TextureDocument.inl
+++ /dev/null
@@ -1,85 +0,0 @@
-#pragma once
-
-#include "TextureDocument.hpp"
-
-namespace Engine
-{
-	namespace Renderer
-	{
-		TextureDocument::TextureDocument(CreateInfo&& info) :
-			byteArray(std::move(info.byteArray)),
-			baseInternalFormat(info.baseInternalFormat),
-			internalFormat(info.internalFormat),
-			type(info.type),
-			numDimensions(info.numDimensions),
-			dimensions(info.dimensions),
-			numLayers(info.numLayers),
-			numLevels(info.numLevels),
-			isCompressed(info.isCompressed)
-		{
-
-		}
-
-		TextureDocument::~TextureDocument()
-		{
-
-		}
-
-		const std::vector<uint8_t>& TextureDocument::GetByteArray() const
-		{
-			return byteArray;
-		}
-
-		const uint8_t* TextureDocument::GetData() const
-		{
-			return byteArray.data();
-		}
-
-		size_t TextureDocument::GetByteLength() const
-		{
-			return byteArray.size();
-		}
-
-		const std::array<uint32_t, 3>& TextureDocument::GetDimensions() const
-		{
-			return dimensions;
-		}
-
-		bool TextureDocument::IsCompressed() const
-		{
-			return isCompressed;
-		}
-
-		TextureDocument::Format TextureDocument::GetBaseInternalFormat() const
-		{
-			return baseInternalFormat;
-		}
-
-		TextureDocument::Format TextureDocument::GetInternalFormat() const
-		{
-			return internalFormat;
-		}
-
-		TextureDocument::Type TextureDocument::GetType() const
-		{
-			return type;
-		}
-
-		TextureDocument::CreateInfo TextureDocument::ToCreateInfo(TextureDocument&& texDoc)
-		{
-			CreateInfo info{};
-
-			info.byteArray = std::move(texDoc.byteArray);
-			info.isCompressed = texDoc.isCompressed;
-			info.baseInternalFormat = texDoc.baseInternalFormat;
-			info.internalFormat = texDoc.internalFormat;
-			info.type = texDoc.type;
-			info.numDimensions = texDoc.numDimensions;
-			info.dimensions = texDoc.dimensions;
-			info.numLayers = texDoc.numLayers;
-			info.numLevels = texDoc.numLevels;
-
-			return info;
-		}
-	}
-}
\ No newline at end of file