gosu 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/dependencies/SDL/include/SDL.h +108 -14
  3. data/dependencies/SDL/include/SDL_assert.h +81 -50
  4. data/dependencies/SDL/include/SDL_atomic.h +135 -35
  5. data/dependencies/SDL/include/SDL_audio.h +960 -355
  6. data/dependencies/SDL/include/SDL_bits.h +11 -6
  7. data/dependencies/SDL/include/SDL_blendmode.h +91 -14
  8. data/dependencies/SDL/include/SDL_clipboard.h +30 -7
  9. data/dependencies/SDL/include/SDL_config.h +277 -27
  10. data/dependencies/SDL/include/SDL_config_android.h +13 -38
  11. data/dependencies/SDL/include/SDL_config_iphoneos.h +21 -62
  12. data/dependencies/SDL/include/SDL_config_macosx.h +23 -92
  13. data/dependencies/SDL/include/SDL_config_minimal.h +1 -4
  14. data/dependencies/SDL/include/SDL_config_pandora.h +15 -22
  15. data/dependencies/SDL/include/SDL_config_psp.h +16 -37
  16. data/dependencies/SDL/include/SDL_config_windows.h +28 -91
  17. data/dependencies/SDL/include/SDL_config_winrt.h +33 -61
  18. data/dependencies/SDL/include/SDL_config_wiz.h +28 -56
  19. data/dependencies/SDL/include/SDL_copying.h +1 -1
  20. data/dependencies/SDL/include/SDL_cpuinfo.h +331 -71
  21. data/dependencies/SDL/include/SDL_egl.h +906 -280
  22. data/dependencies/SDL/include/SDL_endian.h +101 -47
  23. data/dependencies/SDL/include/SDL_error.h +70 -19
  24. data/dependencies/SDL/include/SDL_events.h +387 -79
  25. data/dependencies/SDL/include/SDL_filesystem.h +73 -64
  26. data/dependencies/SDL/include/SDL_gamecontroller.h +585 -125
  27. data/dependencies/SDL/include/SDL_gesture.h +36 -6
  28. data/dependencies/SDL/include/SDL_haptic.h +304 -210
  29. data/dependencies/SDL/include/SDL_hidapi.h +451 -0
  30. data/dependencies/SDL/include/SDL_hints.h +1286 -897
  31. data/dependencies/SDL/include/SDL_joystick.h +577 -130
  32. data/dependencies/SDL/include/SDL_keyboard.h +162 -63
  33. data/dependencies/SDL/include/SDL_keycode.h +7 -5
  34. data/dependencies/SDL/include/SDL_loadso.h +42 -8
  35. data/dependencies/SDL/include/SDL_locale.h +34 -32
  36. data/dependencies/SDL/include/SDL_log.h +212 -19
  37. data/dependencies/SDL/include/SDL_main.h +72 -17
  38. data/dependencies/SDL/include/SDL_messagebox.h +70 -23
  39. data/dependencies/SDL/include/SDL_metal.h +27 -32
  40. data/dependencies/SDL/include/SDL_misc.h +19 -15
  41. data/dependencies/SDL/include/SDL_mouse.h +262 -110
  42. data/dependencies/SDL/include/SDL_mutex.h +286 -66
  43. data/dependencies/SDL/include/SDL_name.h +1 -1
  44. data/dependencies/SDL/include/SDL_opengl.h +1 -1
  45. data/dependencies/SDL/include/SDL_opengles.h +1 -1
  46. data/dependencies/SDL/include/SDL_opengles2.h +2 -2
  47. data/dependencies/SDL/include/SDL_pixels.h +199 -34
  48. data/dependencies/SDL/include/SDL_platform.h +39 -2
  49. data/dependencies/SDL/include/SDL_power.h +23 -10
  50. data/dependencies/SDL/include/SDL_quit.h +1 -1
  51. data/dependencies/SDL/include/SDL_rect.h +78 -28
  52. data/dependencies/SDL/include/SDL_render.h +1204 -472
  53. data/dependencies/SDL/include/SDL_revision.h +2 -2
  54. data/dependencies/SDL/include/SDL_rwops.h +605 -33
  55. data/dependencies/SDL/include/SDL_scancode.h +1 -1
  56. data/dependencies/SDL/include/SDL_sensor.h +76 -42
  57. data/dependencies/SDL/include/SDL_shape.h +38 -27
  58. data/dependencies/SDL/include/SDL_stdinc.h +96 -24
  59. data/dependencies/SDL/include/SDL_surface.h +571 -139
  60. data/dependencies/SDL/include/SDL_system.h +339 -101
  61. data/dependencies/SDL/include/SDL_syswm.h +50 -20
  62. data/dependencies/SDL/include/SDL_test.h +1 -1
  63. data/dependencies/SDL/include/SDL_test_assert.h +2 -2
  64. data/dependencies/SDL/include/SDL_test_common.h +23 -6
  65. data/dependencies/SDL/include/SDL_test_compare.h +1 -1
  66. data/dependencies/SDL/include/SDL_test_crc32.h +1 -1
  67. data/dependencies/SDL/include/SDL_test_font.h +3 -3
  68. data/dependencies/SDL/include/SDL_test_fuzzer.h +28 -26
  69. data/dependencies/SDL/include/SDL_test_harness.h +6 -6
  70. data/dependencies/SDL/include/SDL_test_images.h +1 -1
  71. data/dependencies/SDL/include/SDL_test_log.h +1 -1
  72. data/dependencies/SDL/include/SDL_test_md5.h +1 -1
  73. data/dependencies/SDL/include/SDL_test_memory.h +1 -1
  74. data/dependencies/SDL/include/SDL_test_random.h +2 -2
  75. data/dependencies/SDL/include/SDL_thread.h +226 -128
  76. data/dependencies/SDL/include/SDL_timer.h +129 -22
  77. data/dependencies/SDL/include/SDL_touch.h +48 -8
  78. data/dependencies/SDL/include/SDL_types.h +1 -1
  79. data/dependencies/SDL/include/SDL_version.h +72 -46
  80. data/dependencies/SDL/include/SDL_video.h +1266 -460
  81. data/dependencies/SDL/include/SDL_vulkan.h +100 -161
  82. data/dependencies/SDL/include/begin_code.h +22 -1
  83. data/dependencies/SDL/include/close_code.h +1 -1
  84. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  85. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  86. data/dependencies/SDL_sound/SDL_sound.c +83 -7
  87. data/dependencies/SDL_sound/SDL_sound.h +4 -4
  88. data/dependencies/SDL_sound/SDL_sound_aiff.c +9 -12
  89. data/dependencies/SDL_sound/SDL_sound_au.c +7 -7
  90. data/dependencies/SDL_sound/SDL_sound_coreaudio.c +3 -3
  91. data/dependencies/SDL_sound/SDL_sound_flac.c +1 -1
  92. data/dependencies/SDL_sound/SDL_sound_internal.h +17 -10
  93. data/dependencies/SDL_sound/SDL_sound_modplug.c +25 -27
  94. data/dependencies/SDL_sound/SDL_sound_mp3.c +5 -17
  95. data/dependencies/SDL_sound/SDL_sound_raw.c +11 -11
  96. data/dependencies/SDL_sound/SDL_sound_shn.c +8 -7
  97. data/dependencies/SDL_sound/SDL_sound_voc.c +6 -4
  98. data/dependencies/SDL_sound/SDL_sound_vorbis.c +6 -11
  99. data/dependencies/SDL_sound/SDL_sound_wav.c +35 -29
  100. data/dependencies/SDL_sound/dr_flac.h +618 -220
  101. data/dependencies/SDL_sound/dr_mp3.h +263 -94
  102. data/dependencies/SDL_sound/libmodplug/fastmix.c +58 -64
  103. data/dependencies/SDL_sound/libmodplug/libmodplug.h +25 -103
  104. data/dependencies/SDL_sound/libmodplug/load_669.c +14 -17
  105. data/dependencies/SDL_sound/libmodplug/load_amf.c +11 -7
  106. data/dependencies/SDL_sound/libmodplug/load_ams.c +65 -22
  107. data/dependencies/SDL_sound/libmodplug/load_dbm.c +8 -4
  108. data/dependencies/SDL_sound/libmodplug/load_dmf.c +55 -25
  109. data/dependencies/SDL_sound/libmodplug/load_far.c +9 -13
  110. data/dependencies/SDL_sound/libmodplug/load_gdm.c +448 -0
  111. data/dependencies/SDL_sound/libmodplug/load_it.c +45 -49
  112. data/dependencies/SDL_sound/libmodplug/load_mdl.c +80 -53
  113. data/dependencies/SDL_sound/libmodplug/load_med.c +20 -12
  114. data/dependencies/SDL_sound/libmodplug/load_mod.c +40 -15
  115. data/dependencies/SDL_sound/libmodplug/load_mt2.c +29 -17
  116. data/dependencies/SDL_sound/libmodplug/load_okt.c +12 -8
  117. data/dependencies/SDL_sound/libmodplug/load_psm.c +101 -78
  118. data/dependencies/SDL_sound/libmodplug/load_ptm.c +18 -17
  119. data/dependencies/SDL_sound/libmodplug/load_s3m.c +9 -7
  120. data/dependencies/SDL_sound/libmodplug/load_stm.c +3 -2
  121. data/dependencies/SDL_sound/libmodplug/load_ult.c +2 -2
  122. data/dependencies/SDL_sound/libmodplug/load_umx.c +315 -35
  123. data/dependencies/SDL_sound/libmodplug/load_xm.c +25 -21
  124. data/dependencies/SDL_sound/libmodplug/mmcmp.c +295 -149
  125. data/dependencies/SDL_sound/libmodplug/modplug.c +7 -123
  126. data/dependencies/SDL_sound/libmodplug/modplug.h +32 -29
  127. data/dependencies/SDL_sound/libmodplug/snd_dsp.c +0 -1
  128. data/dependencies/SDL_sound/libmodplug/snd_flt.c +2 -2
  129. data/dependencies/SDL_sound/libmodplug/snd_fx.c +24 -18
  130. data/dependencies/SDL_sound/libmodplug/sndfile.c +55 -156
  131. data/dependencies/SDL_sound/libmodplug/sndmix.c +7 -12
  132. data/dependencies/SDL_sound/libmodplug/tables.h +10 -15
  133. data/dependencies/SDL_sound/stb_vorbis.h +508 -325
  134. data/dependencies/{al_soft → mojoAL}/AL/al.h +38 -30
  135. data/dependencies/{al_soft → mojoAL}/AL/alc.h +27 -56
  136. data/dependencies/mojoAL/mojoal.c +4594 -0
  137. data/ext/gosu/extconf.rb +29 -30
  138. data/include/Gosu/Audio.hpp +70 -85
  139. data/include/Gosu/Color.hpp +19 -11
  140. data/include/Gosu/Font.hpp +40 -44
  141. data/include/Gosu/Graphics.hpp +58 -71
  142. data/include/Gosu/GraphicsBase.hpp +26 -33
  143. data/include/Gosu/Image.hpp +56 -62
  144. data/include/Gosu/ImageData.hpp +23 -27
  145. data/include/Gosu/Inspection.hpp +1 -4
  146. data/include/Gosu/TextInput.hpp +34 -40
  147. data/include/Gosu/Version.hpp +1 -1
  148. data/include/Gosu/Window.hpp +71 -70
  149. data/lib/SDL2.dll +0 -0
  150. data/lib/gosu/compat.rb +24 -37
  151. data/lib/gosu.rb +2 -2
  152. data/lib64/SDL2.dll +0 -0
  153. data/src/Audio.cpp +86 -86
  154. data/src/AudioFile.hpp +6 -6
  155. data/src/AudioFileAudioToolbox.cpp +1 -1
  156. data/src/AudioFileSDLSound.cpp +1 -1
  157. data/src/AudioImpl.hpp +5 -5
  158. data/src/BitmapIO.cpp +0 -20
  159. data/src/BlockAllocator.cpp +2 -1
  160. data/src/Channel.cpp +22 -20
  161. data/src/Color.cpp +12 -9
  162. data/src/EmptyImageData.hpp +15 -17
  163. data/src/FileUnix.cpp +1 -1
  164. data/src/FileWin.cpp +1 -1
  165. data/src/Font.cpp +48 -53
  166. data/src/Graphics.cpp +135 -143
  167. data/src/Image.cpp +41 -42
  168. data/src/Input.cpp +1 -1
  169. data/src/InputUIKit.cpp +1 -1
  170. data/src/LargeImageData.cpp +108 -101
  171. data/src/LargeImageData.hpp +17 -15
  172. data/src/Log.hpp +6 -6
  173. data/src/Macro.cpp +35 -37
  174. data/src/Macro.hpp +11 -11
  175. data/src/Math.cpp +8 -1
  176. data/src/Resolution.cpp +12 -7
  177. data/src/RubyGosu.cxx +5 -5
  178. data/src/TexChunk.cpp +50 -41
  179. data/src/TexChunk.hpp +22 -22
  180. data/src/Text.cpp +37 -37
  181. data/src/TextBuilder.cpp +60 -57
  182. data/src/TextBuilder.hpp +20 -20
  183. data/src/TextInput.cpp +127 -135
  184. data/src/TrueTypeFont.cpp +107 -107
  185. data/src/TrueTypeFont.hpp +39 -38
  186. data/src/TrueTypeFontApple.cpp +19 -22
  187. data/src/TrueTypeFontUnix.cpp +21 -26
  188. data/src/TrueTypeFontWin.cpp +30 -30
  189. data/src/Window.cpp +95 -86
  190. data/src/WindowUIKit.cpp +46 -49
  191. metadata +7 -17
  192. data/dependencies/SDL/include/SDL_config_os2.h +0 -188
  193. data/dependencies/SDL_sound/libmodplug/load_abc.c +0 -4725
  194. data/dependencies/SDL_sound/libmodplug/load_mid.c +0 -1405
  195. data/dependencies/SDL_sound/libmodplug/load_pat.c +0 -1143
  196. data/dependencies/SDL_sound/libmodplug/load_pat.h +0 -25
  197. data/dependencies/al_soft/AL/alext.h +0 -585
  198. data/dependencies/al_soft/AL/efx-creative.h +0 -3
  199. data/dependencies/al_soft/AL/efx-presets.h +0 -402
  200. data/dependencies/al_soft/AL/efx.h +0 -762
  201. data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
  202. data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
  203. data/lib/OpenAL32.dll +0 -0
  204. 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.9.7 - 2018-07-05
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 char* comments;
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 drflac_uint8* pTrackData;
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 char* pComments);
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
- #define DRFLAC_NO_CPUID
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
- __asm__ __volatile__ (
796
- "cpuid" : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0)
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
- #define DRFLAC_NO_CPUID
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
- #define DRFLAC_HAS_LZCNT_INTRINSIC
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 DRFLAC_HAS_BYTESWAP_INTRINSIC
825
- #elif defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
826
- #define DRFLAC_HAS_BYTESWAP_INTRINSIC
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) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)
829
- #define DRFLAC_HAS_BYTESWAP_INTRINSIC
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 DRFLAC_HAS_BYTESWAP_INTRINSIC
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 DRFLAC_HAS_BYTESWAP_INTRINSIC
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 DRFLAC_HAS_BYTESWAP_INTRINSIC
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) (sizeof((bs)->cache))
1281
- #define DRFLAC_CACHE_L1_SIZE_BITS(bs) (sizeof((bs)->cache)*8)
1282
- #define DRFLAC_CACHE_L1_BITS_REMAINING(bs) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - ((bs)->consumedBits))
1283
- #ifdef DRFLAC_64BIT
1284
- #define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~(((drflac_uint64)-1LL) >> (_bitCount)))
1285
- #else
1286
- #define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~(((drflac_uint32)-1) >> (_bitCount)))
1287
- #endif
1288
- #define DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (_bitCount))
1289
- #define DRFLAC_CACHE_L1_SELECT(bs, _bitCount) (((bs)->cache) & DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount))
1290
- #define DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SELECT((bs), _bitCount) >> DRFLAC_CACHE_L1_SELECTION_SHIFT((bs), _bitCount))
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(DRFLAC_CACHE_L1_SIZE_BITS(bs) - bs->consumedBits); // <-- Make sure the consumed bits are always set to zero. Other parts of the library depend on this property.
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
- #ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
1905
+ #ifdef DRFLAC_IMPLEMENT_CLZ_MSVC
1793
1906
  return drflac__clz_msvc(x);
