gosu 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/dependencies/SDL/include/SDL.h +108 -14
- data/dependencies/SDL/include/SDL_assert.h +81 -50
- data/dependencies/SDL/include/SDL_atomic.h +135 -35
- data/dependencies/SDL/include/SDL_audio.h +960 -355
- data/dependencies/SDL/include/SDL_bits.h +11 -6
- data/dependencies/SDL/include/SDL_blendmode.h +91 -14
- data/dependencies/SDL/include/SDL_clipboard.h +30 -7
- data/dependencies/SDL/include/SDL_config.h +277 -27
- data/dependencies/SDL/include/SDL_config_android.h +13 -38
- data/dependencies/SDL/include/SDL_config_iphoneos.h +21 -62
- data/dependencies/SDL/include/SDL_config_macosx.h +23 -92
- data/dependencies/SDL/include/SDL_config_minimal.h +1 -4
- data/dependencies/SDL/include/SDL_config_pandora.h +15 -22
- data/dependencies/SDL/include/SDL_config_psp.h +16 -37
- data/dependencies/SDL/include/SDL_config_windows.h +28 -91
- data/dependencies/SDL/include/SDL_config_winrt.h +33 -61
- data/dependencies/SDL/include/SDL_config_wiz.h +28 -56
- data/dependencies/SDL/include/SDL_copying.h +1 -1
- data/dependencies/SDL/include/SDL_cpuinfo.h +331 -71
- data/dependencies/SDL/include/SDL_egl.h +906 -280
- data/dependencies/SDL/include/SDL_endian.h +101 -47
- data/dependencies/SDL/include/SDL_error.h +70 -19
- data/dependencies/SDL/include/SDL_events.h +387 -79
- data/dependencies/SDL/include/SDL_filesystem.h +73 -64
- data/dependencies/SDL/include/SDL_gamecontroller.h +585 -125
- data/dependencies/SDL/include/SDL_gesture.h +36 -6
- data/dependencies/SDL/include/SDL_haptic.h +304 -210
- data/dependencies/SDL/include/SDL_hidapi.h +451 -0
- data/dependencies/SDL/include/SDL_hints.h +1286 -897
- data/dependencies/SDL/include/SDL_joystick.h +577 -130
- data/dependencies/SDL/include/SDL_keyboard.h +162 -63
- data/dependencies/SDL/include/SDL_keycode.h +7 -5
- data/dependencies/SDL/include/SDL_loadso.h +42 -8
- data/dependencies/SDL/include/SDL_locale.h +34 -32
- data/dependencies/SDL/include/SDL_log.h +212 -19
- data/dependencies/SDL/include/SDL_main.h +72 -17
- data/dependencies/SDL/include/SDL_messagebox.h +70 -23
- data/dependencies/SDL/include/SDL_metal.h +27 -32
- data/dependencies/SDL/include/SDL_misc.h +19 -15
- data/dependencies/SDL/include/SDL_mouse.h +262 -110
- data/dependencies/SDL/include/SDL_mutex.h +286 -66
- data/dependencies/SDL/include/SDL_name.h +1 -1
- data/dependencies/SDL/include/SDL_opengl.h +1 -1
- data/dependencies/SDL/include/SDL_opengles.h +1 -1
- data/dependencies/SDL/include/SDL_opengles2.h +2 -2
- data/dependencies/SDL/include/SDL_pixels.h +199 -34
- data/dependencies/SDL/include/SDL_platform.h +39 -2
- data/dependencies/SDL/include/SDL_power.h +23 -10
- data/dependencies/SDL/include/SDL_quit.h +1 -1
- data/dependencies/SDL/include/SDL_rect.h +78 -28
- data/dependencies/SDL/include/SDL_render.h +1204 -472
- data/dependencies/SDL/include/SDL_revision.h +2 -2
- data/dependencies/SDL/include/SDL_rwops.h +605 -33
- data/dependencies/SDL/include/SDL_scancode.h +1 -1
- data/dependencies/SDL/include/SDL_sensor.h +76 -42
- data/dependencies/SDL/include/SDL_shape.h +38 -27
- data/dependencies/SDL/include/SDL_stdinc.h +96 -24
- data/dependencies/SDL/include/SDL_surface.h +571 -139
- data/dependencies/SDL/include/SDL_system.h +339 -101
- data/dependencies/SDL/include/SDL_syswm.h +50 -20
- data/dependencies/SDL/include/SDL_test.h +1 -1
- data/dependencies/SDL/include/SDL_test_assert.h +2 -2
- data/dependencies/SDL/include/SDL_test_common.h +23 -6
- data/dependencies/SDL/include/SDL_test_compare.h +1 -1
- data/dependencies/SDL/include/SDL_test_crc32.h +1 -1
- data/dependencies/SDL/include/SDL_test_font.h +3 -3
- data/dependencies/SDL/include/SDL_test_fuzzer.h +28 -26
- data/dependencies/SDL/include/SDL_test_harness.h +6 -6
- data/dependencies/SDL/include/SDL_test_images.h +1 -1
- data/dependencies/SDL/include/SDL_test_log.h +1 -1
- data/dependencies/SDL/include/SDL_test_md5.h +1 -1
- data/dependencies/SDL/include/SDL_test_memory.h +1 -1
- data/dependencies/SDL/include/SDL_test_random.h +2 -2
- data/dependencies/SDL/include/SDL_thread.h +226 -128
- data/dependencies/SDL/include/SDL_timer.h +129 -22
- data/dependencies/SDL/include/SDL_touch.h +48 -8
- data/dependencies/SDL/include/SDL_types.h +1 -1
- data/dependencies/SDL/include/SDL_version.h +72 -46
- data/dependencies/SDL/include/SDL_video.h +1266 -460
- data/dependencies/SDL/include/SDL_vulkan.h +100 -161
- data/dependencies/SDL/include/begin_code.h +22 -1
- data/dependencies/SDL/include/close_code.h +1 -1
- data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
- data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
- data/dependencies/SDL_sound/SDL_sound.c +83 -7
- data/dependencies/SDL_sound/SDL_sound.h +4 -4
- data/dependencies/SDL_sound/SDL_sound_aiff.c +9 -12
- data/dependencies/SDL_sound/SDL_sound_au.c +7 -7
- data/dependencies/SDL_sound/SDL_sound_coreaudio.c +3 -3
- data/dependencies/SDL_sound/SDL_sound_flac.c +1 -1
- data/dependencies/SDL_sound/SDL_sound_internal.h +17 -10
- data/dependencies/SDL_sound/SDL_sound_modplug.c +25 -27
- data/dependencies/SDL_sound/SDL_sound_mp3.c +5 -17
- data/dependencies/SDL_sound/SDL_sound_raw.c +11 -11
- data/dependencies/SDL_sound/SDL_sound_shn.c +8 -7
- data/dependencies/SDL_sound/SDL_sound_voc.c +6 -4
- data/dependencies/SDL_sound/SDL_sound_vorbis.c +6 -11
- data/dependencies/SDL_sound/SDL_sound_wav.c +35 -29
- data/dependencies/SDL_sound/dr_flac.h +618 -220
- data/dependencies/SDL_sound/dr_mp3.h +263 -94
- data/dependencies/SDL_sound/libmodplug/fastmix.c +58 -64
- data/dependencies/SDL_sound/libmodplug/libmodplug.h +25 -103
- data/dependencies/SDL_sound/libmodplug/load_669.c +14 -17
- data/dependencies/SDL_sound/libmodplug/load_amf.c +11 -7
- data/dependencies/SDL_sound/libmodplug/load_ams.c +65 -22
- data/dependencies/SDL_sound/libmodplug/load_dbm.c +8 -4
- data/dependencies/SDL_sound/libmodplug/load_dmf.c +55 -25
- data/dependencies/SDL_sound/libmodplug/load_far.c +9 -13
- data/dependencies/SDL_sound/libmodplug/load_gdm.c +448 -0
- data/dependencies/SDL_sound/libmodplug/load_it.c +45 -49
- data/dependencies/SDL_sound/libmodplug/load_mdl.c +80 -53
- data/dependencies/SDL_sound/libmodplug/load_med.c +20 -12
- data/dependencies/SDL_sound/libmodplug/load_mod.c +40 -15
- data/dependencies/SDL_sound/libmodplug/load_mt2.c +29 -17
- data/dependencies/SDL_sound/libmodplug/load_okt.c +12 -8
- data/dependencies/SDL_sound/libmodplug/load_psm.c +101 -78
- data/dependencies/SDL_sound/libmodplug/load_ptm.c +18 -17
- data/dependencies/SDL_sound/libmodplug/load_s3m.c +9 -7
- data/dependencies/SDL_sound/libmodplug/load_stm.c +3 -2
- data/dependencies/SDL_sound/libmodplug/load_ult.c +2 -2
- data/dependencies/SDL_sound/libmodplug/load_umx.c +315 -35
- data/dependencies/SDL_sound/libmodplug/load_xm.c +25 -21
- data/dependencies/SDL_sound/libmodplug/mmcmp.c +295 -149
- data/dependencies/SDL_sound/libmodplug/modplug.c +7 -123
- data/dependencies/SDL_sound/libmodplug/modplug.h +32 -29
- data/dependencies/SDL_sound/libmodplug/snd_dsp.c +0 -1
- data/dependencies/SDL_sound/libmodplug/snd_flt.c +2 -2
- data/dependencies/SDL_sound/libmodplug/snd_fx.c +24 -18
- data/dependencies/SDL_sound/libmodplug/sndfile.c +55 -156
- data/dependencies/SDL_sound/libmodplug/sndmix.c +7 -12
- data/dependencies/SDL_sound/libmodplug/tables.h +10 -15
- data/dependencies/SDL_sound/stb_vorbis.h +508 -325
- data/dependencies/{al_soft → mojoAL}/AL/al.h +38 -30
- data/dependencies/{al_soft → mojoAL}/AL/alc.h +27 -56
- data/dependencies/mojoAL/mojoal.c +4594 -0
- data/ext/gosu/extconf.rb +29 -30
- data/include/Gosu/Audio.hpp +70 -85
- data/include/Gosu/Color.hpp +19 -11
- data/include/Gosu/Font.hpp +40 -44
- data/include/Gosu/Graphics.hpp +58 -71
- data/include/Gosu/GraphicsBase.hpp +26 -33
- data/include/Gosu/Image.hpp +56 -62
- data/include/Gosu/ImageData.hpp +23 -27
- data/include/Gosu/Inspection.hpp +1 -4
- data/include/Gosu/TextInput.hpp +34 -40
- data/include/Gosu/Version.hpp +1 -1
- data/include/Gosu/Window.hpp +71 -70
- data/lib/SDL2.dll +0 -0
- data/lib/gosu/compat.rb +24 -37
- data/lib/gosu.rb +2 -2
- data/lib64/SDL2.dll +0 -0
- data/src/Audio.cpp +86 -86
- data/src/AudioFile.hpp +6 -6
- data/src/AudioFileAudioToolbox.cpp +1 -1
- data/src/AudioFileSDLSound.cpp +1 -1
- data/src/AudioImpl.hpp +5 -5
- data/src/BitmapIO.cpp +0 -20
- data/src/BlockAllocator.cpp +2 -1
- data/src/Channel.cpp +22 -20
- data/src/Color.cpp +12 -9
- data/src/EmptyImageData.hpp +15 -17
- data/src/FileUnix.cpp +1 -1
- data/src/FileWin.cpp +1 -1
- data/src/Font.cpp +48 -53
- data/src/Graphics.cpp +135 -143
- data/src/Image.cpp +41 -42
- data/src/Input.cpp +1 -1
- data/src/InputUIKit.cpp +1 -1
- data/src/LargeImageData.cpp +108 -101
- data/src/LargeImageData.hpp +17 -15
- data/src/Log.hpp +6 -6
- data/src/Macro.cpp +35 -37
- data/src/Macro.hpp +11 -11
- data/src/Math.cpp +8 -1
- data/src/Resolution.cpp +12 -7
- data/src/RubyGosu.cxx +5 -5
- data/src/TexChunk.cpp +50 -41
- data/src/TexChunk.hpp +22 -22
- data/src/Text.cpp +37 -37
- data/src/TextBuilder.cpp +60 -57
- data/src/TextBuilder.hpp +20 -20
- data/src/TextInput.cpp +127 -135
- data/src/TrueTypeFont.cpp +107 -107
- data/src/TrueTypeFont.hpp +39 -38
- data/src/TrueTypeFontApple.cpp +19 -22
- data/src/TrueTypeFontUnix.cpp +21 -26
- data/src/TrueTypeFontWin.cpp +30 -30
- data/src/Window.cpp +95 -86
- data/src/WindowUIKit.cpp +46 -49
- metadata +7 -17
- data/dependencies/SDL/include/SDL_config_os2.h +0 -188
- data/dependencies/SDL_sound/libmodplug/load_abc.c +0 -4725
- data/dependencies/SDL_sound/libmodplug/load_mid.c +0 -1405
- data/dependencies/SDL_sound/libmodplug/load_pat.c +0 -1143
- data/dependencies/SDL_sound/libmodplug/load_pat.h +0 -25
- data/dependencies/al_soft/AL/alext.h +0 -585
- data/dependencies/al_soft/AL/efx-creative.h +0 -3
- data/dependencies/al_soft/AL/efx-presets.h +0 -402
- data/dependencies/al_soft/AL/efx.h +0 -762
- data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
- data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
- data/lib/OpenAL32.dll +0 -0
- data/lib64/OpenAL32.dll +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
// (this code is from https://github.com/mackron/dr_libs/blob/master/dr_flac.h ... ---ryan.)
|
2
2
|
// FLAC audio decoder. Public domain. See "unlicense" statement at the end of this file.
|
3
|
-
// dr_flac - v0.
|
3
|
+
// dr_flac - v0.10.0 - 2018-09-11
|
4
4
|
//
|
5
5
|
// David Reid - mackron@gmail.com
|
6
6
|
|
@@ -81,16 +81,11 @@
|
|
81
81
|
// #define these options before including this file.
|
82
82
|
//
|
83
83
|
// #define DR_FLAC_NO_STDIO
|
84
|
-
// Disable drflac_open_file().
|
84
|
+
// Disable drflac_open_file() and family.
|
85
85
|
//
|
86
86
|
// #define DR_FLAC_NO_OGG
|
87
87
|
// Disables support for Ogg/FLAC streams.
|
88
88
|
//
|
89
|
-
// #define DR_FLAC_NO_WIN32_IO
|
90
|
-
// In the Win32 build, dr_flac uses the Win32 IO APIs for drflac_open_file() by default. This setting will make it use the
|
91
|
-
// standard FILE APIs instead. Ignored when DR_FLAC_NO_STDIO is #defined. (The rationale for this configuration is that
|
92
|
-
// there's a bug in one compiler's Win32 implementation of the FILE APIs which is not present in the Win32 IO APIs.)
|
93
|
-
//
|
94
89
|
// #define DR_FLAC_BUFFER_SIZE <number>
|
95
90
|
// Defines the size of the internal buffer to store data from onRead(). This buffer is used to reduce the number of calls
|
96
91
|
// back to the client for more data. Larger values means more memory, but better performance. My tests show diminishing
|
@@ -110,8 +105,6 @@
|
|
110
105
|
// - dr_flac does not currently support changing the sample rate nor channel count mid stream.
|
111
106
|
// - Audio data is output as signed 32-bit PCM, regardless of the bits per sample the FLAC stream is encoded as.
|
112
107
|
// - This has not been tested on big-endian architectures.
|
113
|
-
// - Rice codes in unencoded binary form (see https://xiph.org/flac/format.html#rice_partition) has not been tested. If anybody
|
114
|
-
// knows where I can find some test files for this, let me know.
|
115
108
|
// - dr_flac is not thread-safe, but its APIs can be called from any thread so long as you do your own synchronization.
|
116
109
|
// - When using Ogg encapsulation, a corrupted metadata block will result in drflac_open_with_metadata() and drflac_open()
|
117
110
|
// returning inconsistent samples.
|
@@ -167,15 +160,9 @@ extern "C" {
|
|
167
160
|
#endif
|
168
161
|
|
169
162
|
// Check if we can enable 64-bit optimizations.
|
170
|
-
#if defined(_WIN64)
|
171
|
-
#define DRFLAC_64BIT
|
172
|
-
#endif
|
173
|
-
|
174
|
-
#if defined(__GNUC__)
|
175
|
-
#if defined(__x86_64__) || defined(__ppc64__)
|
163
|
+
#if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
|
176
164
|
#define DRFLAC_64BIT
|
177
165
|
#endif
|
178
|
-
#endif
|
179
166
|
|
180
167
|
#ifdef DRFLAC_64BIT
|
181
168
|
typedef drflac_uint64 drflac_cache_t;
|
@@ -292,7 +279,7 @@ typedef struct
|
|
292
279
|
drflac_uint32 vendorLength;
|
293
280
|
const char* vendor;
|
294
281
|
drflac_uint32 commentCount;
|
295
|
-
const
|
282
|
+
const void* pComments;
|
296
283
|
} vorbis_comment;
|
297
284
|
|
298
285
|
struct
|
@@ -301,7 +288,7 @@ typedef struct
|
|
301
288
|
drflac_uint64 leadInSampleCount;
|
302
289
|
drflac_bool32 isCD;
|
303
290
|
drflac_uint8 trackCount;
|
304
|
-
const
|
291
|
+
const void* pTrackData;
|
305
292
|
} cuesheet;
|
306
293
|
|
307
294
|
struct
|
@@ -744,13 +731,49 @@ typedef struct
|
|
744
731
|
|
745
732
|
// Initializes a vorbis comment iterator. This can be used for iterating over the vorbis comments in a VORBIS_COMMENT
|
746
733
|
// metadata block.
|
747
|
-
void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const
|
734
|
+
void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments);
|
748
735
|
|
749
736
|
// Goes to the next vorbis comment in the given iterator. If null is returned it means there are no more comments. The
|
750
737
|
// returned string is NOT null terminated.
|
751
738
|
const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut);
|
752
739
|
|
753
740
|
|
741
|
+
// Structure representing an iterator for cuesheet tracks in a CUESHEET metadata block.
|
742
|
+
typedef struct
|
743
|
+
{
|
744
|
+
drflac_uint32 countRemaining;
|
745
|
+
const char* pRunningData;
|
746
|
+
} drflac_cuesheet_track_iterator;
|
747
|
+
|
748
|
+
// Packing is important on this structure because we map this directly to the raw data within the CUESHEET metadata block.
|
749
|
+
#pragma pack(4)
|
750
|
+
typedef struct
|
751
|
+
{
|
752
|
+
drflac_uint64 offset;
|
753
|
+
drflac_uint8 index;
|
754
|
+
drflac_uint8 reserved[3];
|
755
|
+
} drflac_cuesheet_track_index;
|
756
|
+
#pragma pack()
|
757
|
+
|
758
|
+
typedef struct
|
759
|
+
{
|
760
|
+
drflac_uint64 offset;
|
761
|
+
drflac_uint8 trackNumber;
|
762
|
+
char ISRC[12];
|
763
|
+
drflac_bool8 isAudio;
|
764
|
+
drflac_bool8 preEmphasis;
|
765
|
+
drflac_uint8 indexCount;
|
766
|
+
const drflac_cuesheet_track_index* pIndexPoints;
|
767
|
+
} drflac_cuesheet_track;
|
768
|
+
|
769
|
+
// Initializes a cuesheet track iterator. This can be used for iterating over the cuesheet tracks in a CUESHEET metadata
|
770
|
+
// block.
|
771
|
+
void drflac_init_cuesheet_track_iterator(drflac_cuesheet_track_iterator* pIter, drflac_uint32 trackCount, const void* pTrackData);
|
772
|
+
|
773
|
+
// Goes to the next cuesheet track in the given iterator. If DRFLAC_FALSE is returned it means there are no more comments.
|
774
|
+
drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator* pIter, drflac_cuesheet_track* pCuesheetTrack);
|
775
|
+
|
776
|
+
|
754
777
|
|
755
778
|
#ifdef __cplusplus
|
756
779
|
}
|
@@ -764,16 +787,26 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, dr
|
|
764
787
|
//
|
765
788
|
///////////////////////////////////////////////////////////////////////////////
|
766
789
|
#ifdef DR_FLAC_IMPLEMENTATION
|
790
|
+
#ifdef __linux__
|
791
|
+
#ifndef _BSD_SOURCE
|
792
|
+
#define _BSD_SOURCE
|
793
|
+
#endif
|
794
|
+
#ifndef __USE_BSD
|
795
|
+
#define __USE_BSD
|
796
|
+
#endif
|
797
|
+
#include <endian.h>
|
798
|
+
#endif
|
799
|
+
|
767
800
|
#include <stdlib.h>
|
768
801
|
#include <string.h>
|
769
802
|
|
770
803
|
// CPU architecture.
|
771
804
|
#if defined(__x86_64__) || defined(_M_X64)
|
772
|
-
#define DRFLAC_X64
|
805
|
+
#define DRFLAC_X64
|
773
806
|
#elif defined(__i386) || defined(_M_IX86)
|
774
|
-
#define DRFLAC_X86
|
807
|
+
#define DRFLAC_X86
|
775
808
|
#elif defined(__arm__) || defined(_M_ARM)
|
776
|
-
#define DRFLAC_ARM
|
809
|
+
#define DRFLAC_ARM
|
777
810
|
#endif
|
778
811
|
|
779
812
|
// Compile-time CPU feature support.
|
@@ -786,48 +819,92 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, dr
|
|
786
819
|
__cpuid(info, fid);
|
787
820
|
}
|
788
821
|
#else
|
789
|
-
|
822
|
+
#define DRFLAC_NO_CPUID
|
790
823
|
#endif
|
791
824
|
#else
|
792
825
|
#if defined(__GNUC__) || defined(__clang__)
|
793
826
|
static void drflac__cpuid(int info[4], int fid)
|
794
827
|
{
|
795
|
-
|
796
|
-
|
797
|
-
|
828
|
+
// It looks like the -fPIC option uses the ebx register which GCC complains about. We can work around this by just using a different register, the
|
829
|
+
// specific register of which I'm letting the compiler decide on. The "k" prefix is used to specify a 32-bit register. The {...} syntax is for
|
830
|
+
// supporting different assembly dialects.
|
831
|
+
//
|
832
|
+
// What's basically happening is that we're saving and restoring the ebx register manually.
|
833
|
+
#if defined(DRFLAC_X86) && defined(__PIC__)
|
834
|
+
__asm__ __volatile__ (
|
835
|
+
"xchg{l} {%%}ebx, %k1;"
|
836
|
+
"cpuid;"
|
837
|
+
"xchg{l} {%%}ebx, %k1;"
|
838
|
+
: "=a"(info[0]), "=&r"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0)
|
839
|
+
);
|
840
|
+
#else
|
841
|
+
__asm__ __volatile__ (
|
842
|
+
"cpuid" : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0)
|
843
|
+
);
|
844
|
+
#endif
|
798
845
|
}
|
799
846
|
#else
|
800
|
-
|
847
|
+
#define DRFLAC_NO_CPUID
|
801
848
|
#endif
|
802
849
|
#endif
|
803
850
|
#else
|
804
|
-
#define DRFLAC_NO_CPUID
|
851
|
+
#define DRFLAC_NO_CPUID
|
805
852
|
#endif
|
806
853
|
|
807
854
|
|
808
|
-
#ifdef __linux__
|
809
|
-
#define _BSD_SOURCE
|
810
|
-
#include <endian.h>
|
811
|
-
#endif
|
812
|
-
|
813
855
|
#if defined(_MSC_VER) && _MSC_VER >= 1500 && (defined(DRFLAC_X86) || defined(DRFLAC_X64))
|
814
|
-
#define DRFLAC_HAS_LZCNT_INTRINSIC
|
856
|
+
#define DRFLAC_HAS_LZCNT_INTRINSIC
|
815
857
|
#elif (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))
|
816
|
-
#define DRFLAC_HAS_LZCNT_INTRINSIC
|
858
|
+
#define DRFLAC_HAS_LZCNT_INTRINSIC
|
817
859
|
#elif defined(__clang__)
|
818
860
|
#if __has_builtin(__builtin_clzll) || __has_builtin(__builtin_clzl)
|
819
|
-
|
861
|
+
#define DRFLAC_HAS_LZCNT_INTRINSIC
|
820
862
|
#endif
|
821
863
|
#endif
|
822
864
|
|
823
865
|
#if defined(_MSC_VER) && _MSC_VER >= 1300
|
824
|
-
#define
|
825
|
-
#
|
826
|
-
#define
|
866
|
+
#define DRFLAC_HAS_BYTESWAP16_INTRINSIC
|
867
|
+
#define DRFLAC_HAS_BYTESWAP32_INTRINSIC
|
868
|
+
#define DRFLAC_HAS_BYTESWAP64_INTRINSIC
|
827
869
|
#elif defined(__clang__)
|
828
|
-
#if __has_builtin(__builtin_bswap16)
|
829
|
-
|
870
|
+
#if __has_builtin(__builtin_bswap16)
|
871
|
+
#define DRFLAC_HAS_BYTESWAP16_INTRINSIC
|
872
|
+
#endif
|
873
|
+
#if __has_builtin(__builtin_bswap32)
|
874
|
+
#define DRFLAC_HAS_BYTESWAP32_INTRINSIC
|
875
|
+
#endif
|
876
|
+
#if __has_builtin(__builtin_bswap64)
|
877
|
+
#define DRFLAC_HAS_BYTESWAP64_INTRINSIC
|
878
|
+
#endif
|
879
|
+
#elif defined(__GNUC__)
|
880
|
+
#if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
881
|
+
#define DRFLAC_HAS_BYTESWAP32_INTRINSIC
|
882
|
+
#define DRFLAC_HAS_BYTESWAP64_INTRINSIC
|
830
883
|
#endif
|
884
|
+
#if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
|
885
|
+
#define DRFLAC_HAS_BYTESWAP16_INTRINSIC
|
886
|
+
#endif
|
887
|
+
#elif defined(__WATCOMC__) && defined(__386__)
|
888
|
+
#define DRFLAC_HAS_BYTESWAP16_INTRINSIC
|
889
|
+
#define DRFLAC_HAS_BYTESWAP32_INTRINSIC
|
890
|
+
#define DRFLAC_HAS_BYTESWAP64_INTRINSIC
|
891
|
+
extern __inline drflac_uint16 _watcom_bswap16(drflac_uint16);
|
892
|
+
extern __inline drflac_uint32 _watcom_bswap32(drflac_uint32);
|
893
|
+
extern __inline drflac_uint64 _watcom_bswap64(drflac_uint64);
|
894
|
+
#pragma aux _watcom_bswap16 = \
|
895
|
+
"xchg al, ah" \
|
896
|
+
parm [ax] \
|
897
|
+
modify [ax];
|
898
|
+
#pragma aux _watcom_bswap32 = \
|
899
|
+
"bswap eax" \
|
900
|
+
parm [eax] \
|
901
|
+
modify [eax];
|
902
|
+
#pragma aux _watcom_bswap64 = \
|
903
|
+
"bswap eax" \
|
904
|
+
"bswap edx" \
|
905
|
+
"xchg eax,edx" \
|
906
|
+
parm [eax edx] \
|
907
|
+
modify [eax edx];
|
831
908
|
#endif
|
832
909
|
|
833
910
|
|
@@ -859,6 +936,8 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, dr
|
|
859
936
|
#else
|
860
937
|
#ifdef __GNUC__
|
861
938
|
#define DRFLAC_INLINE inline __attribute__((always_inline))
|
939
|
+
#elif defined(__WATCOMC__)
|
940
|
+
#define DRFLAC_INLINE __inline
|
862
941
|
#else
|
863
942
|
#define DRFLAC_INLINE inline
|
864
943
|
#endif
|
@@ -893,7 +972,9 @@ typedef drflac_int32 drflac_result;
|
|
893
972
|
|
894
973
|
|
895
974
|
// CPU caps.
|
975
|
+
#if defined(DRFLAC_HAS_LZCNT_INTRINSIC)
|
896
976
|
static drflac_bool32 drflac__gIsLZCNTSupported = DRFLAC_FALSE;
|
977
|
+
#endif
|
897
978
|
#ifndef DRFLAC_NO_CPUID
|
898
979
|
static drflac_bool32 drflac__gIsSSE42Supported = DRFLAC_FALSE;
|
899
980
|
static void drflac__init_cpu_caps()
|
@@ -902,8 +983,10 @@ static void drflac__init_cpu_caps()
|
|
902
983
|
drflac_zero_memory(info, sizeof (info));
|
903
984
|
|
904
985
|
// LZCNT
|
986
|
+
#if defined(DRFLAC_HAS_LZCNT_INTRINSIC)
|
905
987
|
drflac__cpuid(info, 0x80000001);
|
906
988
|
drflac__gIsLZCNTSupported = (info[2] & (1 << 5)) != 0;
|
989
|
+
#endif
|
907
990
|
|
908
991
|
// SSE4.2
|
909
992
|
drflac__cpuid(info, 1);
|
@@ -925,11 +1008,13 @@ static DRFLAC_INLINE drflac_bool32 drflac__is_little_endian()
|
|
925
1008
|
|
926
1009
|
static DRFLAC_INLINE drflac_uint16 drflac__swap_endian_uint16(drflac_uint16 n)
|
927
1010
|
{
|
928
|
-
#ifdef
|
1011
|
+
#ifdef DRFLAC_HAS_BYTESWAP16_INTRINSIC
|
929
1012
|
#if defined(_MSC_VER)
|
930
1013
|
return _byteswap_ushort(n);
|
931
1014
|
#elif defined(__GNUC__) || defined(__clang__)
|
932
1015
|
return __builtin_bswap16(n);
|
1016
|
+
#elif defined(__WATCOMC__) && defined(__386__)
|
1017
|
+
return _watcom_bswap16(n);
|
933
1018
|
#else
|
934
1019
|
#error "This compiler does not support the byte swap intrinsic."
|
935
1020
|
#endif
|
@@ -941,11 +1026,13 @@ static DRFLAC_INLINE drflac_uint16 drflac__swap_endian_uint16(drflac_uint16 n)
|
|
941
1026
|
|
942
1027
|
static DRFLAC_INLINE drflac_uint32 drflac__swap_endian_uint32(drflac_uint32 n)
|
943
1028
|
{
|
944
|
-
#ifdef
|
1029
|
+
#ifdef DRFLAC_HAS_BYTESWAP32_INTRINSIC
|
945
1030
|
#if defined(_MSC_VER)
|
946
1031
|
return _byteswap_ulong(n);
|
947
1032
|
#elif defined(__GNUC__) || defined(__clang__)
|
948
1033
|
return __builtin_bswap32(n);
|
1034
|
+
#elif defined(__WATCOMC__) && defined(__386__)
|
1035
|
+
return _watcom_bswap32(n);
|
949
1036
|
#else
|
950
1037
|
#error "This compiler does not support the byte swap intrinsic."
|
951
1038
|
#endif
|
@@ -959,11 +1046,13 @@ static DRFLAC_INLINE drflac_uint32 drflac__swap_endian_uint32(drflac_uint32 n)
|
|
959
1046
|
|
960
1047
|
static DRFLAC_INLINE drflac_uint64 drflac__swap_endian_uint64(drflac_uint64 n)
|
961
1048
|
{
|
962
|
-
#ifdef
|
1049
|
+
#ifdef DRFLAC_HAS_BYTESWAP64_INTRINSIC
|
963
1050
|
#if defined(_MSC_VER)
|
964
1051
|
return _byteswap_uint64(n);
|
965
1052
|
#elif defined(__GNUC__) || defined(__clang__)
|
966
1053
|
return __builtin_bswap64(n);
|
1054
|
+
#elif defined(__WATCOMC__) && defined(__386__)
|
1055
|
+
return _watcom_bswap64(n);
|
967
1056
|
#else
|
968
1057
|
#error "This compiler does not support the byte swap intrinsic."
|
969
1058
|
#endif
|
@@ -1277,20 +1366,17 @@ static DRFLAC_INLINE drflac_uint16 drflac_crc16(drflac_uint16 crc, drflac_cache_
|
|
1277
1366
|
// is a 32- or 64-bit unsigned integer (depending on whether or not a 32- or 64-bit build is being compiled) and the L2 is an
|
1278
1367
|
// array of "cache lines", with each cache line being the same size as the L1. The L2 is a buffer of about 4KB and is where data
|
1279
1368
|
// from onRead() is read into.
|
1280
|
-
#define DRFLAC_CACHE_L1_SIZE_BYTES(bs)
|
1281
|
-
#define DRFLAC_CACHE_L1_SIZE_BITS(bs)
|
1282
|
-
#define DRFLAC_CACHE_L1_BITS_REMAINING(bs)
|
1283
|
-
#
|
1284
|
-
#define
|
1285
|
-
#
|
1286
|
-
#define
|
1287
|
-
#
|
1288
|
-
#define
|
1289
|
-
#define
|
1290
|
-
#define
|
1291
|
-
#define DRFLAC_CACHE_L2_SIZE_BYTES(bs) (sizeof((bs)->cacheL2))
|
1292
|
-
#define DRFLAC_CACHE_L2_LINE_COUNT(bs) (DRFLAC_CACHE_L2_SIZE_BYTES(bs) / sizeof((bs)->cacheL2[0]))
|
1293
|
-
#define DRFLAC_CACHE_L2_LINES_REMAINING(bs) (DRFLAC_CACHE_L2_LINE_COUNT(bs) - (bs)->nextL2Line)
|
1369
|
+
#define DRFLAC_CACHE_L1_SIZE_BYTES(bs) (sizeof((bs)->cache))
|
1370
|
+
#define DRFLAC_CACHE_L1_SIZE_BITS(bs) (sizeof((bs)->cache)*8)
|
1371
|
+
#define DRFLAC_CACHE_L1_BITS_REMAINING(bs) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (bs)->consumedBits)
|
1372
|
+
#define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~((~(drflac_cache_t)0) >> (_bitCount)))
|
1373
|
+
#define DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (_bitCount))
|
1374
|
+
#define DRFLAC_CACHE_L1_SELECT(bs, _bitCount) (((bs)->cache) & DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount))
|
1375
|
+
#define DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SELECT((bs), (_bitCount)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT((bs), (_bitCount)))
|
1376
|
+
#define DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, _bitCount)(DRFLAC_CACHE_L1_SELECT((bs), (_bitCount)) >> (DRFLAC_CACHE_L1_SELECTION_SHIFT((bs), (_bitCount)) & (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1)))
|
1377
|
+
#define DRFLAC_CACHE_L2_SIZE_BYTES(bs) (sizeof((bs)->cacheL2))
|
1378
|
+
#define DRFLAC_CACHE_L2_LINE_COUNT(bs) (DRFLAC_CACHE_L2_SIZE_BYTES(bs) / sizeof((bs)->cacheL2[0]))
|
1379
|
+
#define DRFLAC_CACHE_L2_LINES_REMAINING(bs) (DRFLAC_CACHE_L2_LINE_COUNT(bs) - (bs)->nextL2Line)
|
1294
1380
|
|
1295
1381
|
|
1296
1382
|
#ifndef DR_FLAC_NO_CRC
|
@@ -1402,6 +1488,7 @@ static drflac_bool32 drflac__reload_cache(drflac_bs* bs)
|
|
1402
1488
|
// data from the unaligned cache.
|
1403
1489
|
size_t bytesRead = bs->unalignedByteCount;
|
1404
1490
|
if (bytesRead == 0) {
|
1491
|
+
bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs); // <-- The stream has been exhausted, so marked the bits as consumed.
|
1405
1492
|
return DRFLAC_FALSE;
|
1406
1493
|
}
|
1407
1494
|
|
@@ -1409,7 +1496,7 @@ static drflac_bool32 drflac__reload_cache(drflac_bs* bs)
|
|
1409
1496
|
bs->consumedBits = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bytesRead) * 8;
|
1410
1497
|
|
1411
1498
|
bs->cache = drflac__be2host__cache_line(bs->unalignedCache);
|
1412
|
-
bs->cache &= DRFLAC_CACHE_L1_SELECTION_MASK(
|
1499
|
+
bs->cache &= DRFLAC_CACHE_L1_SELECTION_MASK(DRFLAC_CACHE_L1_BITS_REMAINING(bs)); // <-- Make sure the consumed bits are always set to zero. Other parts of the library depend on this property.
|
1413
1500
|
bs->unalignedByteCount = 0; // <-- At this point the unaligned bytes have been moved into the cache and we thus have no more unaligned bytes.
|
1414
1501
|
|
1415
1502
|
#ifndef DR_FLAC_NO_CRC
|
@@ -1448,15 +1535,26 @@ static DRFLAC_INLINE drflac_bool32 drflac__read_uint32(drflac_bs* bs, unsigned i
|
|
1448
1535
|
}
|
1449
1536
|
|
1450
1537
|
if (bitCount <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
|
1538
|
+
// If we want to load all 32-bits from a 32-bit cache we need to do it slightly differently because we can't do
|
1539
|
+
// a 32-bit shift on a 32-bit integer. This will never be the case on 64-bit caches, so we can have a slightly
|
1540
|
+
// more optimal solution for this.
|
1541
|
+
#ifdef DRFLAC_64BIT
|
1542
|
+
*pResultOut = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount);
|
1543
|
+
bs->consumedBits += bitCount;
|
1544
|
+
bs->cache <<= bitCount;
|
1545
|
+
#else
|
1451
1546
|
if (bitCount < DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
|
1452
1547
|
*pResultOut = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount);
|
1453
1548
|
bs->consumedBits += bitCount;
|
1454
1549
|
bs->cache <<= bitCount;
|
1455
1550
|
} else {
|
1551
|
+
// Cannot shift by 32-bits, so need to do it differently.
|
1456
1552
|
*pResultOut = (drflac_uint32)bs->cache;
|
1457
1553
|
bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs);
|
1458
1554
|
bs->cache = 0;
|
1459
1555
|
}
|
1556
|
+
#endif
|
1557
|
+
|
1460
1558
|
return DRFLAC_TRUE;
|
1461
1559
|
} else {
|
1462
1560
|
// It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them.
|
@@ -1704,6 +1802,9 @@ static drflac_bool32 drflac__find_and_seek_to_next_sync_code(drflac_bs* bs)
|
|
1704
1802
|
#if defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(DRFLAC_X64) || defined(DRFLAC_X86))
|
1705
1803
|
#define DRFLAC_IMPLEMENT_CLZ_MSVC
|
1706
1804
|
#endif
|
1805
|
+
#if defined(__WATCOMC__) && defined(__386__)
|
1806
|
+
#define DRFLAC_IMPLEMENT_CLZ_WATCOM
|
1807
|
+
#endif
|
1707
1808
|
|
1708
1809
|
static DRFLAC_INLINE drflac_uint32 drflac__clz_software(drflac_cache_t x)
|
1709
1810
|
{
|
@@ -1768,6 +1869,8 @@ static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x)
|
|
1768
1869
|
#endif
|
1769
1870
|
|
1770
1871
|
#ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
|
1872
|
+
#include <intrin.h> // For BitScanReverse().
|
1873
|
+
|
1771
1874
|
static DRFLAC_INLINE drflac_uint32 drflac__clz_msvc(drflac_cache_t x)
|
1772
1875
|
{
|
1773
1876
|
drflac_uint32 n;
|
@@ -1780,6 +1883,16 @@ static DRFLAC_INLINE drflac_uint32 drflac__clz_msvc(drflac_cache_t x)
|
|
1780
1883
|
}
|
1781
1884
|
#endif
|
1782
1885
|
|
1886
|
+
#ifdef DRFLAC_IMPLEMENT_CLZ_WATCOM
|
1887
|
+
static __inline drflac_uint32 drflac__clz_watcom (drflac_uint32);
|
1888
|
+
#pragma aux drflac__clz_watcom = \
|
1889
|
+
"bsr eax, eax" \
|
1890
|
+
"xor eax, 31" \
|
1891
|
+
parm [eax] nomemory \
|
1892
|
+
value [eax] \
|
1893
|
+
modify exact [eax] nomemory;
|
1894
|
+
#endif
|
1895
|
+
|
1783
1896
|
static DRFLAC_INLINE drflac_uint32 drflac__clz(drflac_cache_t x)
|
1784
1897
|
{
|
1785
1898
|
// This function assumes at least one bit is set. Checking for 0 needs to be done at a higher level, outside this function.
|
@@ -1789,11 +1902,13 @@ static DRFLAC_INLINE drflac_uint32 drflac__clz(drflac_cache_t x)
|
|
1789
1902
|
} else
|
1790
1903
|
#endif
|
1791
1904
|
{
|
1792
|
-
|
1905
|
+
#ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
|
1793
1906
|
return drflac__clz_msvc(x);
|
1794
|
-
|
1907
|
+
#elif defined(DRFLAC_IMPLEMENT_CLZ_WATCOM)
|
1908
|
+
return drflac__clz_watcom(x);
|
1909
|
+
#else
|
1795
1910
|
return drflac__clz_software(x);
|
1796
|
-
|
1911
|
+
#endif
|
1797
1912
|
}
|
1798
1913
|
}
|
1799
1914
|
|
@@ -2235,9 +2350,9 @@ static drflac_bool32 drflac__read_rice_parts__reference(drflac_bs* bs, drflac_ui
|
|
2235
2350
|
|
2236
2351
|
static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
|
2237
2352
|
{
|
2238
|
-
|
2239
|
-
drflac_cache_t resultHiShift = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParam;
|
2353
|
+
drflac_assert(riceParam > 0); // <-- riceParam should never be 0. drflac__read_rice_parts__param_equals_zero() should be used instead for this case.
|
2240
2354
|
|
2355
|
+
drflac_cache_t riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParam);
|
2241
2356
|
|
2242
2357
|
drflac_uint32 zeroCounter = 0;
|
2243
2358
|
while (bs->cache == 0) {
|
@@ -2255,29 +2370,27 @@ static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts(drflac_bs* bs, drflac
|
|
2255
2370
|
drflac_uint32 riceParamPart;
|
2256
2371
|
drflac_uint32 riceLength = setBitOffsetPlus1 + riceParam;
|
2257
2372
|
if (riceLength < DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
|
2258
|
-
riceParamPart = (drflac_uint32)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> (
|
2373
|
+
riceParamPart = (drflac_uint32)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceLength));
|
2259
2374
|
|
2260
2375
|
bs->consumedBits += riceLength;
|
2261
2376
|
bs->cache <<= riceLength;
|
2262
2377
|
} else {
|
2263
2378
|
bs->consumedBits += riceLength;
|
2264
|
-
if (setBitOffsetPlus1 < DRFLAC_CACHE_L1_SIZE_BITS(bs)) {
|
2265
|
-
bs->cache <<= setBitOffsetPlus1;
|
2266
|
-
}
|
2379
|
+
bs->cache <<= setBitOffsetPlus1 & (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1); // <-- Equivalent to "if (setBitOffsetPlus1 < DRFLAC_CACHE_L1_SIZE_BITS(bs)) { bs->cache <<= setBitOffsetPlus1; }"
|
2267
2380
|
|
2268
2381
|
// It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them.
|
2269
2382
|
drflac_uint32 bitCountLo = bs->consumedBits - DRFLAC_CACHE_L1_SIZE_BITS(bs);
|
2270
|
-
drflac_cache_t resultHi = bs
|
2383
|
+
drflac_cache_t resultHi = DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, riceParam); // <-- Use DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE() if ever this function allows riceParam=0.
|
2271
2384
|
|
2272
2385
|
if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
|
2273
|
-
|
2386
|
+
#ifndef DR_FLAC_NO_CRC
|
2274
2387
|
drflac__update_crc16(bs);
|
2275
|
-
|
2388
|
+
#endif
|
2276
2389
|
bs->cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
|
2277
2390
|
bs->consumedBits = 0;
|
2278
|
-
|
2391
|
+
#ifndef DR_FLAC_NO_CRC
|
2279
2392
|
bs->crc16Cache = bs->cache;
|
2280
|
-
|
2393
|
+
#endif
|
2281
2394
|
} else {
|
2282
2395
|
// Slow path. We need to fetch more data from the client.
|
2283
2396
|
if (!drflac__reload_cache(bs)) {
|
@@ -2285,7 +2398,62 @@ static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts(drflac_bs* bs, drflac
|
|
2285
2398
|
}
|
2286
2399
|
}
|
2287
2400
|
|
2288
|
-
riceParamPart = (drflac_uint32)(
|
2401
|
+
riceParamPart = (drflac_uint32)(resultHi | DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, bitCountLo));
|
2402
|
+
|
2403
|
+
bs->consumedBits += bitCountLo;
|
2404
|
+
bs->cache <<= bitCountLo;
|
2405
|
+
}
|
2406
|
+
|
2407
|
+
*pZeroCounterOut = zeroCounter;
|
2408
|
+
*pRiceParamPartOut = riceParamPart;
|
2409
|
+
return DRFLAC_TRUE;
|
2410
|
+
}
|
2411
|
+
|
2412
|
+
static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts__param_equals_zero(drflac_bs* bs, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut)
|
2413
|
+
{
|
2414
|
+
drflac_cache_t riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(0);
|
2415
|
+
|
2416
|
+
drflac_uint32 zeroCounter = 0;
|
2417
|
+
while (bs->cache == 0) {
|
2418
|
+
zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs);
|
2419
|
+
if (!drflac__reload_cache(bs)) {
|
2420
|
+
return DRFLAC_FALSE;
|
2421
|
+
}
|
2422
|
+
}
|
2423
|
+
|
2424
|
+
drflac_uint32 setBitOffsetPlus1 = drflac__clz(bs->cache);
|
2425
|
+
zeroCounter += setBitOffsetPlus1;
|
2426
|
+
setBitOffsetPlus1 += 1;
|
2427
|
+
|
2428
|
+
|
2429
|
+
drflac_uint32 riceParamPart;
|
2430
|
+
drflac_uint32 riceLength = setBitOffsetPlus1;
|
2431
|
+
if (riceLength < DRFLAC_CACHE_L1_BITS_REMAINING(bs)) {
|
2432
|
+
riceParamPart = (drflac_uint32)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceLength));
|
2433
|
+
|
2434
|
+
bs->consumedBits += riceLength;
|
2435
|
+
bs->cache <<= riceLength;
|
2436
|
+
} else {
|
2437
|
+
// It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them.
|
2438
|
+
drflac_uint32 bitCountLo = riceLength + bs->consumedBits - DRFLAC_CACHE_L1_SIZE_BITS(bs);
|
2439
|
+
|
2440
|
+
if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) {
|
2441
|
+
#ifndef DR_FLAC_NO_CRC
|
2442
|
+
drflac__update_crc16(bs);
|
2443
|
+
#endif
|
2444
|
+
bs->cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
|
2445
|
+
bs->consumedBits = 0;
|
2446
|
+
#ifndef DR_FLAC_NO_CRC
|
2447
|
+
bs->crc16Cache = bs->cache;
|
2448
|
+
#endif
|
2449
|
+
} else {
|
2450
|
+
// Slow path. We need to fetch more data from the client.
|
2451
|
+
if (!drflac__reload_cache(bs)) {
|
2452
|
+
return DRFLAC_FALSE;
|
2453
|
+
}
|
2454
|
+
}
|
2455
|
+
|
2456
|
+
riceParamPart = (drflac_uint32)(DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, bitCountLo));
|
2289
2457
|
|
2290
2458
|
bs->consumedBits += bitCountLo;
|
2291
2459
|
bs->cache <<= bitCountLo;
|
@@ -2376,12 +2544,94 @@ static drflac_bool32 drflac__decode_samples_with_residual__rice__simple(drflac_b
|
|
2376
2544
|
return DRFLAC_TRUE;
|
2377
2545
|
}
|
2378
2546
|
|
2547
|
+
static drflac_bool32 drflac__decode_samples_with_residual__rice__param_equals_zero(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut)
|
2548
|
+
{
|
2549
|
+
drflac_assert(bs != NULL);
|
2550
|
+
drflac_assert(count > 0);
|
2551
|
+
drflac_assert(pSamplesOut != NULL);
|
2552
|
+
|
2553
|
+
static drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF};
|
2554
|
+
|
2555
|
+
drflac_uint32 zeroCountPart0;
|
2556
|
+
drflac_uint32 zeroCountPart1;
|
2557
|
+
drflac_uint32 zeroCountPart2;
|
2558
|
+
drflac_uint32 zeroCountPart3;
|
2559
|
+
drflac_uint32 riceParamPart0;
|
2560
|
+
drflac_uint32 riceParamPart1;
|
2561
|
+
drflac_uint32 riceParamPart2;
|
2562
|
+
drflac_uint32 riceParamPart3;
|
2563
|
+
drflac_uint32 i4 = 0;
|
2564
|
+
drflac_uint32 count4 = count >> 2;
|
2565
|
+
while (i4 < count4) {
|
2566
|
+
// Rice extraction.
|
2567
|
+
if (!drflac__read_rice_parts__param_equals_zero(bs, &zeroCountPart0, &riceParamPart0) ||
|
2568
|
+
!drflac__read_rice_parts__param_equals_zero(bs, &zeroCountPart1, &riceParamPart1) ||
|
2569
|
+
!drflac__read_rice_parts__param_equals_zero(bs, &zeroCountPart2, &riceParamPart2) ||
|
2570
|
+
!drflac__read_rice_parts__param_equals_zero(bs, &zeroCountPart3, &riceParamPart3)) {
|
2571
|
+
return DRFLAC_FALSE;
|
2572
|
+
}
|
2573
|
+
|
2574
|
+
riceParamPart0 |= zeroCountPart0;
|
2575
|
+
riceParamPart1 |= zeroCountPart1;
|
2576
|
+
riceParamPart2 |= zeroCountPart2;
|
2577
|
+
riceParamPart3 |= zeroCountPart3;
|
2578
|
+
|
2579
|
+
riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
|
2580
|
+
riceParamPart1 = (riceParamPart1 >> 1) ^ t[riceParamPart1 & 0x01];
|
2581
|
+
riceParamPart2 = (riceParamPart2 >> 1) ^ t[riceParamPart2 & 0x01];
|
2582
|
+
riceParamPart3 = (riceParamPart3 >> 1) ^ t[riceParamPart3 & 0x01];
|
2583
|
+
|
2584
|
+
if (bitsPerSample > 16) {
|
2585
|
+
pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 0);
|
2586
|
+
pSamplesOut[1] = riceParamPart1 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 1);
|
2587
|
+
pSamplesOut[2] = riceParamPart2 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 2);
|
2588
|
+
pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 3);
|
2589
|
+
} else {
|
2590
|
+
pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 0);
|
2591
|
+
pSamplesOut[1] = riceParamPart1 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 1);
|
2592
|
+
pSamplesOut[2] = riceParamPart2 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 2);
|
2593
|
+
pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 3);
|
2594
|
+
}
|
2595
|
+
|
2596
|
+
i4 += 1;
|
2597
|
+
pSamplesOut += 4;
|
2598
|
+
}
|
2599
|
+
|
2600
|
+
drflac_uint32 i = i4 << 2;
|
2601
|
+
while (i < count) {
|
2602
|
+
// Rice extraction.
|
2603
|
+
if (!drflac__read_rice_parts__param_equals_zero(bs, &zeroCountPart0, &riceParamPart0)) {
|
2604
|
+
return DRFLAC_FALSE;
|
2605
|
+
}
|
2606
|
+
|
2607
|
+
// Rice reconstruction.
|
2608
|
+
riceParamPart0 |= zeroCountPart0;
|
2609
|
+
riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01];
|
2610
|
+
|
2611
|
+
// Sample reconstruction.
|
2612
|
+
if (bitsPerSample > 16) {
|
2613
|
+
pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 0);
|
2614
|
+
} else {
|
2615
|
+
pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 0);
|
2616
|
+
}
|
2617
|
+
|
2618
|
+
i += 1;
|
2619
|
+
pSamplesOut += 1;
|
2620
|
+
}
|
2621
|
+
|
2622
|
+
return DRFLAC_TRUE;
|
2623
|
+
}
|
2624
|
+
|
2379
2625
|
static drflac_bool32 drflac__decode_samples_with_residual__rice(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)
|
2380
2626
|
{
|
2381
2627
|
#if 0
|
2382
2628
|
return drflac__decode_samples_with_residual__rice__reference(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
|
2383
2629
|
#else
|
2384
|
-
|
2630
|
+
if (riceParam != 0) {
|
2631
|
+
return drflac__decode_samples_with_residual__rice__simple(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
|
2632
|
+
} else {
|
2633
|
+
return drflac__decode_samples_with_residual__rice__param_equals_zero(bs, bitsPerSample, count, order, shift, coefficients, pSamplesOut);
|
2634
|
+
}
|
2385
2635
|
#endif
|
2386
2636
|
}
|
2387
2637
|
|
@@ -2391,11 +2641,20 @@ static drflac_bool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, drflac_
|
|
2391
2641
|
drflac_assert(bs != NULL);
|
2392
2642
|
drflac_assert(count > 0);
|
2393
2643
|
|
2394
|
-
|
2395
|
-
|
2396
|
-
|
2397
|
-
|
2398
|
-
|
2644
|
+
drflac_uint32 zeroCountPart;
|
2645
|
+
drflac_uint32 riceParamPart;
|
2646
|
+
|
2647
|
+
if (riceParam != 0) {
|
2648
|
+
for (drflac_uint32 i = 0; i < count; ++i) {
|
2649
|
+
if (!drflac__read_rice_parts(bs, riceParam, &zeroCountPart, &riceParamPart)) {
|
2650
|
+
return DRFLAC_FALSE;
|
2651
|
+
}
|
2652
|
+
}
|
2653
|
+
} else {
|
2654
|
+
for (drflac_uint32 i = 0; i < count; ++i) {
|
2655
|
+
if (!drflac__read_rice_parts__param_equals_zero(bs, &zeroCountPart, &riceParamPart)) {
|
2656
|
+
return DRFLAC_FALSE;
|
2657
|
+
}
|
2399
2658
|
}
|
2400
2659
|
}
|
2401
2660
|
|
@@ -2406,12 +2665,16 @@ static drflac_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs*
|
|
2406
2665
|
{
|
2407
2666
|
drflac_assert(bs != NULL);
|
2408
2667
|
drflac_assert(count > 0);
|
2409
|
-
drflac_assert(unencodedBitsPerSample
|
2668
|
+
drflac_assert(unencodedBitsPerSample <= 31); // <-- unencodedBitsPerSample is a 5 bit number, so cannot exceed 31.
|
2410
2669
|
drflac_assert(pSamplesOut != NULL);
|
2411
2670
|
|
2412
2671
|
for (unsigned int i = 0; i < count; ++i) {
|
2413
|
-
if (
|
2414
|
-
|
2672
|
+
if (unencodedBitsPerSample > 0) {
|
2673
|
+
if (!drflac__read_int32(bs, unencodedBitsPerSample, pSamplesOut + i)) {
|
2674
|
+
return DRFLAC_FALSE;
|
2675
|
+
}
|
2676
|
+
} else {
|
2677
|
+
pSamplesOut[i] = 0;
|
2415
2678
|
}
|
2416
2679
|
|
2417
2680
|
if (bitsPerSample > 16) {
|
@@ -2471,14 +2734,14 @@ static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_
|
|
2471
2734
|
if (!drflac__read_uint8(bs, 4, &riceParam)) {
|
2472
2735
|
return DRFLAC_FALSE;
|
2473
2736
|
}
|
2474
|
-
if (riceParam ==
|
2737
|
+
if (riceParam == 15) {
|
2475
2738
|
riceParam = 0xFF;
|
2476
2739
|
}
|
2477
2740
|
} else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
|
2478
2741
|
if (!drflac__read_uint8(bs, 5, &riceParam)) {
|
2479
2742
|
return DRFLAC_FALSE;
|
2480
2743
|
}
|
2481
|
-
if (riceParam ==
|
2744
|
+
if (riceParam == 31) {
|
2482
2745
|
riceParam = 0xFF;
|
2483
2746
|
}
|
2484
2747
|
}
|
@@ -2537,6 +2800,17 @@ static drflac_bool32 drflac__read_and_seek_residual(drflac_bs* bs, drflac_uint32
|
|
2537
2800
|
return DRFLAC_FALSE;
|
2538
2801
|
}
|
2539
2802
|
|
2803
|
+
// From the FLAC spec:
|
2804
|
+
// The Rice partition order in a Rice-coded residual section must be less than or equal to 8.
|
2805
|
+
if (partitionOrder > 8) {
|
2806
|
+
return DRFLAC_FALSE;
|
2807
|
+
}
|
2808
|
+
|
2809
|
+
// Validation check.
|
2810
|
+
if ((blockSize / (1 << partitionOrder)) <= order) {
|
2811
|
+
return DRFLAC_FALSE;
|
2812
|
+
}
|
2813
|
+
|
2540
2814
|
drflac_uint32 samplesInPartition = (blockSize / (1 << partitionOrder)) - order;
|
2541
2815
|
drflac_uint32 partitionsRemaining = (1 << partitionOrder);
|
2542
2816
|
for (;;)
|
@@ -2546,14 +2820,14 @@ static drflac_bool32 drflac__read_and_seek_residual(drflac_bs* bs, drflac_uint32
|
|
2546
2820
|
if (!drflac__read_uint8(bs, 4, &riceParam)) {
|
2547
2821
|
return DRFLAC_FALSE;
|
2548
2822
|
}
|
2549
|
-
if (riceParam ==
|
2823
|
+
if (riceParam == 15) {
|
2550
2824
|
riceParam = 0xFF;
|
2551
2825
|
}
|
2552
2826
|
} else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) {
|
2553
2827
|
if (!drflac__read_uint8(bs, 5, &riceParam)) {
|
2554
2828
|
return DRFLAC_FALSE;
|
2555
2829
|
}
|
2556
|
-
if (riceParam ==
|
2830
|
+
if (riceParam == 31) {
|
2557
2831
|
riceParam = 0xFF;
|
2558
2832
|
}
|
2559
2833
|
}
|
@@ -2710,6 +2984,9 @@ static drflac_bool32 drflac__read_next_frame_header(drflac_bs* bs, drflac_uint8
|
|
2710
2984
|
if (!drflac__read_uint8(bs, 1, &reserved)) {
|
2711
2985
|
return DRFLAC_FALSE;
|
2712
2986
|
}
|
2987
|
+
if (reserved == 1) {
|
2988
|
+
continue;
|
2989
|
+
}
|
2713
2990
|
crc8 = drflac_crc8(crc8, reserved, 1);
|
2714
2991
|
|
2715
2992
|
|
@@ -2724,6 +3001,9 @@ static drflac_bool32 drflac__read_next_frame_header(drflac_bs* bs, drflac_uint8
|
|
2724
3001
|
if (!drflac__read_uint8(bs, 4, &blockSize)) {
|
2725
3002
|
return DRFLAC_FALSE;
|
2726
3003
|
}
|
3004
|
+
if (blockSize == 0) {
|
3005
|
+
continue;
|
3006
|
+
}
|
2727
3007
|
crc8 = drflac_crc8(crc8, blockSize, 4);
|
2728
3008
|
|
2729
3009
|
|
@@ -2738,6 +3018,9 @@ static drflac_bool32 drflac__read_next_frame_header(drflac_bs* bs, drflac_uint8
|
|
2738
3018
|
if (!drflac__read_uint8(bs, 4, &channelAssignment)) {
|
2739
3019
|
return DRFLAC_FALSE;
|
2740
3020
|
}
|
3021
|
+
if (channelAssignment > 10) {
|
3022
|
+
continue;
|
3023
|
+
}
|
2741
3024
|
crc8 = drflac_crc8(crc8, channelAssignment, 4);
|
2742
3025
|
|
2743
3026
|
|
@@ -2745,12 +3028,18 @@ static drflac_bool32 drflac__read_next_frame_header(drflac_bs* bs, drflac_uint8
|
|
2745
3028
|
if (!drflac__read_uint8(bs, 3, &bitsPerSample)) {
|
2746
3029
|
return DRFLAC_FALSE;
|
2747
3030
|
}
|
3031
|
+
if (bitsPerSample == 3 || bitsPerSample == 7) {
|
3032
|
+
continue;
|
3033
|
+
}
|
2748
3034
|
crc8 = drflac_crc8(crc8, bitsPerSample, 3);
|
2749
3035
|
|
2750
3036
|
|
2751
3037
|
if (!drflac__read_uint8(bs, 1, &reserved)) {
|
2752
3038
|
return DRFLAC_FALSE;
|
2753
3039
|
}
|
3040
|
+
if (reserved == 1) {
|
3041
|
+
continue;
|
3042
|
+
}
|
2754
3043
|
crc8 = drflac_crc8(crc8, reserved, 1);
|
2755
3044
|
|
2756
3045
|
|
@@ -2838,11 +3127,11 @@ static drflac_bool32 drflac__read_next_frame_header(drflac_bs* bs, drflac_uint8
|
|
2838
3127
|
return DRFLAC_FALSE;
|
2839
3128
|
}
|
2840
3129
|
|
2841
|
-
|
3130
|
+
#ifndef DR_FLAC_NO_CRC
|
2842
3131
|
if (header->crc8 != crc8) {
|
2843
3132
|
continue; // CRC mismatch. Loop back to the top and find the next sync code.
|
2844
3133
|
}
|
2845
|
-
|
3134
|
+
#endif
|
2846
3135
|
return DRFLAC_TRUE;
|
2847
3136
|
}
|
2848
3137
|
}
|
@@ -2916,6 +3205,9 @@ static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame,
|
|
2916
3205
|
}
|
2917
3206
|
|
2918
3207
|
// Need to handle wasted bits per sample.
|
3208
|
+
if (pSubframe->wastedBitsPerSample >= pSubframe->bitsPerSample) {
|
3209
|
+
return DRFLAC_FALSE;
|
3210
|
+
}
|
2919
3211
|
pSubframe->bitsPerSample -= pSubframe->wastedBitsPerSample;
|
2920
3212
|
pSubframe->pDecodedSamples = pDecodedSamplesOut;
|
2921
3213
|
|
@@ -2966,6 +3258,9 @@ static drflac_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, i
|
|
2966
3258
|
}
|
2967
3259
|
|
2968
3260
|
// Need to handle wasted bits per sample.
|
3261
|
+
if (pSubframe->wastedBitsPerSample >= pSubframe->bitsPerSample) {
|
3262
|
+
return DRFLAC_FALSE;
|
3263
|
+
}
|
2969
3264
|
pSubframe->bitsPerSample -= pSubframe->wastedBitsPerSample;
|
2970
3265
|
pSubframe->pDecodedSamples = NULL;
|
2971
3266
|
|
@@ -3014,7 +3309,6 @@ static drflac_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, i
|
|
3014
3309
|
}
|
3015
3310
|
lpcPrecision += 1;
|
3016
3311
|
|
3017
|
-
|
3018
3312
|
bitsToSeek = (pSubframe->lpcOrder * lpcPrecision) + 5; // +5 for shift.
|
3019
3313
|
if (!drflac__seek_bits(bs, bitsToSeek)) {
|
3020
3314
|
return DRFLAC_FALSE;
|
@@ -3508,7 +3802,6 @@ drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_s
|
|
3508
3802
|
}
|
3509
3803
|
runningFilePos += 4;
|
3510
3804
|
|
3511
|
-
|
3512
3805
|
drflac_metadata metadata;
|
3513
3806
|
metadata.type = blockType;
|
3514
3807
|
metadata.pRawData = NULL;
|
@@ -3518,6 +3811,10 @@ drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_s
|
|
3518
3811
|
{
|
3519
3812
|
case DRFLAC_METADATA_BLOCK_TYPE_APPLICATION:
|
3520
3813
|
{
|
3814
|
+
if (blockSize < 4) {
|
3815
|
+
return DRFLAC_FALSE;
|
3816
|
+
}
|
3817
|
+
|
3521
3818
|
if (onMeta) {
|
3522
3819
|
void* pRawData = DRFLAC_MALLOC(blockSize);
|
3523
3820
|
if (pRawData == NULL) {
|
@@ -3577,6 +3874,10 @@ drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_s
|
|
3577
3874
|
|
3578
3875
|
case DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT:
|
3579
3876
|
{
|
3877
|
+
if (blockSize < 8) {
|
3878
|
+
return DRFLAC_FALSE;
|
3879
|
+
}
|
3880
|
+
|
3580
3881
|
if (onMeta) {
|
3581
3882
|
void* pRawData = DRFLAC_MALLOC(blockSize);
|
3582
3883
|
if (pRawData == NULL) {
|
@@ -3592,10 +3893,39 @@ drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_s
|
|
3592
3893
|
metadata.rawDataSize = blockSize;
|
3593
3894
|
|
3594
3895
|
const char* pRunningData = (const char*)pRawData;
|
3595
|
-
|
3596
|
-
|
3597
|
-
metadata.data.vorbis_comment.
|
3598
|
-
|
3896
|
+
const char* const pRunningDataEnd = (const char*)pRawData + blockSize;
|
3897
|
+
|
3898
|
+
metadata.data.vorbis_comment.vendorLength = drflac__le2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
|
3899
|
+
|
3900
|
+
// Need space for the rest of the block
|
3901
|
+
if ((pRunningDataEnd - pRunningData) - 4 < (drflac_int64)metadata.data.vorbis_comment.vendorLength) { // <-- Note the order of operations to avoid overflow to a valid value
|
3902
|
+
DRFLAC_FREE(pRawData);
|
3903
|
+
return DRFLAC_FALSE;
|
3904
|
+
}
|
3905
|
+
metadata.data.vorbis_comment.vendor = pRunningData; pRunningData += metadata.data.vorbis_comment.vendorLength;
|
3906
|
+
metadata.data.vorbis_comment.commentCount = drflac__le2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
|
3907
|
+
|
3908
|
+
// Need space for 'commentCount' comments after the block, which at minimum is a drflac_uint32 per comment
|
3909
|
+
if ((pRunningDataEnd - pRunningData) / sizeof(drflac_uint32) < metadata.data.vorbis_comment.commentCount) { // <-- Note the order of operations to avoid overflow to a valid value
|
3910
|
+
DRFLAC_FREE(pRawData);
|
3911
|
+
return DRFLAC_FALSE;
|
3912
|
+
}
|
3913
|
+
metadata.data.vorbis_comment.pComments = pRunningData;
|
3914
|
+
|
3915
|
+
// Check that the comments section is valid before passing it to the callback
|
3916
|
+
for (drflac_uint32 i = 0; i < metadata.data.vorbis_comment.commentCount; ++i) {
|
3917
|
+
if (pRunningDataEnd - pRunningData < 4) {
|
3918
|
+
DRFLAC_FREE(pRawData);
|
3919
|
+
return DRFLAC_FALSE;
|
3920
|
+
}
|
3921
|
+
const drflac_uint32 commentLength = drflac__le2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
|
3922
|
+
if (pRunningDataEnd - pRunningData < (drflac_int64)commentLength) { // <-- Note the order of operations to avoid overflow to a valid value
|
3923
|
+
DRFLAC_FREE(pRawData);
|
3924
|
+
return DRFLAC_FALSE;
|
3925
|
+
}
|
3926
|
+
pRunningData += commentLength;
|
3927
|
+
}
|
3928
|
+
|
3599
3929
|
onMeta(pUserDataMD, &metadata);
|
3600
3930
|
|
3601
3931
|
DRFLAC_FREE(pRawData);
|
@@ -3604,6 +3934,10 @@ drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_s
|
|
3604
3934
|
|
3605
3935
|
case DRFLAC_METADATA_BLOCK_TYPE_CUESHEET:
|
3606
3936
|
{
|
3937
|
+
if (blockSize < 396) {
|
3938
|
+
return DRFLAC_FALSE;
|
3939
|
+
}
|
3940
|
+
|
3607
3941
|
if (onMeta) {
|
3608
3942
|
void* pRawData = DRFLAC_MALLOC(blockSize);
|
3609
3943
|
if (pRawData == NULL) {
|
@@ -3618,12 +3952,39 @@ drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_s
|
|
3618
3952
|
metadata.pRawData = pRawData;
|
3619
3953
|
metadata.rawDataSize = blockSize;
|
3620
3954
|
|
3621
|
-
|
3622
|
-
|
3623
|
-
|
3624
|
-
metadata.data.cuesheet.
|
3625
|
-
metadata.data.cuesheet.
|
3626
|
-
metadata.data.cuesheet.
|
3955
|
+
char* pRunningData = (char*)pRawData;
|
3956
|
+
const char* const pRunningDataEnd = (const char*)pRawData + blockSize;
|
3957
|
+
|
3958
|
+
drflac_copy_memory(metadata.data.cuesheet.catalog, pRunningData, 128); pRunningData += 128;
|
3959
|
+
metadata.data.cuesheet.leadInSampleCount = drflac__be2host_64(*(const drflac_uint64*)pRunningData); pRunningData += 8;
|
3960
|
+
metadata.data.cuesheet.isCD = (pRunningData[0] & 0x80) != 0; pRunningData += 259;
|
3961
|
+
metadata.data.cuesheet.trackCount = pRunningData[0]; pRunningData += 1;
|
3962
|
+
metadata.data.cuesheet.pTrackData = pRunningData;
|
3963
|
+
|
3964
|
+
// Check that the cuesheet tracks are valid before passing it to the callback
|
3965
|
+
for (drflac_uint8 i = 0; i < metadata.data.cuesheet.trackCount; ++i) {
|
3966
|
+
if (pRunningDataEnd - pRunningData < 36) {
|
3967
|
+
DRFLAC_FREE(pRawData);
|
3968
|
+
return DRFLAC_FALSE;
|
3969
|
+
}
|
3970
|
+
|
3971
|
+
// Skip to the index point count
|
3972
|
+
pRunningData += 35;
|
3973
|
+
const drflac_uint8 indexCount = pRunningData[0]; pRunningData += 1;
|
3974
|
+
const drflac_uint32 indexPointSize = indexCount * sizeof(drflac_cuesheet_track_index);
|
3975
|
+
if (pRunningDataEnd - pRunningData < (drflac_int64)indexPointSize) {
|
3976
|
+
DRFLAC_FREE(pRawData);
|
3977
|
+
return DRFLAC_FALSE;
|
3978
|
+
}
|
3979
|
+
|
3980
|
+
// Endian swap.
|
3981
|
+
for (drflac_uint8 index = 0; index < indexCount; ++index) {
|
3982
|
+
drflac_cuesheet_track_index* pTrack = (drflac_cuesheet_track_index*)pRunningData;
|
3983
|
+
pRunningData += sizeof(drflac_cuesheet_track_index);
|
3984
|
+
pTrack->offset = drflac__be2host_64(pTrack->offset);
|
3985
|
+
}
|
3986
|
+
}
|
3987
|
+
|
3627
3988
|
onMeta(pUserDataMD, &metadata);
|
3628
3989
|
|
3629
3990
|
DRFLAC_FREE(pRawData);
|
@@ -3632,6 +3993,10 @@ drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_s
|
|
3632
3993
|
|
3633
3994
|
case DRFLAC_METADATA_BLOCK_TYPE_PICTURE:
|
3634
3995
|
{
|
3996
|
+
if (blockSize < 32) {
|
3997
|
+
return DRFLAC_FALSE;
|
3998
|
+
}
|
3999
|
+
|
3635
4000
|
if (onMeta) {
|
3636
4001
|
void* pRawData = DRFLAC_MALLOC(blockSize);
|
3637
4002
|
if (pRawData == NULL) {
|
@@ -3647,17 +4012,38 @@ drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_s
|
|
3647
4012
|
metadata.rawDataSize = blockSize;
|
3648
4013
|
|
3649
4014
|
const char* pRunningData = (const char*)pRawData;
|
3650
|
-
|
3651
|
-
|
3652
|
-
metadata.data.picture.
|
3653
|
-
metadata.data.picture.
|
3654
|
-
|
3655
|
-
|
3656
|
-
metadata.data.picture.
|
3657
|
-
|
3658
|
-
|
3659
|
-
|
4015
|
+
const char* const pRunningDataEnd = (const char*)pRawData + blockSize;
|
4016
|
+
|
4017
|
+
metadata.data.picture.type = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
|
4018
|
+
metadata.data.picture.mimeLength = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
|
4019
|
+
|
4020
|
+
// Need space for the rest of the block
|
4021
|
+
if ((pRunningDataEnd - pRunningData) - 24 < (drflac_int64)metadata.data.picture.mimeLength) { // <-- Note the order of operations to avoid overflow to a valid value
|
4022
|
+
DRFLAC_FREE(pRawData);
|
4023
|
+
return DRFLAC_FALSE;
|
4024
|
+
}
|
4025
|
+
metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength;
|
4026
|
+
metadata.data.picture.descriptionLength = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
|
4027
|
+
|
4028
|
+
// Need space for the rest of the block
|
4029
|
+
if ((pRunningDataEnd - pRunningData) - 20 < (drflac_int64)metadata.data.picture.descriptionLength) { // <-- Note the order of operations to avoid overflow to a valid value
|
4030
|
+
DRFLAC_FREE(pRawData);
|
4031
|
+
return DRFLAC_FALSE;
|
4032
|
+
}
|
4033
|
+
metadata.data.picture.description = pRunningData; pRunningData += metadata.data.picture.descriptionLength;
|
4034
|
+
metadata.data.picture.width = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
|
4035
|
+
metadata.data.picture.height = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
|
4036
|
+
metadata.data.picture.colorDepth = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
|
4037
|
+
metadata.data.picture.indexColorCount = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
|
4038
|
+
metadata.data.picture.pictureDataSize = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
|
3660
4039
|
metadata.data.picture.pPictureData = (const drflac_uint8*)pRunningData;
|
4040
|
+
|
4041
|
+
// Need space for the picture after the block
|
4042
|
+
if (pRunningDataEnd - pRunningData < (drflac_int64)metadata.data.picture.pictureDataSize) { // <-- Note the order of operations to avoid overflow to a valid value
|
4043
|
+
DRFLAC_FREE(pRawData);
|
4044
|
+
return DRFLAC_FALSE;
|
4045
|
+
}
|
4046
|
+
|
3661
4047
|
onMeta(pUserDataMD, &metadata);
|
3662
4048
|
|
3663
4049
|
DRFLAC_FREE(pRawData);
|
@@ -3810,6 +4196,7 @@ typedef enum
|
|
3810
4196
|
} drflac_ogg_crc_mismatch_recovery;
|
3811
4197
|
|
3812
4198
|
|
4199
|
+
#ifndef DR_FLAC_NO_CRC
|
3813
4200
|
static drflac_uint32 drflac__crc32_table[] = {
|
3814
4201
|
0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L,
|
3815
4202
|
0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L,
|
@@ -3876,6 +4263,7 @@ static drflac_uint32 drflac__crc32_table[] = {
|
|
3876
4263
|
0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L,
|
3877
4264
|
0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L
|
3878
4265
|
};
|
4266
|
+
#endif
|
3879
4267
|
|
3880
4268
|
static DRFLAC_INLINE drflac_uint32 drflac_crc32_byte(drflac_uint32 crc32, drflac_uint8 data)
|
3881
4269
|
{
|
@@ -3964,7 +4352,6 @@ drflac_result drflac_ogg__read_page_header_after_capture_pattern(drflac_read_pro
|
|
3964
4352
|
*pCRC32 = drflac_crc32_byte(*pCRC32, data[i]);
|
3965
4353
|
}
|
3966
4354
|
|
3967
|
-
|
3968
4355
|
if (onRead(pUserData, pHeader->segmentTable, pHeader->segmentCount) != pHeader->segmentCount) {
|
3969
4356
|
return DRFLAC_END_OF_STREAM;
|
3970
4357
|
}
|
@@ -4250,7 +4637,7 @@ static drflac_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_see
|
|
4250
4637
|
{
|
4251
4638
|
drflac_oggbs* oggbs = (drflac_oggbs*)pUserData;
|
4252
4639
|
drflac_assert(oggbs != NULL);
|
4253
|
-
drflac_assert(offset
|
4640
|
+
drflac_assert(offset >= 0); // <-- Never seek backwards.
|
4254
4641
|
|
4255
4642
|
// Seeking is always forward which makes things a lot simpler.
|
4256
4643
|
if (origin == drflac_seek_origin_start) {
|
@@ -4320,7 +4707,6 @@ drflac_bool32 drflac_ogg__seek_to_sample(drflac* pFlac, drflac_uint64 sampleInde
|
|
4320
4707
|
break; // The sample is somewhere in the previous page.
|
4321
4708
|
}
|
4322
4709
|
|
4323
|
-
|
4324
4710
|
// At this point we know the sample is not in the previous page. It could possibly be in this page. For simplicity we
|
4325
4711
|
// disregard any pages that do not begin a fresh packet.
|
4326
4712
|
if ((oggbs->currentPageHeader.headerType & 0x01) == 0) { // <-- Is it a fresh page?
|
@@ -4338,7 +4724,6 @@ drflac_bool32 drflac_ogg__seek_to_sample(drflac* pFlac, drflac_uint64 sampleInde
|
|
4338
4724
|
}
|
4339
4725
|
}
|
4340
4726
|
|
4341
|
-
|
4342
4727
|
// We found the page that that is closest to the sample, so now we need to find it. The first thing to do is seek to the
|
4343
4728
|
// start of that page. In the loop above we checked that it was a fresh page which means this page is also the start of
|
4344
4729
|
// a new frame. This property means that after we've seeked to the page we can immediately start looping over frames until
|
@@ -4350,7 +4735,6 @@ drflac_bool32 drflac_ogg__seek_to_sample(drflac* pFlac, drflac_uint64 sampleInde
|
|
4350
4735
|
return DRFLAC_FALSE;
|
4351
4736
|
}
|
4352
4737
|
|
4353
|
-
|
4354
4738
|
// At this point we'll be sitting on the first byte of the frame header of the first frame in the page. We just keep
|
4355
4739
|
// looping over these frames until we find the one containing the sample we're after.
|
4356
4740
|
drflac_uint64 runningSampleCount = runningGranulePosition;
|
@@ -4554,7 +4938,6 @@ drflac_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_pro
|
|
4554
4938
|
|
4555
4939
|
pInit->runningFilePos += pageBodySize;
|
4556
4940
|
|
4557
|
-
|
4558
4941
|
// Read the header of the next page.
|
4559
4942
|
if (drflac_ogg__read_page_header(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) {
|
4560
4943
|
return DRFLAC_FALSE;
|
@@ -4562,7 +4945,6 @@ drflac_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_pro
|
|
4562
4945
|
pInit->runningFilePos += bytesRead;
|
4563
4946
|
}
|
4564
4947
|
|
4565
|
-
|
4566
4948
|
// If we get here it means we found a FLAC audio stream. We should be sitting on the first byte of the header of the next page. The next
|
4567
4949
|
// packets in the FLAC logical stream contain the metadata. The only thing left to do in the initialization phase for Ogg is to create the
|
4568
4950
|
// Ogg bistream object.
|
@@ -4804,6 +5186,7 @@ drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_p
|
|
4804
5186
|
|
4805
5187
|
// We need to seek back to where we were. If this fails it's a critical error.
|
4806
5188
|
if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFramePos, drflac_seek_origin_start)) {
|
5189
|
+
DRFLAC_FREE(pFlac);
|
4807
5190
|
return NULL;
|
4808
5191
|
}
|
4809
5192
|
} else {
|
@@ -4814,8 +5197,6 @@ drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_p
|
|
4814
5197
|
}
|
4815
5198
|
}
|
4816
5199
|
|
4817
|
-
|
4818
|
-
|
4819
5200
|
// If we get here, but don't have a STREAMINFO block, it means we've opened the stream in relaxed mode and need to decode
|
4820
5201
|
// the first frame.
|
4821
5202
|
if (!init.hasStreamInfoBlock) {
|
@@ -4844,11 +5225,7 @@ drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_p
|
|
4844
5225
|
}
|
4845
5226
|
|
4846
5227
|
|
4847
|
-
|
4848
5228
|
#ifndef DR_FLAC_NO_STDIO
|
4849
|
-
typedef void* drflac_file;
|
4850
|
-
|
4851
|
-
#if defined(DR_FLAC_NO_WIN32_IO) || !defined(_WIN32)
|
4852
5229
|
#include <stdio.h>
|
4853
5230
|
|
4854
5231
|
static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead)
|
@@ -4858,12 +5235,12 @@ static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t byt
|
|
4858
5235
|
|
4859
5236
|
static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin)
|
4860
5237
|
{
|
4861
|
-
drflac_assert(offset
|
5238
|
+
drflac_assert(offset >= 0); // <-- Never seek backwards.
|
4862
5239
|
|
4863
5240
|
return fseek((FILE*)pUserData, offset, (origin == drflac_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
|
4864
5241
|
}
|
4865
5242
|
|
4866
|
-
static
|
5243
|
+
static FILE* drflac__fopen(const char* filename)
|
4867
5244
|
{
|
4868
5245
|
FILE* pFile;
|
4869
5246
|
#ifdef _MSC_VER
|
@@ -4877,65 +5254,20 @@ static drflac_file drflac__open_file_handle(const char* filename)
|
|
4877
5254
|
}
|
4878
5255
|
#endif
|
4879
5256
|
|
4880
|
-
return
|
5257
|
+
return pFile;
|
4881
5258
|
}
|
4882
5259
|
|
4883
|
-
static void drflac__close_file_handle(drflac_file file)
|
4884
|
-
{
|
4885
|
-
fclose((FILE*)file);
|
4886
|
-
}
|
4887
|
-
#else
|
4888
|
-
#include <windows.h>
|
4889
|
-
|
4890
|
-
// This doesn't seem to be defined for VC6.
|
4891
|
-
#ifndef INVALID_SET_FILE_POINTER
|
4892
|
-
#define INVALID_SET_FILE_POINTER ((DWORD)-1)
|
4893
|
-
#endif
|
4894
|
-
|
4895
|
-
static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead)
|
4896
|
-
{
|
4897
|
-
drflac_assert(bytesToRead < 0xFFFFFFFF); // dr_flac will never request huge amounts of data at a time. This is a safe assertion.
|
4898
|
-
|
4899
|
-
DWORD bytesRead;
|
4900
|
-
ReadFile((HANDLE)pUserData, bufferOut, (DWORD)bytesToRead, &bytesRead, NULL);
|
4901
|
-
|
4902
|
-
return (size_t)bytesRead;
|
4903
|
-
}
|
4904
|
-
|
4905
|
-
static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin)
|
4906
|
-
{
|
4907
|
-
drflac_assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start));
|
4908
|
-
|
4909
|
-
return SetFilePointer((HANDLE)pUserData, offset, NULL, (origin == drflac_seek_origin_current) ? FILE_CURRENT : FILE_BEGIN) != INVALID_SET_FILE_POINTER;
|
4910
|
-
}
|
4911
|
-
|
4912
|
-
static drflac_file drflac__open_file_handle(const char* filename)
|
4913
|
-
{
|
4914
|
-
HANDLE hFile = CreateFileA(filename, FILE_GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
4915
|
-
if (hFile == INVALID_HANDLE_VALUE) {
|
4916
|
-
return NULL;
|
4917
|
-
}
|
4918
|
-
|
4919
|
-
return (drflac_file)hFile;
|
4920
|
-
}
|
4921
|
-
|
4922
|
-
static void drflac__close_file_handle(drflac_file file)
|
4923
|
-
{
|
4924
|
-
CloseHandle((HANDLE)file);
|
4925
|
-
}
|
4926
|
-
#endif
|
4927
|
-
|
4928
5260
|
|
4929
5261
|
drflac* drflac_open_file(const char* filename)
|
4930
5262
|
{
|
4931
|
-
|
5263
|
+
FILE* file = drflac__fopen(filename);
|
4932
5264
|
if (file == NULL) {
|
4933
5265
|
return NULL;
|
4934
5266
|
}
|
4935
5267
|
|
4936
5268
|
drflac* pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, (void*)file);
|
4937
5269
|
if (pFlac == NULL) {
|
4938
|
-
|
5270
|
+
fclose(file);
|
4939
5271
|
return NULL;
|
4940
5272
|
}
|
4941
5273
|
|
@@ -4944,14 +5276,14 @@ drflac* drflac_open_file(const char* filename)
|
|
4944
5276
|
|
4945
5277
|
drflac* drflac_open_file_with_metadata(const char* filename, drflac_meta_proc onMeta, void* pUserData)
|
4946
5278
|
{
|
4947
|
-
|
5279
|
+
FILE* file = drflac__fopen(filename);
|
4948
5280
|
if (file == NULL) {
|
4949
5281
|
return NULL;
|
4950
5282
|
}
|
4951
5283
|
|
4952
5284
|
drflac* pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, drflac_container_unknown, (void*)file, pUserData);
|
4953
5285
|
if (pFlac == NULL) {
|
4954
|
-
|
5286
|
+
fclose(file);
|
4955
5287
|
return pFlac;
|
4956
5288
|
}
|
4957
5289
|
|
@@ -4982,20 +5314,23 @@ static drflac_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_
|
|
4982
5314
|
{
|
4983
5315
|
drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData;
|
4984
5316
|
drflac_assert(memoryStream != NULL);
|
4985
|
-
drflac_assert(offset
|
4986
|
-
|
5317
|
+
drflac_assert(offset >= 0); // <-- Never seek backwards.
|
5318
|
+
|
5319
|
+
if (offset > (drflac_int64)memoryStream->dataSize) {
|
5320
|
+
return DRFLAC_FALSE;
|
5321
|
+
}
|
4987
5322
|
|
4988
5323
|
if (origin == drflac_seek_origin_current) {
|
4989
5324
|
if (memoryStream->currentReadPos + offset <= memoryStream->dataSize) {
|
4990
5325
|
memoryStream->currentReadPos += offset;
|
4991
5326
|
} else {
|
4992
|
-
|
5327
|
+
return DRFLAC_FALSE; // Trying to seek too far forward.
|
4993
5328
|
}
|
4994
5329
|
} else {
|
4995
5330
|
if ((drflac_uint32)offset <= memoryStream->dataSize) {
|
4996
5331
|
memoryStream->currentReadPos = offset;
|
4997
5332
|
} else {
|
4998
|
-
|
5333
|
+
return DRFLAC_FALSE; // Trying to seek too far forward.
|
4999
5334
|
}
|
5000
5335
|
}
|
5001
5336
|
|
@@ -5090,7 +5425,7 @@ void drflac_close(drflac* pFlac)
|
|
5090
5425
|
// If we opened the file with drflac_open_file() we will want to close the file handle. We can know whether or not drflac_open_file()
|
5091
5426
|
// was used by looking at the callbacks.
|
5092
5427
|
if (pFlac->bs.onRead == drflac__on_read_stdio) {
|
5093
|
-
|
5428
|
+
fclose((FILE*)pFlac->bs.pUserData);
|
5094
5429
|
}
|
5095
5430
|
|
5096
5431
|
#ifndef DR_FLAC_NO_OGG
|
@@ -5099,7 +5434,7 @@ void drflac_close(drflac* pFlac)
|
|
5099
5434
|
drflac_assert(pFlac->bs.onRead == drflac__on_read_ogg);
|
5100
5435
|
drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs;
|
5101
5436
|
if (oggbs->onRead == drflac__on_read_stdio) {
|
5102
|
-
|
5437
|
+
fclose((FILE*)oggbs->pUserData);
|
5103
5438
|
}
|
5104
5439
|
}
|
5105
5440
|
#endif
|
@@ -5131,10 +5466,10 @@ drflac_uint64 drflac__read_s32__misaligned(drflac* pFlac, drflac_uint64 samplesT
|
|
5131
5466
|
case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE:
|
5132
5467
|
{
|
5133
5468
|
if (channelIndex == 0) {
|
5134
|
-
decodedSample = pFlac->currentFrame.subframes[channelIndex].pDecodedSamples[nextSampleInFrame];
|
5469
|
+
decodedSample = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample;
|
5135
5470
|
} else {
|
5136
|
-
int side = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame];
|
5137
|
-
int left = pFlac->currentFrame.subframes[channelIndex - 1].pDecodedSamples[nextSampleInFrame];
|
5471
|
+
int side = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample;
|
5472
|
+
int left = pFlac->currentFrame.subframes[channelIndex - 1].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex - 1].wastedBitsPerSample;
|
5138
5473
|
decodedSample = left - side;
|
5139
5474
|
}
|
5140
5475
|
} break;
|
@@ -5142,11 +5477,11 @@ drflac_uint64 drflac__read_s32__misaligned(drflac* pFlac, drflac_uint64 samplesT
|
|
5142
5477
|
case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE:
|
5143
5478
|
{
|
5144
5479
|
if (channelIndex == 0) {
|
5145
|
-
int side = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame];
|
5146
|
-
int right = pFlac->currentFrame.subframes[channelIndex + 1].pDecodedSamples[nextSampleInFrame];
|
5480
|
+
int side = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample;
|
5481
|
+
int right = pFlac->currentFrame.subframes[channelIndex + 1].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 1].wastedBitsPerSample;
|
5147
5482
|
decodedSample = side + right;
|
5148
5483
|
} else {
|
5149
|
-
decodedSample = pFlac->currentFrame.subframes[channelIndex].pDecodedSamples[nextSampleInFrame];
|
5484
|
+
decodedSample = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample;
|
5150
5485
|
}
|
5151
5486
|
} break;
|
5152
5487
|
|
@@ -5155,14 +5490,14 @@ drflac_uint64 drflac__read_s32__misaligned(drflac* pFlac, drflac_uint64 samplesT
|
|
5155
5490
|
int mid;
|
5156
5491
|
int side;
|
5157
5492
|
if (channelIndex == 0) {
|
5158
|
-
mid = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame];
|
5159
|
-
side = pFlac->currentFrame.subframes[channelIndex + 1].pDecodedSamples[nextSampleInFrame];
|
5493
|
+
mid = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample;
|
5494
|
+
side = pFlac->currentFrame.subframes[channelIndex + 1].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 1].wastedBitsPerSample;
|
5160
5495
|
|
5161
5496
|
mid = (((unsigned int)mid) << 1) | (side & 0x01);
|
5162
5497
|
decodedSample = (mid + side) >> 1;
|
5163
5498
|
} else {
|
5164
|
-
mid = pFlac->currentFrame.subframes[channelIndex - 1].pDecodedSamples[nextSampleInFrame];
|
5165
|
-
side = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame];
|
5499
|
+
mid = pFlac->currentFrame.subframes[channelIndex - 1].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex - 1].wastedBitsPerSample;
|
5500
|
+
side = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample;
|
5166
5501
|
|
5167
5502
|
mid = (((unsigned int)mid) << 1) | (side & 0x01);
|
5168
5503
|
decodedSample = (mid - side) >> 1;
|
@@ -5172,12 +5507,12 @@ drflac_uint64 drflac__read_s32__misaligned(drflac* pFlac, drflac_uint64 samplesT
|
|
5172
5507
|
case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT:
|
5173
5508
|
default:
|
5174
5509
|
{
|
5175
|
-
decodedSample = pFlac->currentFrame.subframes[channelIndex].pDecodedSamples[nextSampleInFrame];
|
5510
|
+
decodedSample = pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample;
|
5176
5511
|
} break;
|
5177
5512
|
}
|
5178
5513
|
|
5179
5514
|
|
5180
|
-
decodedSample <<= (
|
5515
|
+
decodedSample <<= (32 - pFlac->bitsPerSample);
|
5181
5516
|
|
5182
5517
|
if (bufferOut) {
|
5183
5518
|
*bufferOut++ = decodedSample;
|
@@ -5269,12 +5604,12 @@ drflac_uint64 drflac_read_s32(drflac* pFlac, drflac_uint64 samplesToRead, drflac
|
|
5269
5604
|
const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame;
|
5270
5605
|
|
5271
5606
|
for (drflac_uint64 i = 0; i < alignedSampleCountPerChannel; ++i) {
|
5272
|
-
int left = pDecodedSamples0[i];
|
5273
|
-
int side = pDecodedSamples1[i];
|
5607
|
+
int left = pDecodedSamples0[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample);
|
5608
|
+
int side = pDecodedSamples1[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample);
|
5274
5609
|
int right = left - side;
|
5275
5610
|
|
5276
|
-
bufferOut[i*2+0] = left
|
5277
|
-
bufferOut[i*2+1] = right
|
5611
|
+
bufferOut[i*2+0] = left;
|
5612
|
+
bufferOut[i*2+1] = right;
|
5278
5613
|
}
|
5279
5614
|
} break;
|
5280
5615
|
|
@@ -5284,12 +5619,12 @@ drflac_uint64 drflac_read_s32(drflac* pFlac, drflac_uint64 samplesToRead, drflac
|
|
5284
5619
|
const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame;
|
5285
5620
|
|
5286
5621
|
for (drflac_uint64 i = 0; i < alignedSampleCountPerChannel; ++i) {
|
5287
|
-
int side = pDecodedSamples0[i];
|
5288
|
-
int right = pDecodedSamples1[i];
|
5622
|
+
int side = pDecodedSamples0[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample);
|
5623
|
+
int right = pDecodedSamples1[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample);
|
5289
5624
|
int left = right + side;
|
5290
5625
|
|
5291
|
-
bufferOut[i*2+0] = left
|
5292
|
-
bufferOut[i*2+1] = right
|
5626
|
+
bufferOut[i*2+0] = left;
|
5627
|
+
bufferOut[i*2+1] = right;
|
5293
5628
|
}
|
5294
5629
|
} break;
|
5295
5630
|
|
@@ -5299,11 +5634,13 @@ drflac_uint64 drflac_read_s32(drflac* pFlac, drflac_uint64 samplesToRead, drflac
|
|
5299
5634
|
const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame;
|
5300
5635
|
|
5301
5636
|
for (drflac_uint64 i = 0; i < alignedSampleCountPerChannel; ++i) {
|
5302
|
-
int
|
5303
|
-
int
|
5637
|
+
int mid = pDecodedSamples0[i] << pFlac->currentFrame.subframes[0].wastedBitsPerSample;
|
5638
|
+
int side = pDecodedSamples1[i] << pFlac->currentFrame.subframes[1].wastedBitsPerSample;
|
5639
|
+
|
5640
|
+
mid = (((drflac_uint32)mid) << 1) | (side & 0x01);
|
5304
5641
|
|
5305
|
-
bufferOut[i*2+0] = ((mid + side) >> 1) << (unusedBitsPerSample
|
5306
|
-
bufferOut[i*2+1] = ((mid - side) >> 1) << (unusedBitsPerSample
|
5642
|
+
bufferOut[i*2+0] = ((mid + side) >> 1) << (unusedBitsPerSample);
|
5643
|
+
bufferOut[i*2+1] = ((mid - side) >> 1) << (unusedBitsPerSample);
|
5307
5644
|
}
|
5308
5645
|
} break;
|
5309
5646
|
|
@@ -5459,13 +5796,13 @@ drflac_bool32 drflac_seek_to_sample(drflac* pFlac, drflac_uint64 sampleIndex)
|
|
5459
5796
|
|
5460
5797
|
// Different techniques depending on encapsulation. Using the native FLAC seektable with Ogg encapsulation is a bit awkward so
|
5461
5798
|
// we'll instead use Ogg's natural seeking facility.
|
5462
|
-
|
5799
|
+
#ifndef DR_FLAC_NO_OGG
|
5463
5800
|
if (pFlac->container == drflac_container_ogg)
|
5464
5801
|
{
|
5465
5802
|
wasSuccessful = drflac_ogg__seek_to_sample(pFlac, sampleIndex);
|
5466
5803
|
}
|
5467
5804
|
else
|
5468
|
-
|
5805
|
+
#endif
|
5469
5806
|
{
|
5470
5807
|
// First try seeking via the seek table. If this fails, fall back to a brute force seek which is much slower.
|
5471
5808
|
wasSuccessful = drflac__seek_to_sample__seek_table(pFlac, sampleIndex);
|
@@ -5480,18 +5817,19 @@ drflac_bool32 drflac_seek_to_sample(drflac* pFlac, drflac_uint64 sampleIndex)
|
|
5480
5817
|
}
|
5481
5818
|
|
5482
5819
|
|
5483
|
-
|
5484
5820
|
//// High Level APIs ////
|
5485
5821
|
|
5486
|
-
|
5487
|
-
#
|
5488
|
-
#ifdef DRFLAC_64BIT
|
5489
|
-
#define SIZE_MAX ((drflac_uint64)0xFFFFFFFFFFFFFFFF)
|
5822
|
+
#if defined(SIZE_MAX)
|
5823
|
+
#define DRFLAC_SIZE_MAX SIZE_MAX
|
5490
5824
|
#else
|
5491
|
-
#
|
5492
|
-
#
|
5825
|
+
#if defined(DRFLAC_64BIT)
|
5826
|
+
#define DRFLAC_SIZE_MAX ((drflac_uint64)0xFFFFFFFFFFFFFFFF)
|
5827
|
+
#else
|
5828
|
+
#define DRFLAC_SIZE_MAX 0xFFFFFFFF
|
5829
|
+
#endif
|
5493
5830
|
#endif
|
5494
5831
|
|
5832
|
+
|
5495
5833
|
// Using a macro as the definition of the drflac__full_decode_and_close_*() API family. Sue me.
|
5496
5834
|
#define DRFLAC_DEFINE_FULL_DECODE_AND_CLOSE(extension, type) \
|
5497
5835
|
static type* drflac__full_decode_and_close_ ## extension (drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalSampleCountOut)\
|
@@ -5532,7 +5870,7 @@ static type* drflac__full_decode_and_close_ ## extension (drflac* pFlac, unsigne
|
|
5532
5870
|
drflac_zero_memory(pSampleData + totalSampleCount, (size_t)(sampleDataBufferSize - totalSampleCount*sizeof(type))); \
|
5533
5871
|
} else { \
|
5534
5872
|
drflac_uint64 dataSize = totalSampleCount * sizeof(type); \
|
5535
|
-
if (dataSize >
|
5873
|
+
if (dataSize > (drflac_uint64)DRFLAC_SIZE_MAX) { \
|
5536
5874
|
goto on_error; /* The decoded data is too big. */ \
|
5537
5875
|
} \
|
5538
5876
|
\
|
@@ -5698,15 +6036,14 @@ void drflac_free(void* pSampleDataReturnedByOpenAndDecode)
|
|
5698
6036
|
|
5699
6037
|
|
5700
6038
|
|
5701
|
-
|
5702
|
-
void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const char* pComments)
|
6039
|
+
void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments)
|
5703
6040
|
{
|
5704
6041
|
if (pIter == NULL) {
|
5705
6042
|
return;
|
5706
6043
|
}
|
5707
6044
|
|
5708
6045
|
pIter->countRemaining = commentCount;
|
5709
|
-
pIter->pRunningData = pComments;
|
6046
|
+
pIter->pRunningData = (const char*)pComments;
|
5710
6047
|
}
|
5711
6048
|
|
5712
6049
|
const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut)
|
@@ -5718,7 +6055,7 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, dr
|
|
5718
6055
|
return NULL;
|
5719
6056
|
}
|
5720
6057
|
|
5721
|
-
drflac_uint32 length = drflac__le2host_32(*(drflac_uint32*)pIter->pRunningData);
|
6058
|
+
drflac_uint32 length = drflac__le2host_32(*(const drflac_uint32*)pIter->pRunningData);
|
5722
6059
|
pIter->pRunningData += 4;
|
5723
6060
|
|
5724
6061
|
const char* pComment = pIter->pRunningData;
|
@@ -5728,11 +6065,72 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, dr
|
|
5728
6065
|
if (pCommentLengthOut) *pCommentLengthOut = length;
|
5729
6066
|
return pComment;
|
5730
6067
|
}
|
6068
|
+
|
6069
|
+
|
6070
|
+
void drflac_init_cuesheet_track_iterator(drflac_cuesheet_track_iterator* pIter, drflac_uint32 trackCount, const void* pTrackData)
|
6071
|
+
{
|
6072
|
+
if (pIter == NULL) {
|
6073
|
+
return;
|
6074
|
+
}
|
6075
|
+
|
6076
|
+
pIter->countRemaining = trackCount;
|
6077
|
+
pIter->pRunningData = (const char*)pTrackData;
|
6078
|
+
}
|
6079
|
+
|
6080
|
+
drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator* pIter, drflac_cuesheet_track* pCuesheetTrack)
|
6081
|
+
{
|
6082
|
+
if (pIter == NULL || pIter->countRemaining == 0 || pIter->pRunningData == NULL) {
|
6083
|
+
return DRFLAC_FALSE;
|
6084
|
+
}
|
6085
|
+
|
6086
|
+
drflac_cuesheet_track cuesheetTrack;
|
6087
|
+
|
6088
|
+
const char* pRunningData = pIter->pRunningData;
|
6089
|
+
|
6090
|
+
drflac_uint64 offsetHi = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
|
6091
|
+
drflac_uint64 offsetLo = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4;
|
6092
|
+
cuesheetTrack.offset = offsetLo | (offsetHi << 32);
|
6093
|
+
cuesheetTrack.trackNumber = pRunningData[0]; pRunningData += 1;
|
6094
|
+
drflac_copy_memory(cuesheetTrack.ISRC, pRunningData, sizeof(cuesheetTrack.ISRC)); pRunningData += 12;
|
6095
|
+
cuesheetTrack.isAudio = (pRunningData[0] & 0x80) != 0;
|
6096
|
+
cuesheetTrack.preEmphasis = (pRunningData[0] & 0x40) != 0; pRunningData += 14;
|
6097
|
+
cuesheetTrack.indexCount = pRunningData[0]; pRunningData += 1;
|
6098
|
+
cuesheetTrack.pIndexPoints = (const drflac_cuesheet_track_index*)pRunningData; pRunningData += cuesheetTrack.indexCount * sizeof(drflac_cuesheet_track_index);
|
6099
|
+
|
6100
|
+
pIter->pRunningData = pRunningData;
|
6101
|
+
pIter->countRemaining -= 1;
|
6102
|
+
|
6103
|
+
if (pCuesheetTrack) *pCuesheetTrack = cuesheetTrack;
|
6104
|
+
return DRFLAC_TRUE;
|
6105
|
+
}
|
5731
6106
|
#endif //DR_FLAC_IMPLEMENTATION
|
5732
6107
|
|
5733
6108
|
|
5734
6109
|
// REVISION HISTORY
|
5735
6110
|
//
|
6111
|
+
// v0.10.0 - 2018-09-11
|
6112
|
+
// - Remove the DR_FLAC_NO_WIN32_IO option and the Win32 file IO functionality. If you need to use Win32 file IO you
|
6113
|
+
// need to do it yourself via the callback API.
|
6114
|
+
// - Fix the clang build.
|
6115
|
+
// - Fix undefined behavior.
|
6116
|
+
// - Fix errors with CUESHEET metdata blocks.
|
6117
|
+
// - Add an API for iterating over each cuesheet track in the CUESHEET metadata block. This works the same way as the
|
6118
|
+
// Vorbis comment API.
|
6119
|
+
// - Other miscellaneous bug fixes, mostly relating to invalid FLAC streams.
|
6120
|
+
// - Minor optimizations.
|
6121
|
+
//
|
6122
|
+
// v0.9.11 - 2018-08-29
|
6123
|
+
// - Fix a bug with sample reconstruction.
|
6124
|
+
//
|
6125
|
+
// v0.9.10 - 2018-08-07
|
6126
|
+
// - Improve 64-bit detection.
|
6127
|
+
//
|
6128
|
+
// v0.9.9 - 2018-08-05
|
6129
|
+
// - Fix C++ build on older versions of GCC.
|
6130
|
+
//
|
6131
|
+
// v0.9.8 - 2018-07-24
|
6132
|
+
// - Fix compilation errors.
|
6133
|
+
//
|
5736
6134
|
// v0.9.7 - 2018-07-05
|
5737
6135
|
// - Fix a warning.
|
5738
6136
|
//
|