mirror of
https://github.com/raysan5/raylib.git
synced 2026-04-13 02:29:10 -04:00
Update dr_flac.h
This commit is contained in:
306
src/external/dr_flac.h
vendored
306
src/external/dr_flac.h
vendored
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
|
FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
|
||||||
dr_flac - v0.13.0 - TBD
|
dr_flac - v0.13.3 - 2026-01-17
|
||||||
|
|
||||||
David Reid - mackron@gmail.com
|
David Reid - mackron@gmail.com
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define DRFLAC_VERSION_MAJOR 0
|
#define DRFLAC_VERSION_MAJOR 0
|
||||||
#define DRFLAC_VERSION_MINOR 13
|
#define DRFLAC_VERSION_MINOR 13
|
||||||
#define DRFLAC_VERSION_REVISION 0
|
#define DRFLAC_VERSION_REVISION 3
|
||||||
#define DRFLAC_VERSION_STRING DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION)
|
#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. */
|
#include <stddef.h> /* For size_t. */
|
||||||
@ -331,6 +331,12 @@ typedef struct
|
|||||||
*/
|
*/
|
||||||
drflac_uint32 type;
|
drflac_uint32 type;
|
||||||
|
|
||||||
|
/* The size in bytes of the block and the buffer pointed to by pRawData if it's non-NULL. */
|
||||||
|
drflac_uint32 rawDataSize;
|
||||||
|
|
||||||
|
/* The offset in the stream of the raw data. */
|
||||||
|
drflac_uint64 rawDataOffset;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A pointer to the raw data. This points to a temporary buffer so don't hold on to it. It's best to
|
A pointer to the raw data. This points to a temporary buffer so don't hold on to it. It's best to
|
||||||
not modify the contents of this buffer. Use the structures below for more meaningful and structured
|
not modify the contents of this buffer. Use the structures below for more meaningful and structured
|
||||||
@ -338,9 +344,6 @@ typedef struct
|
|||||||
*/
|
*/
|
||||||
const void* pRawData;
|
const void* pRawData;
|
||||||
|
|
||||||
/* The size in bytes of the block and the buffer pointed to by pRawData if it's non-NULL. */
|
|
||||||
drflac_uint32 rawDataSize;
|
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
drflac_streaminfo streaminfo;
|
drflac_streaminfo streaminfo;
|
||||||
@ -392,6 +395,7 @@ typedef struct
|
|||||||
drflac_uint32 colorDepth;
|
drflac_uint32 colorDepth;
|
||||||
drflac_uint32 indexColorCount;
|
drflac_uint32 indexColorCount;
|
||||||
drflac_uint32 pictureDataSize;
|
drflac_uint32 pictureDataSize;
|
||||||
|
drflac_uint64 pictureDataOffset; /* Offset from the start of the stream. */
|
||||||
const drflac_uint8* pPictureData;
|
const drflac_uint8* pPictureData;
|
||||||
} picture;
|
} picture;
|
||||||
} data;
|
} data;
|
||||||
@ -2712,9 +2716,17 @@ static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x)
|
|||||||
#if defined(__GNUC__) || defined(__clang__)
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
#if defined(DRFLAC_X64)
|
#if defined(DRFLAC_X64)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
A note on lzcnt.
|
||||||
|
|
||||||
|
We check for the presence of the lzcnt instruction at runtime before calling this function, but we still generate this code. I have had
|
||||||
|
a report where the assembler does not recognize the lzcnt instruction. To work around this we are going to use `rep; bsr` instead which
|
||||||
|
has an identical byte encoding as lzcnt, and should hopefully improve compatibility with older assemblers.
|
||||||
|
*/
|
||||||
drflac_uint64 r;
|
drflac_uint64 r;
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
"lzcnt{ %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc"
|
"rep; bsr{q %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc"
|
||||||
|
/*"lzcnt{ %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc"*/
|
||||||
);
|
);
|
||||||
|
|
||||||
return (drflac_uint32)r;
|
return (drflac_uint32)r;
|
||||||
@ -2723,12 +2735,13 @@ static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x)
|
|||||||
{
|
{
|
||||||
drflac_uint32 r;
|
drflac_uint32 r;
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
"lzcnt{l %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc"
|
"rep; bsr{l %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc"
|
||||||
|
/*"lzcnt{l %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc"*/
|
||||||
);
|
);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
#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. */
|
#elif defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(__ARM_ARCH_6M__) && !(defined(__thumb__) && !defined(__thumb2__)) && !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;
|
unsigned int r;
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
@ -6434,8 +6447,9 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||||||
runningFilePos += 4;
|
runningFilePos += 4;
|
||||||
|
|
||||||
metadata.type = blockType;
|
metadata.type = blockType;
|
||||||
metadata.pRawData = NULL;
|
|
||||||
metadata.rawDataSize = 0;
|
metadata.rawDataSize = 0;
|
||||||
|
metadata.rawDataOffset = runningFilePos;
|
||||||
|
metadata.pRawData = NULL;
|
||||||
|
|
||||||
switch (blockType)
|
switch (blockType)
|
||||||
{
|
{
|
||||||
@ -6712,59 +6726,151 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (onMeta) {
|
if (onMeta) {
|
||||||
void* pRawData;
|
drflac_bool32 result = DRFLAC_TRUE;
|
||||||
const char* pRunningData;
|
drflac_uint32 blockSizeRemaining = blockSize;
|
||||||
const char* pRunningDataEnd;
|
char* pMime = NULL;
|
||||||
|
char* pDescription = NULL;
|
||||||
|
void* pPictureData = NULL;
|
||||||
|
|
||||||
pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
|
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.type, 4) != 4) {
|
||||||
if (pRawData == NULL) {
|
result = DRFLAC_FALSE;
|
||||||
return DRFLAC_FALSE;
|
goto done_flac;
|
||||||
|
}
|
||||||
|
blockSizeRemaining -= 4;
|
||||||
|
metadata.data.picture.type = drflac__be2host_32(metadata.data.picture.type);
|
||||||
|
|
||||||
|
|
||||||
|
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.mimeLength, 4) != 4) {
|
||||||
|
result = DRFLAC_FALSE;
|
||||||
|
goto done_flac;
|
||||||
|
}
|
||||||
|
blockSizeRemaining -= 4;
|
||||||
|
metadata.data.picture.mimeLength = drflac__be2host_32(metadata.data.picture.mimeLength);
|
||||||
|
|
||||||
|
pMime = (char*)drflac__malloc_from_callbacks(metadata.data.picture.mimeLength + 1, pAllocationCallbacks); /* +1 for null terminator. */
|
||||||
|
if (pMime == NULL) {
|
||||||
|
result = DRFLAC_FALSE;
|
||||||
|
goto done_flac;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onRead(pUserData, pRawData, blockSize) != blockSize) {
|
if (blockSizeRemaining < metadata.data.picture.mimeLength || onRead(pUserData, pMime, metadata.data.picture.mimeLength) != metadata.data.picture.mimeLength) {
|
||||||
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
|
result = DRFLAC_FALSE;
|
||||||
return DRFLAC_FALSE;
|
goto done_flac;
|
||||||
|
}
|
||||||
|
blockSizeRemaining -= metadata.data.picture.mimeLength;
|
||||||
|
pMime[metadata.data.picture.mimeLength] = '\0'; /* Null terminate for safety. */
|
||||||
|
metadata.data.picture.mime = (const char*)pMime;
|
||||||
|
|
||||||
|
|
||||||
|
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.descriptionLength, 4) != 4) {
|
||||||
|
result = DRFLAC_FALSE;
|
||||||
|
goto done_flac;
|
||||||
|
}
|
||||||
|
blockSizeRemaining -= 4;
|
||||||
|
metadata.data.picture.descriptionLength = drflac__be2host_32(metadata.data.picture.descriptionLength);
|
||||||
|
|
||||||
|
pDescription = (char*)drflac__malloc_from_callbacks(metadata.data.picture.descriptionLength + 1, pAllocationCallbacks); /* +1 for null terminator. */
|
||||||
|
if (pDescription == NULL) {
|
||||||
|
result = DRFLAC_FALSE;
|
||||||
|
goto done_flac;
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata.pRawData = pRawData;
|
if (blockSizeRemaining < metadata.data.picture.descriptionLength || onRead(pUserData, pDescription, metadata.data.picture.descriptionLength) != metadata.data.picture.descriptionLength) {
|
||||||
metadata.rawDataSize = blockSize;
|
result = DRFLAC_FALSE;
|
||||||
|
goto done_flac;
|
||||||
pRunningData = (const char*)pRawData;
|
|
||||||
pRunningDataEnd = (const char*)pRawData + blockSize;
|
|
||||||
|
|
||||||
metadata.data.picture.type = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
|
|
||||||
metadata.data.picture.mimeLength = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
|
|
||||||
|
|
||||||
/* Need space for the rest of the block */
|
|
||||||
if ((pRunningDataEnd - pRunningData) - 24 < (drflac_int64)metadata.data.picture.mimeLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
|
|
||||||
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
|
|
||||||
return DRFLAC_FALSE;
|
|
||||||
}
|
}
|
||||||
metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength;
|
blockSizeRemaining -= metadata.data.picture.descriptionLength;
|
||||||
metadata.data.picture.descriptionLength = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
|
pDescription[metadata.data.picture.descriptionLength] = '\0'; /* Null terminate for safety. */
|
||||||
|
metadata.data.picture.description = (const char*)pDescription;
|
||||||
|
|
||||||
/* Need space for the rest of the block */
|
|
||||||
if ((pRunningDataEnd - pRunningData) - 20 < (drflac_int64)metadata.data.picture.descriptionLength) { /* <-- Note the order of operations to avoid overflow to a valid value */
|
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.width, 4) != 4) {
|
||||||
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
|
result = DRFLAC_FALSE;
|
||||||
return DRFLAC_FALSE;
|
goto done_flac;
|
||||||
}
|
}
|
||||||
metadata.data.picture.description = pRunningData; pRunningData += metadata.data.picture.descriptionLength;
|
blockSizeRemaining -= 4;
|
||||||
metadata.data.picture.width = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
|
metadata.data.picture.width = drflac__be2host_32(metadata.data.picture.width);
|
||||||
metadata.data.picture.height = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
|
|
||||||
metadata.data.picture.colorDepth = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
|
|
||||||
metadata.data.picture.indexColorCount = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
|
|
||||||
metadata.data.picture.pictureDataSize = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
|
|
||||||
metadata.data.picture.pPictureData = (const drflac_uint8*)pRunningData;
|
|
||||||
|
|
||||||
/* Need space for the picture after the block */
|
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.height, 4) != 4) {
|
||||||
if (pRunningDataEnd - pRunningData < (drflac_int64)metadata.data.picture.pictureDataSize) { /* <-- Note the order of operations to avoid overflow to a valid value */
|
result = DRFLAC_FALSE;
|
||||||
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
|
goto done_flac;
|
||||||
return DRFLAC_FALSE;
|
}
|
||||||
|
blockSizeRemaining -= 4;
|
||||||
|
metadata.data.picture.height = drflac__be2host_32(metadata.data.picture.height);
|
||||||
|
|
||||||
|
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.colorDepth, 4) != 4) {
|
||||||
|
result = DRFLAC_FALSE;
|
||||||
|
goto done_flac;
|
||||||
|
}
|
||||||
|
blockSizeRemaining -= 4;
|
||||||
|
metadata.data.picture.colorDepth = drflac__be2host_32(metadata.data.picture.colorDepth);
|
||||||
|
|
||||||
|
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.indexColorCount, 4) != 4) {
|
||||||
|
result = DRFLAC_FALSE;
|
||||||
|
goto done_flac;
|
||||||
|
}
|
||||||
|
blockSizeRemaining -= 4;
|
||||||
|
metadata.data.picture.indexColorCount = drflac__be2host_32(metadata.data.picture.indexColorCount);
|
||||||
|
|
||||||
|
|
||||||
|
/* Picture data. */
|
||||||
|
if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.pictureDataSize, 4) != 4) {
|
||||||
|
result = DRFLAC_FALSE;
|
||||||
|
goto done_flac;
|
||||||
|
}
|
||||||
|
blockSizeRemaining -= 4;
|
||||||
|
metadata.data.picture.pictureDataSize = drflac__be2host_32(metadata.data.picture.pictureDataSize);
|
||||||
|
|
||||||
|
if (blockSizeRemaining < metadata.data.picture.pictureDataSize) {
|
||||||
|
result = DRFLAC_FALSE;
|
||||||
|
goto done_flac;
|
||||||
}
|
}
|
||||||
|
|
||||||
onMeta(pUserDataMD, &metadata);
|
/* For the actual image data we want to store the offset to the start of the stream. */
|
||||||
|
metadata.data.picture.pictureDataOffset = runningFilePos + (blockSize - blockSizeRemaining);
|
||||||
|
|
||||||
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
|
/*
|
||||||
|
For the allocation of image data, we can allow memory allocation to fail, in which case we just leave
|
||||||
|
the pointer as null. If it fails, we need to fall back to seeking past the image data.
|
||||||
|
*/
|
||||||
|
#ifndef DR_FLAC_NO_PICTURE_METADATA_MALLOC
|
||||||
|
pPictureData = drflac__malloc_from_callbacks(metadata.data.picture.pictureDataSize, pAllocationCallbacks);
|
||||||
|
if (pPictureData != NULL) {
|
||||||
|
if (onRead(pUserData, pPictureData, metadata.data.picture.pictureDataSize) != metadata.data.picture.pictureDataSize) {
|
||||||
|
result = DRFLAC_FALSE;
|
||||||
|
goto done_flac;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* Allocation failed. We need to seek past the picture data. */
|
||||||
|
if (!onSeek(pUserData, metadata.data.picture.pictureDataSize, DRFLAC_SEEK_CUR)) {
|
||||||
|
result = DRFLAC_FALSE;
|
||||||
|
goto done_flac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blockSizeRemaining -= metadata.data.picture.pictureDataSize;
|
||||||
|
(void)blockSizeRemaining;
|
||||||
|
|
||||||
|
metadata.data.picture.pPictureData = (const drflac_uint8*)pPictureData;
|
||||||
|
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
if (metadata.data.picture.pictureDataOffset != 0 || metadata.data.picture.pPictureData != NULL) {
|
||||||
|
onMeta(pUserDataMD, &metadata);
|
||||||
|
} else {
|
||||||
|
/* Don't have a valid offset or data pointer, so just pretend we don't have a picture metadata. */
|
||||||
|
}
|
||||||
|
|
||||||
|
done_flac:
|
||||||
|
drflac__free_from_callbacks(pMime, pAllocationCallbacks);
|
||||||
|
drflac__free_from_callbacks(pDescription, pAllocationCallbacks);
|
||||||
|
drflac__free_from_callbacks(pPictureData, pAllocationCallbacks);
|
||||||
|
|
||||||
|
if (result != DRFLAC_TRUE) {
|
||||||
|
return DRFLAC_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -6800,13 +6906,16 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||||||
*/
|
*/
|
||||||
if (onMeta) {
|
if (onMeta) {
|
||||||
void* pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
|
void* pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
|
||||||
if (pRawData == NULL) {
|
if (pRawData != NULL) {
|
||||||
return DRFLAC_FALSE;
|
if (onRead(pUserData, pRawData, blockSize) != blockSize) {
|
||||||
}
|
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
|
||||||
|
return DRFLAC_FALSE;
|
||||||
if (onRead(pUserData, pRawData, blockSize) != blockSize) {
|
}
|
||||||
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
|
} else {
|
||||||
return DRFLAC_FALSE;
|
/* Allocation failed. We need to seek past the block. */
|
||||||
|
if (!onSeek(pUserData, blockSize, DRFLAC_SEEK_CUR)) {
|
||||||
|
return DRFLAC_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata.pRawData = pRawData;
|
metadata.pRawData = pRawData;
|
||||||
@ -8699,7 +8808,7 @@ static drflac_bool32 drflac__on_tell_stdio(void* pUserData, drflac_int64* pCurso
|
|||||||
DRFLAC_ASSERT(pFileStdio != NULL);
|
DRFLAC_ASSERT(pFileStdio != NULL);
|
||||||
DRFLAC_ASSERT(pCursor != NULL);
|
DRFLAC_ASSERT(pCursor != NULL);
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32) && !defined(NXDK)
|
||||||
#if defined(_MSC_VER) && _MSC_VER > 1200
|
#if defined(_MSC_VER) && _MSC_VER > 1200
|
||||||
result = _ftelli64(pFileStdio);
|
result = _ftelli64(pFileStdio);
|
||||||
#else
|
#else
|
||||||
@ -8821,8 +8930,6 @@ static drflac_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_
|
|||||||
|
|
||||||
DRFLAC_ASSERT(memoryStream != NULL);
|
DRFLAC_ASSERT(memoryStream != NULL);
|
||||||
|
|
||||||
newCursor = memoryStream->currentReadPos;
|
|
||||||
|
|
||||||
if (origin == DRFLAC_SEEK_SET) {
|
if (origin == DRFLAC_SEEK_SET) {
|
||||||
newCursor = 0;
|
newCursor = 0;
|
||||||
} else if (origin == DRFLAC_SEEK_CUR) {
|
} else if (origin == DRFLAC_SEEK_CUR) {
|
||||||
@ -11702,58 +11809,43 @@ static type* drflac__full_read_and_close_ ## extension (drflac* pFlac, unsigned
|
|||||||
{ \
|
{ \
|
||||||
type* pSampleData = NULL; \
|
type* pSampleData = NULL; \
|
||||||
drflac_uint64 totalPCMFrameCount; \
|
drflac_uint64 totalPCMFrameCount; \
|
||||||
|
type buffer[4096]; \
|
||||||
|
drflac_uint64 pcmFramesRead; \
|
||||||
|
size_t sampleDataBufferSize = sizeof(buffer); \
|
||||||
\
|
\
|
||||||
DRFLAC_ASSERT(pFlac != NULL); \
|
DRFLAC_ASSERT(pFlac != NULL); \
|
||||||
\
|
\
|
||||||
totalPCMFrameCount = pFlac->totalPCMFrameCount; \
|
totalPCMFrameCount = 0; \
|
||||||
\
|
\
|
||||||
if (totalPCMFrameCount == 0) { \
|
pSampleData = (type*)drflac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks); \
|
||||||
type buffer[4096]; \
|
if (pSampleData == NULL) { \
|
||||||
drflac_uint64 pcmFramesRead; \
|
goto on_error; \
|
||||||
size_t sampleDataBufferSize = sizeof(buffer); \
|
} \
|
||||||
\
|
\
|
||||||
pSampleData = (type*)drflac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks); \
|
while ((pcmFramesRead = (drflac_uint64)drflac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) { \
|
||||||
if (pSampleData == NULL) { \
|
if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) { \
|
||||||
goto on_error; \
|
type* pNewSampleData; \
|
||||||
} \
|
size_t newSampleDataBufferSize; \
|
||||||
\
|
\
|
||||||
while ((pcmFramesRead = (drflac_uint64)drflac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) { \
|
newSampleDataBufferSize = sampleDataBufferSize * 2; \
|
||||||
if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) { \
|
pNewSampleData = (type*)drflac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks); \
|
||||||
type* pNewSampleData; \
|
if (pNewSampleData == NULL) { \
|
||||||
size_t newSampleDataBufferSize; \
|
drflac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks); \
|
||||||
\
|
goto on_error; \
|
||||||
newSampleDataBufferSize = sampleDataBufferSize * 2; \
|
|
||||||
pNewSampleData = (type*)drflac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks); \
|
|
||||||
if (pNewSampleData == NULL) { \
|
|
||||||
drflac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks); \
|
|
||||||
goto on_error; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
sampleDataBufferSize = newSampleDataBufferSize; \
|
|
||||||
pSampleData = pNewSampleData; \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
DRFLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \
|
sampleDataBufferSize = newSampleDataBufferSize; \
|
||||||
totalPCMFrameCount += pcmFramesRead; \
|
pSampleData = pNewSampleData; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to \
|
DRFLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \
|
||||||
protect those ears from random noise! */ \
|
totalPCMFrameCount += pcmFramesRead; \
|
||||||
DRFLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \
|
|
||||||
} else { \
|
|
||||||
drflac_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type); \
|
|
||||||
if (dataSize > (drflac_uint64)DRFLAC_SIZE_MAX) { \
|
|
||||||
goto on_error; /* The decoded data is too big. */ \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
pSampleData = (type*)drflac__malloc_from_callbacks((size_t)dataSize, &pFlac->allocationCallbacks); /* <-- Safe cast as per the check above. */ \
|
|
||||||
if (pSampleData == NULL) { \
|
|
||||||
goto on_error; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
totalPCMFrameCount = drflac_read_pcm_frames_##extension(pFlac, pFlac->totalPCMFrameCount, pSampleData); \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
/* At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to \
|
||||||
|
protect those ears from random noise! */ \
|
||||||
|
DRFLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \
|
||||||
|
\
|
||||||
if (sampleRateOut) *sampleRateOut = pFlac->sampleRate; \
|
if (sampleRateOut) *sampleRateOut = pFlac->sampleRate; \
|
||||||
if (channelsOut) *channelsOut = pFlac->channels; \
|
if (channelsOut) *channelsOut = pFlac->channels; \
|
||||||
if (totalPCMFrameCountOut) *totalPCMFrameCountOut = totalPCMFrameCount; \
|
if (totalPCMFrameCountOut) *totalPCMFrameCountOut = totalPCMFrameCount; \
|
||||||
@ -12077,7 +12169,19 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
|
|||||||
/*
|
/*
|
||||||
REVISION HISTORY
|
REVISION HISTORY
|
||||||
================
|
================
|
||||||
v0.13.0 - TBD
|
v0.13.3 - 2026-01-17
|
||||||
|
- Fix a compiler compatibility issue with some inlined assembly.
|
||||||
|
- Fix a compilation warning.
|
||||||
|
|
||||||
|
v0.13.2 - 2025-12-02
|
||||||
|
- Improve robustness of the parsing of picture metadata to improve support for memory constrained embedded devices.
|
||||||
|
- Fix a warning about an assigned by unused variable.
|
||||||
|
- Improvements to drflac_open_and_read_pcm_frames_*() and family to avoid excessively large memory allocations from malformed files.
|
||||||
|
|
||||||
|
v0.13.1 - 2025-09-10
|
||||||
|
- Fix an error with the NXDK build.
|
||||||
|
|
||||||
|
v0.13.0 - 2025-07-23
|
||||||
- API CHANGE: Seek origin enums have been renamed to match the naming convention used by other dr_libs libraries:
|
- API CHANGE: Seek origin enums have been renamed to match the naming convention used by other dr_libs libraries:
|
||||||
- drflac_seek_origin_start -> DRFLAC_SEEK_SET
|
- drflac_seek_origin_start -> DRFLAC_SEEK_SET
|
||||||
- drflac_seek_origin_current -> DRFLAC_SEEK_CUR
|
- drflac_seek_origin_current -> DRFLAC_SEEK_CUR
|
||||||
|
|||||||
Reference in New Issue
Block a user