1794
- #else
1907
+ #elif defined(DRFLAC_IMPLEMENT_CLZ_WATCOM)
1908
+ return drflac__clz_watcom(x);
1909
+ #else
1795
1910
  return drflac__clz_software(x);
1796
- #endif
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
- drflac_cache_t riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParam);
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)) >> (DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceLength));
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->cache & riceParamMask; // <-- This mask is OK because all bits after the first bits are always zero.
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
- #ifndef DR_FLAC_NO_CRC
2386
+ #ifndef DR_FLAC_NO_CRC
2274
2387
  drflac__update_crc16(bs);
2275
- #endif
2388
+ #endif
2276
2389
  bs->cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]);
2277
2390
  bs->consumedBits = 0;
2278
- #ifndef DR_FLAC_NO_CRC
2391
+ #ifndef DR_FLAC_NO_CRC
2279
2392
  bs->crc16Cache = bs->cache;
2280
- #endif
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)((resultHi >> resultHiShift) | DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountLo));
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
- return drflac__decode_samples_with_residual__rice__simple(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut);
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
- for (drflac_uint32 i = 0; i < count; ++i) {
2395
- drflac_uint32 zeroCountPart;
2396
- drflac_uint32 riceParamPart;
2397
- if (!drflac__read_rice_parts(bs, riceParam, &zeroCountPart, &riceParamPart)) {
2398
- return DRFLAC_FALSE;
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 > 0 && unencodedBitsPerSample <= 32);
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 (!drflac__read_int32(bs, unencodedBitsPerSample, pSamplesOut + i)) {
2414
- return DRFLAC_FALSE;
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 == 16) {
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 == 32) {
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 == 16) {
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 == 32) {
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
- #ifndef DR_FLAC_NO_CRC
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
- #endif
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
- metadata.data.vorbis_comment.vendorLength = drflac__le2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
3596
- metadata.data.vorbis_comment.vendor = pRunningData; pRunningData += metadata.data.vorbis_comment.vendorLength;
3597
- metadata.data.vorbis_comment.commentCount = drflac__le2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
3598
- metadata.data.vorbis_comment.comments = pRunningData;
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
- const char* pRunningData = (const char*)pRawData;
3622
- drflac_copy_memory(metadata.data.cuesheet.catalog, pRunningData, 128); pRunningData += 128;
3623
- metadata.data.cuesheet.leadInSampleCount = drflac__be2host_64(*(drflac_uint64*)pRunningData); pRunningData += 4;
3624
- metadata.data.cuesheet.isCD = ((pRunningData[0] & 0x80) >> 7) != 0; pRunningData += 259;
3625
- metadata.data.cuesheet.trackCount = pRunningData[0]; pRunningData += 1;
3626
- metadata.data.cuesheet.pTrackData = (const drflac_uint8*)pRunningData;
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
- metadata.data.picture.type = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
3651
- metadata.data.picture.mimeLength = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
3652
- metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength;
3653
- metadata.data.picture.descriptionLength = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
3654
- metadata.data.picture.description = pRunningData;
3655
- metadata.data.picture.width = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
3656
- metadata.data.picture.height = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
3657
- metadata.data.picture.colorDepth = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
3658
- metadata.data.picture.indexColorCount = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
3659
- metadata.data.picture.pictureDataSize = drflac__be2host_32(*(drflac_uint32*)pRunningData); pRunningData += 4;
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 > 0 || (offset == 0 && origin == drflac_seek_origin_start));
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 > 0 || (offset == 0 && origin == drflac_seek_origin_start));
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 drflac_file drflac__open_file_handle(const char* filename)
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 (drflac_file)pFile;
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
- drflac_file file = drflac__open_file_handle(filename);
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
- drflac__close_file_handle(file);
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
- drflac_file file = drflac__open_file_handle(filename);
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
- drflac__close_file_handle(file);
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 > 0 || (offset == 0 && origin == drflac_seek_origin_start));
4986
- drflac_assert(offset <= (drflac_int64)memoryStream->dataSize);
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
- memoryStream->currentReadPos = memoryStream->dataSize; // Trying to seek too far forward.
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
- memoryStream->currentReadPos = memoryStream->dataSize; // Trying to seek too far forward.
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
- drflac__close_file_handle((drflac_file)pFlac->bs.pUserData);
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
- drflac__close_file_handle((drflac_file)oggbs->pUserData);
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 <<= ((32 - pFlac->bitsPerSample) + pFlac->currentFrame.subframes[channelIndex].wastedBitsPerSample);
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 << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample);
5277
- bufferOut[i*2+1] = right << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample);
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 << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample);
5292
- bufferOut[i*2+1] = right << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample);
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 side = pDecodedSamples1[i];
5303
- int mid = (((drflac_uint32)pDecodedSamples0[i]) << 1) | (side & 0x01);
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 + pFlac->currentFrame.subframes[0].wastedBitsPerSample);
5306
- bufferOut[i*2+1] = ((mid - side) >> 1) << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample);
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
- #ifndef DR_FLAC_NO_OGG
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
- #endif
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
- // I couldn't figure out where SIZE_MAX was defined for VC6. If anybody knows, let me know.
5487
- #if defined(_MSC_VER) && _MSC_VER <= 1200
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
- #define SIZE_MAX 0xFFFFFFFF
5492
- #endif
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 > SIZE_MAX) { \
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
  //