Update external libraries

This commit is contained in:
Ray 2021-04-14 21:06:00 +02:00
parent 646f1f06c4
commit 37f523fdeb
4 changed files with 781 additions and 391 deletions

527
src/external/cgltf.h vendored
View file

@ -1,7 +1,7 @@
/**
* cgltf - a single-file glTF 2.0 parser written in C99.
*
* Version: 1.8
* Version: 1.10
*
* Website: https://github.com/jkuhlmann/cgltf
*
@ -24,7 +24,7 @@
*
* `cgltf_options` is the struct passed to `cgltf_parse()` to control
* parts of the parsing process. You can use it to force the file type
* and provide memory allocation as well as file operation callbacks.
* and provide memory allocation as well as file operation callbacks.
* Should be zero-initialized to trigger default behavior.
*
* `cgltf_data` is the struct allocated and filled by `cgltf_parse()`.
@ -42,8 +42,8 @@
*
* `cgltf_result cgltf_load_buffer_base64(const cgltf_options* options,
* cgltf_size size, const char* base64, void** out_data)` decodes
* base64-encoded data content. Used internally by `cgltf_load_buffers()`
* and may be useful if you're not dealing with normal files.
* base64-encoded data content. Used internally by `cgltf_load_buffers()`.
* This is useful when decoding data URIs in images.
*
* `cgltf_result cgltf_parse_file(const cgltf_options* options, const
* char* path, cgltf_data** out_data)` can be used to open the given
@ -246,6 +246,7 @@ typedef struct cgltf_extension {
typedef struct cgltf_buffer
{
char* name;
cgltf_size size;
char* uri;
void* data; /* loaded by cgltf_load_buffers */
@ -281,6 +282,7 @@ typedef struct cgltf_meshopt_compression
typedef struct cgltf_buffer_view
{
char *name;
cgltf_buffer* buffer;
cgltf_size offset;
cgltf_size size;
@ -315,6 +317,7 @@ typedef struct cgltf_accessor_sparse
typedef struct cgltf_accessor
{
char* name;
cgltf_component_type component_type;
cgltf_bool normalized;
cgltf_type type;
@ -354,6 +357,7 @@ typedef struct cgltf_image
typedef struct cgltf_sampler
{
char* name;
cgltf_int mag_filter;
cgltf_int min_filter;
cgltf_int wrap_s;
@ -439,10 +443,19 @@ typedef struct cgltf_ior
typedef struct cgltf_specular
{
cgltf_texture_view specular_texture;
cgltf_texture_view specular_color_texture;
cgltf_float specular_color_factor[3];
cgltf_float specular_factor;
} cgltf_specular;
typedef struct cgltf_volume
{
cgltf_texture_view thickness_texture;
cgltf_float thickness_factor;
cgltf_float attenuation_color[3];
cgltf_float attenuation_distance;
} cgltf_volume;
typedef struct cgltf_sheen
{
cgltf_texture_view sheen_color_texture;
@ -458,6 +471,7 @@ typedef struct cgltf_material
cgltf_bool has_pbr_specular_glossiness;
cgltf_bool has_clearcoat;
cgltf_bool has_transmission;
cgltf_bool has_volume;
cgltf_bool has_ior;
cgltf_bool has_specular;
cgltf_bool has_sheen;
@ -468,6 +482,7 @@ typedef struct cgltf_material
cgltf_specular specular;
cgltf_sheen sheen;
cgltf_transmission transmission;
cgltf_volume volume;
cgltf_texture_view normal_texture;
cgltf_texture_view occlusion_texture;
cgltf_texture_view emissive_texture;
@ -481,6 +496,13 @@ typedef struct cgltf_material
cgltf_extension* extensions;
} cgltf_material;
typedef struct cgltf_material_mapping
{
cgltf_size variant;
cgltf_material* material;
cgltf_extras extras;
} cgltf_material_mapping;
typedef struct cgltf_morph_target {
cgltf_attribute* attributes;
cgltf_size attributes_count;
@ -503,6 +525,8 @@ typedef struct cgltf_primitive {
cgltf_extras extras;
cgltf_bool has_draco_mesh_compression;
cgltf_draco_mesh_compression draco_mesh_compression;
cgltf_material_mapping* mappings;
cgltf_size mappings_count;
cgltf_size extensions_count;
cgltf_extension* extensions;
} cgltf_primitive;
@ -534,8 +558,10 @@ typedef struct cgltf_skin {
} cgltf_skin;
typedef struct cgltf_camera_perspective {
cgltf_bool has_aspect_ratio;
cgltf_float aspect_ratio;
cgltf_float yfov;
cgltf_bool has_zfar;
cgltf_float zfar;
cgltf_float znear;
cgltf_extras extras;
@ -633,6 +659,12 @@ typedef struct cgltf_animation {
cgltf_extension* extensions;
} cgltf_animation;
typedef struct cgltf_material_variant
{
char* name;
cgltf_extras extras;
} cgltf_material_variant;
typedef struct cgltf_asset {
char* copyright;
char* generator;
@ -694,6 +726,9 @@ typedef struct cgltf_data
cgltf_animation* animations;
cgltf_size animations_count;
cgltf_material_variant* variants;
cgltf_size variants_count;
cgltf_extras extras;
cgltf_size data_extensions_count;
@ -776,6 +811,7 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras*
#include <string.h> /* For strncpy */
#include <stdio.h> /* For fopen */
#include <limits.h> /* For UINT_MAX etc */
#include <float.h> /* For FLT_MAX */
#if !defined(CGLTF_MALLOC) || !defined(CGLTF_FREE) || !defined(CGLTF_ATOI) || !defined(CGLTF_ATOF)
#include <stdlib.h> /* For malloc, free, atoi, atof */
@ -847,6 +883,9 @@ static const uint32_t GlbMagicBinChunk = 0x004E4942;
#ifndef CGLTF_ATOF
#define CGLTF_ATOF(str) atof(str)
#endif
#ifndef CGLTF_VALIDATE_ENABLE_ASSERTS
#define CGLTF_VALIDATE_ENABLE_ASSERTS 0
#endif
static void* cgltf_default_alloc(void* user, cgltf_size size)
{
@ -1344,6 +1383,12 @@ static cgltf_size cgltf_calc_index_bound(cgltf_buffer_view* buffer_view, cgltf_s
return bound;
}
#if CGLTF_VALIDATE_ENABLE_ASSERTS
#define CGLTF_ASSERT_IF(cond, result) assert(!(cond)); if (cond) return result;
#else
#define CGLTF_ASSERT_IF(cond, result) if (cond) return result;
#endif
cgltf_result cgltf_validate(cgltf_data* data)
{
for (cgltf_size i = 0; i < data->accessors_count; ++i)
@ -1356,10 +1401,7 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
cgltf_size req_size = accessor->offset + accessor->stride * (accessor->count - 1) + element_size;
if (accessor->buffer_view->size < req_size)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(accessor->buffer_view->size < req_size, cgltf_result_data_too_short);
}
if (accessor->is_sparse)
@ -1370,27 +1412,18 @@ cgltf_result cgltf_validate(cgltf_data* data)
cgltf_size indices_req_size = sparse->indices_byte_offset + indices_component_size * sparse->count;
cgltf_size values_req_size = sparse->values_byte_offset + element_size * sparse->count;
if (sparse->indices_buffer_view->size < indices_req_size ||
sparse->values_buffer_view->size < values_req_size)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(sparse->indices_buffer_view->size < indices_req_size ||
sparse->values_buffer_view->size < values_req_size, cgltf_result_data_too_short);
if (sparse->indices_component_type != cgltf_component_type_r_8u &&
sparse->indices_component_type != cgltf_component_type_r_16u &&
sparse->indices_component_type != cgltf_component_type_r_32u)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(sparse->indices_component_type != cgltf_component_type_r_8u &&
sparse->indices_component_type != cgltf_component_type_r_16u &&
sparse->indices_component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);
if (sparse->indices_buffer_view->buffer->data)
{
cgltf_size index_bound = cgltf_calc_index_bound(sparse->indices_buffer_view, sparse->indices_byte_offset, sparse->indices_component_type, sparse->count);
if (index_bound >= accessor->count)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(index_bound >= accessor->count, cgltf_result_data_too_short);
}
}
}
@ -1399,64 +1432,31 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
cgltf_size req_size = data->buffer_views[i].offset + data->buffer_views[i].size;
if (data->buffer_views[i].buffer && data->buffer_views[i].buffer->size < req_size)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(data->buffer_views[i].buffer && data->buffer_views[i].buffer->size < req_size, cgltf_result_data_too_short);
if (data->buffer_views[i].has_meshopt_compression)
{
cgltf_meshopt_compression* mc = &data->buffer_views[i].meshopt_compression;
if (mc->buffer == NULL || mc->buffer->size < mc->offset + mc->size)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(mc->buffer == NULL || mc->buffer->size < mc->offset + mc->size, cgltf_result_data_too_short);
if (data->buffer_views[i].stride && mc->stride != data->buffer_views[i].stride)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->buffer_views[i].stride && mc->stride != data->buffer_views[i].stride, cgltf_result_invalid_gltf);
if (data->buffer_views[i].size != mc->stride * mc->count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->buffer_views[i].size != mc->stride * mc->count, cgltf_result_invalid_gltf);
if (mc->mode == cgltf_meshopt_compression_mode_invalid)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_invalid, cgltf_result_invalid_gltf);
if (mc->mode == cgltf_meshopt_compression_mode_attributes && !(mc->stride % 4 == 0 && mc->stride <= 256))
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_attributes && !(mc->stride % 4 == 0 && mc->stride <= 256), cgltf_result_invalid_gltf);
if (mc->mode == cgltf_meshopt_compression_mode_triangles && mc->count % 3 != 0)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(mc->mode == cgltf_meshopt_compression_mode_triangles && mc->count % 3 != 0, cgltf_result_invalid_gltf);
if ((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->stride != 2 && mc->stride != 4)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->stride != 2 && mc->stride != 4, cgltf_result_invalid_gltf);
if ((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->filter != cgltf_meshopt_compression_filter_none)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->filter != cgltf_meshopt_compression_filter_none, cgltf_result_invalid_gltf);
if (mc->filter == cgltf_meshopt_compression_filter_octahedral && mc->stride != 4 && mc->stride != 8)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_octahedral && mc->stride != 4 && mc->stride != 8, cgltf_result_invalid_gltf);
if (mc->filter == cgltf_meshopt_compression_filter_quaternion && mc->stride != 8)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_quaternion && mc->stride != 8, cgltf_result_invalid_gltf);
}
}
@ -1464,26 +1464,17 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
if (data->meshes[i].weights)
{
if (data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].weights_count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].weights_count, cgltf_result_invalid_gltf);
}
if (data->meshes[i].target_names)
{
if (data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].target_names_count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->meshes[i].primitives_count && data->meshes[i].primitives[0].targets_count != data->meshes[i].target_names_count, cgltf_result_invalid_gltf);
}
for (cgltf_size j = 0; j < data->meshes[i].primitives_count; ++j)
{
if (data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets_count != data->meshes[i].primitives[0].targets_count, cgltf_result_invalid_gltf);
if (data->meshes[i].primitives[j].attributes_count)
{
@ -1491,41 +1482,34 @@ cgltf_result cgltf_validate(cgltf_data* data)
for (cgltf_size k = 0; k < data->meshes[i].primitives[j].attributes_count; ++k)
{
if (data->meshes[i].primitives[j].attributes[k].data->count != first->count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].attributes[k].data->count != first->count, cgltf_result_invalid_gltf);
}
for (cgltf_size k = 0; k < data->meshes[i].primitives[j].targets_count; ++k)
{
for (cgltf_size m = 0; m < data->meshes[i].primitives[j].targets[k].attributes_count; ++m)
{
if (data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].targets[k].attributes[m].data->count != first->count, cgltf_result_invalid_gltf);
}
}
cgltf_accessor* indices = data->meshes[i].primitives[j].indices;
if (indices &&
CGLTF_ASSERT_IF(indices &&
indices->component_type != cgltf_component_type_r_8u &&
indices->component_type != cgltf_component_type_r_16u &&
indices->component_type != cgltf_component_type_r_32u)
{
return cgltf_result_invalid_gltf;
}
indices->component_type != cgltf_component_type_r_32u, cgltf_result_invalid_gltf);
if (indices && indices->buffer_view && indices->buffer_view->buffer->data)
{
cgltf_size index_bound = cgltf_calc_index_bound(indices->buffer_view, indices->offset, indices->component_type, indices->count);
if (index_bound >= first->count)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(index_bound >= first->count, cgltf_result_data_too_short);
}
for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
{
CGLTF_ASSERT_IF(data->meshes[i].primitives[j].mappings[k].variant >= data->variants_count, cgltf_result_invalid_gltf);
}
}
}
@ -1535,10 +1519,7 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
if (data->nodes[i].weights && data->nodes[i].mesh)
{
if (data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF (data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count, cgltf_result_invalid_gltf);
}
}
@ -1549,10 +1530,7 @@ cgltf_result cgltf_validate(cgltf_data* data)
while (p1 && p2)
{
if (p1 == p2)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(p1 == p2, cgltf_result_invalid_gltf);
p1 = p1->parent;
p2 = p2->parent ? p2->parent->parent : NULL;
@ -1563,10 +1541,7 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
for (cgltf_size j = 0; j < data->scenes[i].nodes_count; ++j)
{
if (data->scenes[i].nodes[j]->parent)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(data->scenes[i].nodes[j]->parent, cgltf_result_invalid_gltf);
}
}
@ -1585,20 +1560,14 @@ cgltf_result cgltf_validate(cgltf_data* data)
if (channel->target_path == cgltf_animation_path_type_weights)
{
if (!channel->target_node->mesh || !channel->target_node->mesh->primitives_count)
{
return cgltf_result_invalid_gltf;
}
CGLTF_ASSERT_IF(!channel->target_node->mesh || !channel->target_node->mesh->primitives_count, cgltf_result_invalid_gltf);
components = channel->target_node->mesh->primitives[0].targets_count;
}
cgltf_size values = channel->sampler->interpolation == cgltf_interpolation_type_cubic_spline ? 3 : 1;
if (channel->sampler->input->count * components * values != channel->sampler->output->count)
{
return cgltf_result_data_too_short;
}
CGLTF_ASSERT_IF(channel->sampler->input->count * components * values != channel->sampler->output->count, cgltf_result_data_too_short);
}
}
@ -1661,6 +1630,8 @@ void cgltf_free(cgltf_data* data)
for (cgltf_size i = 0; i < data->accessors_count; ++i)
{
data->memory.free(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);
@ -1673,6 +1644,7 @@ void cgltf_free(cgltf_data* data)
for (cgltf_size i = 0; i < data->buffer_views_count; ++i)
{
data->memory.free(data->memory.user_data, data->buffer_views[i].name);
data->memory.free(data->memory.user_data, data->buffer_views[i].data);
cgltf_free_extensions(data, data->buffer_views[i].extensions, data->buffer_views[i].extensions_count);
@ -1681,6 +1653,8 @@ void cgltf_free(cgltf_data* data)
for (cgltf_size i = 0; i < data->buffers_count; ++i)
{
data->memory.free(data->memory.user_data, data->buffers[i].name);
if (data->buffers[i].data != data->bin)
{
file_release(&data->memory, &data->file, data->buffers[i].data);
@ -1727,6 +1701,8 @@ void cgltf_free(cgltf_data* data)
data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].draco_mesh_compression.attributes);
}
data->memory.free(data->memory.user_data, data->meshes[i].primitives[j].mappings);
cgltf_free_extensions(data, data->meshes[i].primitives[j].extensions, data->meshes[i].primitives[j].extensions_count);
}
@ -1768,11 +1744,16 @@ void cgltf_free(cgltf_data* data)
if(data->materials[i].has_specular)
{
cgltf_free_extensions(data, data->materials[i].specular.specular_texture.extensions, data->materials[i].specular.specular_texture.extensions_count);
cgltf_free_extensions(data, data->materials[i].specular.specular_color_texture.extensions, data->materials[i].specular.specular_color_texture.extensions_count);
}
if(data->materials[i].has_transmission)
{
cgltf_free_extensions(data, data->materials[i].transmission.transmission_texture.extensions, data->materials[i].transmission.transmission_texture.extensions_count);
}
if (data->materials[i].has_volume)
{
cgltf_free_extensions(data, data->materials[i].volume.thickness_texture.extensions, data->materials[i].volume.thickness_texture.extensions_count);
}
if(data->materials[i].has_sheen)
{
cgltf_free_extensions(data, data->materials[i].sheen.sheen_color_texture.extensions, data->materials[i].sheen.sheen_color_texture.extensions_count);
@ -1809,6 +1790,7 @@ void cgltf_free(cgltf_data* data)
for (cgltf_size i = 0; i < data->samplers_count; ++i)
{
data->memory.free(data->memory.user_data, data->samplers[i].name);
cgltf_free_extensions(data, data->samplers[i].extensions, data->samplers[i].extensions_count);
}
@ -1879,6 +1861,13 @@ void cgltf_free(cgltf_data* data)
data->memory.free(data->memory.user_data, data->animations);
for (cgltf_size i = 0; i < data->variants_count; ++i)
{
data->memory.free(data->memory.user_data, data->variants[i].name);
}
data->memory.free(data->memory.user_data, data->variants);
cgltf_free_extensions(data, data->data_extensions, data->data_extensions_count);
for (cgltf_size i = 0; i < data->extensions_used_count; ++i)
@ -2608,6 +2597,136 @@ 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;
}
if (i < 0)
{
return i;
}
}
return i;
}
static int cgltf_parse_json_material_mapping_data(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_material_mapping* out_mappings, cgltf_size* offset)
{
(void)options;
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
int size = tokens[i].size;
++i;
for (int j = 0; j < size; ++j)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
int obj_size = tokens[i].size;
++i;
int material = -1;
int variants_tok = -1;
cgltf_extras extras = {0, 0};
for (int k = 0; k < obj_size; ++k)
{
CGLTF_CHECK_KEY(tokens[i]);
if (cgltf_json_strcmp(tokens + i, json_chunk, "material") == 0)
{
++i;
material = cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "variants") == 0)
{
variants_tok = i+1;
CGLTF_CHECK_TOKTYPE(tokens[variants_tok], JSMN_ARRAY);
i = cgltf_skip_json(tokens, i+1);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
{
i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &extras);
}
else
{
i = cgltf_skip_json(tokens, i+1);
}
if (i < 0)
{
return i;
}
}
if (material < 0 || variants_tok < 0)
{
return CGLTF_ERROR_JSON;
}
if (out_mappings)
{
for (int k = 0; k < tokens[variants_tok].size; ++k)
{
int variant = cgltf_json_to_int(&tokens[variants_tok + 1 + k], json_chunk);
if (variant < 0)
return variant;
out_mappings[*offset].material = CGLTF_PTRINDEX(cgltf_material, material);
out_mappings[*offset].variant = variant;
out_mappings[*offset].extras = extras;
(*offset)++;
}
}
else
{
(*offset) += tokens[variants_tok].size;
}
}
return i;
}
static int cgltf_parse_json_material_mappings(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_primitive* out_prim)
{
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, "mappings") == 0)
{
if (out_prim->mappings)
{
return CGLTF_ERROR_JSON;
}
cgltf_size mappings_offset = 0;
int k = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, NULL, &mappings_offset);
if (k < 0)
{
return k;
}
out_prim->mappings_count = mappings_offset;
out_prim->mappings = (cgltf_material_mapping*)cgltf_calloc(options, sizeof(cgltf_material_mapping), out_prim->mappings_count);
mappings_offset = 0;
i = cgltf_parse_json_material_mapping_data(options, tokens, i + 1, json_chunk, out_prim->mappings, &mappings_offset);
}
else
{
i = cgltf_skip_json(tokens, i+1);
}
if (i < 0)
{
return i;
}
}
return i;
@ -2700,6 +2819,10 @@ static int cgltf_parse_json_primitive(cgltf_options* options, jsmntok_t const* t
out_prim->has_draco_mesh_compression = 1;
i = cgltf_parse_json_draco_mesh_compression(options, tokens, i + 1, json_chunk, &out_prim->draco_mesh_compression);
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_variants") == 0)
{
i = cgltf_parse_json_material_mappings(options, tokens, i + 1, json_chunk, out_prim);
}
else
{
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_prim->extensions[out_prim->extensions_count++]));
@ -2783,7 +2906,7 @@ static int cgltf_parse_json_mesh(cgltf_options* options, jsmntok_t const* tokens
{
CGLTF_CHECK_KEY(tokens[i]);
if (cgltf_json_strcmp(tokens+i, json_chunk, "targetNames") == 0)
if (cgltf_json_strcmp(tokens+i, json_chunk, "targetNames") == 0 && tokens[i+1].type == JSMN_ARRAY)
{
i = cgltf_parse_json_string_array(options, tokens, i + 1, json_chunk, &out_mesh->target_names, &out_mesh->target_names_count);
}
@ -3005,7 +3128,11 @@ static int cgltf_parse_json_accessor(cgltf_options* options, jsmntok_t const* to
{
CGLTF_CHECK_KEY(tokens[i]);
if (cgltf_json_strcmp(tokens+i, json_chunk, "bufferView") == 0)
if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
{
i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_accessor->name);
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "bufferView") == 0)
{
++i;
out_accessor->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
@ -3467,6 +3594,10 @@ static int cgltf_parse_json_specular(cgltf_options* options, jsmntok_t const* to
{
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->specular_texture);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "specularColorTexture") == 0)
{
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->specular_color_texture);
}
else
{
i = cgltf_skip_json(tokens, i+1);
@ -3515,6 +3646,50 @@ static int cgltf_parse_json_transmission(cgltf_options* options, jsmntok_t const
return i;
}
static int cgltf_parse_json_volume(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_volume* out_volume)
{
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, "thicknessFactor") == 0)
{
++i;
out_volume->thickness_factor = cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "thicknessTexture") == 0)
{
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_volume->thickness_texture);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "attenuationColor") == 0)
{
i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_volume->attenuation_color, 3);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "attenuationDistance") == 0)
{
++i;
out_volume->attenuation_distance = cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
else
{
i = cgltf_skip_json(tokens, i + 1);
}
if (i < 0)
{
return i;
}
}
return i;
}
static int cgltf_parse_json_sheen(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_sheen* out_sheen)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
@ -3623,7 +3798,11 @@ static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tok
{
CGLTF_CHECK_KEY(tokens[i]);
if (cgltf_json_strcmp(tokens + i, json_chunk, "magFilter") == 0)
if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
{
i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_sampler->name);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "magFilter") == 0)
{
++i;
out_sampler->mag_filter
@ -3734,6 +3913,9 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to
cgltf_fill_float_array(out_material->pbr_specular_glossiness.specular_factor, 3, 1.0f);
out_material->pbr_specular_glossiness.glossiness_factor = 1.0f;
cgltf_fill_float_array(out_material->volume.attenuation_color, 3, 1.0f);
out_material->volume.attenuation_distance = FLT_MAX;
out_material->alpha_cutoff = 0.5f;
int size = tokens[i].size;
@ -3859,6 +4041,11 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to
out_material->has_transmission = 1;
i = cgltf_parse_json_transmission(options, tokens, i + 1, json_chunk, &out_material->transmission);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_volume") == 0)
{
out_material->has_volume = 1;
i = cgltf_parse_json_volume(options, tokens, i + 1, json_chunk, &out_material->volume);
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_sheen") == 0)
{
out_material->has_sheen = 1;
@ -4089,7 +4276,11 @@ static int cgltf_parse_json_buffer_view(cgltf_options* options, jsmntok_t const*
{
CGLTF_CHECK_KEY(tokens[i]);
if (cgltf_json_strcmp(tokens+i, json_chunk, "buffer") == 0)
if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
{
i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer_view->name);
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "buffer") == 0)
{
++i;
out_buffer_view->buffer = CGLTF_PTRINDEX(cgltf_buffer, cgltf_json_to_int(tokens + i, json_chunk));
@ -4223,7 +4414,11 @@ static int cgltf_parse_json_buffer(cgltf_options* options, jsmntok_t const* toke
{
CGLTF_CHECK_KEY(tokens[i]);
if (cgltf_json_strcmp(tokens+i, json_chunk, "byteLength") == 0)
if (cgltf_json_strcmp(tokens + i, json_chunk, "name") == 0)
{
i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_buffer->name);
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteLength") == 0)
{
++i;
out_buffer->size =
@ -4405,6 +4600,7 @@ static int cgltf_parse_json_camera(cgltf_options* options, jsmntok_t const* toke
if (cgltf_json_strcmp(tokens+i, json_chunk, "aspectRatio") == 0)
{
++i;
out_camera->data.perspective.has_aspect_ratio = 1;
out_camera->data.perspective.aspect_ratio = cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
@ -4417,6 +4613,7 @@ static int cgltf_parse_json_camera(cgltf_options* options, jsmntok_t const* toke
else if (cgltf_json_strcmp(tokens+i, json_chunk, "zfar") == 0)
{
++i;
out_camera->data.perspective.has_zfar = 1;
out_camera->data.perspective.zfar = cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
@ -5160,6 +5357,58 @@ static int cgltf_parse_json_animations(cgltf_options* options, jsmntok_t const*
return i;
}
static int cgltf_parse_json_variant(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_material_variant* out_variant)
{
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, "name") == 0)
{
i = cgltf_parse_json_string(options, tokens, i + 1, json_chunk, &out_variant->name);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
{
i = cgltf_parse_json_extras(tokens, i + 1, json_chunk, &out_variant->extras);
}
else
{
i = cgltf_skip_json(tokens, i+1);
}
if (i < 0)
{
return i;
}
}
return i;
}
static int cgltf_parse_json_variants(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_data* out_data)
{
i = cgltf_parse_json_array(options, tokens, i, json_chunk, sizeof(cgltf_material_variant), (void**)&out_data->variants, &out_data->variants_count);
if (i < 0)
{
return i;
}
for (cgltf_size j = 0; j < out_data->variants_count; ++j)
{
i = cgltf_parse_json_variant(options, tokens, i, json_chunk, &out_data->variants[j]);
if (i < 0)
{
return i;
}
}
return i;
}
static int cgltf_parse_json_asset(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_asset* out_asset)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
@ -5400,6 +5649,34 @@ static int cgltf_parse_json_root(cgltf_options* options, jsmntok_t const* tokens
}
}
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_variants") == 0)
{
++i;
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
int data_size = tokens[i].size;
++i;
for (int m = 0; m < data_size; ++m)
{
CGLTF_CHECK_KEY(tokens[i]);
if (cgltf_json_strcmp(tokens + i, json_chunk, "variants") == 0)
{
i = cgltf_parse_json_variants(options, tokens, i + 1, json_chunk, out_data);
}
else
{
i = cgltf_skip_json(tokens, i + 1);
}
if (i < 0)
{
return i;
}
}
}
else
{
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_data->data_extensions[out_data->data_extensions_count++]));
@ -5542,6 +5819,11 @@ static int cgltf_fixup_pointers(cgltf_data* data)
CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].draco_mesh_compression.attributes[m].data, data->accessors, data->accessors_count);
}
}
for (cgltf_size k = 0; k < data->meshes[i].primitives[j].mappings_count; ++k)
{
CGLTF_PTRFIXUP_REQ(data->meshes[i].primitives[j].mappings[k].material, data->materials, data->materials_count);
}
}
}
@ -5594,9 +5876,12 @@ static int cgltf_fixup_pointers(cgltf_data* data)
CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_normal_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].specular.specular_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].specular.specular_color_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].transmission.transmission_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].volume.thickness_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].sheen.sheen_color_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].sheen.sheen_roughness_texture.texture, data->textures, data->textures_count);
}

