Skip to content

Commit d697ff7

Browse files
committed
updated dr_mp3.h and dr_flac.h from mainstream.
1 parent 753e9f7 commit d697ff7

File tree

2 files changed

+217
-99
lines changed

2 files changed

+217
-99
lines changed

src/dr_libs/dr_flac.h

Lines changed: 158 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
3-
dr_flac - v0.13.0 - 2025-07-23
3+
dr_flac - v0.13.2 - TBD
44

55
David Reid - [email protected]
66

@@ -126,7 +126,7 @@ extern "C" {
126126

127127
#define DRFLAC_VERSION_MAJOR 0
128128
#define DRFLAC_VERSION_MINOR 13
129-
#define DRFLAC_VERSION_REVISION 0
129+
#define DRFLAC_VERSION_REVISION 2
130130
#define DRFLAC_VERSION_STRING DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION)
131131

132132
#include <stddef.h> /* For size_t. */
@@ -331,16 +331,19 @@ typedef struct
331331
*/
332332
drflac_uint32 type;
333333

334+
/* The size in bytes of the block and the buffer pointed to by pRawData if it's non-NULL. */
335+
drflac_uint32 rawDataSize;
336+
337+
/* The offset in the stream of the raw data. */
338+
drflac_uint64 rawDataOffset;
339+
334340
/*
335341
A pointer to the raw data. This points to a temporary buffer so don't hold on to it. It's best to
336342
not modify the contents of this buffer. Use the structures below for more meaningful and structured
337343
information about the metadata. It's possible for this to be null.
338344
*/
339345
const void* pRawData;
340346

341-
/* The size in bytes of the block and the buffer pointed to by pRawData if it's non-NULL. */
342-
drflac_uint32 rawDataSize;
343-
344347
union
345348
{
346349
drflac_streaminfo streaminfo;
@@ -392,6 +395,7 @@ typedef struct
392395
drflac_uint32 colorDepth;
393396
drflac_uint32 indexColorCount;
394397
drflac_uint32 pictureDataSize;
398+
drflac_uint64 pictureDataOffset; /* Offset from the start of the stream. */
395399
const drflac_uint8* pPictureData;
396400
} picture;
397401
} data;
@@ -6434,8 +6438,9 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
64346438
runningFilePos += 4;
64356439

64366440
metadata.type = blockType;
6437-
metadata.pRawData = NULL;
64386441
metadata.rawDataSize = 0;
6442+
metadata.rawDataOffset = runningFilePos;
6443+
metadata.pRawData = NULL;
64396444

64406445
switch (blockType)
64416446
{
@@ -6712,59 +6717,149 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
67126717
}
67136718

67146719
if (onMeta) {
6715-
void* pRawData;
6716-
const char* pRunningData;
6717-
const char* pRunningDataEnd;
6720+
drflac_bool32 result = DRFLAC_TRUE;
6721+
drflac_uint32 blockSizeRemaining = blockSize;
6722+
char* pMime = NULL;
6723+
char* pDescription = NULL;
6724+
void* pPictureData = NULL;
6725+
6726+
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.type, 4) != 4) {
6727+
result = DRFLAC_FALSE;
6728+
goto done_flac;
6729+
}
6730+
blockSizeRemaining -= 4;
6731+
metadata.data.picture.type = drflac__be2host_32(metadata.data.picture.type);
67186732

6719-
pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6720-
if (pRawData == NULL) {
6721-
return DRFLAC_FALSE;
6733+
6734+
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.mimeLength, 4) != 4) {
6735+
result = DRFLAC_FALSE;
6736+
goto done_flac;
67226737
}
6738+
blockSizeRemaining -= 4;
6739+
metadata.data.picture.mimeLength = drflac__be2host_32(metadata.data.picture.mimeLength);
67236740

6724-
if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6725-
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6726-
return DRFLAC_FALSE;
6741+
pMime = (char*)drflac__malloc_from_callbacks(metadata.data.picture.mimeLength + 1, pAllocationCallbacks); /* +1 for null terminator. */
6742+
if (pMime == NULL) {
6743+
result = DRFLAC_FALSE;
6744+
goto done_flac;
67276745
}
67286746

6729-
metadata.pRawData = pRawData;
6730-
metadata.rawDataSize = blockSize;
6747+
if (blockSizeRemaining < metadata.data.picture.mimeLength || onRead(pUserData, pMime, metadata.data.picture.mimeLength) != metadata.data.picture.mimeLength) {
6748+
result = DRFLAC_FALSE;
6749+
goto done_flac;
6750+
}
6751+
blockSizeRemaining -= metadata.data.picture.mimeLength;
6752+
pMime[metadata.data.picture.mimeLength] = '\0'; /* Null terminate for safety. */
6753+
metadata.data.picture.mime = (const char*)pMime;
67316754

