From 2806eb6d718d6507409d05b04ad62e9414b5e22b Mon Sep 17 00:00:00 2001 From: Kevin Trogant Date: Mon, 17 Oct 2022 16:04:56 +0200 Subject: [PATCH] Initial commit What works? - Reading files (AssetManager::loadFile) - Rendering colored & textured rects (Renderer::addRect) - Getting input (TouchInputEvent) TODO Port this to windows --- .gitignore | 15 + .idea/.gitignore | 3 + .idea/.name | 1 + .idea/compiler.xml | 6 + .idea/gradle.xml | 19 + .idea/misc.xml | 9 + app/.gitignore | 1 + app/build.gradle | 69 + app/proguard-rules.pro | 21 + .../kde/ExampleInstrumentedTest.java | 26 + app/src/main/AndroidManifest.xml | 29 + app/src/main/assets/smiley_PNG42.png | Bin 0 -> 285391 bytes app/src/main/cpp/AssetManager.cpp | 68 + app/src/main/cpp/AssetManager.h | 40 + app/src/main/cpp/CMakeLists.txt | 27 + app/src/main/cpp/Hash.cpp | 152 + app/src/main/cpp/Hash.h | 33 + app/src/main/cpp/Log.h | 17 + app/src/main/cpp/NativeEngine.cpp | 410 + app/src/main/cpp/NativeEngine.h | 65 + app/src/main/cpp/Position.h | 10 + app/src/main/cpp/Renderer.cpp | 258 + app/src/main/cpp/Renderer.h | 62 + app/src/main/cpp/StringRepository.cpp | 84 + app/src/main/cpp/StringRepository.h | 39 + app/src/main/cpp/Texture.cpp | 34 + app/src/main/cpp/Texture.h | 25 + app/src/main/cpp/TouchInput.h | 19 + app/src/main/cpp/kde.cpp | 15 + app/src/main/cpp/stb_image.h | 7897 +++++++++++++++++ .../tech/recreational/kde/KDEActivity.java | 26 + .../drawable-v24/ic_launcher_foreground.xml | 30 + .../res/drawable/ic_launcher_background.xml | 170 + .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1404 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 2898 bytes app/src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 982 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 1772 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1900 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 3918 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 2884 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 5914 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 3844 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 7778 bytes app/src/main/res/values-night/themes.xml | 16 + app/src/main/res/values/colors.xml | 10 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/themes.xml | 7 + app/src/main/res/xml/backup_rules.xml | 13 + .../main/res/xml/data_extraction_rules.xml | 19 + .../recreational/kde/ExampleUnitTest.java | 17 + build.gradle | 9 + gradle.properties | 21 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 185 + gradlew.bat | 89 + settings.gradle | 16 + 59 files changed, 10101 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/.name create mode 100644 .idea/compiler.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/misc.xml create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/tech/recreational/kde/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/assets/smiley_PNG42.png create mode 100644 app/src/main/cpp/AssetManager.cpp create mode 100644 app/src/main/cpp/AssetManager.h create mode 100644 app/src/main/cpp/CMakeLists.txt create mode 100644 app/src/main/cpp/Hash.cpp create mode 100644 app/src/main/cpp/Hash.h create mode 100644 app/src/main/cpp/Log.h create mode 100644 app/src/main/cpp/NativeEngine.cpp create mode 100644 app/src/main/cpp/NativeEngine.h create mode 100644 app/src/main/cpp/Position.h create mode 100644 app/src/main/cpp/Renderer.cpp create mode 100644 app/src/main/cpp/Renderer.h create mode 100644 app/src/main/cpp/StringRepository.cpp create mode 100644 app/src/main/cpp/StringRepository.h create mode 100644 app/src/main/cpp/Texture.cpp create mode 100644 app/src/main/cpp/Texture.h create mode 100644 app/src/main/cpp/TouchInput.h create mode 100644 app/src/main/cpp/kde.cpp create mode 100644 app/src/main/cpp/stb_image.h create mode 100644 app/src/main/java/tech/recreational/kde/KDEActivity.java create mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/values-night/themes.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/themes.xml create mode 100644 app/src/main/res/xml/backup_rules.xml create mode 100644 app/src/main/res/xml/data_extraction_rules.xml create mode 100644 app/src/test/java/tech/recreational/kde/ExampleUnitTest.java create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..d0c8815 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +Krimi Dinner Engine \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..fb7f4a8 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..a2d7c21 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..2a4d5b5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..aad73cf --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,69 @@ +plugins { + id 'com.android.application' +} + +android { + compileSdk 32 + + defaultConfig { + applicationId "tech.recreational.kde" + minSdk 26 + targetSdk 32 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + externalNativeBuild { + cmake { + arguments "-DANDROID_STL=c++_static" + cppFlags '' + } + } + + ndk { + // Skip deprecated ABIs. Only required when using NDK 16 or earlier. + abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' + } + } + + buildFeatures { + prefab true + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + externalNativeBuild { + cmake { + arguments "-DANDROID_STL=c++_shared" + } + } + } + debug { + externalNativeBuild { + minifyEnabled = false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + cmake { + arguments "-DANDROID_STL=c++_shared" + } + } + } + } + externalNativeBuild { + cmake { + path file('src/main/cpp/CMakeLists.txt') + version '3.18.1' + } + } +} + +dependencies { + implementation 'androidx.games:games-activity:1.2.1' + implementation 'androidx.games:games-frame-pacing:1.10.1' + implementation 'androidx.appcompat:appcompat:1.3.0' + implementation 'com.google.android.material:material:1.4.0' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/tech/recreational/kde/ExampleInstrumentedTest.java b/app/src/androidTest/java/tech/recreational/kde/ExampleInstrumentedTest.java new file mode 100644 index 0000000..75a6919 --- /dev/null +++ b/app/src/androidTest/java/tech/recreational/kde/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package tech.recreational.kde; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("tech.recreational.kde", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7a493d6 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/smiley_PNG42.png b/app/src/main/assets/smiley_PNG42.png new file mode 100644 index 0000000000000000000000000000000000000000..5e6f1f68f818d33a40a0d54b7e60d57e3c009a10 GIT binary patch literal 285391 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%0Augn4b$$75A4R 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%0Aff6A8>qQ!I5~x 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%0Ao6nDiZ&$t|G4_{c&OJm?2~d7C(4pi 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�`~HExF}xV{9vOOFlHdnMU8tD!n#28Y^yn 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

{m@tjX)tIl9+$$<|%~_t9Irs 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 + +#define STBI_NO_STDIO +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +AssetManager* AssetManager::ptr = nullptr; + +AssetManager::AssetManager() : m_asset_mgr(nullptr) {}; +AssetManager::~AssetManager() {} + +void AssetManager::create(AAssetManager *android_asset_manager) +{ + AssetManager::ptr = new AssetManager; + AssetManager::ptr->m_asset_mgr = android_asset_manager; +} + +bool AssetManager::loadFile(const char* path, FileBuffer* p_file_buffer) +{ + AAsset* asset = AAssetManager_open(m_asset_mgr, path, AASSET_MODE_BUFFER); + if (!asset) { + ALOGE("Failed to open asset %s", path); + return false; + } + const void* buffer = AAsset_getBuffer(asset); + if (!buffer) { + ALOGE("Failed to retrieve contents of asset %s", path); + return false; + } + auto length = static_cast(AAsset_getLength64(asset)); + p_file_buffer->data = buffer, + p_file_buffer->size = length; + p_file_buffer->internal = asset; + return true; +} + +bool AssetManager::loadTexture(const char* path, Texture* p_texture) +{ + FileBuffer texture_data = {}; + if (!loadFile(path, &texture_data)) + return false; + + int width, height, channels; + const auto* raw_data = reinterpret_cast(texture_data.data); + stbi_uc* data = stbi_load_from_memory(raw_data, + static_cast(texture_data.size), + &width, &height, &channels, + 4); + if (!data) { + ALOGE("Failed to parse texture file %s", path); + releaseFileBuffer(texture_data); + return false; + } + *p_texture = Texture(width, height, data); + + return true; +} + +void AssetManager::releaseFileBuffer(FileBuffer &fb) +{ + AAsset_close(reinterpret_cast(fb.internal)); + fb.internal = nullptr; + fb.data = nullptr; + fb.size = 0; +} \ No newline at end of file diff --git a/app/src/main/cpp/AssetManager.h b/app/src/main/cpp/AssetManager.h new file mode 100644 index 0000000..955aae8 --- /dev/null +++ b/app/src/main/cpp/AssetManager.h @@ -0,0 +1,40 @@ +#ifndef KRIMI_DINNER_ENGINE_ASSETMANAGER_H +#define KRIMI_DINNER_ENGINE_ASSETMANAGER_H + +#include "Texture.h" +#include "Renderer.h" + +struct AAssetManager; + +struct FileBuffer +{ + const void* data; + size_t size; + + void* internal; +}; + +class AssetManager { +public: + static AssetManager* ptr; + + static void create(AAssetManager* android_asset_manager); + + bool loadFile(const char* path, FileBuffer* p_file_buffer); + + bool loadTexture(const char* path, Texture* p_texture); + + void releaseFileBuffer(FileBuffer& fb); + +private: + AssetManager(); + ~AssetManager(); + + AssetManager(const AssetManager&) = delete; + AssetManager& operator=(const AssetManager&) = delete; + + AAssetManager* m_asset_mgr; +}; + + +#endif diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000..3d0867b --- /dev/null +++ b/app/src/main/cpp/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.18.1) +project("kde") + +find_library(log-lib log ) +find_package(game-activity REQUIRED CONFIG) +find_package(games-frame-pacing REQUIRED CONFIG) + +add_library(kde SHARED + kde.cpp + NativeEngine.cpp + NativeEngine.h + Renderer.cpp + Renderer.h + Texture.cpp + Texture.h + AssetManager.cpp + AssetManager.h + StringRepository.h + StringRepository.cpp + Hash.h + Hash.cpp) +target_link_libraries(kde ${log-lib} + EGL + GLESv3 + android + game-activity::game-activity + games-frame-pacing::swappy_static) diff --git a/app/src/main/cpp/Hash.cpp b/app/src/main/cpp/Hash.cpp new file mode 100644 index 0000000..ea5421f --- /dev/null +++ b/app/src/main/cpp/Hash.cpp @@ -0,0 +1,152 @@ +#include "Hash.h" +#include +#include + +Hash::Hash() + : m_bucket_count(0), + m_used_buckets(0), + m_keys(nullptr), + m_values(nullptr) +{ +} + +Hash::Hash(uint32_t bucket_count) + : m_bucket_count(0), + m_used_buckets(0), + m_keys(nullptr), + m_values(nullptr) +{ + auto* mem = reinterpret_cast(malloc(sizeof(uint64_t) * 2 * bucket_count)); + if (!mem) + return; + m_bucket_count = bucket_count; + m_keys = mem; + m_values = mem + bucket_count; + memset(mem, 0, sizeof(uint64_t) * 2 * bucket_count); +} + +Hash::Hash(const Hash& copy) + : m_bucket_count(copy.m_bucket_count), + m_used_buckets(copy.m_used_buckets), + m_keys(nullptr), + m_values(nullptr) +{ + auto* mem = reinterpret_cast(malloc(sizeof(uint64_t) * 2 * m_bucket_count)); + if (!mem) + return; + m_keys = mem; + m_values = mem + m_bucket_count; + memcpy(m_keys, copy.m_keys, sizeof(uint64_t) * 2 * m_bucket_count); +} + +Hash& Hash::operator=(const Hash& rhs) +{ + if (m_keys) + free(m_keys); + m_bucket_count = rhs.m_bucket_count; + m_used_buckets = rhs.m_used_buckets; + auto* mem = reinterpret_cast(malloc(sizeof(uint64_t) * 2 * m_bucket_count)); + if (!mem) { + m_bucket_count = 0; + m_keys = nullptr; + m_values = nullptr; + return *this; + } + m_keys = mem; + m_values = mem + m_bucket_count; + memcpy(m_keys, rhs.m_keys, sizeof(uint64_t) * 2 * m_bucket_count); + return *this; +} + +Hash::~Hash() +{ + free(m_keys); + m_used_buckets = 0; + m_bucket_count = 0; + m_keys = nullptr; + m_values = nullptr; +} + +uint64_t Hash::lookup(uint64_t key, uint64_t default_value) +{ + if (m_bucket_count == 0) + return default_value; + uint64_t i = key % m_bucket_count; + do { + if (m_keys[i] == key) + return m_values[i]; + else if (m_keys[i] == HASH_EMPTY_KEY) + return default_value; + i = (i + 1) % m_bucket_count; + } while (i != key % m_bucket_count); + return default_value; +} + +bool Hash::insert(uint64_t key, uint64_t value) +{ + if (key == HASH_EMPTY_KEY || key == HASH_TOMBSTONE_KEY) { + return false; + } + + // Resize if necessary + float usage = static_cast(m_used_buckets) / static_cast(m_bucket_count); + if (m_bucket_count == 0 || usage > .5f) { + uint32_t new_cap = (m_bucket_count > 0) ? m_bucket_count * 2 : 128; + auto* new_mem = reinterpret_cast(malloc(sizeof(uint64_t) * new_cap * 2)); + if (!new_mem) + return false; + uint64_t* new_keys = new_mem; + uint64_t* new_values = new_keys + new_cap; + memset(new_keys, HASH_EMPTY_KEY, sizeof(uint64_t) * new_cap); + + // Re-insert all values + for (uint32_t i = 0; i < m_bucket_count; ++i) { + if (m_keys[i] != HASH_EMPTY_KEY) { + uint64_t idx = m_keys[i] % new_cap; + while (true) { + if (new_keys[idx] == HASH_EMPTY_KEY) { + new_keys[idx] = m_keys[i]; + new_values[idx] = m_values[i]; + break; + } + idx = (idx + 1) % new_cap; + } + } + } + free(m_keys); + m_keys = new_keys; + m_values = new_values; + m_bucket_count = new_cap; + } + + uint64_t i = key % m_bucket_count; + do { + if (m_keys[i] == HASH_EMPTY_KEY || m_keys[i] == HASH_TOMBSTONE_KEY) { + m_keys[i] = key; + m_values[i] = value; + ++m_used_buckets; + return true; + } + else if (m_keys[i] == key) { + m_values[i] = value; + return true; + } + i = (i + 1) % m_bucket_count; + } while (i != (key % m_bucket_count)); + return false; +} + +void Hash::remove(uint64_t key) +{ + if (m_bucket_count == 0) + return; + uint64_t i = key % m_bucket_count; + do { + if (m_keys[i] == key) { + m_keys[i] = HASH_TOMBSTONE_KEY; + } + else if (m_keys[i] == HASH_EMPTY_KEY) { + break; + } + } while (i != key % m_bucket_count); +} diff --git a/app/src/main/cpp/Hash.h b/app/src/main/cpp/Hash.h new file mode 100644 index 0000000..5e00a66 --- /dev/null +++ b/app/src/main/cpp/Hash.h @@ -0,0 +1,33 @@ +#ifndef KRIMI_DINNER_ENGINE_HASH_H +#define KRIMI_DINNER_ENGINE_HASH_H + +#include + +static constexpr uint64_t HASH_EMPTY_KEY = 0; +static constexpr uint64_t HASH_TOMBSTONE_KEY = 1; + +class Hash +{ +public: + Hash(); + Hash(uint32_t bucket_count); + Hash(const Hash& copy); + Hash& operator=(const Hash& rhs); + ~Hash(); + + uint64_t lookup(uint64_t key, uint64_t default_value); + + bool insert(uint64_t key, uint64_t value); + + void remove(uint64_t key); + +private: + uint32_t m_bucket_count; + uint32_t m_used_buckets; + uint64_t* m_keys; + uint64_t* m_values; +}; + +using nt_hash = Hash; + +#endif diff --git a/app/src/main/cpp/Log.h b/app/src/main/cpp/Log.h new file mode 100644 index 0000000..563491d --- /dev/null +++ b/app/src/main/cpp/Log.h @@ -0,0 +1,17 @@ +#ifndef KRIMI_DINNER_ENGINE_LOG_H +#define KRIMI_DINNER_ENGINE_LOG_H + +#include + +#define LOG_TAG "KrimiDinnerEngine" + +#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__); +#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__); +#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__); +#ifdef NDEBUG +#define ALOGV(...) +#else +#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__); +#endif + +#endif //KRIMI_DINNER_ENGINE_LOG_H diff --git a/app/src/main/cpp/NativeEngine.cpp b/app/src/main/cpp/NativeEngine.cpp new file mode 100644 index 0000000..89c8bec --- /dev/null +++ b/app/src/main/cpp/NativeEngine.cpp @@ -0,0 +1,410 @@ +// +// Created by kevin on 02.10.2022. +// + +#include "NativeEngine.h" +#include "Log.h" +#include "AssetManager.h" +#include "Renderer.h" +#include "TouchInput.h" + +#include +#include +#include +#include + +static NativeEngineState g_app_state = { false }; + +static void _handle_cmd_proxy(struct android_app* app, int32_t cmd) +{ + auto* engine = reinterpret_cast(app->userData); + engine->handleAppCmd(cmd); +} + +NativeEngine::NativeEngine(struct android_app *app) + : m_app(app), + m_egl_display(EGL_NO_DISPLAY), + m_egl_surface(EGL_NO_SURFACE), + m_egl_context(EGL_NO_CONTEXT), + m_jni_env(nullptr), + m_has_focus(false), + m_has_window(false), + m_is_visible(false), + m_in_motion(false) +{ + SwappyGL_init(getJniEnv(), m_app->activity->javaGameActivity); + SwappyGL_setSwapIntervalNS(SWAPPY_SWAP_20FPS); + + android_app_set_key_event_filter(m_app, NULL); + android_app_set_motion_event_filter(m_app, NULL); + + AssetManager::create(m_app->activity->assetManager); + + m_smiley = StringRepository::global->internString("smiley_PNG42.png"); + m_smiley_pos = { 100, 100 }; +} + +NativeEngine::~NativeEngine() +{ + ALOGI("NativeEngine: destructor"); + SwappyGL_destroy(); + killContext(); + if (m_jni_env) { + m_app->activity->vm->DetachCurrentThread(); + } +} + +void NativeEngine::gameLoop() +{ + m_app->userData = this; + m_app->onAppCmd = _handle_cmd_proxy; + m_app->textInputState = 0; + + while (true) { + int events; + struct android_poll_source* source; + + // Poll commands + while ((ALooper_pollAll(isAnimating() ? 0 : -1, nullptr, + &events, reinterpret_cast(&source))) >= 0) { + if (source) + source->process(source->app, source); + if (m_app->destroyRequested) + return; + } + + constexpr int MAX_INPUT_EVENTS = 16; + TouchInputEvent input_events[MAX_INPUT_EVENTS]; + int input_event_count = 0; + + // Handle input + android_input_buffer* input_buffer = android_app_swap_input_buffers(m_app); + if (input_buffer) { + if (input_buffer->keyEventsCount > 0) { + android_app_clear_key_events(input_buffer); + } + if (input_buffer->motionEventsCount > 0) { + for (unsigned int i = 0; i < input_buffer->motionEventsCount; ++i) { + GameActivityMotionEvent motion_event = input_buffer->motionEvents[i]; + if (motion_event.action == AMOTION_EVENT_ACTION_DOWN) { + if (motion_event.pointerCount > 0) { + GameActivityPointerAxes pointer = motion_event.pointers[0]; + float x = GameActivityPointerAxes_getX(&pointer); + float y = GameActivityPointerAxes_getY(&pointer); + + // Record this motion + m_in_motion = true; + m_last_down.x = x; + m_last_down.y = y; + } + } + else if (motion_event.action == AMOTION_EVENT_ACTION_UP) { + if (!m_in_motion) { + ALOGW("Got an UP motion without a corresponding DOWN motion"); + continue; + } + + if (motion_event.pointerCount > 0) { + GameActivityPointerAxes pointer = motion_event.pointers[0]; + float x = GameActivityPointerAxes_getX(&pointer); + float y = GameActivityPointerAxes_getY(&pointer); + + float dist = sqrtf((x - m_last_down.x) * (x - m_last_down.x) + + (y - m_last_down.y) * (y - m_last_down.y)); + + if (dist < 5.f) { + // TAP + ALOGI("TAP at %f %f", x, y); + input_events[input_event_count].kind = TouchInputEventKind::Tap; + input_events[input_event_count].start = { x, y }; + input_events[input_event_count].end = { x, y }; + ++input_event_count; + } + else { + // Swipe + ALOGI("Swipe from %f %f to %f %f", + m_last_down.x, m_last_down.y, + x, y); + input_events[input_event_count].kind = TouchInputEventKind::Tap; + input_events[input_event_count].start = { m_last_down.x, m_last_down.y }; + input_events[input_event_count].end = { x, y }; + ++input_event_count; + } + m_in_motion = false; + if (input_event_count == MAX_INPUT_EVENTS) + break; + } + } + else if (motion_event.action == AMOTION_EVENT_ACTION_CANCEL) { + m_in_motion = false; + } + } + android_app_clear_motion_events(input_buffer); + } + } + + if (isAnimating() && Renderer::ptr) { + static float x = 1.f; + static float d = -0.01f; + x += d; + if ( x <= 0.f) + d *= -1.f; + else if (x >= 1.f) + d *= -1.f; + + + if (input_event_count > 0) { + m_smiley_pos = input_events[input_event_count - 1].end; + m_smiley_pos.x -= 250; + m_smiley_pos.y -= 250; + } + + Renderer::ptr->addRect(100, 100, 500, 500, 0.3f, 0.3f, 0.3f, 1.f); + Renderer::ptr->addRect(m_smiley_pos.x, m_smiley_pos.y, 500, 500, 0.f, x*x, 1.f - x*x, 1.f, m_smiley); + } + + if (isAnimating()) { + renderFrame(); + } + } +} + +bool NativeEngine::isAnimating() const +{ + return m_has_window && m_has_focus && m_is_visible; +} + + +void NativeEngine::handleAppCmd(int32_t cmd) +{ + ALOGV("NativeEngine: Handling command %d.", cmd); + switch (cmd) { + case APP_CMD_SAVE_STATE: + break; + case APP_CMD_INIT_WINDOW: + ALOGV("NativeEngine:: APP_CMD_INIT_WINDOW"); + if (m_app->window) { + m_has_window = true; + SwappyGL_setWindow(m_app->window); + if (m_app->savedStateSize == sizeof(m_state) && m_app->savedState) { + m_state = *reinterpret_cast(m_app->savedState); + m_has_focus = m_state.has_focus; + } + else { + // Workaround APP_CMD_GAINED_FOCUS issue where the focus state is not passed + // down from GameActivity when restarting Activity + m_has_focus = g_app_state.has_focus; + } + } + ALOGV("HandleCommand(%d): hasWindow = %d, hasFocus = %d", cmd, + m_has_window ? 1 : 0, m_has_focus ? 1 : 0); + break; + case APP_CMD_TERM_WINDOW: + ALOGV("NativeEngine: APP_CMD_TERM_WINDOW"); + killSurface(); + m_has_window = false; + break; + case APP_CMD_GAINED_FOCUS: + ALOGV("NativeEngine: APP_CMD_GAINED_FOCUS"); + m_has_focus = true; + m_state.has_focus = g_app_state.has_focus = m_has_focus; + break; + case APP_CMD_LOST_FOCUS: + ALOGV("NativeEngine: APP_CMD_LOST_FOCUS"); + m_has_focus = false; + m_state.has_focus = g_app_state.has_focus = m_has_focus; + break; + case APP_CMD_START: + ALOGV("NativeEngine: APP_CMD_START"); + m_is_visible = true; + break; + case APP_CMD_STOP: + ALOGV("NativeEngine: APP_CMD_STOP"); + m_is_visible = false; + break; + default: + ALOGW("Unhandled command."); + break; + } + ALOGV("NativeEngine STATUS: F%d, V%d, W%d, EGL: D %p, S %p, CTX %p, CFG %p", + m_has_focus, m_is_visible, m_has_window, m_egl_display, m_egl_surface, m_egl_context, + m_egl_config); +} + +JNIEnv* NativeEngine::getJniEnv() +{ + if (!m_jni_env) { + if (m_app->activity->vm->AttachCurrentThread(&m_jni_env, nullptr) != 0) { + ALOGE("*** FATAL ERROR: failed to attach thread to JNI."); + exit(1); + } + ALOGI("Attached current thread to JNI, %p", m_jni_env); + } + return m_jni_env; +} + +bool NativeEngine::prepareToRender() +{ + if (m_egl_display == EGL_NO_DISPLAY || m_egl_surface == EGL_NO_SURFACE || m_egl_context == EGL_NO_CONTEXT) { + if (!initDisplay()) { + ALOGE("NativeEngine: failed to create display"); + return false; + } + + if (!initSurface()) { + ALOGE("NativeEngine: failed to create surface."); + return false; + } + + if (!initContext()) { + ALOGE("NativeEngine: failed to create context."); + return false; + } + + ALOGI("NativeEngine: binding surface and context (display %p, surface %p, context %p)", + m_egl_display, m_egl_surface, m_egl_context); + + if (eglMakeCurrent(m_egl_display, m_egl_surface, m_egl_surface, m_egl_context) == EGL_FALSE) { + ALOGE("NativeEngine: eglMakeCurrent failed, EGL error: %d", eglGetError()); + return false; + } + + initGLObjects(); + } + return true; +} + +bool NativeEngine::initDisplay() +{ + if (m_egl_display != EGL_NO_DISPLAY) { + return true; + } + + ALOGI("NativeEngine: Initializing display"); + m_egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (eglInitialize(m_egl_display, 0, 0) == EGL_FALSE) { + ALOGE("NativeEngine: Failed to init display, error %d", eglGetError()); + return false; + } + return true; +} + +void NativeEngine::killDisplay() +{ + ALOGI("NativeEngine: Killing display"); + killContext(); + killSurface(); + + if (m_egl_display != EGL_NO_DISPLAY) { + eglTerminate(m_egl_display); + m_egl_display = EGL_NO_DISPLAY; + } +} + +bool NativeEngine::initSurface() +{ + assert(m_egl_display != EGL_NO_DISPLAY); + if (m_egl_surface != EGL_NO_SURFACE) { + return true; + } + + ALOGI("NativeEngine: initializing surface"); + + EGLint num_configs; + const EGLint attribs[] = { + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_BLUE_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_RED_SIZE, 8, + EGL_DEPTH_SIZE, 16, + EGL_NONE, + }; + eglChooseConfig(m_egl_display, attribs, &m_egl_config, 1, &num_configs); + + m_egl_surface = eglCreateWindowSurface(m_egl_display, m_egl_config, m_app->window, nullptr); + if (m_egl_surface == EGL_NO_SURFACE) { + ALOGE("Failed to create EGL surface. EGL error: %d", eglGetError()); + return false; + } + return true; +} + +void NativeEngine::killSurface() +{ + ALOGI("NativeEngine: Killing surface."); + eglMakeCurrent(m_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (m_egl_surface != EGL_NO_SURFACE) { + eglDestroySurface(m_egl_display, m_egl_surface); + m_egl_surface = EGL_NO_SURFACE; + } +} + +bool NativeEngine::initContext() +{ + ALOGI("NativeEngine: initializing context"); + assert(m_egl_display != EGL_NO_DISPLAY); + + EGLint attrib_list[] = { + EGL_CONTEXT_CLIENT_VERSION, 3, + EGL_NONE + }; + + if (m_egl_context != EGL_NO_CONTEXT) + return true; + + m_egl_context = eglCreateContext(m_egl_display, m_egl_config, nullptr, attrib_list); + if (m_egl_context == EGL_NO_CONTEXT) { + ALOGE("Failed to create EGL context, egl error: %d", eglGetError()); + return false; + } + return true; +} + +void NativeEngine::killContext() +{ + ALOGI("NativeEngine: Killing context"); + + killGLObjects(); + + eglMakeCurrent(m_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (m_egl_context != EGL_NO_CONTEXT) { + eglDestroyContext(m_egl_display, m_egl_context); + m_egl_context = EGL_NO_CONTEXT; + } +} + +bool NativeEngine::initGLObjects() +{ + if (Renderer::ptr) { + return true; + } + Renderer::create(); + + return true; +} + +void NativeEngine::killGLObjects() +{ + if (Renderer::ptr) { + Renderer::destroy(); + } +} + +void NativeEngine::renderFrame() +{ + if (!prepareToRender()) { + ALOGE("NativeEngine: preparation to render failed"); + return; + } + + int width, height; + eglQuerySurface(m_egl_display, m_egl_surface, EGL_WIDTH, &width); + eglQuerySurface(m_egl_display, m_egl_surface, EGL_HEIGHT, &height); + + Renderer::ptr->renderFrame(static_cast(width), static_cast(height)); + + if (!SwappyGL_swap(m_egl_display, m_egl_surface)) { + ALOGW("NativeEngine: SwappyGL_swap failed, EGL error %d", eglGetError()); + } +} \ No newline at end of file diff --git a/app/src/main/cpp/NativeEngine.h b/app/src/main/cpp/NativeEngine.h new file mode 100644 index 0000000..deb9261 --- /dev/null +++ b/app/src/main/cpp/NativeEngine.h @@ -0,0 +1,65 @@ +#ifndef KRIMI_DINNER_ENGINE_NATIVEENGINE_H +#define KRIMI_DINNER_ENGINE_NATIVEENGINE_H + +#include "Position.h" +#include "StringRepository.h" + +#include +#include + +struct NativeEngineState +{ + bool has_focus; +}; + +class NativeEngine { +public: + NativeEngine(struct android_app* app); + ~NativeEngine(); + + void gameLoop(); + + void handleAppCmd(int32_t event); + +private: + bool isAnimating() const; + + JNIEnv* getJniEnv(); + + bool prepareToRender(); + void renderFrame(); + + bool initDisplay(); + void killDisplay(); + bool initSurface(); + void killSurface(); + bool initContext(); + void killContext(); + + bool initGLObjects(); + void killGLObjects(); + + struct android_app* m_app; + + bool m_has_window; + bool m_has_focus; + bool m_is_visible; + + NativeEngineState m_state; + + EGLDisplay m_egl_display; + EGLSurface m_egl_surface; + EGLContext m_egl_context; + EGLConfig m_egl_config; + + StringHandle m_smiley; + Position m_smiley_pos; + + Position m_last_down; + bool m_in_motion; + + JNIEnv* m_jni_env; +}; + + +#endif \ No newline at end of file diff --git a/app/src/main/cpp/Position.h b/app/src/main/cpp/Position.h new file mode 100644 index 0000000..076ccc7 --- /dev/null +++ b/app/src/main/cpp/Position.h @@ -0,0 +1,10 @@ +#ifndef KRIMI_DINNER_ENGINE_POSITION_H +#define KRIMI_DINNER_ENGINE_POSITION_H + +struct Position +{ + float x; + float y; +}; + +#endif //KRIMI_DINNER_ENGINE_POSITION_H diff --git a/app/src/main/cpp/Renderer.cpp b/app/src/main/cpp/Renderer.cpp new file mode 100644 index 0000000..b5cf995 --- /dev/null +++ b/app/src/main/cpp/Renderer.cpp @@ -0,0 +1,258 @@ +#include "Renderer.h" +#include "Log.h" +#include "AssetManager.h" + +Renderer* Renderer::ptr = nullptr; + +static const char* g_vert_src = +"#version 300 es \n" +"precision mediump float; \n" +"uniform vec2 res; // resolution \n" +"layout (location = 0) in vec2 v_p0; // top left corner on screen \n" +"layout (location = 1) in vec2 v_p1; // top right corner on screen \n" +"layout (location = 2) in vec2 v_src_p0; \n" +"layout (location = 3) in vec2 v_src_p1; \n" +"layout (location = 4) in vec4 v_color; // color \n" +"out vec4 f_color; \n" +"out vec2 f_uv; \n" +"const vec2 vertices[6] = vec2[6]( \n" +" vec2(-1,-1), \n" +" vec2(+1, -1), \n" +" vec2(-1, +1), \n" +" vec2(+1, -1), \n" +" vec2(+1, +1), \n" +" vec2(-1, +1) \n" +"); \n" +"void main() \n" +"{ \n" +" vec2 v = vertices[gl_VertexID]; \n" +" // destination on screen \n" +" //vec2 dst_half_size = (v_p1 - v_p0) / 2.0; \n" +" //vec2 dst_center = (v_p1 + v_p0) / 2.0; \n" +" vec2 dst_pos = v * ((v_p1 - v_p0) / 2.0) + ((v_p1 + v_p0) / 2.0); \n" +" dst_pos.y = res.y - dst_pos.y; \n" +" vec2 src = v * ((v_src_p1 - v_src_p0) / 2.0) + ((v_src_p1 + v_src_p0) / 2.0); \n" +" gl_Position = vec4(2.0 * dst_pos.x / res.x - 1.0, \n" +" 2.0 * dst_pos.y / res.y - 1.0, \n" +" 0.0, \n" +" 1.0); \n" +" f_color = v_color; \n" +" f_uv = src; \n" +"} \n"; + +static const char* g_frag_src = +"#version 300 es \n" +"precision mediump float; \n" +"in vec2 f_uv; \n" +"in vec4 f_color; \n" +"layout (location = 0) out vec4 frag_color; \n" +"uniform sampler2D s_texture; \n" +"void main() \n" +"{ \n" +" vec4 tex_color = texture(s_texture, f_uv); \n" +" frag_color = tex_color * f_color; \n" +"} \n"; + +void Renderer::create() +{ + Renderer::ptr = new Renderer; +} + +void Renderer::destroy() +{ + delete Renderer::ptr; + Renderer::ptr = nullptr; +} + +Renderer::Renderer() +{ + GLuint vertex = 0, fragment = 0; + vertex = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex, 1, &g_vert_src, nullptr); + glCompileShader(vertex); + int status = 0; + glGetShaderiv(vertex, GL_COMPILE_STATUS, &status); + if (status != GL_TRUE) { + char info[512]; + glGetShaderInfoLog(vertex, 512, nullptr, info); + ALOGE("Failed to compile ui vertex shader: %s", info); + } + + + fragment = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment, 1, &g_frag_src, nullptr); + glCompileShader(fragment); + glGetShaderiv(fragment, GL_COMPILE_STATUS, &status); + if (status != GL_TRUE) { + char info[512]; + glGetShaderInfoLog(fragment, 512, nullptr, info); + ALOGE("Failed to compile ui fragment shader: %s", info); + } + + m_shader = glCreateProgram(); + glAttachShader(m_shader, vertex); + glAttachShader(m_shader, fragment); + glLinkProgram(m_shader); + glGetProgramiv(m_shader, GL_LINK_STATUS, &status); + if (status != GL_TRUE) { + char info[512]; + glGetProgramInfoLog(m_shader, 512, nullptr, info); + ALOGE("Failed to link ui shader: %s", info); + } + + glDeleteShader(vertex); + glDeleteShader(fragment); + + glGenBuffers(1, &m_vbo); + glGenVertexArrays(1, &m_vao); + glBindVertexArray(m_vao); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)0); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)(2 * sizeof(float))); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)(4 * sizeof(float))); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)(6 * sizeof(float))); + glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)(8 * sizeof(float))); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); + glEnableVertexAttribArray(3); + glEnableVertexAttribArray(4); + glVertexAttribDivisor(0, 1); + glVertexAttribDivisor(1, 1); + glVertexAttribDivisor(2, 1); + glVertexAttribDivisor(3, 1); + glVertexAttribDivisor(4, 1); + glBindVertexArray(0); + + // Dummy texture (1x1px white) + unsigned char tex[] = { 255, 255, 255, 255 }; + Texture dummy_texture(1, 1, tex); + m_textures.insert(std::make_pair(0, dummy_texture)); + m_dummy_texture = 0; +} + +Renderer::~Renderer() { + for (auto texture : m_textures) + texture.second.destroy(); + glDeleteProgram(m_shader); + glDeleteVertexArrays(1, &m_vao); + glDeleteBuffers(1, &m_vbo); +} + +void Renderer::addRect(float x, float y, float w, float h) +{ + addRect(x, y, w, h, 1.f, 1.f, 1.f, 1.f, m_dummy_texture, 0.f, 0.f, 1.f, 1.f); +} + +void Renderer::addRect(float x, float y, float w, float h, StringHandle texture) +{ + addRect(x, y, w, h, 1.f, 1.f, 1.f, 1.f, texture, 0.f, 0.f, 1.f, 1.f); +} + +void Renderer::addRect(float x, float y, float w, float h, float r, float g, float b, float a) +{ + addRect(x, y, w, h, r, g, b, a, m_dummy_texture, 0.f, 0.f, 1.f, 1.f); +} + +void Renderer::addRect(float x, float y, float w, float h, float r, float g, float b, float a, StringHandle texture) +{ + addRect(x, y, w, h, r, g, b, a, texture, 0.f, 0.f, 1.f, 1.f); +} + +void Renderer::addRect(float x, float y, float w, float h, StringHandle texture, float src_x, float src_y, float src_w, float src_h) +{ + addRect(x, y, w, h, 1.f, 1.f, 1.f, 1.f, texture, src_x, src_y, src_w, src_h); +} + +void Renderer::addRect(float x, float y, float w, float h, float r, float g, float b, float a, StringHandle texture, float src_x, float src_y, float src_w, float src_h) +{ + if (m_textures.find(texture) == m_textures.end()) { + Texture tex; + if (!AssetManager::ptr->loadTexture(StringRepository::global->getString(texture), + &tex)) { + ALOGE("Failed to load texture"); + return; + } + m_textures.insert(std::make_pair(texture, tex)); + } + + Rect rect = {}; + rect.dst_p0_x = x; + rect.dst_p0_y = y; + rect.dst_p1_x = x + w; + rect.dst_p1_y = y + h; + rect.src_p0_x = src_x; + rect.src_p0_y = src_y; + rect.src_p1_x = src_w; + rect.src_p1_y = src_y + src_h; + rect.r = r; + rect.g = g; + rect.b = b; + rect.a = a; + m_rects.push_back(rect); + m_draw_textures.push_back(texture); +} + +void Renderer::renderFrame(float width, float height) +{ + assert(m_rects.size() == m_draw_textures.size()); + + const auto rect_count = static_cast(m_rects.size()); + if (rect_count == 0) + return; + + glViewport(0, 0, static_cast(width), static_cast(height)); + glClearColor(0.8f, 0.3f, 0.3f, 1.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glBindVertexArray(m_vao); + glUseProgram(m_shader); + glUniform2f(glGetUniformLocation(m_shader, "res"), width, height); + glUniform1i(glGetUniformLocation(m_shader, "s_texture"), 0); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + + size_t start = 0; + StringHandle current_texture = m_draw_textures[0]; + while (start < rect_count) { + glActiveTexture(GL_TEXTURE0); + m_textures[current_texture].bind(); + for (size_t i = start; i < rect_count; ++i) { + StringHandle texture = m_draw_textures[i]; + if ((texture != current_texture)) { + // Draw everything in [start, i - 1] + const size_t count = i - start; + glBufferData(GL_ARRAY_BUFFER, + static_cast(sizeof(Rect) * count), &m_rects[start], + GL_STREAM_DRAW); + glDrawArraysInstanced(GL_TRIANGLES, 0, 6, static_cast(count)); + + start = i; + current_texture = texture; + break; + } + + if (i == rect_count - 1) { + // just draw it + const size_t count = rect_count - start; + glBufferData(GL_ARRAY_BUFFER, + static_cast(sizeof(Rect) * count), &m_rects[start], + GL_STREAM_DRAW); + glDrawArraysInstanced(GL_TRIANGLES, 0, 6, static_cast(count)); + + start = rect_count; + current_texture = texture; + } + } + + + } + m_rects.clear(); + m_draw_textures.clear(); +} \ No newline at end of file diff --git a/app/src/main/cpp/Renderer.h b/app/src/main/cpp/Renderer.h new file mode 100644 index 0000000..c5be621 --- /dev/null +++ b/app/src/main/cpp/Renderer.h @@ -0,0 +1,62 @@ +#ifndef KRIMI_DINNER_ENGINE_RENDERER_H +#define KRIMI_DINNER_ENGINE_RENDERER_H + +#include +#include +#include + +#include "Texture.h" +#include "StringRepository.h" + +class Renderer +{ +public: + static Renderer* ptr; + + static void create(); + + static void destroy(); + + void addRect(float x, float y, float w, float h); + + void addRect(float x, float y, float w, float h, StringHandle texture); + + void addRect(float x, float y, float w, float h, float r, float g, float b, float a); + + void addRect(float x, float y, float w, float h, float r, float g, float b, float a, StringHandle texture); + + void addRect(float x, float y, float w, float h, StringHandle texture, float src_x, float src_y, float src_w, float src_h); + + void addRect(float x, float y, float w, float h, float r, float g, float b, float a, StringHandle texture, float src_x, float src_y, float src_w, float src_h); + + void renderFrame(float width, float height); + +private: + Renderer(); + ~Renderer(); + + Renderer(const Renderer&) = delete; + Renderer& operator=(const Renderer&) = delete; + + struct Rect { + float dst_p0_x, dst_p0_y; + float dst_p1_x, dst_p1_y; + float src_p0_x, src_p0_y; + float src_p1_x, src_p1_y; + float r, g, b, a; + }; + + GLuint m_shader; + GLuint m_vao; + GLuint m_vbo; + + StringHandle m_dummy_texture; + + std::vector m_rects; + std::vector m_draw_textures; + + std::unordered_map m_textures; +}; + + +#endif \ No newline at end of file diff --git a/app/src/main/cpp/StringRepository.cpp b/app/src/main/cpp/StringRepository.cpp new file mode 100644 index 0000000..727c6b0 --- /dev/null +++ b/app/src/main/cpp/StringRepository.cpp @@ -0,0 +1,84 @@ +#include "StringRepository.h" +#include +#include + +static StringRepository g_global_repository; +StringRepository* StringRepository::global = &g_global_repository; + +static uint64_t hashString(const char* string, unsigned int length) +{ + uint64_t hash = 0xcbf29ce484222325; + for (unsigned int i = 0; i < length; ++i) { + hash = hash ^ string[i]; + hash = hash * 0x00000100000001B3; + } + if (hash == HASH_EMPTY_KEY || hash == HASH_TOMBSTONE_KEY) + hash = ~hash; + return hash; +} + +StringRepository::StringRepository(const StringRepository& copy) +{ + if (m_buffer) + free(m_buffer); + m_one_past_last_char = copy.m_one_past_last_char; + m_buffer_size = copy.m_buffer_size; + m_hash = copy.m_hash; + m_buffer = reinterpret_cast(malloc(m_buffer_size)); + memcpy(m_buffer, copy.m_buffer, m_buffer_size); +} + +StringRepository::~StringRepository() +{ + m_one_past_last_char = 0; + m_buffer_size = 0; + free(m_buffer); +} + +StringHandle StringRepository::internStringLength(const char* string, unsigned int length) +{ + uint64_t hash = hashString(string, length); + uint32_t offset = static_cast(m_hash.lookup(hash, UINT32_MAX)); + if (offset == UINT32_MAX) { + offset = m_one_past_last_char; + if ((offset + length + 1) >= m_buffer_size) { + uint32_t new_size = (m_buffer_size > 0) ? 2 * m_buffer_size : 1024; + void* tmp = realloc(m_buffer, new_size); + if (!tmp) + return 0; + m_buffer = reinterpret_cast(tmp); + m_buffer_size = new_size; + } + char* dest = m_buffer + offset; + memcpy(dest, string, length); + dest[length] = '\0'; + m_one_past_last_char += length + 1; + if (!m_hash.insert(hash, offset)) + return 0; + } + return static_cast(offset + 1); +} + +StringHandle StringRepository::internString(const char* string) +{ + return internStringLength(string, strlen(string)); +} + +const char* StringRepository::getString(StringHandle handle) +{ + if (handle == 0 || handle >= m_one_past_last_char) + return nullptr; + uint32_t offset = handle - 1; + return &m_buffer[offset]; +} + +void StringRepository::releaseString(StringHandle) +{ + // do nothing +} + +void StringRepository::freeAll() +{ + m_one_past_last_char = 0; + m_hash = Hash(); +} diff --git a/app/src/main/cpp/StringRepository.h b/app/src/main/cpp/StringRepository.h new file mode 100644 index 0000000..5f3cd63 --- /dev/null +++ b/app/src/main/cpp/StringRepository.h @@ -0,0 +1,39 @@ +#ifndef KRIMI_DINNER_ENGINE_STRINGREPOSITORY_H +#define KRIMI_DINNER_ENGINE_STRINGREPOSITORY_H + +#include +#include "Hash.h" + +using StringHandle = uint32_t; + +// Alias for compatibility +using nt_string_handle = StringHandle; + +class StringRepository +{ +public: + // The default string repository + static StringRepository* global; + + StringRepository() = default; + StringRepository(const StringRepository& copy); + ~StringRepository(); + + StringHandle internStringLength(const char* string, unsigned int length); + + StringHandle internString(const char* string); + + const char* getString(StringHandle handle); + + void releaseString(StringHandle handle); + + void freeAll(); + +private: + uint32_t m_buffer_size; + uint32_t m_one_past_last_char; + char* m_buffer; + Hash m_hash; +}; + +#endif \ No newline at end of file diff --git a/app/src/main/cpp/Texture.cpp b/app/src/main/cpp/Texture.cpp new file mode 100644 index 0000000..57c60a7 --- /dev/null +++ b/app/src/main/cpp/Texture.cpp @@ -0,0 +1,34 @@ +#include "Texture.h" + +Texture::Texture(unsigned int width, unsigned int height, const void *data) + : m_texture(0) +{ + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &m_texture); + glBindTexture(GL_TEXTURE_2D, m_texture); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGBA, + static_cast(width), + static_cast(height), + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + data); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); +} + +void Texture::destroy() +{ + glDeleteTextures(1, &m_texture); +} + +void Texture::bind() const +{ + glBindTexture(GL_TEXTURE_2D, m_texture); +} \ No newline at end of file diff --git a/app/src/main/cpp/Texture.h b/app/src/main/cpp/Texture.h new file mode 100644 index 0000000..4a69f50 --- /dev/null +++ b/app/src/main/cpp/Texture.h @@ -0,0 +1,25 @@ +#ifndef KRIMI_DINNER_ENGINE_TEXTURE_H +#define KRIMI_DINNER_ENGINE_TEXTURE_H + +#include + +class Renderer; + +class Texture +{ +public: + Texture() : m_texture(0) {} + Texture(unsigned int width, unsigned int height, const void* data); + Texture(const Texture&) = default; + Texture(Texture&&) = default; + Texture& operator=(const Texture&) = default; + + void destroy(); + + void bind() const; + +private: + GLuint m_texture; +}; + +#endif diff --git a/app/src/main/cpp/TouchInput.h b/app/src/main/cpp/TouchInput.h new file mode 100644 index 0000000..760c6d5 --- /dev/null +++ b/app/src/main/cpp/TouchInput.h @@ -0,0 +1,19 @@ +#ifndef KRIMI_DINNER_ENGINE_TOUCHINPUT_H +#define KRIMI_DINNER_ENGINE_TOUCHINPUT_H + +#include "Position.h" + +enum class TouchInputEventKind +{ + Tap, + Swipe +}; + +struct TouchInputEvent +{ + TouchInputEventKind kind; + Position start; + Position end; +}; + +#endif \ No newline at end of file diff --git a/app/src/main/cpp/kde.cpp b/app/src/main/cpp/kde.cpp new file mode 100644 index 0000000..feabc41 --- /dev/null +++ b/app/src/main/cpp/kde.cpp @@ -0,0 +1,15 @@ +#include +#include +extern "C" { +#include +} + +extern "C" { void android_main(struct android_app* app); } + +#include "NativeEngine.h" + +void android_main(struct android_app* app) { + auto* engine = new NativeEngine(app); + engine->gameLoop(); + delete engine; +} \ No newline at end of file diff --git a/app/src/main/cpp/stb_image.h b/app/src/main/cpp/stb_image.h new file mode 100644 index 0000000..d60371b --- /dev/null +++ b/app/src/main/cpp/stb_image.h @@ -0,0 +1,7897 @@ +/* stb_image - v2.27 - public domain image loader - http://nothings.org/stb + no warranty implied; use at your own risk + + Do this: + #define STB_IMAGE_IMPLEMENTATION + before you include this file in *one* C or C++ file to create the implementation. + + // i.e. it should look like this: + #include ... + #include ... + #include ... + #define STB_IMAGE_IMPLEMENTATION + #include "stb_image.h" + + You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. + And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free + + + QUICK NOTES: + Primarily of interest to game developers and other people who can + avoid problematic images and only need the trivial interface + + JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) + PNG 1/2/4/8/16-bit-per-channel + + TGA (not sure what subset, if a subset) + BMP non-1bpp, non-RLE + PSD (composited view only, no extra channels, 8/16 bit-per-channel) + + GIF (*comp always reports as 4-channel) + HDR (radiance rgbE format) + PIC (Softimage PIC) + PNM (PPM and PGM binary only) + + Animated GIF still needs a proper API, but here's one way to do it: + http://gist.github.com/urraka/685d9a6340b26b830d49 + + - decode from memory or through FILE (define STBI_NO_STDIO to remove code) + - decode from arbitrary I/O callbacks + - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) + + Full documentation under "DOCUMENTATION" below. + + +LICENSE + + See end of file for license information. + +RECENT REVISION HISTORY: + + 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes + 2.26 (2020-07-13) many minor fixes + 2.25 (2020-02-02) fix warnings + 2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically + 2.23 (2019-08-11) fix clang static analysis warning + 2.22 (2019-03-04) gif fixes, fix warnings + 2.21 (2019-02-25) fix typo in comment + 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings + 2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes + 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs + 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 + RGB-format JPEG; remove white matting in PSD; + allocate large structures on the stack; + correct channel count for PNG & BMP + 2.10 (2016-01-22) avoid warning introduced in 2.09 + 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED + + See end of file for full revision history. + + + ============================ Contributors ========================= + + Image formats Extensions, features + Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) + Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) + Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) + Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) + Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) + Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) + Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) + github:urraka (animated gif) Junggon Kim (PNM comments) + Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA) + socks-the-fox (16-bit PNG) + Jeremy Sawicki (handle all ImageNet JPGs) + Optimizations & bugfixes Mikhail Morozov (1-bit BMP) + Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) + Arseny Kapoulkine Simon Breuss (16-bit PNM) + John-Mark Allen + Carmelo J Fdez-Aguera + + Bug & warning fixes + Marc LeBlanc David Woo Guillaume George Martins Mozeiko + Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski + Phil Jordan Dave Moore Roy Eltham + Hayaki Saito Nathan Reed Won Chun + Luke Graham Johan Duparc Nick Verigakis the Horde3D community + Thomas Ruf Ronny Chevalier github:rlyeh + Janez Zemva John Bartholomew Michal Cichon github:romigrou + Jonathan Blow Ken Hamada Tero Hanninen github:svdijk + Eugene Golushkov Laurent Gomila Cort Stratton github:snagar + Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex + Cass Everitt Ryamond Barbiero github:grim210 + Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw + Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus + Josh Tobin Matthew Gregan github:poppolopoppo + Julian Raschke Gregory Mullen Christian Floisand github:darealshinji + Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007 + Brad Weinberger Matvey Cherevko github:mosra + Luca Sas Alexander Veselov Zack Middleton [reserved] + Ryan C. Gordon [reserved] [reserved] + DO NOT ADD YOUR NAME HERE + + Jacko Dirks + + To add your name to the credits, pick a random blank space in the middle and fill it. + 80% of merge conflicts on stb PRs are due to people adding their name at the end + of the credits. +*/ + +#ifndef STBI_INCLUDE_STB_IMAGE_H +#define STBI_INCLUDE_STB_IMAGE_H + +// DOCUMENTATION +// +// Limitations: +// - no 12-bit-per-channel JPEG +// - no JPEGs with arithmetic coding +// - GIF always returns *comp=4 +// +// Basic usage (see HDR discussion below for HDR usage): +// int x,y,n; +// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); +// // ... process data if not NULL ... +// // ... x = width, y = height, n = # 8-bit components per pixel ... +// // ... replace '0' with '1'..'4' to force that many components per pixel +// // ... but 'n' will always be the number that it would have been if you said 0 +// stbi_image_free(data) +// +// Standard parameters: +// int *x -- outputs image width in pixels +// int *y -- outputs image height in pixels +// int *channels_in_file -- outputs # of image components in image file +// int desired_channels -- if non-zero, # of image components requested in result +// +// The return value from an image loader is an 'unsigned char *' which points +// to the pixel data, or NULL on an allocation failure or if the image is +// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, +// with each pixel consisting of N interleaved 8-bit components; the first +// pixel pointed to is top-left-most in the image. There is no padding between +// image scanlines or between pixels, regardless of format. The number of +// components N is 'desired_channels' if desired_channels is non-zero, or +// *channels_in_file otherwise. If desired_channels is non-zero, +// *channels_in_file has the number of components that _would_ have been +// output otherwise. E.g. if you set desired_channels to 4, you will always +// get RGBA output, but you can check *channels_in_file to see if it's trivially +// opaque because e.g. there were only 3 channels in the source image. +// +// An output image with N components has the following components interleaved +// in this order in each pixel: +// +// N=#comp components +// 1 grey +// 2 grey, alpha +// 3 red, green, blue +// 4 red, green, blue, alpha +// +// If image loading fails for any reason, the return value will be NULL, +// and *x, *y, *channels_in_file will be unchanged. The function +// stbi_failure_reason() can be queried for an extremely brief, end-user +// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS +// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly +// more user-friendly ones. +// +// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. +// +// To query the width, height and component count of an image without having to +// decode the full file, you can use the stbi_info family of functions: +// +// int x,y,n,ok; +// ok = stbi_info(filename, &x, &y, &n); +// // returns ok=1 and sets x, y, n if image is a supported format, +// // 0 otherwise. +// +// Note that stb_image pervasively uses ints in its public API for sizes, +// including sizes of memory buffers. This is now part of the API and thus +// hard to change without causing breakage. As a result, the various image +// loaders all have certain limits on image size; these differ somewhat +// by format but generally boil down to either just under 2GB or just under +// 1GB. When the decoded image would be larger than this, stb_image decoding +// will fail. +// +// Additionally, stb_image will reject image files that have any of their +// dimensions set to a larger value than the configurable STBI_MAX_DIMENSIONS, +// which defaults to 2**24 = 16777216 pixels. Due to the above memory limit, +// the only way to have an image with such dimensions load correctly +// is for it to have a rather extreme aspect ratio. Either way, the +// assumption here is that such larger images are likely to be malformed +// or malicious. If you do need to load an image with individual dimensions +// larger than that, and it still fits in the overall size limit, you can +// #define STBI_MAX_DIMENSIONS on your own to be something larger. +// +// =========================================================================== +// +// UNICODE: +// +// If compiling for Windows and you wish to use Unicode filenames, compile +// with +// #define STBI_WINDOWS_UTF8 +// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert +// Windows wchar_t filenames to utf8. +// +// =========================================================================== +// +// Philosophy +// +// stb libraries are designed with the following priorities: +// +// 1. easy to use +// 2. easy to maintain +// 3. good performance +// +// Sometimes I let "good performance" creep up in priority over "easy to maintain", +// and for best performance I may provide less-easy-to-use APIs that give higher +// performance, in addition to the easy-to-use ones. Nevertheless, it's important +// to keep in mind that from the standpoint of you, a client of this library, +// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. +// +// Some secondary priorities arise directly from the first two, some of which +// provide more explicit reasons why performance can't be emphasized. +// +// - Portable ("ease of use") +// - Small source code footprint ("easy to maintain") +// - No dependencies ("ease of use") +// +// =========================================================================== +// +// I/O callbacks +// +// I/O callbacks allow you to read from arbitrary sources, like packaged +// files or some other source. Data read from callbacks are processed +// through a small internal buffer (currently 128 bytes) to try to reduce +// overhead. +// +// The three functions you must define are "read" (reads some bytes of data), +// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). +// +// =========================================================================== +// +// SIMD support +// +// The JPEG decoder will try to automatically use SIMD kernels on x86 when +// supported by the compiler. For ARM Neon support, you must explicitly +// request it. +// +// (The old do-it-yourself SIMD API is no longer supported in the current +// code.) +// +// On x86, SSE2 will automatically be used when available based on a run-time +// test; if not, the generic C versions are used as a fall-back. On ARM targets, +// the typical path is to have separate builds for NEON and non-NEON devices +// (at least this is true for iOS and Android). Therefore, the NEON support is +// toggled by a build flag: define STBI_NEON to get NEON loops. +// +// If for some reason you do not want to use any of SIMD code, or if +// you have issues compiling it, you can disable it entirely by +// defining STBI_NO_SIMD. +// +// =========================================================================== +// +// HDR image support (disable by defining STBI_NO_HDR) +// +// stb_image supports loading HDR images in general, and currently the Radiance +// .HDR file format specifically. You can still load any file through the existing +// interface; if you attempt to load an HDR file, it will be automatically remapped +// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; +// both of these constants can be reconfigured through this interface: +// +// stbi_hdr_to_ldr_gamma(2.2f); +// stbi_hdr_to_ldr_scale(1.0f); +// +// (note, do not use _inverse_ constants; stbi_image will invert them +// appropriately). +// +// Additionally, there is a new, parallel interface for loading files as +// (linear) floats to preserve the full dynamic range: +// +// float *data = stbi_loadf(filename, &x, &y, &n, 0); +// +// If you load LDR images through this interface, those images will +// be promoted to floating point values, run through the inverse of +// constants corresponding to the above: +// +// stbi_ldr_to_hdr_scale(1.0f); +// stbi_ldr_to_hdr_gamma(2.2f); +// +// Finally, given a filename (or an open file or memory block--see header +// file for details) containing image data, you can query for the "most +// appropriate" interface to use (that is, whether the image is HDR or +// not), using: +// +// stbi_is_hdr(char *filename); +// +// =========================================================================== +// +// iPhone PNG support: +// +// We optionally support converting iPhone-formatted PNGs (which store +// premultiplied BGRA) back to RGB, even though they're internally encoded +// differently. To enable this conversion, call +// stbi_convert_iphone_png_to_rgb(1). +// +// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per +// pixel to remove any premultiplied alpha *only* if the image file explicitly +// says there's premultiplied data (currently only happens in iPhone images, +// and only if iPhone convert-to-rgb processing is on). +// +// =========================================================================== +// +// ADDITIONAL CONFIGURATION +// +// - You can suppress implementation of any of the decoders to reduce +// your code footprint by #defining one or more of the following +// symbols before creating the implementation. +// +// STBI_NO_JPEG +// STBI_NO_PNG +// STBI_NO_BMP +// STBI_NO_PSD +// STBI_NO_TGA +// STBI_NO_GIF +// STBI_NO_HDR +// STBI_NO_PIC +// STBI_NO_PNM (.ppm and .pgm) +// +// - You can request *only* certain decoders and suppress all other ones +// (this will be more forward-compatible, as addition of new decoders +// doesn't require you to disable them explicitly): +// +// STBI_ONLY_JPEG +// STBI_ONLY_PNG +// STBI_ONLY_BMP +// STBI_ONLY_PSD +// STBI_ONLY_TGA +// STBI_ONLY_GIF +// STBI_ONLY_HDR +// STBI_ONLY_PIC +// STBI_ONLY_PNM (.ppm and .pgm) +// +// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still +// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB +// +// - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater +// than that size (in either width or height) without further processing. +// This is to let programs in the wild set an upper bound to prevent +// denial-of-service attacks on untrusted data, as one could generate a +// valid image of gigantic dimensions and force stb_image to allocate a +// huge block of memory and spend disproportionate time decoding it. By +// default this is set to (1 << 24), which is 16777216, but that's still +// very big. + +#ifndef STBI_NO_STDIO +#include +#endif // STBI_NO_STDIO + +#define STBI_VERSION 1 + +enum +{ + STBI_default = 0, // only used for desired_channels + + STBI_grey = 1, + STBI_grey_alpha = 2, + STBI_rgb = 3, + STBI_rgb_alpha = 4 +}; + +#include +typedef unsigned char stbi_uc; +typedef unsigned short stbi_us; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef STBIDEF +#ifdef STB_IMAGE_STATIC +#define STBIDEF static +#else +#define STBIDEF extern +#endif +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// PRIMARY API - works on images of any type +// + +// +// load image by filename, open file, or memory buffer +// + +typedef struct +{ + int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative + int (*eof) (void *user); // returns nonzero if we are at end of file/data +} stbi_io_callbacks; + +//////////////////////////////////// +// +// 8-bits-per-channel interface +// + +STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); +// for stbi_load_from_file, file pointer is left pointing immediately after image +#endif + +#ifndef STBI_NO_GIF +STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp); +#endif + +#ifdef STBI_WINDOWS_UTF8 +STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); +#endif + +//////////////////////////////////// +// +// 16-bits-per-channel interface +// + +STBIDEF stbi_us *stbi_load_16_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); +#endif + +//////////////////////////////////// +// +// float-per-channel interface +// +#ifndef STBI_NO_LINEAR + STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + + #ifndef STBI_NO_STDIO + STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); + #endif +#endif + +#ifndef STBI_NO_HDR + STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); + STBIDEF void stbi_hdr_to_ldr_scale(float scale); +#endif // STBI_NO_HDR + +#ifndef STBI_NO_LINEAR + STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); + STBIDEF void stbi_ldr_to_hdr_scale(float scale); +#endif // STBI_NO_LINEAR + +// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename); +STBIDEF int stbi_is_hdr_from_file(FILE *f); +#endif // STBI_NO_STDIO + + +// get a VERY brief reason for failure +// on most compilers (and ALL modern mainstream compilers) this is threadsafe +STBIDEF const char *stbi_failure_reason (void); + +// free the loaded image -- this is just free() +STBIDEF void stbi_image_free (void *retval_from_stbi_load); + +// get image dimensions & components without fully decoding +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len); +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user); + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); +STBIDEF int stbi_is_16_bit (char const *filename); +STBIDEF int stbi_is_16_bit_from_file(FILE *f); +#endif + + + +// for image formats that explicitly notate that they have premultiplied alpha, +// we just return the colors as stored in the file. set this flag to force +// unpremultiplication. results are undefined if the unpremultiply overflow. +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + +// indicate whether we should process iphone images back to canonical format, +// or just pass them through "as-is" +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + +// flip the image vertically, so the first pixel in the output array is the bottom left +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); + +// as above, but only applies to images loaded on the thread that calls the function +// this function is only available if your compiler supports thread-local variables; +// calling it will fail to link if your compiler doesn't +STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply); +STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert); +STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); + +// ZLIB client - used by PNG, available for other purposes + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); +STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + +STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + + +#ifdef __cplusplus +} +#endif + +// +// +//// end header file ///////////////////////////////////////////////////// +#endif // STBI_INCLUDE_STB_IMAGE_H + +#ifdef STB_IMAGE_IMPLEMENTATION + +#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ + || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ + || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ + || defined(STBI_ONLY_ZLIB) + #ifndef STBI_ONLY_JPEG + #define STBI_NO_JPEG + #endif + #ifndef STBI_ONLY_PNG + #define STBI_NO_PNG + #endif + #ifndef STBI_ONLY_BMP + #define STBI_NO_BMP + #endif + #ifndef STBI_ONLY_PSD + #define STBI_NO_PSD + #endif + #ifndef STBI_ONLY_TGA + #define STBI_NO_TGA + #endif + #ifndef STBI_ONLY_GIF + #define STBI_NO_GIF + #endif + #ifndef STBI_ONLY_HDR + #define STBI_NO_HDR + #endif + #ifndef STBI_ONLY_PIC + #define STBI_NO_PIC + #endif + #ifndef STBI_ONLY_PNM + #define STBI_NO_PNM + #endif +#endif + +#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) +#define STBI_NO_ZLIB +#endif + + +#include +#include // ptrdiff_t on osx +#include +#include +#include + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) +#include // ldexp, pow +#endif + +#ifndef STBI_NO_STDIO +#include +#endif + +#ifndef STBI_ASSERT +#include +#define STBI_ASSERT(x) assert(x) +#endif + +#ifdef __cplusplus +#define STBI_EXTERN extern "C" +#else +#define STBI_EXTERN extern +#endif + + +#ifndef _MSC_VER + #ifdef __cplusplus + #define stbi_inline inline + #else + #define stbi_inline + #endif +#else + #define stbi_inline __forceinline +#endif + +#ifndef STBI_NO_THREAD_LOCALS + #if defined(__cplusplus) && __cplusplus >= 201103L + #define STBI_THREAD_LOCAL thread_local + #elif defined(__GNUC__) && __GNUC__ < 5 + #define STBI_THREAD_LOCAL __thread + #elif defined(_MSC_VER) + #define STBI_THREAD_LOCAL __declspec(thread) + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) + #define STBI_THREAD_LOCAL _Thread_local + #endif + + #ifndef STBI_THREAD_LOCAL + #if defined(__GNUC__) + #define STBI_THREAD_LOCAL __thread + #endif + #endif +#endif + +#ifdef _MSC_VER +typedef unsigned short stbi__uint16; +typedef signed short stbi__int16; +typedef unsigned int stbi__uint32; +typedef signed int stbi__int32; +#else +#include +typedef uint16_t stbi__uint16; +typedef int16_t stbi__int16; +typedef uint32_t stbi__uint32; +typedef int32_t stbi__int32; +#endif + +// should produce compiler error if size is wrong +typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; + +#ifdef _MSC_VER +#define STBI_NOTUSED(v) (void)(v) +#else +#define STBI_NOTUSED(v) (void)sizeof(v) +#endif + +#ifdef _MSC_VER +#define STBI_HAS_LROTL +#endif + +#ifdef STBI_HAS_LROTL + #define stbi_lrot(x,y) _lrotl(x,y) +#else + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31))) +#endif + +#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) +// ok +#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." +#endif + +#ifndef STBI_MALLOC +#define STBI_MALLOC(sz) malloc(sz) +#define STBI_REALLOC(p,newsz) realloc(p,newsz) +#define STBI_FREE(p) free(p) +#endif + +#ifndef STBI_REALLOC_SIZED +#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) +#endif + +// x86/x64 detection +#if defined(__x86_64__) || defined(_M_X64) +#define STBI__X64_TARGET +#elif defined(__i386) || defined(_M_IX86) +#define STBI__X86_TARGET +#endif + +#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) +// gcc doesn't support sse2 intrinsics unless you compile with -msse2, +// which in turn means it gets to use SSE2 everywhere. This is unfortunate, +// but previous attempts to provide the SSE2 functions with runtime +// detection caused numerous issues. The way architecture extensions are +// exposed in GCC/Clang is, sadly, not really suited for one-file libs. +// New behavior: if compiled with -msse2, we use SSE2 without any +// detection; if not, we don't use it at all. +#define STBI_NO_SIMD +#endif + +#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) +// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET +// +// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the +// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. +// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not +// simultaneously enabling "-mstackrealign". +// +// See https://github.com/nothings/stb/issues/81 for more information. +// +// So default to no SSE2 on 32-bit MinGW. If you've read this far and added +// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. +#define STBI_NO_SIMD +#endif + +#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) +#define STBI_SSE2 +#include + +#ifdef _MSC_VER + +#if _MSC_VER >= 1400 // not VC6 +#include // __cpuid +static int stbi__cpuid3(void) +{ + int info[4]; + __cpuid(info,1); + return info[3]; +} +#else +static int stbi__cpuid3(void) +{ + int res; + __asm { + mov eax,1 + cpuid + mov res,edx + } + return res; +} +#endif + +#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name + +#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) +static int stbi__sse2_available(void) +{ + int info3 = stbi__cpuid3(); + return ((info3 >> 26) & 1) != 0; +} +#endif + +#else // assume GCC-style if not VC++ +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) + +#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) +static int stbi__sse2_available(void) +{ + // If we're even attempting to compile this on GCC/Clang, that means + // -msse2 is on, which means the compiler is allowed to use SSE2 + // instructions at will, and so are we. + return 1; +} +#endif + +#endif +#endif + +// ARM NEON +#if defined(STBI_NO_SIMD) && defined(STBI_NEON) +#undef STBI_NEON +#endif + +#ifdef STBI_NEON +#include +#ifdef _MSC_VER +#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name +#else +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) +#endif +#endif + +#ifndef STBI_SIMD_ALIGN +#define STBI_SIMD_ALIGN(type, name) type name +#endif + +#ifndef STBI_MAX_DIMENSIONS +#define STBI_MAX_DIMENSIONS (1 << 24) +#endif + +/////////////////////////////////////////////// +// +// stbi__context struct and start_xxx functions + +// stbi__context structure is our basic context used by all images, so it +// contains all the IO context, plus some basic image information +typedef struct +{ + stbi__uint32 img_x, img_y; + int img_n, img_out_n; + + stbi_io_callbacks io; + void *io_user_data; + + int read_from_callbacks; + int buflen; + stbi_uc buffer_start[128]; + int callback_already_read; + + stbi_uc *img_buffer, *img_buffer_end; + stbi_uc *img_buffer_original, *img_buffer_original_end; +} stbi__context; + + +static void stbi__refill_buffer(stbi__context *s); + +// initialize a memory-decode context +static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) +{ + s->io.read = NULL; + s->read_from_callbacks = 0; + s->callback_already_read = 0; + s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; + s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; +} + +// initialize a callback-based context +static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user) +{ + s->io = *c; + s->io_user_data = user; + s->buflen = sizeof(s->buffer_start); + s->read_from_callbacks = 1; + s->callback_already_read = 0; + s->img_buffer = s->img_buffer_original = s->buffer_start; + stbi__refill_buffer(s); + s->img_buffer_original_end = s->img_buffer_end; +} + +#ifndef STBI_NO_STDIO + +static int stbi__stdio_read(void *user, char *data, int size) +{ + return (int) fread(data,1,size,(FILE*) user); +} + +static void stbi__stdio_skip(void *user, int n) +{ + int ch; + fseek((FILE*) user, n, SEEK_CUR); + ch = fgetc((FILE*) user); /* have to read a byte to reset feof()'s flag */ + if (ch != EOF) { + ungetc(ch, (FILE *) user); /* push byte back onto stream if valid. */ + } +} + +static int stbi__stdio_eof(void *user) +{ + return feof((FILE*) user) || ferror((FILE *) user); +} + +static stbi_io_callbacks stbi__stdio_callbacks = +{ + stbi__stdio_read, + stbi__stdio_skip, + stbi__stdio_eof, +}; + +static void stbi__start_file(stbi__context *s, FILE *f) +{ + stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); +} + +//static void stop_file(stbi__context *s) { } + +#endif // !STBI_NO_STDIO + +static void stbi__rewind(stbi__context *s) +{ + // conceptually rewind SHOULD rewind to the beginning of the stream, + // but we just rewind to the beginning of the initial buffer, because + // we only use it after doing 'test', which only ever looks at at most 92 bytes + s->img_buffer = s->img_buffer_original; + s->img_buffer_end = s->img_buffer_original_end; +} + +enum +{ + STBI_ORDER_RGB, + STBI_ORDER_BGR +}; + +typedef struct +{ + int bits_per_channel; + int num_channels; + int channel_order; +} stbi__result_info; + +#ifndef STBI_NO_JPEG +static int stbi__jpeg_test(stbi__context *s); +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNG +static int stbi__png_test(stbi__context *s); +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__png_is16(stbi__context *s); +#endif + +#ifndef STBI_NO_BMP +static int stbi__bmp_test(stbi__context *s); +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_TGA +static int stbi__tga_test(stbi__context *s); +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s); +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc); +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__psd_is16(stbi__context *s); +#endif + +#ifndef STBI_NO_HDR +static int stbi__hdr_test(stbi__context *s); +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_test(stbi__context *s); +static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_GIF +static int stbi__gif_test(stbi__context *s); +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp); +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNM +static int stbi__pnm_test(stbi__context *s); +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__pnm_is16(stbi__context *s); +#endif + +static +#ifdef STBI_THREAD_LOCAL +STBI_THREAD_LOCAL +#endif +const char *stbi__g_failure_reason; + +STBIDEF const char *stbi_failure_reason(void) +{ + return stbi__g_failure_reason; +} + +#ifndef STBI_NO_FAILURE_STRINGS +static int stbi__err(const char *str) +{ + stbi__g_failure_reason = str; + return 0; +} +#endif + +static void *stbi__malloc(size_t size) +{ + return STBI_MALLOC(size); +} + +// stb_image uses ints pervasively, including for offset calculations. +// therefore the largest decoded image size we can support with the +// current code, even on 64-bit targets, is INT_MAX. this is not a +// significant limitation for the intended use case. +// +// we do, however, need to make sure our size calculations don't +// overflow. hence a few helper functions for size calculations that +// multiply integers together, making sure that they're non-negative +// and no overflow occurs. + +// return 1 if the sum is valid, 0 on overflow. +// negative terms are considered invalid. +static int stbi__addsizes_valid(int a, int b) +{ + if (b < 0) return 0; + // now 0 <= b <= INT_MAX, hence also + // 0 <= INT_MAX - b <= INTMAX. + // And "a + b <= INT_MAX" (which might overflow) is the + // same as a <= INT_MAX - b (no overflow) + return a <= INT_MAX - b; +} + +// returns 1 if the product is valid, 0 on overflow. +// negative factors are considered invalid. +static int stbi__mul2sizes_valid(int a, int b) +{ + if (a < 0 || b < 0) return 0; + if (b == 0) return 1; // mul-by-0 is always safe + // portable way to check for no overflows in a*b + return a <= INT_MAX/b; +} + +#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) +// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow +static int stbi__mad2sizes_valid(int a, int b, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add); +} +#endif + +// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow +static int stbi__mad3sizes_valid(int a, int b, int c, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__addsizes_valid(a*b*c, add); +} + +// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) +static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add); +} +#endif + +#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) +// mallocs with size overflow checking +static void *stbi__malloc_mad2(int a, int b, int add) +{ + if (!stbi__mad2sizes_valid(a, b, add)) return NULL; + return stbi__malloc(a*b + add); +} +#endif + +static void *stbi__malloc_mad3(int a, int b, int c, int add) +{ + if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; + return stbi__malloc(a*b*c + add); +} + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) +static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) +{ + if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; + return stbi__malloc(a*b*c*d + add); +} +#endif + +// stbi__err - error +// stbi__errpf - error returning pointer to float +// stbi__errpuc - error returning pointer to unsigned char + +#ifdef STBI_NO_FAILURE_STRINGS + #define stbi__err(x,y) 0 +#elif defined(STBI_FAILURE_USERMSG) + #define stbi__err(x,y) stbi__err(y) +#else + #define stbi__err(x,y) stbi__err(x) +#endif + +#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) +#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) + +STBIDEF void stbi_image_free(void *retval_from_stbi_load) +{ + STBI_FREE(retval_from_stbi_load); +} + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); +#endif + +#ifndef STBI_NO_HDR +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); +#endif + +static int stbi__vertically_flip_on_load_global = 0; + +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load_global = flag_true_if_should_flip; +} + +#ifndef STBI_THREAD_LOCAL +#define stbi__vertically_flip_on_load stbi__vertically_flip_on_load_global +#else +static STBI_THREAD_LOCAL int stbi__vertically_flip_on_load_local, stbi__vertically_flip_on_load_set; + +STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load_local = flag_true_if_should_flip; + stbi__vertically_flip_on_load_set = 1; +} + +#define stbi__vertically_flip_on_load (stbi__vertically_flip_on_load_set \ + ? stbi__vertically_flip_on_load_local \ + : stbi__vertically_flip_on_load_global) +#endif // STBI_THREAD_LOCAL + +static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) +{ + memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields + ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed + ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order + ri->num_channels = 0; + + // test the formats with a very explicit header first (at least a FOURCC + // or distinctive magic number first) + #ifndef STBI_NO_PNG + if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_BMP + if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_GIF + if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_PSD + if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc); + #else + STBI_NOTUSED(bpc); + #endif + #ifndef STBI_NO_PIC + if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri); + #endif + + // then the formats that can end up attempting to load with just 1 or 2 + // bytes matching expectations; these are prone to false positives, so + // try them later + #ifndef STBI_NO_JPEG + if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_PNM + if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri); + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri); + return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } + #endif + + #ifndef STBI_NO_TGA + // test tga last because it's a crappy test! + if (stbi__tga_test(s)) + return stbi__tga_load(s,x,y,comp,req_comp, ri); + #endif + + return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); +} + +static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi_uc *reduced; + + reduced = (stbi_uc *) stbi__malloc(img_len); + if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) + reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling + + STBI_FREE(orig); + return reduced; +} + +static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi__uint16 *enlarged; + + enlarged = (stbi__uint16 *) stbi__malloc(img_len*2); + if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) + enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff + + STBI_FREE(orig); + return enlarged; +} + +static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel) +{ + int row; + size_t bytes_per_row = (size_t)w * bytes_per_pixel; + stbi_uc temp[2048]; + stbi_uc *bytes = (stbi_uc *)image; + + for (row = 0; row < (h>>1); row++) { + stbi_uc *row0 = bytes + row*bytes_per_row; + stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row; + // swap row0 with row1 + size_t bytes_left = bytes_per_row; + while (bytes_left) { + size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); + memcpy(temp, row0, bytes_copy); + memcpy(row0, row1, bytes_copy); + memcpy(row1, temp, bytes_copy); + row0 += bytes_copy; + row1 += bytes_copy; + bytes_left -= bytes_copy; + } + } +} + +#ifndef STBI_NO_GIF +static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel) +{ + int slice; + int slice_size = w * h * bytes_per_pixel; + + stbi_uc *bytes = (stbi_uc *)image; + for (slice = 0; slice < z; ++slice) { + stbi__vertical_flip(bytes, w, h, bytes_per_pixel); + bytes += slice_size; + } +} +#endif + +static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); + + if (result == NULL) + return NULL; + + // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. + STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); + + if (ri.bits_per_channel != 8) { + result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 8; + } + + // @TODO: move stbi__convert_format to here + + if (stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); + } + + return (unsigned char *) result; +} + +static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16); + + if (result == NULL) + return NULL; + + // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. + STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); + + if (ri.bits_per_channel != 16) { + result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 16; + } + + // @TODO: move stbi__convert_format16 to here + // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision + + if (stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16)); + } + + return (stbi__uint16 *) result; +} + +#if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR) +static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) +{ + if (stbi__vertically_flip_on_load && result != NULL) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(float)); + } +} +#endif + +#ifndef STBI_NO_STDIO + +#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) +STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); +STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); +#endif + +#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) +STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) +{ + return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); +} +#endif + +static FILE *stbi__fopen(char const *filename, char const *mode) +{ + FILE *f; +#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) + wchar_t wMode[64]; + wchar_t wFilename[1024]; + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename))) + return 0; + + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode))) + return 0; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != _wfopen_s(&f, wFilename, wMode)) + f = 0; +#else + f = _wfopen(wFilename, wMode); +#endif + +#elif defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != fopen_s(&f, filename, mode)) + f=0; +#else + f = fopen(filename, mode); +#endif + return f; +} + + +STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + unsigned char *result; + if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__uint16 *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + stbi__uint16 *result; + if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file_16(f,x,y,comp,req_comp); + fclose(f); + return result; +} + + +#endif //!STBI_NO_STDIO + +STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); +} + +STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); + return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); +} + +STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); +} + +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_GIF +STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_mem(&s,buffer,len); + + result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp); + if (stbi__vertically_flip_on_load) { + stbi__vertical_flip_slices( result, *x, *y, *z, *comp ); + } + + return result; +} +#endif + +#ifndef STBI_NO_LINEAR +static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *data; + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + stbi__result_info ri; + float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri); + if (hdr_data) + stbi__float_postprocess(hdr_data,x,y,comp,req_comp); + return hdr_data; + } + #endif + data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); + if (data) + return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); +} + +STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_STDIO +STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + float *result; + FILE *f = stbi__fopen(filename, "rb"); + if (!f) return stbi__errpf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_file(&s,f); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} +#endif // !STBI_NO_STDIO + +#endif // !STBI_NO_LINEAR + +// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is +// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always +// reports false! + +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(buffer); + STBI_NOTUSED(len); + return 0; + #endif +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result=0; + if (f) { + result = stbi_is_hdr_from_file(f); + fclose(f); + } + return result; +} + +STBIDEF int stbi_is_hdr_from_file(FILE *f) +{ + #ifndef STBI_NO_HDR + long pos = ftell(f); + int res; + stbi__context s; + stbi__start_file(&s,f); + res = stbi__hdr_test(&s); + fseek(f, pos, SEEK_SET); + return res; + #else + STBI_NOTUSED(f); + return 0; + #endif +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(clbk); + STBI_NOTUSED(user); + return 0; + #endif +} + +#ifndef STBI_NO_LINEAR +static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; + +STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } +STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } +#endif + +static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; + +STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } +STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } + + +////////////////////////////////////////////////////////////////////////////// +// +// Common code used by all image loaders +// + +enum +{ + STBI__SCAN_load=0, + STBI__SCAN_type, + STBI__SCAN_header +}; + +static void stbi__refill_buffer(stbi__context *s) +{ + int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); + s->callback_already_read += (int) (s->img_buffer - s->img_buffer_original); + if (n == 0) { + // at end of file, treat same as if from memory, but need to handle case + // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file + s->read_from_callbacks = 0; + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start+1; + *s->img_buffer = 0; + } else { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } +} + +stbi_inline static stbi_uc stbi__get8(stbi__context *s) +{ + if (s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; + if (s->read_from_callbacks) { + stbi__refill_buffer(s); + return *s->img_buffer++; + } + return 0; +} + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +stbi_inline static int stbi__at_eof(stbi__context *s) +{ + if (s->io.read) { + if (!(s->io.eof)(s->io_user_data)) return 0; + // if feof() is true, check if buffer = end + // special case: we've only got the special 0 character at the end + if (s->read_from_callbacks == 0) return 1; + } + + return s->img_buffer >= s->img_buffer_end; +} +#endif + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) +// nothing +#else +static void stbi__skip(stbi__context *s, int n) +{ + if (n == 0) return; // already there! + if (n < 0) { + s->img_buffer = s->img_buffer_end; + return; + } + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + s->img_buffer = s->img_buffer_end; + (s->io.skip)(s->io_user_data, n - blen); + return; + } + } + s->img_buffer += n; +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) +// nothing +#else +static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) +{ + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + int res, count; + + memcpy(buffer, s->img_buffer, blen); + + count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); + res = (count == (n-blen)); + s->img_buffer = s->img_buffer_end; + return res; + } + } + + if (s->img_buffer+n <= s->img_buffer_end) { + memcpy(buffer, s->img_buffer, n); + s->img_buffer += n; + return 1; + } else + return 0; +} +#endif + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) +// nothing +#else +static int stbi__get16be(stbi__context *s) +{ + int z = stbi__get8(s); + return (z << 8) + stbi__get8(s); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) +// nothing +#else +static stbi__uint32 stbi__get32be(stbi__context *s) +{ + stbi__uint32 z = stbi__get16be(s); + return (z << 16) + stbi__get16be(s); +} +#endif + +#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) +// nothing +#else +static int stbi__get16le(stbi__context *s) +{ + int z = stbi__get8(s); + return z + (stbi__get8(s) << 8); +} +#endif + +#ifndef STBI_NO_BMP +static stbi__uint32 stbi__get32le(stbi__context *s) +{ + stbi__uint32 z = stbi__get16le(s); + z += (stbi__uint32)stbi__get16le(s) << 16; + return z; +} +#endif + +#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +////////////////////////////////////////////////////////////////////////////// +// +// generic converter from built-in img_n to req_comp +// individual types do this automatically as much as possible (e.g. jpeg +// does all cases internally since it needs to colorspace convert anyway, +// and it never has alpha, so very few cases ). png can automatically +// interleave an alpha=255 channel, but falls back to this for other cases +// +// assume data buffer is malloced, so malloc a new one and free that one +// only failure mode is malloc failing + +static stbi_uc stbi__compute_y(int r, int g, int b) +{ + return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + unsigned char *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0); + if (good == NULL) { + STBI_FREE(data); + return stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + unsigned char *src = data + j * x * img_n ; + unsigned char *dest = good + j * x * req_comp; + + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; + default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); + } + #undef STBI__CASE + } + + STBI_FREE(data); + return good; +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) +// nothing +#else +static stbi__uint16 stbi__compute_y_16(int r, int g, int b) +{ + return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) +// nothing +#else +static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + stbi__uint16 *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2); + if (good == NULL) { + STBI_FREE(data); + return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + stbi__uint16 *src = data + j * x * img_n ; + stbi__uint16 *dest = good + j * x * req_comp; + + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; + default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*) stbi__errpuc("unsupported", "Unsupported format conversion"); + } + #undef STBI__CASE + } + + STBI_FREE(data); + return good; +} +#endif + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) +{ + int i,k,n; + float *output; + if (!data) return NULL; + output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0); + if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); + } + } + if (n < comp) { + for (i=0; i < x*y; ++i) { + output[i*comp + n] = data[i*comp + n]/255.0f; + } + } + STBI_FREE(data); + return output; +} +#endif + +#ifndef STBI_NO_HDR +#define stbi__float2int(x) ((int) (x)) +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) +{ + int i,k,n; + stbi_uc *output; + if (!data) return NULL; + output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0); + if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + if (k < comp) { + float z = data[i*comp+k] * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + } + STBI_FREE(data); + return output; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// "baseline" JPEG/JFIF decoder +// +// simple implementation +// - doesn't support delayed output of y-dimension +// - simple interface (only one output format: 8-bit interleaved RGB) +// - doesn't try to recover corrupt jpegs +// - doesn't allow partial loading, loading multiple at once +// - still fast on x86 (copying globals into locals doesn't help x86) +// - allocates lots of intermediate memory (full size of all components) +// - non-interleaved case requires this anyway +// - allows good upsampling (see next) +// high-quality +// - upsampled channels are bilinearly interpolated, even across blocks +// - quality integer IDCT derived from IJG's 'slow' +// performance +// - fast huffman; reasonable integer IDCT +// - some SIMD kernels for common paths on targets with SSE2/NEON +// - uses a lot of intermediate memory, could cache poorly + +#ifndef STBI_NO_JPEG + +// huffman decoding acceleration +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache + +typedef struct +{ + stbi_uc fast[1 << FAST_BITS]; + // weirdly, repacking this into AoS is a 10% speed loss, instead of a win + stbi__uint16 code[256]; + stbi_uc values[256]; + stbi_uc size[257]; + unsigned int maxcode[18]; + int delta[17]; // old 'firstsymbol' - old 'firstcode' +} stbi__huffman; + +typedef struct +{ + stbi__context *s; + stbi__huffman huff_dc[4]; + stbi__huffman huff_ac[4]; + stbi__uint16 dequant[4][64]; + stbi__int16 fast_ac[4][1 << FAST_BITS]; + +// sizes for components, interleaved MCUs + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; + +// definition of jpeg image component + struct + { + int id; + int h,v; + int tq; + int hd,ha; + int dc_pred; + + int x,y,w2,h2; + stbi_uc *data; + void *raw_data, *raw_coeff; + stbi_uc *linebuf; + short *coeff; // progressive only + int coeff_w, coeff_h; // number of 8x8 coefficient blocks + } img_comp[4]; + + stbi__uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop + + int progressive; + int spec_start; + int spec_end; + int succ_high; + int succ_low; + int eob_run; + int jfif; + int app14_color_transform; // Adobe APP14 tag + int rgb; + + int scan_n, order[4]; + int restart_interval, todo; + +// kernels + void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]); + void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step); + stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs); +} stbi__jpeg; + +static int stbi__build_huffman(stbi__huffman *h, int *count) +{ + int i,j,k=0; + unsigned int code; + // build size list for each symbol (from JPEG spec) + for (i=0; i < 16; ++i) + for (j=0; j < count[i]; ++j) + h->size[k++] = (stbi_uc) (i+1); + h->size[k] = 0; + + // compute actual symbols (from jpeg spec) + code = 0; + k = 0; + for(j=1; j <= 16; ++j) { + // compute delta to add to code to compute symbol id + h->delta[j] = k - code; + if (h->size[k] == j) { + while (h->size[k] == j) + h->code[k++] = (stbi__uint16) (code++); + if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG"); + } + // compute largest code + 1 for this size, preshifted as needed later + h->maxcode[j] = code << (16-j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; + + // build non-spec acceleration table; 255 is flag for not-accelerated + memset(h->fast, 255, 1 << FAST_BITS); + for (i=0; i < k; ++i) { + int s = h->size[i]; + if (s <= FAST_BITS) { + int c = h->code[i] << (FAST_BITS-s); + int m = 1 << (FAST_BITS-s); + for (j=0; j < m; ++j) { + h->fast[c+j] = (stbi_uc) i; + } + } + } + return 1; +} + +// build a table that decodes both magnitude and value of small ACs in +// one go. +static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) +{ + int i; + for (i=0; i < (1 << FAST_BITS); ++i) { + stbi_uc fast = h->fast[i]; + fast_ac[i] = 0; + if (fast < 255) { + int rs = h->values[fast]; + int run = (rs >> 4) & 15; + int magbits = rs & 15; + int len = h->size[fast]; + + if (magbits && len + magbits <= FAST_BITS) { + // magnitude code followed by receive_extend code + int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); + int m = 1 << (magbits - 1); + if (k < m) k += (~0U << magbits) + 1; + // if the result is small enough, we can fit it in fast_ac table + if (k >= -128 && k <= 127) + fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits)); + } + } + } +} + +static void stbi__grow_buffer_unsafe(stbi__jpeg *j) +{ + do { + unsigned int b = j->nomore ? 0 : stbi__get8(j->s); + if (b == 0xff) { + int c = stbi__get8(j->s); + while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes + if (c != 0) { + j->marker = (unsigned char) c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while (j->code_bits <= 24); +} + +// (1 << n) - 1 +static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; + +// decode a jpeg huffman value from the bitstream +stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) +{ + unsigned int temp; + int c,k; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + // look at the top FAST_BITS and determine what symbol ID it is, + // if the code is <= FAST_BITS + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + k = h->fast[c]; + if (k < 255) { + int s = h->size[k]; + if (s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } + + // naive test is to shift the code_buffer down so k bits are + // valid, then test against maxcode. To speed this up, we've + // preshifted maxcode left so that it has (16-k) 0s at the + // end; in other words, regardless of the number of bits, it + // wants to be compared against something shifted to have 16; + // that way we don't need to shift inside the loop. + temp = j->code_buffer >> 16; + for (k=FAST_BITS+1 ; ; ++k) + if (temp < h->maxcode[k]) + break; + if (k == 17) { + // error! code not found + j->code_bits -= 16; + return -1; + } + + if (k > j->code_bits) + return -1; + + // convert the huffman code to the symbol id + c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; + STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); + + // convert the id to a symbol + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; +} + +// bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); + + sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k + (stbi__jbias[n] & (sgn - 1)); +} + +// get some unsigned bits +stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) +{ + unsigned int k; + if (j->code_bits < n) stbi__grow_buffer_unsafe(j); + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k; +} + +stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) +{ + unsigned int k; + if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); + k = j->code_buffer; + j->code_buffer <<= 1; + --j->code_bits; + return k & 0x80000000; +} + +// given a value that's at position X in the zigzag stream, +// where does it appear in the 8x8 matrix coded as row-major? +static const stbi_uc stbi__jpeg_dezigzag[64+15] = +{ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63 +}; + +// decode one 64-entry block-- +static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant) +{ + int diff,dc,k; + int t; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + t = stbi__jpeg_huff_decode(j, hdc); + if (t < 0 || t > 15) return stbi__err("bad huffman code","Corrupt JPEG"); + + // 0 all the ac values now so we can do it 32-bits at a time + memset(data,0,64*sizeof(data[0])); + + diff = t ? stbi__extend_receive(j, t) : 0; + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc * dequant[0]); + + // decode AC components, see JPEG spec + k = 1; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) * dequant[zig]); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (rs != 0xf0) break; // end block + k += 16; + } else { + k += r; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]); + } + } + } while (k < 64); + return 1; +} + +static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) +{ + int diff,dc; + int t; + if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + if (j->succ_high == 0) { + // first scan for DC coefficient, must be first + memset(data,0,64*sizeof(data[0])); // 0 all the ac values now + t = stbi__jpeg_huff_decode(j, hdc); + if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + diff = t ? stbi__extend_receive(j, t) : 0; + + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc * (1 << j->succ_low)); + } else { + // refinement scan for DC coefficient + if (stbi__jpeg_get_bit(j)) + data[0] += (short) (1 << j->succ_low); + } + return 1; +} + +// @OPTIMIZE: store non-zigzagged during the decode passes, +// and only de-zigzag when dequantizing +static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) +{ + int k; + if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->succ_high == 0) { + int shift = j->succ_low; + + if (j->eob_run) { + --j->eob_run; + return 1; + } + + k = j->spec_start; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) * (1 << shift)); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r); + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + --j->eob_run; + break; + } + k += 16; + } else { + k += r; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) * (1 << shift)); + } + } + } while (k <= j->spec_end); + } else { + // refinement scan for these AC coefficients + + short bit = (short) (1 << j->succ_low); + + if (j->eob_run) { + --j->eob_run; + for (k = j->spec_start; k <= j->spec_end; ++k) { + short *p = &data[stbi__jpeg_dezigzag[k]]; + if (*p != 0) + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } + } else { + k = j->spec_start; + do { + int r,s; + int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r) - 1; + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + r = 64; // force end of block + } else { + // r=15 s=0 should write 16 0s, so we just do + // a run of 15 0s and then write s (which is 0), + // so we don't have to do anything special here + } + } else { + if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); + // sign bit + if (stbi__jpeg_get_bit(j)) + s = bit; + else + s = -bit; + } + + // advance by r + while (k <= j->spec_end) { + short *p = &data[stbi__jpeg_dezigzag[k++]]; + if (*p != 0) { + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } else { + if (r == 0) { + *p = (short) s; + break; + } + --r; + } + } + } while (k <= j->spec_end); + } + } + return 1; +} + +// take a -128..127 value and stbi__clamp it and convert to 0..255 +stbi_inline static stbi_uc stbi__clamp(int x) +{ + // trick to use a single test to catch both cases + if ((unsigned int) x > 255) { + if (x < 0) return 0; + if (x > 255) return 255; + } + return (stbi_uc) x; +} + +#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) +#define stbi__fsh(x) ((x) * 4096) + +// derived from jidctint -- DCT_ISLOW +#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ + int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2+p3) * stbi__f2f(0.5411961f); \ + t2 = p1 + p3*stbi__f2f(-1.847759065f); \ + t3 = p1 + p2*stbi__f2f( 0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = stbi__fsh(p2+p3); \ + t1 = stbi__fsh(p2-p3); \ + x0 = t0+t3; \ + x3 = t0-t3; \ + x1 = t1+t2; \ + x2 = t1-t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0+t2; \ + p4 = t1+t3; \ + p1 = t0+t3; \ + p2 = t1+t2; \ + p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ + t0 = t0*stbi__f2f( 0.298631336f); \ + t1 = t1*stbi__f2f( 2.053119869f); \ + t2 = t2*stbi__f2f( 3.072711026f); \ + t3 = t3*stbi__f2f( 1.501321110f); \ + p1 = p5 + p1*stbi__f2f(-0.899976223f); \ + p2 = p5 + p2*stbi__f2f(-2.562915447f); \ + p3 = p3*stbi__f2f(-1.961570560f); \ + p4 = p4*stbi__f2f(-0.390180644f); \ + t3 += p1+p4; \ + t2 += p2+p3; \ + t1 += p2+p4; \ + t0 += p1+p3; + +static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) +{ + int i,val[64],*v=val; + stbi_uc *o; + short *d = data; + + // columns + for (i=0; i < 8; ++i,++d, ++v) { + // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing + if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 + && d[40]==0 && d[48]==0 && d[56]==0) { + // no shortcut 0 seconds + // (1|2|3|4|5|6|7)==0 0 seconds + // all separate -0.047 seconds + // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds + int dcterm = d[0]*4; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } else { + STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) + // constants scaled things up by 1<<12; let's bring them back + // down, but keep 2 extra bits of precision + x0 += 512; x1 += 512; x2 += 512; x3 += 512; + v[ 0] = (x0+t3) >> 10; + v[56] = (x0-t3) >> 10; + v[ 8] = (x1+t2) >> 10; + v[48] = (x1-t2) >> 10; + v[16] = (x2+t1) >> 10; + v[40] = (x2-t1) >> 10; + v[24] = (x3+t0) >> 10; + v[32] = (x3-t0) >> 10; + } + } + + for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { + // no fast case since the first 1D IDCT spread components out + STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) + // constants scaled things up by 1<<12, plus we had 1<<2 from first + // loop, plus horizontal and vertical each scale by sqrt(8) so together + // we've got an extra 1<<3, so 1<<17 total we need to remove. + // so we want to round that, which means adding 0.5 * 1<<17, + // aka 65536. Also, we'll end up with -128 to 127 that we want + // to encode as 0..255 by adding 128, so we'll add that before the shift + x0 += 65536 + (128<<17); + x1 += 65536 + (128<<17); + x2 += 65536 + (128<<17); + x3 += 65536 + (128<<17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = stbi__clamp((x0+t3) >> 17); + o[7] = stbi__clamp((x0-t3) >> 17); + o[1] = stbi__clamp((x1+t2) >> 17); + o[6] = stbi__clamp((x1-t2) >> 17); + o[2] = stbi__clamp((x2+t1) >> 17); + o[5] = stbi__clamp((x2-t1) >> 17); + o[3] = stbi__clamp((x3+t0) >> 17); + o[4] = stbi__clamp((x3-t0) >> 17); + } +} + +#ifdef STBI_SSE2 +// sse2 integer IDCT. not the fastest possible implementation but it +// produces bit-identical results to the generic C version so it's +// fully "transparent". +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + // This is constructed to match our regular (generic) integer IDCT exactly. + __m128i row0, row1, row2, row3, row4, row5, row6, row7; + __m128i tmp; + + // dot product constant: even elems=x, odd elems=y + #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) + + // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) + // out(1) = c1[even]*x + c1[odd]*y + #define dct_rot(out0,out1, x,y,c0,c1) \ + __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ + __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ + __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ + __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ + __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ + __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) + + // out = in << 12 (in 16-bit, out 32-bit) + #define dct_widen(out, in) \ + __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ + __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) + + // wide add + #define dct_wadd(out, a, b) \ + __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_add_epi32(a##_h, b##_h) + + // wide sub + #define dct_wsub(out, a, b) \ + __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) + + // butterfly a/b, add bias, then shift by "s" and pack + #define dct_bfly32o(out0, out1, a,b,bias,s) \ + { \ + __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ + __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ + dct_wadd(sum, abiased, b); \ + dct_wsub(dif, abiased, b); \ + out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ + out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ + } + + // 8-bit interleave step (for transposes) + #define dct_interleave8(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi8(a, b); \ + b = _mm_unpackhi_epi8(tmp, b) + + // 16-bit interleave step (for transposes) + #define dct_interleave16(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi16(a, b); \ + b = _mm_unpackhi_epi16(tmp, b) + + #define dct_pass(bias,shift) \ + { \ + /* even part */ \ + dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ + __m128i sum04 = _mm_add_epi16(row0, row4); \ + __m128i dif04 = _mm_sub_epi16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ + dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ + __m128i sum17 = _mm_add_epi16(row1, row7); \ + __m128i sum35 = _mm_add_epi16(row3, row5); \ + dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ + dct_wadd(x4, y0o, y4o); \ + dct_wadd(x5, y1o, y5o); \ + dct_wadd(x6, y2o, y5o); \ + dct_wadd(x7, y3o, y4o); \ + dct_bfly32o(row0,row7, x0,x7,bias,shift); \ + dct_bfly32o(row1,row6, x1,x6,bias,shift); \ + dct_bfly32o(row2,row5, x2,x5,bias,shift); \ + dct_bfly32o(row3,row4, x3,x4,bias,shift); \ + } + + __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); + __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f)); + __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); + __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); + __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f)); + __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f)); + __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f)); + __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f)); + + // rounding biases in column/row passes, see stbi__idct_block for explanation. + __m128i bias_0 = _mm_set1_epi32(512); + __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); + + // load + row0 = _mm_load_si128((const __m128i *) (data + 0*8)); + row1 = _mm_load_si128((const __m128i *) (data + 1*8)); + row2 = _mm_load_si128((const __m128i *) (data + 2*8)); + row3 = _mm_load_si128((const __m128i *) (data + 3*8)); + row4 = _mm_load_si128((const __m128i *) (data + 4*8)); + row5 = _mm_load_si128((const __m128i *) (data + 5*8)); + row6 = _mm_load_si128((const __m128i *) (data + 6*8)); + row7 = _mm_load_si128((const __m128i *) (data + 7*8)); + + // column pass + dct_pass(bias_0, 10); + + { + // 16bit 8x8 transpose pass 1 + dct_interleave16(row0, row4); + dct_interleave16(row1, row5); + dct_interleave16(row2, row6); + dct_interleave16(row3, row7); + + // transpose pass 2 + dct_interleave16(row0, row2); + dct_interleave16(row1, row3); + dct_interleave16(row4, row6); + dct_interleave16(row5, row7); + + // transpose pass 3 + dct_interleave16(row0, row1); + dct_interleave16(row2, row3); + dct_interleave16(row4, row5); + dct_interleave16(row6, row7); + } + + // row pass + dct_pass(bias_1, 17); + + { + // pack + __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 + __m128i p1 = _mm_packus_epi16(row2, row3); + __m128i p2 = _mm_packus_epi16(row4, row5); + __m128i p3 = _mm_packus_epi16(row6, row7); + + // 8bit 8x8 transpose pass 1 + dct_interleave8(p0, p2); // a0e0a1e1... + dct_interleave8(p1, p3); // c0g0c1g1... + + // transpose pass 2 + dct_interleave8(p0, p1); // a0c0e0g0... + dct_interleave8(p2, p3); // b0d0f0h0... + + // transpose pass 3 + dct_interleave8(p0, p2); // a0b0c0d0... + dct_interleave8(p1, p3); // a4b4c4d4... + + // store + _mm_storel_epi64((__m128i *) out, p0); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p2); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p1); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p3); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); + } + +#undef dct_const +#undef dct_rot +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_interleave8 +#undef dct_interleave16 +#undef dct_pass +} + +#endif // STBI_SSE2 + +#ifdef STBI_NEON + +// NEON integer IDCT. should produce bit-identical +// results to the generic C version. +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; + + int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); + int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); + int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f)); + int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f)); + int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); + int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); + int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); + int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); + int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f)); + int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f)); + int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f)); + int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f)); + +#define dct_long_mul(out, inq, coeff) \ + int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) + +#define dct_long_mac(out, acc, inq, coeff) \ + int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) + +#define dct_widen(out, inq) \ + int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ + int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) + +// wide add +#define dct_wadd(out, a, b) \ + int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vaddq_s32(a##_h, b##_h) + +// wide sub +#define dct_wsub(out, a, b) \ + int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vsubq_s32(a##_h, b##_h) + +// butterfly a/b, then shift using "shiftop" by "s" and pack +#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ + { \ + dct_wadd(sum, a, b); \ + dct_wsub(dif, a, b); \ + out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ + out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ + } + +#define dct_pass(shiftop, shift) \ + { \ + /* even part */ \ + int16x8_t sum26 = vaddq_s16(row2, row6); \ + dct_long_mul(p1e, sum26, rot0_0); \ + dct_long_mac(t2e, p1e, row6, rot0_1); \ + dct_long_mac(t3e, p1e, row2, rot0_2); \ + int16x8_t sum04 = vaddq_s16(row0, row4); \ + int16x8_t dif04 = vsubq_s16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + int16x8_t sum15 = vaddq_s16(row1, row5); \ + int16x8_t sum17 = vaddq_s16(row1, row7); \ + int16x8_t sum35 = vaddq_s16(row3, row5); \ + int16x8_t sum37 = vaddq_s16(row3, row7); \ + int16x8_t sumodd = vaddq_s16(sum17, sum35); \ + dct_long_mul(p5o, sumodd, rot1_0); \ + dct_long_mac(p1o, p5o, sum17, rot1_1); \ + dct_long_mac(p2o, p5o, sum35, rot1_2); \ + dct_long_mul(p3o, sum37, rot2_0); \ + dct_long_mul(p4o, sum15, rot2_1); \ + dct_wadd(sump13o, p1o, p3o); \ + dct_wadd(sump24o, p2o, p4o); \ + dct_wadd(sump23o, p2o, p3o); \ + dct_wadd(sump14o, p1o, p4o); \ + dct_long_mac(x4, sump13o, row7, rot3_0); \ + dct_long_mac(x5, sump24o, row5, rot3_1); \ + dct_long_mac(x6, sump23o, row3, rot3_2); \ + dct_long_mac(x7, sump14o, row1, rot3_3); \ + dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ + dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ + dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ + dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ + } + + // load + row0 = vld1q_s16(data + 0*8); + row1 = vld1q_s16(data + 1*8); + row2 = vld1q_s16(data + 2*8); + row3 = vld1q_s16(data + 3*8); + row4 = vld1q_s16(data + 4*8); + row5 = vld1q_s16(data + 5*8); + row6 = vld1q_s16(data + 6*8); + row7 = vld1q_s16(data + 7*8); + + // add DC bias + row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); + + // column pass + dct_pass(vrshrn_n_s32, 10); + + // 16bit 8x8 transpose + { +// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. +// whether compilers actually get this is another story, sadly. +#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } +#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } + + // pass 1 + dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 + dct_trn16(row2, row3); + dct_trn16(row4, row5); + dct_trn16(row6, row7); + + // pass 2 + dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 + dct_trn32(row1, row3); + dct_trn32(row4, row6); + dct_trn32(row5, row7); + + // pass 3 + dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 + dct_trn64(row1, row5); + dct_trn64(row2, row6); + dct_trn64(row3, row7); + +#undef dct_trn16 +#undef dct_trn32 +#undef dct_trn64 + } + + // row pass + // vrshrn_n_s32 only supports shifts up to 16, we need + // 17. so do a non-rounding shift of 16 first then follow + // up with a rounding shift by 1. + dct_pass(vshrn_n_s32, 16); + + { + // pack and round + uint8x8_t p0 = vqrshrun_n_s16(row0, 1); + uint8x8_t p1 = vqrshrun_n_s16(row1, 1); + uint8x8_t p2 = vqrshrun_n_s16(row2, 1); + uint8x8_t p3 = vqrshrun_n_s16(row3, 1); + uint8x8_t p4 = vqrshrun_n_s16(row4, 1); + uint8x8_t p5 = vqrshrun_n_s16(row5, 1); + uint8x8_t p6 = vqrshrun_n_s16(row6, 1); + uint8x8_t p7 = vqrshrun_n_s16(row7, 1); + + // again, these can translate into one instruction, but often don't. +#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } +#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } + + // sadly can't use interleaved stores here since we only write + // 8 bytes to each scan line! + + // 8x8 8-bit transpose pass 1 + dct_trn8_8(p0, p1); + dct_trn8_8(p2, p3); + dct_trn8_8(p4, p5); + dct_trn8_8(p6, p7); + + // pass 2 + dct_trn8_16(p0, p2); + dct_trn8_16(p1, p3); + dct_trn8_16(p4, p6); + dct_trn8_16(p5, p7); + + // pass 3 + dct_trn8_32(p0, p4); + dct_trn8_32(p1, p5); + dct_trn8_32(p2, p6); + dct_trn8_32(p3, p7); + + // store + vst1_u8(out, p0); out += out_stride; + vst1_u8(out, p1); out += out_stride; + vst1_u8(out, p2); out += out_stride; + vst1_u8(out, p3); out += out_stride; + vst1_u8(out, p4); out += out_stride; + vst1_u8(out, p5); out += out_stride; + vst1_u8(out, p6); out += out_stride; + vst1_u8(out, p7); + +#undef dct_trn8_8 +#undef dct_trn8_16 +#undef dct_trn8_32 + } + +#undef dct_long_mul +#undef dct_long_mac +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_pass +} + +#endif // STBI_NEON + +#define STBI__MARKER_none 0xff +// if there's a pending marker from the entropy stream, return that +// otherwise, fetch from the stream and get a marker. if there's no +// marker, return 0xff, which is never a valid marker value +static stbi_uc stbi__get_marker(stbi__jpeg *j) +{ + stbi_uc x; + if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } + x = stbi__get8(j->s); + if (x != 0xff) return STBI__MARKER_none; + while (x == 0xff) + x = stbi__get8(j->s); // consume repeated 0xff fill bytes + return x; +} + +// in each scan, we'll have scan_n components, and the order +// of the components is specified by order[] +#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) + +// after a restart interval, stbi__jpeg_reset the entropy decoder and +// the dc prediction +static void stbi__jpeg_reset(stbi__jpeg *j) +{ + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; + j->marker = STBI__MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + j->eob_run = 0; + // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + // since we don't even allow 1<<30 pixels +} + +static int stbi__parse_entropy_coded_data(stbi__jpeg *z) +{ + stbi__jpeg_reset(z); + if (!z->progressive) { + if (z->scan_n == 1) { + int i,j; + STBI_SIMD_ALIGN(short, data[64]); + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + STBI_SIMD_ALIGN(short, data[64]); + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x)*8; + int y2 = (j*z->img_comp[n].v + y)*8; + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } else { + if (z->scan_n == 1) { + int i,j; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + if (z->spec_start == 0) { + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } else { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) + return 0; + } + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x); + int y2 = (j*z->img_comp[n].v + y); + short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } +} + +static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant) +{ + int i; + for (i=0; i < 64; ++i) + data[i] *= dequant[i]; +} + +static void stbi__jpeg_finish(stbi__jpeg *z) +{ + if (z->progressive) { + // dequantize and idct the data + int i,j,n; + for (n=0; n < z->s->img_n; ++n) { + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + } + } + } + } +} + +static int stbi__process_marker(stbi__jpeg *z, int m) +{ + int L; + switch (m) { + case STBI__MARKER_none: // no marker found + return stbi__err("expected marker","Corrupt JPEG"); + + case 0xDD: // DRI - specify restart interval + if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG"); + z->restart_interval = stbi__get16be(z->s); + return 1; + + case 0xDB: // DQT - define quantization table + L = stbi__get16be(z->s)-2; + while (L > 0) { + int q = stbi__get8(z->s); + int p = q >> 4, sixteen = (p != 0); + int t = q & 15,i; + if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG"); + if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); + + for (i=0; i < 64; ++i) + z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); + L -= (sixteen ? 129 : 65); + } + return L==0; + + case 0xC4: // DHT - define huffman table + L = stbi__get16be(z->s)-2; + while (L > 0) { + stbi_uc *v; + int sizes[16],i,n=0; + int q = stbi__get8(z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG"); + for (i=0; i < 16; ++i) { + sizes[i] = stbi__get8(z->s); + n += sizes[i]; + } + L -= 17; + if (tc == 0) { + if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0; + v = z->huff_dc[th].values; + } else { + if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0; + v = z->huff_ac[th].values; + } + for (i=0; i < n; ++i) + v[i] = stbi__get8(z->s); + if (tc != 0) + stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); + L -= n; + } + return L==0; + } + + // check for comment block or APP blocks + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { + L = stbi__get16be(z->s); + if (L < 2) { + if (m == 0xFE) + return stbi__err("bad COM len","Corrupt JPEG"); + else + return stbi__err("bad APP len","Corrupt JPEG"); + } + L -= 2; + + if (m == 0xE0 && L >= 5) { // JFIF APP0 segment + static const unsigned char tag[5] = {'J','F','I','F','\0'}; + int ok = 1; + int i; + for (i=0; i < 5; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 5; + if (ok) + z->jfif = 1; + } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment + static const unsigned char tag[6] = {'A','d','o','b','e','\0'}; + int ok = 1; + int i; + for (i=0; i < 6; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 6; + if (ok) { + stbi__get8(z->s); // version + stbi__get16be(z->s); // flags0 + stbi__get16be(z->s); // flags1 + z->app14_color_transform = stbi__get8(z->s); // color transform + L -= 6; + } + } + + stbi__skip(z->s, L); + return 1; + } + + return stbi__err("unknown marker","Corrupt JPEG"); +} + +// after we see SOS +static int stbi__process_scan_header(stbi__jpeg *z) +{ + int i; + int Ls = stbi__get16be(z->s); + z->scan_n = stbi__get8(z->s); + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG"); + if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG"); + for (i=0; i < z->scan_n; ++i) { + int id = stbi__get8(z->s), which; + int q = stbi__get8(z->s); + for (which = 0; which < z->s->img_n; ++which) + if (z->img_comp[which].id == id) + break; + if (which == z->s->img_n) return 0; // no match + z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG"); + z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG"); + z->order[i] = which; + } + + { + int aa; + z->spec_start = stbi__get8(z->s); + z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 + aa = stbi__get8(z->s); + z->succ_high = (aa >> 4); + z->succ_low = (aa & 15); + if (z->progressive) { + if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) + return stbi__err("bad SOS", "Corrupt JPEG"); + } else { + if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG"); + if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG"); + z->spec_end = 63; + } + } + + return 1; +} + +static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) +{ + int i; + for (i=0; i < ncomp; ++i) { + if (z->img_comp[i].raw_data) { + STBI_FREE(z->img_comp[i].raw_data); + z->img_comp[i].raw_data = NULL; + z->img_comp[i].data = NULL; + } + if (z->img_comp[i].raw_coeff) { + STBI_FREE(z->img_comp[i].raw_coeff); + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].coeff = 0; + } + if (z->img_comp[i].linebuf) { + STBI_FREE(z->img_comp[i].linebuf); + z->img_comp[i].linebuf = NULL; + } + } + return why; +} + +static int stbi__process_frame_header(stbi__jpeg *z, int scan) +{ + stbi__context *s = z->s; + int Lf,p,i,q, h_max=1,v_max=1,c; + Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG + p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires + if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + c = stbi__get8(s); + if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG"); + s->img_n = c; + for (i=0; i < c; ++i) { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } + + if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG"); + + z->rgb = 0; + for (i=0; i < s->img_n; ++i) { + static const unsigned char rgb[3] = { 'R', 'G', 'B' }; + z->img_comp[i].id = stbi__get8(s); + if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) + ++z->rgb; + q = stbi__get8(s); + z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); + z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); + z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG"); + } + + if (scan != STBI__SCAN_load) return 1; + + if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); + + for (i=0; i < s->img_n; ++i) { + if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } + + // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios + // and I've never seen a non-corrupted JPEG file actually use them + for (i=0; i < s->img_n; ++i) { + if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H","Corrupt JPEG"); + if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V","Corrupt JPEG"); + } + + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + // these sizes can't be more than 17 bits + z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + + for (i=0; i < s->img_n; ++i) { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + // + // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) + // so these muls can't overflow with 32-bit ints (which we require) + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].coeff = 0; + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].linebuf = NULL; + z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); + if (z->img_comp[i].raw_data == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); + // align blocks for idct using mmx/sse + z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); + if (z->progressive) { + // w2, h2 are multiples of 8 (see above) + z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; + z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; + z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); + if (z->img_comp[i].raw_coeff == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); + z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); + } + } + + return 1; +} + +// use comparisons since in some cases we handle more than one case (e.g. SOF) +#define stbi__DNL(x) ((x) == 0xdc) +#define stbi__SOI(x) ((x) == 0xd8) +#define stbi__EOI(x) ((x) == 0xd9) +#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) +#define stbi__SOS(x) ((x) == 0xda) + +#define stbi__SOF_progressive(x) ((x) == 0xc2) + +static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) +{ + int m; + z->jfif = 0; + z->app14_color_transform = -1; // valid values are 0,1,2 + z->marker = STBI__MARKER_none; // initialize cached marker to empty + m = stbi__get_marker(z); + if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); + if (scan == STBI__SCAN_type) return 1; + m = stbi__get_marker(z); + while (!stbi__SOF(m)) { + if (!stbi__process_marker(z,m)) return 0; + m = stbi__get_marker(z); + while (m == STBI__MARKER_none) { + // some files have extra padding after their blocks, so ok, we'll scan + if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); + m = stbi__get_marker(z); + } + } + z->progressive = stbi__SOF_progressive(m); + if (!stbi__process_frame_header(z, scan)) return 0; + return 1; +} + +// decode image to YCbCr format +static int stbi__decode_jpeg_image(stbi__jpeg *j) +{ + int m; + for (m = 0; m < 4; m++) { + j->img_comp[m].raw_data = NULL; + j->img_comp[m].raw_coeff = NULL; + } + j->restart_interval = 0; + if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; + m = stbi__get_marker(j); + while (!stbi__EOI(m)) { + if (stbi__SOS(m)) { + if (!stbi__process_scan_header(j)) return 0; + if (!stbi__parse_entropy_coded_data(j)) return 0; + if (j->marker == STBI__MARKER_none ) { + // handle 0s at the end of image data from IP Kamera 9060 + while (!stbi__at_eof(j->s)) { + int x = stbi__get8(j->s); + if (x == 255) { + j->marker = stbi__get8(j->s); + break; + } + } + // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 + } + } else if (stbi__DNL(m)) { + int Ld = stbi__get16be(j->s); + stbi__uint32 NL = stbi__get16be(j->s); + if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); + if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); + } else { + if (!stbi__process_marker(j, m)) return 0; + } + m = stbi__get_marker(j); + } + if (j->progressive) + stbi__jpeg_finish(j); + return 1; +} + +// static jfif-centered resampling (across block boundaries) + +typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, + int w, int hs); + +#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) + +static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + STBI_NOTUSED(out); + STBI_NOTUSED(in_far); + STBI_NOTUSED(w); + STBI_NOTUSED(hs); + return in_near; +} + +static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples vertically for every one in input + int i; + STBI_NOTUSED(hs); + for (i=0; i < w; ++i) + out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2); + return out; +} + +static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples horizontally for every one in input + int i; + stbi_uc *input = in_near; + + if (w == 1) { + // if only one sample, can't do any interpolation + out[0] = out[1] = input[0]; + return out; + } + + out[0] = input[0]; + out[1] = stbi__div4(input[0]*3 + input[1] + 2); + for (i=1; i < w-1; ++i) { + int n = 3*input[i]+2; + out[i*2+0] = stbi__div4(n+input[i-1]); + out[i*2+1] = stbi__div4(n+input[i+1]); + } + out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2); + out[i*2+1] = input[w-1]; + + STBI_NOTUSED(in_far); + STBI_NOTUSED(hs); + + return out; +} + +#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) + +static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i,t0,t1; + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + out[0] = stbi__div4(t1+2); + for (i=1; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i=0,t0,t1; + + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + // process groups of 8 pixels for as long as we can. + // note we can't handle the last pixel in a row in this loop + // because we need to handle the filter boundary conditions. + for (; i < ((w-1) & ~7); i += 8) { +#if defined(STBI_SSE2) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + __m128i zero = _mm_setzero_si128(); + __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); + __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); + __m128i farw = _mm_unpacklo_epi8(farb, zero); + __m128i nearw = _mm_unpacklo_epi8(nearb, zero); + __m128i diff = _mm_sub_epi16(farw, nearw); + __m128i nears = _mm_slli_epi16(nearw, 2); + __m128i curr = _mm_add_epi16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + __m128i prv0 = _mm_slli_si128(curr, 2); + __m128i nxt0 = _mm_srli_si128(curr, 2); + __m128i prev = _mm_insert_epi16(prv0, t1, 0); + __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + __m128i bias = _mm_set1_epi16(8); + __m128i curs = _mm_slli_epi16(curr, 2); + __m128i prvd = _mm_sub_epi16(prev, curr); + __m128i nxtd = _mm_sub_epi16(next, curr); + __m128i curb = _mm_add_epi16(curs, bias); + __m128i even = _mm_add_epi16(prvd, curb); + __m128i odd = _mm_add_epi16(nxtd, curb); + + // interleave even and odd pixels, then undo scaling. + __m128i int0 = _mm_unpacklo_epi16(even, odd); + __m128i int1 = _mm_unpackhi_epi16(even, odd); + __m128i de0 = _mm_srli_epi16(int0, 4); + __m128i de1 = _mm_srli_epi16(int1, 4); + + // pack and write output + __m128i outv = _mm_packus_epi16(de0, de1); + _mm_storeu_si128((__m128i *) (out + i*2), outv); +#elif defined(STBI_NEON) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + uint8x8_t farb = vld1_u8(in_far + i); + uint8x8_t nearb = vld1_u8(in_near + i); + int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); + int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); + int16x8_t curr = vaddq_s16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + int16x8_t prv0 = vextq_s16(curr, curr, 7); + int16x8_t nxt0 = vextq_s16(curr, curr, 1); + int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); + int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + int16x8_t curs = vshlq_n_s16(curr, 2); + int16x8_t prvd = vsubq_s16(prev, curr); + int16x8_t nxtd = vsubq_s16(next, curr); + int16x8_t even = vaddq_s16(curs, prvd); + int16x8_t odd = vaddq_s16(curs, nxtd); + + // undo scaling and round, then store with even/odd phases interleaved + uint8x8x2_t o; + o.val[0] = vqrshrun_n_s16(even, 4); + o.val[1] = vqrshrun_n_s16(odd, 4); + vst2_u8(out + i*2, o); +#endif + + // "previous" value for next iter + t1 = 3*in_near[i+7] + in_far[i+7]; + } + + t0 = t1; + t1 = 3*in_near[i] + in_far[i]; + out[i*2] = stbi__div16(3*t1 + t0 + 8); + + for (++i; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} +#endif + +static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // resample with nearest-neighbor + int i,j; + STBI_NOTUSED(in_far); + for (i=0; i < w; ++i) + for (j=0; j < hs; ++j) + out[i*hs+j] = in_near[i]; + return out; +} + +// this is a reduced-precision calculation of YCbCr-to-RGB introduced +// to make sure the code produces the same results in both SIMD and scalar +#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) +static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) +{ + int i = 0; + +#ifdef STBI_SSE2 + // step == 3 is pretty ugly on the final interleave, and i'm not convinced + // it's useful in practice (you wouldn't use it for textures, for example). + // so just accelerate step == 4 case. + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + __m128i signflip = _mm_set1_epi8(-0x80); + __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); + __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); + __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); + __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); + __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); + __m128i xw = _mm_set1_epi16(255); // alpha channel + + for (; i+7 < count; i += 8) { + // load + __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); + __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); + __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); + __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 + __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 + + // unpack to short (and left-shift cr, cb by 8) + __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); + __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); + __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); + + // color transform + __m128i yws = _mm_srli_epi16(yw, 4); + __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); + __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); + __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); + __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); + __m128i rws = _mm_add_epi16(cr0, yws); + __m128i gwt = _mm_add_epi16(cb0, yws); + __m128i bws = _mm_add_epi16(yws, cb1); + __m128i gws = _mm_add_epi16(gwt, cr1); + + // descale + __m128i rw = _mm_srai_epi16(rws, 4); + __m128i bw = _mm_srai_epi16(bws, 4); + __m128i gw = _mm_srai_epi16(gws, 4); + + // back to byte, set up for transpose + __m128i brb = _mm_packus_epi16(rw, bw); + __m128i gxb = _mm_packus_epi16(gw, xw); + + // transpose to interleave channels + __m128i t0 = _mm_unpacklo_epi8(brb, gxb); + __m128i t1 = _mm_unpackhi_epi8(brb, gxb); + __m128i o0 = _mm_unpacklo_epi16(t0, t1); + __m128i o1 = _mm_unpackhi_epi16(t0, t1); + + // store + _mm_storeu_si128((__m128i *) (out + 0), o0); + _mm_storeu_si128((__m128i *) (out + 16), o1); + out += 32; + } + } +#endif + +#ifdef STBI_NEON + // in this version, step=3 support would be easy to add. but is there demand? + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + uint8x8_t signflip = vdup_n_u8(0x80); + int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); + int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); + int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); + int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); + + for (; i+7 < count; i += 8) { + // load + uint8x8_t y_bytes = vld1_u8(y + i); + uint8x8_t cr_bytes = vld1_u8(pcr + i); + uint8x8_t cb_bytes = vld1_u8(pcb + i); + int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); + int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); + + // expand to s16 + int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); + int16x8_t crw = vshll_n_s8(cr_biased, 7); + int16x8_t cbw = vshll_n_s8(cb_biased, 7); + + // color transform + int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); + int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); + int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); + int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); + int16x8_t rws = vaddq_s16(yws, cr0); + int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); + int16x8_t bws = vaddq_s16(yws, cb1); + + // undo scaling, round, convert to byte + uint8x8x4_t o; + o.val[0] = vqrshrun_n_s16(rws, 4); + o.val[1] = vqrshrun_n_s16(gws, 4); + o.val[2] = vqrshrun_n_s16(bws, 4); + o.val[3] = vdup_n_u8(255); + + // store, interleaving r/g/b/a + vst4_u8(out, o); + out += 8*4; + } + } +#endif + + for (; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#endif + +// set up the kernels +static void stbi__setup_jpeg(stbi__jpeg *j) +{ + j->idct_block_kernel = stbi__idct_block; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; + +#ifdef STBI_SSE2 + if (stbi__sse2_available()) { + j->idct_block_kernel = stbi__idct_simd; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; + } +#endif + +#ifdef STBI_NEON + j->idct_block_kernel = stbi__idct_simd; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; +#endif +} + +// clean up the temporary component buffers +static void stbi__cleanup_jpeg(stbi__jpeg *j) +{ + stbi__free_jpeg_components(j, j->s->img_n, 0); +} + +typedef struct +{ + resample_row_func resample; + stbi_uc *line0,*line1; + int hs,vs; // expansion factor in each axis + int w_lores; // horizontal pixels pre-expansion + int ystep; // how far through vertical expansion we are + int ypos; // which pre-expansion row we're on +} stbi__resample; + +// fast 0..255 * 0..255 => 0..255 rounded multiplication +static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) +{ + unsigned int t = x*y + 128; + return (stbi_uc) ((t + (t >>8)) >> 8); +} + +static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) +{ + int n, decode_n, is_rgb; + z->s->img_n = 0; // make stbi__cleanup_jpeg safe + + // validate req_comp + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + + // load a jpeg image from whichever source, but leave in YCbCr format + if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } + + // determine actual number of components to generate + n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; + + is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); + + if (z->s->img_n == 3 && n < 3 && !is_rgb) + decode_n = 1; + else + decode_n = z->s->img_n; + + // nothing to do if no components requested; check this now to avoid + // accessing uninitialized coutput[0] later + if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } + + // resample and color-convert + { + int k; + unsigned int i,j; + stbi_uc *output; + stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL }; + + stbi__resample res_comp[4]; + + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + + // allocate line buffer big enough for upsampling off the edges + // with upsample factor of 4 + z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); + if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs-1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; + + if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; + else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; + else r->resample = stbi__resample_row_generic; + } + + // can't error after this so, this is safe + output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); + if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + // now go ahead and resample + for (j=0; j < z->s->img_y; ++j) { + stbi_uc *out = output + n * z->s->img_x * j; + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + if (++r->ystep >= r->vs) { + r->ystep = 0; + r->line0 = r->line1; + if (++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + if (n >= 3) { + stbi_uc *y = coutput[0]; + if (z->s->img_n == 3) { + if (is_rgb) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = y[i]; + out[1] = coutput[1][i]; + out[2] = coutput[2][i]; + out[3] = 255; + out += n; + } + } else { + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } else if (z->s->img_n == 4) { + if (z->app14_color_transform == 0) { // CMYK + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(coutput[0][i], m); + out[1] = stbi__blinn_8x8(coutput[1][i], m); + out[2] = stbi__blinn_8x8(coutput[2][i], m); + out[3] = 255; + out += n; + } + } else if (z->app14_color_transform == 2) { // YCCK + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(255 - out[0], m); + out[1] = stbi__blinn_8x8(255 - out[1], m); + out[2] = stbi__blinn_8x8(255 - out[2], m); + out += n; + } + } else { // YCbCr + alpha? Ignore the fourth channel for now + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } else + for (i=0; i < z->s->img_x; ++i) { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; // not used if n==3 + out += n; + } + } else { + if (is_rgb) { + if (n == 1) + for (i=0; i < z->s->img_x; ++i) + *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + else { + for (i=0; i < z->s->img_x; ++i, out += 2) { + out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + out[1] = 255; + } + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 0) { + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); + stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); + stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); + out[0] = stbi__compute_y(r, g, b); + out[1] = 255; + out += n; + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 2) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); + out[1] = 255; + out += n; + } + } else { + stbi_uc *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } + } + } + } + stbi__cleanup_jpeg(z); + *out_x = z->s->img_x; + *out_y = z->s->img_y; + if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output + return output; + } +} + +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + unsigned char* result; + stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); + if (!j) return stbi__errpuc("outofmem", "Out of memory"); + STBI_NOTUSED(ri); + j->s = s; + stbi__setup_jpeg(j); + result = load_jpeg_image(j, x,y,comp,req_comp); + STBI_FREE(j); + return result; +} + +static int stbi__jpeg_test(stbi__context *s) +{ + int r; + stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); + if (!j) return stbi__err("outofmem", "Out of memory"); + j->s = s; + stbi__setup_jpeg(j); + r = stbi__decode_jpeg_header(j, STBI__SCAN_type); + stbi__rewind(s); + STBI_FREE(j); + return r; +} + +static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) +{ + if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { + stbi__rewind( j->s ); + return 0; + } + if (x) *x = j->s->img_x; + if (y) *y = j->s->img_y; + if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; + return 1; +} + +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) +{ + int result; + stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); + if (!j) return stbi__err("outofmem", "Out of memory"); + j->s = s; + result = stbi__jpeg_info_raw(j, x, y, comp); + STBI_FREE(j); + return result; +} +#endif + +// public domain zlib decode v0.2 Sean Barrett 2006-11-18 +// simple implementation +// - all input must be provided in an upfront buffer +// - all output is written to a single output buffer (can malloc/realloc) +// performance +// - fast huffman + +#ifndef STBI_NO_ZLIB + +// fast-way is faster to check than jpeg huffman, but slow way is slower +#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables +#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) +#define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet + +// zlib-style huffman encoding +// (jpegs packs from left, zlib from right, so can't share code) +typedef struct +{ + stbi__uint16 fast[1 << STBI__ZFAST_BITS]; + stbi__uint16 firstcode[16]; + int maxcode[17]; + stbi__uint16 firstsymbol[16]; + stbi_uc size[STBI__ZNSYMS]; + stbi__uint16 value[STBI__ZNSYMS]; +} stbi__zhuffman; + +stbi_inline static int stbi__bitreverse16(int n) +{ + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; +} + +stbi_inline static int stbi__bit_reverse(int v, int bits) +{ + STBI_ASSERT(bits <= 16); + // to bit reverse n bits, reverse 16 and shift + // e.g. 11 bits, bit reverse and shift away 5 + return stbi__bitreverse16(v) >> (16-bits); +} + +static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num) +{ + int i,k=0; + int code, next_code[16], sizes[17]; + + // DEFLATE spec for generating codes + memset(sizes, 0, sizeof(sizes)); + memset(z->fast, 0, sizeof(z->fast)); + for (i=0; i < num; ++i) + ++sizes[sizelist[i]]; + sizes[0] = 0; + for (i=1; i < 16; ++i) + if (sizes[i] > (1 << i)) + return stbi__err("bad sizes", "Corrupt PNG"); + code = 0; + for (i=1; i < 16; ++i) { + next_code[i] = code; + z->firstcode[i] = (stbi__uint16) code; + z->firstsymbol[i] = (stbi__uint16) k; + code = (code + sizes[i]); + if (sizes[i]) + if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG"); + z->maxcode[i] = code << (16-i); // preshift for inner loop + code <<= 1; + k += sizes[i]; + } + z->maxcode[16] = 0x10000; // sentinel + for (i=0; i < num; ++i) { + int s = sizelist[i]; + if (s) { + int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; + stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i); + z->size [c] = (stbi_uc ) s; + z->value[c] = (stbi__uint16) i; + if (s <= STBI__ZFAST_BITS) { + int j = stbi__bit_reverse(next_code[s],s); + while (j < (1 << STBI__ZFAST_BITS)) { + z->fast[j] = fastv; + j += (1 << s); + } + } + ++next_code[s]; + } + } + return 1; +} + +// zlib-from-memory implementation for PNG reading +// because PNG allows splitting the zlib stream arbitrarily, +// and it's annoying structurally to have PNG call ZLIB call PNG, +// we require PNG read all the IDATs and combine them into a single +// memory buffer + +typedef struct +{ + stbi_uc *zbuffer, *zbuffer_end; + int num_bits; + stbi__uint32 code_buffer; + + char *zout; + char *zout_start; + char *zout_end; + int z_expandable; + + stbi__zhuffman z_length, z_distance; +} stbi__zbuf; + +stbi_inline static int stbi__zeof(stbi__zbuf *z) +{ + return (z->zbuffer >= z->zbuffer_end); +} + +stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) +{ + return stbi__zeof(z) ? 0 : *z->zbuffer++; +} + +static void stbi__fill_bits(stbi__zbuf *z) +{ + do { + if (z->code_buffer >= (1U << z->num_bits)) { + z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ + return; + } + z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; + z->num_bits += 8; + } while (z->num_bits <= 24); +} + +stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) +{ + unsigned int k; + if (z->num_bits < n) stbi__fill_bits(z); + k = z->code_buffer & ((1 << n) - 1); + z->code_buffer >>= n; + z->num_bits -= n; + return k; +} + +static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s,k; + // not resolved by fast table, so compute it the slow way + // use jpeg approach, which requires MSbits at top + k = stbi__bit_reverse(a->code_buffer, 16); + for (s=STBI__ZFAST_BITS+1; ; ++s) + if (k < z->maxcode[s]) + break; + if (s >= 16) return -1; // invalid code! + // code size is s, so: + b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; + if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! + if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; +} + +stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s; + if (a->num_bits < 16) { + if (stbi__zeof(a)) { + return -1; /* report error for unexpected end of data. */ + } + stbi__fill_bits(a); + } + b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; + if (b) { + s = b >> 9; + a->code_buffer >>= s; + a->num_bits -= s; + return b & 511; + } + return stbi__zhuffman_decode_slowpath(a, z); +} + +static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes +{ + char *q; + unsigned int cur, limit, old_limit; + z->zout = zout; + if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); + cur = (unsigned int) (z->zout - z->zout_start); + limit = old_limit = (unsigned) (z->zout_end - z->zout_start); + if (UINT_MAX - cur < (unsigned) n) return stbi__err("outofmem", "Out of memory"); + while (cur + n > limit) { + if(limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); + limit *= 2; + } + q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); + STBI_NOTUSED(old_limit); + if (q == NULL) return stbi__err("outofmem", "Out of memory"); + z->zout_start = q; + z->zout = q + cur; + z->zout_end = q + limit; + return 1; +} + +static const int stbi__zlength_base[31] = { + 3,4,5,6,7,8,9,10,11,13, + 15,17,19,23,27,31,35,43,51,59, + 67,83,99,115,131,163,195,227,258,0,0 }; + +static const int stbi__zlength_extra[31]= +{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + +static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, +257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + +static const int stbi__zdist_extra[32] = +{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +static int stbi__parse_huffman_block(stbi__zbuf *a) +{ + char *zout = a->zout; + for(;;) { + int z = stbi__zhuffman_decode(a, &a->z_length); + if (z < 256) { + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes + if (zout >= a->zout_end) { + if (!stbi__zexpand(a, zout, 1)) return 0; + zout = a->zout; + } + *zout++ = (char) z; + } else { + stbi_uc *p; + int len,dist; + if (z == 256) { + a->zout = zout; + return 1; + } + z -= 257; + len = stbi__zlength_base[z]; + if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); + z = stbi__zhuffman_decode(a, &a->z_distance); + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); + dist = stbi__zdist_base[z]; + if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); + if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); + if (zout + len > a->zout_end) { + if (!stbi__zexpand(a, zout, len)) return 0; + zout = a->zout; + } + p = (stbi_uc *) (zout - dist); + if (dist == 1) { // run of one byte; common in images. + stbi_uc v = *p; + if (len) { do *zout++ = v; while (--len); } + } else { + if (len) { do *zout++ = *p++; while (--len); } + } + } + } +} + +static int stbi__compute_huffman_codes(stbi__zbuf *a) +{ + static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + stbi__zhuffman z_codelength; + stbi_uc lencodes[286+32+137];//padding for maximum single op + stbi_uc codelength_sizes[19]; + int i,n; + + int hlit = stbi__zreceive(a,5) + 257; + int hdist = stbi__zreceive(a,5) + 1; + int hclen = stbi__zreceive(a,4) + 4; + int ntot = hlit + hdist; + + memset(codelength_sizes, 0, sizeof(codelength_sizes)); + for (i=0; i < hclen; ++i) { + int s = stbi__zreceive(a,3); + codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; + } + if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + + n = 0; + while (n < ntot) { + int c = stbi__zhuffman_decode(a, &z_codelength); + if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); + if (c < 16) + lencodes[n++] = (stbi_uc) c; + else { + stbi_uc fill = 0; + if (c == 16) { + c = stbi__zreceive(a,2)+3; + if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); + fill = lencodes[n-1]; + } else if (c == 17) { + c = stbi__zreceive(a,3)+3; + } else if (c == 18) { + c = stbi__zreceive(a,7)+11; + } else { + return stbi__err("bad codelengths", "Corrupt PNG"); + } + if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); + memset(lencodes+n, fill, c); + n += c; + } + } + if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG"); + if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; + return 1; +} + +static int stbi__parse_uncompressed_block(stbi__zbuf *a) +{ + stbi_uc header[4]; + int len,nlen,k; + if (a->num_bits & 7) + stbi__zreceive(a, a->num_bits & 7); // discard + // drain the bit-packed data into header + k = 0; + while (a->num_bits > 0) { + header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check + a->code_buffer >>= 8; + a->num_bits -= 8; + } + if (a->num_bits < 0) return stbi__err("zlib corrupt","Corrupt PNG"); + // now fill header the normal way + while (k < 4) + header[k++] = stbi__zget8(a); + len = header[1] * 256 + header[0]; + nlen = header[3] * 256 + header[2]; + if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); + if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); + if (a->zout + len > a->zout_end) + if (!stbi__zexpand(a, a->zout, len)) return 0; + memcpy(a->zout, a->zbuffer, len); + a->zbuffer += len; + a->zout += len; + return 1; +} + +static int stbi__parse_zlib_header(stbi__zbuf *a) +{ + int cmf = stbi__zget8(a); + int cm = cmf & 15; + /* int cinfo = cmf >> 4; */ + int flg = stbi__zget8(a); + if (stbi__zeof(a)) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec + if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec + if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png + if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png + // window = 1 << (8 + cinfo)... but who cares, we fully buffer output + return 1; +} + +static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = +{ + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 +}; +static const stbi_uc stbi__zdefault_distance[32] = +{ + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 +}; +/* +Init algorithm: +{ + int i; // use <= to match clearly with spec + for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; + for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; + for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; + for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; + + for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; +} +*/ + +static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) +{ + int final, type; + if (parse_header) + if (!stbi__parse_zlib_header(a)) return 0; + a->num_bits = 0; + a->code_buffer = 0; + do { + final = stbi__zreceive(a,1); + type = stbi__zreceive(a,2); + if (type == 0) { + if (!stbi__parse_uncompressed_block(a)) return 0; + } else if (type == 3) { + return 0; + } else { + if (type == 1) { + // use fixed code lengths + if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , STBI__ZNSYMS)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; + } else { + if (!stbi__compute_huffman_codes(a)) return 0; + } + if (!stbi__parse_huffman_block(a)) return 0; + } + } while (!final); + return 1; +} + +static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) +{ + a->zout_start = obuf; + a->zout = obuf; + a->zout_end = obuf + olen; + a->z_expandable = exp; + + return stbi__parse_zlib(a, parse_header); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) +{ + return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(16384); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer+len; + if (stbi__do_zlib(&a, p, 16384, 1, 0)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) + return (int) (a.zout - a.zout_start); + else + return -1; +} +#endif + +// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 +// simple implementation +// - only 8-bit samples +// - no CRC checking +// - allocates lots of intermediate memory +// - avoids problem of streaming data between subsystems +// - avoids explicit window management +// performance +// - uses stb_zlib, a PD zlib implementation with fast huffman decoding + +#ifndef STBI_NO_PNG +typedef struct +{ + stbi__uint32 length; + stbi__uint32 type; +} stbi__pngchunk; + +static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) +{ + stbi__pngchunk c; + c.length = stbi__get32be(s); + c.type = stbi__get32be(s); + return c; +} + +static int stbi__check_png_header(stbi__context *s) +{ + static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; + int i; + for (i=0; i < 8; ++i) + if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); + return 1; +} + +typedef struct +{ + stbi__context *s; + stbi_uc *idata, *expanded, *out; + int depth; +} stbi__png; + + +enum { + STBI__F_none=0, + STBI__F_sub=1, + STBI__F_up=2, + STBI__F_avg=3, + STBI__F_paeth=4, + // synthetic filters used for first scanline to avoid needing a dummy row of 0s + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static stbi_uc first_row_filter[5] = +{ + STBI__F_none, + STBI__F_sub, + STBI__F_none, + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static int stbi__paeth(int a, int b, int c) +{ + int p = a + b - c; + int pa = abs(p-a); + int pb = abs(p-b); + int pc = abs(p-c); + if (pa <= pb && pa <= pc) return a; + if (pb <= pc) return b; + return c; +} + +static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; + +// create the png data from post-deflated data +static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) +{ + int bytes = (depth == 16? 2 : 1); + stbi__context *s = a->s; + stbi__uint32 i,j,stride = x*out_n*bytes; + stbi__uint32 img_len, img_width_bytes; + int k; + int img_n = s->img_n; // copy it into a local for later + + int output_bytes = out_n*bytes; + int filter_bytes = img_n*bytes; + int width = x; + + STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); + a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into + if (!a->out) return stbi__err("outofmem", "Out of memory"); + + if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); + img_width_bytes = (((img_n * x * depth) + 7) >> 3); + img_len = (img_width_bytes + 1) * y; + + // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, + // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), + // so just check for raw_len < img_len always. + if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); + + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *prior; + int filter = *raw++; + + if (filter > 4) + return stbi__err("invalid filter","Corrupt PNG"); + + if (depth < 8) { + if (img_width_bytes > x) return stbi__err("invalid width","Corrupt PNG"); + cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place + filter_bytes = 1; + width = img_width_bytes; + } + prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above + + // if first row, use special filter that doesn't sample previous row + if (j == 0) filter = first_row_filter[filter]; + + // handle first byte explicitly + for (k=0; k < filter_bytes; ++k) { + switch (filter) { + case STBI__F_none : cur[k] = raw[k]; break; + case STBI__F_sub : cur[k] = raw[k]; break; + case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break; + case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break; + case STBI__F_avg_first : cur[k] = raw[k]; break; + case STBI__F_paeth_first: cur[k] = raw[k]; break; + } + } + + if (depth == 8) { + if (img_n != out_n) + cur[img_n] = 255; // first pixel + raw += img_n; + cur += out_n; + prior += out_n; + } else if (depth == 16) { + if (img_n != out_n) { + cur[filter_bytes] = 255; // first pixel top byte + cur[filter_bytes+1] = 255; // first pixel bottom byte + } + raw += filter_bytes; + cur += output_bytes; + prior += output_bytes; + } else { + raw += 1; + cur += 1; + prior += 1; + } + + // this is a little gross, so that we don't switch per-pixel or per-component + if (depth < 8 || img_n == out_n) { + int nk = (width - 1)*filter_bytes; + #define STBI__CASE(f) \ + case f: \ + for (k=0; k < nk; ++k) + switch (filter) { + // "none" filter turns into a memcpy here; make that explicit. + case STBI__F_none: memcpy(cur, raw, nk); break; + STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break; + STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; + STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break; + STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break; + STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break; + STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break; + } + #undef STBI__CASE + raw += nk; + } else { + STBI_ASSERT(img_n+1 == out_n); + #define STBI__CASE(f) \ + case f: \ + for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ + for (k=0; k < filter_bytes; ++k) + switch (filter) { + STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; + STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break; + STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; + STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break; + STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break; + STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break; + STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break; + } + #undef STBI__CASE + + // the loop above sets the high byte of the pixels' alpha, but for + // 16 bit png files we also need the low byte set. we'll do that here. + if (depth == 16) { + cur = a->out + stride*j; // start at the beginning of the row again + for (i=0; i < x; ++i,cur+=output_bytes) { + cur[filter_bytes+1] = 255; + } + } + } + } + + // we make a separate pass to expand bits to pixels; for performance, + // this could run two scanlines behind the above code, so it won't + // intefere with filtering but will still be in the cache. + if (depth < 8) { + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes; + // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit + // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop + stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range + + // note that the final byte might overshoot and write more data than desired. + // we can allocate enough data that this never writes out of memory, but it + // could also overwrite the next scanline. can it overwrite non-empty data + // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. + // so we need to explicitly clamp the final ones + + if (depth == 4) { + for (k=x*img_n; k >= 2; k-=2, ++in) { + *cur++ = scale * ((*in >> 4) ); + *cur++ = scale * ((*in ) & 0x0f); + } + if (k > 0) *cur++ = scale * ((*in >> 4) ); + } else if (depth == 2) { + for (k=x*img_n; k >= 4; k-=4, ++in) { + *cur++ = scale * ((*in >> 6) ); + *cur++ = scale * ((*in >> 4) & 0x03); + *cur++ = scale * ((*in >> 2) & 0x03); + *cur++ = scale * ((*in ) & 0x03); + } + if (k > 0) *cur++ = scale * ((*in >> 6) ); + if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); + if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); + } else if (depth == 1) { + for (k=x*img_n; k >= 8; k-=8, ++in) { + *cur++ = scale * ((*in >> 7) ); + *cur++ = scale * ((*in >> 6) & 0x01); + *cur++ = scale * ((*in >> 5) & 0x01); + *cur++ = scale * ((*in >> 4) & 0x01); + *cur++ = scale * ((*in >> 3) & 0x01); + *cur++ = scale * ((*in >> 2) & 0x01); + *cur++ = scale * ((*in >> 1) & 0x01); + *cur++ = scale * ((*in ) & 0x01); + } + if (k > 0) *cur++ = scale * ((*in >> 7) ); + if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); + if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); + if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); + if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); + if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); + if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); + } + if (img_n != out_n) { + int q; + // insert alpha = 255 + cur = a->out + stride*j; + if (img_n == 1) { + for (q=x-1; q >= 0; --q) { + cur[q*2+1] = 255; + cur[q*2+0] = cur[q]; + } + } else { + STBI_ASSERT(img_n == 3); + for (q=x-1; q >= 0; --q) { + cur[q*4+3] = 255; + cur[q*4+2] = cur[q*3+2]; + cur[q*4+1] = cur[q*3+1]; + cur[q*4+0] = cur[q*3+0]; + } + } + } + } + } else if (depth == 16) { + // force the image data from big-endian to platform-native. + // this is done in a separate pass due to the decoding relying + // on the data being untouched, but could probably be done + // per-line during decode if care is taken. + stbi_uc *cur = a->out; + stbi__uint16 *cur16 = (stbi__uint16*)cur; + + for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) { + *cur16 = (cur[0] << 8) | cur[1]; + } + } + + return 1; +} + +static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) +{ + int bytes = (depth == 16 ? 2 : 1); + int out_bytes = out_n * bytes; + stbi_uc *final; + int p; + if (!interlaced) + return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); + + // de-interlacing + final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); + if (!final) return stbi__err("outofmem", "Out of memory"); + for (p=0; p < 7; ++p) { + int xorig[] = { 0,4,0,2,0,1,0 }; + int yorig[] = { 0,0,4,0,2,0,1 }; + int xspc[] = { 8,8,4,4,2,2,1 }; + int yspc[] = { 8,8,8,4,4,2,2 }; + int i,j,x,y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; + y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; + if (x && y) { + stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; + if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { + STBI_FREE(final); + return 0; + } + for (j=0; j < y; ++j) { + for (i=0; i < x; ++i) { + int out_y = j*yspc[p]+yorig[p]; + int out_x = i*xspc[p]+xorig[p]; + memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes, + a->out + (j*x+i)*out_bytes, out_bytes); + } + } + STBI_FREE(a->out); + image_data += img_len; + image_data_len -= img_len; + } + } + a->out = final; + + return 1; +} + +static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + // compute color-based transparency, assuming we've + // already got 255 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i=0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 255); + p += 2; + } + } else { + for (i=0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi__uint16 *p = (stbi__uint16*) z->out; + + // compute color-based transparency, assuming we've + // already got 65535 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i = 0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 65535); + p += 2; + } + } else { + for (i = 0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n) +{ + stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; + stbi_uc *p, *temp_out, *orig = a->out; + + p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); + if (p == NULL) return stbi__err("outofmem", "Out of memory"); + + // between here and free(out) below, exitting would leak + temp_out = p; + + if (pal_img_n == 3) { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p += 3; + } + } else { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p[3] = palette[n+3]; + p += 4; + } + } + STBI_FREE(a->out); + a->out = temp_out; + + STBI_NOTUSED(len); + + return 1; +} + +static int stbi__unpremultiply_on_load_global = 0; +static int stbi__de_iphone_flag_global = 0; + +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) +{ + stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; +} + +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) +{ + stbi__de_iphone_flag_global = flag_true_if_should_convert; +} + +#ifndef STBI_THREAD_LOCAL +#define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global +#define stbi__de_iphone_flag stbi__de_iphone_flag_global +#else +static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; +static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; + +STBIDEF void stbi__unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) +{ + stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; + stbi__unpremultiply_on_load_set = 1; +} + +STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) +{ + stbi__de_iphone_flag_local = flag_true_if_should_convert; + stbi__de_iphone_flag_set = 1; +} + +#define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ + ? stbi__unpremultiply_on_load_local \ + : stbi__unpremultiply_on_load_global) +#define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ + ? stbi__de_iphone_flag_local \ + : stbi__de_iphone_flag_global) +#endif // STBI_THREAD_LOCAL + +static void stbi__de_iphone(stbi__png *z) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + if (s->img_out_n == 3) { // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 3; + } + } else { + STBI_ASSERT(s->img_out_n == 4); + if (stbi__unpremultiply_on_load) { + // convert bgr to rgb and unpremultiply + for (i=0; i < pixel_count; ++i) { + stbi_uc a = p[3]; + stbi_uc t = p[0]; + if (a) { + stbi_uc half = a / 2; + p[0] = (p[2] * 255 + half) / a; + p[1] = (p[1] * 255 + half) / a; + p[2] = ( t * 255 + half) / a; + } else { + p[0] = p[2]; + p[2] = t; + } + p += 4; + } + } else { + // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 4; + } + } + } +} + +#define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) + +static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) +{ + stbi_uc palette[1024], pal_img_n=0; + stbi_uc has_trans=0, tc[3]={0}; + stbi__uint16 tc16[3]; + stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; + int first=1,k,interlace=0, color=0, is_iphone=0; + stbi__context *s = z->s; + + z->expanded = NULL; + z->idata = NULL; + z->out = NULL; + + if (!stbi__check_png_header(s)) return 0; + + if (scan == STBI__SCAN_type) return 1; + + for (;;) { + stbi__pngchunk c = stbi__get_chunk_header(s); + switch (c.type) { + case STBI__PNG_TYPE('C','g','B','I'): + is_iphone = 1; + stbi__skip(s, c.length); + break; + case STBI__PNG_TYPE('I','H','D','R'): { + int comp,filter; + if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); + first = 0; + if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); + s->img_x = stbi__get32be(s); + s->img_y = stbi__get32be(s); + if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); + color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); + comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); + filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); + interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); + if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); + if (!pal_img_n) { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + if (scan == STBI__SCAN_header) return 1; + } else { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); + // if SCAN_header, have to scan to see if we have a tRNS + } + break; + } + + case STBI__PNG_TYPE('P','L','T','E'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); + pal_len = c.length / 3; + if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG"); + for (i=0; i < pal_len; ++i) { + palette[i*4+0] = stbi__get8(s); + palette[i*4+1] = stbi__get8(s); + palette[i*4+2] = stbi__get8(s); + palette[i*4+3] = 255; + } + break; + } + + case STBI__PNG_TYPE('t','R','N','S'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG"); + if (pal_img_n) { + if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } + if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG"); + if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG"); + pal_img_n = 4; + for (i=0; i < c.length; ++i) + palette[i*4+3] = stbi__get8(s); + } else { + if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG"); + if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); + has_trans = 1; + if (z->depth == 16) { + for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is + } else { + for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger + } + } + break; + } + + case STBI__PNG_TYPE('I','D','A','T'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG"); + if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; } + if ((int)(ioff + c.length) < (int)ioff) return 0; + if (ioff + c.length > idata_limit) { + stbi__uint32 idata_limit_old = idata_limit; + stbi_uc *p; + if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + STBI_NOTUSED(idata_limit_old); + p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); + z->idata = p; + } + if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); + ioff += c.length; + break; + } + + case STBI__PNG_TYPE('I','E','N','D'): { + stbi__uint32 raw_len, bpl; + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (scan != STBI__SCAN_load) return 1; + if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG"); + // initial guess for decoded data size to avoid unnecessary reallocs + bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component + raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; + z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone); + if (z->expanded == NULL) return 0; // zlib should set error + STBI_FREE(z->idata); z->idata = NULL; + if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n+1; + else + s->img_out_n = s->img_n; + if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; + if (has_trans) { + if (z->depth == 16) { + if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; + } else { + if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; + } + } + if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) + stbi__de_iphone(z); + if (pal_img_n) { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if (req_comp >= 3) s->img_out_n = req_comp; + if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } else if (has_trans) { + // non-paletted image with tRNS -> source image has (constant) alpha + ++s->img_n; + } + STBI_FREE(z->expanded); z->expanded = NULL; + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + return 1; + } + + default: + // if critical, fail + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if ((c.type & (1 << 29)) == 0) { + #ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX PNG chunk not known"; + invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); + invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); + invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); + invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); + #endif + return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); + } + stbi__skip(s, c.length); + break; + } + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + } +} + +static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) +{ + void *result=NULL; + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { + if (p->depth <= 8) + ri->bits_per_channel = 8; + else if (p->depth == 16) + ri->bits_per_channel = 16; + else + return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); + result = p->out; + p->out = NULL; + if (req_comp && req_comp != p->s->img_out_n) { + if (ri->bits_per_channel == 8) + result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + else + result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + p->s->img_out_n = req_comp; + if (result == NULL) return result; + } + *x = p->s->img_x; + *y = p->s->img_y; + if (n) *n = p->s->img_n; + } + STBI_FREE(p->out); p->out = NULL; + STBI_FREE(p->expanded); p->expanded = NULL; + STBI_FREE(p->idata); p->idata = NULL; + + return result; +} + +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi__png p; + p.s = s; + return stbi__do_png(&p, x,y,comp,req_comp, ri); +} + +static int stbi__png_test(stbi__context *s) +{ + int r; + r = stbi__check_png_header(s); + stbi__rewind(s); + return r; +} + +static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) +{ + if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { + stbi__rewind( p->s ); + return 0; + } + if (x) *x = p->s->img_x; + if (y) *y = p->s->img_y; + if (comp) *comp = p->s->img_n; + return 1; +} + +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__png p; + p.s = s; + return stbi__png_info_raw(&p, x, y, comp); +} + +static int stbi__png_is16(stbi__context *s) +{ + stbi__png p; + p.s = s; + if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) + return 0; + if (p.depth != 16) { + stbi__rewind(p.s); + return 0; + } + return 1; +} +#endif + +// Microsoft/Windows BMP image + +#ifndef STBI_NO_BMP +static int stbi__bmp_test_raw(stbi__context *s) +{ + int r; + int sz; + if (stbi__get8(s) != 'B') return 0; + if (stbi__get8(s) != 'M') return 0; + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + stbi__get32le(s); // discard data offset + sz = stbi__get32le(s); + r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); + return r; +} + +static int stbi__bmp_test(stbi__context *s) +{ + int r = stbi__bmp_test_raw(s); + stbi__rewind(s); + return r; +} + + +// returns 0..31 for the highest set bit +static int stbi__high_bit(unsigned int z) +{ + int n=0; + if (z == 0) return -1; + if (z >= 0x10000) { n += 16; z >>= 16; } + if (z >= 0x00100) { n += 8; z >>= 8; } + if (z >= 0x00010) { n += 4; z >>= 4; } + if (z >= 0x00004) { n += 2; z >>= 2; } + if (z >= 0x00002) { n += 1;/* >>= 1;*/ } + return n; +} + +static int stbi__bitcount(unsigned int a) +{ + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits + return a & 0xff; +} + +// extract an arbitrarily-aligned N-bit value (N=bits) +// from v, and then make it 8-bits long and fractionally +// extend it to full full range. +static int stbi__shiftsigned(unsigned int v, int shift, int bits) +{ + static unsigned int mul_table[9] = { + 0, + 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, + 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, + }; + static unsigned int shift_table[9] = { + 0, 0,0,1,0,2,4,6,0, + }; + if (shift < 0) + v <<= -shift; + else + v >>= shift; + STBI_ASSERT(v < 256); + v >>= (8-bits); + STBI_ASSERT(bits >= 0 && bits <= 8); + return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits]; +} + +typedef struct +{ + int bpp, offset, hsz; + unsigned int mr,mg,mb,ma, all_a; + int extra_read; +} stbi__bmp_data; + +static int stbi__bmp_set_mask_defaults(stbi__bmp_data *info, int compress) +{ + // BI_BITFIELDS specifies masks explicitly, don't override + if (compress == 3) + return 1; + + if (compress == 0) { + if (info->bpp == 16) { + info->mr = 31u << 10; + info->mg = 31u << 5; + info->mb = 31u << 0; + } else if (info->bpp == 32) { + info->mr = 0xffu << 16; + info->mg = 0xffu << 8; + info->mb = 0xffu << 0; + info->ma = 0xffu << 24; + info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 + } else { + // otherwise, use defaults, which is all-0 + info->mr = info->mg = info->mb = info->ma = 0; + } + return 1; + } + return 0; // error +} + +static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) +{ + int hsz; + if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + info->offset = stbi__get32le(s); + info->hsz = hsz = stbi__get32le(s); + info->mr = info->mg = info->mb = info->ma = 0; + info->extra_read = 14; + + if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); + + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); + if (hsz == 12) { + s->img_x = stbi__get16le(s); + s->img_y = stbi__get16le(s); + } else { + s->img_x = stbi__get32le(s); + s->img_y = stbi__get32le(s); + } + if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); + info->bpp = stbi__get16le(s); + if (hsz != 12) { + int compress = stbi__get32le(s); + if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); + if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes + if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel + stbi__get32le(s); // discard sizeof + stbi__get32le(s); // discard hres + stbi__get32le(s); // discard vres + stbi__get32le(s); // discard colorsused + stbi__get32le(s); // discard max important + if (hsz == 40 || hsz == 56) { + if (hsz == 56) { + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + } + if (info->bpp == 16 || info->bpp == 32) { + if (compress == 0) { + stbi__bmp_set_mask_defaults(info, compress); + } else if (compress == 3) { + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->extra_read += 12; + // not documented, but generated by photoshop and handled by mspaint + if (info->mr == info->mg && info->mg == info->mb) { + // ?!?!? + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else { + // V4/V5 header + int i; + if (hsz != 108 && hsz != 124) + return stbi__errpuc("bad BMP", "bad BMP"); + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->ma = stbi__get32le(s); + if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs + stbi__bmp_set_mask_defaults(info, compress); + stbi__get32le(s); // discard color space + for (i=0; i < 12; ++i) + stbi__get32le(s); // discard color space parameters + if (hsz == 124) { + stbi__get32le(s); // discard rendering intent + stbi__get32le(s); // discard offset of profile data + stbi__get32le(s); // discard size of profile data + stbi__get32le(s); // discard reserved + } + } + } + return (void *) 1; +} + + +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *out; + unsigned int mr=0,mg=0,mb=0,ma=0, all_a; + stbi_uc pal[256][4]; + int psize=0,i,j,width; + int flip_vertically, pad, target; + stbi__bmp_data info; + STBI_NOTUSED(ri); + + info.all_a = 255; + if (stbi__bmp_parse_header(s, &info) == NULL) + return NULL; // error code already set + + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + + if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + mr = info.mr; + mg = info.mg; + mb = info.mb; + ma = info.ma; + all_a = info.all_a; + + if (info.hsz == 12) { + if (info.bpp < 24) + psize = (info.offset - info.extra_read - 24) / 3; + } else { + if (info.bpp < 16) + psize = (info.offset - info.extra_read - info.hsz) >> 2; + } + if (psize == 0) { + if (info.offset != s->callback_already_read + (s->img_buffer - s->img_buffer_original)) { + return stbi__errpuc("bad offset", "Corrupt BMP"); + } + } + + if (info.bpp == 24 && ma == 0xff000000) + s->img_n = 3; + else + s->img_n = ma ? 4 : 3; + if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 + target = req_comp; + else + target = s->img_n; // if they want monochrome, we'll post-convert + + // sanity-check size + if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) + return stbi__errpuc("too large", "Corrupt BMP"); + + out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + if (info.bpp < 16) { + int z=0; + if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } + for (i=0; i < psize; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + if (info.hsz != 12) stbi__get8(s); + pal[i][3] = 255; + } + stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); + if (info.bpp == 1) width = (s->img_x + 7) >> 3; + else if (info.bpp == 4) width = (s->img_x + 1) >> 1; + else if (info.bpp == 8) width = s->img_x; + else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } + pad = (-width)&3; + if (info.bpp == 1) { + for (j=0; j < (int) s->img_y; ++j) { + int bit_offset = 7, v = stbi__get8(s); + for (i=0; i < (int) s->img_x; ++i) { + int color = (v>>bit_offset)&0x1; + out[z++] = pal[color][0]; + out[z++] = pal[color][1]; + out[z++] = pal[color][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + if((--bit_offset) < 0) { + bit_offset = 7; + v = stbi__get8(s); + } + } + stbi__skip(s, pad); + } + } else { + for (j=0; j < (int) s->img_y; ++j) { + for (i=0; i < (int) s->img_x; i += 2) { + int v=stbi__get8(s),v2=0; + if (info.bpp == 4) { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + v = (info.bpp == 8) ? stbi__get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + } + stbi__skip(s, pad); + } + } + } else { + int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; + int z = 0; + int easy=0; + stbi__skip(s, info.offset - info.extra_read - info.hsz); + if (info.bpp == 24) width = 3 * s->img_x; + else if (info.bpp == 16) width = 2*s->img_x; + else /* bpp = 32 and pad = 0 */ width=0; + pad = (-width) & 3; + if (info.bpp == 24) { + easy = 1; + } else if (info.bpp == 32) { + if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) + easy = 2; + } + if (!easy) { + if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } + // right shift amt to put high bit in position #7 + rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr); + gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); + bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); + ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); + if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } + } + for (j=0; j < (int) s->img_y; ++j) { + if (easy) { + for (i=0; i < (int) s->img_x; ++i) { + unsigned char a; + out[z+2] = stbi__get8(s); + out[z+1] = stbi__get8(s); + out[z+0] = stbi__get8(s); + z += 3; + a = (easy == 2 ? stbi__get8(s) : 255); + all_a |= a; + if (target == 4) out[z++] = a; + } + } else { + int bpp = info.bpp; + for (i=0; i < (int) s->img_x; ++i) { + stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); + unsigned int a; + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); + a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); + all_a |= a; + if (target == 4) out[z++] = STBI__BYTECAST(a); + } + } + stbi__skip(s, pad); + } + } + + // if alpha channel is all 0s, replace with all 255s + if (target == 4 && all_a == 0) + for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) + out[i] = 255; + + if (flip_vertically) { + stbi_uc t; + for (j=0; j < (int) s->img_y>>1; ++j) { + stbi_uc *p1 = out + j *s->img_x*target; + stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; + for (i=0; i < (int) s->img_x*target; ++i) { + t = p1[i]; p1[i] = p2[i]; p2[i] = t; + } + } + } + + if (req_comp && req_comp != target) { + out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + return out; +} +#endif + +// Targa Truevision - TGA +// by Jonathan Dummer +#ifndef STBI_NO_TGA +// returns STBI_rgb or whatever, 0 on error +static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) +{ + // only RGB or RGBA (incl. 16bit) or grey allowed + if (is_rgb16) *is_rgb16 = 0; + switch(bits_per_pixel) { + case 8: return STBI_grey; + case 16: if(is_grey) return STBI_grey_alpha; + // fallthrough + case 15: if(is_rgb16) *is_rgb16 = 1; + return STBI_rgb; + case 24: // fallthrough + case 32: return bits_per_pixel/8; + default: return 0; + } +} + +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) +{ + int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; + int sz, tga_colormap_type; + stbi__get8(s); // discard Offset + tga_colormap_type = stbi__get8(s); // colormap type + if( tga_colormap_type > 1 ) { + stbi__rewind(s); + return 0; // only RGB or indexed allowed + } + tga_image_type = stbi__get8(s); // image type + if ( tga_colormap_type == 1 ) { // colormapped (paletted) image + if (tga_image_type != 1 && tga_image_type != 9) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip image x and y origin + tga_colormap_bpp = sz; + } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE + if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) { + stbi__rewind(s); + return 0; // only RGB or grey allowed, +/- RLE + } + stbi__skip(s,9); // skip colormap specification and image x/y origin + tga_colormap_bpp = 0; + } + tga_w = stbi__get16le(s); + if( tga_w < 1 ) { + stbi__rewind(s); + return 0; // test width + } + tga_h = stbi__get16le(s); + if( tga_h < 1 ) { + stbi__rewind(s); + return 0; // test height + } + tga_bits_per_pixel = stbi__get8(s); // bits per pixel + stbi__get8(s); // ignore alpha bits + if (tga_colormap_bpp != 0) { + if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { + // when using a colormap, tga_bits_per_pixel is the size of the indexes + // I don't think anything but 8 or 16bit indexes makes sense + stbi__rewind(s); + return 0; + } + tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); + } else { + tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); + } + if(!tga_comp) { + stbi__rewind(s); + return 0; + } + if (x) *x = tga_w; + if (y) *y = tga_h; + if (comp) *comp = tga_comp; + return 1; // seems to have passed everything +} + +static int stbi__tga_test(stbi__context *s) +{ + int res = 0; + int sz, tga_color_type; + stbi__get8(s); // discard Offset + tga_color_type = stbi__get8(s); // color type + if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed + sz = stbi__get8(s); // image type + if ( tga_color_type == 1 ) { // colormapped (paletted) image + if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + stbi__skip(s,4); // skip image x and y origin + } else { // "normal" image w/o colormap + if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE + stbi__skip(s,9); // skip colormap specification and image x/y origin + } + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height + sz = stbi__get8(s); // bits per pixel + if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + + res = 1; // if we got this far, everything's good and we can return 1 instead of 0 + +errorEnd: + stbi__rewind(s); + return res; +} + +// read 16bit value and convert to 24bit RGB +static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) +{ + stbi__uint16 px = (stbi__uint16)stbi__get16le(s); + stbi__uint16 fiveBitMask = 31; + // we have 3 channels with 5bits each + int r = (px >> 10) & fiveBitMask; + int g = (px >> 5) & fiveBitMask; + int b = px & fiveBitMask; + // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later + out[0] = (stbi_uc)((r * 255)/31); + out[1] = (stbi_uc)((g * 255)/31); + out[2] = (stbi_uc)((b * 255)/31); + + // some people claim that the most significant bit might be used for alpha + // (possibly if an alpha-bit is set in the "image descriptor byte") + // but that only made 16bit test images completely translucent.. + // so let's treat all 15 and 16bit TGAs as RGB with no alpha. +} + +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + // read in the TGA header stuff + int tga_offset = stbi__get8(s); + int tga_indexed = stbi__get8(s); + int tga_image_type = stbi__get8(s); + int tga_is_RLE = 0; + int tga_palette_start = stbi__get16le(s); + int tga_palette_len = stbi__get16le(s); + int tga_palette_bits = stbi__get8(s); + int tga_x_origin = stbi__get16le(s); + int tga_y_origin = stbi__get16le(s); + int tga_width = stbi__get16le(s); + int tga_height = stbi__get16le(s); + int tga_bits_per_pixel = stbi__get8(s); + int tga_comp, tga_rgb16=0; + int tga_inverted = stbi__get8(s); + // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) + // image data + unsigned char *tga_data; + unsigned char *tga_palette = NULL; + int i, j; + unsigned char raw_data[4] = {0}; + int RLE_count = 0; + int RLE_repeating = 0; + int read_next_pixel = 1; + STBI_NOTUSED(ri); + STBI_NOTUSED(tga_x_origin); // @TODO + STBI_NOTUSED(tga_y_origin); // @TODO + + if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + // do a tiny bit of precessing + if ( tga_image_type >= 8 ) + { + tga_image_type -= 8; + tga_is_RLE = 1; + } + tga_inverted = 1 - ((tga_inverted >> 5) & 1); + + // If I'm paletted, then I'll use the number of bits from the palette + if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); + else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); + + if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency + return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); + + // tga info + *x = tga_width; + *y = tga_height; + if (comp) *comp = tga_comp; + + if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) + return stbi__errpuc("too large", "Corrupt TGA"); + + tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); + if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); + + // skip to the data's starting position (offset usually = 0) + stbi__skip(s, tga_offset ); + + if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) { + for (i=0; i < tga_height; ++i) { + int row = tga_inverted ? tga_height -i - 1 : i; + stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; + stbi__getn(s, tga_row, tga_width * tga_comp); + } + } else { + // do I need to load a palette? + if ( tga_indexed) + { + if (tga_palette_len == 0) { /* you have to have at least one entry! */ + STBI_FREE(tga_data); + return stbi__errpuc("bad palette", "Corrupt TGA"); + } + + // any data to skip? (offset usually = 0) + stbi__skip(s, tga_palette_start ); + // load the palette + tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); + if (!tga_palette) { + STBI_FREE(tga_data); + return stbi__errpuc("outofmem", "Out of memory"); + } + if (tga_rgb16) { + stbi_uc *pal_entry = tga_palette; + STBI_ASSERT(tga_comp == STBI_rgb); + for (i=0; i < tga_palette_len; ++i) { + stbi__tga_read_rgb16(s, pal_entry); + pal_entry += tga_comp; + } + } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { + STBI_FREE(tga_data); + STBI_FREE(tga_palette); + return stbi__errpuc("bad palette", "Corrupt TGA"); + } + } + // load the data + for (i=0; i < tga_width * tga_height; ++i) + { + // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? + if ( tga_is_RLE ) + { + if ( RLE_count == 0 ) + { + // yep, get the next byte as a RLE command + int RLE_cmd = stbi__get8(s); + RLE_count = 1 + (RLE_cmd & 127); + RLE_repeating = RLE_cmd >> 7; + read_next_pixel = 1; + } else if ( !RLE_repeating ) + { + read_next_pixel = 1; + } + } else + { + read_next_pixel = 1; + } + // OK, if I need to read a pixel, do it now + if ( read_next_pixel ) + { + // load however much data we did have + if ( tga_indexed ) + { + // read in index, then perform the lookup + int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); + if ( pal_idx >= tga_palette_len ) { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_comp; + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = tga_palette[pal_idx+j]; + } + } else if(tga_rgb16) { + STBI_ASSERT(tga_comp == STBI_rgb); + stbi__tga_read_rgb16(s, raw_data); + } else { + // read in the data raw + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = stbi__get8(s); + } + } + // clear the reading flag for the next pixel + read_next_pixel = 0; + } // end of reading a pixel + + // copy data + for (j = 0; j < tga_comp; ++j) + tga_data[i*tga_comp+j] = raw_data[j]; + + // in case we're in RLE mode, keep counting down + --RLE_count; + } + // do I need to invert the image? + if ( tga_inverted ) + { + for (j = 0; j*2 < tga_height; ++j) + { + int index1 = j * tga_width * tga_comp; + int index2 = (tga_height - 1 - j) * tga_width * tga_comp; + for (i = tga_width * tga_comp; i > 0; --i) + { + unsigned char temp = tga_data[index1]; + tga_data[index1] = tga_data[index2]; + tga_data[index2] = temp; + ++index1; + ++index2; + } + } + } + // clear my palette, if I had one + if ( tga_palette != NULL ) + { + STBI_FREE( tga_palette ); + } + } + + // swap RGB - if the source data was RGB16, it already is in the right order + if (tga_comp >= 3 && !tga_rgb16) + { + unsigned char* tga_pixel = tga_data; + for (i=0; i < tga_width * tga_height; ++i) + { + unsigned char temp = tga_pixel[0]; + tga_pixel[0] = tga_pixel[2]; + tga_pixel[2] = temp; + tga_pixel += tga_comp; + } + } + + // convert to target component count + if (req_comp && req_comp != tga_comp) + tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); + + // the things I do to get rid of an error message, and yet keep + // Microsoft's C compilers happy... [8^( + tga_palette_start = tga_palette_len = tga_palette_bits = + tga_x_origin = tga_y_origin = 0; + STBI_NOTUSED(tga_palette_start); + // OK, done + return tga_data; +} +#endif + +// ************************************************************************************************* +// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s) +{ + int r = (stbi__get32be(s) == 0x38425053); + stbi__rewind(s); + return r; +} + +static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount) +{ + int count, nleft, len; + + count = 0; + while ((nleft = pixelCount - count) > 0) { + len = stbi__get8(s); + if (len == 128) { + // No-op. + } else if (len < 128) { + // Copy next len+1 bytes literally. + len++; + if (len > nleft) return 0; // corrupt data + count += len; + while (len) { + *p = stbi__get8(s); + p += 4; + len--; + } + } else if (len > 128) { + stbi_uc val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len = 257 - len; + if (len > nleft) return 0; // corrupt data + val = stbi__get8(s); + count += len; + while (len) { + *p = val; + p += 4; + len--; + } + } + } + + return 1; +} + +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) +{ + int pixelCount; + int channelCount, compression; + int channel, i; + int bitdepth; + int w,h; + stbi_uc *out; + STBI_NOTUSED(ri); + + // Check identifier + if (stbi__get32be(s) != 0x38425053) // "8BPS" + return stbi__errpuc("not PSD", "Corrupt PSD image"); + + // Check file type version. + if (stbi__get16be(s) != 1) + return stbi__errpuc("wrong version", "Unsupported version of PSD image"); + + // Skip 6 reserved bytes. + stbi__skip(s, 6 ); + + // Read the number of channels (R, G, B, A, etc). + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) + return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); + + // Read the rows and columns of the image. + h = stbi__get32be(s); + w = stbi__get32be(s); + + if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + // Make sure the depth is 8 bits. + bitdepth = stbi__get16be(s); + if (bitdepth != 8 && bitdepth != 16) + return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); + + // Make sure the color mode is RGB. + // Valid options are: + // 0: Bitmap + // 1: Grayscale + // 2: Indexed color + // 3: RGB color + // 4: CMYK color + // 7: Multichannel + // 8: Duotone + // 9: Lab color + if (stbi__get16be(s) != 3) + return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); + + // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) + stbi__skip(s,stbi__get32be(s) ); + + // Skip the image resources. (resolution, pen tool paths, etc) + stbi__skip(s, stbi__get32be(s) ); + + // Skip the reserved data. + stbi__skip(s, stbi__get32be(s) ); + + // Find out if the data is compressed. + // Known values: + // 0: no compression + // 1: RLE compressed + compression = stbi__get16be(s); + if (compression > 1) + return stbi__errpuc("bad compression", "PSD has an unknown compression format"); + + // Check size + if (!stbi__mad3sizes_valid(4, w, h, 0)) + return stbi__errpuc("too large", "Corrupt PSD"); + + // Create the destination image. + + if (!compression && bitdepth == 16 && bpc == 16) { + out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); + ri->bits_per_channel = 16; + } else + out = (stbi_uc *) stbi__malloc(4 * w*h); + + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + pixelCount = w*h; + + // Initialize the data to zero. + //memset( out, 0, pixelCount * 4 ); + + // Finally, the image data. + if (compression) { + // RLE as used by .PSD and .TIFF + // Loop until you get the number of unpacked bytes you are expecting: + // Read the next source byte into n. + // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. + // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. + // Else if n is 128, noop. + // Endloop + + // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, + // which we're going to just skip. + stbi__skip(s, h * channelCount * 2 ); + + // Read the RLE data by channel. + for (channel = 0; channel < 4; channel++) { + stbi_uc *p; + + p = out+channel; + if (channel >= channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++, p += 4) + *p = (channel == 3 ? 255 : 0); + } else { + // Read the RLE data. + if (!stbi__psd_decode_rle(s, p, pixelCount)) { + STBI_FREE(out); + return stbi__errpuc("corrupt", "bad RLE data"); + } + } + } + + } else { + // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) + // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. + + // Read the data by channel. + for (channel = 0; channel < 4; channel++) { + if (channel >= channelCount) { + // Fill this channel with default data. + if (bitdepth == 16 && bpc == 16) { + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + stbi__uint16 val = channel == 3 ? 65535 : 0; + for (i = 0; i < pixelCount; i++, q += 4) + *q = val; + } else { + stbi_uc *p = out+channel; + stbi_uc val = channel == 3 ? 255 : 0; + for (i = 0; i < pixelCount; i++, p += 4) + *p = val; + } + } else { + if (ri->bits_per_channel == 16) { // output bpc + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + for (i = 0; i < pixelCount; i++, q += 4) + *q = (stbi__uint16) stbi__get16be(s); + } else { + stbi_uc *p = out+channel; + if (bitdepth == 16) { // input bpc + for (i = 0; i < pixelCount; i++, p += 4) + *p = (stbi_uc) (stbi__get16be(s) >> 8); + } else { + for (i = 0; i < pixelCount; i++, p += 4) + *p = stbi__get8(s); + } + } + } + } + } + + // remove weird white matte from PSD + if (channelCount >= 4) { + if (ri->bits_per_channel == 16) { + for (i=0; i < w*h; ++i) { + stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i; + if (pixel[3] != 0 && pixel[3] != 65535) { + float a = pixel[3] / 65535.0f; + float ra = 1.0f / a; + float inv_a = 65535.0f * (1 - ra); + pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a); + pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a); + pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a); + } + } + } else { + for (i=0; i < w*h; ++i) { + unsigned char *pixel = out + 4*i; + if (pixel[3] != 0 && pixel[3] != 255) { + float a = pixel[3] / 255.0f; + float ra = 1.0f / a; + float inv_a = 255.0f * (1 - ra); + pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); + pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); + pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); + } + } + } + } + + // convert to desired output format + if (req_comp && req_comp != 4) { + if (ri->bits_per_channel == 16) + out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h); + else + out = stbi__convert_format(out, 4, req_comp, w, h); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + if (comp) *comp = 4; + *y = h; + *x = w; + + return out; +} +#endif + +// ************************************************************************************************* +// Softimage PIC loader +// by Tom Seddon +// +// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format +// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ + +#ifndef STBI_NO_PIC +static int stbi__pic_is4(stbi__context *s,const char *str) +{ + int i; + for (i=0; i<4; ++i) + if (stbi__get8(s) != (stbi_uc)str[i]) + return 0; + + return 1; +} + +static int stbi__pic_test_core(stbi__context *s) +{ + int i; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) + return 0; + + for(i=0;i<84;++i) + stbi__get8(s); + + if (!stbi__pic_is4(s,"PICT")) + return 0; + + return 1; +} + +typedef struct +{ + stbi_uc size,type,channel; +} stbi__pic_packet; + +static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) +{ + int mask=0x80, i; + + for (i=0; i<4; ++i, mask>>=1) { + if (channel & mask) { + if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short"); + dest[i]=stbi__get8(s); + } + } + + return dest; +} + +static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src) +{ + int mask=0x80,i; + + for (i=0;i<4; ++i, mask>>=1) + if (channel&mask) + dest[i]=src[i]; +} + +static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result) +{ + int act_comp=0,num_packets=0,y,chained; + stbi__pic_packet packets[10]; + + // this will (should...) cater for even some bizarre stuff like having data + // for the same channel in multiple packets. + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return stbi__errpuc("bad format","too many packets"); + + packet = &packets[num_packets++]; + + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + + act_comp |= packet->channel; + + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)"); + if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp"); + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? + + for(y=0; ytype) { + default: + return stbi__errpuc("bad format","packet has bad compression type"); + + case 0: {//uncompressed + int x; + + for(x=0;xchannel,dest)) + return 0; + break; + } + + case 1://Pure RLE + { + int left=width, i; + + while (left>0) { + stbi_uc count,value[4]; + + count=stbi__get8(s); + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)"); + + if (count > left) + count = (stbi_uc) left; + + if (!stbi__readval(s,packet->channel,value)) return 0; + + for(i=0; ichannel,dest,value); + left -= count; + } + } + break; + + case 2: {//Mixed RLE + int left=width; + while (left>0) { + int count = stbi__get8(s), i; + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)"); + + if (count >= 128) { // Repeated + stbi_uc value[4]; + + if (count==128) + count = stbi__get16be(s); + else + count -= 127; + if (count > left) + return stbi__errpuc("bad file","scanline overrun"); + + if (!stbi__readval(s,packet->channel,value)) + return 0; + + for(i=0;ichannel,dest,value); + } else { // Raw + ++count; + if (count>left) return stbi__errpuc("bad file","scanline overrun"); + + for(i=0;ichannel,dest)) + return 0; + } + left-=count; + } + break; + } + } + } + } + + return result; +} + +static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri) +{ + stbi_uc *result; + int i, x,y, internal_comp; + STBI_NOTUSED(ri); + + if (!comp) comp = &internal_comp; + + for (i=0; i<92; ++i) + stbi__get8(s); + + x = stbi__get16be(s); + y = stbi__get16be(s); + + if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); + if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); + + stbi__get32be(s); //skip `ratio' + stbi__get16be(s); //skip `fields' + stbi__get16be(s); //skip `pad' + + // intermediate buffer is RGBA + result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); + if (!result) return stbi__errpuc("outofmem", "Out of memory"); + memset(result, 0xff, x*y*4); + + if (!stbi__pic_load_core(s,x,y,comp, result)) { + STBI_FREE(result); + result=0; + } + *px = x; + *py = y; + if (req_comp == 0) req_comp = *comp; + result=stbi__convert_format(result,4,req_comp,x,y); + + return result; +} + +static int stbi__pic_test(stbi__context *s) +{ + int r = stbi__pic_test_core(s); + stbi__rewind(s); + return r; +} +#endif + +// ************************************************************************************************* +// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb + +#ifndef STBI_NO_GIF +typedef struct +{ + stbi__int16 prefix; + stbi_uc first; + stbi_uc suffix; +} stbi__gif_lzw; + +typedef struct +{ + int w,h; + stbi_uc *out; // output buffer (always 4 components) + stbi_uc *background; // The current "background" as far as a gif is concerned + stbi_uc *history; + int flags, bgindex, ratio, transparent, eflags; + stbi_uc pal[256][4]; + stbi_uc lpal[256][4]; + stbi__gif_lzw codes[8192]; + stbi_uc *color_table; + int parse, step; + int lflags; + int start_x, start_y; + int max_x, max_y; + int cur_x, cur_y; + int line_size; + int delay; +} stbi__gif; + +static int stbi__gif_test_raw(stbi__context *s) +{ + int sz; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; + sz = stbi__get8(s); + if (sz != '9' && sz != '7') return 0; + if (stbi__get8(s) != 'a') return 0; + return 1; +} + +static int stbi__gif_test(stbi__context *s) +{ + int r = stbi__gif_test_raw(s); + stbi__rewind(s); + return r; +} + +static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) +{ + int i; + for (i=0; i < num_entries; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + pal[i][3] = transp == i ? 0 : 255; + } +} + +static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) +{ + stbi_uc version; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') + return stbi__err("not GIF", "Corrupt GIF"); + + version = stbi__get8(s); + if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); + if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); + + stbi__g_failure_reason = ""; + g->w = stbi__get16le(s); + g->h = stbi__get16le(s); + g->flags = stbi__get8(s); + g->bgindex = stbi__get8(s); + g->ratio = stbi__get8(s); + g->transparent = -1; + + if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + + if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + + if (is_info) return 1; + + if (g->flags & 0x80) + stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); + + return 1; +} + +static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); + if (!g) return stbi__err("outofmem", "Out of memory"); + if (!stbi__gif_header(s, g, comp, 1)) { + STBI_FREE(g); + stbi__rewind( s ); + return 0; + } + if (x) *x = g->w; + if (y) *y = g->h; + STBI_FREE(g); + return 1; +} + +static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) +{ + stbi_uc *p, *c; + int idx; + + // recurse to decode the prefixes, since the linked-list is backwards, + // and working backwards through an interleaved image would be nasty + if (g->codes[code].prefix >= 0) + stbi__out_gif_code(g, g->codes[code].prefix); + + if (g->cur_y >= g->max_y) return; + + idx = g->cur_x + g->cur_y; + p = &g->out[idx]; + g->history[idx / 4] = 1; + + c = &g->color_table[g->codes[code].suffix * 4]; + if (c[3] > 128) { // don't render transparent pixels; + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } + g->cur_x += 4; + + if (g->cur_x >= g->max_x) { + g->cur_x = g->start_x; + g->cur_y += g->step; + + while (g->cur_y >= g->max_y && g->parse > 0) { + g->step = (1 << g->parse) * g->line_size; + g->cur_y = g->start_y + (g->step >> 1); + --g->parse; + } + } +} + +static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) +{ + stbi_uc lzw_cs; + stbi__int32 len, init_code; + stbi__uint32 first; + stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; + stbi__gif_lzw *p; + + lzw_cs = stbi__get8(s); + if (lzw_cs > 12) return NULL; + clear = 1 << lzw_cs; + first = 1; + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + bits = 0; + valid_bits = 0; + for (init_code = 0; init_code < clear; init_code++) { + g->codes[init_code].prefix = -1; + g->codes[init_code].first = (stbi_uc) init_code; + g->codes[init_code].suffix = (stbi_uc) init_code; + } + + // support no starting clear code + avail = clear+2; + oldcode = -1; + + len = 0; + for(;;) { + if (valid_bits < codesize) { + if (len == 0) { + len = stbi__get8(s); // start new block + if (len == 0) + return g->out; + } + --len; + bits |= (stbi__int32) stbi__get8(s) << valid_bits; + valid_bits += 8; + } else { + stbi__int32 code = bits & codemask; + bits >>= codesize; + valid_bits -= codesize; + // @OPTIMIZE: is there some way we can accelerate the non-clear path? + if (code == clear) { // clear code + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + first = 0; + } else if (code == clear + 1) { // end of stream code + stbi__skip(s, len); + while ((len = stbi__get8(s)) > 0) + stbi__skip(s,len); + return g->out; + } else if (code <= avail) { + if (first) { + return stbi__errpuc("no clear code", "Corrupt GIF"); + } + + if (oldcode >= 0) { + p = &g->codes[avail++]; + if (avail > 8192) { + return stbi__errpuc("too many codes", "Corrupt GIF"); + } + + p->prefix = (stbi__int16) oldcode; + p->first = g->codes[oldcode].first; + p->suffix = (code == avail) ? p->first : g->codes[code].first; + } else if (code == avail) + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + + stbi__out_gif_code(g, (stbi__uint16) code); + + if ((avail & codemask) == 0 && avail <= 0x0FFF) { + codesize++; + codemask = (1 << codesize) - 1; + } + + oldcode = code; + } else { + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + } + } + } +} + +// this function is designed to support animated gifs, although stb_image doesn't support it +// two back is the image from two frames ago, used for a very specific disposal format +static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back) +{ + int dispose; + int first_frame; + int pi; + int pcount; + STBI_NOTUSED(req_comp); + + // on first frame, any non-written pixels get the background colour (non-transparent) + first_frame = 0; + if (g->out == 0) { + if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header + if (!stbi__mad3sizes_valid(4, g->w, g->h, 0)) + return stbi__errpuc("too large", "GIF image is too large"); + pcount = g->w * g->h; + g->out = (stbi_uc *) stbi__malloc(4 * pcount); + g->background = (stbi_uc *) stbi__malloc(4 * pcount); + g->history = (stbi_uc *) stbi__malloc(pcount); + if (!g->out || !g->background || !g->history) + return stbi__errpuc("outofmem", "Out of memory"); + + // image is treated as "transparent" at the start - ie, nothing overwrites the current background; + // background colour is only used for pixels that are not rendered first frame, after that "background" + // color refers to the color that was there the previous frame. + memset(g->out, 0x00, 4 * pcount); + memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent) + memset(g->history, 0x00, pcount); // pixels that were affected previous frame + first_frame = 1; + } else { + // second frame - how do we dispose of the previous one? + dispose = (g->eflags & 0x1C) >> 2; + pcount = g->w * g->h; + + if ((dispose == 3) && (two_back == 0)) { + dispose = 2; // if I don't have an image to revert back to, default to the old background + } + + if (dispose == 3) { // use previous graphic + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi]) { + memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 ); + } + } + } else if (dispose == 2) { + // restore what was changed last frame to background before that frame; + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi]) { + memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 ); + } + } + } else { + // This is a non-disposal case eithe way, so just + // leave the pixels as is, and they will become the new background + // 1: do not dispose + // 0: not specified. + } + + // background is what out is after the undoing of the previou frame; + memcpy( g->background, g->out, 4 * g->w * g->h ); + } + + // clear my history; + memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame + + for (;;) { + int tag = stbi__get8(s); + switch (tag) { + case 0x2C: /* Image Descriptor */ + { + stbi__int32 x, y, w, h; + stbi_uc *o; + + x = stbi__get16le(s); + y = stbi__get16le(s); + w = stbi__get16le(s); + h = stbi__get16le(s); + if (((x + w) > (g->w)) || ((y + h) > (g->h))) + return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); + + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; + + // if the width of the specified rectangle is 0, that means + // we may not see *any* pixels or the image is malformed; + // to make sure this is caught, move the current y down to + // max_y (which is what out_gif_code checks). + if (w == 0) + g->cur_y = g->max_y; + + g->lflags = stbi__get8(s); + + if (g->lflags & 0x40) { + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } else { + g->step = g->line_size; + g->parse = 0; + } + + if (g->lflags & 0x80) { + stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (stbi_uc *) g->lpal; + } else if (g->flags & 0x80) { + g->color_table = (stbi_uc *) g->pal; + } else + return stbi__errpuc("missing color table", "Corrupt GIF"); + + o = stbi__process_gif_raster(s, g); + if (!o) return NULL; + + // if this was the first frame, + pcount = g->w * g->h; + if (first_frame && (g->bgindex > 0)) { + // if first frame, any pixel not drawn to gets the background color + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi] == 0) { + g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; + memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 ); + } + } + } + + return o; + } + + case 0x21: // Comment Extension. + { + int len; + int ext = stbi__get8(s); + if (ext == 0xF9) { // Graphic Control Extension. + len = stbi__get8(s); + if (len == 4) { + g->eflags = stbi__get8(s); + g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. + + // unset old transparent + if (g->transparent >= 0) { + g->pal[g->transparent][3] = 255; + } + if (g->eflags & 0x01) { + g->transparent = stbi__get8(s); + if (g->transparent >= 0) { + g->pal[g->transparent][3] = 0; + } + } else { + // don't need transparent + stbi__skip(s, 1); + g->transparent = -1; + } + } else { + stbi__skip(s, len); + break; + } + } + while ((len = stbi__get8(s)) != 0) { + stbi__skip(s, len); + } + break; + } + + case 0x3B: // gif stream termination code + return (stbi_uc *) s; // using '1' causes warning on some compilers + + default: + return stbi__errpuc("unknown code", "Corrupt GIF"); + } + } +} + +static void *stbi__load_gif_main_outofmem(stbi__gif *g, stbi_uc *out, int **delays) +{ + STBI_FREE(g->out); + STBI_FREE(g->history); + STBI_FREE(g->background); + + if (out) STBI_FREE(out); + if (delays && *delays) STBI_FREE(*delays); + return stbi__errpuc("outofmem", "Out of memory"); +} + +static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) +{ + if (stbi__gif_test(s)) { + int layers = 0; + stbi_uc *u = 0; + stbi_uc *out = 0; + stbi_uc *two_back = 0; + stbi__gif g; + int stride; + int out_size = 0; + int delays_size = 0; + + STBI_NOTUSED(out_size); + STBI_NOTUSED(delays_size); + + memset(&g, 0, sizeof(g)); + if (delays) { + *delays = 0; + } + + do { + u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + + if (u) { + *x = g.w; + *y = g.h; + ++layers; + stride = g.w * g.h * 4; + + if (out) { + void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride ); + if (!tmp) + return stbi__load_gif_main_outofmem(&g, out, delays); + else { + out = (stbi_uc*) tmp; + out_size = layers * stride; + } + + if (delays) { + int *new_delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers ); + if (!new_delays) + return stbi__load_gif_main_outofmem(&g, out, delays); + *delays = new_delays; + delays_size = layers * sizeof(int); + } + } else { + out = (stbi_uc*)stbi__malloc( layers * stride ); + if (!out) + return stbi__load_gif_main_outofmem(&g, out, delays); + out_size = layers * stride; + if (delays) { + *delays = (int*) stbi__malloc( layers * sizeof(int) ); + if (!*delays) + return stbi__load_gif_main_outofmem(&g, out, delays); + delays_size = layers * sizeof(int); + } + } + memcpy( out + ((layers - 1) * stride), u, stride ); + if (layers >= 2) { + two_back = out - 2 * stride; + } + + if (delays) { + (*delays)[layers - 1U] = g.delay; + } + } + } while (u != 0); + + // free temp buffer; + STBI_FREE(g.out); + STBI_FREE(g.history); + STBI_FREE(g.background); + + // do the final conversion after loading everything; + if (req_comp && req_comp != 4) + out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h); + + *z = layers; + return out; + } else { + return stbi__errpuc("not GIF", "Image was not as a gif type."); + } +} + +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *u = 0; + stbi__gif g; + memset(&g, 0, sizeof(g)); + STBI_NOTUSED(ri); + + u = stbi__gif_load_next(s, &g, comp, req_comp, 0); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + if (u) { + *x = g.w; + *y = g.h; + + // moved conversion to after successful load so that the same + // can be done for multiple frames. + if (req_comp && req_comp != 4) + u = stbi__convert_format(u, 4, req_comp, g.w, g.h); + } else if (g.out) { + // if there was an error and we allocated an image buffer, free it! + STBI_FREE(g.out); + } + + // free buffers needed for multiple frame loading; + STBI_FREE(g.history); + STBI_FREE(g.background); + + return u; +} + +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) +{ + return stbi__gif_info_raw(s,x,y,comp); +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR loader +// originally by Nicolas Schulz +#ifndef STBI_NO_HDR +static int stbi__hdr_test_core(stbi__context *s, const char *signature) +{ + int i; + for (i=0; signature[i]; ++i) + if (stbi__get8(s) != signature[i]) + return 0; + stbi__rewind(s); + return 1; +} + +static int stbi__hdr_test(stbi__context* s) +{ + int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); + stbi__rewind(s); + if(!r) { + r = stbi__hdr_test_core(s, "#?RGBE\n"); + stbi__rewind(s); + } + return r; +} + +#define STBI__HDR_BUFLEN 1024 +static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) +{ + int len=0; + char c = '\0'; + + c = (char) stbi__get8(z); + + while (!stbi__at_eof(z) && c != '\n') { + buffer[len++] = c; + if (len == STBI__HDR_BUFLEN-1) { + // flush to end of line + while (!stbi__at_eof(z) && stbi__get8(z) != '\n') + ; + break; + } + c = (char) stbi__get8(z); + } + + buffer[len] = 0; + return buffer; +} + +static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) +{ + if ( input[3] != 0 ) { + float f1; + // Exponent + f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); + if (req_comp <= 2) + output[0] = (input[0] + input[1] + input[2]) * f1 / 3; + else { + output[0] = input[0] * f1; + output[1] = input[1] * f1; + output[2] = input[2] * f1; + } + if (req_comp == 2) output[1] = 1; + if (req_comp == 4) output[3] = 1; + } else { + switch (req_comp) { + case 4: output[3] = 1; /* fallthrough */ + case 3: output[0] = output[1] = output[2] = 0; + break; + case 2: output[1] = 1; /* fallthrough */ + case 1: output[0] = 0; + break; + } + } +} + +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + int width, height; + stbi_uc *scanline; + float *hdr_data; + int len; + unsigned char count, value; + int i, j, k, c1,c2, z; + const char *headerToken; + STBI_NOTUSED(ri); + + // Check identifier + headerToken = stbi__hdr_gettoken(s,buffer); + if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) + return stbi__errpf("not HDR", "Corrupt HDR image"); + + // Parse header + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); + + // Parse width and height + // can't use sscanf() if we're not using stdio! + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + height = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + width = (int) strtol(token, NULL, 10); + + if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); + if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); + + *x = width; + *y = height; + + if (comp) *comp = 3; + if (req_comp == 0) req_comp = 3; + + if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) + return stbi__errpf("too large", "HDR image is too large"); + + // Read data + hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); + if (!hdr_data) + return stbi__errpf("outofmem", "Out of memory"); + + // Load image data + // image data is stored as some number of sca + if ( width < 8 || width >= 32768) { + // Read flat data + for (j=0; j < height; ++j) { + for (i=0; i < width; ++i) { + stbi_uc rgbe[4]; + main_decode_loop: + stbi__getn(s, rgbe, 4); + stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); + } + } + } else { + // Read RLE-encoded data + scanline = NULL; + + for (j = 0; j < height; ++j) { + c1 = stbi__get8(s); + c2 = stbi__get8(s); + len = stbi__get8(s); + if (c1 != 2 || c2 != 2 || (len & 0x80)) { + // not run-length encoded, so we have to actually use THIS data as a decoded + // pixel (note this can't be a valid pixel--one of RGB must be >= 128) + stbi_uc rgbe[4]; + rgbe[0] = (stbi_uc) c1; + rgbe[1] = (stbi_uc) c2; + rgbe[2] = (stbi_uc) len; + rgbe[3] = (stbi_uc) stbi__get8(s); + stbi__hdr_convert(hdr_data, rgbe, req_comp); + i = 1; + j = 0; + STBI_FREE(scanline); + goto main_decode_loop; // yes, this makes no sense + } + len <<= 8; + len |= stbi__get8(s); + if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } + if (scanline == NULL) { + scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0); + if (!scanline) { + STBI_FREE(hdr_data); + return stbi__errpf("outofmem", "Out of memory"); + } + } + + for (k = 0; k < 4; ++k) { + int nleft; + i = 0; + while ((nleft = width - i) > 0) { + count = stbi__get8(s); + if (count > 128) { + // Run + value = stbi__get8(s); + count -= 128; + if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = value; + } else { + // Dump + if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = stbi__get8(s); + } + } + } + for (i=0; i < width; ++i) + stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); + } + if (scanline) + STBI_FREE(scanline); + } + + return hdr_data; +} + +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + int dummy; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + if (stbi__hdr_test(s) == 0) { + stbi__rewind( s ); + return 0; + } + + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) { + stbi__rewind( s ); + return 0; + } + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *y = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *x = (int) strtol(token, NULL, 10); + *comp = 3; + return 1; +} +#endif // STBI_NO_HDR + +#ifndef STBI_NO_BMP +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) +{ + void *p; + stbi__bmp_data info; + + info.all_a = 255; + p = stbi__bmp_parse_header(s, &info); + if (p == NULL) { + stbi__rewind( s ); + return 0; + } + if (x) *x = s->img_x; + if (y) *y = s->img_y; + if (comp) { + if (info.bpp == 24 && info.ma == 0xff000000) + *comp = 3; + else + *comp = info.ma ? 4 : 3; + } + return 1; +} +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) +{ + int channelCount, dummy, depth; + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + *y = stbi__get32be(s); + *x = stbi__get32be(s); + depth = stbi__get16be(s); + if (depth != 8 && depth != 16) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 3) { + stbi__rewind( s ); + return 0; + } + *comp = 4; + return 1; +} + +static int stbi__psd_is16(stbi__context *s) +{ + int channelCount, depth; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + STBI_NOTUSED(stbi__get32be(s)); + STBI_NOTUSED(stbi__get32be(s)); + depth = stbi__get16be(s); + if (depth != 16) { + stbi__rewind( s ); + return 0; + } + return 1; +} +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) +{ + int act_comp=0,num_packets=0,chained,dummy; + stbi__pic_packet packets[10]; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { + stbi__rewind(s); + return 0; + } + + stbi__skip(s, 88); + + *x = stbi__get16be(s); + *y = stbi__get16be(s); + if (stbi__at_eof(s)) { + stbi__rewind( s); + return 0; + } + if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { + stbi__rewind( s ); + return 0; + } + + stbi__skip(s, 8); + + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return 0; + + packet = &packets[num_packets++]; + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + act_comp |= packet->channel; + + if (stbi__at_eof(s)) { + stbi__rewind( s ); + return 0; + } + if (packet->size != 8) { + stbi__rewind( s ); + return 0; + } + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); + + return 1; +} +#endif + +// ************************************************************************************************* +// Portable Gray Map and Portable Pixel Map loader +// by Ken Miller +// +// PGM: http://netpbm.sourceforge.net/doc/pgm.html +// PPM: http://netpbm.sourceforge.net/doc/ppm.html +// +// Known limitations: +// Does not support comments in the header section +// Does not support ASCII image data (formats P2 and P3) + +#ifndef STBI_NO_PNM + +static int stbi__pnm_test(stbi__context *s) +{ + char p, t; + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind( s ); + return 0; + } + return 1; +} + +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *out; + STBI_NOTUSED(ri); + + ri->bits_per_channel = stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n); + if (ri->bits_per_channel == 0) + return 0; + + if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + + if (!stbi__mad4sizes_valid(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0)) + return stbi__errpuc("too large", "PNM too large"); + + out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8)); + + if (req_comp && req_comp != s->img_n) { + out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + return out; +} + +static int stbi__pnm_isspace(char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; +} + +static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) +{ + for (;;) { + while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) + *c = (char) stbi__get8(s); + + if (stbi__at_eof(s) || *c != '#') + break; + + while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' ) + *c = (char) stbi__get8(s); + } +} + +static int stbi__pnm_isdigit(char c) +{ + return c >= '0' && c <= '9'; +} + +static int stbi__pnm_getinteger(stbi__context *s, char *c) +{ + int value = 0; + + while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { + value = value*10 + (*c - '0'); + *c = (char) stbi__get8(s); + } + + return value; +} + +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) +{ + int maxv, dummy; + char c, p, t; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + stbi__rewind(s); + + // Get identifier + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind(s); + return 0; + } + + *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm + + c = (char) stbi__get8(s); + stbi__pnm_skip_whitespace(s, &c); + + *x = stbi__pnm_getinteger(s, &c); // read width + stbi__pnm_skip_whitespace(s, &c); + + *y = stbi__pnm_getinteger(s, &c); // read height + stbi__pnm_skip_whitespace(s, &c); + + maxv = stbi__pnm_getinteger(s, &c); // read max value + if (maxv > 65535) + return stbi__err("max value > 65535", "PPM image supports only 8-bit and 16-bit images"); + else if (maxv > 255) + return 16; + else + return 8; +} + +static int stbi__pnm_is16(stbi__context *s) +{ + if (stbi__pnm_info(s, NULL, NULL, NULL) == 16) + return 1; + return 0; +} +#endif + +static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) +{ + #ifndef STBI_NO_JPEG + if (stbi__jpeg_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNG + if (stbi__png_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_GIF + if (stbi__gif_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_BMP + if (stbi__bmp_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PIC + if (stbi__pic_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNM + if (stbi__pnm_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_info(s, x, y, comp)) return 1; + #endif + + // test tga last because it's a crappy test! + #ifndef STBI_NO_TGA + if (stbi__tga_info(s, x, y, comp)) + return 1; + #endif + return stbi__err("unknown image type", "Image not of any known type, or corrupt"); +} + +static int stbi__is_16_main(stbi__context *s) +{ + #ifndef STBI_NO_PNG + if (stbi__png_is16(s)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_is16(s)) return 1; + #endif + + #ifndef STBI_NO_PNM + if (stbi__pnm_is16(s)) return 1; + #endif + return 0; +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; +} + +STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__info_main(&s,x,y,comp); + fseek(f,pos,SEEK_SET); + return r; +} + +STBIDEF int stbi_is_16_bit(char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_is_16_bit_from_file(f); + fclose(f); + return result; +} + +STBIDEF int stbi_is_16_bit_from_file(FILE *f) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__is_16_main(&s); + fseek(f,pos,SEEK_SET); + return r; +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__info_main(&s,x,y,comp); +} + +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__info_main(&s,x,y,comp); +} + +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__is_16_main(&s); +} + +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__is_16_main(&s); +} + +#endif // STB_IMAGE_IMPLEMENTATION + +/* + revision history: + 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug + 1-bit BMP + *_is_16_bit api + avoid warnings + 2.16 (2017-07-23) all functions have 16-bit variants; + STBI_NO_STDIO works again; + compilation fixes; + fix rounding in unpremultiply; + optimize vertical flip; + disable raw_len validation; + documentation fixes + 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode; + warning fixes; disable run-time SSE detection on gcc; + uniform handling of optional "return" values; + thread-safe initialization of zlib tables + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs + 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) allocate large structures on the stack + remove white matting for transparent PSD + fix reported channel count for PNG & BMP + re-enable SSE2 in non-gcc 64-bit + support RGB-formatted JPEG + read 16-bit PNGs (only as 8-bit) + 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED + 2.09 (2016-01-16) allow comments in PNM files + 16-bit-per-pixel TGA (not bit-per-component) + info() for TGA could break due to .hdr handling + info() for BMP to shares code instead of sloppy parse + can use STBI_REALLOC_SIZED if allocator doesn't support realloc + code cleanup + 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA + 2.07 (2015-09-13) fix compiler warnings + partial animated GIF support + limited 16-bpc PSD support + #ifdef unused functions + bug with < 92 byte PIC,PNM,HDR,TGA + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value + 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning + 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit + 2.03 (2015-04-12) extra corruption checking (mmozeiko) + stbi_set_flip_vertically_on_load (nguillemot) + fix NEON support; fix mingw support + 2.02 (2015-01-19) fix incorrect assert, fix warning + 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 + 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG + 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) + progressive JPEG (stb) + PGM/PPM support (Ken Miller) + STBI_MALLOC,STBI_REALLOC,STBI_FREE + GIF bugfix -- seemingly never worked + STBI_NO_*, STBI_ONLY_* + 1.48 (2014-12-14) fix incorrectly-named assert() + 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) + optimize PNG (ryg) + fix bug in interlaced PNG with user-specified channel count (stb) + 1.46 (2014-08-26) + fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG + 1.45 (2014-08-16) + fix MSVC-ARM internal compiler error by wrapping malloc + 1.44 (2014-08-07) + various warning fixes from Ronny Chevalier + 1.43 (2014-07-15) + fix MSVC-only compiler problem in code changed in 1.42 + 1.42 (2014-07-09) + don't define _CRT_SECURE_NO_WARNINGS (affects user code) + fixes to stbi__cleanup_jpeg path + added STBI_ASSERT to avoid requiring assert.h + 1.41 (2014-06-25) + fix search&replace from 1.36 that messed up comments/error messages + 1.40 (2014-06-22) + fix gcc struct-initialization warning + 1.39 (2014-06-15) + fix to TGA optimization when req_comp != number of components in TGA; + fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) + add support for BMP version 5 (more ignored fields) + 1.38 (2014-06-06) + suppress MSVC warnings on integer casts truncating values + fix accidental rename of 'skip' field of I/O + 1.37 (2014-06-04) + remove duplicate typedef + 1.36 (2014-06-03) + convert to header file single-file library + if de-iphone isn't set, load iphone images color-swapped instead of returning NULL + 1.35 (2014-05-27) + various warnings + fix broken STBI_SIMD path + fix bug where stbi_load_from_file no longer left file pointer in correct place + fix broken non-easy path for 32-bit BMP (possibly never used) + TGA optimization by Arseny Kapoulkine + 1.34 (unknown) + use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case + 1.33 (2011-07-14) + make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements + 1.32 (2011-07-13) + support for "info" function for all supported filetypes (SpartanJ) + 1.31 (2011-06-20) + a few more leak fixes, bug in PNG handling (SpartanJ) + 1.30 (2011-06-11) + added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) + removed deprecated format-specific test/load functions + removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway + error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) + fix inefficiency in decoding 32-bit BMP (David Woo) + 1.29 (2010-08-16) + various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) + fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) + cast-to-stbi_uc to fix warnings + 1.26 (2010-07-24) + fix bug in file buffering for PNG reported by SpartanJ + 1.25 (2010-07-17) + refix trans_data warning (Won Chun) + 1.24 (2010-07-12) + perf improvements reading from files on platforms with lock-heavy fgetc() + minor perf improvements for jpeg + deprecated type-specific functions so we'll get feedback if they're needed + attempt to fix trans_data warning (Won Chun) + 1.23 fixed bug in iPhone support + 1.22 (2010-07-10) + removed image *writing* support + stbi_info support from Jetro Lauha + GIF support from Jean-Marc Lienher + iPhone PNG-extensions from James Brown + warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) + 1.21 fix use of 'stbi_uc' in header (reported by jon blow) + 1.20 added support for Softimage PIC, by Tom Seddon + 1.19 bug in interlaced PNG corruption check (found by ryg) + 1.18 (2008-08-02) + fix a threading bug (local mutable static) + 1.17 support interlaced PNG + 1.16 major bugfix - stbi__convert_format converted one too many pixels + 1.15 initialize some fields for thread safety + 1.14 fix threadsafe conversion bug + header-file-only version (#define STBI_HEADER_FILE_ONLY before including) + 1.13 threadsafe + 1.12 const qualifiers in the API + 1.11 Support installable IDCT, colorspace conversion routines + 1.10 Fixes for 64-bit (don't use "unsigned long") + optimized upsampling by Fabian "ryg" Giesen + 1.09 Fix format-conversion for PSD code (bad global variables!) + 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz + 1.07 attempt to fix C++ warning/errors again + 1.06 attempt to fix C++ warning/errors again + 1.05 fix TGA loading to return correct *comp and use good luminance calc + 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free + 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR + 1.02 support for (subset of) HDR files, float interface for preferred access to them + 1.01 fix bug: possible bug in handling right-side up bmps... not sure + fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all + 1.00 interface to zlib that skips zlib header + 0.99 correct handling of alpha in palette + 0.98 TGA loader by lonesock; dynamically add loaders (untested) + 0.97 jpeg errors on too large a file; also catch another malloc failure + 0.96 fix detection of invalid v value - particleman@mollyrocket forum + 0.95 during header scan, seek to markers in case of padding + 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same + 0.93 handle jpegtran output; verbose errors + 0.92 read 4,8,16,24,32-bit BMP files of several formats + 0.91 output 24-bit Windows 3.0 BMP files + 0.90 fix a few more warnings; bump version number to approach 1.0 + 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd + 0.60 fix compiling as c++ + 0.59 fix warnings: merge Dave Moore's -Wall fixes + 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian + 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available + 0.56 fix bug: zlib uncompressed mode len vs. nlen + 0.55 fix bug: restart_interval not initialized to 0 + 0.54 allow NULL for 'int *comp' + 0.53 fix bug in png 3->4; speedup png decoding + 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments + 0.51 obey req_comp requests, 1-component jpegs return as 1-component, + on 'test' only check type, not whether we support this variant + 0.50 (2006-11-19) + first released version +*/ + + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/app/src/main/java/tech/recreational/kde/KDEActivity.java b/app/src/main/java/tech/recreational/kde/KDEActivity.java new file mode 100644 index 0000000..6d9c141 --- /dev/null +++ b/app/src/main/java/tech/recreational/kde/KDEActivity.java @@ -0,0 +1,26 @@ +package tech.recreational.kde; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsControllerCompat; +import androidx.core.view.WindowInsetsCompat; + +import com.google.androidgamesdk.GameActivity; + +public class KDEActivity extends GameActivity { + static { + System.loadLibrary("kde"); + } + + protected void onResume() { + super.onResume(); + hideSystemBars(); + } + + private void hideSystemBars() { + WindowInsetsControllerCompat windowInsetsController = ViewCompat.getWindowInsetsController( + getWindow().getDecorView()); + if (windowInsetsController == null) + return; + windowInsetsController.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); + windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()); + } +} diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..c209e78ecd372343283f4157dcfd918ec5165bb3 GIT binary patch literal 1404 zcmV-?1%vuhNk&F=1pok7MM6+kP&il$0000G0000-002h-06|PpNX!5L00Dqw+t%{r zzW2vH!KF=w&cMnnN@{whkTw+#mAh0SV?YL=)3MimFYCWp#fpdtz~8$hD5VPuQgtcN zXl<@<#Cme5f5yr2h%@8TWh?)bSK`O z^Z@d={gn7J{iyxL_y_%J|L>ep{dUxUP8a{byupH&!UNR*OutO~0{*T4q5R6@ApLF! z5{w?Z150gC7#>(VHFJZ-^6O@PYp{t!jH(_Z*nzTK4 zkc{fLE4Q3|mA2`CWQ3{8;gxGizgM!zccbdQoOLZc8hThi-IhN90RFT|zlxh3Ty&VG z?Fe{#9RrRnxzsu|Lg2ddugg7k%>0JeD+{XZ7>Z~{=|M+sh1MF7~ zz>To~`~LVQe1nNoR-gEzkpe{Ak^7{{ZBk2i_<+`Bq<^GB!RYG+z)h;Y3+<{zlMUYd zrd*W4w&jZ0%kBuDZ1EW&KLpyR7r2=}fF2%0VwHM4pUs}ZI2egi#DRMYZPek*^H9YK zay4Iy3WXFG(F14xYsoDA|KXgGc5%2DhmQ1gFCkrgHBm!lXG8I5h*uf{rn48Z!_@ z4Bk6TJAB2CKYqPjiX&mWoW>OPFGd$wqroa($ne7EUK;#3VYkXaew%Kh^3OrMhtjYN?XEoY`tRPQsAkH-DSL^QqyN0>^ zmC>{#F14jz4GeW{pJoRpLFa_*GI{?T93^rX7SPQgT@LbLqpNA}<@2wH;q493)G=1Y z#-sCiRNX~qf3KgiFzB3I>4Z%AfS(3$`-aMIBU+6?gbgDb!)L~A)je+;fR0jWLL-Fu z4)P{c7{B4Hp91&%??2$v9iRSFnuckHUm}or9seH6 z>%NbT+5*@L5(I9j@06@(!{ZI?U0=pKn8uwIg&L{JV14+8s2hnvbRrU|hZCd}IJu7*;;ECgO%8_*W Kmw_-CKmY()leWbG literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..b2dfe3d1ba5cf3ee31b3ecc1ced89044a1f3b7a9 GIT binary patch literal 2898 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..4f0f1d64e58ba64d180ce43ee13bf9a17835fbca GIT binary patch literal 982 zcmV;{11bDcNk&G_0{{S5MM6+kP&il$0000G0000l001ul06|PpNU8t;00Dqo+t#w^ z^1csucXz7-Qrhzl9HuHB%l>&>1tG2^vb*E&k^T3$FG1eQZ51g$uv4V+kI`0<^1Z@N zk?Jjh$olyC%l>)Xq;7!>{iBj&BjJ`P&$fsCfpve_epJOBkTF?nu-B7D!hO=2ZR}

C%4 zc_9eOXvPbC4kzU8YowIA8cW~Uv|eB&yYwAObSwL2vY~UYI7NXPvf3b+c^?wcs~_t{ ze_m66-0)^{JdOMKPwjpQ@Sna!*?$wTZ~su*tNv7o!gXT!GRgivP}ec?5>l1!7<(rT zds|8x(qGc673zrvYIz;J23FG{9nHMnAuP}NpAED^laz3mAN1sy+NXK)!6v1FxQ;lh zOBLA>$~P3r4b*NcqR;y6pwyhZ3_PiDb|%n1gGjl3ZU}ujInlP{eks-#oA6>rh&g+!f`hv#_%JrgYPu z(U^&XLW^QX7F9Z*SRPpQl{B%x)_AMp^}_v~?j7 zapvHMKxSf*Mtyx8I}-<*UGn3)oHd(nn=)BZ`d$lDBwq_GL($_TPaS{UeevT(AJ`p0 z9%+hQb6z)U9qjbuXjg|dExCLjpS8$VKQ55VsIC%@{N5t{NsW)=hNGI`J=x97_kbz@ E0Of=7!TQj4N+cqN`nQhxvX7dAV-`K|Ub$-q+H-5I?Tx0g9jWxd@A|?POE8`3b8fO$T))xP* z(X?&brZw({`)WU&rdAs1iTa0x6F@PIxJ&&L|dpySV!ID|iUhjCcKz(@mE z!x@~W#3H<)4Ae(4eQJRk`Iz3<1)6^m)0b_4_TRZ+cz#eD3f8V;2r-1fE!F}W zEi0MEkTTx}8i1{`l_6vo0(Vuh0HD$I4SjZ=?^?k82R51bC)2D_{y8mi_?X^=U?2|F{Vr7s!k(AZC$O#ZMyavHhlQ7 zUR~QXuH~#o#>(b$u4?s~HLF*3IcF7023AlwAYudn0FV~|odGH^05AYPEfR)8p`i{n zwg3zPVp{+wOsxKc>)(pMupKF!Y2HoUqQ3|Yu|8lwR=?5zZuhG6J?H`bSNk_wPoM{u zSL{c@pY7+c2kck>`^q1^^gR0QB7Y?KUD{vz-uVX~;V-rW)PDcI)$_UjgVV?S?=oLR zf4}zz{#*R_{LkiJ#0RdQLNC^2Vp%JPEUvG9ra2BVZ92(p9h7Ka@!yf9(lj#}>+|u* z;^_?KWdzkM`6gqPo9;;r6&JEa)}R3X{(CWv?NvgLeOTq$cZXqf7|sPImi-7cS8DCN zGf;DVt3Am`>hH3{4-WzH43Ftx)SofNe^-#|0HdCo<+8Qs!}TZP{HH8~z5n`ExcHuT zDL1m&|DVpIy=xsLO>8k92HcmfSKhflQ0H~9=^-{#!I1g(;+44xw~=* zxvNz35vfsQE)@)Zsp*6_GjYD};Squ83<_?^SbALb{a`j<0Gn%6JY!zhp=Fg}Ga2|8 z52e1WU%^L1}15Ex0fF$e@eCT(()_P zvV?CA%#Sy08_U6VPt4EtmVQraWJX` zh=N|WQ>LgrvF~R&qOfB$!%D3cGv?;Xh_z$z7k&s4N)$WYf*k=|*jCEkO19{h_(%W4 zPuOqbCw`SeAX*R}UUsbVsgtuG?xs(#Ikx9`JZoQFz0n*7ZG@Fv@kZk`gzO$HoA9kN z8U5{-yY zvV{`&WKU2$mZeoBmiJrEdzUZAv1sRxpePdg1)F*X^Y)zp^Y*R;;z~vOv-z&)&G)JQ{m!C9cmziu1^nHA z`#`0c>@PnQ9CJKgC5NjJD8HM3|KC(g5nnCq$n0Gsu_DXk36@ql%npEye|?%RmG)

FJ$wK}0tWNB{uH;AM~i literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..948a3070fe34c611c42c0d3ad3013a0dce358be0 GIT binary patch literal 1900 zcmV-y2b1_xNk&Fw2LJ$9MM6+kP&il$0000G0001A003VA06|PpNH75a00DqwTbm-~ zullQTcXxO9ki!OCRx^i?oR|n!<8G0=kI^!JSjFi-LL*`V;ET0H2IXfU0*i>o6o6Gy zRq6Ap5(_{XLdXcL-MzlN`ugSdZY_`jXhcENAu)N_0?GhF))9R;E`!bo9p?g?SRgw_ zEXHhFG$0{qYOqhdX<(wE4N@es3VIo$%il%6xP9gjiBri+2pI6aY4 zJbgh-Ud|V%3O!IcHKQx1FQH(_*TK;1>FQWbt^$K1zNn^cczkBs=QHCYZ8b&l!UV{K z{L0$KCf_&KR^}&2Fe|L&?1I7~pBENnCtCuH3sjcx6$c zwqkNkru);ie``q+_QI;IYLD9OV0ZxkuyBz|5<$1BH|vtey$> z5oto4=l-R-Aaq`Dk0}o9N0VrkqW_#;!u{!bJLDq%0092{Ghe=F;(kn} z+sQ@1=UlX30+2nWjkL$B^b!H2^QYO@iFc0{(-~yXj2TWz?VG{v`Jg zg}WyYnwGgn>{HFaG7E~pt=)sOO}*yd(UU-D(E&x{xKEl6OcU?pl)K%#U$dn1mDF19 zSw@l8G!GNFB3c3VVK0?uyqN&utT-D5%NM4g-3@Sii9tSXKtwce~uF zS&Jn746EW^wV~8zdQ1XC28~kXu8+Yo9p!<8h&(Q({J*4DBglPdpe4M_mD8AguZFn~ ztiuO~{6Bx?SfO~_ZV(GIboeR9~hAym{{fV|VM=77MxDrbW6`ujX z<3HF(>Zr;#*uCvC*bpoSr~C$h?_%nXps@A)=l_;({Fo#6Y1+Zv`!T5HB+)#^-Ud_; zBwftPN=d8Vx)*O1Mj+0oO=mZ+NVH*ptNDC-&zZ7Hwho6UQ#l-yNvc0Cm+2$$6YUk2D2t#vdZX-u3>-Be1u9gtTBiMB^xwWQ_rgvGpZ6(C@e23c!^K=>ai-Rqu zhqT`ZQof;9Bu!AD(i^PCbYV%yha9zuoKMp`U^z;3!+&d@Hud&_iy!O-$b9ZLcSRh? z)R|826w}TU!J#X6P%@Zh=La$I6zXa#h!B;{qfug}O%z@K{EZECu6zl)7CiNi%xti0 zB{OKfAj83~iJvmpTU|&q1^?^cIMn2RQ?jeSB95l}{DrEPTW{_gmU_pqTc)h@4T>~& zluq3)GM=xa(#^VU5}@FNqpc$?#SbVsX!~RH*5p0p@w z;~v{QMX0^bFT1!cXGM8K9FP+=9~-d~#TK#ZE{4umGT=;dfvWi?rYj;^l_Zxywze`W z^Cr{55U@*BalS}K%Czii_80e0#0#Zkhlij4-~I@}`-JFJ7$5{>LnoJSs??J8kWVl6|8A}RCGAu9^rAsfCE=2}tHwl93t0C?#+jMpvr7O3`2=tr{Hg$=HlnjVG^ewm|Js0J*kfPa6*GhtB>`fN!m#9J(sU!?(OSfzY*zS(FJ<-Vb zfAIg+`U)YaXv#sY(c--|X zEB+TVyZ%Ie4L$gi#Fc++`h6%vzsS$pjz9aLt+ZL(g;n$Dzy5=m=_TV(3H8^C{r0xd zp#a%}ht55dOq?yhwYPrtp-m1xXp;4X;)NhxxUpgP%XTLmO zcjaFva^}dP3$&sfFTIR_jC=2pHh9kpI@2(6V*GQo7Ws)`j)hd+tr@P~gR*2gO@+1? zG<`_tB+LJuF|SZ9tIec;h%}}6WClT`L>HSW?E{Hp1h^+mlbf_$9zA>!ug>NALJsO{ mU%z=YwVD?}XMya)Bp;vlyE5&E_6!fzx9pwrdz474!~g(M6R?N? literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..1b9a6956b3acdc11f40ce2bb3f6efbd845cc243f GIT binary patch literal 3918 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�(p-{x$&=IACIfoAR!za)F-^da-t3#0Dycnp zwO~NVXwXCl;jE<}>%@xz|=8fIJAB?>+E{7)|4l${4ngA3G|=r z2Dyv;VVWSgZx9Wj>qUjleGl3Ei9K4>h!(lPS%8VOG>Xu0%6VDz^O=bjJmuP7>DeUv zrbI}MlHB^^d?{zv6d=@_ZD2lg1&G7UjnVN{1}9WkaM3H~btX0GtSzB+tZ^qRgWo4m z!GmimlG$=wgXCnr6j@m<1gAL46#T~5Bnm=2{^@>|t&`9mkEPddj zAvG~@Tv~TAm2i%VW}R-g(Z0)z-Y|szHr@rk>4MAyG*Ma*7Yh#H7(!-5>DZ@8r;_dx z{prSe<>~099F8vsYd2xff7uAS%7{S)f(|@me3t2$iy&NEc7OUEchp@9A|X;;IA>8!oX+y(BKJ$EzV* znR$z;!L$s7uy@{OT~nG#B!NRraT8(X##Ho!0r_o@gg0CA-9H^;-uE&?$2$nHv_00o z%cbuUc-tCx$Uh&EZ4Nf4Zgqv)Y6>usG3>GeQnxx_Z6+PcbX-+ysbt1hQ`K1LDpOE? zrAhIZhSN9yVIAOa22gn577tbc&i3|3V8NWy&!tw##`}9*x}gtI^h1DzZRA>UuaJG) zaZ7j)dq!O}{?#8Y7~7i6fHh4{`pL?>-18|p!S75Y#^DM>-S3)vuZG+Q7l@ek zQP~#cBpWgg#mApc_sPYjpw8odQuRokmTkzcNl`^CcKB7e&;zViV;{Y{o^Y$%7i0m# z62%#1Lq!RC?}lK>%mp}T!3Xv;L*0v*>USLm``N%>w>@fwC+#T&Tx2bN4w(20JB}oU zuSa6v^kXi0xPs?pbaOHnyiqq6By1EZY9OZ^^QA>{q-Hsd&m`pbQ%8121aWG-F5xf zlZ%;B{;C>X19|`^_?dVyCq>n+41w7|!tUS!{9rHlbhX=SZO5CQ^;!Du_E7*`GiR^Q w)2!4MKjfSAeNo!9>IaV6aUZ*?W>} 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

K7UpUK$>l@ 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 E2O(~oYXATM literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..1749762 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sun Oct 02 14:06:47 CEST 2022 +distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..4f906e0 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..4d105d3 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,16 @@ +pluginManagement { + repositories { + gradlePluginPortal() + google() + mavenCentral() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} +rootProject.name = "Krimi Dinner Engine" +include ':app'

UmY2RIYtNPVDpE$%vda+HD#3m z&VuXJ{BK&Qe+rBa7eq}Q(bq|tn(RrJAk|ztj2(i{d>nmQnM?;HF2k&9sA6up5tmjl z7lySlzMbifH17-m-Lwa_F&e7nOH?ESi3#ckR3tsM+jsck3`oG!uMS}|eAwVXv>}qxwq?QY%QJ0}r@^;fhuUA9W z*BVl>TGo&N004@xSiwDUXUvp51sVmqO3m)=B55aPwf@0=e}cN+$-BdKxY`YrT_4)0 z_d10#i44Q*rFr8MC>*)v$EJvz``(pb{e&*6k+b zsMz%($|1+8hn8c2?P(l@;Rb&CsZeYoCI3?2!LqjbwPXW3z4G$Qfj=cT5Yb%vY0(AX oeb?AaKtwrnc|$|zzw9vfvn^aJJ!zd)XFXqqy0000001=f@-~a#s literal 0 HcmV?d00001 diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml new file mode 100644 index 0000000..162e407 --- /dev/null +++ b/app/src/main/res/values-night/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..0cfa5d5 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Krimi Dinner Engine + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..3523cb5 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml new file mode 100644 index 0000000..fa0f996 --- /dev/null +++ b/app/src/main/res/xml/backup_rules.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml new file mode 100644 index 0000000..9ee9997 --- /dev/null +++ b/app/src/main/res/xml/data_extraction_rules.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/test/java/tech/recreational/kde/ExampleUnitTest.java b/app/src/test/java/tech/recreational/kde/ExampleUnitTest.java new file mode 100644 index 0000000..f0677db --- /dev/null +++ b/app/src/test/java/tech/recreational/kde/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package tech.recreational.kde; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..6ce296e --- /dev/null +++ b/build.gradle @@ -0,0 +1,9 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +plugins { + id 'com.android.application' version '7.2.2' apply false + id 'com.android.library' version '7.2.2' apply false +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..dab7c28 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,21 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app"s APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f GIT binary patch literal 59203 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