124
src/external/dr_flac.h vendored
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.22 - 2020-11-01
dr_flac - v0.12.29 - 2021-04-02
David Reid - mackron@gmail.com
@ -166,7 +166,7 @@ If you just want to quickly decode an entire FLAC file in one go you can do some
...
drflac_free(pSampleData);
drflac_free(pSampleData, NULL);
```
You can read samples as signed 16-bit integer and 32-bit floating-point PCM with the *_s16() and *_f32() family of APIs respectively, but note that these
@ -232,7 +232,7 @@ extern "C" {
#define DRFLAC_VERSION_MAJOR 0
#define DRFLAC_VERSION_MINOR 12
#define DRFLAC_VERSION_REVISION 22
#define DRFLAC_VERSION_REVISION 29
#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. */
@ -408,7 +408,10 @@ typedef struct
typedef struct
{
/* The metadata type. Use this to know how to interpret the data below. */
/*
The metadata type. Use this to know how to interpret the data below. Will be set to one of the
DRFLAC_METADATA_BLOCK_TYPE_* tokens.
*/
drflac_uint32 type;
/*
@ -552,7 +555,8 @@ pMetadata (in)
Remarks
-------
Use pMetadata->type to determine which metadata block is being handled and how to read the data.
Use pMetadata->type to determine which metadata block is being handled and how to read the data. This
will be set to one of the DRFLAC_METADATA_BLOCK_TYPE_* tokens.
*/
typedef void (* drflac_meta_proc)(void* pUserData, drflac_metadata* pMetadata);
@ -797,6 +801,8 @@ from a block of memory respectively.
The STREAMINFO block must be present for this to succeed. Use `drflac_open_relaxed()` to open a FLAC stream where the header may not be present.
Use `drflac_open_with_metadata()` if you need access to metadata.
Seek Also
---------
@ -843,6 +849,8 @@ as that is for internal use only.
Opening in relaxed mode will continue reading data from onRead until it finds a valid frame. If a frame is never found it will continue forever. To abort,
force your `onRead` callback to return 0, which dr_flac will use as an indicator that the end of the stream was found.
Use `drflac_open_with_metadata_relaxed()` if you need access to metadata.
*/
DRFLAC_API drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks);
@ -882,7 +890,9 @@ Close the decoder with `drflac_close()`.
This is slower than `drflac_open()`, so avoid this one if you don't need metadata. Internally, this will allocate and free memory on the heap for every
metadata block except for STREAMINFO and PADDING blocks.
The caller is notified of the metadata via the `onMeta` callback. All metadata blocks will be handled before the function returns.
The caller is notified of the metadata via the `onMeta` callback. All metadata blocks will be handled before the function returns. This callback takes a
pointer to a `drflac_metadata` object which is a union containing the data of all relevant metadata blocks. Use the `type` member to discriminate against
the different metadata types.
The STREAMINFO block must be present for this to succeed. Use `drflac_open_with_metadata_relaxed()` to open a FLAC stream where the header may not be present.
@ -1330,6 +1340,9 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
#endif
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE
#endif
#ifndef __USE_BSD
#define __USE_BSD
#endif
@ -1354,6 +1367,8 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
#else
#define DRFLAC_INLINE inline __attribute__((always_inline))
#endif
#elif defined(__WATCOMC__)
#define DRFLAC_INLINE __inline
#else
#define DRFLAC_INLINE
#endif
@ -1363,7 +1378,7 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
#define DRFLAC_X64
#elif defined(__i386) || defined(_M_IX86)
#define DRFLAC_X86
#elif defined(__arm__) || defined(_M_ARM)
#elif defined(__arm__) || defined(_M_ARM) || defined(_M_ARM64)
#define DRFLAC_ARM
#endif
@ -1562,6 +1577,27 @@ static DRFLAC_INLINE drflac_bool32 drflac_has_sse41(void)
#if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
#define DRFLAC_HAS_BYTESWAP16_INTRINSIC
#endif
#elif defined(__WATCOMC__) && defined(__386__)
#define DRFLAC_HAS_BYTESWAP16_INTRINSIC
#define DRFLAC_HAS_BYTESWAP32_INTRINSIC
#define DRFLAC_HAS_BYTESWAP64_INTRINSIC
extern __inline drflac_uint16 _watcom_bswap16(drflac_uint16);
extern __inline drflac_uint32 _watcom_bswap32(drflac_uint32);
extern __inline drflac_uint64 _watcom_bswap64(drflac_uint64);
#pragma aux _watcom_bswap16 = \
"xchg al, ah" \
parm [ax] \
modify [ax];
#pragma aux _watcom_bswap32 = \
"bswap eax" \
parm [eax] \
modify [eax];
#pragma aux _watcom_bswap64 = \
"bswap eax" \
"bswap edx" \
"xchg eax,edx" \
parm [eax edx] \
modify [eax edx];
#endif
@ -1785,6 +1821,8 @@ static DRFLAC_INLINE drflac_uint16 drflac__swap_endian_uint16(drflac_uint16 n)
return _byteswap_ushort(n);
#elif defined(__GNUC__) || defined(__clang__)
return __builtin_bswap16(n);
#elif defined(__WATCOMC__) && defined(__386__)
return _watcom_bswap16(n);
#else
#error "This compiler does not support the byte swap intrinsic."
#endif
@ -1814,6 +1852,8 @@ static DRFLAC_INLINE drflac_uint32 drflac__swap_endian_uint32(drflac_uint32 n)
#else
return __builtin_bswap32(n);
#endif
#elif defined(__WATCOMC__) && defined(__386__)
return _watcom_bswap32(n);
#else
#error "This compiler does not support the byte swap intrinsic."
#endif
@ -1832,6 +1872,8 @@ static DRFLAC_INLINE drflac_uint64 drflac__swap_endian_uint64(drflac_uint64 n)
return _byteswap_uint64(n);
#elif defined(__GNUC__) || defined(__clang__)
return __builtin_bswap64(n);
#elif defined(__WATCOMC__) && defined(__386__)
return _watcom_bswap64(n);
#else
#error "This compiler does not support the byte swap intrinsic."
#endif
@ -2639,6 +2681,9 @@ static drflac_bool32 drflac__find_and_seek_to_next_sync_code(drflac_bs* bs)
#if defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(__clang__)
#define DRFLAC_IMPLEMENT_CLZ_MSVC
#endif
#if defined(__WATCOMC__) && defined(__386__)
#define DRFLAC_IMPLEMENT_CLZ_WATCOM
#endif
static DRFLAC_INLINE drflac_uint32 drflac__clz_software(drflac_cache_t x)
{
@ -2786,6 +2831,16 @@ static DRFLAC_INLINE drflac_uint32 drflac__clz_msvc(drflac_cache_t x)
}
#endif
#ifdef DRFLAC_IMPLEMENT_CLZ_WATCOM
static __inline drflac_uint32 drflac__clz_watcom (drflac_uint32);
#pragma aux drflac__clz_watcom = \
"bsr eax, eax" \
"xor eax, 31" \
parm [eax] nomemory \
value [eax] \
modify exact [eax] nomemory;
#endif
static DRFLAC_INLINE drflac_uint32 drflac__clz(drflac_cache_t x)
{
#ifdef DRFLAC_IMPLEMENT_CLZ_LZCNT
@ -2796,6 +2851,8 @@ static DRFLAC_INLINE drflac_uint32 drflac__clz(drflac_cache_t x)
{
#ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
return drflac__clz_msvc(x);
#elif defined(DRFLAC_IMPLEMENT_CLZ_WATCOM)
return (x == 0) ? sizeof(x)*8 : drflac__clz_watcom(x);
#else
return drflac__clz_software(x);
#endif
@ -3179,7 +3236,6 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__reference(drfla
drflac_uint32 i;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
DRFLAC_ASSERT(pSamplesOut != NULL);
for (i = 0; i < count; ++i) {
@ -3561,7 +3617,6 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__scalar_zeroorde
drflac_uint32 i;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
DRFLAC_ASSERT(pSamplesOut != NULL);
(void)bitsPerSample;
@ -3607,7 +3662,6 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__scalar(drflac_b
drflac_uint32 i;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
DRFLAC_ASSERT(pSamplesOut != NULL);
if (order == 0) {
@ -4161,7 +4215,6 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41_64(drflac
static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
{
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
DRFLAC_ASSERT(pSamplesOut != NULL);
/* In my testing the order is rarely > 12, so in this case I'm going to simplify the SSE implementation by only handling order <= 12. */
@ -4660,7 +4713,6 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__neon_64(drflac_
static drflac_bool32 drflac__decode_samples_with_residual__rice__neon(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
{
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
DRFLAC_ASSERT(pSamplesOut != NULL);
/* In my testing the order is rarely > 12, so in this case I'm going to simplify the NEON implementation by only handling order <= 12. */
@ -4703,7 +4755,6 @@ static drflac_bool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, drflac_
drflac_uint32 i;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
for (i = 0; i < count; ++i) {
if (!drflac__seek_rice_parts(bs, riceParam)) {
@ -4719,7 +4770,6 @@ static drflac_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs*
drflac_uint32 i;
DRFLAC_ASSERT(bs != NULL);
DRFLAC_ASSERT(count > 0);
DRFLAC_ASSERT(unencodedBitsPerSample <= 31); /* <-- unencodedBitsPerSample is a 5 bit number, so cannot exceed 31. */
DRFLAC_ASSERT(pSamplesOut != NULL);
@ -4783,7 +4833,7 @@ static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_
}
/* Validation check. */
if ((blockSize / (1 << partitionOrder)) <= order) {
if ((blockSize / (1 << partitionOrder)) < order) {
return DRFLAC_FALSE;
}
@ -5155,7 +5205,8 @@ static drflac_bool32 drflac__read_next_flac_frame_header(drflac_bs* bs, drflac_u
DRFLAC_ASSERT(blockSize > 0);
if (blockSize == 1) {
header->blockSizeInPCMFrames = 192;
} else if (blockSize >= 2 && blockSize <= 5) {
} else if (blockSize <= 5) {
DRFLAC_ASSERT(blockSize >= 2);
header->blockSizeInPCMFrames = 576 * (1 << (blockSize - 2));
} else if (blockSize == 6) {
if (!drflac__read_uint16(bs, 8, &header->blockSizeInPCMFrames)) {
@ -8309,7 +8360,7 @@ static drflac_result drflac_result_from_errno(int e)
static drflac_result drflac_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
{
#if _MSC_VER && _MSC_VER >= 1400
#if defined(_MSC_VER) && _MSC_VER >= 1400
errno_t err;
#endif
@ -8321,7 +8372,7 @@ static drflac_result drflac_fopen(FILE** ppFile, const char* pFilePath, const ch
return DRFLAC_INVALID_ARGS;
}
#if _MSC_VER && _MSC_VER >= 1400
#if defined(_MSC_VER) && _MSC_VER >= 1400
err = fopen_s(ppFile, pFilePath, pOpenMode);
if (err != 0) {
return drflac_result_from_errno(err);
@ -8356,12 +8407,13 @@ _wfopen() isn't always available in all compilation environments.
* MSVC seems to support it universally as far back as VC6 from what I can tell (haven't checked further back).
* MinGW-64 (both 32- and 64-bit) seems to support it.
* MinGW wraps it in !defined(__STRICT_ANSI__).
* OpenWatcom wraps it in !defined(_NO_EXT_KEYS).
This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs()
fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support.
*/
#if defined(_WIN32)
#if defined(_MSC_VER) || defined(__MINGW64__) || !defined(__STRICT_ANSI__)
#if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
#define DRFLAC_HAS_WFOPEN
#endif
#endif
@ -11331,6 +11383,7 @@ DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 p
return drflac__seek_to_first_frame(pFlac);
} else {
drflac_bool32 wasSuccessful = DRFLAC_FALSE;
drflac_uint64 originalPCMFrame = pFlac->currentPCMFrame;
/* Clamp the sample to the end. */
if (pcmFrameIndex > pFlac->totalPCMFrameCount) {
@ -11388,7 +11441,16 @@ DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 p
}
}
pFlac->currentPCMFrame = pcmFrameIndex;
if (wasSuccessful) {
pFlac->currentPCMFrame = pcmFrameIndex;
} else {
/* Seek failed. Try putting the decoder back to it's original state. */
if (drflac_seek_to_pcm_frame(pFlac, originalPCMFrame) == DRFLAC_FALSE) {
/* Failed to seek back to the original PCM frame. Fall back to 0. */
drflac_seek_to_pcm_frame(pFlac, 0);
}
}
return wasSuccessful;
}
}
@ -11789,6 +11851,28 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
/*
REVISION HISTORY
================
v0.12.29 - 2021-04-02
- Fix a bug where the running PCM frame index is set to an invalid value when over-seeking.
- Fix a decoding error due to an incorrect validation check.
v0.12.28 - 2021-02-21
- Fix a warning due to referencing _MSC_VER when it is undefined.
v0.12.27 - 2021-01-31
- Fix a static analysis warning.
v0.12.26 - 2021-01-17
- Fix a compilation warning due to _BSD_SOURCE being deprecated.
v0.12.25 - 2020-12-26
- Update documentation.
v0.12.24 - 2020-11-29
- Fix ARM64/NEON detection when compiling with MSVC.
v0.12.23 - 2020-11-21
- Fix compilation with OpenWatcom.
v0.12.22 - 2020-11-01
- Fix an error with the previous release.

83
src/external/dr_mp3.h vendored
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.19 - 2020-11-13
dr_mp3 - v0.6.27 - 2021-02-21
David Reid - mackron@gmail.com
@ -95,7 +95,7 @@ extern "C" {
#define DRMP3_VERSION_MAJOR 0
#define DRMP3_VERSION_MINOR 6
#define DRMP3_VERSION_REVISION 19
#define DRMP3_VERSION_REVISION 27
#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. */
@ -239,6 +239,8 @@ typedef drmp3_int32 drmp3_result;
#else
#define DRMP3_INLINE inline __attribute__((always_inline))
#endif
#elif defined(__WATCOMC__)
#define DRMP3_INLINE __inline
#else
#define DRMP3_INLINE
#endif
@ -279,14 +281,6 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num
Main API (Pull API)
===================
*/
#ifndef DRMP3_DEFAULT_CHANNELS
#define DRMP3_DEFAULT_CHANNELS 2
#endif
#ifndef DRMP3_DEFAULT_SAMPLE_RATE
#define DRMP3_DEFAULT_SAMPLE_RATE 44100
#endif
typedef enum
{
drmp3_seek_origin_start,
@ -596,7 +590,7 @@ DRMP3_API const char* drmp3_version_string(void)
#if !defined(DR_MP3_NO_SIMD)
#if !defined(DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(_M_ARM64) || defined(__x86_64__) || defined(__aarch64__))
#if !defined(DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64))
/* x64 always have SSE2, arm64 always have neon, no need for generic code */
#define DR_MP3_ONLY_SIMD
#endif
@ -672,7 +666,7 @@ end:
return g_have_simd - 1;
#endif
}
#elif defined(__ARM_NEON) || defined(__aarch64__)
#elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64)
#include <arm_neon.h>
#define DRMP3_HAVE_SSE 0
#define DRMP3_HAVE_SIMD 1
@ -705,7 +699,7 @@ static int drmp3_have_simd(void)
#endif
#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__)
#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64)
#define DRMP3_HAVE_ARMV6 1
static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(int32_t a)
{
@ -1868,7 +1862,7 @@ static void drmp3d_DCT_II(float *grbuf, int n)
} else
#endif
#ifdef DR_MP3_ONLY_SIMD
{}
{} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
#else
for (; k < n; k++)
{
@ -2101,7 +2095,7 @@ static void drmp3d_synth(float *xl, drmp3d_sample_t *dstl, int nch, float *lins)
} else
#endif
#ifdef DR_MP3_ONLY_SIMD
{}
{} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
#else
for (i = 14; i >= 0; i--)
{
@ -2829,7 +2823,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm
/* Decode the first frame to confirm that it is indeed a valid MP3 stream. */
if (!drmp3_decode_next_frame(pMP3)) {
drmp3_uninit(pMP3);
drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks); /* The call above may have allocated memory. Need to make sure it's freed before aborting. */
return DRMP3_FALSE; /* Not a valid MP3 stream. */
}
@ -3331,7 +3325,7 @@ static drmp3_result drmp3_result_from_errno(int e)
static drmp3_result drmp3_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
{
#if _MSC_VER && _MSC_VER >= 1400
#if defined(_MSC_VER) && _MSC_VER >= 1400
errno_t err;
#endif
@ -3343,7 +3337,7 @@ static drmp3_result drmp3_fopen(FILE** ppFile, const char* pFilePath, const char
return DRMP3_INVALID_ARGS;
}
#if _MSC_VER && _MSC_VER >= 1400
#if defined(_MSC_VER) && _MSC_VER >= 1400
err = fopen_s(ppFile, pFilePath, pOpenMode);
if (err != 0) {
return drmp3_result_from_errno(err);
@ -3378,12 +3372,13 @@ _wfopen() isn't always available in all compilation environments.
* MSVC seems to support it universally as far back as VC6 from what I can tell (haven't checked further back).
* MinGW-64 (both 32- and 64-bit) seems to support it.
* MinGW wraps it in !defined(__STRICT_ANSI__).
* OpenWatcom wraps it in !defined(_NO_EXT_KEYS).
This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs()
fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support.
*/
#if defined(_WIN32)
#if defined(_MSC_VER) || defined(__MINGW64__) || !defined(__STRICT_ANSI__)
#if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
#define DRMP3_HAS_WFOPEN
#endif
#endif
@ -3484,22 +3479,38 @@ static drmp3_bool32 drmp3__on_seek_stdio(void* pUserData, int offset, drmp3_seek
DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
drmp3_bool32 result;
FILE* pFile;
if (drmp3_fopen(&pFile, pFilePath, "rb") != DRMP3_SUCCESS) {
return DRMP3_FALSE;
}
return drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
if (result != DRMP3_TRUE) {
fclose(pFile);
return result;
}
return DRMP3_TRUE;
}
DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
{
drmp3_bool32 result;
FILE* pFile;
if (drmp3_wfopen(&pFile, pFilePath, L"rb", pAllocationCallbacks) != DRMP3_SUCCESS) {
return DRMP3_FALSE;
}
return drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
if (result != DRMP3_TRUE) {
fclose(pFile);
return result;
}
return DRMP3_TRUE;
}
#endif
@ -3511,7 +3522,11 @@ DRMP3_API void drmp3_uninit(drmp3* pMP3)
#ifndef DR_MP3_NO_STDIO
if (pMP3->onRead == drmp3__on_read_stdio) {
fclose((FILE*)pMP3->pUserData);
FILE* pFile = (FILE*)pMP3->pUserData;
if (pFile != NULL) {
fclose(pFile);
pMP3->pUserData = NULL; /* Make sure the file handle is cleared to NULL to we don't attempt to close it a second time. */
}
}
#endif
@ -4435,6 +4450,30 @@ counts rather than sample counts.
/*
REVISION HISTORY
================
v0.6.27 - 2021-02-21
- Fix a warning due to referencing _MSC_VER when it is undefined.
v0.6.26 - 2021-01-31
- Bring up to date with minimp3.
v0.6.25 - 2020-12-26
- Remove DRMP3_DEFAULT_CHANNELS and DRMP3_DEFAULT_SAMPLE_RATE which are leftovers from some removed APIs.
v0.6.24 - 2020-12-07
- Fix a typo in version date for 0.6.23.
v0.6.23 - 2020-12-03
- Fix an error where a file can be closed twice when initialization of the decoder fails.
v0.6.22 - 2020-12-02
- Fix an error where it's possible for a file handle to be left open when initialization of the decoder fails.
v0.6.21 - 2020-11-28
- Bring up to date with minimp3.
v0.6.20 - 2020-11-21
- Fix compilation with OpenWatcom.
v0.6.19 - 2020-11-13
- Minor code clean up.

438
src/external/dr_wav.h vendored

File diff suppressed because it is too large Load diff