6732-
pRunningData = (const char*)pRawData;
6733-
pRunningDataEnd = (const char*)pRawData + blockSize;
67346755

6735-
metadata.data.picture.type = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6736-
metadata.data.picture.mimeLength = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6756+
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.descriptionLength, 4) != 4) {
6757+
result = DRFLAC_FALSE;
6758+
goto done_flac;
6759+
}
6760+
blockSizeRemaining -= 4;
6761+
metadata.data.picture.descriptionLength = drflac__be2host_32(metadata.data.picture.descriptionLength);
67376762

6738-
/* Need space for the rest of the block */
6739-
if ((pRunningDataEnd - pRunningData) - 24 < (drflac_int64)metadata.data.picture.mimeLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
6740-
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6741-
return DRFLAC_FALSE;
6763+
pDescription = (char*)drflac__malloc_from_callbacks(metadata.data.picture.descriptionLength + 1, pAllocationCallbacks); /* +1 for null terminator. */
6764+
if (pDescription == NULL) {
6765+
result = DRFLAC_FALSE;
6766+
goto done_flac;
67426767
}
6743-
metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength;
6744-
metadata.data.picture.descriptionLength = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
67456768

6746-
/* Need space for the rest of the block */
6747-
if ((pRunningDataEnd - pRunningData) - 20 < (drflac_int64)metadata.data.picture.descriptionLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
6748-
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6749-
return DRFLAC_FALSE;
6769+
if (blockSizeRemaining < metadata.data.picture.descriptionLength || onRead(pUserData, pDescription, metadata.data.picture.descriptionLength) != metadata.data.picture.descriptionLength) {
6770+
result = DRFLAC_FALSE;
6771+
goto done_flac;
67506772
}
6751-
metadata.data.picture.description = pRunningData; pRunningData += metadata.data.picture.descriptionLength;
6752-
metadata.data.picture.width = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6753-
metadata.data.picture.height = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6754-
metadata.data.picture.colorDepth = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6755-
metadata.data.picture.indexColorCount = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6756-
metadata.data.picture.pictureDataSize = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
6757-
metadata.data.picture.pPictureData = (const drflac_uint8*)pRunningData;
6758-
6759-
/* Need space for the picture after the block */
6760-
if (pRunningDataEnd - pRunningData < (drflac_int64)metadata.data.picture.pictureDataSize) { /* <-- Note the order of operations to avoid overflow to a valid value */
6761-
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6762-
return DRFLAC_FALSE;
6773+
blockSizeRemaining -= metadata.data.picture.descriptionLength;
6774+
pDescription[metadata.data.picture.descriptionLength] = '\0'; /* Null terminate for safety. */
6775+
metadata.data.picture.description = (const char*)pDescription;
6776+
6777+
6778+
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.width, 4) != 4) {
6779+
result = DRFLAC_FALSE;
6780+
goto done_flac;
67636781
}
6782+
blockSizeRemaining -= 4;
6783+
metadata.data.picture.width = drflac__be2host_32(metadata.data.picture.width);
67646784

6765-
onMeta(pUserDataMD, &metadata);
6785+
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.height, 4) != 4) {
6786+
result = DRFLAC_FALSE;
6787+
goto done_flac;
6788+
}
6789+
blockSizeRemaining -= 4;
6790+
metadata.data.picture.height = drflac__be2host_32(metadata.data.picture.height);
67666791

