Update C sources

This commit is contained in:
Milan Nikolic 2023-11-09 14:32:33 +01:00
parent 07d1374c41
commit d0612c27b2
No known key found for this signature in database
GPG key ID: 9229D0EAA3AA4E75
17 changed files with 2216 additions and 1053 deletions

View file

@ -328,15 +328,6 @@ typedef struct cgltf_accessor_sparse
cgltf_component_type indices_component_type;
cgltf_buffer_view* values_buffer_view;
cgltf_size values_byte_offset;
cgltf_extras extras;
cgltf_extras indices_extras;
cgltf_extras values_extras;
cgltf_size extensions_count;
cgltf_extension* extensions;
cgltf_size indices_extensions_count;
cgltf_extension* indices_extensions;
cgltf_size values_extensions_count;
cgltf_extension* values_extensions;
} cgltf_accessor_sparse;
typedef struct cgltf_accessor
@ -419,9 +410,6 @@ typedef struct cgltf_texture_view
cgltf_float scale; /* equivalent to strength for occlusion_texture */
cgltf_bool has_transform;
cgltf_texture_transform transform;
cgltf_extras extras;
cgltf_size extensions_count;
cgltf_extension* extensions;
} cgltf_texture_view;
typedef struct cgltf_pbr_metallic_roughness
@ -504,6 +492,13 @@ typedef struct cgltf_iridescence
cgltf_texture_view iridescence_thickness_texture;
} cgltf_iridescence;
typedef struct cgltf_anisotropy
{
cgltf_float anisotropy_strength;
cgltf_float anisotropy_rotation;
cgltf_texture_view anisotropy_texture;
} cgltf_anisotropy;
typedef struct cgltf_material
{
char* name;
@ -517,6 +512,7 @@ typedef struct cgltf_material
cgltf_bool has_sheen;
cgltf_bool has_emissive_strength;
cgltf_bool has_iridescence;
cgltf_bool has_anisotropy;
cgltf_pbr_metallic_roughness pbr_metallic_roughness;
cgltf_pbr_specular_glossiness pbr_specular_glossiness;
cgltf_clearcoat clearcoat;
@ -527,6 +523,7 @@ typedef struct cgltf_material
cgltf_volume volume;
cgltf_emissive_strength emissive_strength;
cgltf_iridescence iridescence;
cgltf_anisotropy anisotropy;
cgltf_texture_view normal_texture;
cgltf_texture_view occlusion_texture;
cgltf_texture_view emissive_texture;
@ -559,7 +556,6 @@ typedef struct cgltf_draco_mesh_compression {
} cgltf_draco_mesh_compression;
typedef struct cgltf_mesh_gpu_instancing {
cgltf_buffer_view* buffer_view;
cgltf_attribute* attributes;
cgltf_size attributes_count;
} cgltf_mesh_gpu_instancing;
@ -842,10 +838,28 @@ 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);
cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count);
/* this function is deprecated and will be removed in the future; use cgltf_extras::data instead */
cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras* extras, char* dest, cgltf_size* dest_size);
cgltf_size cgltf_mesh_index(const cgltf_data* data, const cgltf_mesh* object);
cgltf_size cgltf_material_index(const cgltf_data* data, const cgltf_material* object);
cgltf_size cgltf_accessor_index(const cgltf_data* data, const cgltf_accessor* object);
cgltf_size cgltf_buffer_view_index(const cgltf_data* data, const cgltf_buffer_view* object);
cgltf_size cgltf_buffer_index(const cgltf_data* data, const cgltf_buffer* object);
cgltf_size cgltf_image_index(const cgltf_data* data, const cgltf_image* object);
cgltf_size cgltf_texture_index(const cgltf_data* data, const cgltf_texture* object);
cgltf_size cgltf_sampler_index(const cgltf_data* data, const cgltf_sampler* object);
cgltf_size cgltf_skin_index(const cgltf_data* data, const cgltf_skin* object);
cgltf_size cgltf_camera_index(const cgltf_data* data, const cgltf_camera* object);
cgltf_size cgltf_light_index(const cgltf_data* data, const cgltf_light* object);
cgltf_size cgltf_node_index(const cgltf_data* data, const cgltf_node* object);
cgltf_size cgltf_scene_index(const cgltf_data* data, const cgltf_scene* object);
cgltf_size cgltf_animation_index(const cgltf_data* data, const cgltf_animation* object);
cgltf_size cgltf_animation_sampler_index(const cgltf_animation* animation, const cgltf_animation_sampler* object);
cgltf_size cgltf_animation_channel_index(const cgltf_animation* animation, const cgltf_animation_channel* object);
#ifdef __cplusplus
}
#endif
@ -866,6 +880,7 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras*
#ifdef CGLTF_IMPLEMENTATION
#include <assert.h> /* For assert */
#include <string.h> /* For strncpy */
#include <stdio.h> /* For fopen */
#include <limits.h> /* For UINT_MAX etc */
@ -875,10 +890,6 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras*
#include <stdlib.h> /* For malloc, free, atoi, atof */
#endif
#if CGLTF_VALIDATE_ENABLE_ASSERTS
#include <assert.h>
#endif
/* JSMN_PARENT_LINKS is necessary to make parsing large structures linear in input size */
#define JSMN_PARENT_LINKS
@ -1000,7 +1011,7 @@ static cgltf_result cgltf_default_file_read(const struct cgltf_memory_options* m
{
fseek(file, 0, SEEK_END);
#ifdef _WIN32
#ifdef _MSC_VER
__int64 length = _ftelli64(file);
#else
long length = ftell(file);
@ -1144,7 +1155,7 @@ cgltf_result cgltf_parse(const cgltf_options* options, const void* data, cgltf_s
json_chunk += GlbChunkHeaderSize;
const void* bin = 0;
const void* bin = NULL;
cgltf_size bin_size = 0;
if (GlbHeaderSize + GlbChunkHeaderSize + json_length + GlbChunkHeaderSize <= size)
@ -1763,12 +1774,6 @@ static void cgltf_free_extensions(cgltf_data* data, cgltf_extension* extensions,
data->memory.free_func(data->memory.user_data, extensions);
}
static void cgltf_free_texture_view(cgltf_data* data, cgltf_texture_view* view)
{
cgltf_free_extensions(data, view->extensions, view->extensions_count);
cgltf_free_extras(data, &view->extras);
}
void cgltf_free(cgltf_data* data)
{
if (!data)
@ -1790,15 +1795,6 @@ void cgltf_free(cgltf_data* data)
{
data->memory.free_func(data->memory.user_data, data->accessors[i].name);
if(data->accessors[i].is_sparse)
{
cgltf_free_extensions(data, data->accessors[i].sparse.extensions, data->accessors[i].sparse.extensions_count);
cgltf_free_extensions(data, data->accessors[i].sparse.indices_extensions, data->accessors[i].sparse.indices_extensions_count);
cgltf_free_extensions(data, data->accessors[i].sparse.values_extensions, data->accessors[i].sparse.values_extensions_count);
cgltf_free_extras(data, &data->accessors[i].sparse.extras);
cgltf_free_extras(data, &data->accessors[i].sparse.indices_extras);
cgltf_free_extras(data, &data->accessors[i].sparse.values_extras);
}
cgltf_free_extensions(data, data->accessors[i].extensions, data->accessors[i].extensions_count);
cgltf_free_extras(data, &data->accessors[i].extras);
}
@ -1900,50 +1896,6 @@ void cgltf_free(cgltf_data* data)
{
data->memory.free_func(data->memory.user_data, data->materials[i].name);
if(data->materials[i].has_pbr_metallic_roughness)
{
cgltf_free_texture_view(data, &data->materials[i].pbr_metallic_roughness.metallic_roughness_texture);
cgltf_free_texture_view(data, &data->materials[i].pbr_metallic_roughness.base_color_texture);
}
if(data->materials[i].has_pbr_specular_glossiness)
{
cgltf_free_texture_view(data, &data->materials[i].pbr_specular_glossiness.diffuse_texture);
cgltf_free_texture_view(data, &data->materials[i].pbr_specular_glossiness.specular_glossiness_texture);
}
if(data->materials[i].has_clearcoat)
{
cgltf_free_texture_view(data, &data->materials[i].clearcoat.clearcoat_texture);
cgltf_free_texture_view(data, &data->materials[i].clearcoat.clearcoat_roughness_texture);
cgltf_free_texture_view(data, &data->materials[i].clearcoat.clearcoat_normal_texture);
}
if(data->materials[i].has_specular)
{
cgltf_free_texture_view(data, &data->materials[i].specular.specular_texture);
cgltf_free_texture_view(data, &data->materials[i].specular.specular_color_texture);
}
if(data->materials[i].has_transmission)
{
cgltf_free_texture_view(data, &data->materials[i].transmission.transmission_texture);
}
if (data->materials[i].has_volume)
{
cgltf_free_texture_view(data, &data->materials[i].volume.thickness_texture);
}
if(data->materials[i].has_sheen)
{
cgltf_free_texture_view(data, &data->materials[i].sheen.sheen_color_texture);
cgltf_free_texture_view(data, &data->materials[i].sheen.sheen_roughness_texture);
}
if(data->materials[i].has_iridescence)
{
cgltf_free_texture_view(data, &data->materials[i].iridescence.iridescence_texture);
cgltf_free_texture_view(data, &data->materials[i].iridescence.iridescence_thickness_texture);
}
cgltf_free_texture_view(data, &data->materials[i].normal_texture);
cgltf_free_texture_view(data, &data->materials[i].occlusion_texture);
cgltf_free_texture_view(data, &data->materials[i].emissive_texture);
cgltf_free_extensions(data, data->materials[i].extensions, data->materials[i].extensions_count);
cgltf_free_extras(data, &data->materials[i].extras);
}
@ -2198,8 +2150,6 @@ static cgltf_ssize cgltf_component_read_integer(const void* in, cgltf_component_
return *((const uint16_t*) in);
case cgltf_component_type_r_32u:
return *((const uint32_t*) in);
case cgltf_component_type_r_32f:
return (cgltf_ssize)*((const float*) in);
case cgltf_component_type_r_8:
return *((const int8_t*) in);
case cgltf_component_type_r_8u:
@ -2217,8 +2167,6 @@ static cgltf_size cgltf_component_read_index(const void* in, cgltf_component_typ
return *((const uint16_t*) in);
case cgltf_component_type_r_32u:
return *((const uint32_t*) in);
case cgltf_component_type_r_32f:
return (cgltf_size)((cgltf_ssize)*((const float*) in));
case cgltf_component_type_r_8u:
return *((const uint8_t*) in);
default:
@ -2356,21 +2304,41 @@ cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_fl
cgltf_size element_count = float_count / floats_per_element;
// First pass: convert each element in the base accessor.
cgltf_float* dest = out;
cgltf_accessor dense = *accessor;
dense.is_sparse = 0;
for (cgltf_size index = 0; index < element_count; index++, dest += floats_per_element)
if (accessor->buffer_view == NULL)
{
if (!cgltf_accessor_read_float(&dense, index, dest, floats_per_element))
memset(out, 0, element_count * floats_per_element * sizeof(cgltf_float));
}
else
{
const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
if (element == NULL)
{
return 0;
}
element += accessor->offset;
if (accessor->component_type == cgltf_component_type_r_32f && accessor->stride == floats_per_element * sizeof(cgltf_float))
{
memcpy(out, element, element_count * floats_per_element * sizeof(cgltf_float));
}
else
{
cgltf_float* dest = out;
for (cgltf_size index = 0; index < element_count; index++, dest += floats_per_element, element += accessor->stride)
{
if (!cgltf_element_read_float(element, accessor->type, accessor->component_type, accessor->normalized, dest, floats_per_element))
{
return 0;
}
}
}
}
// Second pass: write out each element in the sparse accessor.
if (accessor->is_sparse)
{
const cgltf_accessor_sparse* sparse = &dense.sparse;
const cgltf_accessor_sparse* sparse = &accessor->sparse;
const uint8_t* index_data = cgltf_buffer_view_data(sparse->indices_buffer_view);
const uint8_t* reader_head = cgltf_buffer_view_data(sparse->values_buffer_view);
@ -2384,17 +2352,15 @@ cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_fl
reader_head += sparse->values_byte_offset;
cgltf_size index_stride = cgltf_component_size(sparse->indices_component_type);
for (cgltf_size reader_index = 0; reader_index < sparse->count; reader_index++, index_data += index_stride)
for (cgltf_size reader_index = 0; reader_index < sparse->count; reader_index++, index_data += index_stride, reader_head += accessor->stride)
{
size_t writer_index = cgltf_component_read_index(index_data, sparse->indices_component_type);
float* writer_head = out + writer_index * floats_per_element;
if (!cgltf_element_read_float(reader_head, dense.type, dense.component_type, dense.normalized, writer_head, floats_per_element))
if (!cgltf_element_read_float(reader_head, accessor->type, accessor->component_type, accessor->normalized, writer_head, floats_per_element))
{
return 0;
}
reader_head += dense.stride;
}
}
@ -2488,6 +2454,143 @@ cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size
return cgltf_component_read_index(element, accessor->component_type);
}
cgltf_size cgltf_mesh_index(const cgltf_data* data, const cgltf_mesh* object)
{
assert(object && (cgltf_size)(object - data->meshes) < data->meshes_count);
return (cgltf_size)(object - data->meshes);
}
cgltf_size cgltf_material_index(const cgltf_data* data, const cgltf_material* object)
{
assert(object && (cgltf_size)(object - data->materials) < data->materials_count);
return (cgltf_size)(object - data->materials);
}
cgltf_size cgltf_accessor_index(const cgltf_data* data, const cgltf_accessor* object)
{
assert(object && (cgltf_size)(object - data->accessors) < data->accessors_count);
return (cgltf_size)(object - data->accessors);
}
cgltf_size cgltf_buffer_view_index(const cgltf_data* data, const cgltf_buffer_view* object)
{
assert(object && (cgltf_size)(object - data->buffer_views) < data->buffer_views_count);
return (cgltf_size)(object - data->buffer_views);
}
cgltf_size cgltf_buffer_index(const cgltf_data* data, const cgltf_buffer* object)
{
assert(object && (cgltf_size)(object - data->buffers) < data->buffers_count);
return (cgltf_size)(object - data->buffers);
}
cgltf_size cgltf_image_index(const cgltf_data* data, const cgltf_image* object)
{
assert(object && (cgltf_size)(object - data->images) < data->images_count);
return (cgltf_size)(object - data->images);
}
cgltf_size cgltf_texture_index(const cgltf_data* data, const cgltf_texture* object)
{
assert(object && (cgltf_size)(object - data->textures) < data->textures_count);
return (cgltf_size)(object - data->textures);
}
cgltf_size cgltf_sampler_index(const cgltf_data* data, const cgltf_sampler* object)
{
assert(object && (cgltf_size)(object - data->samplers) < data->samplers_count);
return (cgltf_size)(object - data->samplers);
}
cgltf_size cgltf_skin_index(const cgltf_data* data, const cgltf_skin* object)
{
assert(object && (cgltf_size)(object - data->skins) < data->skins_count);
return (cgltf_size)(object - data->skins);
}
cgltf_size cgltf_camera_index(const cgltf_data* data, const cgltf_camera* object)
{
assert(object && (cgltf_size)(object - data->cameras) < data->cameras_count);
return (cgltf_size)(object - data->cameras);
}
cgltf_size cgltf_light_index(const cgltf_data* data, const cgltf_light* object)
{
assert(object && (cgltf_size)(object - data->lights) < data->lights_count);
return (cgltf_size)(object - data->lights);
}
cgltf_size cgltf_node_index(const cgltf_data* data, const cgltf_node* object)
{
assert(object && (cgltf_size)(object - data->nodes) < data->nodes_count);
return (cgltf_size)(object - data->nodes);
}
cgltf_size cgltf_scene_index(const cgltf_data* data, const cgltf_scene* object)
{
assert(object && (cgltf_size)(object - data->scenes) < data->scenes_count);
return (cgltf_size)(object - data->scenes);
}
cgltf_size cgltf_animation_index(const cgltf_data* data, const cgltf_animation* object)
{
assert(object && (cgltf_size)(object - data->animations) < data->animations_count);
return (cgltf_size)(object - data->animations);
}
cgltf_size cgltf_animation_sampler_index(const cgltf_animation* animation, const cgltf_animation_sampler* object)
{
assert(object && (cgltf_size)(object - animation->samplers) < animation->samplers_count);
return (cgltf_size)(object - animation->samplers);
}
cgltf_size cgltf_animation_channel_index(const cgltf_animation* animation, const cgltf_animation_channel* object)
{
assert(object && (cgltf_size)(object - animation->channels) < animation->channels_count);
return (cgltf_size)(object - animation->channels);
}
cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, cgltf_uint* out, cgltf_size index_count)
{
if (out == NULL)
{
return accessor->count;
}
index_count = accessor->count < index_count ? accessor->count : index_count;
if (accessor->is_sparse)
{
return 0;
}
if (accessor->buffer_view == NULL)
{
return 0;
}
const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
if (element == NULL)
{
return 0;
}
element += accessor->offset;
if (accessor->component_type == cgltf_component_type_r_32u && accessor->stride == sizeof(cgltf_uint))
{
memcpy(out, element, index_count * sizeof(cgltf_uint));
}
else
{
cgltf_uint* dest = out;
for (cgltf_size index = 0; index < index_count; index++, dest++, element += accessor->stride)
{
*dest = (cgltf_uint)cgltf_component_read_index(element, accessor->component_type);
}
}
return index_count;
}
#define CGLTF_ERROR_JSON -1
#define CGLTF_ERROR_NOMEM -2
#define CGLTF_ERROR_LEGACY -3
@ -2864,6 +2967,10 @@ static int cgltf_parse_json_draco_mesh_compression(cgltf_options* options, jsmnt
out_draco_mesh_compression->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
++i;
}
else
{
i = cgltf_skip_json(tokens, i+1);
}
if (i < 0)
{
@ -2889,11 +2996,9 @@ static int cgltf_parse_json_mesh_gpu_instancing(cgltf_options* options, jsmntok_
{
i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_mesh_gpu_instancing->attributes, &out_mesh_gpu_instancing->attributes_count);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "bufferView") == 0)
else
{
++i;
out_mesh_gpu_instancing->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
++i;
i = cgltf_skip_json(tokens, i+1);
}
if (i < 0)
@ -3291,7 +3396,7 @@ static cgltf_component_type cgltf_json_to_component_type(jsmntok_t const* tok, c
}
}
static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor_sparse* out_sparse)
static int cgltf_parse_json_accessor_sparse(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_accessor_sparse* out_sparse)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
@ -3338,14 +3443,6 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co
out_sparse->indices_component_type = cgltf_json_to_component_type(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
{
i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sparse->indices_extras);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
{
i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->indices_extensions_count, &out_sparse->indices_extensions);
}
else
{
i = cgltf_skip_json(tokens, i+1);
@ -3381,14 +3478,6 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co
out_sparse->values_byte_offset = cgltf_json_to_size(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
{
i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sparse->values_extras);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
{
i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->values_extensions_count, &out_sparse->values_extensions);
}
else
{
i = cgltf_skip_json(tokens, i+1);
@ -3400,14 +3489,6 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co
}
}
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
{
i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_sparse->extras);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
{
i = cgltf_parse_json_unprocessed_extensions(options, tokens, i, json_chunk, &out_sparse->extensions_count, &out_sparse->extensions);
}
else
{
i = cgltf_skip_json(tokens, i+1);
@ -3521,7 +3602,7 @@ static int cgltf_parse_json_accessor(cgltf_options* options, jsmntok_t const* to
else if (cgltf_json_strcmp(tokens + i, json_chunk, "sparse") == 0)
{
out_accessor->is_sparse = 1;
i = cgltf_parse_json_accessor_sparse(options, tokens, i + 1, json_chunk, &out_accessor->sparse);
i = cgltf_parse_json_accessor_sparse(tokens, i + 1, json_chunk, &out_accessor->sparse);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
{
@ -3593,6 +3674,8 @@ static int cgltf_parse_json_texture_transform(jsmntok_t const* tokens, int i, co
static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_texture_view* out_texture_view)
{
(void)options;
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
out_texture_view->scale = 1.0f;
@ -3629,28 +3712,12 @@ static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const
out_texture_view->scale = cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
{
i = cgltf_parse_json_extras(options, tokens, i + 1, json_chunk, &out_texture_view->extras);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extensions") == 0)
{
++i;
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
if(out_texture_view->extensions)
{
return CGLTF_ERROR_JSON;
}
int extensions_size = tokens[i].size;
out_texture_view->extensions_count = 0;
out_texture_view->extensions = (cgltf_extension*)cgltf_calloc(options, sizeof(cgltf_extension), extensions_size);
if (!out_texture_view->extensions)
{
return CGLTF_ERROR_NOMEM;
}
++i;
@ -3665,7 +3732,7 @@ static int cgltf_parse_json_texture_view(cgltf_options* options, jsmntok_t const
}
else
{
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture_view->extensions[out_texture_view->extensions_count++]));
i = cgltf_skip_json(tokens, i + 1);
}
if (i < 0)
@ -3719,13 +3786,11 @@ static int cgltf_parse_json_pbr_metallic_roughness(cgltf_options* options, jsmnt
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "baseColorTexture") == 0)
{
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
&out_pbr->base_color_texture);
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->base_color_texture);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "metallicRoughnessTexture") == 0)
{
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk,
&out_pbr->metallic_roughness_texture);
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_pbr->metallic_roughness_texture);
}
else
{
@ -4128,6 +4193,47 @@ static int cgltf_parse_json_iridescence(cgltf_options* options, jsmntok_t const*
return i;
}
static int cgltf_parse_json_anisotropy(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_anisotropy* out_anisotropy)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
int size = tokens[i].size;
++i;
for (int j = 0; j < size; ++j)
{
CGLTF_CHECK_KEY(tokens[i]);
if (cgltf_json_strcmp(tokens + i, json_chunk, "anisotropyStrength") == 0)
{
++i;
out_anisotropy->anisotropy_strength = cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "anisotropyRotation") == 0)
{
++i;
out_anisotropy->anisotropy_rotation = cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "anisotropyTexture") == 0)
{
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_anisotropy->anisotropy_texture);
}
else
{
i = cgltf_skip_json(tokens, i + 1);
}
if (i < 0)
{
return i;
}
}
return i;
}
static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_image* out_image)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
@ -4516,6 +4622,11 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to
out_material->has_iridescence = 1;
i = cgltf_parse_json_iridescence(options, tokens, i + 1, json_chunk, &out_material->iridescence);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_anisotropy") == 0)
{
out_material->has_anisotropy = 1;
i = cgltf_parse_json_anisotropy(options, tokens, i + 1, json_chunk, &out_material->anisotropy);
}
else
{
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++]));
@ -6367,6 +6478,8 @@ static int cgltf_fixup_pointers(cgltf_data* data)
CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_thickness_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].anisotropy.anisotropy_texture.texture, data->textures, data->textures_count);
}
for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
@ -6411,7 +6524,6 @@ static int cgltf_fixup_pointers(cgltf_data* data)
if (data->nodes[i].has_mesh_gpu_instancing)
{
CGLTF_PTRFIXUP_REQ(data->nodes[i].mesh_gpu_instancing.buffer_view, data->buffer_views, data->buffer_views_count);
for (cgltf_size m = 0; m < data->nodes[i].mesh_gpu_instancing.attributes_count; ++m)
{
CGLTF_PTRFIXUP_REQ(data->nodes[i].mesh_gpu_instancing.attributes[m].data, data->accessors, data->accessors_count);

View file

@ -1,6 +1,6 @@
/*
FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
dr_flac - v0.12.39 - 2022-09-17
dr_flac - v0.12.42 - 2023-11-02
David Reid - mackron@gmail.com
@ -235,12 +235,12 @@ extern "C" {
#define DRFLAC_VERSION_MAJOR 0
#define DRFLAC_VERSION_MINOR 12
#define DRFLAC_VERSION_REVISION 39
#define DRFLAC_VERSION_REVISION 42
#define DRFLAC_VERSION_STRING DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION)
#include <stddef.h> /* For size_t. */
/* Sized types. */
/* Sized Types */
typedef signed char drflac_int8;
typedef unsigned char drflac_uint8;
typedef signed short drflac_int16;
@ -273,7 +273,9 @@ typedef drflac_uint8 drflac_bool8;
typedef drflac_uint32 drflac_bool32;
#define DRFLAC_TRUE 1
#define DRFLAC_FALSE 0
/* End Sized Types */
/* Decorations */
#if !defined(DRFLAC_API)
#if defined(DRFLAC_DLL)
#if defined(_WIN32)
@ -303,6 +305,7 @@ typedef drflac_uint32 drflac_bool32;
#define DRFLAC_PRIVATE static
#endif
#endif
/* End Decorations */
#if defined(_MSC_VER) && _MSC_VER >= 1700 /* Visual Studio 2012 */
#define DRFLAC_DEPRECATED __declspec(deprecated)
@ -321,6 +324,16 @@ typedef drflac_uint32 drflac_bool32;
DRFLAC_API void drflac_version(drflac_uint32* pMajor, drflac_uint32* pMinor, drflac_uint32* pRevision);
DRFLAC_API const char* drflac_version_string(void);
/* Allocation Callbacks */
typedef struct
{
void* pUserData;
void* (* onMalloc)(size_t sz, void* pUserData);
void* (* onRealloc)(void* p, size_t sz, void* pUserData);
void (* onFree)(void* p, void* pUserData);
} drflac_allocation_callbacks;
/* End Allocation Callbacks */
/*
As data is read from the client it is placed into an internal buffer for fast access. This controls the size of that buffer. Larger values means more speed,
but also more memory. In my testing there is diminishing returns after about 4KB, but you can fiddle with this to suit your own needs. Must be a multiple of 8.
@ -329,11 +342,22 @@ but also more memory. In my testing there is diminishing returns after about 4KB
#define DR_FLAC_BUFFER_SIZE 4096
#endif
/* Check if we can enable 64-bit optimizations. */
/* Architecture Detection */
#if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
#define DRFLAC_64BIT
#endif
#if defined(__x86_64__) || defined(_M_X64)
#define DRFLAC_X64
#elif defined(__i386) || defined(_M_IX86)
#define DRFLAC_X86
#elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64)
#define DRFLAC_ARM
#endif
/* End Architecture Detection */
#ifdef DRFLAC_64BIT
typedef drflac_uint64 drflac_cache_t;
#else
@ -562,14 +586,6 @@ will be set to one of the DRFLAC_METADATA_BLOCK_TYPE_* tokens.
typedef void (* drflac_meta_proc)(void* pUserData, drflac_metadata* pMetadata);
typedef struct
{
void* pUserData;
void* (* onMalloc)(size_t sz, void* pUserData);
void* (* onRealloc)(void* p, size_t sz, void* pUserData);
void (* onFree)(void* p, void* pUserData);
} drflac_allocation_callbacks;
/* Structure for internal use. Only used for decoders opened with drflac_open_memory. */
typedef struct
{
@ -1351,6 +1367,7 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
#include <stdlib.h>
#include <string.h>
/* Inline */
#ifdef _MSC_VER
#define DRFLAC_INLINE __forceinline
#elif defined(__GNUC__)
@ -1377,15 +1394,7 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
#else
#define DRFLAC_INLINE
#endif
/* CPU architecture. */
#if defined(__x86_64__) || defined(_M_X64)
#define DRFLAC_X64
#elif defined(__i386) || defined(_M_IX86)
#define DRFLAC_X86
#elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64)
#define DRFLAC_ARM
#endif
/* End Inline */
/*
Intrinsics Support
@ -1623,6 +1632,7 @@ static DRFLAC_INLINE drflac_bool32 drflac_has_sse41(void)
#define DRFLAC_MAX_SIMD_VECTOR_SIZE 64 /* 64 for AVX-512 in the future. */
/* Result Codes */
typedef drflac_int32 drflac_result;
#define DRFLAC_SUCCESS 0
#define DRFLAC_ERROR -1 /* A generic error. */
@ -1678,7 +1688,10 @@ typedef drflac_int32 drflac_result;
#define DRFLAC_CANCELLED -51
#define DRFLAC_MEMORY_ALREADY_MAPPED -52
#define DRFLAC_AT_END -53
#define DRFLAC_CRC_MISMATCH -128
#define DRFLAC_CRC_MISMATCH -100
/* End Result Codes */
#define DRFLAC_SUBFRAME_CONSTANT 0
#define DRFLAC_SUBFRAME_VERBATIM 1
@ -1838,7 +1851,7 @@ static DRFLAC_INLINE drflac_uint32 drflac__swap_endian_uint32(drflac_uint32 n)
#if defined(_MSC_VER) && !defined(__clang__)
return _byteswap_ulong(n);
#elif defined(__GNUC__) || defined(__clang__)
#if defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(DRFLAC_64BIT) /* <-- 64-bit inline assembly has not been tested, so disabling for now. */
#if defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(__ARM_ARCH_6M__) && !defined(DRFLAC_64BIT) /* <-- 64-bit inline assembly has not been tested, so disabling for now. */
/* Inline assembly optimized implementation for ARM. In my testing, GCC does not generate optimized code with __builtin_bswap32(). */
drflac_uint32 r;
__asm__ __volatile__ (
@ -2802,7 +2815,7 @@ static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x)
return r;
}
#elif defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(DRFLAC_64BIT) /* <-- I haven't tested 64-bit inline assembly, so only enabling this for the 32-bit build for now. */
#elif defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(__ARM_ARCH_6M__) && !defined(DRFLAC_64BIT) /* <-- I haven't tested 64-bit inline assembly, so only enabling this for the 32-bit build for now. */
{
unsigned int r;
__asm__ __volatile__ (
@ -6479,7 +6492,7 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
for (;;) {
drflac_metadata metadata;
drflac_uint8 isLastBlock = 0;
drflac_uint8 blockType;
drflac_uint8 blockType = 0;
drflac_uint32 blockSize;
if (drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == DRFLAC_FALSE) {
return DRFLAC_FALSE;
@ -8141,6 +8154,7 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
#include <wchar.h> /* For wcslen(), wcsrtombs() */
#endif
/* Errno */
/* drflac_result_from_errno() is only used for fopen() and wfopen() so putting it inside DR_WAV_NO_STDIO for now. If something else needs this later we can move it out. */
#include <errno.h>
static drflac_result drflac_result_from_errno(int e)
@ -8544,7 +8558,9 @@ static drflac_result drflac_result_from_errno(int e)
default: return DRFLAC_ERROR;
}
}
/* End Errno */
/* fopen */
static drflac_result drflac_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
@ -8702,6 +8718,7 @@ static drflac_result drflac_wfopen(FILE** ppFile, const wchar_t* pFilePath, cons
return DRFLAC_SUCCESS;
}
#endif
/* End fopen */
static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead)
{
@ -11666,6 +11683,7 @@ DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 p
/* High Level APIs */
/* SIZE_MAX */
#if defined(SIZE_MAX)
#define DRFLAC_SIZE_MAX SIZE_MAX
#else
@ -11675,6 +11693,7 @@ DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 p
#define DRFLAC_SIZE_MAX 0xFFFFFFFF
#endif
#endif
/* End SIZE_MAX */
/* Using a macro as the definition of the drflac__full_decode_and_close_*() API family. Sue me. */
@ -12058,6 +12077,16 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
/*
REVISION HISTORY
================
v0.12.42 - 2023-11-02
- Fix build for ARMv6-M.
- Fix a compilation warning with GCC.
v0.12.41 - 2023-06-17
- Fix an incorrect date in revision history. No functional change.
v0.12.40 - 2023-05-22
- Minor code restructure. No functional change.
v0.12.39 - 2022-09-17
- Fix compilation with DJGPP.
- Fix compilation error with Visual Studio 2019 and the ARM build.
@ -12488,7 +12517,7 @@ For more information, please refer to <http://unlicense.org/>
===============================================================================
ALTERNATIVE 2 - MIT No Attribution
===============================================================================
Copyright 2020 David Reid
Copyright 2023 David Reid
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

View file

@ -1,6 +1,6 @@
/*
MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
dr_mp3 - v0.6.34 - 2022-09-17
dr_mp3 - v0.6.38 - 2023-11-02
David Reid - mackron@gmail.com
@ -95,12 +95,12 @@ extern "C" {
#define DRMP3_VERSION_MAJOR 0
#define DRMP3_VERSION_MINOR 6
#define DRMP3_VERSION_REVISION 34
#define DRMP3_VERSION_REVISION 38
#define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION)
#include <stddef.h> /* For size_t. */
/* Sized types. */
/* Sized Types */
typedef signed char drmp3_int8;
typedef unsigned char drmp3_uint8;
typedef signed short drmp3_int16;
@ -133,7 +133,9 @@ typedef drmp3_uint8 drmp3_bool8;
typedef drmp3_uint32 drmp3_bool32;
#define DRMP3_TRUE 1
#define DRMP3_FALSE 0
/* End Sized Types */
/* Decorations */
#if !defined(DRMP3_API)
#if defined(DRMP3_DLL)
#if defined(_WIN32)
@ -163,7 +165,9 @@ typedef drmp3_uint32 drmp3_bool32;
#define DRMP3_PRIVATE static
#endif
#endif
/* End Decorations */
/* Result Codes */
typedef drmp3_int32 drmp3_result;
#define DRMP3_SUCCESS 0
#define DRMP3_ERROR -1 /* A generic error. */
@ -219,11 +223,12 @@ typedef drmp3_int32 drmp3_result;
#define DRMP3_CANCELLED -51
#define DRMP3_MEMORY_ALREADY_MAPPED -52
#define DRMP3_AT_END -53
/* End Result Codes */
#define DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152
#define DRMP3_MAX_SAMPLES_PER_FRAME (DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2)
/* Inline */
#ifdef _MSC_VER
#define DRMP3_INLINE __forceinline
#elif defined(__GNUC__)
@ -250,12 +255,24 @@ typedef drmp3_int32 drmp3_result;
#else
#define DRMP3_INLINE
#endif
/* End Inline */
DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision);
DRMP3_API const char* drmp3_version_string(void);
/* Allocation Callbacks */
typedef struct
{
void* pUserData;
void* (* onMalloc)(size_t sz, void* pUserData);
void* (* onRealloc)(void* p, size_t sz, void* pUserData);
void (* onFree)(void* p, void* pUserData);
} drmp3_allocation_callbacks;
/* End Allocation Callbacks */
/*
Low Level Push API
==================
@ -329,14 +346,6 @@ will be either drmp3_seek_origin_start or drmp3_seek_origin_current.
*/
typedef drmp3_bool32 (* drmp3_seek_proc)(void* pUserData, int offset, drmp3_seek_origin origin);
typedef struct
{
void* pUserData;
void* (* onMalloc)(size_t sz, void* pUserData);
void* (* onRealloc)(void* p, size_t sz, void* pUserData);
void (* onFree)(void* p, void* pUserData);
} drmp3_allocation_callbacks;
typedef struct
{
drmp3_uint32 channels;
@ -704,7 +713,7 @@ static int drmp3_have_simd(void)
#endif
#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64)
#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(__ARM_ARCH_6M__)
#define DRMP3_HAVE_ARMV6 1
static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(drmp3_int32 a)
{
@ -2415,6 +2424,7 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num
Main Public API
************************************************************************************************************************************************************/
/* SIZE_MAX */
#if defined(SIZE_MAX)
#define DRMP3_SIZE_MAX SIZE_MAX
#else
@ -2424,6 +2434,7 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num
#define DRMP3_SIZE_MAX 0xFFFFFFFF
#endif
#endif
/* End SIZE_MAX */
/* Options. */
#ifndef DRMP3_SEEK_LEADING_MP3_FRAMES
@ -2690,6 +2701,11 @@ static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sa
DRMP3_ASSERT(pMP3->pData != NULL);
DRMP3_ASSERT(pMP3->dataCapacity > 0);
/* Do a runtime check here to try silencing a false-positive from clang-analyzer. */
if (pMP3->pData == NULL) {
return 0;
}
pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info); /* <-- Safe size_t -> int conversion thanks to the check above. */
/* Consume the data. */
@ -2931,6 +2947,7 @@ DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t
#include <stdio.h>
#include <wchar.h> /* For wcslen(), wcsrtombs() */
/* Errno */
/* drmp3_result_from_errno() is only used inside DR_MP3_NO_STDIO for now. Move this out if it's ever used elsewhere. */
#include <errno.h>
static drmp3_result drmp3_result_from_errno(int e)
@ -3334,7 +3351,9 @@ static drmp3_result drmp3_result_from_errno(int e)
default: return DRMP3_ERROR;
}
}
/* End Errno */
/* fopen */
static drmp3_result drmp3_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
@ -3490,7 +3509,7 @@ static drmp3_result drmp3_wfopen(FILE** ppFile, const wchar_t* pFilePath, const
return DRMP3_SUCCESS;
}
/* End fopen */
static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead)
@ -4476,6 +4495,18 @@ counts rather than sample counts.
/*
REVISION HISTORY
================
v0.6.38 - 2023-11-02
- Fix build for ARMv6-M.
v0.6.37 - 2023-07-07
- Silence a static analysis warning.
v0.6.36 - 2023-06-17
- Fix an incorrect date in revision history. No functional change.
v0.6.35 - 2023-05-22
- Minor code restructure. No functional change.
v0.6.34 - 2022-09-17
- Fix compilation with DJGPP.
- Fix compilation when compiling with x86 with no SSE2.
@ -4777,7 +4808,7 @@ For more information, please refer to <http://unlicense.org/>
===============================================================================
ALTERNATIVE 2 - MIT No Attribution
===============================================================================
Copyright 2020 David Reid
Copyright 2023 David Reid
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

1235
raylib/external/dr_wav.h vendored

File diff suppressed because it is too large Load diff

40
raylib/external/m3d.h vendored
View file

@ -89,7 +89,7 @@ typedef uint8_t M3D_VOXEL;
#define M3D_NUMBONE 4
#endif
#ifndef M3D_BONEMAXLEVEL
#define M3D_BONEMAXLEVEL 8
#define M3D_BONEMAXLEVEL 64
#endif
#ifndef _MSC_VER
#ifndef _inline
@ -2172,6 +2172,8 @@ M3D_INDEX _m3d_gettx(m3d_t *model, m3dread_t readfilecb, m3dfree_t freecb, char
stbi__context s;
stbi__result_info ri;
/* failsafe */
if(!fn || !*fn) return M3D_UNDEF;
/* do we have loaded this texture already? */
for(i = 0; i < model->numtexture; i++)
if(!strcmp(fn, model->texture[i].name)) return i;
@ -2246,9 +2248,9 @@ void _m3d_getpr(m3d_t *model, _unused m3dread_t readfilecb, _unused m3dfree_t f
{
#ifdef M3D_PR_INTERP
unsigned int i, len = 0;
unsigned char *buff = readfilecb ? (*readfilecb)(fn, &len) : NULL;
unsigned char *buff = readfilecb && fn && *fn ? (*readfilecb)(fn, &len) : NULL;
if(!buff && model->inlined) {
if(!buff && fn && *fn && model->inlined) {
for(i = 0; i < model->numinlined; i++)
if(!strcmp(fn, model->inlined[i].name)) {
buff = model->inlined[i].data;
@ -3439,6 +3441,7 @@ memerr: M3D_LOG("Out of memory");
model->bone[i].numweight = 0;
model->bone[i].weight = NULL;
}
if(i != model->numbone) { M3D_LOG("Truncated bone chunk"); model->numbone = i; model->numskin = 0; model->errcode = M3D_ERR_BONE; }
/* read skin definitions */
if(model->numskin) {
model->skin = (m3ds_t*)M3D_MALLOC(model->numskin * sizeof(m3ds_t));
@ -3471,6 +3474,7 @@ memerr: M3D_LOG("Out of memory");
model->skin[i].weight[j] /= w;
}
}
if(i != model->numskin) { M3D_LOG("Truncated skin in bone chunk"); model->numskin = i; model->errcode = M3D_ERR_BONE; }
}
} else
/* material */
@ -4726,14 +4730,14 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
unsigned char *out = NULL, *z = NULL, weights[M3D_NUMBONE < 8 ? 8 : M3D_NUMBONE], *norm = NULL;
unsigned int i, j, k, l, n, o, len, chunklen, *length;
int maxvox = 0, minvox = 0;
M3D_FLOAT scale = (M3D_FLOAT)0.0, min_x, max_x, min_y, max_y, min_z, max_z;
M3D_FLOAT scale = (M3D_FLOAT)0.0, min_x, max_x, min_y, max_y, min_z, max_z, mw;
M3D_INDEX last, *vrtxidx = NULL, *mtrlidx = NULL, *tmapidx = NULL, *skinidx = NULL;
#ifdef M3D_VERTEXMAX
M3D_INDEX lastp;
#endif
uint32_t idx, numcmap = 0, *cmap = NULL, numvrtx = 0, maxvrtx = 0, numtmap = 0, maxtmap = 0, numproc = 0;
uint32_t numskin = 0, maxskin = 0, numstr = 0, maxt = 0, maxbone = 0, numgrp = 0, maxgrp = 0, *grpidx = NULL;
uint8_t *opa;
uint8_t *opa = NULL;
m3dcd_t *cd;
m3dc_t *cmd;
m3dstr_t *str = NULL;
@ -5072,10 +5076,9 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
for(i = 0; i < model->numskin; i++) {
if(skinidx[i] == M3D_UNDEF) continue;
memset(&sk, 0, sizeof(m3dssave_t));
for(j = 0, min_x = (M3D_FLOAT)0.0; j < M3D_NUMBONE && model->skin[i].boneid[j] != M3D_UNDEF &&
model->skin[i].weight[j] > (M3D_FLOAT)0.0; j++) {
for(j = 0, min_x = (M3D_FLOAT)0.0; j < M3D_NUMBONE && model->skin[i].boneid[j] != M3D_UNDEF; j++) {
sk.data.boneid[j] = model->skin[i].boneid[j];
sk.data.weight[j] = model->skin[i].weight[j];
sk.data.weight[j] = model->skin[i].weight[j] > (M3D_FLOAT)0.0 ? model->skin[i].weight[j] : (M3D_FLOAT)0.01;
min_x += sk.data.weight[j];
}
if(j > maxbone) maxbone = j;
@ -5191,6 +5194,7 @@ memerr: if(vrtxidx) M3D_FREE(vrtxidx);
if(sa) M3D_FREE(sa);
if(sd) M3D_FREE(sd);
if(out) M3D_FREE(out);
if(opa) free(opa);
if(h) M3D_FREE(h);
M3D_LOG("Out of memory");
model->errcode = M3D_ERR_ALLOC;
@ -5218,8 +5222,16 @@ memerr: if(vrtxidx) M3D_FREE(vrtxidx);
if(model->preview.data && model->preview.length) {
sl = _m3d_safestr(sn, 0);
if(sl) {
/* gcc thinks that "ptr is used after free", well, gcc is simply wrong. */
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuse-after-free"
#endif
ptr -= (uintptr_t)out; len = (unsigned int)((uintptr_t)ptr + (uintptr_t)20 + strlen(sl));
out = (unsigned char*)M3D_REALLOC(out, len); ptr += (uintptr_t)out;
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
if(!out) { setlocale(LC_NUMERIC, ol); goto memerr; }
ptr += sprintf(ptr, "Preview\r\n%s.png\r\n\r\n", sl);
M3D_FREE(sl); sl = NULL;
@ -5228,6 +5240,7 @@ memerr: if(vrtxidx) M3D_FREE(vrtxidx);
M3D_FREE(sn); sn = NULL;
/* texture map */
if(numtmap && tmap && !(flags & M3D_EXP_NOTXTCRD) && !(flags & M3D_EXP_NOFACE)) {
/* interestingly gcc does not complain about "ptr is used after free" here, although the code is 100% the same */
ptr -= (uintptr_t)out; len = (unsigned int)((uintptr_t)ptr + (uintptr_t)(maxtmap * 32) + (uintptr_t)12);
out = (unsigned char*)M3D_REALLOC(out, len); ptr += (uintptr_t)out;
if(!out) { setlocale(LC_NUMERIC, ol); goto memerr; }
@ -5846,9 +5859,13 @@ memerr: if(vrtxidx) M3D_FREE(vrtxidx);
if(skin[i].newidx == last) continue;
last = skin[i].newidx;
memset(&weights, 0, nb_s);
for(j = 0; j < (uint32_t)nb_s && skin[i].data.boneid[j] != M3D_UNDEF &&
skin[i].data.weight[j] > (M3D_FLOAT)0.0; j++)
for(j = k = l = 0, mw = 0.0; j < (uint32_t)nb_s && skin[i].data.boneid[j] != M3D_UNDEF &&
skin[i].data.weight[j] > (M3D_FLOAT)0.0; j++) {
if(mw < skin[i].data.weight[j]) { mw = skin[i].data.weight[j]; k = j; }
weights[j] = (uint8_t)(skin[i].data.weight[j] * 255);
if(!weights[j]) { weights[j]++; l--; }
}
weights[k] += l;
switch(nb_s) {
case 1: weights[0] = 255; break;
case 2: memcpy(out, weights, 2); out += 2; break;
@ -5941,7 +5958,7 @@ memerr: if(vrtxidx) M3D_FREE(vrtxidx);
}
/* mesh face */
if(model->numface && face && !(flags & M3D_EXP_NOFACE)) {
chunklen = 8 + si_s + model->numface * (6 * vi_s + 3 * ti_s + si_s + 1);
chunklen = 8 + si_s + model->numface * (9 * vi_s + 3 * ti_s + si_s + 1);
h = (m3dhdr_t*)M3D_REALLOC(h, len + chunklen);
if(!h) goto memerr;
memcpy((uint8_t*)h + len, "MESH", 4);
@ -6268,6 +6285,7 @@ memerr: if(vrtxidx) M3D_FREE(vrtxidx);
if(skin) M3D_FREE(skin);
if(str) M3D_FREE(str);
if(vrtx) M3D_FREE(vrtx);
if(opa) free(opa);
if(h) M3D_FREE(h);
return out;
}

View file

@ -1,6 +1,6 @@
/*
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
miniaudio - v0.11.19 - TBD
miniaudio - v0.11.19 - 2023-11-04
David Reid - mackron@gmail.com
@ -7042,7 +7042,7 @@ struct ma_device_config
ma_uint32 periods;
ma_performance_profile performanceProfile;
ma_bool8 noPreSilencedOutputBuffer; /* When set to true, the contents of the output buffer passed into the data callback will be left undefined rather than initialized to silence. */
ma_bool8 noClip; /* When set to true, the contents of the output buffer passed into the data callback will be clipped after returning. Only applies when the playback sample format is f32. */
ma_bool8 noClip; /* When set to true, the contents of the output buffer passed into the data callback will not be clipped after returning. Only applies when the playback sample format is f32. */
ma_bool8 noDisableDenormals; /* Do not disable denormals when firing the data callback. */
ma_bool8 noFixedSizedCallback; /* Disables strict fixed-sized data callbacks. Setting this to true will result in the period size being treated only as a hint to the backend. This is an optimization for those who don't need fixed sized callbacks. */
ma_device_data_proc dataCallback;
@ -8626,8 +8626,8 @@ then be set directly on the structure. Below are the members of the `ma_device_c
callback will write to every sample in the output buffer, or if you are doing your own clearing.
noClip
When set to true, the contents of the output buffer passed into the data callback will be clipped after returning. When set to false (default), the
contents of the output buffer are left alone after returning and it will be left up to the backend itself to decide whether or not the clip. This only
When set to true, the contents of the output buffer are left alone after returning and it will be left up to the backend itself to decide whether or
not to clip. When set to false (default), the contents of the output buffer passed into the data callback will be clipped after returning. This only
applies when the playback sample format is f32.
noDisableDenormals
@ -40464,7 +40464,7 @@ static ma_result ma_context_init__webaudio(ma_context* pContext, const ma_contex
};
miniaudio.unlock_event_types = (function(){
return ['touchstart', 'touchend', 'click'];
return ['touchend', 'click'];
})();
miniaudio.unlock = function() {
@ -60158,7 +60158,7 @@ extern "C" {
#define MA_DR_FLAC_XSTRINGIFY(x) MA_DR_FLAC_STRINGIFY(x)
#define MA_DR_FLAC_VERSION_MAJOR 0
#define MA_DR_FLAC_VERSION_MINOR 12
#define MA_DR_FLAC_VERSION_REVISION 41
#define MA_DR_FLAC_VERSION_REVISION 42
#define MA_DR_FLAC_VERSION_STRING MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MAJOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MINOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_REVISION)
#include <stddef.h>
#if defined(_MSC_VER) && _MSC_VER >= 1700
@ -60445,7 +60445,7 @@ extern "C" {
#define MA_DR_MP3_XSTRINGIFY(x) MA_DR_MP3_STRINGIFY(x)
#define MA_DR_MP3_VERSION_MAJOR 0
#define MA_DR_MP3_VERSION_MINOR 6
#define MA_DR_MP3_VERSION_REVISION 37
#define MA_DR_MP3_VERSION_REVISION 38
#define MA_DR_MP3_VERSION_STRING MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MAJOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MINOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_REVISION)
#include <stddef.h>
#define MA_DR_MP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152
@ -82387,7 +82387,7 @@ static MA_INLINE ma_uint32 ma_dr_flac__swap_endian_uint32(ma_uint32 n)
#if defined(_MSC_VER) && !defined(__clang__)
return _byteswap_ulong(n);
#elif defined(__GNUC__) || defined(__clang__)
#if defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(MA_64BIT)
#if defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(__ARM_ARCH_6M__) && !defined(MA_64BIT)
ma_uint32 r;
__asm__ __volatile__ (
#if defined(MA_64BIT)
@ -83128,7 +83128,7 @@ static MA_INLINE ma_uint32 ma_dr_flac__clz_lzcnt(ma_dr_flac_cache_t x)
);
return r;
}
#elif defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(MA_64BIT)
#elif defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(__ARM_ARCH_6M__) && !defined(MA_64BIT)
{
unsigned int r;
__asm__ __volatile__ (
@ -85869,7 +85869,7 @@ static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRea
for (;;) {
ma_dr_flac_metadata metadata;
ma_uint8 isLastBlock = 0;
ma_uint8 blockType;
ma_uint8 blockType = 0;
ma_uint32 blockSize;
if (ma_dr_flac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == MA_FALSE) {
return MA_FALSE;
@ -89949,7 +89949,7 @@ static int ma_dr_mp3_have_simd(void)
#else
#define MA_DR_MP3_HAVE_SIMD 0
#endif
#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64)
#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(__ARM_ARCH_6M__)
#define MA_DR_MP3_HAVE_ARMV6 1
static __inline__ __attribute__((always_inline)) ma_int32 ma_dr_mp3_clip_int16_arm(ma_int32 a)
{

170
raylib/external/qoa.h vendored
View file

@ -8,71 +8,96 @@ QOA - The "Quite OK Audio" format for fast, lossy audio compression
-- Data Format
A QOA file has an 8 byte file header, followed by a number of frames. Each frame
consists of an 8 byte frame header, the current 8 byte en-/decoder state per
channel and 256 slices per channel. Each slice is 8 bytes wide and encodes 20
samples of audio data.
QOA encodes pulse-code modulated (PCM) audio data with up to 255 channels,
sample rates from 1 up to 16777215 hertz and a bit depth of 16 bits.
Note that the last frame of a file may contain less than 256 slices per channel.
The last slice (per channel) in the last frame may contain less 20 samples, but
the slice will still be 8 bytes wide, with the unused samples zeroed out.
The compression method employed in QOA is lossy; it discards some information
from the uncompressed PCM data. For many types of audio signals this compression
is "transparent", i.e. the difference from the original file is often not
audible.
The samplerate and number of channels is only stated in the frame headers, but
not in the file header. A decoder may peek into the first frame of the file to
find these values.
QOA encodes 20 samples of 16 bit PCM data into slices of 64 bits. A single
sample therefore requires 3.2 bits of storage space, resulting in a 5x
compression (16 / 3.2).
In a valid QOA file all frames have the same number of channels and the same
samplerate. These restrictions may be relaxed for streaming. This remains to
be decided.
A QOA file consists of an 8 byte file header, followed by a number of frames.
Each frame contains an 8 byte frame header, the current 16 byte en-/decoder
state per channel and 256 slices per channel. Each slice is 8 bytes wide and
encodes 20 samples of audio data.
All values in a QOA file are BIG ENDIAN. Luckily, EVERYTHING in a QOA file,
including the headers, is 64 bit aligned, so it's possible to read files with
just a read_u64() that does the byte swapping if necessary.
In pseudocode, the file layout is as follows:
All values, including the slices, are big endian. The file layout is as follows:
struct {
struct {
char magic[4]; // magic bytes 'qoaf'
uint32_t samples; // number of samples per channel in this file
} file_header; // = 64 bits
char magic[4]; // magic bytes "qoaf"
uint32_t samples; // samples per channel in this file
} file_header;
struct {
struct {
uint8_t num_channels; // number of channels
uint8_t num_channels; // no. of channels
uint24_t samplerate; // samplerate in hz
uint16_t fsamples; // sample count per channel in this frame
uint16_t fsize; // frame size (including the frame header)
} frame_header; // = 64 bits
uint16_t fsamples; // samples per channel in this frame
uint16_t fsize; // frame size (includes this header)
} frame_header;
struct {
int16_t history[4]; // = 64 bits
int16_t weights[4]; // = 64 bits
int16_t history[4]; // most recent last
int16_t weights[4]; // most recent last
} lms_state[num_channels];
qoa_slice_t slices[256][num_channels]; // = 64 bits each
} frames[samples * channels / qoa_max_framesize()];
} qoa_file;
qoa_slice_t slices[256][num_channels];
Wheras the 64bit qoa_slice_t is defined as follows:
} frames[ceil(samples / (256 * 20))];
} qoa_file_t;
Each `qoa_slice_t` contains a quantized scalefactor `sf_quant` and 20 quantized
residuals `qrNN`:
.- QOA_SLICE -- 64 bits, 20 samples --------------------------/ /------------.
| Byte[0] | Byte[1] | Byte[2] \ \ Byte[7] |
| 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 | 7 6 5 / / 2 1 0 |
|------------+--------+--------+--------+---------+---------+-\ \--+---------|
| sf_index | r00 | r01 | r02 | r03 | r04 | / / | r19 |
| sf_quant | qr00 | qr01 | qr02 | qr03 | qr04 | / / | qr19 |
`-------------------------------------------------------------\ \------------`
`sf_index` defines the scalefactor to use for this slice as an index into the
qoa_scalefactor_tab[16]
Each frame except the last must contain exactly 256 slices per channel. The last
frame may contain between 1 .. 256 (inclusive) slices per channel. The last
slice (for each channel) in the last frame may contain less than 20 samples; the
slice still must be 8 bytes wide, with the unused samples zeroed out.
`r00`--`r19` are the residuals for the individual samples, divided by the
scalefactor and quantized by the qoa_quant_tab[].
Channels are interleaved per slice. E.g. for 2 channel stereo:
slice[0] = L, slice[1] = R, slice[2] = L, slice[3] = R ...
In the decoder, a prediction of the next sample is computed by multiplying the
state (the last four output samples) with the predictor. The residual from the
slice is then dequantized using the qoa_dequant_tab[] and added to the
prediction. The result is clamped to int16 to form the final output sample.
A valid QOA file or stream must have at least one frame. Each frame must contain
at least one channel and one sample with a samplerate between 1 .. 16777215
(inclusive).
If the total number of samples is not known by the encoder, the samples in the
file header may be set to 0x00000000 to indicate that the encoder is
"streaming". In a streaming context, the samplerate and number of channels may
differ from frame to frame. For static files (those with samples set to a
non-zero value), each frame must have the same number of channels and same
samplerate.
Note that this implementation of QOA only handles files with a known total
number of samples.
A decoder should support at least 8 channels. The channel layout for channel
counts 1 .. 8 is:
1. Mono
2. L, R
3. L, R, C
4. FL, FR, B/SL, B/SR
5. FL, FR, C, B/SL, B/SR
6. FL, FR, C, LFE, B/SL, B/SR
7. FL, FR, C, LFE, B, SL, SR
8. FL, FR, C, LFE, BL, BR, SL, SR
QOA predicts each audio sample based on the previously decoded ones using a
"Sign-Sign Least Mean Squares Filter" (LMS). This prediction plus the
dequantized residual forms the final output sample.
*/
@ -158,7 +183,7 @@ the higher end. Note that the residual zero is identical to the lowest positive
value. This is mostly fine, since the qoa_div() function always rounds away
from zero. */
static int qoa_quant_tab[17] = {
static const int qoa_quant_tab[17] = {
7, 7, 7, 5, 5, 3, 3, 1, /* -8..-1 */
0, /* 0 */
0, 2, 2, 4, 4, 6, 6, 6 /* 1.. 8 */
@ -169,13 +194,13 @@ static int qoa_quant_tab[17] = {
less accurate at the higher end. In theory, the highest scalefactor that we
would need to encode the highest 16bit residual is (2**16)/8 = 8192. However we
rely on the LMS filter to predict samples accurately enough that a maximum
residual of one quarter of the 16 bit range is high sufficient. I.e. with the
residual of one quarter of the 16 bit range is sufficient. I.e. with the
scalefactor 2048 times the quant range of 8 we can encode residuals up to 2**14.
The scalefactor values are computed as:
scalefactor_tab[s] <- round(pow(s + 1, 2.75)) */
static int qoa_scalefactor_tab[16] = {
static const int qoa_scalefactor_tab[16] = {
1, 7, 21, 45, 84, 138, 211, 304, 421, 562, 731, 928, 1157, 1419, 1715, 2048
};
@ -188,7 +213,7 @@ do this in .16 fixed point with integers, instead of floats.
The reciprocal_tab is computed as:
reciprocal_tab[s] <- ((1<<16) + scalefactor_tab[s] - 1) / scalefactor_tab[s] */
static int qoa_reciprocal_tab[16] = {
static const int qoa_reciprocal_tab[16] = {
65536, 9363, 3121, 1457, 781, 475, 311, 216, 156, 117, 90, 71, 57, 47, 39, 32
};
@ -200,9 +225,13 @@ Since qoa_div rounds away from the zero, the smallest entries are mapped to 3/4
instead of 1. The dequant_tab assumes the following dequantized values for each
of the quant_tab indices and is computed as:
float dqt[8] = {0.75, -0.75, 2.5, -2.5, 4.5, -4.5, 7, -7};
dequant_tab[s][q] <- round(scalefactor_tab[s] * dqt[q]) */
dequant_tab[s][q] <- round_ties_away_from_zero(scalefactor_tab[s] * dqt[q])
static int qoa_dequant_tab[16][8] = {
The rounding employed here is "to nearest, ties away from zero", i.e. positive
and negative values are treated symmetrically.
*/
static const int qoa_dequant_tab[16][8] = {
{ 1, -1, 3, -3, 5, -5, 7, -7},
{ 5, -5, 18, -18, 32, -32, 49, -49},
{ 16, -16, 53, -53, 95, -95, 147, -147},
@ -270,7 +299,21 @@ static inline int qoa_div(int v, int scalefactor) {
}
static inline int qoa_clamp(int v, int min, int max) {
return (v < min) ? min : (v > max) ? max : v;
if (v < min) { return min; }
if (v > max) { return max; }
return v;
}
/* This specialized clamp function for the signed 16 bit range improves decode
performance quite a bit. The extra if() statement works nicely with the CPUs
branch prediction as this branch is rarely taken. */
static inline int qoa_clamp_s16(int v) {
if ((unsigned int)(v + 32768) > 65535) {
if (v < -32768) { return -32768; }
if (v > 32767) { return 32767; }
}
return v;
}
static inline qoa_uint64_t qoa_read_u64(const unsigned char *bytes, unsigned int *p) {
@ -312,6 +355,7 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned
unsigned int p = 0;
unsigned int slices = (frame_len + QOA_SLICE_LEN - 1) / QOA_SLICE_LEN;
unsigned int frame_size = QOA_FRAME_SIZE(channels, slices);
int prev_scalefactor[QOA_MAX_CHANNELS] = {0};
/* Write the frame header */
qoa_write_u64((
@ -321,8 +365,24 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned
(qoa_uint64_t)frame_size
), bytes, &p);
/* Write the current LMS state */
for (int c = 0; c < channels; c++) {
/* If the weights have grown too large, reset them to 0. This may happen
with certain high-frequency sounds. This is a last resort and will
introduce quite a bit of noise, but should at least prevent pops/clicks */
int weights_sum =
qoa->lms[c].weights[0] * qoa->lms[c].weights[0] +
qoa->lms[c].weights[1] * qoa->lms[c].weights[1] +
qoa->lms[c].weights[2] * qoa->lms[c].weights[2] +
qoa->lms[c].weights[3] * qoa->lms[c].weights[3];
if (weights_sum > 0x2fffffff) {
qoa->lms[c].weights[0] = 0;
qoa->lms[c].weights[1] = 0;
qoa->lms[c].weights[2] = 0;
qoa->lms[c].weights[3] = 0;
}
/* Write the current LMS state */
qoa_uint64_t weights = 0;
qoa_uint64_t history = 0;
for (int i = 0; i < QOA_LMS_LEN; i++) {
@ -348,8 +408,13 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned
qoa_uint64_t best_error = -1;
qoa_uint64_t best_slice;
qoa_lms_t best_lms;
int best_scalefactor;
for (int scalefactor = 0; scalefactor < 16; scalefactor++) {
for (int sfi = 0; sfi < 16; sfi++) {
/* There is a strong correlation between the scalefactors of
neighboring slices. As an optimization, start testing
the best scalefactor of the previous slice first. */
int scalefactor = (sfi + prev_scalefactor[c]) % 16;
/* We have to reset the LMS state to the last known good one
before trying each scalefactor, as each pass updates the LMS
@ -367,7 +432,7 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned
int clamped = qoa_clamp(scaled, -8, 8);
int quantized = qoa_quant_tab[clamped + 8];
int dequantized = qoa_dequant_tab[scalefactor][quantized];
int reconstructed = qoa_clamp(predicted + dequantized, -32768, 32767);
int reconstructed = qoa_clamp_s16(predicted + dequantized);
long long error = (sample - reconstructed);
current_error += error * error;
@ -383,9 +448,12 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned
best_error = current_error;
best_slice = slice;
best_lms = lms;
best_scalefactor = scalefactor;
}
}
prev_scalefactor[c] = best_scalefactor;
qoa->lms[c] = best_lms;
#ifdef QOA_RECORD_TOTAL_ERROR
qoa->error += best_error;
@ -553,7 +621,7 @@ unsigned int qoa_decode_frame(const unsigned char *bytes, unsigned int size, qoa
int predicted = qoa_lms_predict(&qoa->lms[c]);
int quantized = (slice >> 57) & 0x7;
int dequantized = qoa_dequant_tab[scalefactor][quantized];
int reconstructed = qoa_clamp(predicted + dequantized, -32768, 32767);
int reconstructed = qoa_clamp_s16(predicted + dequantized);
sample_data[si] = reconstructed;
slice <<= 3;

12
raylib/external/qoi.h vendored
View file

@ -594,7 +594,7 @@ void *qoi_decode(const void *data, int size, qoi_desc *desc, int channels) {
int qoi_write(const char *filename, const void *data, const qoi_desc *desc) {
FILE *f = fopen(filename, "wb");
int size;
int size, err;
void *encoded;
if (!f) {
@ -608,10 +608,12 @@ int qoi_write(const char *filename, const void *data, const qoi_desc *desc) {
}
fwrite(encoded, 1, size, f);
fflush(f);
err = ferror(f);
fclose(f);
QOI_FREE(encoded);
return size;
return err ? 0 : size;
}
void *qoi_read(const char *filename, qoi_desc *desc, int channels) {
@ -625,11 +627,10 @@ void *qoi_read(const char *filename, qoi_desc *desc, int channels) {
fseek(f, 0, SEEK_END);
size = ftell(f);
if (size <= 0) {
if (size <= 0 || fseek(f, 0, SEEK_SET) != 0) {
fclose(f);
return NULL;
}
fseek(f, 0, SEEK_SET);
data = QOI_MALLOC(size);
if (!data) {
@ -639,8 +640,7 @@ void *qoi_read(const char *filename, qoi_desc *desc, int channels) {
bytes_read = fread(data, 1, size, f);
fclose(f);
pixels = qoi_decode(data, bytes_read, desc, channels);
pixels = (bytes_read != size) ? NULL : qoi_decode(data, bytes_read, desc, channels);
QOI_FREE(data);
return pixels;
}

View file

@ -1,6 +1,6 @@
/**********************************************************************************************
*
* rl_gputex - GPU compressed textures loading and saving
* rl_gputex v1.0 - GPU compressed textures loading and saving
*
* DESCRIPTION:
*

View file

@ -186,7 +186,7 @@ int *rprand_load_sequence(unsigned int count, int min, int max)
{
int *sequence = NULL;
if (count > (abs(max - min) + 1))
if (count > (unsigned int)(abs(max - min) + 1))
{
RPRAND_LOG("WARNING: Sequence count required is greater than range provided\n");
//count = (max - min);
@ -198,9 +198,9 @@ int *rprand_load_sequence(unsigned int count, int min, int max)
int value = 0;
bool value_is_dup = false;
for (int i = 0; i < count;)
for (unsigned int i = 0; i < count;)
{
value = (rprand_xoshiro()%(abs(max - min) + 1)) + min;
value = ((int)rprand_xoshiro()%(abs(max - min) + 1)) + min;
value_is_dup = false;
for (int j = 0; j < i; j++)

View file

@ -122,6 +122,7 @@ extern "C" {
struct sinfl {
const unsigned char *bitptr;
const unsigned char *bitend; // @raysan5: added
unsigned long long bitbuf;
int bitcnt;
@ -185,9 +186,10 @@ sinfl_read64(const void *p) {
}
static void
sinfl_copy64(unsigned char **dst, unsigned char **src) {
unsigned long long n;
memcpy(&n, *src, 8);
memcpy(*dst, &n, 8);
//unsigned long long n;
//memcpy(&n, *src, 8);
//memcpy(*dst, &n, 8);
memcpy(*dst, *src, 8); // @raysan5
*dst += 8, *src += 8;
}
static unsigned char*
@ -210,9 +212,22 @@ sinfl_copy128(unsigned char **dst, unsigned char **src) {
#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 in range [56,63] */
if (s->bitend - s->bitptr >= 8) {
// @raysan5: original code, only those 3 lines
s->bitbuf |= sinfl_read64(s->bitptr) << s->bitcnt;
s->bitptr += (63 - s->bitcnt) >> 3;
s->bitcnt |= 56; /* bitcount in range [56,63] */
} else {
// @raysan5: added this case when bits remaining < 8
int bitswant = 63 - s->bitcnt;
int byteswant = bitswant >> 3;
int bytesuse = s->bitend - s->bitptr <= byteswant ? (int)(s->bitend - s->bitptr) : byteswant;
unsigned long long n = 0;
memcpy(&n, s->bitptr, bytesuse);
s->bitbuf |= n << s->bitcnt;
s->bitptr += bytesuse;
s->bitcnt += bytesuse << 3;
}
}
static int
sinfl_peek(struct sinfl *s, int cnt) {
@ -384,6 +399,7 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
int last = 0;
s.bitptr = in;
s.bitend = e; // @raysan5: added
while (1) {
switch (state) {
case hdr: {