Update C sources

This commit is contained in:
Milan Nikolic 2023-11-04 13:06:19 +01:00
parent 443f35cfac
commit 15fba7e9ac
No known key found for this signature in database
GPG key ID: 9229D0EAA3AA4E75
29 changed files with 31985 additions and 22038 deletions

View file

@ -65,7 +65,8 @@
*
* `cgltf_num_components` is a tiny utility that tells you the dimensionality of
* a certain accessor type. This can be used before `cgltf_accessor_unpack_floats` to help allocate
* the necessary amount of memory.
* the necessary amount of memory. `cgltf_component_size` and `cgltf_calc_size` exist for
* similar purposes.
*
* `cgltf_accessor_read_float` reads a certain element from a non-sparse accessor and converts it to
* floating point, assuming that `cgltf_load_buffers` has already been called. The passed-in element
@ -837,6 +838,8 @@ cgltf_bool cgltf_accessor_read_uint(const cgltf_accessor* accessor, cgltf_size i
cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size index);
cgltf_size cgltf_num_components(cgltf_type type);
cgltf_size cgltf_component_size(cgltf_component_type component_type);
cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type);
cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_float* out, cgltf_size float_count);
@ -1488,8 +1491,6 @@ cgltf_result cgltf_load_buffers(const cgltf_options* options, cgltf_data* data,
return cgltf_result_success;
}
static cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type);
static cgltf_size cgltf_calc_index_bound(cgltf_buffer_view* buffer_view, cgltf_size offset, cgltf_component_type component_type, cgltf_size count)
{
char* data = (char*)buffer_view->buffer->data + offset + buffer_view->offset;
@ -2217,7 +2218,7 @@ static cgltf_size cgltf_component_read_index(const void* in, cgltf_component_typ
case cgltf_component_type_r_32u:
return *((const uint32_t*) in);
case cgltf_component_type_r_32f:
return (cgltf_size)*((const float*) in);
return (cgltf_size)((cgltf_ssize)*((const float*) in));
case cgltf_component_type_r_8u:
return *((const uint8_t*) in);
default:
@ -2253,8 +2254,6 @@ static cgltf_float cgltf_component_read_float(const void* in, cgltf_component_ty
return (cgltf_float)cgltf_component_read_integer(in, component_type);
}
static cgltf_size cgltf_component_size(cgltf_component_type component_type);
static cgltf_bool cgltf_element_read_float(const uint8_t* element, cgltf_type type, cgltf_component_type component_type, cgltf_bool normalized, cgltf_float* out, cgltf_size element_size)
{
cgltf_size num_components = cgltf_num_components(type);
@ -5965,7 +5964,7 @@ cgltf_size cgltf_num_components(cgltf_type type) {
}
}
static cgltf_size cgltf_component_size(cgltf_component_type component_type) {
cgltf_size cgltf_component_size(cgltf_component_type component_type) {
switch (component_type)
{
case cgltf_component_type_r_8:
@ -5983,7 +5982,7 @@ static cgltf_size cgltf_component_size(cgltf_component_type component_type) {
}
}
static cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type)
cgltf_size cgltf_calc_size(cgltf_type type, cgltf_component_type component_type)
{
cgltf_size component_size = cgltf_component_size(component_type);
if (type == cgltf_type_mat2 && component_size == 1)

File diff suppressed because it is too large Load diff

View file

@ -256,16 +256,16 @@ static void msf_cook_frame(MsfCookedFrame * frame, uint8_t * raw, uint8_t * used
int width, int height, int pitch, int depth)
{ MsfTimeFunc
//bit depth for each channel
const static int rdepthsArray[17] = { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5 };
const static int gdepthsArray[17] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6 };
const static int bdepthsArray[17] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5 };
static const int rdepthsArray[17] = { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5 };
static const int gdepthsArray[17] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6 };
static const int bdepthsArray[17] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5 };
//this extra level of indirection looks unnecessary but we need to explicitly decay the arrays to pointers
//in order to be able to swap them because of C's annoying not-quite-pointers, not-quite-value-types stack arrays.
const int * rdepths = msf_gif_bgra_flag? bdepthsArray : rdepthsArray;
const int * gdepths = gdepthsArray;
const int * bdepths = msf_gif_bgra_flag? rdepthsArray : bdepthsArray;
const static int ditherKernel[16] = {
static const int ditherKernel[16] = {
0 << 12, 8 << 12, 2 << 12, 10 << 12,
12 << 12, 4 << 12, 14 << 12, 6 << 12,
3 << 12, 11 << 12, 1 << 12, 9 << 12,
@ -404,7 +404,7 @@ static MsfGifBuffer * msf_compress_frame(void * allocContext, int width, int hei
MsfGifBuffer * buffer = (MsfGifBuffer *) MSF_GIF_MALLOC(allocContext, maxBufSize);
if (!buffer) { return NULL; }
uint8_t * writeHead = buffer->data;
MsfStridedList lzw = { lzwMem };
MsfStridedList lzw = { lzwMem, 0, 0 };
//allocate tlb
int totalBits = frame.rbits + frame.gbits + frame.bbits;

3053
raylib/external/nanosvg.h vendored Normal file

File diff suppressed because it is too large Load diff

1458
raylib/external/nanosvgrast.h vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -36,7 +36,7 @@
// QOA streaming data descriptor
typedef struct {
qoa_desc info; // QOA descriptor data
FILE *file; // QOA file to read, if NULL, using memory buffer -> file_data
unsigned char *file_data; // QOA file data on memory
unsigned int file_data_size; // QOA file data on memory size
@ -107,7 +107,7 @@ qoaplay_desc *qoaplay_open(const char *path)
unsigned int sample_data_size = qoa.channels*QOA_FRAME_LEN*sizeof(short)*2;
qoaplay_desc *qoa_ctx = QOA_MALLOC(sizeof(qoaplay_desc) + buffer_size + sample_data_size);
memset(qoa_ctx, 0, sizeof(qoaplay_desc));
qoa_ctx->file = file;
qoa_ctx->file_data = NULL;
qoa_ctx->file_data_size = 0;

View file

@ -9,7 +9,7 @@
*
* Note that some file formats (DDS, PVR, KTX) also support uncompressed data storage.
* In those cases data is loaded uncompressed and format is returned.
*
*
* TODO:
* - Implement raylib function: rlGetGlTextureFormats(), required by rl_save_ktx_to_memory()
* - Review rl_load_ktx_from_memory() to support KTX v2.2 specs
@ -261,11 +261,9 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
}
else if (((header->ddspf.flags == 0x04) || (header->ddspf.flags == 0x05)) && (header->ddspf.fourcc > 0)) // Compressed
{
int data_size = 0;
// Calculate data size, including all mipmaps
if (header->mipmap_count > 1) data_size = header->pitch_or_linear_size*2;
else data_size = header->pitch_or_linear_size;
// NOTE: This forces only 1 mipmap to be loaded which is not really correct but it works
int data_size = (header->pitch_or_linear_size < file_size - 0x80) ? header->pitch_or_linear_size : file_size - 0x80;
*mips = 1;
image_data = RL_MALLOC(data_size*sizeof(unsigned char));
@ -814,5 +812,4 @@ static int get_pixel_data_size(int width, int height, int format)
return data_size;
}
#endif // RL_GPUTEX_IMPLEMENTATION

305
raylib/external/rprand.h vendored Normal file
View file

@ -0,0 +1,305 @@
/**********************************************************************************************
*
* rprand v1.0 - A simple and easy-to-use pseudo-random numbers generator (PRNG)
*
* FEATURES:
* - Pseudo-random values generation, 32 bits: [0..4294967295]
* - Sequence generation avoiding duplicate values
* - Using standard and proven prng algorithm (Xoshiro128**)
* - State initialized with a separate generator (SplitMix64)
*
* LIMITATIONS:
* - No negative numbers, up to the user to manage them
*
* POSSIBLE IMPROVEMENTS:
* - Support 64 bits generation
*
* ADDITIONAL NOTES:
* This library implements two pseudo-random number generation algorithms:
*
* - Xoshiro128** : https://prng.di.unimi.it/xoshiro128starstar.c
* - SplitMix64 : https://prng.di.unimi.it/splitmix64.c
*
* SplitMix64 is used to initialize the Xoshiro128** state, from a provided seed
*
* It's suggested to use SplitMix64 to initialize the state of the generators starting from
* a 64-bit seed, as research has shown that initialization must be performed with a generator
* radically different in nature from the one initialized to avoid correlation on similar seeds.
*
* CONFIGURATION:
* #define RPRAND_IMPLEMENTATION
* Generates the implementation of the library into the included file.
* If not defined, the library is in header only mode and can be included in other headers
* or source files without problems. But only ONE file should hold the implementation.
*
* DEPENDENCIES: none
*
* VERSIONS HISTORY:
* 1.0 (01-Jun-2023) First version
*
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2023 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#ifndef RPRAND_H
#define RPRAND_H
#define RPRAND_VERSION "1.0"
// Function specifiers in case library is build/used as a shared library (Windows)
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
#if defined(_WIN32)
#if defined(BUILD_LIBTYPE_SHARED)
#define RPRAND __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
#elif defined(USE_LIBTYPE_SHARED)
#define RPRAND __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
#endif
#endif
// Function specifiers definition
#ifndef RPRANDAPI
#define RPRANDAPI // Functions defined as 'extern' by default (implicit specifiers)
#endif
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
// Allow custom memory allocators
#ifndef RPRAND_CALLOC
#define RPRAND_CALLOC(ptr,sz) calloc(ptr,sz)
#endif
#ifndef RPRAND_FREE
#define RPRAND_FREE(ptr) free(ptr)
#endif
// Simple log system to avoid RPNG_LOG() calls if required
// NOTE: Avoiding those calls, also avoids const strings memory usage
#define RPRAND_SHOW_LOG_INFO
#if defined(RPNG_SHOW_LOG_INFO)
#define RPRAND_LOG(...) printf(__VA_ARGS__)
#else
#define RPRAND_LOG(...)
#endif
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
//...
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
//...
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
RPRANDAPI void rprand_set_seed(unsigned long long seed); // Set rprand_state for Xoshiro128**, seed is 64bit
RPRANDAPI int rprand_get_value(int min, int max); // Get random value within a range, min and max included
RPRANDAPI int *rprand_load_sequence(unsigned int count, int min, int max); // Load pseudo-random numbers sequence with no duplicates
RPRANDAPI void rprand_unload_sequence(int *sequence); // Unload pseudo-random numbers sequence
#ifdef __cplusplus
}
#endif
#endif // RPRAND_H
/***********************************************************************************
*
* RPRAND IMPLEMENTATION
*
************************************************************************************/
#if defined(RPRAND_IMPLEMENTATION)
#include <stdlib.h> // Required for: calloc(), free(), abs()
#include <stdint.h> // Required for data types: uint32_t, uint64_t
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
// ...
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
static uint64_t rprand_seed = 0; // SplitMix64 actual seed
static uint32_t rprand_state[4] = { 0 }; // Xoshiro128** state, nitialized by SplitMix64
//----------------------------------------------------------------------------------
// Module internal functions declaration
//----------------------------------------------------------------------------------
static uint32_t rprand_xoshiro(void); // Xoshiro128** generator (uses global rprand_state)
static uint64_t rprand_splitmix64(void); // SplitMix64 generator (uses seed to generate rprand_state)
//----------------------------------------------------------------------------------
// Module functions definition
//----------------------------------------------------------------------------------
// Set rprand_state for Xoshiro128**
// NOTE: We use a custom generation algorithm using SplitMix64
void rprand_set_seed(unsigned long long seed)
{
rprand_seed = (uint64_t)seed; // Set SplitMix64 seed for further use
// To generate the Xoshiro128** state, we use SplitMix64 generator first
// We generate 4 pseudo-random 64bit numbers that we combine using their LSB|MSB
rprand_state[0] = (uint32_t)(rprand_splitmix64() & 0xffffffff);
rprand_state[1] = (uint32_t)((rprand_splitmix64() & 0xffffffff00000000) >> 32);
rprand_state[2] = (uint32_t)(rprand_splitmix64() & 0xffffffff);
rprand_state[3] = (uint32_t)((rprand_splitmix64() & 0xffffffff00000000) >> 32);
}
// Get random value within a range, min and max included
int rprand_get_value(int min, int max)
{
int value = rprand_xoshiro()%(abs(max - min) + 1) + min;
return value;
}
// Load pseudo-random numbers sequence with no duplicates, min and max included
int *rprand_load_sequence(unsigned int count, int min, int max)
{
int *sequence = NULL;
if (count > (abs(max - min) + 1))
{
RPRAND_LOG("WARNING: Sequence count required is greater than range provided\n");
//count = (max - min);
return sequence;
}
sequence = (int *)RPRAND_CALLOC(count, sizeof(int));
int value = 0;
bool value_is_dup = false;
for (int i = 0; i < count;)
{
value = (rprand_xoshiro()%(abs(max - min) + 1)) + min;
value_is_dup = false;
for (int j = 0; j < i; j++)
{
if (sequence[j] == value)
{
value_is_dup = true;
break;
}
}
if (!value_is_dup)
{
sequence[i] = value;
i++;
}
}
return sequence;
}
// Unload pseudo-random numbers sequence
void rprand_unload_sequence(int *sequence)
{
RPRAND_FREE(sequence);
sequence = NULL;
}
//----------------------------------------------------------------------------------
// Module internal functions definition
//----------------------------------------------------------------------------------
static inline uint32_t rprand_rotate_left(const uint32_t x, int k)
{
return (x << k) | (x >> (32 - k));
}
// Xoshiro128** generator info:
//
// Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
//
// To the extent possible under law, the author has dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// See <http://creativecommons.org/publicdomain/zero/1.0/>.
//
// This is xoshiro128** 1.1, one of our 32-bit all-purpose, rock-solid
// generators. It has excellent speed, a state size (128 bits) that is
// large enough for mild parallelism, and it passes all tests we are aware
// of.
//
// Note that version 1.0 had mistakenly s[0] instead of s[1] as state
// word passed to the scrambler.
//
// For generating just single-precision (i.e., 32-bit) floating-point
// numbers, xoshiro128+ is even faster.
//
// The state must be seeded so that it is not everywhere zero.
//
uint32_t rprand_xoshiro(void)
{
const uint32_t result = rprand_rotate_left(rprand_state[1]*5, 7)*9;
const uint32_t t = rprand_state[1] << 9;
rprand_state[2] ^= rprand_state[0];
rprand_state[3] ^= rprand_state[1];
rprand_state[1] ^= rprand_state[2];
rprand_state[0] ^= rprand_state[3];
rprand_state[2] ^= t;
rprand_state[3] = rprand_rotate_left(rprand_state[3], 11);
return result;
}
// SplitMix64 generator info:
//
// Written in 2015 by Sebastiano Vigna (vigna@acm.org)
//
// To the extent possible under law, the author has dedicated all copyright
// and related and neighboring rights to this software to the public domain
// worldwide. This software is distributed without any warranty.
//
// See <http://creativecommons.org/publicdomain/zero/1.0/>.
//
//
// This is a fixed-increment version of Java 8's SplittableRandom generator
// See http://dx.doi.org/10.1145/2714064.2660195 and
// http://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html
//
// It is a very fast generator passing BigCrush, and it can be useful if
// for some reason you absolutely want 64 bits of state.
uint64_t rprand_splitmix64()
{
uint64_t z = (rprand_seed += 0x9e3779b97f4a7c15);
z = (z ^ (z >> 30))*0xbf58476d1ce4e5b9;
z = (z ^ (z >> 27))*0x94d049bb133111eb;
return z ^ (z >> 31);
}
#endif // RPRAND_IMPLEMENTATION

View file

@ -38,10 +38,10 @@ this file implementation in *one* C or C++ file to prevent collisions.
| zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 |
| zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 |
| zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 |
| sdefl 1.0 -0 | 127 MB/s | 371 MB/s | 40004116 | 39.88 |
| sdefl 1.0 -1 | 111 MB/s | 398 MB/s | 38940674 | 38.82 |
| sdefl 1.0 -5 | 45 MB/s | 420 MB/s | 36577183 | 36.46 |
| sdefl 1.0 -7 | 38 MB/s | 423 MB/s | 36523781 | 36.41 |
| sdefl 1.0 -0 | 127 MB/s | 355 MB/s | 40004116 | 39.88 |
| sdefl 1.0 -1 | 111 MB/s | 413 MB/s | 38940674 | 38.82 |
| sdefl 1.0 -5 | 45 MB/s | 436 MB/s | 36577183 | 36.46 |
| sdefl 1.0 -7 | 38 MB/s | 432 MB/s | 36523781 | 36.41 |
| libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 |
| libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 |
| libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 |
@ -50,20 +50,20 @@ this file implementation in *one* C or C++ file to prevent collisions.
### Compression
Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia):
| File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` |
| :------ | ---------: | -----------------: | ---------: | ----------: |
| dickens | 10.192.446 | 4,260,187| 3,845,261| 3,833,657 |
| mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 |
| mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 |
| nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 |
| ooffice | 6.152.192 | 3,320,063 | 3,186,373 | 3,183,815 |
| osdb | 10.085.684 | 3,919,646 | 3,649,510 | 3,649,477 |
| reymont | 6.627.202 | 2,263,378 | 1,857,588 | 1,827,237 |
| samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 |
| sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 |
| webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 |
| xml | 5.345.280 | 886,620| 674,009 | 662,141 |
| x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 |
| File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` |
| --------| -----------| -------------| ---------- | ------------|
| dickens | 10.192.446 | 4,260,187 | 3,845,261 | 3,833,657 |
| mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 |
| mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 |
| nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 |
| ooffice | 6.152.192 | 3,320,063 | 3,186,373 | 3,183,815 |
| osdb | 10.085.684 | 3,919,646 | 3,649,510 | 3,649,477 |
| reymont | 6.627.202 | 2,263,378 | 1,857,588 | 1,827,237 |
| samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 |
| sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 |
| webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 |
| xml | 5.345.280 | 886,620 | 674,009 | 662,141 |
| x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 |
## License
```
@ -71,7 +71,7 @@ Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2020 Micha Mettke
Copyright (c) 2020-2023 Micha Mettke
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
@ -125,7 +125,7 @@ extern "C" {
#define SDEFL_MIN_MATCH 4
#define SDEFL_BLK_MAX (256*1024)
#define SDEFL_SEQ_SIZ ((SDEFL_BLK_MAX + SDEFL_MIN_MATCH)/SDEFL_MIN_MATCH)
#define SDEFL_SEQ_SIZ ((SDEFL_BLK_MAX+2)/3)
#define SDEFL_SYM_MAX (288)
#define SDEFL_OFF_MAX (32)
@ -185,6 +185,7 @@ extern int zsdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl);
#define SDEFL_MAX_CODE_LEN (15)
#define SDEFL_SYM_BITS (10u)
#define SDEFL_SYM_MSK ((1u << SDEFL_SYM_BITS)-1u)
#define SDEFL_RAW_BLK_SIZE (65535)
#define SDEFL_LIT_LEN_CODES (14)
#define SDEFL_OFF_CODES (15)
#define SDEFL_PRE_CODES (7)
@ -192,6 +193,7 @@ extern int zsdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl);
#define SDEFL_EOB (256)
#define sdefl_npow2(n) (1 << (sdefl_ilog2((n)-1) + 1))
#define sdefl_div_round_up(n,d) (((n)+((d)-1))/(d))
static int
sdefl_ilog2(int n) {
@ -438,12 +440,12 @@ sdefl_precode(struct sdefl_symcnt *cnt, unsigned *freqs, unsigned *items,
} while (run_start != total);
cnt->items = (int)(at - items);
}
struct sdefl_match_codes {
struct sdefl_match_codest {
int ls, lc;
int dc, dx;
};
static void
sdefl_match_codes(struct sdefl_match_codes *cod, int dist, int len) {
sdefl_match_codes(struct sdefl_match_codest *cod, int dist, int len) {
static const short dxmax[] = {0,6,12,24,48,96,192,384,768,1536,3072,6144,12288,24576};
static const unsigned char lslot[258+1] = {
0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12,
@ -462,11 +464,53 @@ sdefl_match_codes(struct sdefl_match_codes *cod, int dist, int len) {
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 28
};
assert(len <= 258);
assert(dist <= 32768);
cod->ls = lslot[len];
cod->lc = 257 + cod->ls;
assert(cod->lc <= 285);
cod->dx = sdefl_ilog2(sdefl_npow2(dist) >> 2);
cod->dc = cod->dx ? ((cod->dx + 1) << 1) + (dist > dxmax[cod->dx]) : dist-1;
}
enum sdefl_blk_type {
SDEFL_BLK_UCOMPR,
SDEFL_BLK_DYN
};
static enum sdefl_blk_type
sdefl_blk_type(const struct sdefl *s, int blk_len, int pre_item_len,
const unsigned *pre_freq, const unsigned char *pre_len) {
static const unsigned char x_pre_bits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
static const unsigned char x_len_bits[] = {0,0,0,0,0,0,0,0, 1,1,1,1,2,2,2,2,
3,3,3,3,4,4,4,4, 5,5,5,5,0};
static const unsigned char x_off_bits[] = {0,0,0,0,1,1,2,2, 3,3,4,4,5,5,6,6,
7,7,8,8,9,9,10,10, 11,11,12,12,13,13};
int dyn_cost = 0;
int fix_cost = 0;
int sym = 0;
dyn_cost += 5 + 5 + 4 + (3 * pre_item_len);
for (sym = 0; sym < SDEFL_PRE_MAX; sym++)
dyn_cost += pre_freq[sym] * (x_pre_bits[sym] + pre_len[sym]);
for (sym = 0; sym < 256; sym++)
dyn_cost += s->freq.lit[sym] * s->cod.len.lit[sym];
dyn_cost += s->cod.len.lit[SDEFL_EOB];
for (sym = 257; sym < 286; sym++)
dyn_cost += s->freq.lit[sym] * (x_len_bits[sym - 257] + s->cod.len.lit[sym]);
for (sym = 0; sym < 30; sym++)
dyn_cost += s->freq.off[sym] * (x_off_bits[sym] + s->cod.len.off[sym]);
fix_cost += 8*(5 * sdefl_div_round_up(blk_len, SDEFL_RAW_BLK_SIZE) + blk_len + 1 + 2);
return (dyn_cost < fix_cost) ? SDEFL_BLK_DYN : SDEFL_BLK_UCOMPR;
}
static void
sdefl_put16(unsigned char **dst, unsigned short x) {
unsigned char *val = *dst;
val[0] = (unsigned char)(x & 0xff);
val[1] = (unsigned char)(x >> 8);
*dst = val + 2;
}
static void
sdefl_match(unsigned char **dst, struct sdefl *s, int dist, int len) {
static const char lxn[] = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
@ -475,7 +519,7 @@ sdefl_match(unsigned char **dst, struct sdefl *s, int dist, int len) {
static const short dmin[] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,
385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
struct sdefl_match_codes cod;
struct sdefl_match_codest cod;
sdefl_match_codes(&cod, dist, len);
sdefl_put(dst, s, (int)s->cod.word.lit[cod.lc], s->cod.len.lit[cod.lc]);
sdefl_put(dst, s, len - lmin[cod.ls], lxn[cod.ls]);
@ -484,7 +528,8 @@ sdefl_match(unsigned char **dst, struct sdefl *s, int dist, int len) {
}
static void
sdefl_flush(unsigned char **dst, struct sdefl *s, int is_last,
const unsigned char *in) {
const unsigned char *in, int blk_begin, int blk_end) {
int blk_len = blk_end - blk_begin;
int j, i = 0, item_cnt = 0;
struct sdefl_symcnt symcnt = {0};
unsigned codes[SDEFL_PRE_MAX];
@ -494,41 +539,69 @@ sdefl_flush(unsigned char **dst, struct sdefl *s, int is_last,
static const unsigned char perm[SDEFL_PRE_MAX] = {16,17,18,0,8,7,9,6,10,5,11,
4,12,3,13,2,14,1,15};
/* huffman codes */
/* calculate huffman codes */
s->freq.lit[SDEFL_EOB]++;
sdefl_huff(s->cod.len.lit, s->cod.word.lit, s->freq.lit, SDEFL_SYM_MAX, SDEFL_LIT_LEN_CODES);
sdefl_huff(s->cod.len.off, s->cod.word.off, s->freq.off, SDEFL_OFF_MAX, SDEFL_OFF_CODES);
sdefl_precode(&symcnt, freqs, items, s->cod.len.lit, s->cod.len.off);
sdefl_huff(lens, codes, freqs, SDEFL_PRE_MAX, SDEFL_PRE_CODES);
for (item_cnt = SDEFL_PRE_MAX; item_cnt > 4; item_cnt--) {
if (lens[perm[item_cnt - 1]]) break;
if (lens[perm[item_cnt - 1]]){
break;
}
}
/* block header */
sdefl_put(dst, s, is_last ? 0x01 : 0x00, 1); /* block */
sdefl_put(dst, s, 0x02, 2); /* dynamic huffman */
sdefl_put(dst, s, symcnt.lit - 257, 5);
sdefl_put(dst, s, symcnt.off - 1, 5);
sdefl_put(dst, s, item_cnt - 4, 4);
for (i = 0; i < item_cnt; ++i)
sdefl_put(dst, s, lens[perm[i]], 3);
for (i = 0; i < symcnt.items; ++i) {
unsigned sym = items[i] & 0x1F;
sdefl_put(dst, s, (int)codes[sym], lens[sym]);
if (sym < 16) continue;
if (sym == 16) sdefl_put(dst, s, items[i] >> 5, 2);
else if(sym == 17) sdefl_put(dst, s, items[i] >> 5, 3);
else sdefl_put(dst, s, items[i] >> 5, 7);
}
/* block sequences */
for (i = 0; i < s->seq_cnt; ++i) {
if (s->seq[i].off >= 0)
for (j = 0; j < s->seq[i].len; ++j) {
int c = in[s->seq[i].off + j];
sdefl_put(dst, s, (int)s->cod.word.lit[c], s->cod.len.lit[c]);
/* write block */
switch (sdefl_blk_type(s, blk_len, item_cnt, freqs, lens)) {
case SDEFL_BLK_UCOMPR: {
/* uncompressed blocks */
int n = sdefl_div_round_up(blk_len, SDEFL_RAW_BLK_SIZE);
for (i = 0; i < n; ++i) {
int fin = is_last && (i + 1 == n);
int amount = blk_len < SDEFL_RAW_BLK_SIZE ? blk_len : SDEFL_RAW_BLK_SIZE;
sdefl_put(dst, s, !!fin, 1); /* block */
sdefl_put(dst, s, 0x00, 2); /* stored block */
if (s->bitcnt) {
sdefl_put(dst, s, 0x00, 8 - s->bitcnt);
}
else sdefl_match(dst, s, -s->seq[i].off, s->seq[i].len);
}
sdefl_put(dst, s, (int)(s)->cod.word.lit[SDEFL_EOB], (s)->cod.len.lit[SDEFL_EOB]);
assert(s->bitcnt == 0);
sdefl_put16(dst, (unsigned short)amount);
sdefl_put16(dst, ~(unsigned short)amount);
memcpy(*dst, in + blk_begin + i * SDEFL_RAW_BLK_SIZE, amount);
*dst = *dst + amount;
blk_len -= amount;
}
} break;
case SDEFL_BLK_DYN: {
/* dynamic huffman block */
sdefl_put(dst, s, !!is_last, 1); /* block */
sdefl_put(dst, s, 0x02, 2); /* dynamic huffman */
sdefl_put(dst, s, symcnt.lit - 257, 5);
sdefl_put(dst, s, symcnt.off - 1, 5);
sdefl_put(dst, s, item_cnt - 4, 4);
for (i = 0; i < item_cnt; ++i) {
sdefl_put(dst, s, lens[perm[i]], 3);
}
for (i = 0; i < symcnt.items; ++i) {
unsigned sym = items[i] & 0x1F;
sdefl_put(dst, s, (int)codes[sym], lens[sym]);
if (sym < 16) continue;
if (sym == 16) sdefl_put(dst, s, items[i] >> 5, 2);
else if(sym == 17) sdefl_put(dst, s, items[i] >> 5, 3);
else sdefl_put(dst, s, items[i] >> 5, 7);
}
/* block sequences */
for (i = 0; i < s->seq_cnt; ++i) {
if (s->seq[i].off >= 0) {
for (j = 0; j < s->seq[i].len; ++j) {
int c = in[s->seq[i].off + j];
sdefl_put(dst, s, (int)s->cod.word.lit[c], s->cod.len.lit[c]);
}
} else {
sdefl_match(dst, s, -s->seq[i].off, s->seq[i].len);
}
}
sdefl_put(dst, s, (int)(s)->cod.word.lit[SDEFL_EOB], (s)->cod.len.lit[SDEFL_EOB]);
} break;}
memset(&s->freq, 0, sizeof(s->freq));
s->seq_cnt = 0;
}
@ -541,8 +614,12 @@ sdefl_seq(struct sdefl *s, int off, int len) {
}
static void
sdefl_reg_match(struct sdefl *s, int off, int len) {
struct sdefl_match_codes cod;
struct sdefl_match_codest cod;
sdefl_match_codes(&cod, off, len);
assert(cod.lc < SDEFL_SYM_MAX);
assert(cod.dc < SDEFL_OFF_MAX);
s->freq.lit[cod.lc]++;
s->freq.off[cod.dc]++;
}
@ -551,22 +628,35 @@ struct sdefl_match {
int len;
};
static void
sdefl_fnd(struct sdefl_match *m, const struct sdefl *s,
int chain_len, int max_match, const unsigned char *in, int p) {
int i = s->tbl[sdefl_hash32(&in[p])];
int limit = ((p-SDEFL_WIN_SIZ)<SDEFL_NIL)?SDEFL_NIL:(p-SDEFL_WIN_SIZ);
sdefl_fnd(struct sdefl_match *m, const struct sdefl *s, int chain_len,
int max_match, const unsigned char *in, int p, int e) {
int i = s->tbl[sdefl_hash32(in + p)];
int limit = ((p - SDEFL_WIN_SIZ) < SDEFL_NIL) ? SDEFL_NIL : (p-SDEFL_WIN_SIZ);
assert(p < e);
assert(p + max_match <= e);
while (i > limit) {
if (in[i+m->len] == in[p+m->len] &&
(sdefl_uload32(&in[i]) == sdefl_uload32(&in[p]))){
assert(i + m->len < e);
assert(p + m->len < e);
assert(i + SDEFL_MIN_MATCH < e);
assert(p + SDEFL_MIN_MATCH < e);
if (in[i + m->len] == in[p + m->len] &&
(sdefl_uload32(&in[i]) == sdefl_uload32(&in[p]))) {
int n = SDEFL_MIN_MATCH;
while (n < max_match && in[i+n] == in[p+n]) n++;
while (n < max_match && in[i + n] == in[p + n]) {
assert(i + n < e);
assert(p + n < e);
n++;
}
if (n > m->len) {
m->len = n, m->off = p - i;
if (n == max_match) break;
if (n == max_match)
break;
}
}
if (!(--chain_len)) break;
i = s->prv[i&SDEFL_WIN_MSK];
i = s->prv[i & SDEFL_WIN_MSK];
}
}
static int
@ -579,18 +669,20 @@ sdefl_compr(struct sdefl *s, unsigned char *out, const unsigned char *in,
for (n = 0; n < SDEFL_HASH_SIZ; ++n) {
s->tbl[n] = SDEFL_NIL;
}
do {int blk_end = i + SDEFL_BLK_MAX < in_len ? i + SDEFL_BLK_MAX : in_len;
do {int blk_begin = i;
int blk_end = ((i + SDEFL_BLK_MAX) < in_len) ? (i + SDEFL_BLK_MAX) : in_len;
while (i < blk_end) {
struct sdefl_match m = {0};
int max_match = ((in_len-i)>SDEFL_MAX_MATCH) ? SDEFL_MAX_MATCH:(in_len-i);
int left = blk_end - i;
int max_match = (left > SDEFL_MAX_MATCH) ? SDEFL_MAX_MATCH : left;
int nice_match = pref[lvl] < max_match ? pref[lvl] : max_match;
int run = 1, inc = 1, run_inc;
int run = 1, inc = 1, run_inc = 0;
if (max_match > SDEFL_MIN_MATCH) {
sdefl_fnd(&m, s, max_chain, max_match, in, i);
sdefl_fnd(&m, s, max_chain, max_match, in, i, in_len);
}
if (lvl >= 5 && m.len >= SDEFL_MIN_MATCH && m.len < nice_match){
if (lvl >= 5 && m.len >= SDEFL_MIN_MATCH && m.len + 1 < nice_match){
struct sdefl_match m2 = {0};
sdefl_fnd(&m2, s, max_chain, m.len+1, in, i+1);
sdefl_fnd(&m2, s, max_chain, m.len + 1, in, i + 1, in_len);
m.len = (m2.len > m.len) ? 0 : m.len;
}
if (m.len >= SDEFL_MIN_MATCH) {
@ -615,20 +707,23 @@ sdefl_compr(struct sdefl *s, unsigned char *out, const unsigned char *in,
unsigned h = sdefl_hash32(&in[i]);
s->prv[i&SDEFL_WIN_MSK] = s->tbl[h];
s->tbl[h] = i, i += inc;
assert(i <= blk_end);
}
} else {
i += run_inc;
assert(i <= blk_end);
}
}
if (litlen) {
sdefl_seq(s, i - litlen, litlen);
litlen = 0;
}
sdefl_flush(&q, s, blk_end == in_len, in);
sdefl_flush(&q, s, blk_end == in_len, in, blk_begin, blk_end);
} while (i < in_len);
if (s->bitcnt)
if (s->bitcnt) {
sdefl_put(&q, s, 0x00, 8 - s->bitcnt);
}
assert(s->bitcnt == 0);
return (int)(q - out);
}
extern int
@ -688,9 +783,8 @@ zsdeflate(struct sdefl *s, void *out, const void *in, int n, int lvl) {
}
extern int
sdefl_bound(int len) {
int a = 128 + (len * 110) / 100;
int b = 128 + len + ((len / (31 * 1024)) + 1) * 5;
return (a > b) ? a : b;
int max_blocks = 1 + sdefl_div_round_up(len, SDEFL_RAW_BLK_SIZE);
int bound = 5 * max_blocks + len + 1 + 4 + 8;
return bound;
}
#endif /* SDEFL_IMPLEMENTATION */

View file

@ -10,7 +10,7 @@ as needed to keep the implementation as concise as possible.
- Dual license with either MIT or public domain
- Small implementation
- Deflate: 525 LoC
- Inflate: 320 LoC
- Inflate: 500 LoC
- Webassembly:
- Deflate ~3.7 KB (~2.2KB compressed)
- Inflate ~3.6 KB (~2.2KB compressed)
@ -39,10 +39,10 @@ this file implementation in *one* C or C++ file to prevent collisions.
| zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 |
| zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 |
| zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 |
| sdefl 1.0 -0 | 127 MB/s | 371 MB/s | 40004116 | 39.88 |
| sdefl 1.0 -1 | 111 MB/s | 398 MB/s | 38940674 | 38.82 |
| sdefl 1.0 -5 | 45 MB/s | 420 MB/s | 36577183 | 36.46 |
| sdefl 1.0 -7 | 38 MB/s | 423 MB/s | 36523781 | 36.41 |
| sdefl 1.0 -0 | 127 MB/s | 355 MB/s | 40004116 | 39.88 |
| sdefl 1.0 -1 | 111 MB/s | 413 MB/s | 38940674 | 38.82 |
| sdefl 1.0 -5 | 45 MB/s | 436 MB/s | 36577183 | 36.46 |
| sdefl 1.0 -7 | 38 MB/s | 432 MB/s | 36523781 | 36.41 |
| libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 |
| libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 |
| libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 |
@ -51,20 +51,20 @@ this file implementation in *one* C or C++ file to prevent collisions.
### Compression
Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia):
| File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` |
| :------ | ---------: | -----------------: | ---------: | ----------: |
| dickens | 10.192.446 | 4,260,187| 3,845,261| 3,833,657 |
| mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 |
| mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 |
| nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 |
| ooffice | 6.152.192 | 3,320,063 | 3,186,373 | 3,183,815 |
| osdb | 10.085.684 | 3,919,646 | 3,649,510 | 3,649,477 |
| reymont | 6.627.202 | 2,263,378 | 1,857,588 | 1,827,237 |
| samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 |
| sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 |
| webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 |
| xml | 5.345.280 | 886,620| 674,009 | 662,141 |
| x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 |
| File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` |
| --------| -----------| -------------| ---------- | ------------|
| dickens | 10.192.446 | 4,260,187 | 3,845,261 | 3,833,657 |
| mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 |
| mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 |
| nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 |
| ooffice | 6.152.192 | 3,320,063 | 3,186,373 | 3,183,815 |
| osdb | 10.085.684 | 3,919,646 | 3,649,510 | 3,649,477 |
| reymont | 6.627.202 | 2,263,378 | 1,857,588 | 1,827,237 |
| samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 |
| sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 |
| webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 |
| xml | 5.345.280 | 886,620 | 674,009 | 662,141 |
| x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 |
## License
```
@ -72,7 +72,7 @@ Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2020 Micha Mettke
Copyright (c) 2020-2023 Micha Mettke
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
@ -151,7 +151,7 @@ extern int zsinflate(void *out, int cap, const void *in, int size);
#endif
#ifndef SINFL_NO_SIMD
#if __x86_64__ || defined(_WIN32) || defined(_WIN64)
#if defined(__x86_64__) || defined(_WIN32) || defined(_WIN64)
#include <emmintrin.h>
#define sinfl_char16 __m128i
#define sinfl_char16_ld(p) _mm_loadu_si128((const __m128i *)(void*)(p))
@ -183,6 +183,18 @@ sinfl_read64(const void *p) {
memcpy(&n, p, 8);
return n;
}
static void
sinfl_copy64(unsigned char **dst, unsigned char **src) {
unsigned long long n;
memcpy(&n, *src, 8);
memcpy(*dst, &n, 8);
*dst += 8, *src += 8;
}
static unsigned char*
sinfl_write64(unsigned char *dst, unsigned long long w) {
memcpy(dst, &w, 8);
return dst + 8;
}
#ifndef SINFL_NO_SIMD
static unsigned char*
sinfl_write128(unsigned char *dst, sinfl_char16 w) {
@ -195,25 +207,12 @@ sinfl_copy128(unsigned char **dst, unsigned char **src) {
sinfl_char16_str(*dst, n);
*dst += 16, *src += 16;
}
#else
static unsigned char*
sinfl_write64(unsigned char *dst, unsigned long long w) {
memcpy(dst, &w, 8);
return dst + 8;
}
static void
sinfl_copy64(unsigned char **dst, unsigned char **src) {
unsigned long long n;
memcpy(&n, *src, 8);
memcpy(*dst, &n, 8);
*dst += 8, *src += 8;
}
#endif
static void
sinfl_refill(struct sinfl *s) {
s->bitbuf |= sinfl_read64(s->bitptr) << s->bitcnt;
s->bitptr += (63 - s->bitcnt) >> 3;
s->bitcnt |= 56; /* bitcount is in range [56,63] */
s->bitcnt |= 56; /* bitcount in range [56,63] */
}
static int
sinfl_peek(struct sinfl *s, int cnt) {
@ -222,7 +221,7 @@ sinfl_peek(struct sinfl *s, int cnt) {
return s->bitbuf & ((1ull << cnt) - 1);
}
static void
sinfl_consume(struct sinfl *s, int cnt) {
sinfl_eat(struct sinfl *s, int cnt) {
assert(cnt <= s->bitcnt);
s->bitbuf >>= cnt;
s->bitcnt -= cnt;
@ -230,7 +229,7 @@ sinfl_consume(struct sinfl *s, int cnt) {
static int
sinfl__get(struct sinfl *s, int cnt) {
int res = sinfl_peek(s, cnt);
sinfl_consume(s, cnt);
sinfl_eat(s, cnt);
return res;
}
static int
@ -285,7 +284,7 @@ sinfl_build_subtbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
while (1) {
unsigned entry;
int bit, stride, i;
/* start new subtable */
/* start new sub-table */
if ((gen->word & ((1 << tbl_bits)-1)) != sub_prefix) {
int used = 0;
sub_prefix = gen->word & ((1 << tbl_bits)-1);
@ -299,7 +298,7 @@ sinfl_build_subtbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
tbl_end = sub_start + (1 << sub_bits);
tbl[sub_prefix] = (sub_start << 16) | 0x10 | (sub_bits & 0xf);
}
/* fill subtable */
/* fill sub-table */
entry = (*gen->sorted << 16) | ((gen->len - tbl_bits) & 0xf);
gen->sorted++;
i = sub_start + (gen->word >> tbl_bits);
@ -353,18 +352,17 @@ sinfl_build(unsigned *tbl, unsigned char *lens, int tbl_bits, int maxlen,
}
static int
sinfl_decode(struct sinfl *s, const unsigned *tbl, int bit_len) {
sinfl_refill(s);
{int idx = sinfl_peek(s, bit_len);
int idx = sinfl_peek(s, bit_len);
unsigned key = tbl[idx];
if (key & 0x10) {
/* sub-table lookup */
int len = key & 0x0f;
sinfl_consume(s, bit_len);
sinfl_eat(s, bit_len);
idx = sinfl_peek(s, len);
key = tbl[((key >> 16) & 0xffff) + (unsigned)idx];
}
sinfl_consume(s, key & 0x0f);
return (key >> 16) & 0x0fff;}
sinfl_eat(s, key & 0x0f);
return (key >> 16) & 0x0fff;
}
static int
sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size) {
@ -402,17 +400,21 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
} break;
case stored: {
/* uncompressed block */
int len;
sinfl_refill(&s);
unsigned len, nlen;
sinfl__get(&s,s.bitcnt & 7);
len = sinfl__get(&s,16);
//int nlen = sinfl__get(&s,16); // @raysan5: Unused variable?
in -= 2; s.bitcnt = 0;
len = (unsigned short)sinfl__get(&s,16);
nlen = (unsigned short)sinfl__get(&s,16);
s.bitptr -= s.bitcnt / 8;
s.bitbuf = s.bitcnt = 0;
if (len > (e-in) || !len)
if ((unsigned short)len != (unsigned short)~nlen)
return (int)(out-o);
memcpy(out, in, (size_t)len);
in += len, out += len;
if (len > (e - s.bitptr) || !len)
return (int)(out-o);
memcpy(out, s.bitptr, (size_t)len);
s.bitptr += len, out += len;
if (last) return (int)(out-o);
state = hdr;
} break;
case fixed: {
@ -430,40 +432,64 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
state = blk;
} break;
case dyn: {
/* dynamic huffman codes */
int n, i;
unsigned hlens[SINFL_PRE_TBL_SIZE];
unsigned char nlens[19] = {0}, lens[288+32];
/* dynamic huffman codes */
int n, i;
unsigned hlens[SINFL_PRE_TBL_SIZE];
unsigned char nlens[19] = {0}, lens[288+32];
sinfl_refill(&s);
{int nlit = 257 + sinfl__get(&s,5);
int ndist = 1 + sinfl__get(&s,5);
int nlen = 4 + sinfl__get(&s,4);
for (n = 0; n < nlen; n++)
nlens[order[n]] = (unsigned char)sinfl_get(&s,3);
sinfl_build(hlens, nlens, 7, 7, 19);
/* decode code lengths */
for (n = 0; n < nlit + ndist;) {
int sym = 0;
sinfl_refill(&s);
{int nlit = 257 + sinfl__get(&s,5);
int ndist = 1 + sinfl__get(&s,5);
int nlen = 4 + sinfl__get(&s,4);
for (n = 0; n < nlen; n++)
nlens[order[n]] = (unsigned char)sinfl_get(&s,3);
sinfl_build(hlens, nlens, 7, 7, 19);
/* decode code lengths */
for (n = 0; n < nlit + ndist;) {
int sym = sinfl_decode(&s, hlens, 7);
switch (sym) {default: lens[n++] = (unsigned char)sym; break;
case 16: for (i=3+sinfl_get(&s,2);i;i--,n++) lens[n]=lens[n-1]; break;
case 17: for (i=3+sinfl_get(&s,3);i;i--,n++) lens[n]=0; break;
case 18: for (i=11+sinfl_get(&s,7);i;i--,n++) lens[n]=0; break;}
}
/* build lit/dist tables */
sinfl_build(s.lits, lens, 10, 15, nlit);
sinfl_build(s.dsts, lens + nlit, 8, 15, ndist);
state = blk;}
sym = sinfl_decode(&s, hlens, 7);
switch (sym) {default: lens[n++] = (unsigned char)sym; break;
case 16: for (i=3+sinfl_get(&s,2);i;i--,n++) lens[n]=lens[n-1]; break;
case 17: for (i=3+sinfl_get(&s,3);i;i--,n++) lens[n]=0; break;
case 18: for (i=11+sinfl_get(&s,7);i;i--,n++) lens[n]=0; break;}
}
/* build lit/dist tables */
sinfl_build(s.lits, lens, 10, 15, nlit);
sinfl_build(s.dsts, lens + nlit, 8, 15, ndist);
state = blk;}
} break;
case blk: {
/* decompress block */
int sym = sinfl_decode(&s, s.lits, 10);
if (sym < 256) {
/* literal */
*out++ = (unsigned char)sym;
} else if (sym > 256) {sym -= 257; /* match symbol */
while (1) {
int sym;
sinfl_refill(&s);
sym = sinfl_decode(&s, s.lits, 10);
if (sym < 256) {
/* literal */
if (sinfl_unlikely(out >= oe)) {
return (int)(out-o);
}
*out++ = (unsigned char)sym;
sym = sinfl_decode(&s, s.lits, 10);
if (sym < 256) {
*out++ = (unsigned char)sym;
continue;
}
}
if (sinfl_unlikely(sym == 256)) {
/* end of block */
if (last) return (int)(out-o);
state = hdr;
break;
}
/* match */
if (sym >= 286) {
/* length codes 286 and 287 must not appear in compressed data */
return (int)(out-o);
}
sym -= 257;
{int len = sinfl__get(&s, lbits[sym]) + lbase[sym];
int dsym = sinfl_decode(&s, s.dsts, 8);
int offs = sinfl__get(&s, dbits[dsym]) + dbase[dsym];
@ -476,11 +502,17 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
#ifndef SINFL_NO_SIMD
if (sinfl_likely(oe - out >= 16 * 3)) {
if (offs >= 16) {
/* copy match */
/* simd copy match */
sinfl_copy128(&dst, &src);
sinfl_copy128(&dst, &src);
do sinfl_copy128(&dst, &src);
while (dst < out);
} else if (offs >= 8) {
/* word copy match */
sinfl_copy64(&dst, &src);
sinfl_copy64(&dst, &src);
do sinfl_copy64(&dst, &src);
while (dst < out);
} else if (offs == 1) {
/* rle match copying */
sinfl_char16 w = sinfl_char16_char(src[0]);
@ -489,6 +521,7 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
do dst = sinfl_write128(dst, w);
while (dst < out);
} else {
/* byte copy match */
*dst++ = *src++;
*dst++ = *src++;
do *dst++ = *src++;
@ -498,7 +531,7 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
#else
if (sinfl_likely(oe - out >= 3 * 8 - 3)) {
if (offs >= 8) {
/* copy match */
/* word copy match */
sinfl_copy64(&dst, &src);
sinfl_copy64(&dst, &src);
do sinfl_copy64(&dst, &src);
@ -513,6 +546,7 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
do dst = sinfl_write64(dst, w);
while (dst < out);
} else {
/* byte copy match */
*dst++ = *src++;
*dst++ = *src++;
do *dst++ = *src++;
@ -524,13 +558,8 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
*dst++ = *src++;
*dst++ = *src++;
do *dst++ = *src++;
while (dst < out);}
}
} else {
/* end of block */
if (last) return (int)(out-o);
state = hdr;
break;
while (dst < out);
}}
}
} break;}
}

File diff suppressed because it is too large Load diff

10303
raylib/external/stb_image_resize2.h vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -746,7 +746,7 @@ static int tinyobj_parse_and_index_mtl_file(tinyobj_material_t **materials_out,
(*materials_out) = NULL;
(*num_materials_out) = 0;
fp = fopen(filename, "r");
fp = fopen(filename, "rt");
if (!fp) {
fprintf(stderr, "TINYOBJ: Error reading file '%s': %s (%d)\n", filename, strerror(errno), errno);
return TINYOBJ_ERROR_FILE_OPERATION;
@ -1269,6 +1269,11 @@ int tinyobj_parse_obj(tinyobj_attrib_t *attrib, tinyobj_shape_t **shapes,
if (is_line_ending(buf, i, end_idx)) {
line_infos[line_no].pos = prev_pos;
line_infos[line_no].len = i - prev_pos;
// ---- QUICK BUG FIX : https://github.com/raysan5/raylib/issues/3473
if ( i > 0 && buf[i-1] == '\r' ) line_infos[line_no].len--;
// --------
prev_pos = i + 1;
line_no++;
}

View file

@ -555,7 +555,7 @@ int Vox_LoadFromMemory(unsigned char* pvoxData, unsigned int voxDataSize, VoxArr
version = ((unsigned int*)fileDataPtr)[0];
fileDataPtr += 4;
if (version != 150)
if (version != 150 && version != 200)
{
return VOX_ERROR_FILE_VERSION_NOT_MATCH; //"MagicaVoxel version doesn't match"
}