From 6cfda9fafb435848010c120da2ba872ba7dccd55 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Sun, 18 Sep 2022 03:04:40 +0300
Subject: [PATCH] updated dr_libs from mainstream.
---
src/codecs/dr_libs/dr_flac.h | 312 +++++++++++++++++++++++++----------
src/codecs/dr_libs/dr_mp3.h | 40 +++--
2 files changed, 252 insertions(+), 100 deletions(-)
diff --git a/src/codecs/dr_libs/dr_flac.h b/src/codecs/dr_libs/dr_flac.h
index bd174c4a..0c43eed7 100644
--- a/src/codecs/dr_libs/dr_flac.h
+++ b/src/codecs/dr_libs/dr_flac.h
@@ -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.38 - 2022-04-10
+dr_flac - v0.12.39 - 2022-09-17
David Reid - mackron@gmail.com
@@ -210,6 +210,9 @@ Build Options
#define DR_FLAC_NO_SIMD
Disables SIMD optimizations (SSE on x86/x64 architectures, NEON on ARM architectures). Use this if you are having compatibility issues with your compiler.
+#define DR_FLAC_NO_WCHAR
+ Disables all functions ending with `_w`. Use this if your compiler does not provide wchar.h. Not required if DR_FLAC_NO_STDIO is also defined.
+
Notes
@@ -232,7 +235,7 @@ extern "C" {
#define DRFLAC_VERSION_MAJOR 0
#define DRFLAC_VERSION_MINOR 12
-#define DRFLAC_VERSION_REVISION 38
+#define DRFLAC_VERSION_REVISION 39
#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. */
@@ -383,15 +386,13 @@ typedef enum
drflac_seek_origin_current
} drflac_seek_origin;
-/* Packing is important on this structure because we map this directly to the raw data within the SEEKTABLE metadata block. */
-#pragma pack(2)
+/* The order of members in this structure is important because we map this directly to the raw data within the SEEKTABLE metadata block. */
typedef struct
{
drflac_uint64 firstPCMFrame;
drflac_uint64 flacFrameOffset; /* The offset from the first byte of the header of the first frame. */
drflac_uint16 pcmFrameCount;
} drflac_seekpoint;
-#pragma pack()
typedef struct
{
@@ -1280,15 +1281,13 @@ typedef struct
const char* pRunningData;
} drflac_cuesheet_track_iterator;
-/* Packing is important on this structure because we map this directly to the raw data within the CUESHEET metadata block. */
-#pragma pack(4)
+/* The order of members here is important because we map this directly to the raw data within the CUESHEET metadata block. */
typedef struct
{
drflac_uint64 offset;
drflac_uint8 index;
drflac_uint8 reserved[3];
} drflac_cuesheet_track_index;
-#pragma pack()
typedef struct
{
@@ -1515,9 +1514,7 @@ static DRFLAC_INLINE drflac_bool32 drflac_has_sse41(void)
{
#if defined(DRFLAC_SUPPORT_SSE41)
#if (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(DRFLAC_NO_SSE41)
- #if defined(DRFLAC_X64)
- return DRFLAC_TRUE; /* 64-bit targets always support SSE4.1. */
- #elif (defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE4_1__)
+ #if defined(__SSE4_1__) || defined(__AVX__)
return DRFLAC_TRUE; /* If the compiler is allowed to freely generate SSE41 code we can assume support. */
#else
#if defined(DRFLAC_NO_CPUID)
@@ -1582,18 +1579,21 @@ static DRFLAC_INLINE drflac_bool32 drflac_has_sse41(void)
extern __inline drflac_uint64 _watcom_bswap64(drflac_uint64);
#pragma aux _watcom_bswap16 = \
"xchg al, ah" \
- parm [ax] \
- modify [ax];
+ parm [ax] \
+ value [ax] \
+ modify nomemory;
#pragma aux _watcom_bswap32 = \
- "bswap eax" \
- parm [eax] \
- modify [eax];
+ "bswap eax" \
+ parm [eax] \
+ value [eax] \
+ modify nomemory;
#pragma aux _watcom_bswap64 = \
"bswap eax" \
"bswap edx" \
"xchg eax,edx" \
parm [eax edx] \
- modify [eax edx];
+ value [eax edx] \
+ modify nomemory;
#endif
@@ -1694,6 +1694,10 @@ typedef drflac_int32 drflac_result;
#define DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE 9
#define DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE 10
+#define DRFLAC_SEEKPOINT_SIZE_IN_BYTES 18
+#define DRFLAC_CUESHEET_TRACK_SIZE_IN_BYTES 36
+#define DRFLAC_CUESHEET_TRACK_INDEX_SIZE_IN_BYTES 12
+
#define drflac_align(x, a) ((((x) + (a) - 1) / (a)) * (a))
@@ -2696,6 +2700,10 @@ static drflac_bool32 drflac__find_and_seek_to_next_sync_code(drflac_bs* bs)
#if defined(__WATCOMC__) && defined(__386__)
#define DRFLAC_IMPLEMENT_CLZ_WATCOM
#endif
+#ifdef __MRC__
+#include <intrinsics.h>
+#define DRFLAC_IMPLEMENT_CLZ_MRC
+#endif
static DRFLAC_INLINE drflac_uint32 drflac__clz_software(drflac_cache_t x)
{
@@ -2736,6 +2744,8 @@ static DRFLAC_INLINE drflac_bool32 drflac__is_lzcnt_supported(void)
/* Fast compile time check for ARM. */
#if defined(DRFLAC_HAS_LZCNT_INTRINSIC) && defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5)
return DRFLAC_TRUE;
+#elif defined(__MRC__)
+ return DRFLAC_TRUE;
#else
/* If the compiler itself does not support the intrinsic then we'll need to return false. */
#ifdef DRFLAC_HAS_LZCNT_INTRINSIC
@@ -2845,6 +2855,15 @@ static DRFLAC_INLINE drflac_uint32 drflac__clz_msvc(drflac_cache_t x)
#ifdef DRFLAC_IMPLEMENT_CLZ_WATCOM
static __inline drflac_uint32 drflac__clz_watcom (drflac_uint32);
+#ifdef DRFLAC_IMPLEMENT_CLZ_WATCOM_LZCNT
+/* Use the LZCNT instruction (only available on some processors since the 2010s). */
+#pragma aux drflac__clz_watcom_lzcnt = \
+ "db 0F3h, 0Fh, 0BDh, 0C0h" /* lzcnt eax, eax */ \
+ parm [eax] \
+ value [eax] \
+ modify nomemory;
+#else
+/* Use the 386+-compatible implementation. */
#pragma aux drflac__clz_watcom = \
"bsr eax, eax" \
"xor eax, 31" \
@@ -2852,6 +2871,7 @@ static __inline drflac_uint32 drflac__clz_watcom (drflac_uint32);
value [eax] \
modify exact [eax] nomemory;
#endif
+#endif
static DRFLAC_INLINE drflac_uint32 drflac__clz(drflac_cache_t x)
{
@@ -2863,8 +2883,12 @@ 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_LZCNT)
+ return drflac__clz_watcom_lzcnt(x);
#elif defined(DRFLAC_IMPLEMENT_CLZ_WATCOM)
return (x == 0) ? sizeof(x)*8 : drflac__clz_watcom(x);
+#elif defined(__MRC__)
+ return __cntlzw(x);
#else
return drflac__clz_software(x);
#endif
@@ -4426,7 +4450,7 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__neon_32(drflac_
const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
- riceParamMask = ~((~0UL) << riceParam);
+ riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
riceParamMask128 = vdupq_n_u32(riceParamMask);
riceParam128 = vdupq_n_s32(riceParam);
@@ -4618,7 +4642,7 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__neon_64(drflac_
const drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
- riceParamMask = ~((~0UL) << riceParam);
+ riceParamMask = (drflac_uint32)~((~0UL) << riceParam);
riceParamMask128 = vdupq_n_u32(riceParamMask);
riceParam128 = vdupq_n_s32(riceParam);
@@ -6442,7 +6466,7 @@ static void drflac__free_from_callbacks(void* p, const drflac_allocation_callbac
}
-static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_uint64* pFirstFramePos, drflac_uint64* pSeektablePos, drflac_uint32* pSeektableSize, drflac_allocation_callbacks* pAllocationCallbacks)
+static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_uint64* pFirstFramePos, drflac_uint64* pSeektablePos, drflac_uint32* pSeekpointCount, drflac_allocation_callbacks* pAllocationCallbacks)
{
/*
We want to keep track of the byte position in the stream of the seektable. At the time of calling this function we know that
@@ -6502,32 +6526,37 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
seektableSize = blockSize;
if (onMeta) {
+ drflac_uint32 seekpointCount;
drflac_uint32 iSeekpoint;
void* pRawData;
- pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
+ seekpointCount = blockSize/DRFLAC_SEEKPOINT_SIZE_IN_BYTES;
+
+ pRawData = drflac__malloc_from_callbacks(seekpointCount * sizeof(drflac_seekpoint), pAllocationCallbacks);
if (pRawData == NULL) {
return DRFLAC_FALSE;
}
- if (onRead(pUserData, pRawData, blockSize) != blockSize) {
- drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
- return DRFLAC_FALSE;
- }
+ /* We need to read seekpoint by seekpoint and do some processing. */
+ for (iSeekpoint = 0; iSeekpoint < seekpointCount; ++iSeekpoint) {
+ drflac_seekpoint* pSeekpoint = (drflac_seekpoint*)pRawData + iSeekpoint;
- metadata.pRawData = pRawData;
- metadata.rawDataSize = blockSize;
- metadata.data.seektable.seekpointCount = blockSize/sizeof(drflac_seekpoint);
- metadata.data.seektable.pSeekpoints = (const drflac_seekpoint*)pRawData;
+ if (onRead(pUserData, pSeekpoint, DRFLAC_SEEKPOINT_SIZE_IN_BYTES) != DRFLAC_SEEKPOINT_SIZE_IN_BYTES) {
+ drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
+ return DRFLAC_FALSE;
+ }
- /* Endian swap. */
- for (iSeekpoint = 0; iSeekpoint < metadata.data.seektable.seekpointCount; ++iSeekpoint) {
- drflac_seekpoint* pSeekpoint = (drflac_seekpoint*)pRawData + iSeekpoint;
+ /* Endian swap. */
pSeekpoint->firstPCMFrame = drflac__be2host_64(pSeekpoint->firstPCMFrame);
pSeekpoint->flacFrameOffset = drflac__be2host_64(pSeekpoint->flacFrameOffset);
pSeekpoint->pcmFrameCount = drflac__be2host_16(pSeekpoint->pcmFrameCount);
}
+ metadata.pRawData = pRawData;
+ metadata.rawDataSize = blockSize;
+ metadata.data.seektable.seekpointCount = seekpointCount;
+ metadata.data.seektable.pSeekpoints = (const drflac_seekpoint*)pRawData;
+
onMeta(pUserDataMD, &metadata);
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
@@ -6612,9 +6641,15 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
void* pRawData;
const char* pRunningData;
const char* pRunningDataEnd;
+ size_t bufferSize;
drflac_uint8 iTrack;
drflac_uint8 iIndex;
+ void* pTrackData;
+ /*
+ This needs to be loaded in two passes. The first pass is used to calculate the size of the memory allocation
+ we need for storing the necessary data. The second pass will fill that buffer with usable data.
+ */
pRawData = drflac__malloc_from_callbacks(blockSize, pAllocationCallbacks);
if (pRawData == NULL) {
return DRFLAC_FALSE;
@@ -6635,38 +6670,91 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
metadata.data.cuesheet.leadInSampleCount = drflac__be2host_64(*(const drflac_uint64*)pRunningData); pRunningData += 8;
metadata.data.cuesheet.isCD = (pRunningData[0] & 0x80) != 0; pRunningData += 259;
metadata.data.cuesheet.trackCount = pRunningData[0]; pRunningData += 1;
- metadata.data.cuesheet.pTrackData = pRunningData;
+ metadata.data.cuesheet.pTrackData = NULL; /* Will be filled later. */
- /* Check that the cuesheet tracks are valid before passing it to the callback */
- for (iTrack = 0; iTrack < metadata.data.cuesheet.trackCount; ++iTrack) {
- drflac_uint8 indexCount;
- drflac_uint32 indexPointSize;
+ /* Pass 1: Calculate the size of the buffer for the track data. */
+ {
+ const char* pRunningDataSaved = pRunningData; /* Will be restored at the end in preparation for the second pass. */
- if (pRunningDataEnd - pRunningData < 36) {
- drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
- return DRFLAC_FALSE;
+ bufferSize = metadata.data.cuesheet.trackCount * DRFLAC_CUESHEET_TRACK_SIZE_IN_BYTES;
+
+ for (iTrack = 0; iTrack < metadata.data.cuesheet.trackCount; ++iTrack) {
+ drflac_uint8 indexCount;
+ drflac_uint32 indexPointSize;
+
+ if (pRunningDataEnd - pRunningData < DRFLAC_CUESHEET_TRACK_SIZE_IN_BYTES) {
+ drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
+ return DRFLAC_FALSE;
+ }
+
+ /* Skip to the index point count */
+ pRunningData += 35;
+
+ indexCount = pRunningData[0];
+ pRunningData += 1;
+
+ bufferSize += indexCount * sizeof(drflac_cuesheet_track_index);
+
+ /* Quick validation check. */
+ indexPointSize = indexCount * DRFLAC_CUESHEET_TRACK_INDEX_SIZE_IN_BYTES;
+ if (pRunningDataEnd - pRunningData < (drflac_int64)indexPointSize) {
+ drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
+ return DRFLAC_FALSE;
+ }
+
+ pRunningData += indexPointSize;
}
- /* Skip to the index point count */
- pRunningData += 35;
- indexCount = pRunningData[0]; pRunningData += 1;
- indexPointSize = indexCount * sizeof(drflac_cuesheet_track_index);
- if (pRunningDataEnd - pRunningData < (drflac_int64)indexPointSize) {
+ pRunningData = pRunningDataSaved;
+ }
+
+ /* Pass 2: Allocate a buffer and fill the data. Validation was done in the step above so can be skipped. */
+ {
+ char* pRunningTrackData;
+
+ pTrackData = drflac__malloc_from_callbacks(bufferSize, pAllocationCallbacks);
+ if (pTrackData == NULL) {
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
return DRFLAC_FALSE;
}
- /* Endian swap. */
- for (iIndex = 0; iIndex < indexCount; ++iIndex) {
- drflac_cuesheet_track_index* pTrack = (drflac_cuesheet_track_index*)pRunningData;
- pRunningData += sizeof(drflac_cuesheet_track_index);
- pTrack->offset = drflac__be2host_64(pTrack->offset);
+ pRunningTrackData = (char*)pTrackData;
+
+ for (iTrack = 0; iTrack < metadata.data.cuesheet.trackCount; ++iTrack) {
+ drflac_uint8 indexCount;
+
+ DRFLAC_COPY_MEMORY(pRunningTrackData, pRunningData, DRFLAC_CUESHEET_TRACK_SIZE_IN_BYTES);
+ pRunningData += DRFLAC_CUESHEET_TRACK_SIZE_IN_BYTES-1; /* Skip forward, but not beyond the last byte in the CUESHEET_TRACK block which is the index count. */
+ pRunningTrackData += DRFLAC_CUESHEET_TRACK_SIZE_IN_BYTES-1;
+
+ /* Grab the index count for the next part. */
+ indexCount = pRunningData[0];
+ pRunningData += 1;
+ pRunningTrackData += 1;
+
+ /* Extract each track index. */
+ for (iIndex = 0; iIndex < indexCount; ++iIndex) {
+ drflac_cuesheet_track_index* pTrackIndex = (drflac_cuesheet_track_index*)pRunningTrackData;
+
+ DRFLAC_COPY_MEMORY(pRunningTrackData, pRunningData, DRFLAC_CUESHEET_TRACK_INDEX_SIZE_IN_BYTES);
+ pRunningData += DRFLAC_CUESHEET_TRACK_INDEX_SIZE_IN_BYTES;
+ pRunningTrackData += sizeof(drflac_cuesheet_track_index);
+
+ pTrackIndex->offset = drflac__be2host_64(pTrackIndex->offset);
+ }
}
+
+ metadata.data.cuesheet.pTrackData = pTrackData;
}
+ /* The original data is no longer needed. */
+ drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
+ pRawData = NULL;
+
onMeta(pUserDataMD, &metadata);
- drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
+ drflac__free_from_callbacks(pTrackData, pAllocationCallbacks);
+ pTrackData = NULL;
}
} break;
@@ -6705,7 +6793,7 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
return DRFLAC_FALSE;
}
- metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength;
+ metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength;
metadata.data.picture.descriptionLength = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
/* Need space for the rest of the block */
@@ -6713,7 +6801,7 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
drflac__free_from_callbacks(pRawData, pAllocationCallbacks);
return DRFLAC_FALSE;
}
- metadata.data.picture.description = pRunningData; pRunningData += metadata.data.picture.descriptionLength;
+ metadata.data.picture.description = pRunningData; pRunningData += metadata.data.picture.descriptionLength;
metadata.data.picture.width = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.height = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
metadata.data.picture.colorDepth = drflac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
@@ -6796,9 +6884,9 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
}
}
- *pSeektablePos = seektablePos;
- *pSeektableSize = seektableSize;
- *pFirstFramePos = runningFilePos;
+ *pSeektablePos = seektablePos;
+ *pSeekpointCount = seektableSize / DRFLAC_SEEKPOINT_SIZE_IN_BYTES;
+ *pFirstFramePos = runningFilePos;
return DRFLAC_TRUE;
}
@@ -7828,11 +7916,11 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
drflac_uint32 wholeSIMDVectorCountPerChannel;
drflac_uint32 decodedSamplesAllocationSize;
#ifndef DR_FLAC_NO_OGG
- drflac_oggbs oggbs;
+ drflac_oggbs* pOggbs = NULL;
#endif
drflac_uint64 firstFramePos;
drflac_uint64 seektablePos;
- drflac_uint32 seektableSize;
+ drflac_uint32 seekpointCount;
drflac_allocation_callbacks allocationCallbacks;
drflac* pFlac;
@@ -7886,18 +7974,21 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
/* There's additional data required for Ogg streams. */
if (init.container == drflac_container_ogg) {
allocationSize += sizeof(drflac_oggbs);
- }
- DRFLAC_ZERO_MEMORY(&oggbs, sizeof(oggbs));
- if (init.container == drflac_container_ogg) {
- oggbs.onRead = onRead;
- oggbs.onSeek = onSeek;
- oggbs.pUserData = pUserData;
- oggbs.currentBytePos = init.oggFirstBytePos;
- oggbs.firstBytePos = init.oggFirstBytePos;
- oggbs.serialNumber = init.oggSerial;
- oggbs.bosPageHeader = init.oggBosHeader;
- oggbs.bytesRemainingInPage = 0;
+ pOggbs = (drflac_oggbs*)drflac__malloc_from_callbacks(sizeof(*pOggbs), &allocationCallbacks);
+ if (pOggbs == NULL) {
+ return NULL; /*DRFLAC_OUT_OF_MEMORY;*/
+ }
+
+ DRFLAC_ZERO_MEMORY(pOggbs, sizeof(*pOggbs));
+ pOggbs->onRead = onRead;
+ pOggbs->onSeek = onSeek;
+ pOggbs->pUserData = pUserData;
+ pOggbs->currentBytePos = init.oggFirstBytePos;
+ pOggbs->firstBytePos = init.oggFirstBytePos;
+ pOggbs->serialNumber = init.oggSerial;
+ pOggbs->bosPageHeader = init.oggBosHeader;
+ pOggbs->bytesRemainingInPage = 0;
}
#endif
@@ -7906,9 +7997,9 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
consist of only a single heap allocation. To this, the size of the seek table needs to be known, which we determine when reading
and decoding the metadata.
*/
- firstFramePos = 42; /* <-- We know we are at byte 42 at this point. */
- seektablePos = 0;
- seektableSize = 0;
+ firstFramePos = 42; /* <-- We know we are at byte 42 at this point. */
+ seektablePos = 0;
+ seekpointCount = 0;
if (init.hasMetadataBlocks) {
drflac_read_proc onReadOverride = onRead;
drflac_seek_proc onSeekOverride = onSeek;
@@ -7918,20 +8009,26 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
if (init.container == drflac_container_ogg) {
onReadOverride = drflac__on_read_ogg;
onSeekOverride = drflac__on_seek_ogg;
- pUserDataOverride = (void*)&oggbs;
+ pUserDataOverride = (void*)pOggbs;
}
#endif
- if (!drflac__read_and_decode_metadata(onReadOverride, onSeekOverride, onMeta, pUserDataOverride, pUserDataMD, &firstFramePos, &seektablePos, &seektableSize, &allocationCallbacks)) {
+ if (!drflac__read_and_decode_metadata(onReadOverride, onSeekOverride, onMeta, pUserDataOverride, pUserDataMD, &firstFramePos, &seektablePos, &seekpointCount, &allocationCallbacks)) {
+ #ifndef DR_FLAC_NO_OGG
+ drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
+ #endif
return NULL;
}
- allocationSize += seektableSize;
+ allocationSize += seekpointCount * sizeof(drflac_seekpoint);
}
pFlac = (drflac*)drflac__malloc_from_callbacks(allocationSize, &allocationCallbacks);
if (pFlac == NULL) {
+ #ifndef DR_FLAC_NO_OGG
+ drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
+ #endif
return NULL;
}
@@ -7941,8 +8038,12 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
#ifndef DR_FLAC_NO_OGG
if (init.container == drflac_container_ogg) {
- drflac_oggbs* pInternalOggbs = (drflac_oggbs*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize + seektableSize);
- DRFLAC_COPY_MEMORY(pInternalOggbs, &oggbs, sizeof(oggbs));
+ drflac_oggbs* pInternalOggbs = (drflac_oggbs*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize + (seekpointCount * sizeof(drflac_seekpoint)));
+ DRFLAC_COPY_MEMORY(pInternalOggbs, pOggbs, sizeof(*pOggbs));
+
+ /* At this point the pOggbs object has been handed over to pInternalOggbs and can be freed. */
+ drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
+ pOggbs = NULL;
/* The Ogg bistream needs to be layered on top of the original bitstream. */
pFlac->bs.onRead = drflac__on_read_ogg;
@@ -7966,7 +8067,7 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
{
/* If we have a seektable we need to load it now, making sure we move back to where we were previously. */
if (seektablePos != 0) {
- pFlac->seekpointCount = seektableSize / sizeof(*pFlac->pSeekpoints);
+ pFlac->seekpointCount = seekpointCount;
pFlac->pSeekpoints = (drflac_seekpoint*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize);
DRFLAC_ASSERT(pFlac->bs.onSeek != NULL);
@@ -7974,18 +8075,20 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
/* Seek to the seektable, then just read directly into our seektable buffer. */
if (pFlac->bs.onSeek(pFlac->bs.pUserData, (int)seektablePos, drflac_seek_origin_start)) {
- if (pFlac->bs.onRead(pFlac->bs.pUserData, pFlac->pSeekpoints, seektableSize) == seektableSize) {
- /* Endian swap. */
- drflac_uint32 iSeekpoint;
- for (iSeekpoint = 0; iSeekpoint < pFlac->seekpointCount; ++iSeekpoint) {
+ drflac_uint32 iSeekpoint;
+
+ for (iSeekpoint = 0; iSeekpoint < seekpointCount; iSeekpoint += 1) {
+ if (pFlac->bs.onRead(pFlac->bs.pUserData, pFlac->pSeekpoints + iSeekpoint, DRFLAC_SEEKPOINT_SIZE_IN_BYTES) == DRFLAC_SEEKPOINT_SIZE_IN_BYTES) {
+ /* Endian swap. */
pFlac->pSeekpoints[iSeekpoint].firstPCMFrame = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].firstPCMFrame);
pFlac->pSeekpoints[iSeekpoint].flacFrameOffset = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].flacFrameOffset);
pFlac->pSeekpoints[iSeekpoint].pcmFrameCount = drflac__be2host_16(pFlac->pSeekpoints[iSeekpoint].pcmFrameCount);
+ } else {
+ /* Failed to read the seektable. Pretend we don't have one. */
+ pFlac->pSeekpoints = NULL;
+ pFlac->seekpointCount = 0;
+ break;
}
- } else {
- /* Failed to read the seektable. Pretend we don't have one. */
- pFlac->pSeekpoints = NULL;
- pFlac->seekpointCount = 0;
}
/* We need to seek back to where we were. If this fails it's a critical error. */
@@ -8034,7 +8137,9 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
#ifndef DR_FLAC_NO_STDIO
#include <stdio.h>
+#ifndef DR_FLAC_NO_WCHAR
#include <wchar.h> /* For wcslen(), wcsrtombs() */
+#endif
/* 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>
@@ -8500,6 +8605,7 @@ fallback, so if you notice your compiler not detecting this properly I'm happy t
#endif
#endif
+#ifndef DR_FLAC_NO_WCHAR
static drflac_result drflac_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drflac_allocation_callbacks* pAllocationCallbacks)
{
if (ppFile != NULL) {
@@ -8528,10 +8634,23 @@ static drflac_result drflac_wfopen(FILE** ppFile, const wchar_t* pFilePath, cons
}
#else
/*
- Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can
- think of to do this is with wcsrtombs(). Note that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for
- maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler error I'll look into improving compatibility.
+ Use fopen() on anything other than Windows. Requires a conversion. This is annoying because
+ fopen() is locale specific. The only real way I can think of to do this is with wcsrtombs(). Note
+ that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for
+ maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler
+ error I'll look into improving compatibility.
*/
+
+ /*
+ Some compilers don't support wchar_t or wcsrtombs() which we're using below. In this case we just
+ need to abort with an error. If you encounter a compiler lacking such support, add it to this list
+ and submit a bug report and it'll be added to the library upstream.
+ */
+ #if defined(__DJGPP__)
+ {
+ /* Nothing to do here. This will fall through to the error check below. */
+ }
+ #else
{
mbstate_t mbs;
size_t lenMB;
@@ -8573,6 +8692,7 @@ static drflac_result drflac_wfopen(FILE** ppFile, const wchar_t* pFilePath, cons
drflac__free_from_callbacks(pFilePathMB, pAllocationCallbacks);
}
+ #endif
if (*ppFile == NULL) {
return DRFLAC_ERROR;
@@ -8581,6 +8701,7 @@ static drflac_result drflac_wfopen(FILE** ppFile, const wchar_t* pFilePath, cons
return DRFLAC_SUCCESS;
}
+#endif
static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead)
{
@@ -8613,6 +8734,7 @@ DRFLAC_API drflac* drflac_open_file(const char* pFileName, const drflac_allocati
return pFlac;
}
+#ifndef DR_FLAC_NO_WCHAR
DRFLAC_API drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks)
{
drflac* pFlac;
@@ -8630,6 +8752,7 @@ DRFLAC_API drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_all
return pFlac;
}
+#endif
DRFLAC_API drflac* drflac_open_file_with_metadata(const char* pFileName, drflac_meta_proc onMeta, void* pUserData, const drflac_allocation_callbacks* pAllocationCallbacks)
{
@@ -8649,6 +8772,7 @@ DRFLAC_API drflac* drflac_open_file_with_metadata(const char* pFileName, drflac_
return pFlac;
}
+#ifndef DR_FLAC_NO_WCHAR
DRFLAC_API drflac* drflac_open_file_with_metadata_w(const wchar_t* pFileName, drflac_meta_proc onMeta, voi
(Patch may be truncated, please check the link at the top of this post.)