summaryrefslogtreecommitdiff
path: root/subprojects
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects')
-rw-r--r--subprojects/argspp/args.cpp477
-rw-r--r--subprojects/argspp/args.h119
-rw-r--r--subprojects/argspp/meson.build5
-rw-r--r--subprojects/glad/include/KHR/khrplatform.h27
-rw-r--r--subprojects/glad/include/glad/gl.h69
-rw-r--r--subprojects/glad/meson.build7
-rw-r--r--subprojects/glad/src/gl.c16
m---------subprojects/glfw0
m---------subprojects/glm0
m---------subprojects/json0
-rw-r--r--subprojects/lz4/include/lz4.h764
-rw-r--r--subprojects/lz4/include/lz4frame.h615
-rw-r--r--subprojects/lz4/include/lz4hc.h438
-rw-r--r--subprojects/lz4/meson.build14
-rw-r--r--subprojects/lz4/static/lz4.libbin200650 -> 0 bytes
-rw-r--r--subprojects/s3tc-dxt-decompression/meson.build11
-rw-r--r--subprojects/stb_image/meson.build5
-rw-r--r--subprojects/stb_image/stb_image.h417
-rw-r--r--subprojects/stb_image/stb_image_write.h80
19 files changed, 1040 insertions, 2024 deletions
diff --git a/subprojects/argspp/args.cpp b/subprojects/argspp/args.cpp
new file mode 100644
index 0000000..21f483e
--- /dev/null
+++ b/subprojects/argspp/args.cpp
@@ -0,0 +1,477 @@
+// -----------------------------------------------------------------------------
+// Args++: an argument-parsing library in portable C++11.
+// -----------------------------------------------------------------------------
+
+#include "args.h"
+
+#include <algorithm>
+#include <cctype>
+#include <iostream>
+#include <sstream>
+#include <deque>
+#include <set>
+
+using namespace std;
+using namespace args;
+
+
+// -----------------------------------------------------------------------------
+// Flags and Options.
+// -----------------------------------------------------------------------------
+
+
+struct args::Flag {
+ int count = 0;
+};
+
+
+struct args::Option {
+ vector<string> values;
+ string fallback;
+};
+
+
+// -----------------------------------------------------------------------------
+// ArgStream.
+// -----------------------------------------------------------------------------
+
+
+struct args::ArgStream {
+ deque<string> args;
+ void append(string const& arg);
+ string next();
+ bool hasNext();
+};
+
+
+void ArgStream::append(string const& arg) {
+ args.push_back(arg);
+}
+
+
+string ArgStream::next() {
+ string arg = args.front();
+ args.pop_front();
+ return arg;
+}
+
+
+bool ArgStream::hasNext() {
+ return args.size() > 0;
+}
+
+
+// -----------------------------------------------------------------------------
+// ArgParser: setup.
+// -----------------------------------------------------------------------------
+
+
+void ArgParser::flag(string const& name) {
+ Flag* flag = new Flag();
+ stringstream stream(name);
+ string alias;
+ while (stream >> alias) {
+ flags[alias] = flag;
+ }
+}
+
+
+void ArgParser::option(string const& name, string const& fallback) {
+ Option* option = new Option();
+ option->fallback = fallback;
+ stringstream stream(name);
+ string alias;
+ while (stream >> alias) {
+ options[alias] = option;
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+// ArgParser: retrieve values.
+// -----------------------------------------------------------------------------
+
+
+bool ArgParser::found(string const& name) const {
+ if (flags.count(name) > 0) {
+ return flags.at(name)->count > 0;
+ }
+ if (options.count(name) > 0) {
+ return options.at(name)->values.size() > 0;
+ }
+ return false;
+}
+
+
+int ArgParser::count(string const& name) const {
+ if (flags.count(name) > 0) {
+ return flags.at(name)->count;
+ }
+ if (options.count(name) > 0) {
+ return options.at(name)->values.size();
+ }
+ return 0;
+}
+
+
+string ArgParser::value(string const& name) const {
+ if (options.count(name) > 0) {
+ if (options.at(name)->values.size() > 0) {
+ return options.at(name)->values.back();
+ }
+ return options.at(name)->fallback;
+ }
+ return string();
+}
+
+
+vector<string> ArgParser::values(string const& name) const {
+ if (options.count(name) > 0) {
+ return options.at(name)->values;
+ }
+ return vector<string>();
+}
+
+
+// -----------------------------------------------------------------------------
+// ArgParser: commands.
+// -----------------------------------------------------------------------------
+
+
+ArgParser& ArgParser::command(
+ string const& name,
+ string const& helptext,
+ void (*callback)(string cmd_name, ArgParser& cmd_parser)) {
+
+ ArgParser *parser = new ArgParser();
+ parser->helptext = helptext;
+ parser->callback = callback;
+
+ stringstream stream(name);
+ string alias;
+
+ while (stream >> alias) {
+ commands[alias] = parser;
+ }
+
+ return *parser;
+}
+
+
+bool ArgParser::commandFound() {
+ return command_name != "";
+}
+
+
+string ArgParser::commandName() {
+ return command_name;
+}
+
+
+ArgParser& ArgParser::commandParser() {
+ return *commands[command_name];
+}
+
+
+// -----------------------------------------------------------------------------
+// ArgParser: parse arguments.
+// -----------------------------------------------------------------------------
+
+
+// Parse an option of the form --name=value or -n=value.
+void ArgParser::parseEqualsOption(string prefix, string name, string value) {
+ if (options.count(name) > 0) {
+ if (value.size() > 0) {
+ options[name]->values.push_back(value);
+ } else {
+ cerr << "Error: missing value for " << prefix << name << ".\n";
+ exit(1);
+ }
+ } else {
+ cerr << "Error: " << prefix << name << " is not a recognised option.\n";
+ exit(1);
+ }
+}
+
+
+// Parse a long-form option, i.e. an option beginning with a double dash.
+void ArgParser::parseLongOption(string arg, ArgStream& stream) {
+ size_t pos = arg.find("=");
+ if (pos != string::npos) {
+ parseEqualsOption("--", arg.substr(0, pos), arg.substr(pos + 1));
+ return;
+ }
+
+ if (flags.count(arg) > 0) {
+ flags[arg]->count++;
+ return;
+ }
+
+ if (options.count(arg) > 0) {
+ if (stream.hasNext()) {
+ options[arg]->values.push_back(stream.next());
+ return;
+ } else {
+ cerr << "Error: missing argument for --" << arg << ".\n";
+ exit(1);
+ }
+ }
+
+ if (arg == "help" && this->helptext != "") {
+ exitHelp();
+ }
+
+ if (arg == "version" && this->version != "") {
+ exitVersion();
+ }
+
+ cerr << "Error: --" << arg << " is not a recognised flag or option.\n";
+ exit(1);
+}
+
+
+// Parse a short-form option, i.e. an option beginning with a single dash.
+void ArgParser::parseShortOption(string arg, ArgStream& stream) {
+ size_t pos = arg.find("=");
+ if (pos != string::npos) {
+ parseEqualsOption("-", arg.substr(0, pos), arg.substr(pos + 1));
+ return;
+ }
+
+ for (char& c: arg) {
+ string name = string(1, c);
+
+ if (flags.count(name) > 0) {
+ flags[name]->count++;
+ continue;
+ }
+
+ if (options.count(name) > 0) {
+ if (stream.hasNext()) {
+ options[name]->values.push_back(stream.next());
+ continue;
+ } else {
+ if (arg.size() > 1) {
+ cerr << "Error: missing argument for '" << c << "' in -" << arg << ".\n";
+ } else {
+ cerr << "Error: missing argument for -" << c << ".\n";
+ }
+ exit(1);
+ }
+ }
+
+ if (c == 'h' && this->helptext != "") {
+ exitHelp();
+ }
+
+ if (c == 'v' && this->version != "") {
+ exitVersion();
+ }
+
+ if (arg.size() > 1) {
+ cerr << "Error: '" << c << "' in -" << arg << " is not a recognised flag or option.\n";
+ } else {
+ cerr << "Error: -" << c << " is not a recognised flag or option.\n";
+ }
+ exit(1);
+ }
+}
+
+
+// Parse a stream of string arguments.
+void ArgParser::parse(ArgStream& stream) {
+ bool is_first_arg = true;
+
+ while (stream.hasNext()) {
+ string arg = stream.next();
+
+ // If we enounter a '--', turn off option parsing.
+ if (arg == "--") {
+ while (stream.hasNext()) {
+ args.push_back(stream.next());
+ }
+ continue;
+ }
+
+ // Is the argument a long-form option or flag?
+ if (arg.compare(0, 2, "--") == 0) {
+ parseLongOption(arg.substr(2), stream);
+ continue;
+ }
+
+ // Is the argument a short-form option or flag? If the argument
+ // consists of a single dash or a dash followed by a digit, we treat
+ // it as a positional argument.
+ if (arg[0] == '-') {
+ if (arg.size() == 1 || isdigit(arg[1])) {
+ args.push_back(arg);
+ } else {
+ parseShortOption(arg.substr(1), stream);
+ }
+ continue;
+ }
+
+ // Is the argument a registered command?
+ if (is_first_arg && commands.count(arg) > 0) {
+ ArgParser* command_parser = commands[arg];
+ command_name = arg;
+ command_parser->parse(stream);
+ if (command_parser->callback != nullptr) {
+ command_parser->callback(arg, *command_parser);
+ }
+ continue;
+ }
+
+ // Is the argument the automatic 'help' command?
+ if (is_first_arg && arg == "help" && commands.size() > 0) {
+ if (stream.hasNext()) {
+ string name = stream.next();
+ if (commands.find(name) == commands.end()) {
+ cerr << "Error: '" << name << "' is not a recognised command.\n";
+ exit(1);
+ } else {
+ commands[name]->exitHelp();
+ }
+ } else {
+ cerr << "Error: the help command requires an argument.\n";
+ exit(1);
+ }
+ }
+
+ // Otherwise add the argument to our list of positional arguments.
+ args.push_back(arg);
+ is_first_arg = false;
+ }
+}
+
+
+// Parse an array of string arguments. We assume that [argc] and [argv] are the
+// original parameters passed to main() and skip the first element. In some
+// situations [argv] can be empty, i.e. [argc == 0]. This can lead to security
+// vulnerabilities if not handled explicitly.
+void ArgParser::parse(int argc, char **argv) {
+ if (argc > 1) {
+ ArgStream stream;
+ for (int i = 1; i < argc; i++) {
+ stream.append(argv[i]);
+ }
+ parse(stream);
+ }
+}
+
+
+// Parse a vector of string arguments.
+void ArgParser::parse(vector<string> args) {
+ ArgStream stream;
+ for (string& arg: args) {
+ stream.append(arg);
+ }
+ parse(stream);
+}
+
+
+// -----------------------------------------------------------------------------
+// ArgParser: utilities.
+// -----------------------------------------------------------------------------
+
+
+// Override the << stream insertion operator to support vectors. This will
+// allow us to cout our lists of option values in the print() method.
+template<typename T>
+static ostream& operator<<(ostream& stream, const vector<T>& vec) {
+ stream << "[";
+ for(size_t i = 0; i < vec.size(); ++i) {
+ if (i) cout << ", ";
+ stream << vec[i];
+ }
+ stream << "]";
+ return stream;
+}
+
+
+// Dump the parser's state to stdout.
+void ArgParser::print() {
+ cout << "Options:\n";
+ if (options.size() > 0) {
+ for (auto element: options) {
+ cout << " " << element.first << ": ";
+ Option *option = element.second;
+ cout << "(" << option->fallback << ") ";
+ cout << option->values;
+ cout << "\n";
+ }
+ } else {
+ cout << " [none]\n";
+ }
+
+ cout << "\nFlags:\n";
+ if (flags.size() > 0) {
+ for (auto element: flags) {
+ cout << " " << element.first << ": " << element.second->count << "\n";
+ }
+ } else {
+ cout << " [none]\n";
+ }
+
+ cout << "\nArguments:\n";
+ if (args.size() > 0) {
+ for (auto arg: args) {
+ cout << " " << arg << "\n";
+ }
+ } else {
+ cout << " [none]\n";
+ }
+
+ cout << "\nCommand:\n";
+ if (commandFound()) {
+ cout << " " << command_name << "\n";
+ } else {
+ cout << " [none]\n";
+ }
+}
+
+
+// Print the parser's help text and exit.
+void ArgParser::exitHelp() {
+ cout << helptext << endl;
+ exit(0);
+}
+
+
+// Print the parser's version string and exit.
+void ArgParser::exitVersion() {
+ cout << version << endl;
+ exit(0);
+}
+
+
+// -----------------------------------------------------------------------------
+// ArgParser: cleanup.
+// -----------------------------------------------------------------------------
+
+
+ArgParser::~ArgParser() {
+ set<Option*> unique_options;
+ for (auto element: options) {
+ unique_options.insert(element.second);
+ }
+ for (auto pointer: unique_options) {
+ delete pointer;
+ }
+
+ set<Flag*> unique_flags;
+ for (auto element: flags) {
+ unique_flags.insert(element.second);
+ }
+ for (auto pointer: unique_flags) {
+ delete pointer;
+ }
+
+ set<ArgParser*> unique_cmd_parsers;
+ for (auto element: commands) {
+ unique_cmd_parsers.insert(element.second);
+ }
+ for (auto pointer: unique_cmd_parsers) {
+ delete pointer;
+ }
+}
diff --git a/subprojects/argspp/args.h b/subprojects/argspp/args.h
new file mode 100644
index 0000000..a120f4e
--- /dev/null
+++ b/subprojects/argspp/args.h
@@ -0,0 +1,119 @@
+// -----------------------------------------------------------------------------
+// Args++: an argument-parsing library in portable C++11.
+//
+// Author: Darren Mulholland <dmulholl@tcd.ie>
+// License: Public Domain
+// Version: 2.1.0
+// -----------------------------------------------------------------------------
+
+#ifndef args_h
+#define args_h
+
+#include <map>
+#include <string>
+#include <vector>
+#include <sstream>
+
+namespace args {
+
+ struct ArgStream;
+ struct Option;
+ struct Flag;
+
+ class ArgParser {
+ public:
+ ArgParser(
+ std::string const& helptext = "",
+ std::string const& version = ""
+ ) : helptext(helptext), version(version) {}
+
+ ~ArgParser();
+
+ // Stores positional arguments.
+ std::vector<std::string> args;
+
+ // Application/command help text and version strings.
+ std::string helptext;
+ std::string version;
+
+ // Callback function for command parsers.
+ void (*callback)(std::string cmd_name, ArgParser& cmd_parser);
+
+ // Register flags and options.
+ void flag(std::string const& name);
+ void option(std::string const& name, std::string const& fallback = "");
+
+ // Parse the application's command line arguments.
+ void parse(int argc, char **argv);
+ void parse(std::vector<std::string> args);
+
+ // Retrieve flag and option values.
+ bool found(std::string const& name) const;
+ int count(std::string const& name) const;
+ std::string value(std::string const& name) const;
+ std::vector<std::string> values(std::string const& name) const;
+
+ template<typename T>
+ T value(std::string const& name) const
+ {
+ std::string str = value(name);
+ T ret = scan<T>(str);
+ return ret;
+ }
+
+ template<typename T>
+ std::vector<T> values(std::string const& name) const
+ {
+ std::vector<std::string> vec = values(name);
+ std::vector<T> ret;
+ ret.reserve(vec.size());
+ for (size_t i = 0; i < vec.size(); ++i) {
+ T value = vec[i];
+ ret.push_back(value);
+ }
+ return ret;
+ }
+
+ // Register a command. Returns the command's ArgParser instance.
+ ArgParser& command(
+ std::string const& name,
+ std::string const& helptext = "",
+ void (*callback)(std::string cmd_name, ArgParser& cmd_parser) = nullptr
+ );
+
+ // Utilities for handling commands manually.
+ bool commandFound();
+ std::string commandName();
+ ArgParser& commandParser();
+
+ // Print a parser instance to stdout.
+ void print();
+
+ private:
+ std::map<std::string, Option*> options;
+ std::map<std::string, Flag*> flags;
+ std::map<std::string, ArgParser*> commands;
+ std::string command_name;
+
+ void parse(ArgStream& args);
+ void registerOption(std::string const& name, Option* option);
+ void parseLongOption(std::string arg, ArgStream& stream);
+ void parseShortOption(std::string arg, ArgStream& stream);
+ void parseEqualsOption(std::string prefix, std::string name, std::string value);
+ void exitHelp();
+ void exitVersion();
+
+ template<typename T>
+ T scan(const std::string &input) const
+ {
+ std::stringstream stream(input);
+ T ret;
+ if ((stream >> ret).fail()) {
+ return T{0};
+ }
+ return ret;
+ }
+ };
+}
+
+#endif
diff --git a/subprojects/argspp/meson.build b/subprojects/argspp/meson.build
new file mode 100644
index 0000000..50aec98
--- /dev/null
+++ b/subprojects/argspp/meson.build
@@ -0,0 +1,5 @@
+project('argspp', 'cpp', version: '2.1.0')
+
+argspp_inc = include_directories('.')
+argspp_lib = static_library('argspp', 'args.cpp', include_directories: argspp_inc)
+argspp = declare_dependency(link_with: argspp_lib, include_directories: argspp_inc)
diff --git a/subprojects/glad/include/KHR/khrplatform.h b/subprojects/glad/include/KHR/khrplatform.h
index dd22d92..0164644 100644
--- a/subprojects/glad/include/KHR/khrplatform.h
+++ b/subprojects/glad/include/KHR/khrplatform.h
@@ -153,6 +153,20 @@ typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
+/*
+ * To support platform where unsigned long cannot be used interchangeably with
+ * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
+ * Ideally, we could just use (u)intptr_t everywhere, but this could result in
+ * ABI breakage if khronos_uintptr_t is changed from unsigned long to
+ * unsigned long long or similar (this results in different C++ name mangling).
+ * To avoid changes for existing platforms, we restrict usage of intptr_t to
+ * platforms where the size of a pointer is larger than the size of long.
+ */
+#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
+#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
+#define KHRONOS_USE_INTPTR_T
+#endif
+#endif
#elif defined(__VMS ) || defined(__sgi)
@@ -235,14 +249,21 @@ typedef unsigned short int khronos_uint16_t;
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
-#ifdef _WIN64
+#ifdef KHRONOS_USE_INTPTR_T
+typedef intptr_t khronos_intptr_t;
+typedef uintptr_t khronos_uintptr_t;
+#elif defined(_WIN64)
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
-typedef signed long long int khronos_ssize_t;
-typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
+#endif
+
+#if defined(_WIN64)
+typedef signed long long int khronos_ssize_t;
+typedef unsigned long long int khronos_usize_t;
+#else
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
diff --git a/subprojects/glad/include/glad/gl.h b/subprojects/glad/include/glad/gl.h
index 936fbdd..4df7f2a 100644
--- a/subprojects/glad/include/glad/gl.h
+++ b/subprojects/glad/include/glad/gl.h
@@ -1,27 +1,28 @@
/**
- * Loader generated by glad 2.0.0-beta on Tue Oct 27 23:17:49 2020
+ * Loader generated by glad 2.0.4 on Fri Jul 21 17:13:42 2023
+ *
+ * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
*
* Generator: C/C++
* Specification: gl
- * Extensions: 2
+ * Extensions: 1
*
* APIs:
* - gl:core=3.3
*
* Options:
- * - MX_GLOBAL = False
- * - ON_DEMAND = False
- * - LOADER = False
* - ALIAS = False
- * - HEADER_ONLY = False
* - DEBUG = False
+ * - HEADER_ONLY = False
+ * - LOADER = False
* - MX = False
+ * - ON_DEMAND = False
*
* Commandline:
- * --api='gl:core=3.3' --extensions='GL_EXT_texture_filter_anisotropic,GL_EXT_texture_lod_bias' c
+ * --api='gl:core=3.3' --extensions='GL_EXT_texture_filter_anisotropic' c
*
* Online:
- * http://glad.sh/#api=gl%3Acore%3D3.3&extensions=GL_EXT_texture_filter_anisotropic%2CGL_EXT_texture_lod_bias&generator=c&options=
+ * http://glad.sh/#api=gl%3Acore%3D3.3&extensions=GL_EXT_texture_filter_anisotropic&generator=c&options=
*
*/
@@ -114,6 +115,8 @@ extern "C" {
#define GLAD_GNUC_EXTENSION
#endif
+#define GLAD_UNUSED(x) (void)(x)
+
#ifndef GLAD_API_CALL
#if defined(GLAD_API_CALL_EXPORT)
#if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__)
@@ -160,7 +163,7 @@ extern "C" {
#define GLAD_VERSION_MAJOR(version) (version / 10000)
#define GLAD_VERSION_MINOR(version) (version % 10000)
-#define GLAD_GENERATOR_VERSION "2.0.0-beta"
+#define GLAD_GENERATOR_VERSION "2.0.4"
typedef void (*GLADapiproc)(void);
@@ -514,7 +517,6 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
-#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD
#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
#define GL_MAX_TEXTURE_SIZE 0x0D33
@@ -866,14 +868,12 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_TEXTURE_DEPTH 0x8071
#define GL_TEXTURE_DEPTH_SIZE 0x884A
#define GL_TEXTURE_DEPTH_TYPE 0x8C16
-#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500
#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
#define GL_TEXTURE_GREEN_SIZE 0x805D
#define GL_TEXTURE_GREEN_TYPE 0x8C11
#define GL_TEXTURE_HEIGHT 0x1001
#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
#define GL_TEXTURE_LOD_BIAS 0x8501
-#define GL_TEXTURE_LOD_BIAS_EXT 0x8501
#define GL_TEXTURE_MAG_FILTER 0x2800
#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
@@ -1000,113 +1000,70 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#include <KHR/khrplatform.h>
-
typedef unsigned int GLenum;
-
typedef unsigned char GLboolean;
-
typedef unsigned int GLbitfield;
-
typedef void GLvoid;
-
typedef khronos_int8_t GLbyte;
-
typedef khronos_uint8_t GLubyte;
-
typedef khronos_int16_t GLshort;
-
typedef khronos_uint16_t GLushort;
-
typedef int GLint;
-
typedef unsigned int GLuint;
-
typedef khronos_int32_t GLclampx;
-
typedef int GLsizei;
-
typedef khronos_float_t GLfloat;
-
typedef khronos_float_t GLclampf;
-
typedef double GLdouble;
-
typedef double GLclampd;
-
typedef void *GLeglClientBufferEXT;
-
typedef void *GLeglImageOES;
-
typedef char GLchar;
-
typedef char GLcharARB;
-
#ifdef __APPLE__
typedef void *GLhandleARB;
#else
typedef unsigned int GLhandleARB;
#endif
-
typedef khronos_uint16_t GLhalf;
-
typedef khronos_uint16_t GLhalfARB;
-
typedef khronos_int32_t GLfixed;
-
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
typedef khronos_intptr_t GLintptr;
#else
typedef khronos_intptr_t GLintptr;
#endif
-
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
typedef khronos_intptr_t GLintptrARB;
#else
typedef khronos_intptr_t GLintptrARB;
#endif
-
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
typedef khronos_ssize_t GLsizeiptr;
#else
typedef khronos_ssize_t GLsizeiptr;
#endif
-
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
typedef khronos_ssize_t GLsizeiptrARB;
#else
typedef khronos_ssize_t GLsizeiptrARB;
#endif
-
typedef khronos_int64_t GLint64;
-
typedef khronos_int64_t GLint64EXT;
-
typedef khronos_uint64_t GLuint64;
-
typedef khronos_uint64_t GLuint64EXT;
-
typedef struct __GLsync *GLsync;
-
struct _cl_context;
-
struct _cl_event;
-
typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
-
typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
-
typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
-
typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam);
-
typedef unsigned short GLhalfNV;
-
typedef GLintptr GLvdpauSurfaceNV;
-
typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void);
-
#define GL_VERSION_1_0 1
GLAD_API_CALL int GLAD_GL_VERSION_1_0;
#define GL_VERSION_1_1 1
@@ -1133,8 +1090,6 @@ GLAD_API_CALL int GLAD_GL_VERSION_3_2;
GLAD_API_CALL int GLAD_GL_VERSION_3_3;
#define GL_EXT_texture_filter_anisotropic 1
GLAD_API_CALL int GLAD_GL_EXT_texture_filter_anisotropic;
-#define GL_EXT_texture_lod_bias 1
-GLAD_API_CALL int GLAD_GL_EXT_texture_lod_bias;
typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture);
diff --git a/subprojects/glad/meson.build b/subprojects/glad/meson.build
index 710e4d0..f998dd9 100644
--- a/subprojects/glad/meson.build
+++ b/subprojects/glad/meson.build
@@ -1,8 +1,5 @@
-project('glad', 'c')
+project('glad', 'c', version: '2.0.4')
glad_inc = include_directories('include')
-
-glad_lib = static_library('glad', 'src/gl.c',
- include_directories : glad_inc)
-
+glad_lib = static_library('glad', 'src/gl.c', include_directories: glad_inc)
glad = declare_dependency(link_with: glad_lib, include_directories: glad_inc)
diff --git a/subprojects/glad/src/gl.c b/subprojects/glad/src/gl.c
index f4d8fa9..3f9ef66 100644
--- a/subprojects/glad/src/gl.c
+++ b/subprojects/glad/src/gl.c
@@ -1,3 +1,6 @@
+/**
+ * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
+ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -33,7 +36,6 @@ int GLAD_GL_VERSION_3_1 = 0;
int GLAD_GL_VERSION_3_2 = 0;
int GLAD_GL_VERSION_3_3 = 0;
int GLAD_GL_EXT_texture_filter_anisotropic = 0;
-int GLAD_GL_EXT_texture_lod_bias = 0;
@@ -779,9 +781,9 @@ static int glad_gl_get_extensions( int version, const char **out_exts, unsigned
#if GLAD_GL_IS_SOME_NEW_VERSION
if(GLAD_VERSION_MAJOR(version) < 3) {
#else
- (void) version;
- (void) out_num_exts_i;
- (void) out_exts_i;
+ GLAD_UNUSED(version);
+ GLAD_UNUSED(out_num_exts_i);
+ GLAD_UNUSED(out_exts_i);
#endif
if (glad_glGetString == NULL) {
return 0;
@@ -874,7 +876,6 @@ static int glad_gl_find_extensions_gl( int version) {
if (!glad_gl_get_extensions(version, &exts, &num_exts_i, &exts_i)) return 0;
GLAD_GL_EXT_texture_filter_anisotropic = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_texture_filter_anisotropic");
- GLAD_GL_EXT_texture_lod_bias = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_texture_lod_bias");
glad_gl_free_extensions(exts_i, num_exts_i);
@@ -882,14 +883,17 @@ static int glad_gl_find_extensions_gl( int version) {
}
static int glad_gl_find_core_gl(void) {
- int i, major, minor;
+ int i;
const char* version;
const char* prefixes[] = {
"OpenGL ES-CM ",
"OpenGL ES-CL ",
"OpenGL ES ",
+ "OpenGL SC ",
NULL
};
+ int major = 0;
+ int minor = 0;
version = (const char*) glad_glGetString(GL_VERSION);
if (!version) return 0;
for (i = 0; prefixes[i]; i++) {
diff --git a/subprojects/glfw b/subprojects/glfw
-Subproject 0ef149c8f2451fbc8e866834675a075cfc295b6
+Subproject 7482de6071d21db77a7236155da44c172a7f6c9
diff --git a/subprojects/glm b/subprojects/glm
-Subproject b3f87720261d623986f164b2a7f6a0a93843027
+Subproject 586a402397dd35d66d7a079049856d1e2cbab30
diff --git a/subprojects/json b/subprojects/json
-Subproject fd7a9f600712b2724463e9f7f703878ade676d6
+Subproject bc889afb4c5bf1c0d8ee29ef35eaaf4c8bef8a5
diff --git a/subprojects/lz4/include/lz4.h b/subprojects/lz4/include/lz4.h
deleted file mode 100644
index 32108e2..0000000
--- a/subprojects/lz4/include/lz4.h
+++ /dev/null
@@ -1,764 +0,0 @@
-/*
- * LZ4 - Fast LZ compression algorithm
- * Header File
- * Copyright (C) 2011-present, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - LZ4 homepage : http://www.lz4.org
- - LZ4 source repository : https://github.com/lz4/lz4
-*/
-#if defined (__cplusplus)
-extern "C" {
-#endif
-
-#ifndef LZ4_H_2983827168210
-#define LZ4_H_2983827168210
-
-/* --- Dependency --- */
-#include <stddef.h> /* size_t */
-
-
-/**
- Introduction
-
- LZ4 is lossless compression algorithm, providing compression speed >500 MB/s per core,
- scalable with multi-cores CPU. It features an extremely fast decoder, with speed in
- multiple GB/s per core, typically reaching RAM speed limits on multi-core systems.
-
- The LZ4 compression library provides in-memory compression and decompression functions.
- It gives full buffer control to user.
- Compression can be done in:
- - a single step (described as Simple Functions)
- - a single step, reusing a context (described in Advanced Functions)
- - unbounded multiple steps (described as Streaming compression)
-
- lz4.h generates and decodes LZ4-compressed blocks (doc/lz4_Block_format.md).
- Decompressing such a compressed block requires additional metadata.
- Exact metadata depends on exact decompression function.
- For the typical case of LZ4_decompress_safe(),
- metadata includes block's compressed size, and maximum bound of decompressed size.
- Each application is free to encode and pass such metadata in whichever way it wants.
-
- lz4.h only handle blocks, it can not generate Frames.
-
- Blocks are different from Frames (doc/lz4_Frame_format.md).
- Frames bundle both blocks and metadata in a specified manner.
- Embedding metadata is required for compressed data to be self-contained and portable.
- Frame format is delivered through a companion API, declared in lz4frame.h.
- The `lz4` CLI can only manage frames.
-*/
-
-/*^***************************************************************
-* Export parameters
-*****************************************************************/
-/*
-* LZ4_DLL_EXPORT :
-* Enable exporting of functions when building a Windows DLL
-* LZ4LIB_VISIBILITY :
-* Control library symbols visibility.
-*/
-#ifndef LZ4LIB_VISIBILITY
-# if defined(__GNUC__) && (__GNUC__ >= 4)
-# define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default")))
-# else
-# define LZ4LIB_VISIBILITY
-# endif
-#endif
-#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1)
-# define LZ4LIB_API __declspec(dllexport) LZ4LIB_VISIBILITY
-#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1)
-# define LZ4LIB_API __declspec(dllimport) LZ4LIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
-#else
-# define LZ4LIB_API LZ4LIB_VISIBILITY
-#endif
-
-/*------ Version ------*/
-#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
-#define LZ4_VERSION_MINOR 9 /* for new (non-breaking) interface capabilities */
-#define LZ4_VERSION_RELEASE 2 /* for tweaks, bug-fixes, or development */
-
-#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
-
-#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE
-#define LZ4_QUOTE(str) #str
-#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str)
-#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION)
-
-LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version */
-LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; useful to check dll version */
-
-
-/*-************************************
-* Tuning parameter
-**************************************/
-/*!
- * LZ4_MEMORY_USAGE :
- * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
- * Increasing memory usage improves compression ratio.
- * Reduced memory usage may improve speed, thanks to better cache locality.
- * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
- */
-#ifndef LZ4_MEMORY_USAGE
-# define LZ4_MEMORY_USAGE 14
-#endif
-
-
-/*-************************************
-* Simple Functions
-**************************************/
-/*! LZ4_compress_default() :
- * Compresses 'srcSize' bytes from buffer 'src'
- * into already allocated 'dst' buffer of size 'dstCapacity'.
- * Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize).
- * It also runs faster, so it's a recommended setting.
- * If the function cannot compress 'src' into a more limited 'dst' budget,
- * compression stops *immediately*, and the function result is zero.
- * In which case, 'dst' content is undefined (invalid).
- * srcSize : max supported value is LZ4_MAX_INPUT_SIZE.
- * dstCapacity : size of buffer 'dst' (which must be already allocated)
- * @return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity)
- * or 0 if compression fails
- * Note : This function is protected against buffer overflow scenarios (never writes outside 'dst' buffer, nor read outside 'source' buffer).
- */
-LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity);
-
-/*! LZ4_decompress_safe() :
- * compressedSize : is the exact complete size of the compressed block.
- * dstCapacity : is the size of destination buffer (which must be already allocated), presumed an upper bound of decompressed size.
- * @return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity)
- * If destination buffer is not large enough, decoding will stop and output an error code (negative value).
- * If the source stream is detected malformed, the function will stop decoding and return a negative result.
- * Note 1 : This function is protected against malicious data packets :
- * it will never writes outside 'dst' buffer, nor read outside 'source' buffer,
- * even if the compressed block is maliciously modified to order the decoder to do these actions.
- * In such case, the decoder stops immediately, and considers the compressed block malformed.
- * Note 2 : compressedSize and dstCapacity must be provided to the function, the compressed block does not contain them.
- * The implementation is free to send / store / derive this information in whichever way is most beneficial.
- * If there is a need for a different format which bundles together both compressed data and its metadata, consider looking at lz4frame.h instead.
- */
-LZ4LIB_API int LZ4_decompress_safe (const char* src, char* dst, int compressedSize, int dstCapacity);
-
-
-/*-************************************
-* Advanced Functions
-**************************************/
-#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
-#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
-
-/*! LZ4_compressBound() :
- Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
- This function is primarily useful for memory allocation purposes (destination buffer size).
- Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
- Note that LZ4_compress_default() compresses faster when dstCapacity is >= LZ4_compressBound(srcSize)
- inputSize : max supported value is LZ4_MAX_INPUT_SIZE
- return : maximum output size in a "worst case" scenario
- or 0, if input size is incorrect (too large or negative)
-*/
-LZ4LIB_API int LZ4_compressBound(int inputSize);
-
-/*! LZ4_compress_fast() :
- Same as LZ4_compress_default(), but allows selection of "acceleration" factor.
- The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
- It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
- An acceleration value of "1" is the same as regular LZ4_compress_default()
- Values <= 0 will be replaced by ACCELERATION_DEFAULT (currently == 1, see lz4.c).
-*/
-LZ4LIB_API int LZ4_compress_fast (const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
-
-
-/*! LZ4_compress_fast_extState() :
- * Same as LZ4_compress_fast(), using an externally allocated memory space for its state.
- * Use LZ4_sizeofState() to know how much memory must be allocated,
- * and allocate it on 8-bytes boundaries (using `malloc()` typically).
- * Then, provide this buffer as `void* state` to compression function.
- */
-LZ4LIB_API int LZ4_sizeofState(void);
-LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
-
-
-/*! LZ4_compress_destSize() :
- * Reverse the logic : compresses as much data as possible from 'src' buffer
- * into already allocated buffer 'dst', of size >= 'targetDestSize'.
- * This function either compresses the entire 'src' content into 'dst' if it's large enough,
- * or fill 'dst' buffer completely with as much data as possible from 'src'.
- * note: acceleration parameter is fixed to "default".
- *
- * *srcSizePtr : will be modified to indicate how many bytes where read from 'src' to fill 'dst'.
- * New value is necessarily <= input value.
- * @return : Nb bytes written into 'dst' (necessarily <= targetDestSize)
- * or 0 if compression fails.
-*/
-LZ4LIB_API int LZ4_compress_destSize (const char* src, char* dst, int* srcSizePtr, int targetDstSize);
-
-
-/*! LZ4_decompress_safe_partial() :
- * Decompress an LZ4 compressed block, of size 'srcSize' at position 'src',
- * into destination buffer 'dst' of size 'dstCapacity'.
- * Up to 'targetOutputSize' bytes will be decoded.
- * The function stops decoding on reaching this objective,
- * which can boost performance when only the beginning of a block is required.
- *
- * @return : the number of bytes decoded in `dst` (necessarily <= dstCapacity)
- * If source stream is detected malformed, function returns a negative result.
- *
- * Note : @return can be < targetOutputSize, if compressed block contains less data.
- *
- * Note 2 : this function features 2 parameters, targetOutputSize and dstCapacity,
- * and expects targetOutputSize <= dstCapacity.
- * It effectively stops decoding on reaching targetOutputSize,
- * so dstCapacity is kind of redundant.
- * This is because in a previous version of this function,
- * decoding operation would not "break" a sequence in the middle.
- * As a consequence, there was no guarantee that decoding would stop at exactly targetOutputSize,
- * it could write more bytes, though only up to dstCapacity.
- * Some "margin" used to be required for this operation to work properly.
- * This is no longer necessary.
- * The function nonetheless keeps its signature, in an effort to not break API.
- */
-LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcSize, int targetOutputSize, int dstCapacity);
-
-
-/*-*********************************************
-* Streaming Compression Functions
-***********************************************/
-typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */
-
-LZ4LIB_API LZ4_stream_t* LZ4_createStream(void);
-LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr);
-
-/*! LZ4_resetStream_fast() : v1.9.0+
- * Use this to prepare an LZ4_stream_t for a new chain of dependent blocks
- * (e.g., LZ4_compress_fast_continue()).
- *
- * An LZ4_stream_t must be initialized once before usage.
- * This is automatically done when created by LZ4_createStream().
- * However, should the LZ4_stream_t be simply declared on stack (for example),
- * it's necessary to initialize it first, using LZ4_initStream().
- *
- * After init, start any new stream with LZ4_resetStream_fast().
- * A same LZ4_stream_t can be re-used multiple times consecutively
- * and compress multiple streams,
- * provided that it starts each new stream with LZ4_resetStream_fast().
- *
- * LZ4_resetStream_fast() is much faster than LZ4_initStream(),
- * but is not compatible with memory regions containing garbage data.
- *
- * Note: it's only useful to call LZ4_resetStream_fast()
- * in the context of streaming compression.
- * The *extState* functions perform their own resets.
- * Invoking LZ4_resetStream_fast() before is redundant, and even counterproductive.
- */
-LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr);
-
-/*! LZ4_loadDict() :
- * Use this function to reference a static dictionary into LZ4_stream_t.
- * The dictionary must remain available during compression.
- * LZ4_loadDict() triggers a reset, so any previous data will be forgotten.
- * The same dictionary will have to be loaded on decompression side for successful decoding.
- * Dictionary are useful for better compression of small data (KB range).
- * While LZ4 accept any input as dictionary,
- * results are generally better when using Zstandard's Dictionary Builder.
- * Loading a size of 0 is allowed, and is the same as reset.
- * @return : loaded dictionary size, in bytes (necessarily <= 64 KB)
- */
-LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
-
-/*! LZ4_compress_fast_continue() :
- * Compress 'src' content using data from previously compressed blocks, for better compression ratio.
- * 'dst' buffer must be already allocated.
- * If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
- *
- * @return : size of compressed block
- * or 0 if there is an error (typically, cannot fit into 'dst').
- *
- * Note 1 : Each invocation to LZ4_compress_fast_continue() generates a new block.
- * Each block has precise boundaries.
- * Each block must be decompressed separately, calling LZ4_decompress_*() with relevant metadata.
- * It's not possible to append blocks together and expect a single invocation of LZ4_decompress_*() to decompress them together.
- *
- * Note 2 : The previous 64KB of source data is __assumed__ to remain present, unmodified, at same address in memory !
- *
- * Note 3 : When input is structured as a double-buffer, each buffer can have any size, including < 64 KB.
- * Make sure that buffers are separated, by at least one byte.
- * This construction ensures that each block only depends on previous block.
- *
- * Note 4 : If input buffer is a ring-buffer, it can have any size, including < 64 KB.
- *
- * Note 5 : After an error, the stream status is undefined (invalid), it can only be reset or freed.
- */
-LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
-
-/*! LZ4_saveDict() :
- * If last 64KB data cannot be guaranteed to remain available at its current memory location,
- * save it into a safer place (char* safeBuffer).
- * This is schematically equivalent to a memcpy() followed by LZ4_loadDict(),
- * but is much faster, because LZ4_saveDict() doesn't need to rebuild tables.
- * @return : saved dictionary size in bytes (necessarily <= maxDictSize), or 0 if error.
- */
-LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int maxDictSize);
-
-
-/*-**********************************************
-* Streaming Decompression Functions
-* Bufferless synchronous API
-************************************************/
-typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* tracking context */
-
-/*! LZ4_createStreamDecode() and LZ4_freeStreamDecode() :
- * creation / destruction of streaming decompression tracking context.
- * A tracking context can be re-used multiple times.
- */
-LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void);
-LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
-
-/*! LZ4_setStreamDecode() :
- * An LZ4_streamDecode_t context can be allocated once and re-used multiple times.
- * Use this function to start decompression of a new stream of blocks.
- * A dictionary can optionally be set. Use NULL or size 0 for a reset order.
- * Dictionary is presumed stable : it must remain accessible and unmodified during next decompression.
- * @return : 1 if OK, 0 if error
- */
-LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
-
-/*! LZ4_decoderRingBufferSize() : v1.8.2+
- * Note : in a ring buffer scenario (optional),
- * blocks are presumed decompressed next to each other
- * up to the moment there is not enough remaining space for next block (remainingSize < maxBlockSize),
- * at which stage it resumes from beginning of ring buffer.
- * When setting such a ring buffer for streaming decompression,
- * provides the minimum size of this ring buffer
- * to be compatible with any source respecting maxBlockSize condition.
- * @return : minimum ring buffer size,
- * or 0 if there is an error (invalid maxBlockSize).
- */
-LZ4LIB_API int LZ4_decoderRingBufferSize(int maxBlockSize);
-#define LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize) (65536 + 14 + (maxBlockSize)) /* for static allocation; maxBlockSize presumed valid */
-
-/*! LZ4_decompress_*_continue() :
- * These decoding functions allow decompression of consecutive blocks in "streaming" mode.
- * A block is an unsplittable entity, it must be presented entirely to a decompression function.
- * Decompression functions only accepts one block at a time.
- * The last 64KB of previously decoded data *must* remain available and unmodified at the memory position where they were decoded.
- * If less than 64KB of data has been decoded, all the data must be present.
- *
- * Special : if decompression side sets a ring buffer, it must respect one of the following conditions :
- * - Decompression buffer size is _at least_ LZ4_decoderRingBufferSize(maxBlockSize).
- * maxBlockSize is the maximum size of any single block. It can have any value > 16 bytes.
- * In which case, encoding and decoding buffers do not need to be synchronized.
- * Actually, data can be produced by any source compliant with LZ4 format specification, and respecting maxBlockSize.
- * - Synchronized mode :
- * Decompression buffer size is _exactly_ the same as compression buffer size,
- * and follows exactly same update rule (block boundaries at same positions),
- * and decoding function is provided with exact decompressed size of each block (exception for last block of the stream),
- * _then_ decoding & encoding ring buffer can have any size, including small ones ( < 64 KB).
- * - Decompression buffer is larger than encoding buffer, by a minimum of maxBlockSize more bytes.
- * In which case, encoding and decoding buffers do not need to be synchronized,
- * and encoding ring buffer can have any size, including small ones ( < 64 KB).
- *
- * Whenever these conditions are not possible,
- * save the last 64KB of decoded data into a safe buffer where it can't be modified during decompression,
- * then indicate where this data is saved using LZ4_setStreamDecode(), before decompressing next block.
-*/
-LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int srcSize, int dstCapacity);
-
-
-/*! LZ4_decompress_*_usingDict() :
- * These decoding functions work the same as
- * a combination of LZ4_setStreamDecode() followed by LZ4_decompress_*_continue()
- * They are stand-alone, and don't need an LZ4_streamDecode_t structure.
- * Dictionary is presumed stable : it must remain accessible and unmodified during decompression.
- * Performance tip : Decompression speed can be substantially increased
- * when dst == dictStart + dictSize.
- */
-LZ4LIB_API int LZ4_decompress_safe_usingDict (const char* src, char* dst, int srcSize, int dstCapcity, const char* dictStart, int dictSize);
-
-#endif /* LZ4_H_2983827168210 */
-
-
-/*^*************************************
- * !!!!!! STATIC LINKING ONLY !!!!!!
- ***************************************/
-
-/*-****************************************************************************
- * Experimental section
- *
- * Symbols declared in this section must be considered unstable. Their
- * signatures or semantics may change, or they may be removed altogether in the
- * future. They are therefore only safe to depend on when the caller is
- * statically linked against the library.
- *
- * To protect against unsafe usage, not only are the declarations guarded,
- * the definitions are hidden by default
- * when building LZ4 as a shared/dynamic library.
- *
- * In order to access these declarations,
- * define LZ4_STATIC_LINKING_ONLY in your application
- * before including LZ4's headers.
- *
- * In order to make their implementations accessible dynamically, you must
- * define LZ4_PUBLISH_STATIC_FUNCTIONS when building the LZ4 library.
- ******************************************************************************/
-
-#ifdef LZ4_STATIC_LINKING_ONLY
-
-#ifndef LZ4_STATIC_3504398509
-#define LZ4_STATIC_3504398509
-
-#ifdef LZ4_PUBLISH_STATIC_FUNCTIONS
-#define LZ4LIB_STATIC_API LZ4LIB_API
-#else
-#define LZ4LIB_STATIC_API
-#endif
-
-
-/*! LZ4_compress_fast_extState_fastReset() :
- * A variant of LZ4_compress_fast_extState().
- *
- * Using this variant avoids an expensive initialization step.
- * It is only safe to call if the state buffer is known to be correctly initialized already
- * (see above comment on LZ4_resetStream_fast() for a definition of "correctly initialized").
- * From a high level, the difference is that
- * this function initializes the provided state with a call to something like LZ4_resetStream_fast()
- * while LZ4_compress_fast_extState() starts with a call to LZ4_resetStream().
- */
-LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
-
-/*! LZ4_attach_dictionary() :
- * This is an experimental API that allows
- * efficient use of a static dictionary many times.
- *
- * Rather than re-loading the dictionary buffer into a working context before
- * each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a
- * working LZ4_stream_t, this function introduces a no-copy setup mechanism,
- * in which the working stream references the dictionary stream in-place.
- *
- * Several assumptions are made about the state of the dictionary stream.
- * Currently, only streams which have been prepared by LZ4_loadDict() should
- * be expected to work.
- *
- * Alternatively, the provided dictionaryStream may be NULL,
- * in which case any existing dictionary stream is unset.
- *
- * If a dictionary is provided, it replaces any pre-existing stream history.
- * The dictionary contents are the only history that can be referenced and
- * logically immediately precede the data compressed in the first subsequent
- * compression call.
- *
- * The dictionary will only remain attached to the working stream through the
- * first compression call, at the end of which it is cleared. The dictionary
- * stream (and source buffer) must remain in-place / accessible / unchanged
- * through the completion of the first compression call on the stream.
- */
-LZ4LIB_STATIC_API void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const LZ4_stream_t* dictionaryStream);
-
-
-/*! In-place compression and decompression
- *
- * It's possible to have input and output sharing the same buffer,
- * for highly contrained memory environments.
- * In both cases, it requires input to lay at the end of the buffer,
- * and decompression to start at beginning of the buffer.
- * Buffer size must feature some margin, hence be larger than final size.
- *
- * |<------------------------buffer--------------------------------->|
- * |<-----------compressed data--------->|
- * |<-----------decompressed size------------------>|
- * |<----margin---->|
- *
- * This technique is more useful for decompression,
- * since decompressed size is typically larger,
- * and margin is short.
- *
- * In-place decompression will work inside any buffer
- * which size is >= LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize).
- * This presumes that decompressedSize > compressedSize.
- * Otherwise, it means compression actually expanded data,
- * and it would be more efficient to store such data with a flag indicating it's not compressed.
- * This can happen when data is not compressible (already compressed, or encrypted).
- *
- * For in-place compression, margin is larger, as it must be able to cope with both
- * history preservation, requiring input data to remain unmodified up to LZ4_DISTANCE_MAX,
- * and data expansion, which can happen when input is not compressible.
- * As a consequence, buffer size requirements are much higher,
- * and memory savings offered by in-place compression are more limited.
- *
- * There are ways to limit this cost for compression :
- * - Reduce history size, by modifying LZ4_DISTANCE_MAX.
- * Note that it is a compile-time constant, so all compressions will apply this limit.
- * Lower values will reduce compression ratio, except when input_size < LZ4_DISTANCE_MAX,
- * so it's a reasonable trick when inputs are known to be small.
- * - Require the compressor to deliver a "maximum compressed size".
- * This is the `dstCapacity` parameter in `LZ4_compress*()`.
- * When this size is < LZ4_COMPRESSBOUND(inputSize), then compression can fail,
- * in which case, the return code will be 0 (zero).
- * The caller must be ready for these cases to happen,
- * and typically design a backup scheme to send data uncompressed.
- * The combination of both techniques can significantly reduce
- * the amount of margin required for in-place compression.
- *
- * In-place compression can work in any buffer
- * which size is >= (maxCompressedSize)
- * with maxCompressedSize == LZ4_COMPRESSBOUND(srcSize) for guaranteed compression success.
- * LZ4_COMPRESS_INPLACE_BUFFER_SIZE() depends on both maxCompressedSize and LZ4_DISTANCE_MAX,
- * so it's possible to reduce memory requirements by playing with them.
- */
-
-#define LZ4_DECOMPRESS_INPLACE_MARGIN(compressedSize) (((compressedSize) >> 8) + 32)
-#define LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize) ((decompressedSize) + LZ4_DECOMPRESS_INPLACE_MARGIN(decompressedSize)) /**< note: presumes that compressedSize < decompressedSize. note2: margin is overestimated a bit, since it could use compressedSize instead */
-
-#ifndef LZ4_DISTANCE_MAX /* history window size; can be user-defined at compile time */
-# define LZ4_DISTANCE_MAX 65535 /* set to maximum value by default */
-#endif
-
-#define LZ4_COMPRESS_INPLACE_MARGIN (LZ4_DISTANCE_MAX + 32) /* LZ4_DISTANCE_MAX can be safely replaced by srcSize when it's smaller */
-#define LZ4_COMPRESS_INPLACE_BUFFER_SIZE(maxCompressedSize) ((maxCompressedSize) + LZ4_COMPRESS_INPLACE_MARGIN) /**< maxCompressedSize is generally LZ4_COMPRESSBOUND(inputSize), but can be set to any lower value, with the risk that compression can fail (return code 0(zero)) */
-
-#endif /* LZ4_STATIC_3504398509 */
-#endif /* LZ4_STATIC_LINKING_ONLY */
-
-
-
-#ifndef LZ4_H_98237428734687
-#define LZ4_H_98237428734687
-
-/*-************************************************************
- * PRIVATE DEFINITIONS
- **************************************************************
- * Do not use these definitions directly.
- * They are only exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`.
- * Accessing members will expose code to API and/or ABI break in future versions of the library.
- **************************************************************/
-#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2)
-#define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE)
-#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */
-
-#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
-#include <stdint.h>
-
-typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
-struct LZ4_stream_t_internal {
- uint32_t hashTable[LZ4_HASH_SIZE_U32];
- uint32_t currentOffset;
- uint16_t dirty;
- uint16_t tableType;
- const uint8_t* dictionary;
- const LZ4_stream_t_internal* dictCtx;
- uint32_t dictSize;
-};
-
-typedef struct {
- const uint8_t* externalDict;
- size_t extDictSize;
- const uint8_t* prefixEnd;
- size_t prefixSize;
-} LZ4_streamDecode_t_internal;
-
-#else
-
-typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
-struct LZ4_stream_t_internal {
- unsigned int hashTable[LZ4_HASH_SIZE_U32];
- unsigned int currentOffset;
- unsigned short dirty;
- unsigned short tableType;
- const unsigned char* dictionary;
- const LZ4_stream_t_internal* dictCtx;
- unsigned int dictSize;
-};
-
-typedef struct {
- const unsigned char* externalDict;
- const unsigned char* prefixEnd;
- size_t extDictSize;
- size_t prefixSize;
-} LZ4_streamDecode_t_internal;
-
-#endif
-
-/*! LZ4_stream_t :
- * information structure to track an LZ4 stream.
- * LZ4_stream_t can also be created using LZ4_createStream(), which is recommended.
- * The structure definition can be convenient for static allocation
- * (on stack, or as part of larger structure).
- * Init this structure with LZ4_initStream() before first use.
- * note : only use this definition in association with static linking !
- * this definition is not API/ABI safe, and may change in a future version.
- */
-#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4 + ((sizeof(void*)==16) ? 4 : 0) /*AS-400*/ )
-#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(unsigned long long))
-union LZ4_stream_u {
- unsigned long long table[LZ4_STREAMSIZE_U64];
- LZ4_stream_t_internal internal_donotuse;
-} ; /* previously typedef'd to LZ4_stream_t */
-
-/*! LZ4_initStream() : v1.9.0+
- * An LZ4_stream_t structure must be initialized at least once.
- * This is automatically done when invoking LZ4_createStream(),
- * but it's not when the structure is simply declared on stack (for example).
- *
- * Use LZ4_initStream() to properly initialize a newly declared LZ4_stream_t.
- * It can also initialize any arbitrary buffer of sufficient size,
- * and will @return a pointer of proper type upon initialization.
- *
- * Note : initialization fails if size and alignment conditions are not respected.
- * In which case, the function will @return NULL.
- * Note2: An LZ4_stream_t structure guarantees correct alignment and size.
- * Note3: Before v1.9.0, use LZ4_resetStream() instead
- */
-LZ4LIB_API LZ4_stream_t* LZ4_initStream (void* buffer, size_t size);
-
-
-/*! LZ4_streamDecode_t :
- * information structure to track an LZ4 stream during decompression.
- * init this structure using LZ4_setStreamDecode() before first use.
- * note : only use in association with static linking !
- * this definition is not API/ABI safe,
- * and may change in a future version !
- */
-#define LZ4_STREAMDECODESIZE_U64 (4 + ((sizeof(void*)==16) ? 2 : 0) /*AS-400*/ )
-#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
-union LZ4_streamDecode_u {
- unsigned long long table[LZ4_STREAMDECODESIZE_U64];
- LZ4_streamDecode_t_internal internal_donotuse;
-} ; /* previously typedef'd to LZ4_streamDecode_t */
-
-
-
-/*-************************************
-* Obsolete Functions
-**************************************/
-
-/*! Deprecation warnings
- *
- * Deprecated functions make the compiler generate a warning when invoked.
- * This is meant to invite users to update their source code.
- * Should deprecation warnings be a problem, it is generally possible to disable them,
- * typically with -Wno-deprecated-declarations for gcc
- * or _CRT_SECURE_NO_WARNINGS in Visual.
- *
- * Another method is to define LZ4_DISABLE_DEPRECATE_WARNINGS
- * before including the header file.
- */
-#ifdef LZ4_DISABLE_DEPRECATE_WARNINGS
-# define LZ4_DEPRECATED(message) /* disable deprecation warnings */
-#else
-# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
-# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */
-# define LZ4_DEPRECATED(message) [[deprecated(message)]]
-# elif (LZ4_GCC_VERSION >= 405) || defined(__clang__)
-# define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
-# elif (LZ4_GCC_VERSION >= 301)
-# define LZ4_DEPRECATED(message) __attribute__((deprecated))
-# elif defined(_MSC_VER)
-# define LZ4_DEPRECATED(message) __declspec(deprecated(message))
-# else
-# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler")
-# define LZ4_DEPRECATED(message)
-# endif
-#endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */
-
-/* Obsolete compression functions */
-LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress (const char* src, char* dest, int srcSize);
-LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress_limitedOutput (const char* src, char* dest, int srcSize, int maxOutputSize);
-LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
-LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
-LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
-LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
-
-/* Obsolete decompression functions */
-LZ4_DEPRECATED("use LZ4_decompress_fast() instead") LZ4LIB_API int LZ4_uncompress (const char* source, char* dest, int outputSize);
-LZ4_DEPRECATED("use LZ4_decompress_safe() instead") LZ4LIB_API int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize);
-
-/* Obsolete streaming functions; degraded functionality; do not use!
- *
- * In order to perform streaming compression, these functions depended on data
- * that is no longer tracked in the state. They have been preserved as well as
- * possible: using them will still produce a correct output. However, they don't
- * actually retain any history between compression calls. The compression ratio
- * achieved will therefore be no better than compressing each chunk
- * independently.
- */
-LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API void* LZ4_create (char* inputBuffer);
-LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API int LZ4_sizeofStreamState(void);
-LZ4_DEPRECATED("Use LZ4_resetStream() instead") LZ4LIB_API int LZ4_resetStreamState(void* state, char* inputBuffer);
-LZ4_DEPRECATED("Use LZ4_saveDict() instead") LZ4LIB_API char* LZ4_slideInputBuffer (void* state);
-
-/* Obsolete streaming decoding functions */
-LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") LZ4LIB_API int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize);
-LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize);
-
-/*! LZ4_decompress_fast() : **unsafe!**
- * These functions used to be faster than LZ4_decompress_safe(),
- * but it has changed, and they are now slower than LZ4_decompress_safe().
- * This is because LZ4_decompress_fast() doesn't know the input size,
- * and therefore must progress more cautiously in the input buffer to not read beyond the end of block.
- * On top of that `LZ4_decompress_fast()` is not protected vs malformed or malicious inputs, making it a security liability.
- * As a consequence, LZ4_decompress_fast() is strongly discouraged, and deprecated.
- *
- * The last remaining LZ4_decompress_fast() specificity is that
- * it can decompress a block without knowing its compressed size.
- * Such functionality could be achieved in a more secure manner,
- * by also providing the maximum size of input buffer,
- * but it would require new prototypes, and adaptation of the implementation to this new use case.
- *
- * Parameters:
- * originalSize : is the uncompressed size to regenerate.
- * `dst` must be already allocated, its size must be >= 'originalSize' bytes.
- * @return : number of bytes read from source buffer (== compressed size).
- * The function expects to finish at block's end exactly.
- * If the source stream is detected malformed, the function stops decoding and returns a negative result.
- * note : LZ4_decompress_fast*() requires originalSize. Thanks to this information, it never writes past the output buffer.
- * However, since it doesn't know its 'src' size, it may read an unknown amount of input, past input buffer bounds.
- * Also, since match offsets are not validated, match reads from 'src' may underflow too.
- * These issues never happen if input (compressed) data is correct.
- * But they may happen if input data is invalid (error or intentional tampering).
- * As a consequence, use these functions in trusted environments with trusted data **only**.
- */
-
-LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe() instead")
-LZ4LIB_API int LZ4_decompress_fast (const char* src, char* dst, int originalSize);
-LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_continue() instead")
-LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int originalSize);
-LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_usingDict() instead")
-LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int originalSize, const char* dictStart, int dictSize);
-
-/*! LZ4_resetStream() :
- * An LZ4_stream_t structure must be initialized at least once.
- * This is done with LZ4_initStream(), or LZ4_resetStream().
- * Consider switching to LZ4_initStream(),
- * invoking LZ4_resetStream() will trigger deprecation warnings in the future.
- */
-LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr);
-
-
-#endif /* LZ4_H_98237428734687 */
-
-
-#if defined (__cplusplus)
-}
-#endif
diff --git a/subprojects/lz4/include/lz4frame.h b/subprojects/lz4/include/lz4frame.h
deleted file mode 100644
index 391e484..0000000
--- a/subprojects/lz4/include/lz4frame.h
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- LZ4 auto-framing library
- Header File
- Copyright (C) 2011-2017, Yann Collet.
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - LZ4 source repository : https://github.com/lz4/lz4
- - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
-*/
-
-/* LZ4F is a stand-alone API able to create and decode LZ4 frames
- * conformant with specification v1.6.1 in doc/lz4_Frame_format.md .
- * Generated frames are compatible with `lz4` CLI.
- *
- * LZ4F also offers streaming capabilities.
- *
- * lz4.h is not required when using lz4frame.h,
- * except to extract common constant such as LZ4_VERSION_NUMBER.
- * */
-
-#ifndef LZ4F_H_09782039843
-#define LZ4F_H_09782039843
-
-#if defined (__cplusplus)
-extern "C" {
-#endif
-
-/* --- Dependency --- */
-#include <stddef.h> /* size_t */
-
-
-/**
- Introduction
-
- lz4frame.h implements LZ4 frame specification (doc/lz4_Frame_format.md).
- lz4frame.h provides frame compression functions that take care
- of encoding standard metadata alongside LZ4-compressed blocks.
-*/
-
-/*-***************************************************************
- * Compiler specifics
- *****************************************************************/
-/* LZ4_DLL_EXPORT :
- * Enable exporting of functions when building a Windows DLL
- * LZ4FLIB_API :
- * Control library symbols visibility.
- */
-#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1)
-# define LZ4FLIB_API __declspec(dllexport)
-#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1)
-# define LZ4FLIB_API __declspec(dllimport)
-#elif defined(__GNUC__) && (__GNUC__ >= 4)
-# define LZ4FLIB_API __attribute__ ((__visibility__ ("default")))
-#else
-# define LZ4FLIB_API
-#endif
-
-#ifdef LZ4F_DISABLE_DEPRECATE_WARNINGS
-# define LZ4F_DEPRECATE(x) x
-#else
-# if defined(_MSC_VER)
-# define LZ4F_DEPRECATE(x) x /* __declspec(deprecated) x - only works with C++ */
-# elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6))
-# define LZ4F_DEPRECATE(x) x __attribute__((deprecated))
-# else
-# define LZ4F_DEPRECATE(x) x /* no deprecation warning for this compiler */
-# endif
-#endif
-
-
-/*-************************************
- * Error management
- **************************************/
-typedef size_t LZ4F_errorCode_t;
-
-LZ4FLIB_API unsigned LZ4F_isError(LZ4F_errorCode_t code); /**< tells when a function result is an error code */
-LZ4FLIB_API const char* LZ4F_getErrorName(LZ4F_errorCode_t code); /**< return error code string; for debugging */
-
-
-/*-************************************
- * Frame compression types
- **************************************/
-/* #define LZ4F_ENABLE_OBSOLETE_ENUMS // uncomment to enable obsolete enums */
-#ifdef LZ4F_ENABLE_OBSOLETE_ENUMS
-# define LZ4F_OBSOLETE_ENUM(x) , LZ4F_DEPRECATE(x) = LZ4F_##x
-#else
-# define LZ4F_OBSOLETE_ENUM(x)
-#endif
-
-/* The larger the block size, the (slightly) better the compression ratio,
- * though there are diminishing returns.
- * Larger blocks also increase memory usage on both compression and decompression sides. */
-typedef enum {
- LZ4F_default=0,
- LZ4F_max64KB=4,
- LZ4F_max256KB=5,
- LZ4F_max1MB=6,
- LZ4F_max4MB=7
- LZ4F_OBSOLETE_ENUM(max64KB)
- LZ4F_OBSOLETE_ENUM(max256KB)
- LZ4F_OBSOLETE_ENUM(max1MB)
- LZ4F_OBSOLETE_ENUM(max4MB)
-} LZ4F_blockSizeID_t;
-
-/* Linked blocks sharply reduce inefficiencies when using small blocks,
- * they compress better.
- * However, some LZ4 decoders are only compatible with independent blocks */
-typedef enum {
- LZ4F_blockLinked=0,
- LZ4F_blockIndependent
- LZ4F_OBSOLETE_ENUM(blockLinked)
- LZ4F_OBSOLETE_ENUM(blockIndependent)
-} LZ4F_blockMode_t;
-
-typedef enum {
- LZ4F_noContentChecksum=0,
- LZ4F_contentChecksumEnabled
- LZ4F_OBSOLETE_ENUM(noContentChecksum)
- LZ4F_OBSOLETE_ENUM(contentChecksumEnabled)
-} LZ4F_contentChecksum_t;
-
-typedef enum {
- LZ4F_noBlockChecksum=0,
- LZ4F_blockChecksumEnabled
-} LZ4F_blockChecksum_t;
-
-typedef enum {
- LZ4F_frame=0,
- LZ4F_skippableFrame
- LZ4F_OBSOLETE_ENUM(skippableFrame)
-} LZ4F_frameType_t;
-
-#ifdef LZ4F_ENABLE_OBSOLETE_ENUMS
-typedef LZ4F_blockSizeID_t blockSizeID_t;
-typedef LZ4F_blockMode_t blockMode_t;
-typedef LZ4F_frameType_t frameType_t;
-typedef LZ4F_contentChecksum_t contentChecksum_t;
-#endif
-
-/*! LZ4F_frameInfo_t :
- * makes it possible to set or read frame parameters.
- * Structure must be first init to 0, using memset() or LZ4F_INIT_FRAMEINFO,
- * setting all parameters to default.
- * It's then possible to update selectively some parameters */
-typedef struct {
- LZ4F_blockSizeID_t blockSizeID; /* max64KB, max256KB, max1MB, max4MB; 0 == default */
- LZ4F_blockMode_t blockMode; /* LZ4F_blockLinked, LZ4F_blockIndependent; 0 == default */
- LZ4F_contentChecksum_t contentChecksumFlag; /* 1: frame terminated with 32-bit checksum of decompressed data; 0: disabled (default) */
- LZ4F_frameType_t frameType; /* read-only field : LZ4F_frame or LZ4F_skippableFrame */
- unsigned long long contentSize; /* Size of uncompressed content ; 0 == unknown */
- unsigned dictID; /* Dictionary ID, sent by compressor to help decoder select correct dictionary; 0 == no dictID provided */
- LZ4F_blockChecksum_t blockChecksumFlag; /* 1: each block followed by a checksum of block's compressed data; 0: disabled (default) */
-} LZ4F_frameInfo_t;
-
-#define LZ4F_INIT_FRAMEINFO { LZ4F_default, LZ4F_blockLinked, LZ4F_noContentChecksum, LZ4F_frame, 0ULL, 0U, LZ4F_noBlockChecksum } /* v1.8.3+ */
-
-/*! LZ4F_preferences_t :
- * makes it possible to supply advanced compression instructions to streaming interface.
- * Structure must be first init to 0, using memset() or LZ4F_INIT_PREFERENCES,
- * setting all parameters to default.
- * All reserved fields must be set to zero. */
-typedef struct {
- LZ4F_frameInfo_t frameInfo;
- int compressionLevel; /* 0: default (fast mode); values > LZ4HC_CLEVEL_MAX count as LZ4HC_CLEVEL_MAX; values < 0 trigger "fast acceleration" */
- unsigned autoFlush; /* 1: always flush; reduces usage of internal buffers */
- unsigned favorDecSpeed; /* 1: parser favors decompression speed vs compression ratio. Only works for high compression modes (>= LZ4HC_CLEVEL_OPT_MIN) */ /* v1.8.2+ */
- unsigned reserved[3]; /* must be zero for forward compatibility */
-} LZ4F_preferences_t;
-
-#define LZ4F_INIT_PREFERENCES { LZ4F_INIT_FRAMEINFO, 0, 0u, 0u, { 0u, 0u, 0u } } /* v1.8.3+ */
-
-
-/*-*********************************
-* Simple compression function
-***********************************/
-
-LZ4FLIB_API int LZ4F_compressionLevel_max(void); /* v1.8.0+ */
-
-/*! LZ4F_compressFrameBound() :
- * Returns the maximum possible compressed size with LZ4F_compressFrame() given srcSize and preferences.
- * `preferencesPtr` is optional. It can be replaced by NULL, in which case, the function will assume default preferences.
- * Note : this result is only usable with LZ4F_compressFrame().
- * It may also be used with LZ4F_compressUpdate() _if no flush() operation_ is performed.
- */
-LZ4FLIB_API size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr);
-
-/*! LZ4F_compressFrame() :
- * Compress an entire srcBuffer into a valid LZ4 frame.
- * dstCapacity MUST be >= LZ4F_compressFrameBound(srcSize, preferencesPtr).
- * The LZ4F_preferences_t structure is optional : you can provide NULL as argument. All preferences will be set to default.
- * @return : number of bytes written into dstBuffer.
- * or an error code if it fails (can be tested using LZ4F_isError())
- */
-LZ4FLIB_API size_t LZ4F_compressFrame(void* dstBuffer, size_t dstCapacity,
- const void* srcBuffer, size_t srcSize,
- const LZ4F_preferences_t* preferencesPtr);
-
-
-/*-***********************************
-* Advanced compression functions
-*************************************/
-typedef struct LZ4F_cctx_s LZ4F_cctx; /* incomplete type */
-typedef LZ4F_cctx* LZ4F_compressionContext_t; /* for compatibility with previous API version */
-
-typedef struct {
- unsigned stableSrc; /* 1 == src content will remain present on future calls to LZ4F_compress(); skip copying src content within tmp buffer */
- unsigned reserved[3];
-} LZ4F_compressOptions_t;
-
-/*--- Resource Management ---*/
-
-#define LZ4F_VERSION 100 /* This number can be used to check for an incompatible API breaking change */
-LZ4FLIB_API unsigned LZ4F_getVersion(void);
-
-/*! LZ4F_createCompressionContext() :
- * The first thing to do is to create a compressionContext object, which will be used in all compression operations.
- * This is achieved using LZ4F_createCompressionContext(), which takes as argument a version.
- * The version provided MUST be LZ4F_VERSION. It is intended to track potential version mismatch, notably when using DLL.
- * The function will provide a pointer to a fully allocated LZ4F_cctx object.
- * If @return != zero, there was an error during context creation.
- * Object can release its memory using LZ4F_freeCompressionContext();
- */
-LZ4FLIB_API LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_cctx** cctxPtr, unsigned version);
-LZ4FLIB_API LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_cctx* cctx);
-
-
-/*---- Compression ----*/
-
-#define LZ4F_HEADER_SIZE_MIN 7 /* LZ4 Frame header size can vary, depending on selected paramaters */
-#define LZ4F_HEADER_SIZE_MAX 19
-
-/* Size in bytes of a block header in little-endian format. Highest bit indicates if block data is uncompressed */
-#define LZ4F_BLOCK_HEADER_SIZE 4
-
-/* Size in bytes of a block checksum footer in little-endian format. */
-#define LZ4F_BLOCK_CHECKSUM_SIZE 4
-
-/* Size in bytes of the content checksum. */
-#define LZ4F_CONTENT_CHECKSUM_SIZE 4
-
-/*! LZ4F_compressBegin() :
- * will write the frame header into dstBuffer.
- * dstCapacity must be >= LZ4F_HEADER_SIZE_MAX bytes.
- * `prefsPtr` is optional : you can provide NULL as argument, all preferences will then be set to default.
- * @return : number of bytes written into dstBuffer for the header
- * or an error code (which can be tested using LZ4F_isError())
- */
-LZ4FLIB_API size_t LZ4F_compressBegin(LZ4F_cctx* cctx,
- void* dstBuffer, size_t dstCapacity,
- const LZ4F_preferences_t* prefsPtr);
-
-/*! LZ4F_compressBound() :
- * Provides minimum dstCapacity required to guarantee success of
- * LZ4F_compressUpdate(), given a srcSize and preferences, for a worst case scenario.
- * When srcSize==0, LZ4F_compressBound() provides an upper bound for LZ4F_flush() and LZ4F_compressEnd() instead.
- * Note that the result is only valid for a single invocation of LZ4F_compressUpdate().
- * When invoking LZ4F_compressUpdate() multiple times,
- * if the output buffer is gradually filled up instead of emptied and re-used from its start,
- * one must check if there is enough remaining capacity before each invocation, using LZ4F_compressBound().
- * @return is always the same for a srcSize and prefsPtr.
- * prefsPtr is optional : when NULL is provided, preferences will be set to cover worst case scenario.
- * tech details :
- * @return includes the possibility that internal buffer might already be filled by up to (blockSize-1) bytes.
- * It also includes frame footer (ending + checksum), since it might be generated by LZ4F_compressEnd().
- * @return doesn't include frame header, as it was already generated by LZ4F_compressBegin().
- */
-LZ4FLIB_API size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* prefsPtr);
-
-/*! LZ4F_compressUpdate() :
- * LZ4F_compressUpdate() can be called repetitively to compress as much data as necessary.
- * Important rule: dstCapacity MUST be large enough to ensure operation success even in worst case situations.
- * This value is provided by LZ4F_compressBound().
- * If this condition is not respected, LZ4F_compress() will fail (result is an errorCode).
- * LZ4F_compressUpdate() doesn't guarantee error recovery.
- * When an error occurs, compression context must be freed or resized.
- * `cOptPtr` is optional : NULL can be provided, in which case all options are set to default.
- * @return : number of bytes written into `dstBuffer` (it can be zero, meaning input data was just buffered).
- * or an error code if it fails (which can be tested using LZ4F_isError())
- */
-LZ4FLIB_API size_t LZ4F_compressUpdate(LZ4F_cctx* cctx,
- void* dstBuffer, size_t dstCapacity,
- const void* srcBuffer, size_t srcSize,
- const LZ4F_compressOptions_t* cOptPtr);
-
-/*! LZ4F_flush() :
- * When data must be generated and sent immediately, without waiting for a block to be completely filled,
- * it's possible to call LZ4_flush(). It will immediately compress any data buffered within cctx.
- * `dstCapacity` must be large enough to ensure the operation will be successful.
- * `cOptPtr` is optional : it's possible to provide NULL, all options will be set to default.
- * @return : nb of bytes written into dstBuffer (can be zero, when there is no data stored within cctx)
- * or an error code if it fails (which can be tested using LZ4F_isError())
- * Note : LZ4F_flush() is guaranteed to be successful when dstCapacity >= LZ4F_compressBound(0, prefsPtr).
- */
-LZ4FLIB_API size_t LZ4F_flush(LZ4F_cctx* cctx,
- void* dstBuffer, size_t dstCapacity,
- const LZ4F_compressOptions_t* cOptPtr);
-
-/*! LZ4F_compressEnd() :
- * To properly finish an LZ4 frame, invoke LZ4F_compressEnd().
- * It will flush whatever data remained within `cctx` (like LZ4_flush())
- * and properly finalize the frame, with an endMark and a checksum.
- * `cOptPtr` is optional : NULL can be provided, in which case all options will be set to default.
- * @return : nb of bytes written into dstBuffer, necessarily >= 4 (endMark),
- * or an error code if it fails (which can be tested using LZ4F_isError())
- * Note : LZ4F_compressEnd() is guaranteed to be successful when dstCapacity >= LZ4F_compressBound(0, prefsPtr).
- * A successful call to LZ4F_compressEnd() makes `cctx` available again for another compression task.
- */
-LZ4FLIB_API size_t LZ4F_compressEnd(LZ4F_cctx* cctx,
- void* dstBuffer, size_t dstCapacity,
- const LZ4F_compressOptions_t* cOptPtr);
-
-
-/*-*********************************
-* Decompression functions
-***********************************/
-typedef struct LZ4F_dctx_s LZ4F_dctx; /* incomplete type */
-typedef LZ4F_dctx* LZ4F_decompressionContext_t; /* compatibility with previous API versions */
-
-typedef struct {
- unsigned stableDst; /* pledges that last 64KB decompressed data will remain available unmodified. This optimization skips storage operations in tmp buffers. */
- unsigned reserved[3]; /* must be set to zero for forward compatibility */
-} LZ4F_decompressOptions_t;
-
-
-/* Resource management */
-
-/*! LZ4F_createDecompressionContext() :
- * Create an LZ4F_dctx object, to track all decompression operations.
- * The version provided MUST be LZ4F_VERSION.
- * The function provides a pointer to an allocated and initialized LZ4F_dctx object.
- * The result is an errorCode, which can be tested using LZ4F_isError().
- * dctx memory can be released using LZ4F_freeDecompressionContext();
- * Result of LZ4F_freeDecompressionContext() indicates current state of decompressionContext when being released.
- * That is, it should be == 0 if decompression has been completed fully and correctly.
- */
-LZ4FLIB_API LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_dctx** dctxPtr, unsigned version);
-LZ4FLIB_API LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_dctx* dctx);
-
-
-/*-***********************************
-* Streaming decompression functions
-*************************************/
-
-#define LZ4F_MIN_SIZE_TO_KNOW_HEADER_LENGTH 5
-
-/*! LZ4F_headerSize() : v1.9.0+
- * Provide the header size of a frame starting at `src`.
- * `srcSize` must be >= LZ4F_MIN_SIZE_TO_KNOW_HEADER_LENGTH,
- * which is enough to decode the header length.
- * @return : size of frame header
- * or an error code, which can be tested using LZ4F_isError()
- * note : Frame header size is variable, but is guaranteed to be
- * >= LZ4F_HEADER_SIZE_MIN bytes, and <= LZ4F_HEADER_SIZE_MAX bytes.
- */
-size_t LZ4F_headerSize(const void* src, size_t srcSize);
-
-/*! LZ4F_getFrameInfo() :
- * This function extracts frame parameters (max blockSize, dictID, etc.).
- * Its usage is optional: user can call LZ4F_decompress() directly.
- *
- * Extracted information will fill an existing LZ4F_frameInfo_t structure.
- * This can be useful for allocation and dictionary identification purposes.
- *
- * LZ4F_getFrameInfo() can work in the following situations :
- *
- * 1) At the beginning of a new frame, before any invocation of LZ4F_decompress().
- * It will decode header from `srcBuffer`,
- * consuming the header and starting the decoding process.
- *
- * Input size must be large enough to contain the full frame header.
- * Frame header size can be known beforehand by LZ4F_headerSize().
- * Frame header size is variable, but is guaranteed to be >= LZ4F_HEADER_SIZE_MIN bytes,
- * and not more than <= LZ4F_HEADER_SIZE_MAX bytes.
- * Hence, blindly providing LZ4F_HEADER_SIZE_MAX bytes or more will always work.
- * It's allowed to provide more input data than the header size,
- * LZ4F_getFrameInfo() will only consume the header.
- *
- * If input size is not large enough,
- * aka if it's smaller than header size,
- * function will fail and return an error code.
- *
- * 2) After decoding has been started,
- * it's possible to invoke LZ4F_getFrameInfo() anytime
- * to extract already decoded frame parameters stored within dctx.
- *
- * Note that, if decoding has barely started,
- * and not yet read enough information to decode the header,
- * LZ4F_getFrameInfo() will fail.
- *
- * The number of bytes consumed from srcBuffer will be updated in *srcSizePtr (necessarily <= original value).
- * LZ4F_getFrameInfo() only consumes bytes when decoding has not yet started,
- * and when decoding the header has been successful.
- * Decompression must then resume from (srcBuffer + *srcSizePtr).
- *
- * @return : a hint about how many srcSize bytes LZ4F_decompress() expects for next call,
- * or an error code which can be tested using LZ4F_isError().
- * note 1 : in case of error, dctx is not modified. Decoding operation can resume from beginning safely.
- * note 2 : frame parameters are *copied into* an already allocated LZ4F_frameInfo_t structure.
- */
-LZ4FLIB_API size_t LZ4F_getFrameInfo(LZ4F_dctx* dctx,
- LZ4F_frameInfo_t* frameInfoPtr,
- const void* srcBuffer, size_t* srcSizePtr);
-
-/*! LZ4F_decompress() :
- * Call this function repetitively to regenerate compressed data from `srcBuffer`.
- * The function will read up to *srcSizePtr bytes from srcBuffer,
- * and decompress data into dstBuffer, of capacity *dstSizePtr.
- *
- * The nb of bytes consumed from srcBuffer will be written into *srcSizePtr (necessarily <= original value).
- * The nb of bytes decompressed into dstBuffer will be written into *dstSizePtr (necessarily <= original value).
- *
- * The function does not necessarily read all input bytes, so always check value in *srcSizePtr.
- * Unconsumed source data must be presented again in subsequent invocations.
- *
- * `dstBuffer` can freely change between each consecutive function invocation.
- * `dstBuffer` content will be overwritten.
- *
- * @return : an hint of how many `srcSize` bytes LZ4F_decompress() expects for next call.
- * Schematically, it's the size of the current (or remaining) compressed block + header of next block.
- * Respecting the hint provides some small speed benefit, because it skips intermediate buffers.
- * This is just a hint though, it's always possible to provide any srcSize.
- *
- * When a frame is fully decoded, @return will be 0 (no more data expected).
- * When provided with more bytes than necessary to decode a frame,
- * LZ4F_decompress() will stop reading exactly at end of current frame, and @return 0.
- *
- * If decompression failed, @return is an error code, which can be tested using LZ4F_isError().
- * After a decompression error, the `dctx` context is not resumable.
- * Use LZ4F_resetDecompressionContext() to return to clean state.
- *
- * After a frame is fully decoded, dctx can be used again to decompress another frame.
- */
-LZ4FLIB_API size_t LZ4F_decompress(LZ4F_dctx* dctx,
- void* dstBuffer, size_t* dstSizePtr,
- const void* srcBuffer, size_t* srcSizePtr,
- const LZ4F_decompressOptions_t* dOptPtr);
-
-
-/*! LZ4F_resetDecompressionContext() : added in v1.8.0
- * In case of an error, the context is left in "undefined" state.
- * In which case, it's necessary to reset it, before re-using it.
- * This method can also be used to abruptly stop any unfinished decompression,
- * and start a new one using same context resources. */
-LZ4FLIB_API void LZ4F_resetDecompressionContext(LZ4F_dctx* dctx); /* always successful */
-
-
-
-#if defined (__cplusplus)
-}
-#endif
-
-#endif /* LZ4F_H_09782039843 */
-
-#if defined(LZ4F_STATIC_LINKING_ONLY) && !defined(LZ4F_H_STATIC_09782039843)
-#define LZ4F_H_STATIC_09782039843
-
-#if defined (__cplusplus)
-extern "C" {
-#endif
-
-/* These declarations are not stable and may change in the future.
- * They are therefore only safe to depend on
- * when the caller is statically linked against the library.
- * To access their declarations, define LZ4F_STATIC_LINKING_ONLY.
- *
- * By default, these symbols aren't published into shared/dynamic libraries.
- * You can override this behavior and force them to be published
- * by defining LZ4F_PUBLISH_STATIC_FUNCTIONS.
- * Use at your own risk.
- */
-#ifdef LZ4F_PUBLISH_STATIC_FUNCTIONS
-#define LZ4FLIB_STATIC_API LZ4FLIB_API
-#else
-#define LZ4FLIB_STATIC_API
-#endif
-
-
-/* --- Error List --- */
-#define LZ4F_LIST_ERRORS(ITEM) \
- ITEM(OK_NoError) \
- ITEM(ERROR_GENERIC) \
- ITEM(ERROR_maxBlockSize_invalid) \
- ITEM(ERROR_blockMode_invalid) \
- ITEM(ERROR_contentChecksumFlag_invalid) \
- ITEM(ERROR_compressionLevel_invalid) \
- ITEM(ERROR_headerVersion_wrong) \
- ITEM(ERROR_blockChecksum_invalid) \
- ITEM(ERROR_reservedFlag_set) \
- ITEM(ERROR_allocation_failed) \
- ITEM(ERROR_srcSize_tooLarge) \
- ITEM(ERROR_dstMaxSize_tooSmall) \
- ITEM(ERROR_frameHeader_incomplete) \
- ITEM(ERROR_frameType_unknown) \
- ITEM(ERROR_frameSize_wrong) \
- ITEM(ERROR_srcPtr_wrong) \
- ITEM(ERROR_decompressionFailed) \
- ITEM(ERROR_headerChecksum_invalid) \
- ITEM(ERROR_contentChecksum_invalid) \
- ITEM(ERROR_frameDecoding_alreadyStarted) \
- ITEM(ERROR_maxCode)
-
-#define LZ4F_GENERATE_ENUM(ENUM) LZ4F_##ENUM,
-
-/* enum list is exposed, to handle specific errors */
-typedef enum { LZ4F_LIST_ERRORS(LZ4F_GENERATE_ENUM)
- _LZ4F_dummy_error_enum_for_c89_never_used } LZ4F_errorCodes;
-
-LZ4FLIB_STATIC_API LZ4F_errorCodes LZ4F_getErrorCode(size_t functionResult);
-
-LZ4FLIB_STATIC_API size_t LZ4F_getBlockSize(unsigned);
-
-/**********************************
- * Bulk processing dictionary API
- *********************************/
-
-/* A Dictionary is useful for the compression of small messages (KB range).
- * It dramatically improves compression efficiency.
- *
- * LZ4 can ingest any input as dictionary, though only the last 64 KB are useful.
- * Best results are generally achieved by using Zstandard's Dictionary Builder
- * to generate a high-quality dictionary from a set of samples.
- *
- * Loading a dictionary has a cost, since it involves construction of tables.
- * The Bulk processing dictionary API makes it possible to share this cost
- * over an arbitrary number of compression jobs, even concurrently,
- * markedly improving compression latency for these cases.
- *
- * The same dictionary will have to be used on the decompression side
- * for decoding to be successful.
- * To help identify the correct dictionary at decoding stage,
- * the frame header allows optional embedding of a dictID field.
- */
-typedef struct LZ4F_CDict_s LZ4F_CDict;
-
-/*! LZ4_createCDict() :
- * When compressing multiple messages / blocks using the same dictionary, it's recommended to load it just once.
- * LZ4_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay.
- * LZ4_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only.
- * `dictBuffer` can be released after LZ4_CDict creation, since its content is copied within CDict */
-LZ4FLIB_STATIC_API LZ4F_CDict* LZ4F_createCDict(const void* dictBuffer, size_t dictSize);
-LZ4FLIB_STATIC_API void LZ4F_freeCDict(LZ4F_CDict* CDict);
-
-
-/*! LZ4_compressFrame_usingCDict() :
- * Compress an entire srcBuffer into a valid LZ4 frame using a digested Dictionary.
- * cctx must point to a context created by LZ4F_createCompressionContext().
- * If cdict==NULL, compress without a dictionary.
- * dstBuffer MUST be >= LZ4F_compressFrameBound(srcSize, preferencesPtr).
- * If this condition is not respected, function will fail (@return an errorCode).
- * The LZ4F_preferences_t structure is optional : you may provide NULL as argument,
- * but it's not recommended, as it's the only way to provide dictID in the frame header.
- * @return : number of bytes written into dstBuffer.
- * or an error code if it fails (can be tested using LZ4F_isError()) */
-LZ4FLIB_STATIC_API size_t LZ4F_compressFrame_usingCDict(
- LZ4F_cctx* cctx,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize,
- const LZ4F_CDict* cdict,
- const LZ4F_preferences_t* preferencesPtr);
-
-
-/*! LZ4F_compressBegin_usingCDict() :
- * Inits streaming dictionary compression, and writes the frame header into dstBuffer.
- * dstCapacity must be >= LZ4F_HEADER_SIZE_MAX bytes.
- * `prefsPtr` is optional : you may provide NULL as argument,
- * however, it's the only way to provide dictID in the frame header.
- * @return : number of bytes written into dstBuffer for the header,
- * or an error code (which can be tested using LZ4F_isError()) */
-LZ4FLIB_STATIC_API size_t LZ4F_compressBegin_usingCDict(
- LZ4F_cctx* cctx,
- void* dstBuffer, size_t dstCapacity,
- const LZ4F_CDict* cdict,
- const LZ4F_preferences_t* prefsPtr);
-
-
-/*! LZ4F_decompress_usingDict() :
- * Same as LZ4F_decompress(), using a predefined dictionary.
- * Dictionary is used "in place", without any preprocessing.
- * It must remain accessible throughout the entire frame decoding. */
-LZ4FLIB_STATIC_API size_t LZ4F_decompress_usingDict(
- LZ4F_dctx* dctxPtr,
- void* dstBuffer, size_t* dstSizePtr,
- const void* srcBuffer, size_t* srcSizePtr,
- const void* dict, size_t dictSize,
- const LZ4F_decompressOptions_t* decompressOptionsPtr);
-
-#if defined (__cplusplus)
-}
-#endif
-
-#endif /* defined(LZ4F_STATIC_LINKING_ONLY) && !defined(LZ4F_H_STATIC_09782039843) */
diff --git a/subprojects/lz4/include/lz4hc.h b/subprojects/lz4/include/lz4hc.h
deleted file mode 100644
index 44e35bb..0000000
--- a/subprojects/lz4/include/lz4hc.h
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- LZ4 HC - High Compression Mode of LZ4
- Header File
- Copyright (C) 2011-2017, Yann Collet.
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - LZ4 source repository : https://github.com/lz4/lz4
- - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
-*/
-#ifndef LZ4_HC_H_19834876238432
-#define LZ4_HC_H_19834876238432
-
-#if defined (__cplusplus)
-extern "C" {
-#endif
-
-/* --- Dependency --- */
-/* note : lz4hc requires lz4.h/lz4.c for compilation */
-#include "lz4.h" /* stddef, LZ4LIB_API, LZ4_DEPRECATED */
-
-
-/* --- Useful constants --- */
-#define LZ4HC_CLEVEL_MIN 3
-#define LZ4HC_CLEVEL_DEFAULT 9
-#define LZ4HC_CLEVEL_OPT_MIN 10
-#define LZ4HC_CLEVEL_MAX 12
-
-
-/*-************************************
- * Block Compression
- **************************************/
-/*! LZ4_compress_HC() :
- * Compress data from `src` into `dst`, using the powerful but slower "HC" algorithm.
- * `dst` must be already allocated.
- * Compression is guaranteed to succeed if `dstCapacity >= LZ4_compressBound(srcSize)` (see "lz4.h")
- * Max supported `srcSize` value is LZ4_MAX_INPUT_SIZE (see "lz4.h")
- * `compressionLevel` : any value between 1 and LZ4HC_CLEVEL_MAX will work.
- * Values > LZ4HC_CLEVEL_MAX behave the same as LZ4HC_CLEVEL_MAX.
- * @return : the number of bytes written into 'dst'
- * or 0 if compression fails.
- */
-LZ4LIB_API int LZ4_compress_HC (const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel);
-
-
-/* Note :
- * Decompression functions are provided within "lz4.h" (BSD license)
- */
-
-
-/*! LZ4_compress_HC_extStateHC() :
- * Same as LZ4_compress_HC(), but using an externally allocated memory segment for `state`.
- * `state` size is provided by LZ4_sizeofStateHC().
- * Memory segment must be aligned on 8-bytes boundaries (which a normal malloc() should do properly).
- */
-LZ4LIB_API int LZ4_sizeofStateHC(void);
-LZ4LIB_API int LZ4_compress_HC_extStateHC(void* stateHC, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel);
-
-
-/*! LZ4_compress_HC_destSize() : v1.9.0+
- * Will compress as much data as possible from `src`
- * to fit into `targetDstSize` budget.
- * Result is provided in 2 parts :
- * @return : the number of bytes written into 'dst' (necessarily <= targetDstSize)
- * or 0 if compression fails.
- * `srcSizePtr` : on success, *srcSizePtr is updated to indicate how much bytes were read from `src`
- */
-LZ4LIB_API int LZ4_compress_HC_destSize(void* stateHC,
- const char* src, char* dst,
- int* srcSizePtr, int targetDstSize,
- int compressionLevel);
-
-
-/*-************************************
- * Streaming Compression
- * Bufferless synchronous API
- **************************************/
- typedef union LZ4_streamHC_u LZ4_streamHC_t; /* incomplete type (defined later) */
-
-/*! LZ4_createStreamHC() and LZ4_freeStreamHC() :
- * These functions create and release memory for LZ4 HC streaming state.
- * Newly created states are automatically initialized.
- * A same state can be used multiple times consecutively,
- * starting with LZ4_resetStreamHC_fast() to start a new stream of blocks.
- */
-LZ4LIB_API LZ4_streamHC_t* LZ4_createStreamHC(void);
-LZ4LIB_API int LZ4_freeStreamHC (LZ4_streamHC_t* streamHCPtr);
-
-/*
- These functions compress data in successive blocks of any size,
- using previous blocks as dictionary, to improve compression ratio.
- One key assumption is that previous blocks (up to 64 KB) remain read-accessible while compressing next blocks.
- There is an exception for ring buffers, which can be smaller than 64 KB.
- Ring-buffer scenario is automatically detected and handled within LZ4_compress_HC_continue().
-
- Before starting compression, state must be allocated and properly initialized.
- LZ4_createStreamHC() does both, though compression level is set to LZ4HC_CLEVEL_DEFAULT.
-
- Selecting the compression level can be done with LZ4_resetStreamHC_fast() (starts a new stream)
- or LZ4_setCompressionLevel() (anytime, between blocks in the same stream) (experimental).
- LZ4_resetStreamHC_fast() only works on states which have been properly initialized at least once,
- which is automatically the case when state is created using LZ4_createStreamHC().
-
- After reset, a first "fictional block" can be designated as initial dictionary,
- using LZ4_loadDictHC() (Optional).
-
- Invoke LZ4_compress_HC_continue() to compress each successive block.
- The number of blocks is unlimited.
- Previous input blocks, including initial dictionary when present,
- must remain accessible and unmodified during compression.
-
- It's allowed to update compression level anytime between blocks,
- using LZ4_setCompressionLevel() (experimental).
-
- 'dst' buffer should be sized to handle worst case scenarios
- (see LZ4_compressBound(), it ensures compression success).
- In case of failure, the API does not guarantee recovery,
- so the state _must_ be reset.
- To ensure compression success
- whenever `dst` buffer size cannot be made >= LZ4_compressBound(),
- consider using LZ4_compress_HC_continue_destSize().
-
- Whenever previous input blocks can't be preserved unmodified in-place during compression of next blocks,
- it's possible to copy the last blocks into a more stable memory space, using LZ4_saveDictHC().
- Return value of LZ4_saveDictHC() is the size of dictionary effectively saved into 'safeBuffer' (<= 64 KB)
-
- After completing a streaming compression,
- it's possible to start a new stream of blocks, using the same LZ4_streamHC_t state,
- just by resetting it, using LZ4_resetStreamHC_fast().
-*/
-
-LZ4LIB_API void LZ4_resetStreamHC_fast(LZ4_streamHC_t* streamHCPtr, int compressionLevel); /* v1.9.0+ */
-LZ4LIB_API int LZ4_loadDictHC (LZ4_streamHC_t* streamHCPtr, const char* dictionary, int dictSize);
-
-LZ4LIB_API int LZ4_compress_HC_continue (LZ4_streamHC_t* streamHCPtr,
- const char* src, char* dst,
- int srcSize, int maxDstSize);
-
-/*! LZ4_compress_HC_continue_destSize() : v1.9.0+
- * Similar to LZ4_compress_HC_continue(),
- * but will read as much data as possible from `src`
- * to fit into `targetDstSize` budget.
- * Result is provided into 2 parts :
- * @return : the number of bytes written into 'dst' (necessarily <= targetDstSize)
- * or 0 if compression fails.
- * `srcSizePtr` : on success, *srcSizePtr will be updated to indicate how much bytes were read from `src`.
- * Note that this function may not consume the entire input.
- */
-LZ4LIB_API int LZ4_compress_HC_continue_destSize(LZ4_streamHC_t* LZ4_streamHCPtr,
- const char* src, char* dst,
- int* srcSizePtr, int targetDstSize);
-
-LZ4LIB_API int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, int maxDictSize);
-
-
-
-/*^**********************************************
- * !!!!!! STATIC LINKING ONLY !!!!!!
- ***********************************************/
-
-/*-******************************************************************
- * PRIVATE DEFINITIONS :
- * Do not use these definitions directly.
- * They are merely exposed to allow static allocation of `LZ4_streamHC_t`.
- * Declare an `LZ4_streamHC_t` directly, rather than any type below.
- * Even then, only do so in the context of static linking, as definitions may change between versions.
- ********************************************************************/
-
-#define LZ4HC_DICTIONARY_LOGSIZE 16
-#define LZ4HC_MAXD (1<<LZ4HC_DICTIONARY_LOGSIZE)
-#define LZ4HC_MAXD_MASK (LZ4HC_MAXD - 1)
-
-#define LZ4HC_HASH_LOG 15
-#define LZ4HC_HASHTABLESIZE (1 << LZ4HC_HASH_LOG)
-#define LZ4HC_HASH_MASK (LZ4HC_HASHTABLESIZE - 1)
-
-
-#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
-#include <stdint.h>
-
-typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal;
-struct LZ4HC_CCtx_internal
-{
- uint32_t hashTable[LZ4HC_HASHTABLESIZE];
- uint16_t chainTable[LZ4HC_MAXD];
- const uint8_t* end; /* next block here to continue on current prefix */
- const uint8_t* base; /* All index relative to this position */
- const uint8_t* dictBase; /* alternate base for extDict */
- uint32_t dictLimit; /* below that point, need extDict */
- uint32_t lowLimit; /* below that point, no more dict */
- uint32_t nextToUpdate; /* index from which to continue dictionary update */
- short compressionLevel;
- int8_t favorDecSpeed; /* favor decompression speed if this flag set,
- otherwise, favor compression ratio */
- int8_t dirty; /* stream has to be fully reset if this flag is set */
- const LZ4HC_CCtx_internal* dictCtx;
-};
-
-#else
-
-typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal;
-struct LZ4HC_CCtx_internal
-{
- unsigned int hashTable[LZ4HC_HASHTABLESIZE];
- unsigned short chainTable[LZ4HC_MAXD];
- const unsigned char* end; /* next block here to continue on current prefix */
- const unsigned char* base; /* All index relative to this position */
- const unsigned char* dictBase; /* alternate base for extDict */
- unsigned int dictLimit; /* below that point, need extDict */
- unsigned int lowLimit; /* below that point, no more dict */
- unsigned int nextToUpdate; /* index from which to continue dictionary update */
- short compressionLevel;
- char favorDecSpeed; /* favor decompression speed if this flag set,
- otherwise, favor compression ratio */
- char dirty; /* stream has to be fully reset if this flag is set */
- const LZ4HC_CCtx_internal* dictCtx;
-};
-
-#endif
-
-
-/* Do not use these definitions directly !
- * Declare or allocate an LZ4_streamHC_t instead.
- */
-#define LZ4_STREAMHCSIZE (4*LZ4HC_HASHTABLESIZE + 2*LZ4HC_MAXD + 56 + ((sizeof(void*)==16) ? 56 : 0) /* AS400*/ ) /* 262200 or 262256*/
-#define LZ4_STREAMHCSIZE_SIZET (LZ4_STREAMHCSIZE / sizeof(size_t))
-union LZ4_streamHC_u {
- size_t table[LZ4_STREAMHCSIZE_SIZET];
- LZ4HC_CCtx_internal internal_donotuse;
-}; /* previously typedef'd to LZ4_streamHC_t */
-
-/* LZ4_streamHC_t :
- * This structure allows static allocation of LZ4 HC streaming state.
- * This can be used to allocate statically, on state, or as part of a larger structure.
- *
- * Such state **must** be initialized using LZ4_initStreamHC() before first use.
- *
- * Note that invoking LZ4_initStreamHC() is not required when
- * the state was created using LZ4_createStreamHC() (which is recommended).
- * Using the normal builder, a newly created state is automatically initialized.
- *
- * Static allocation shall only be used in combination with static linking.
- */
-
-/* LZ4_initStreamHC() : v1.9.0+
- * Required before first use of a statically allocated LZ4_streamHC_t.
- * Before v1.9.0 : use LZ4_resetStreamHC() instead
- */
-LZ4LIB_API LZ4_streamHC_t* LZ4_initStreamHC (void* buffer, size_t size);
-
-
-/*-************************************
-* Deprecated Functions
-**************************************/
-/* see lz4.h LZ4_DISABLE_DEPRECATE_WARNINGS to turn off deprecation warnings */
-
-/* deprecated compression functions */
-LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC (const char* source, char* dest, int inputSize);
-LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize);
-LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2 (const char* source, char* dest, int inputSize, int compressionLevel);
-LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
-LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize);
-LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
-LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel);
-LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
-LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize);
-LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
-
-/* Obsolete streaming functions; degraded functionality; do not use!
- *
- * In order to perform streaming compression, these functions depended on data
- * that is no longer tracked in the state. They have been preserved as well as
- * possible: using them will still produce a correct output. However, use of
- * LZ4_slideInputBufferHC() will truncate the history of the stream, rather
- * than preserve a window-sized chunk of history.
- */
-LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API void* LZ4_createHC (const char* inputBuffer);
-LZ4_DEPRECATED("use LZ4_saveDictHC() instead") LZ4LIB_API char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
-LZ4_DEPRECATED("use LZ4_freeStreamHC() instead") LZ4LIB_API int LZ4_freeHC (void* LZ4HC_Data);
-LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel);
-LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
-LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API int LZ4_sizeofStreamStateHC(void);
-LZ4_DEPRECATED("use LZ4_initStreamHC() instead") LZ4LIB_API int LZ4_resetStreamStateHC(void* state, char* inputBuffer);
-
-
-/* LZ4_resetStreamHC() is now replaced by LZ4_initStreamHC().
- * The intention is to emphasize the difference with LZ4_resetStreamHC_fast(),
- * which is now the recommended function to start a new stream of blocks,
- * but cannot be used to initialize a memory segment containing arbitrary garbage data.
- *
- * It is recommended to switch to LZ4_initStreamHC().
- * LZ4_resetStreamHC() will generate deprecation warnings in a future version.
- */
-LZ4LIB_API void LZ4_resetStreamHC (LZ4_streamHC_t* streamHCPtr, int compressionLevel);
-
-
-#if defined (__cplusplus)
-}
-#endif
-
-#endif /* LZ4_HC_H_19834876238432 */
-
-
-/*-**************************************************
- * !!!!! STATIC LINKING ONLY !!!!!
- * Following definitions are considered experimental.
- * They should not be linked from DLL,
- * as there is no guarantee of API stability yet.
- * Prototypes will be promoted to "stable" status
- * after successfull usage in real-life scenarios.
- ***************************************************/
-#ifdef LZ4_HC_STATIC_LINKING_ONLY /* protection macro */
-#ifndef LZ4_HC_SLO_098092834
-#define LZ4_HC_SLO_098092834
-
-#define LZ4_STATIC_LINKING_ONLY /* LZ4LIB_STATIC_API */
-#include "lz4.h"
-
-#if defined (__cplusplus)
-extern "C" {
-#endif
-
-/*! LZ4_setCompressionLevel() : v1.8.0+ (experimental)
- * It's possible to change compression level
- * between successive invocations of LZ4_compress_HC_continue*()
- * for dynamic adaptation.
- */
-LZ4LIB_STATIC_API void LZ4_setCompressionLevel(
- LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel);
-
-/*! LZ4_favorDecompressionSpeed() : v1.8.2+ (experimental)
- * Opt. Parser will favor decompression speed over compression ratio.
- * Only applicable to levels >= LZ4HC_CLEVEL_OPT_MIN.
- */
-LZ4LIB_STATIC_API void LZ4_favorDecompressionSpeed(
- LZ4_streamHC_t* LZ4_streamHCPtr, int favor);
-
-/*! LZ4_resetStreamHC_fast() : v1.9.0+
- * When an LZ4_streamHC_t is known to be in a internally coherent state,
- * it can often be prepared for a new compression with almost no work, only
- * sometimes falling back to the full, expensive reset that is always required
- * when the stream is in an indeterminate state (i.e., the reset performed by
- * LZ4_resetStreamHC()).
- *
- * LZ4_streamHCs are guaranteed to be in a valid state when:
- * - returned from LZ4_createStreamHC()
- * - reset by LZ4_resetStreamHC()
- * - memset(stream, 0, sizeof(LZ4_streamHC_t))
- * - the stream was in a valid state and was reset by LZ4_resetStreamHC_fast()
- * - the stream was in a valid state and was then used in any compression call
- * that returned success
- * - the stream was in an indeterminate state and was used in a compression
- * call that fully reset the state (LZ4_compress_HC_extStateHC()) and that
- * returned success
- *
- * Note:
- * A stream that was last used in a compression call that returned an error
- * may be passed to this function. However, it will be fully reset, which will
- * clear any existing history and settings from the context.
- */
-LZ4LIB_STATIC_API void LZ4_resetStreamHC_fast(
- LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel);
-
-/*! LZ4_compress_HC_extStateHC_fastReset() :
- * A variant of LZ4_compress_HC_extStateHC().
- *
- * Using this variant avoids an expensive initialization step. It is only safe
- * to call if the state buffer is known to be correctly initialized already
- * (see above comment on LZ4_resetStreamHC_fast() for a definition of
- * "correctly initialized"). From a high level, the difference is that this
- * function initializes the provided state with a call to
- * LZ4_resetStreamHC_fast() while LZ4_compress_HC_extStateHC() starts with a
- * call to LZ4_resetStreamHC().
- */
-LZ4LIB_STATIC_API int LZ4_compress_HC_extStateHC_fastReset (
- void* state,
- const char* src, char* dst,
- int srcSize, int dstCapacity,
- int compressionLevel);
-
-/*! LZ4_attach_HC_dictionary() :
- * This is an experimental API that allows for the efficient use of a
- * static dictionary many times.
- *
- * Rather than re-loading the dictionary buffer into a working context before
- * each compression, or copying a pre-loaded dictionary's LZ4_streamHC_t into a
- * working LZ4_streamHC_t, this function introduces a no-copy setup mechanism,
- * in which the working stream references the dictionary stream in-place.
- *
- * Several assumptions are made about the state of the dictionary stream.
- * Currently, only streams which have been prepared by LZ4_loadDictHC() should
- * be expected to work.
- *
- * Alternatively, the provided dictionary stream pointer may be NULL, in which
- * case any existing dictionary stream is unset.
- *
- * A dictionary should only be attached to a stream without any history (i.e.,
- * a stream that has just been reset).
- *
- * The dictionary will remain attached to the working stream only for the
- * current stream session. Calls to LZ4_resetStreamHC(_fast) will remove the
- * dictionary context association from the working stream. The dictionary
- * stream (and source buffer) must remain in-place / accessible / unchanged
- * through the lifetime of the stream session.
- */
-LZ4LIB_STATIC_API void LZ4_attach_HC_dictionary(
- LZ4_streamHC_t *working_stream,
- const LZ4_streamHC_t *dictionary_stream);
-
-#if defined (__cplusplus)
-}
-#endif
-
-#endif /* LZ4_HC_SLO_098092834 */
-#endif /* LZ4_HC_STATIC_LINKING_ONLY */
diff --git a/subprojects/lz4/meson.build b/subprojects/lz4/meson.build
index ec6f579..00a68a2 100644
--- a/subprojects/lz4/meson.build
+++ b/subprojects/lz4/meson.build
@@ -1,9 +1,13 @@
project('lz4', 'c')
-compiler = meson.get_compiler('c')
+compiler = meson.get_compiler('cpp')
-lz4_inc = include_directories('include')
-lz4_lib = compiler.find_library('lz4',
- dirs: [join_paths(meson.current_source_dir(), 'static')])
+is_msvc = compiler.get_id() == 'msvc' or compiler.get_id() == 'clang-cl'
-lz4 = declare_dependency(dependencies: lz4_lib, include_directories: lz4_inc)
+if is_msvc
+ lz4_lib = compiler.find_library('lz4_static',
+ dirs: [join_paths(meson.current_source_dir(), 'static')])
+ lz4 = declare_dependency(dependencies: lz4_lib, include_directories: include_directories('include'))
+else
+ lz4 = compiler.find_library('lz4')
+endif
diff --git a/subprojects/lz4/static/lz4.lib b/subprojects/lz4/static/lz4.lib
deleted file mode 100644
index a684377..0000000
--- a/subprojects/lz4/static/lz4.lib
+++ /dev/null
Binary files differ
diff --git a/subprojects/s3tc-dxt-decompression/meson.build b/subprojects/s3tc-dxt-decompression/meson.build
index 07f4fd0..734aa23 100644
--- a/subprojects/s3tc-dxt-decompression/meson.build
+++ b/subprojects/s3tc-dxt-decompression/meson.build
@@ -1,12 +1,5 @@
-project('s3tc', 'cpp')
-
-if host_machine.system() == 'linux'
- add_project_arguments('-Wno-unused-variable', language : 'cpp')
-endif
+project('s3tc', 'cpp', version: 'git-d3a8c52')
s3tc_inc = include_directories('.')
-
-s3tc_lib = static_library('s3tc', 's3tc.cpp',
- include_directories : s3tc_inc)
-
+s3tc_lib = static_library('s3tc', 's3tc.cpp', include_directories: s3tc_inc)
s3tc = declare_dependency(link_with: s3tc_lib, include_directories: s3tc_inc)
diff --git a/subprojects/stb_image/meson.build b/subprojects/stb_image/meson.build
index 4cae1d4..ed279a3 100644
--- a/subprojects/stb_image/meson.build
+++ b/subprojects/stb_image/meson.build
@@ -1,3 +1,2 @@
-project('stb_image', 'c')
-
-stbi = declare_dependency(include_directories: include_directories('.'))
+project('stb_image', 'c', version: '2.28')
+stb_image = declare_dependency(include_directories: include_directories('.'))
diff --git a/subprojects/stb_image/stb_image.h b/subprojects/stb_image/stb_image.h
index accef48..5e807a0 100644
--- a/subprojects/stb_image/stb_image.h
+++ b/subprojects/stb_image/stb_image.h
@@ -1,4 +1,4 @@
-/* stb_image - v2.26 - public domain image loader - http://nothings.org/stb
+/* stb_image - v2.28 - public domain image loader - http://nothings.org/stb
no warranty implied; use at your own risk
Do this:
@@ -48,6 +48,8 @@ LICENSE
RECENT REVISION HISTORY:
+ 2.28 (2023-01-29) many error fixes, security errors, just tons of stuff
+ 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
@@ -89,7 +91,7 @@ RECENT REVISION HISTORY:
Jeremy Sawicki (handle all ImageNet JPGs)
Optimizations & bugfixes Mikhail Morozov (1-bit BMP)
Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query)
- Arseny Kapoulkine
+ Arseny Kapoulkine Simon Breuss (16-bit PNM)
John-Mark Allen
Carmelo J Fdez-Aguera
@@ -102,19 +104,21 @@ RECENT REVISION HISTORY:
Thomas Ruf Ronny Chevalier github:rlyeh
Janez Zemva John Bartholomew Michal Cichon github:romigrou
Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
- Laurent Gomila Cort Stratton github:snagar
+ 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
+ Josh Tobin Neil Bickford Matthew Gregan github:poppolopoppo
Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
- Brad Weinberger Matvey Cherevko [reserved]
+ 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.
@@ -137,7 +141,7 @@ RECENT REVISION HISTORY:
// // ... 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)
+// stbi_image_free(data);
//
// Standard parameters:
// int *x -- outputs image width in pixels
@@ -176,6 +180,32 @@ RECENT REVISION HISTORY:
//
// 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:
@@ -281,11 +311,10 @@ RECENT REVISION HISTORY:
//
// iPhone PNG support:
//
-// By default we convert iphone-formatted PNGs back to RGB, even though
-// they are internally encoded differently. You can disable this conversion
-// by calling stbi_convert_iphone_png_to_rgb(0), in which case
-// you will always just get the native iphone "format" through (which
-// is BGR stored in RGB).
+// 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
@@ -489,6 +518,8 @@ 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
@@ -605,7 +636,7 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
#endif
#endif
-#ifdef _MSC_VER
+#if defined(_MSC_VER) || defined(__SYMBIAN32__)
typedef unsigned short stbi__uint16;
typedef signed short stbi__int16;
typedef unsigned int stbi__uint32;
@@ -634,7 +665,7 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#ifdef STBI_HAS_LROTL
#define stbi_lrot(x,y) _lrotl(x,y)
#else
- #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y))))
+ #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))
@@ -748,9 +779,12 @@ static int stbi__sse2_available(void)
#ifdef STBI_NEON
#include <arm_neon.h>
-// assume GCC or Clang on ARM targets
+#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
@@ -924,6 +958,7 @@ static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp);
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
@@ -998,7 +1033,7 @@ static int stbi__mad3sizes_valid(int a, int b, int c, int 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)
+#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) &&
@@ -1021,7 +1056,7 @@ static void *stbi__malloc_mad3(int a, int b, int c, int add)
return stbi__malloc(a*b*c + add);
}
-#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
+#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;
@@ -1029,6 +1064,23 @@ static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
}
#endif
+// returns 1 if the sum of two signed ints is valid (between -2^31 and 2^31-1 inclusive), 0 on overflow.
+static int stbi__addints_valid(int a, int b)
+{
+ if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow
+ if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0.
+ return a <= INT_MAX - b;
+}
+
+// returns 1 if the product of two signed shorts is valid, 0 on overflow.
+static int stbi__mul2shorts_valid(short a, short b)
+{
+ if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow
+ if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid
+ if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN
+ return a >= SHRT_MIN / b;
+}
+
// stbi__err - error
// stbi__errpf - error returning pointer to float
// stbi__errpuc - error returning pointer to unsigned char
@@ -1087,9 +1139,8 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
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;
- #ifndef STBI_NO_JPEG
- if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri);
- #endif
+ // 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
@@ -1107,6 +1158,13 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
#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
@@ -1262,12 +1320,12 @@ static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, in
#ifndef STBI_NO_STDIO
-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
+#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(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
+#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);
@@ -1277,16 +1335,16 @@ STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wch
static FILE *stbi__fopen(char const *filename, char const *mode)
{
FILE *f;
-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
+#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)))
+ 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)))
+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
return 0;
-#if _MSC_VER >= 1400
+#if defined(_MSC_VER) && _MSC_VER >= 1400
if (0 != _wfopen_s(&f, wFilename, wMode))
f = 0;
#else
@@ -1662,7 +1720,8 @@ static int stbi__get16le(stbi__context *s)
static stbi__uint32 stbi__get32le(stbi__context *s)
{
stbi__uint32 z = stbi__get16le(s);
- return z + (stbi__get16le(s) << 16);
+ z += (stbi__uint32)stbi__get16le(s) << 16;
+ return z;
}
#endif
@@ -1944,9 +2003,12 @@ 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)
+ for (i=0; i < 16; ++i) {
+ for (j=0; j < count[i]; ++j) {
h->size[k++] = (stbi_uc) (i+1);
+ if(k >= 257) return stbi__err("bad size list","Corrupt JPEG");
+ }
+ }
h->size[k] = 0;
// compute actual symbols (from jpeg spec)
@@ -2071,6 +2133,8 @@ stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h)
// convert the huffman code to the symbol id
c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k];
+ if(c < 0 || c >= 256) // symbol id out of bounds!
+ return -1;
STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]);
// convert the id to a symbol
@@ -2089,14 +2153,14 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
unsigned int k;
int sgn;
if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
+ if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing
- sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
+ 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);
- if (n < 0 || n >= (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))) return 0;
j->code_buffer = k & ~stbi__bmask[n];
k &= stbi__bmask[n];
j->code_bits -= n;
- return k + (stbi__jbias[n] & ~sgn);
+ return k + (stbi__jbias[n] & (sgn - 1));
}
// get some unsigned bits
@@ -2104,6 +2168,7 @@ 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);
+ if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing
k = stbi_lrot(j->code_buffer, n);
j->code_buffer = k & ~stbi__bmask[n];
k &= stbi__bmask[n];
@@ -2115,6 +2180,7 @@ stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j)
{
unsigned int k;
if (j->code_bits < 1) stbi__grow_buffer_unsafe(j);
+ if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing
k = j->code_buffer;
j->code_buffer <<= 1;
--j->code_bits;
@@ -2146,14 +2212,16 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman
if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
t = stbi__jpeg_huff_decode(j, hdc);
- if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG");
+ 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;
+ if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta","Corrupt JPEG");
dc = j->img_comp[b].dc_pred + diff;
j->img_comp[b].dc_pred = dc;
+ if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
data[0] = (short) (dc * dequant[0]);
// decode AC components, see JPEG spec
@@ -2167,6 +2235,7 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman
if (r) { // fast-AC path
k += (r >> 4) & 15; // run
s = r & 15; // combined length
+ if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available");
j->code_buffer <<= s;
j->code_bits -= s;
// decode into unzigzag'd location
@@ -2203,12 +2272,14 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__
// 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 == -1) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
+ if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
diff = t ? stbi__extend_receive(j, t) : 0;
+ if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG");
dc = j->img_comp[b].dc_pred + diff;
j->img_comp[b].dc_pred = dc;
- data[0] = (short) (dc << j->succ_low);
+ if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
+ data[0] = (short) (dc * (1 << j->succ_low));
} else {
// refinement scan for DC coefficient
if (stbi__jpeg_get_bit(j))
@@ -2242,10 +2313,11 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
if (r) { // fast-AC path
k += (r >> 4) & 15; // run
s = r & 15; // combined length
+ if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available");
j->code_buffer <<= s;
j->code_bits -= s;
zig = stbi__jpeg_dezigzag[k++];
- data[zig] = (short) ((r >> 8) << shift);
+ 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");
@@ -2263,7 +2335,7 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
} else {
k += r;
zig = stbi__jpeg_dezigzag[k++];
- data[zig] = (short) (stbi__extend_receive(j,s) << shift);
+ data[zig] = (short) (stbi__extend_receive(j,s) * (1 << shift));
}
}
} while (k <= j->spec_end);
@@ -3062,6 +3134,7 @@ static int stbi__process_marker(stbi__jpeg *z, int m)
sizes[i] = stbi__get8(z->s);
n += sizes[i];
}
+ if(n > 256) return stbi__err("bad DHT header","Corrupt JPEG"); // Loop over i < n would write past end of values!
L -= 17;
if (tc == 0) {
if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0;
@@ -3227,6 +3300,13 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
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;
@@ -3304,6 +3384,28 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
return 1;
}
+static int stbi__skip_jpeg_junk_at_end(stbi__jpeg *j)
+{
+ // some JPEGs have junk at end, skip over it but if we find what looks
+ // like a valid marker, resume there
+ while (!stbi__at_eof(j->s)) {
+ int x = stbi__get8(j->s);
+ while (x == 255) { // might be a marker
+ if (stbi__at_eof(j->s)) return STBI__MARKER_none;
+ x = stbi__get8(j->s);
+ if (x != 0x00 && x != 0xff) {
+ // not a stuffed zero or lead-in to another marker, looks
+ // like an actual marker, return it
+ return x;
+ }
+ // stuffed zero has x=0 now which ends the loop, meaning we go
+ // back to regular scan loop.
+ // repeated 0xff keeps trying to read the next byte of the marker.
+ }
+ }
+ return STBI__MARKER_none;
+}
+
// decode image to YCbCr format
static int stbi__decode_jpeg_image(stbi__jpeg *j)
{
@@ -3320,25 +3422,22 @@ static int stbi__decode_jpeg_image(stbi__jpeg *j)
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;
- }
- }
+ j->marker = stbi__skip_jpeg_junk_at_end(j);
// if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0
}
+ m = stbi__get_marker(j);
+ if (STBI__RESTART(m))
+ m = stbi__get_marker(j);
} 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");
+ m = stbi__get_marker(j);
} else {
- if (!stbi__process_marker(j, m)) return 0;
+ if (!stbi__process_marker(j, m)) return 1;
+ m = stbi__get_marker(j);
}
- m = stbi__get_marker(j);
}
if (j->progressive)
stbi__jpeg_finish(j);
@@ -3782,6 +3881,10 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
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;
@@ -3924,6 +4027,8 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re
{
unsigned char* result;
stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
+ if (!j) return stbi__errpuc("outofmem", "Out of memory");
+ memset(j, 0, sizeof(stbi__jpeg));
STBI_NOTUSED(ri);
j->s = s;
stbi__setup_jpeg(j);
@@ -3936,6 +4041,8 @@ 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");
+ memset(j, 0, sizeof(stbi__jpeg));
j->s = s;
stbi__setup_jpeg(j);
r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
@@ -3960,6 +4067,8 @@ 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");
+ memset(j, 0, sizeof(stbi__jpeg));
j->s = s;
result = stbi__jpeg_info_raw(j, x, y, comp);
STBI_FREE(j);
@@ -3979,6 +4088,7 @@ static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
// 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)
@@ -3988,8 +4098,8 @@ typedef struct
stbi__uint16 firstcode[16];
int maxcode[17];
stbi__uint16 firstsymbol[16];
- stbi_uc size[288];
- stbi__uint16 value[288];
+ stbi_uc size[STBI__ZNSYMS];
+ stbi__uint16 value[STBI__ZNSYMS];
} stbi__zhuffman;
stbi_inline static int stbi__bitreverse16(int n)
@@ -4120,7 +4230,7 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
if (s >= 16) return -1; // invalid code!
// code size is s, so:
b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
- if (b >= sizeof (z->size)) return -1; // some data was corrupt somewhere!
+ 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;
@@ -4201,11 +4311,12 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
a->zout = zout;
return 1;
}
+ if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data
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");
+ if (z < 0 || z >= 30) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data
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");
@@ -4317,7 +4428,7 @@ static int stbi__parse_zlib_header(stbi__zbuf *a)
return 1;
}
-static const stbi_uc stbi__zdefault_length[288] =
+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,
@@ -4363,7 +4474,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
} else {
if (type == 1) {
// use fixed code lengths
- if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0;
+ 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;
@@ -4759,6 +4870,7 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint3
// 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 };
@@ -4879,19 +4991,46 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int
return 1;
}
-static int stbi__unpremultiply_on_load = 0;
-static int stbi__de_iphone_flag = 0;
+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 = 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 = 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_set_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;
@@ -4981,14 +5120,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
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
}
+ // even with SCAN_header, have to scan to see if we have a tRNS
break;
}
@@ -5020,6 +5158,8 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
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;
+ // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now.
+ if (scan == STBI__SCAN_header) { ++s->img_n; return 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 {
@@ -5032,7 +5172,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
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 (scan == STBI__SCAN_header) {
+ // header scan definitely stops at first IDAT
+ if (pal_img_n)
+ s->img_n = pal_img_n;
+ return 1;
+ }
+ if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes");
if ((int)(ioff + c.length) < (int)ioff) return 0;
if (ioff + c.length > idata_limit) {
stbi__uint32 idata_limit_old = idata_limit;
@@ -5272,6 +5418,32 @@ typedef struct
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;
@@ -5299,6 +5471,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
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
@@ -5313,17 +5487,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
}
if (info->bpp == 16 || info->bpp == 32) {
if (compress == 0) {
- if (info->bpp == 32) {
- info->mr = 0xffu << 16;
- info->mg = 0xffu << 8;
- info->mb = 0xffu << 0;
- info->ma = 0xffu << 24;
- info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
- } else {
- info->mr = 31u << 10;
- info->mg = 31u << 5;
- info->mb = 31u << 0;
- }
+ stbi__bmp_set_mask_defaults(info, compress);
} else if (compress == 3) {
info->mr = stbi__get32le(s);
info->mg = stbi__get32le(s);
@@ -5338,6 +5502,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
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");
@@ -5345,6 +5510,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
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
@@ -5394,9 +5561,22 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
psize = (info.offset - info.extra_read - info.hsz) >> 2;
}
if (psize == 0) {
- STBI_ASSERT(info.offset == s->callback_already_read + (int) (s->img_buffer - s->img_buffer_original));
- if (info.offset != s->callback_already_read + (s->img_buffer - s->buffer_start)) {
- return stbi__errpuc("bad offset", "Corrupt BMP");
+ // accept some number of extra bytes after the header, but if the offset points either to before
+ // the header ends or implies a large amount of extra data, reject the file as malformed
+ int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original);
+ int header_limit = 1024; // max we actually read is below 256 bytes currently.
+ int extra_data_limit = 256*4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size.
+ if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) {
+ return stbi__errpuc("bad header", "Corrupt BMP");
+ }
+ // we established that bytes_read_so_far is positive and sensible.
+ // the first half of this test rejects offsets that are either too small positives, or
+ // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn
+ // ensures the number computed in the second half of the test can't overflow.
+ if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) {
+ return stbi__errpuc("bad offset", "Corrupt BMP");
+ } else {
+ stbi__skip(s, info.offset - bytes_read_so_far);
}
}
@@ -6342,6 +6522,7 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c
// 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)) {
@@ -6457,6 +6638,7 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
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 );
@@ -6766,6 +6948,17 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
}
}
+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)) {
@@ -6777,6 +6970,10 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
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;
@@ -6794,26 +6991,29 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
if (out) {
void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride );
- if (NULL == tmp) {
- STBI_FREE(g.out);
- STBI_FREE(g.history);
- STBI_FREE(g.background);
- return stbi__errpuc("outofmem", "Out of memory");
- }
+ if (!tmp)
+ return stbi__load_gif_main_outofmem(&g, out, delays);
else {
out = (stbi_uc*) tmp;
out_size = layers * stride;
}
if (delays) {
- *delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers );
+ 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);
}
}
@@ -7064,12 +7264,12 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
// 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"); }
+ if ((count == 0) || (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"); }
+ if ((count == 0) || (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);
}
@@ -7138,9 +7338,10 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
info.all_a = 255;
p = stbi__bmp_parse_header(s, &info);
- stbi__rewind( s );
- if (p == NULL)
+ if (p == NULL) {
+ stbi__rewind( s );
return 0;
+ }
if (x) *x = s->img_x;
if (y) *y = s->img_y;
if (comp) {
@@ -7206,8 +7407,8 @@ static int stbi__psd_is16(stbi__context *s)
stbi__rewind( s );
return 0;
}
- (void) stbi__get32be(s);
- (void) stbi__get32be(s);
+ STBI_NOTUSED(stbi__get32be(s));
+ STBI_NOTUSED(stbi__get32be(s));
depth = stbi__get16be(s);
if (depth != 16) {
stbi__rewind( s );
@@ -7286,7 +7487,6 @@ static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
// Known limitations:
// Does not support comments in the header section
// Does not support ASCII image data (formats P2 and P3)
-// Does not support 16-bit-per-channel
#ifndef STBI_NO_PNM
@@ -7307,7 +7507,8 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
stbi_uc *out;
STBI_NOTUSED(ri);
- if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
+ 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?)");
@@ -7317,15 +7518,22 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
*y = s->img_y;
if (comp) *comp = s->img_n;
- if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0))
+ 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_mad3(s->img_n, s->img_x, s->img_y, 0);
+ 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);
+ if (!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) {
+ STBI_FREE(out);
+ return stbi__errpuc("bad PNM", "PNM file truncated");
+ }
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 (ri->bits_per_channel == 16) {
+ out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, s->img_n, req_comp, s->img_x, s->img_y);
+ } else {
+ 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;
@@ -7362,6 +7570,8 @@ static int stbi__pnm_getinteger(stbi__context *s, char *c)
while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) {
value = value*10 + (*c - '0');
*c = (char) stbi__get8(s);
+ if((value > 214748364) || (value == 214748364 && *c > '7'))
+ return stbi__err("integer parse overflow", "Parsing an integer in the PPM header overflowed a 32-bit int");
}
return value;
@@ -7392,17 +7602,29 @@ static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
stbi__pnm_skip_whitespace(s, &c);
*x = stbi__pnm_getinteger(s, &c); // read width
+ if(*x == 0)
+ return stbi__err("invalid width", "PPM image header had zero or overflowing width");
stbi__pnm_skip_whitespace(s, &c);
*y = stbi__pnm_getinteger(s, &c); // read height
+ if (*y == 0)
+ return stbi__err("invalid width", "PPM image header had zero or overflowing width");
stbi__pnm_skip_whitespace(s, &c);
maxv = stbi__pnm_getinteger(s, &c); // read max value
-
- if (maxv > 255)
- return stbi__err("max value > 255", "PPM image not 8-bit");
+ 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 1;
+ return 8;
+}
+
+static int stbi__pnm_is16(stbi__context *s)
+{
+ if (stbi__pnm_info(s, NULL, NULL, NULL) == 16)
+ return 1;
+ return 0;
}
#endif
@@ -7458,6 +7680,9 @@ static int stbi__is_16_main(stbi__context *s)
if (stbi__psd_is16(s)) return 1;
#endif
+ #ifndef STBI_NO_PNM
+ if (stbi__pnm_is16(s)) return 1;
+ #endif
return 0;
}
diff --git a/subprojects/stb_image/stb_image_write.h b/subprojects/stb_image/stb_image_write.h
index 95943eb..e4b32ed 100644
--- a/subprojects/stb_image/stb_image_write.h
+++ b/subprojects/stb_image/stb_image_write.h
@@ -1,4 +1,4 @@
-/* stb_image_write - v1.15 - public domain - http://nothings.org/stb
+/* stb_image_write - v1.16 - public domain - http://nothings.org/stb
writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
no warranty implied; use at your own risk
@@ -140,6 +140,7 @@ CREDITS:
Ivan Tikhonov
github:ignotion
Adam Schackart
+ Andrew Kensler
LICENSE
@@ -166,9 +167,9 @@ LICENSE
#endif
#ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations
-extern int stbi_write_tga_with_rle;
-extern int stbi_write_png_compression_level;
-extern int stbi_write_force_png_filter;
+STBIWDEF int stbi_write_tga_with_rle;
+STBIWDEF int stbi_write_png_compression_level;
+STBIWDEF int stbi_write_force_png_filter;
#endif
#ifndef STBI_WRITE_NO_STDIO
@@ -178,7 +179,7 @@ STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const
STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality);
-#ifdef STBI_WINDOWS_UTF8
+#ifdef STBIW_WINDOWS_UTF8
STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
#endif
#endif
@@ -285,7 +286,7 @@ static void stbi__stdio_write(void *context, void *data, int size)
fwrite(data,1,size,(FILE*) context);
}
-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
+#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8)
#ifdef __cplusplus
#define STBIW_EXTERN extern "C"
#else
@@ -296,25 +297,25 @@ STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned in
STBIWDEF int stbiw_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);
+ return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
}
#endif
static FILE *stbiw__fopen(char const *filename, char const *mode)
{
FILE *f;
-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
+#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8)
wchar_t wMode[64];
wchar_t wFilename[1024];
- if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
+ 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)))
+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
return 0;
-#if _MSC_VER >= 1400
- if (0 != _wfopen_s(&f, wFilename, wMode))
- f = 0;
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ if (0 != _wfopen_s(&f, wFilename, wMode))
+ f = 0;
#else
f = _wfopen(wFilename, wMode);
#endif
@@ -397,7 +398,7 @@ static void stbiw__putc(stbi__write_context *s, unsigned char c)
static void stbiw__write1(stbi__write_context *s, unsigned char a)
{
- if (s->buf_used + 1 > sizeof(s->buffer))
+ if ((size_t)s->buf_used + 1 > sizeof(s->buffer))
stbiw__write_flush(s);
s->buffer[s->buf_used++] = a;
}
@@ -405,7 +406,7 @@ static void stbiw__write1(stbi__write_context *s, unsigned char a)
static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
{
int n;
- if (s->buf_used + 3 > sizeof(s->buffer))
+ if ((size_t)s->buf_used + 3 > sizeof(s->buffer))
stbiw__write_flush(s);
n = s->buf_used;
s->buf_used = n+3;
@@ -490,11 +491,22 @@ static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x,
static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data)
{
- int pad = (-x*3) & 3;
- return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
- "11 4 22 4" "4 44 22 444444",
- 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
- 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
+ if (comp != 4) {
+ // write RGB bitmap
+ int pad = (-x*3) & 3;
+ return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
+ "11 4 22 4" "4 44 22 444444",
+ 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
+ 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
+ } else {
+ // RGBA bitmaps need a v4 header
+ // use BI_BITFIELDS mode with 32bpp and alpha mask
+ // (straight BI_RGB with alpha mask doesn't work in most readers)
+ return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *)data,1,0,
+ "11 4 22 4" "4 44 22 444444 4444 4 444 444 444 444",
+ 'B', 'M', 14+108+x*y*4, 0, 0, 14+108, // file header
+ 108, x,y, 1,32, 3,0,0,0,0,0, 0xff0000,0xff00,0xff,0xff000000u, 0, 0,0,0, 0,0,0, 0,0,0, 0,0,0); // bitmap V4 header
+ }
}
STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
@@ -622,6 +634,8 @@ STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const
#define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
+#ifndef STBI_WRITE_NO_STDIO
+
static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
{
int exponent;
@@ -756,7 +770,7 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
s->func(s->context, header, sizeof(header)-1);
-#ifdef __STDC_WANT_SECURE_LIB__
+#ifdef __STDC_LIB_EXT1__
len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
#else
len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
@@ -777,7 +791,6 @@ STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x,
return stbi_write_hdr_core(&s, x, y, comp, (float *) data);
}
-#ifndef STBI_WRITE_NO_STDIO
STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
{
stbi__write_context s = { 0 };
@@ -968,6 +981,23 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
(void) stbiw__sbfree(hash_table[i]);
STBIW_FREE(hash_table);
+ // store uncompressed instead if compression was worse
+ if (stbiw__sbn(out) > data_len + 2 + ((data_len+32766)/32767)*5) {
+ stbiw__sbn(out) = 2; // truncate to DEFLATE 32K window and FLEVEL = 1
+ for (j = 0; j < data_len;) {
+ int blocklen = data_len - j;
+ if (blocklen > 32767) blocklen = 32767;
+ stbiw__sbpush(out, data_len - j == blocklen); // BFINAL = ?, BTYPE = 0 -- no compression
+ stbiw__sbpush(out, STBIW_UCHAR(blocklen)); // LEN
+ stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8));
+ stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN
+ stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8));
+ memcpy(out+stbiw__sbn(out), data+j, blocklen);
+ stbiw__sbn(out) += blocklen;
+ j += blocklen;
+ }
+ }
+
{
// compute adler32 on input
unsigned int s1=1, s2=0;
@@ -1598,6 +1628,10 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
/* Revision history
+ 1.16 (2021-07-11)
+ make Deflate code emit uncompressed blocks when it would otherwise expand
+ support writing BMPs with alpha channel
+ 1.15 (2020-07-13) unknown
1.14 (2020-02-02) updated JPEG writer to downsample chroma channels
1.13
1.12
@@ -1635,7 +1669,7 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
add HDR output
fix monochrome BMP
0.95 (2014-08-17)
- add monochrome TGA output
+ add monochrome TGA output
0.94 (2014-05-31)
rename private functions to avoid conflicts with stb_image.h
0.93 (2014-05-27)