6767-
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6792+
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.colorDepth, 4) != 4) {
6793+
result = DRFLAC_FALSE;
6794+
goto done_flac;
6795+
}
6796+
blockSizeRemaining -= 4;
6797+
metadata.data.picture.colorDepth = drflac__be2host_32(metadata.data.picture.colorDepth);
6798+
6799+
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.indexColorCount, 4) != 4) {
6800+
result = DRFLAC_FALSE;
6801+
goto done_flac;
6802+
}
6803+
blockSizeRemaining -= 4;
6804+
metadata.data.picture.indexColorCount = drflac__be2host_32(metadata.data.picture.indexColorCount);
6805+
6806+
6807+
/* Picture data. */
6808+
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.pictureDataSize, 4) != 4) {
6809+
result = DRFLAC_FALSE;
6810+
goto done_flac;
6811+
}
6812+
blockSizeRemaining -= 4;
6813+
metadata.data.picture.pictureDataSize = drflac__be2host_32(metadata.data.picture.pictureDataSize);
6814+
6815+
if (blockSizeRemaining < metadata.data.picture.pictureDataSize) {
6816+
result = DRFLAC_FALSE;
6817+
goto done_flac;
6818+
}
6819+
6820+
/* For the actual image data we want to store the offset to the start of the stream. */
6821+
metadata.data.picture.pictureDataOffset = runningFilePos + (blockSize - blockSizeRemaining);
6822+
6823+
/*
6824+
For the allocation of image data, we can allow memory allocation to fail, in which case we just leave
6825+
the pointer as null. If it fails, we need to fall back to seeking past the image data.
6826+
*/
6827+
#ifndef DR_FLAC_NO_PICTURE_METADATA_MALLOC
6828+
pPictureData = drflac__malloc_from_callbacks(metadata.data.picture.pictureDataSize, pAllocationCallbacks);
6829+
if (pPictureData != NULL) {
6830+
if (onRead(pUserData, pPictureData, metadata.data.picture.pictureDataSize) != metadata.data.picture.pictureDataSize) {
6831+
result = DRFLAC_FALSE;
6832+
goto done_flac;
6833+
}
6834+
} else
6835+
#endif
6836+
{
6837+
/* Allocation failed. We need to seek past the picture data. */
6838+
if (!onSeek(pUserData, metadata.data.picture.pictureDataSize, DRFLAC_SEEK_CUR)) {
6839+
result = DRFLAC_FALSE;
6840+
goto done_flac;
6841+
}
6842+
}
6843+
6844+
blockSizeRemaining -= metadata.data.picture.pictureDataSize;
6845+
metadata.data.picture.pPictureData = (const drflac_uint8*)pPictureData;
6846+
6847+
6848+
/* Only fire the callback if we actually have a way to read the image data. We must have either a valid offset, or a valid data pointer. */
6849+
if (metadata.data.picture.pictureDataOffset != 0 || metadata.data.picture.pPictureData != NULL) {
6850+
onMeta(pUserDataMD, &metadata);
6851+
} else {
6852+
/* Don't have a valid offset or data pointer, so just pretend we don't have a picture metadata. */
6853+
}
6854+
6855+
done_flac:
6856+
drflac__free_from_callbacks(pMime, pAllocationCallbacks);
6857+
drflac__free_from_callbacks(pDescription, pAllocationCallbacks);
6858+
drflac__free_from_callbacks(pPictureData, pAllocationCallbacks);
6859+
6860+
if (result != DRFLAC_TRUE) {
6861+
return DRFLAC_FALSE;
6862+
}
67686863
}
67696864
} break;
67706865

@@ -6800,13 +6895,16 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
68006895
*/
68016896
if (onMeta) {
68026897
void* pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
6803-
if (pRawData == NULL) {
6804-
return DRFLAC_FALSE;
6805-
}
6806-
6807-
if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6808-
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6809-
return DRFLAC_FALSE;
6898+
if (pRawData != NULL) {
6899+
if (onRead(pUserData, pRawData, blockSize) != blockSize) {
6900+
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
6901+
return DRFLAC_FALSE;
6902+
}
6903+
} else {
6904+
/* Allocation failed. We need to seek past the block. */
6905+
if (!onSeek(pUserData, blockSize, DRFLAC_SEEK_CUR)) {
6906+
return DRFLAC_FALSE;
6907+
}
68106908
}
68116909

68126910
metadata.pRawData = pRawData;
@@ -8699,7 +8797,7 @@ static drflac_bool32 drflac__on_tell_stdio(void* pUserData, drflac_int64* pCurso
86998797
DRFLAC_ASSERT(pFileStdio != NULL);
87008798
DRFLAC_ASSERT(pCursor != NULL);
87018799

8702-
#if defined(_WIN32)
8800+
#if defined(_WIN32) && !defined(NXDK)
87038801
#if defined(_MSC_VER) && _MSC_VER > 1200
87048802
result = _ftelli64(pFileStdio);
87058803
#else
@@ -8821,8 +8919,6 @@ static drflac_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_
88218919

88228920
DRFLAC_ASSERT(memoryStream != NULL);
88238921

8824-
newCursor = memoryStream->currentReadPos;
8825-
88268922
if (origin == DRFLAC_SEEK_SET) {
88278923
newCursor = 0;
88288924
} else if (origin == DRFLAC_SEEK_CUR) {
@@ -12077,6 +12173,13 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
1207712173
/*
1207812174
REVISION HISTORY
1207912175
================
12176+
v0.13.2 - TBD
12177+
- Improve robustness of the parsing of picture metadata to improve support for memory constrained embedded devices.
12178+
- Fix a warning about an assigned by unused variable.
12179+
12180+
v0.13.1 - 2025-09-10
12181+
- Fix an error with the NXDK build.
12182+
1208012183
v0.13.0 - 2025-07-23
1208112184
- API CHANGE: Seek origin enums have been renamed to match the naming convention used by other dr_libs libraries:
1208212185
- drflac_seek_origin_start -> DRFLAC_SEEK_SET

0 commit comments

Comments
 (0)