Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
miniaudio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
miniaudio
Commits
6edd3cfd
Commit
6edd3cfd
authored
Feb 15, 2020
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update stb_vorbis.
parent
259d8aa2
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
339 additions
and
233 deletions
+339
-233
extras/stb_vorbis.c
extras/stb_vorbis.c
+339
-233
No files found.
extras/stb_vorbis.c
View file @
6edd3cfd
// Ogg Vorbis audio decoder - v1.1
1
- public domain
// Ogg Vorbis audio decoder - v1.1
9
- public domain
// http://nothings.org/stb_vorbis/
//
// Original version written by Sean Barrett in 2007.
//
// Originally sponsored by RAD Game Tools. Seeking
sponsored
//
by Phillip Bennefall, Marc Andersen, Aaron Baker, Elias Software
,
// Aras Pranckevicius, and Sean Barrett.
// Originally sponsored by RAD Game Tools. Seeking
implementation
//
sponsored by Phillip Bennefall, Marc Andersen, Aaron Baker
,
//
Elias Software,
Aras Pranckevicius, and Sean Barrett.
//
// LICENSE
//
...
...
@@ -26,26 +26,36 @@
// Terje Mathisen Niklas Frykholm Andy Hill
// Casey Muratori John Bolton Gargaj
// Laurent Gomila Marc LeBlanc Ronny Chevalier
// Bernhard Wodo Evan Balster
alxprd@github
// Bernhard Wodo Evan Balster
github:alxprd
// Tom Beaumont Ingo Leitgeb Nicolas Guillemot
// Phillip Bennefall Rohit Thiago Goulart
// manxorist@github saga musix github:infatum
// github:manxorist saga musix github:infatum
// Timur Gagiev Maxwell Koo Peter Waller
// github:audinowho Dougall Johnson
//
// Partial history:
// 1.11 - 2017/07/23 - fix MinGW compilation
// 1.10 - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory
// 1.09 - 2016/04/04 - back out 'truncation of last frame' fix from previous version
// 1.08 - 2016/04/02 - warnings; setup memory leaks; truncation of last frame
// 1.07 - 2015/01/16 - fixes for crashes on invalid files; warning fixes; const
// 1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson)
// 1.19 - 2020-02-05 - warnings
// 1.18 - 2020-02-02 - fix seek bugs; parse header comments; misc warnings etc.
// 1.17 - 2019-07-08 - fix CVE-2019-13217..CVE-2019-13223 (by ForAllSecure)
// 1.16 - 2019-03-04 - fix warnings
// 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found
// 1.14 - 2018-02-11 - delete bogus dealloca usage
// 1.13 - 2018-01-29 - fix truncation of last frame (hopefully)
// 1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
// 1.11 - 2017-07-23 - fix MinGW compilation
// 1.10 - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory
// 1.09 - 2016-04-04 - back out 'truncation of last frame' fix from previous version
// 1.08 - 2016-04-02 - warnings; setup memory leaks; truncation of last frame
// 1.07 - 2015-01-16 - fixes for crashes on invalid files; warning fixes; const
// 1.06 - 2015-08-31 - full, correct support for seeking API (Dougall Johnson)
// some crash fixes when out of memory or with corrupt files
// fix some inappropriately signed shifts
// 1.05 - 2015
/04/
19 - don't define __forceinline if it's redundant
// 1.04 - 2014
/08/
27 - fix missing const-correct case in API
// 1.03 - 2014
/08/
07 - warning fixes
// 1.02 - 2014
/07/
09 - declare qsort comparison as explicitly _cdecl in Windows
// 1.01 - 2014
/06/
18 - fix stb_vorbis_get_samples_float (interleaved was correct)
// 1.0 - 2014
/05/
26 - fix memory leaks; fix warnings; fix bugs in >2-channel;
// 1.05 - 2015
-04-
19 - don't define __forceinline if it's redundant
// 1.04 - 2014
-08-
27 - fix missing const-correct case in API
// 1.03 - 2014
-08-
07 - warning fixes
// 1.02 - 2014
-07-
09 - declare qsort comparison as explicitly _cdecl in Windows
// 1.01 - 2014
-06-
18 - fix stb_vorbis_get_samples_float (interleaved was correct)
// 1.0 - 2014
-05-
26 - fix memory leaks; fix warnings; fix bugs in >2-channel;
// (API change) report sample rate for decode-full-file funcs
//
// See end of file for full version history.
...
...
@@ -123,9 +133,20 @@ typedef struct
int
max_frame_size
;
}
stb_vorbis_info
;
typedef
struct
{
char
*
vendor
;
int
comment_list_length
;
char
**
comment_list
;
}
stb_vorbis_comment
;
// get general information about the file
extern
stb_vorbis_info
stb_vorbis_get_info
(
stb_vorbis
*
f
);
// get ogg comments
extern
stb_vorbis_comment
stb_vorbis_get_comment
(
stb_vorbis
*
f
);
// get the last error detected (clears it, too)
extern
int
stb_vorbis_get_error
(
stb_vorbis
*
f
);
...
...
@@ -249,7 +270,7 @@ extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close,
// create an ogg vorbis decoder from an open FILE *, looking for a stream at
// the _current_ seek point (ftell). on failure, returns NULL and sets *error.
// note that stb_vorbis must "own" this stream; if you seek it in between
// calls to stb_vorbis, it will become confused. Morever, if you attempt to
// calls to stb_vorbis, it will become confused. More
o
ver, if you attempt to
// perform stb_vorbis_seek_*() operations on this file, it will assume it
// owns the _entire_ rest of the file after the start point. Use the next
// function, stb_vorbis_open_file_section(), to limit it.
...
...
@@ -370,7 +391,8 @@ enum STBVorbisError
VORBIS_invalid_first_page
,
VORBIS_bad_packet_type
,
VORBIS_cant_find_last_page
,
VORBIS_seek_failed
VORBIS_seek_failed
,
VORBIS_ogg_skeleton_not_supported
};
...
...
@@ -751,6 +773,10 @@ struct stb_vorbis
unsigned
int
temp_memory_required
;
unsigned
int
setup_temp_memory_required
;
char
*
vendor
;
int
comment_list_length
;
char
**
comment_list
;
// input config
#ifndef STB_VORBIS_NO_STDIO
FILE
*
f
;
...
...
@@ -766,8 +792,11 @@ struct stb_vorbis
uint8
push_mode
;
// the page to seek to when seeking to start, may be zero
uint32
first_audio_page_offset
;
// p_first is the page on which the first audio packet ends
// (but not necessarily the page on which it starts)
ProbedPage
p_first
,
p_last
;
// memory management
...
...
@@ -816,7 +845,7 @@ struct stb_vorbis
int
current_loc_valid
;
// per-blocksize precomputed data
// twiddle factors
float
*
A
[
2
],
*
B
[
2
],
*
C
[
2
];
float
*
window
[
2
];
...
...
@@ -880,11 +909,7 @@ static int error(vorb *f, enum STBVorbisError e)
#define array_size_required(count,size) (count*(sizeof(void *)+(size)))
#define temp_alloc(f,size) (f->alloc.alloc_buffer ? setup_temp_malloc(f,size) : alloca(size))
#ifdef dealloca
#define temp_free(f,p) (f->alloc.alloc_buffer ? 0 : dealloca(size))
#else
#define temp_free(f,p) 0
#endif
#define temp_free(f,p) (void)0
#define temp_alloc_save(f) ((f)->temp_offset)
#define temp_alloc_restore(f,p) ((f)->temp_offset = (p))
...
...
@@ -905,7 +930,7 @@ static void *make_block_array(void *mem, int count, int size)
static
void
*
setup_malloc
(
vorb
*
f
,
int
sz
)
{
sz
=
(
sz
+
3
)
&
~
3
;
sz
=
(
sz
+
7
)
&
~
7
;
// round up to nearest 8 for alignment of future allocs.
f
->
setup_memory_required
+=
sz
;
if
(
f
->
alloc
.
alloc_buffer
)
{
void
*
p
=
(
char
*
)
f
->
alloc
.
alloc_buffer
+
f
->
setup_offset
;
...
...
@@ -924,7 +949,7 @@ static void setup_free(vorb *f, void *p)
static
void
*
setup_temp_malloc
(
vorb
*
f
,
int
sz
)
{
sz
=
(
sz
+
3
)
&
~
3
;
sz
=
(
sz
+
7
)
&
~
7
;
// round up to nearest 8 for alignment of future allocs.
if
(
f
->
alloc
.
alloc_buffer
)
{
if
(
f
->
temp_offset
-
sz
<
f
->
setup_offset
)
return
NULL
;
f
->
temp_offset
-=
sz
;
...
...
@@ -1073,7 +1098,7 @@ static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values)
assert
(
z
>=
0
&&
z
<
32
);
available
[
z
]
=
0
;
add_entry
(
c
,
bit_reverse
(
res
),
i
,
m
++
,
len
[
i
],
values
);
// prop
o
gate availability up the tree
// prop
a
gate availability up the tree
if
(
z
!=
len
[
i
])
{
assert
(
len
[
i
]
>=
0
&&
len
[
i
]
<
32
);
for
(
y
=
len
[
i
];
y
>
z
;
--
y
)
{
...
...
@@ -1142,7 +1167,7 @@ static void compute_sorted_huffman(Codebook *c, uint8 *lengths, uint32 *values)
if
(
!
c
->
sparse
)
{
int
k
=
0
;
for
(
i
=
0
;
i
<
c
->
entries
;
++
i
)
if
(
include_in_sort
(
c
,
lengths
[
i
]))
if
(
include_in_sort
(
c
,
lengths
[
i
]))
c
->
sorted_codewords
[
k
++
]
=
bit_reverse
(
c
->
codewords
[
i
]);
assert
(
k
==
c
->
sorted_entries
);
}
else
{
...
...
@@ -1199,8 +1224,10 @@ static int lookup1_values(int entries, int dim)
int
r
=
(
int
)
floor
(
exp
((
float
)
log
((
float
)
entries
)
/
dim
));
if
((
int
)
floor
(
pow
((
float
)
r
+
1
,
dim
))
<=
entries
)
// (int) cast for MinGW warning;
++
r
;
// floor() to avoid _ftol() when non-CRT
assert
(
pow
((
float
)
r
+
1
,
dim
)
>
entries
);
assert
((
int
)
floor
(
pow
((
float
)
r
,
dim
))
<=
entries
);
// (int),floor() as above
if
(
pow
((
float
)
r
+
1
,
dim
)
<=
entries
)
return
-
1
;
if
((
int
)
floor
(
pow
((
float
)
r
,
dim
))
>
entries
)
return
-
1
;
return
r
;
}
...
...
@@ -1323,7 +1350,7 @@ static int getn(vorb *z, uint8 *data, int n)
return
1
;
}
#ifndef STB_VORBIS_NO_STDIO
#ifndef STB_VORBIS_NO_STDIO
if
(
fread
(
data
,
n
,
1
,
z
->
f
)
==
1
)
return
1
;
else
{
...
...
@@ -1398,12 +1425,15 @@ static int capture_pattern(vorb *f)
static
int
start_page_no_capturepattern
(
vorb
*
f
)
{
uint32
loc0
,
loc1
,
n
;
if
(
f
->
first_decode
&&
!
IS_PUSH_MODE
(
f
))
{
f
->
p_first
.
page_start
=
stb_vorbis_get_file_offset
(
f
)
-
4
;
}
// stream structure version
if
(
0
!=
get8
(
f
))
return
error
(
f
,
VORBIS_invalid_stream_structure_version
);
// header flag
f
->
page_flag
=
get8
(
f
);
// absolute granule position
loc0
=
get32
(
f
);
loc0
=
get32
(
f
);
loc1
=
get32
(
f
);
// @TODO: validate loc0,loc1 as valid positions?
// stream serial number -- vorbis doesn't interleave, so discard
...
...
@@ -1434,15 +1464,12 @@ static int start_page_no_capturepattern(vorb *f)
}
if
(
f
->
first_decode
)
{
int
i
,
len
;
ProbedPage
p
;
len
=
0
;
for
(
i
=
0
;
i
<
f
->
segment_count
;
++
i
)
len
+=
f
->
segments
[
i
];
len
+=
27
+
f
->
segment_count
;
p
.
page_start
=
f
->
first_audio_page_offset
;
p
.
page_end
=
p
.
page_start
+
len
;
p
.
last_decoded_sample
=
loc0
;
f
->
p_first
=
p
;
f
->
p_first
.
page_end
=
f
->
p_first
.
page_start
+
len
;
f
->
p_first
.
last_decoded_sample
=
loc0
;
}
f
->
next_seg
=
0
;
return
TRUE
;
...
...
@@ -1533,6 +1560,16 @@ static int get8_packet(vorb *f)
return
x
;
}
static
int
get32_packet
(
vorb
*
f
)
{
uint32
x
;
x
=
get8_packet
(
f
);
x
+=
get8_packet
(
f
)
<<
8
;
x
+=
get8_packet
(
f
)
<<
16
;
x
+=
(
uint32
)
get8_packet
(
f
)
<<
24
;
return
x
;
}
static
void
flush_packet
(
vorb
*
f
)
{
while
(
get8_packet_raw
(
f
)
!=
EOP
);
...
...
@@ -1888,69 +1925,69 @@ static int predict_point(int x, int x0, int x1, int y0, int y1)
// the following table is block-copied from the specification
static
float
inverse_db_table
[
256
]
=
{
1.0649863e-07
f
,
1.1341951e-07
f
,
1.2079015e-07
f
,
1.2863978e-07
f
,
1.3699951e-07
f
,
1.4590251e-07
f
,
1.5538408e-07
f
,
1.6548181e-07
f
,
1.7623575e-07
f
,
1.8768855e-07
f
,
1.9988561e-07
f
,
2.1287530e-07
f
,
2.2670913e-07
f
,
2.4144197e-07
f
,
2.5713223e-07
f
,
2.7384213e-07
f
,
2.9163793e-07
f
,
3.1059021e-07
f
,
3.3077411e-07
f
,
3.5226968e-07
f
,
3.7516214e-07
f
,
3.9954229e-07
f
,
4.2550680e-07
f
,
4.5315863e-07
f
,
4.8260743e-07
f
,
5.1396998e-07
f
,
5.4737065e-07
f
,
5.8294187e-07
f
,
6.2082472e-07
f
,
6.6116941e-07
f
,
7.0413592e-07
f
,
7.4989464e-07
f
,
7.9862701e-07
f
,
8.5052630e-07
f
,
9.0579828e-07
f
,
9.6466216e-07
f
,
1.0273513e-06
f
,
1.0941144e-06
f
,
1.1652161e-06
f
,
1.2409384e-06
f
,
1.3215816e-06
f
,
1.4074654e-06
f
,
1.4989305e-06
f
,
1.5963394e-06
f
,
1.7000785e-06
f
,
1.8105592e-06
f
,
1.9282195e-06
f
,
2.0535261e-06
f
,
2.1869758e-06
f
,
2.3290978e-06
f
,
2.4804557e-06
f
,
2.6416497e-06
f
,
2.8133190e-06
f
,
2.9961443e-06
f
,
3.1908506e-06
f
,
3.3982101e-06
f
,
3.6190449e-06
f
,
3.8542308e-06
f
,
4.1047004e-06
f
,
4.3714470e-06
f
,
4.6555282e-06
f
,
4.9580707e-06
f
,
5.2802740e-06
f
,
5.6234160e-06
f
,
5.9888572e-06
f
,
6.3780469e-06
f
,
6.7925283e-06
f
,
7.2339451e-06
f
,
7.7040476e-06
f
,
8.2047000e-06
f
,
8.7378876e-06
f
,
9.3057248e-06
f
,
9.9104632e-06
f
,
1.0554501e-05
f
,
1.1240392e-05
f
,
1.1970856e-05
f
,
1.2748789e-05
f
,
1.3577278e-05
f
,
1.4459606e-05
f
,
1.5399272e-05
f
,
1.6400004e-05
f
,
1.7465768e-05
f
,
1.8600792e-05
f
,
1.9809576e-05
f
,
2.1096914e-05
f
,
2.2467911e-05
f
,
2.3928002e-05
f
,
2.5482978e-05
f
,
2.7139006e-05
f
,
2.8902651e-05
f
,
3.0780908e-05
f
,
3.2781225e-05
f
,
3.4911534e-05
f
,
3.7180282e-05
f
,
3.9596466e-05
f
,
4.2169667e-05
f
,
4.4910090e-05
f
,
4.7828601e-05
f
,
5.0936773e-05
f
,
5.4246931e-05
f
,
5.7772202e-05
f
,
6.1526565e-05
f
,
6.5524908e-05
f
,
6.9783085e-05
f
,
7.4317983e-05
f
,
7.9147585e-05
f
,
8.4291040e-05
f
,
8.9768747e-05
f
,
9.5602426e-05
f
,
0
.
000101
81521
f
,
0
.
00010
843174
f
,
0
.
00011547
824
f
,
0
.
000122
98267
f
,
0
.
000130
97477
f
,
0
.
00013
948625
f
,
0
.
00014
855085
f
,
0
.
00015
820453
f
,
0
.
00016
848555
f
,
0
.
00017
943469
f
,
0
.
0001
9109536
f
,
0
.
000203513
82
f
,
0
.
00021673
929
f
,
0
.
000230
82423
f
,
0
.
000245
82449
f
,
0
.
0002617
9955
f
,
0
.
00027
881276
f
,
0
.
0002
9693158
f
,
0
.
000316227
87
f
,
0
.
00033677
814
f
,
0
.
00035
866388
f
,
0
.
0003
8197188
f
,
0
.
0004067
9456
f
,
0
.
00043323036
f
,
0
.
0004613
8411
f
,
0
.
0004
9136745
f
,
0
.
0005232
9927
f
,
0
.
00055730621
f
,
0
.
0005
9352311
f
,
0
.
0006320
9358
f
,
0
.
0006731705
8
f
,
0
.
000716
91700
f
,
0
.
00076350630
f
,
0
.
000
81312324
f
,
0
.
000
86596457
f
,
0
.
000
92223983
f
,
0
.
000
98217216
f
,
0
.
001045
9992
f
,
0
.
001113
9742
f
,
0
.
0011
863665
f
,
0
.
0012634633
f
,
0
.
0013455702
f
,
0
.
001433012
9
f
,
0
.
00152613
82
f
,
0
.
0016253153
f
,
0
.
001730
9374
f
,
0
.
001
8434235
f
,
0
.
001
9632195
f
,
0
.
0020
908006
f
,
0
.
0022266726
f
,
0
.
0023713743
f
,
0
.
00252547
95
f
,
0
.
0026
895994
f
,
0
.
002
8643847
f
,
0
.
00305052
86
f
,
0
.
00324
87691
f
,
0
.
00345
98925
f
,
0
.
0036
847358
f
,
0
.
003
9241906
f
,
0
.
00417
92066
f
,
0
.
0044507
950
f
,
0
.
004740032
8
f
,
0
.
00504
80668
f
,
0
.
00537611
86
f
,
0
.
0057254
891
f
,
0
.
0060
975636
f
,
0
.
0064
938176
f
,
0
.
006
9158225
f
,
0
.
0073652516
f
,
0
.
007
8438871
f
,
0
.
00
83536271
f
,
0
.
00
88964928
f
,
0
.
00
9474637
f
,
0
.
0100
90352
f
,
0
.
0107460
80
f
,
0
.
011444421
f
,
0
.
0121
88144
f
,
0
.
012
980198
f
,
0
.
013
823725
f
,
0
.
01472206
8
f
,
0
.
01567
8791
f
,
0
.
0166
97687
f
,
0
.
0177
82797
f
,
0
.
01
8938423
f
,
0
.
02016
9149
f
,
0
.
02147
9854
f
,
0
.
022
875735
f
,
0
.
024362330
f
,
0
.
025
945531
f
,
0
.
02763161
8
f
,
0
.
02
9427276
f
,
0
.
03133
9626
f
,
0
.
033376252
f
,
0
.
03554522
8
f
,
0
.
037
855157
f
,
0
.
0403151
99
f
,
0
.
042
935108
f
,
0
.
045725273
f
,
0
.
04
8696758
f
,
0
.
051
861348
f
,
0
.
0552315
91
f
,
0
.
05
8820850
f
,
0
.
062643361
f
,
0
.
06671427
9
f
,
0
.
07104
9749
f
,
0
.
075666
962
f
,
0
.
080584227
f
,
0
.
085821044
f
,
0
.
091398179
f
,
0
.
097337747
f
,
0
.
10366330
f
,
0
.
11039993
f
,
0
.
11757434
f
,
0
.
12521498
f
,
0
.
13335215
f
,
0
.
14201813
f
,
0
.
15124727
f
,
0
.
16107617
f
,
0
.
17154380
f
,
0
.
18269168
f
,
0
.
19456402
f
,
0
.
20720788
f
,
0
.
22067342
f
,
0
.
23501402
f
,
0
.
25028656
f
,
0
.
26655159
f
,
0
.
28387361
f
,
0
.
30232132
f
,
0
.
32196786
f
,
0
.
34289114
f
,
0
.
36517414
f
,
0
.
38890521
f
,
0
.
41417847
f
,
0
.
44109412
f
,
0
.
46975890
f
,
0
.
50028648
f
,
0
.
53279791
f
,
0
.
56742212
f
,
0
.
60429640
f
,
0
.
64356699
f
,
0
.
68538959
f
,
0
.
72993007
f
,
0
.
77736504
f
,
1.0649863e-07
f
,
1.1341951e-07
f
,
1.2079015e-07
f
,
1.2863978e-07
f
,
1.3699951e-07
f
,
1.4590251e-07
f
,
1.5538408e-07
f
,
1.6548181e-07
f
,
1.7623575e-07
f
,
1.8768855e-07
f
,
1.9988561e-07
f
,
2.1287530e-07
f
,
2.2670913e-07
f
,
2.4144197e-07
f
,
2.5713223e-07
f
,
2.7384213e-07
f
,
2.9163793e-07
f
,
3.1059021e-07
f
,
3.3077411e-07
f
,
3.5226968e-07
f
,
3.7516214e-07
f
,
3.9954229e-07
f
,
4.2550680e-07
f
,
4.5315863e-07
f
,
4.8260743e-07
f
,
5.1396998e-07
f
,
5.4737065e-07
f
,
5.8294187e-07
f
,
6.2082472e-07
f
,
6.6116941e-07
f
,
7.0413592e-07
f
,
7.4989464e-07
f
,
7.9862701e-07
f
,
8.5052630e-07
f
,
9.0579828e-07
f
,
9.6466216e-07
f
,
1.0273513e-06
f
,
1.0941144e-06
f
,
1.1652161e-06
f
,
1.2409384e-06
f
,
1.3215816e-06
f
,
1.4074654e-06
f
,
1.4989305e-06
f
,
1.5963394e-06
f
,
1.7000785e-06
f
,
1.8105592e-06
f
,
1.9282195e-06
f
,
2.0535261e-06
f
,
2.1869758e-06
f
,
2.3290978e-06
f
,
2.4804557e-06
f
,
2.6416497e-06
f
,
2.8133190e-06
f
,
2.9961443e-06
f
,
3.1908506e-06
f
,
3.3982101e-06
f
,
3.6190449e-06
f
,
3.8542308e-06
f
,
4.1047004e-06
f
,
4.3714470e-06
f
,
4.6555282e-06
f
,
4.9580707e-06
f
,
5.2802740e-06
f
,
5.6234160e-06
f
,
5.9888572e-06
f
,
6.3780469e-06
f
,
6.7925283e-06
f
,
7.2339451e-06
f
,
7.7040476e-06
f
,
8.2047000e-06
f
,
8.7378876e-06
f
,
9.3057248e-06
f
,
9.9104632e-06
f
,
1.0554501e-05
f
,
1.1240392e-05
f
,
1.1970856e-05
f
,
1.2748789e-05
f
,
1.3577278e-05
f
,
1.4459606e-05
f
,
1.5399272e-05
f
,
1.6400004e-05
f
,
1.7465768e-05
f
,
1.8600792e-05
f
,
1.9809576e-05
f
,
2.1096914e-05
f
,
2.2467911e-05
f
,
2.3928002e-05
f
,
2.5482978e-05
f
,
2.7139006e-05
f
,
2.8902651e-05
f
,
3.0780908e-05
f
,
3.2781225e-05
f
,
3.4911534e-05
f
,
3.7180282e-05
f
,
3.9596466e-05
f
,
4.2169667e-05
f
,
4.4910090e-05
f
,
4.7828601e-05
f
,
5.0936773e-05
f
,
5.4246931e-05
f
,
5.7772202e-05
f
,
6.1526565e-05
f
,
6.5524908e-05
f
,
6.9783085e-05
f
,
7.4317983e-05
f
,
7.9147585e-05
f
,
8.4291040e-05
f
,
8.9768747e-05
f
,
9.5602426e-05
f
,
0
.
000101
81521
f
,
0
.
00010
843174
f
,
0
.
00011547
824
f
,
0
.
000122
98267
f
,
0
.
000130
97477
f
,
0
.
00013
948625
f
,
0
.
00014
855085
f
,
0
.
00015
820453
f
,
0
.
00016
848555
f
,
0
.
00017
943469
f
,
0
.
0001
9109536
f
,
0
.
000203513
82
f
,
0
.
00021673
929
f
,
0
.
000230
82423
f
,
0
.
000245
82449
f
,
0
.
0002617
9955
f
,
0
.
00027
881276
f
,
0
.
0002
9693158
f
,
0
.
000316227
87
f
,
0
.
00033677
814
f
,
0
.
00035
866388
f
,
0
.
0003
8197188
f
,
0
.
0004067
9456
f
,
0
.
00043323036
f
,
0
.
0004613
8411
f
,
0
.
0004
9136745
f
,
0
.
0005232
9927
f
,
0
.
00055730621
f
,
0
.
0005
9352311
f
,
0
.
0006320
9358
f
,
0
.
0006731705
8
f
,
0
.
000716
91700
f
,
0
.
00076350630
f
,
0
.
000
81312324
f
,
0
.
000
86596457
f
,
0
.
000
92223983
f
,
0
.
000
98217216
f
,
0
.
001045
9992
f
,
0
.
001113
9742
f
,
0
.
0011
863665
f
,
0
.
0012634633
f
,
0
.
0013455702
f
,
0
.
001433012
9
f
,
0
.
00152613
82
f
,
0
.
0016253153
f
,
0
.
001730
9374
f
,
0
.
001
8434235
f
,
0
.
001
9632195
f
,
0
.
0020
908006
f
,
0
.
0022266726
f
,
0
.
0023713743
f
,
0
.
00252547
95
f
,
0
.
0026
895994
f
,
0
.
002
8643847
f
,
0
.
00305052
86
f
,
0
.
00324
87691
f
,
0
.
00345
98925
f
,
0
.
0036
847358
f
,
0
.
003
9241906
f
,
0
.
00417
92066
f
,
0
.
0044507
950
f
,
0
.
004740032
8
f
,
0
.
00504
80668
f
,
0
.
00537611
86
f
,
0
.
0057254
891
f
,
0
.
0060
975636
f
,
0
.
0064
938176
f
,
0
.
006
9158225
f
,
0
.
0073652516
f
,
0
.
007
8438871
f
,
0
.
00
83536271
f
,
0
.
00
88964928
f
,
0
.
00
9474637
f
,
0
.
0100
90352
f
,
0
.
0107460
80
f
,
0
.
011444421
f
,
0
.
0121
88144
f
,
0
.
012
980198
f
,
0
.
013
823725
f
,
0
.
01472206
8
f
,
0
.
01567
8791
f
,
0
.
0166
97687
f
,
0
.
0177
82797
f
,
0
.
01
8938423
f
,
0
.
02016
9149
f
,
0
.
02147
9854
f
,
0
.
022
875735
f
,
0
.
024362330
f
,
0
.
025
945531
f
,
0
.
02763161
8
f
,
0
.
02
9427276
f
,
0
.
03133
9626
f
,
0
.
033376252
f
,
0
.
03554522
8
f
,
0
.
037
855157
f
,
0
.
0403151
99
f
,
0
.
042
935108
f
,
0
.
045725273
f
,
0
.
04
8696758
f
,
0
.
051
861348
f
,
0
.
0552315
91
f
,
0
.
05
8820850
f
,
0
.
062643361
f
,
0
.
06671427
9
f
,
0
.
07104
9749
f
,
0
.
075666
962
f
,
0
.
080584227
f
,
0
.
085821044
f
,
0
.
091398179
f
,
0
.
097337747
f
,
0
.
10366330
f
,
0
.
11039993
f
,
0
.
11757434
f
,
0
.
12521498
f
,
0
.
13335215
f
,
0
.
14201813
f
,
0
.
15124727
f
,
0
.
16107617
f
,
0
.
17154380
f
,
0
.
18269168
f
,
0
.
19456402
f
,
0
.
20720788
f
,
0
.
22067342
f
,
0
.
23501402
f
,
0
.
25028656
f
,
0
.
26655159
f
,
0
.
28387361
f
,
0
.
30232132
f
,
0
.
32196786
f
,
0
.
34289114
f
,
0
.
36517414
f
,
0
.
38890521
f
,
0
.
41417847
f
,
0
.
44109412
f
,
0
.
46975890
f
,
0
.
50028648
f
,
0
.
53279791
f
,
0
.
56742212
f
,
0
.
60429640
f
,
0
.
64356699
f
,
0
.
68538959
f
,
0
.
72993007
f
,
0
.
77736504
f
,
0
.
82788260
f
,
0
.
88168307
f
,
0
.
9389798
f
,
1
.
0
f
};
...
...
@@ -2010,7 +2047,7 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y
ady
-=
abs
(
base
)
*
adx
;
if
(
x1
>
n
)
x1
=
n
;
if
(
x
<
x1
)
{
LINE_OP
(
output
[
x
],
inverse_db_table
[
y
]);
LINE_OP
(
output
[
x
],
inverse_db_table
[
y
&
255
]);
for
(
++
x
;
x
<
x1
;
++
x
)
{
err
+=
ady
;
if
(
err
>=
adx
)
{
...
...
@@ -2018,7 +2055,7 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y
y
+=
sy
;
}
else
y
+=
base
;
LINE_OP
(
output
[
x
],
inverse_db_table
[
y
]);
LINE_OP
(
output
[
x
],
inverse_db_table
[
y
&
255
]);
}
}
}
...
...
@@ -2042,6 +2079,8 @@ static int residue_decode(vorb *f, Codebook *book, float *target, int offset, in
return
TRUE
;
}
// n is 1/2 of the blocksize --
// specification: "Correct per-vector decode length is [n]/2"
static
void
decode_residue
(
vorb
*
f
,
float
*
residue_buffers
[],
int
ch
,
int
n
,
int
rn
,
uint8
*
do_not_decode
)
{
int
i
,
j
,
pass
;
...
...
@@ -2049,7 +2088,10 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int
int
rtype
=
f
->
residue_types
[
rn
];
int
c
=
r
->
classbook
;
int
classwords
=
f
->
codebooks
[
c
].
dimensions
;
int
n_read
=
r
->
end
-
r
->
begin
;
unsigned
int
actual_size
=
rtype
==
2
?
n
*
2
:
n
;
unsigned
int
limit_r_begin
=
(
r
->
begin
<
actual_size
?
r
->
begin
:
actual_size
);
unsigned
int
limit_r_end
=
(
r
->
end
<
actual_size
?
r
->
end
:
actual_size
);
int
n_read
=
limit_r_end
-
limit_r_begin
;
int
part_read
=
n_read
/
r
->
part_size
;
int
temp_alloc_point
=
temp_alloc_save
(
f
);
#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
...
...
@@ -2119,47 +2161,7 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int
++
class_set
;
#endif
}
}
else
if
(
ch
==
1
)
{
while
(
pcount
<
part_read
)
{
int
z
=
r
->
begin
+
pcount
*
r
->
part_size
;
int
c_inter
=
0
,
p_inter
=
z
;
if
(
pass
==
0
)
{
Codebook
*
c
=
f
->
codebooks
+
r
->
classbook
;
int
q
;
DECODE
(
q
,
f
,
c
);
if
(
q
==
EOP
)
goto
done
;
#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
part_classdata
[
0
][
class_set
]
=
r
->
classdata
[
q
];
#else
for
(
i
=
classwords
-
1
;
i
>=
0
;
--
i
)
{
classifications
[
0
][
i
+
pcount
]
=
q
%
r
->
classifications
;
q
/=
r
->
classifications
;
}
#endif
}
for
(
i
=
0
;
i
<
classwords
&&
pcount
<
part_read
;
++
i
,
++
pcount
)
{
int
z
=
r
->
begin
+
pcount
*
r
->
part_size
;
#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
int
c
=
part_classdata
[
0
][
class_set
][
i
];
#else
int
c
=
classifications
[
0
][
pcount
];
#endif
int
b
=
r
->
residue_books
[
c
][
pass
];
if
(
b
>=
0
)
{
Codebook
*
book
=
f
->
codebooks
+
b
;
if
(
!
codebook_decode_deinterleave_repeat
(
f
,
book
,
residue_buffers
,
ch
,
&
c_inter
,
&
p_inter
,
n
,
r
->
part_size
))
goto
done
;
}
else
{
z
+=
r
->
part_size
;
c_inter
=
0
;
p_inter
=
z
;
}
}
#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
++
class_set
;
#endif
}
}
else
{
}
else
if
(
ch
>
2
)
{
while
(
pcount
<
part_read
)
{
int
z
=
r
->
begin
+
pcount
*
r
->
part_size
;
int
c_inter
=
z
%
ch
,
p_inter
=
z
/
ch
;
...
...
@@ -2346,11 +2348,11 @@ void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype)
#if LIBVORBIS_MDCT
// directly call the vorbis MDCT using an interface documented
// by Jeff Roberts... useful for performance comparison
typedef
struct
typedef
struct
{
int
n
;
int
log2n
;
float
*
trig
;
int
*
bitrev
;
...
...
@@ -2369,7 +2371,7 @@ void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
if
(
M1
.
n
==
n
)
M
=
&
M1
;
else
if
(
M2
.
n
==
n
)
M
=
&
M2
;
else
if
(
M1
.
n
==
0
)
{
mdct_init
(
&
M1
,
n
);
M
=
&
M1
;
}
else
{
else
{
if
(
M2
.
n
)
__asm
int
3
;
mdct_init
(
&
M2
,
n
);
M
=
&
M2
;
...
...
@@ -2632,7 +2634,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
// once I combined the passes.
// so there's a missing 'times 2' here (for adding X to itself).
// this prop
o
gates through linearly to the end, where the numbers
// this prop
a
gates through linearly to the end, where the numbers
// are 1/2 too small, and need to be compensated for.
{
...
...
@@ -2782,7 +2784,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
d1
[
0
]
=
u
[
k4
+
1
];
d0
[
1
]
=
u
[
k4
+
2
];
d0
[
0
]
=
u
[
k4
+
3
];
d0
-=
4
;
d1
-=
4
;
bitrev
+=
2
;
...
...
@@ -2863,7 +2865,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
float
p0
,
p1
,
p2
,
p3
;
p3
=
e
[
6
]
*
B
[
7
]
-
e
[
7
]
*
B
[
6
];
p2
=
-
e
[
6
]
*
B
[
6
]
-
e
[
7
]
*
B
[
7
];
p2
=
-
e
[
6
]
*
B
[
6
]
-
e
[
7
]
*
B
[
7
];
d0
[
0
]
=
p3
;
d1
[
3
]
=
-
p3
;
...
...
@@ -2871,7 +2873,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
d3
[
3
]
=
p2
;
p1
=
e
[
4
]
*
B
[
5
]
-
e
[
5
]
*
B
[
4
];
p0
=
-
e
[
4
]
*
B
[
4
]
-
e
[
5
]
*
B
[
5
];
p0
=
-
e
[
4
]
*
B
[
4
]
-
e
[
5
]
*
B
[
5
];
d0
[
1
]
=
p1
;
d1
[
2
]
=
-
p1
;
...
...
@@ -2879,7 +2881,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
d3
[
2
]
=
p0
;
p3
=
e
[
2
]
*
B
[
3
]
-
e
[
3
]
*
B
[
2
];
p2
=
-
e
[
2
]
*
B
[
2
]
-
e
[
3
]
*
B
[
3
];
p2
=
-
e
[
2
]
*
B
[
2
]
-
e
[
3
]
*
B
[
3
];
d0
[
2
]
=
p3
;
d1
[
1
]
=
-
p3
;
...
...
@@ -2887,7 +2889,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
d3
[
1
]
=
p2
;
p1
=
e
[
0
]
*
B
[
1
]
-
e
[
1
]
*
B
[
0
];
p0
=
-
e
[
0
]
*
B
[
0
]
-
e
[
1
]
*
B
[
1
];
p0
=
-
e
[
0
]
*
B
[
0
]
-
e
[
1
]
*
B
[
1
];
d0
[
3
]
=
p1
;
d1
[
0
]
=
-
p1
;
...
...
@@ -3040,7 +3042,6 @@ static float *get_window(vorb *f, int len)
len
<<=
1
;
if
(
len
==
f
->
blocksize_0
)
return
f
->
window
[
0
];
if
(
len
==
f
->
blocksize_1
)
return
f
->
window
[
1
];
assert
(
0
);
return
NULL
;
}
...
...
@@ -3391,7 +3392,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
if
(
f
->
last_seg_which
==
f
->
end_seg_with_known_loc
)
{
// if we have a valid current loc, and this is final:
if
(
f
->
current_loc_valid
&&
(
f
->
page_flag
&
PAGEFLAG_last_page
))
{
uint32
current_end
=
f
->
known_loc_for_packet
-
(
n
-
right_end
)
;
uint32
current_end
=
f
->
known_loc_for_packet
;
// then let's infer the size of the (probably) short final frame
if
(
current_end
<
f
->
current_loc
+
(
right_end
-
left_start
))
{
if
(
current_end
<
f
->
current_loc
)
{
...
...
@@ -3400,7 +3401,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
}
else
{
*
len
=
current_end
-
f
->
current_loc
;
}
*
len
+=
left_start
;
*
len
+=
left_start
;
// this doesn't seem right, but has no ill effect on my test files
if
(
*
len
>
right_end
)
*
len
=
right_end
;
// this should never happen
f
->
current_loc
+=
*
len
;
return
TRUE
;
...
...
@@ -3446,6 +3447,7 @@ static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right)
if
(
f
->
previous_length
)
{
int
i
,
j
,
n
=
f
->
previous_length
;
float
*
w
=
get_window
(
f
,
n
);
if
(
w
==
NULL
)
return
0
;
for
(
i
=
0
;
i
<
f
->
channels
;
++
i
)
{
for
(
j
=
0
;
j
<
n
;
++
j
)
f
->
channel_buffers
[
i
][
left
+
j
]
=
...
...
@@ -3493,7 +3495,7 @@ static int vorbis_pump_first_frame(stb_vorbis *f)
}
#ifndef STB_VORBIS_NO_PUSHDATA_API
static
int
is_whole_packet_present
(
stb_vorbis
*
f
,
int
end_page
)
static
int
is_whole_packet_present
(
stb_vorbis
*
f
)
{
// make sure that we have the packet available before continuing...
// this requires a full ogg parse, but we know we can fetch from f->stream
...
...
@@ -3513,15 +3515,13 @@ static int is_whole_packet_present(stb_vorbis *f, int end_page)
break
;
}
// either this continues, or it ends it...
if
(
end_page
)
if
(
s
<
f
->
segment_count
-
1
)
return
error
(
f
,
VORBIS_invalid_stream
);
if
(
s
==
f
->
segment_count
)
s
=
-
1
;
// set 'crosses page' flag
if
(
p
>
f
->
stream_end
)
return
error
(
f
,
VORBIS_need_more_data
);
first
=
FALSE
;
}
for
(;
s
==
-
1
;)
{
uint8
*
q
;
uint8
*
q
;
int
n
;
// check that we have the page header ready
...
...
@@ -3547,8 +3547,6 @@ static int is_whole_packet_present(stb_vorbis *f, int end_page)
if
(
q
[
s
]
<
255
)
break
;
}
if
(
end_page
)
if
(
s
<
n
-
1
)
return
error
(
f
,
VORBIS_invalid_stream
);
if
(
s
==
n
)
s
=
-
1
;
// set 'crosses page' flag
if
(
p
>
f
->
stream_end
)
return
error
(
f
,
VORBIS_need_more_data
);
...
...
@@ -3565,6 +3563,7 @@ static int start_decoder(vorb *f)
int
longest_floorlist
=
0
;
// first page, first packet
f
->
first_decode
=
TRUE
;
if
(
!
start_page
(
f
))
return
FALSE
;
// validate page flag
...
...
@@ -3573,7 +3572,22 @@ static int start_decoder(vorb *f)
if
(
f
->
page_flag
&
PAGEFLAG_continued_packet
)
return
error
(
f
,
VORBIS_invalid_first_page
);
// check for expected packet length
if
(
f
->
segment_count
!=
1
)
return
error
(
f
,
VORBIS_invalid_first_page
);
if
(
f
->
segments
[
0
]
!=
30
)
return
error
(
f
,
VORBIS_invalid_first_page
);
if
(
f
->
segments
[
0
]
!=
30
)
{
// check for the Ogg skeleton fishead identifying header to refine our error
if
(
f
->
segments
[
0
]
==
64
&&
getn
(
f
,
header
,
6
)
&&
header
[
0
]
==
'f'
&&
header
[
1
]
==
'i'
&&
header
[
2
]
==
's'
&&
header
[
3
]
==
'h'
&&
header
[
4
]
==
'e'
&&
header
[
5
]
==
'a'
&&
get8
(
f
)
==
'd'
&&
get8
(
f
)
==
'\0'
)
return
error
(
f
,
VORBIS_ogg_skeleton_not_supported
);
else
return
error
(
f
,
VORBIS_invalid_first_page
);
}
// read packet
// check packet header
if
(
get8
(
f
)
!=
VORBIS_packet_id
)
return
error
(
f
,
VORBIS_invalid_first_page
);
...
...
@@ -3607,6 +3621,41 @@ static int start_decoder(vorb *f)
if
(
!
start_page
(
f
))
return
FALSE
;
if
(
!
start_packet
(
f
))
return
FALSE
;
if
(
!
next_segment
(
f
))
return
FALSE
;
if
(
get8_packet
(
f
)
!=
VORBIS_packet_comment
)
return
error
(
f
,
VORBIS_invalid_setup
);
for
(
i
=
0
;
i
<
6
;
++
i
)
header
[
i
]
=
get8_packet
(
f
);
if
(
!
vorbis_validate
(
header
))
return
error
(
f
,
VORBIS_invalid_setup
);
//file vendor
len
=
get32_packet
(
f
);
f
->
vendor
=
(
char
*
)
setup_malloc
(
f
,
sizeof
(
char
)
*
(
len
+
1
));
for
(
i
=
0
;
i
<
len
;
++
i
)
{
f
->
vendor
[
i
]
=
get8_packet
(
f
);
}
f
->
vendor
[
len
]
=
(
char
)
'\0'
;
//user comments
f
->
comment_list_length
=
get32_packet
(
f
);
f
->
comment_list
=
(
char
**
)
setup_malloc
(
f
,
sizeof
(
char
*
)
*
(
f
->
comment_list_length
));
for
(
i
=
0
;
i
<
f
->
comment_list_length
;
++
i
)
{
len
=
get32_packet
(
f
);
f
->
comment_list
[
i
]
=
(
char
*
)
setup_malloc
(
f
,
sizeof
(
char
)
*
(
len
+
1
));
for
(
j
=
0
;
j
<
len
;
++
j
)
{
f
->
comment_list
[
i
][
j
]
=
get8_packet
(
f
);
}
f
->
comment_list
[
i
][
len
]
=
(
char
)
'\0'
;
}
// framing_flag
x
=
get8_packet
(
f
);
if
(
!
(
x
&
1
))
return
error
(
f
,
VORBIS_invalid_setup
);
skip
(
f
,
f
->
bytes_in_seg
);
f
->
bytes_in_seg
=
0
;
do
{
len
=
next_segment
(
f
);
skip
(
f
,
len
);
...
...
@@ -3618,7 +3667,7 @@ static int start_decoder(vorb *f)
#ifndef STB_VORBIS_NO_PUSHDATA_API
if
(
IS_PUSH_MODE
(
f
))
{
if
(
!
is_whole_packet_present
(
f
,
TRUE
))
{
if
(
!
is_whole_packet_present
(
f
))
{
// convert error in ogg header to write type
if
(
f
->
error
==
VORBIS_invalid_stream
)
f
->
error
=
VORBIS_invalid_setup
;
...
...
@@ -3672,6 +3721,7 @@ static int start_decoder(vorb *f)
while
(
current_entry
<
c
->
entries
)
{
int
limit
=
c
->
entries
-
current_entry
;
int
n
=
get_bits
(
f
,
ilog
(
limit
));
if
(
current_length
>=
32
)
return
error
(
f
,
VORBIS_invalid_setup
);
if
(
current_entry
+
n
>
(
int
)
c
->
entries
)
{
return
error
(
f
,
VORBIS_invalid_setup
);
}
memset
(
lengths
+
current_entry
,
current_length
,
n
);
current_entry
+=
n
;
...
...
@@ -3775,7 +3825,9 @@ static int start_decoder(vorb *f)
c
->
value_bits
=
get_bits
(
f
,
4
)
+
1
;
c
->
sequence_p
=
get_bits
(
f
,
1
);
if
(
c
->
lookup_type
==
1
)
{
c
->
lookup_values
=
lookup1_values
(
c
->
entries
,
c
->
dimensions
);
int
values
=
lookup1_values
(
c
->
entries
,
c
->
dimensions
);
if
(
values
<
0
)
return
error
(
f
,
VORBIS_invalid_setup
);
c
->
lookup_values
=
(
uint32
)
values
;
}
else
{
c
->
lookup_values
=
c
->
entries
*
c
->
dimensions
;
}
...
...
@@ -3874,7 +3926,7 @@ static int start_decoder(vorb *f)
}
else
{
stbv__floor_ordering
p
[
31
*
8
+
2
];
Floor1
*
g
=
&
f
->
floor_config
[
i
].
floor1
;
int
max_class
=
-
1
;
int
max_class
=
-
1
;
g
->
partitions
=
get_bits
(
f
,
5
);
for
(
j
=
0
;
j
<
g
->
partitions
;
++
j
)
{
g
->
partition_class_list
[
j
]
=
get_bits
(
f
,
4
);
...
...
@@ -3911,11 +3963,14 @@ static int start_decoder(vorb *f)
p
[
j
].
id
=
j
;
}
qsort
(
p
,
g
->
values
,
sizeof
(
p
[
0
]),
point_compare
);
for
(
j
=
0
;
j
<
g
->
values
-
1
;
++
j
)
if
(
p
[
j
].
x
==
p
[
j
+
1
].
x
)
return
error
(
f
,
VORBIS_invalid_setup
);
for
(
j
=
0
;
j
<
g
->
values
;
++
j
)
g
->
sorted_order
[
j
]
=
(
uint8
)
p
[
j
].
id
;
// precompute the neighbors
for
(
j
=
2
;
j
<
g
->
values
;
++
j
)
{
int
low
,
hi
;
int
low
=
0
,
hi
=
0
;
neighbors
(
g
->
Xlist
,
j
,
&
low
,
&
hi
);
g
->
neighbors
[
j
][
0
]
=
low
;
g
->
neighbors
[
j
][
1
]
=
hi
;
...
...
@@ -3984,7 +4039,7 @@ static int start_decoder(vorb *f)
if
(
f
->
mapping
==
NULL
)
return
error
(
f
,
VORBIS_outofmem
);
memset
(
f
->
mapping
,
0
,
f
->
mapping_count
*
sizeof
(
*
f
->
mapping
));
for
(
i
=
0
;
i
<
f
->
mapping_count
;
++
i
)
{
Mapping
*
m
=
f
->
mapping
+
i
;
Mapping
*
m
=
f
->
mapping
+
i
;
int
mapping_type
=
get_bits
(
f
,
16
);
if
(
mapping_type
!=
0
)
return
error
(
f
,
VORBIS_invalid_setup
);
m
->
chan
=
(
MappingChannel
*
)
setup_malloc
(
f
,
f
->
channels
*
sizeof
(
*
m
->
chan
));
...
...
@@ -3997,6 +4052,7 @@ static int start_decoder(vorb *f)
max_submaps
=
m
->
submaps
;
if
(
get_bits
(
f
,
1
))
{
m
->
coupling_steps
=
get_bits
(
f
,
8
)
+
1
;
if
(
m
->
coupling_steps
>
f
->
channels
)
return
error
(
f
,
VORBIS_invalid_setup
);
for
(
k
=
0
;
k
<
m
->
coupling_steps
;
++
k
)
{
m
->
chan
[
k
].
magnitude
=
get_bits
(
f
,
ilog
(
f
->
channels
-
1
));
m
->
chan
[
k
].
angle
=
get_bits
(
f
,
ilog
(
f
->
channels
-
1
));
...
...
@@ -4050,6 +4106,7 @@ static int start_decoder(vorb *f)
f
->
previous_window
[
i
]
=
(
float
*
)
setup_malloc
(
f
,
sizeof
(
float
)
*
f
->
blocksize_1
/
2
);
f
->
finalY
[
i
]
=
(
int16
*
)
setup_malloc
(
f
,
sizeof
(
int16
)
*
longest_floorlist
);
if
(
f
->
channel_buffers
[
i
]
==
NULL
||
f
->
previous_window
[
i
]
==
NULL
||
f
->
finalY
[
i
]
==
NULL
)
return
error
(
f
,
VORBIS_outofmem
);
memset
(
f
->
channel_buffers
[
i
],
0
,
sizeof
(
float
)
*
f
->
blocksize_1
);
#ifdef STB_VORBIS_NO_DEFER_FLOOR
f
->
floor_buffers
[
i
]
=
(
float
*
)
setup_malloc
(
f
,
sizeof
(
float
)
*
f
->
blocksize_1
/
2
);
if
(
f
->
floor_buffers
[
i
]
==
NULL
)
return
error
(
f
,
VORBIS_outofmem
);
...
...
@@ -4077,7 +4134,10 @@ static int start_decoder(vorb *f)
int
i
,
max_part_read
=
0
;
for
(
i
=
0
;
i
<
f
->
residue_count
;
++
i
)
{
Residue
*
r
=
f
->
residue_config
+
i
;
int
n_read
=
r
->
end
-
r
->
begin
;
unsigned
int
actual_size
=
f
->
blocksize_1
/
2
;
unsigned
int
limit_r_begin
=
r
->
begin
<
actual_size
?
r
->
begin
:
actual_size
;
unsigned
int
limit_r_end
=
r
->
end
<
actual_size
?
r
->
end
:
actual_size
;
int
n_read
=
limit_r_end
-
limit_r_begin
;
int
part_read
=
n_read
/
r
->
part_size
;
if
(
part_read
>
max_part_read
)
max_part_read
=
part_read
;
...
...
@@ -4088,12 +4148,13 @@ static int start_decoder(vorb *f)
classify_mem
=
f
->
channels
*
(
sizeof
(
void
*
)
+
max_part_read
*
sizeof
(
int
*
));
#endif
// maximum reasonable partition size is f->blocksize_1
f
->
temp_memory_required
=
classify_mem
;
if
(
imdct_mem
>
f
->
temp_memory_required
)
f
->
temp_memory_required
=
imdct_mem
;
}
f
->
first_decode
=
TRUE
;
if
(
f
->
alloc
.
alloc_buffer
)
{
assert
(
f
->
temp_offset
==
f
->
alloc
.
alloc_buffer_length_in_bytes
);
...
...
@@ -4102,7 +4163,17 @@ static int start_decoder(vorb *f)
return
error
(
f
,
VORBIS_outofmem
);
}
f
->
first_audio_page_offset
=
stb_vorbis_get_file_offset
(
f
);
// @TODO: stb_vorbis_seek_start expects first_audio_page_offset to point to a page
// without PAGEFLAG_continued_packet, so this either points to the first page, or
// the page after the end of the headers. It might be cleaner to point to a page
// in the middle of the headers, when that's the page where the first audio packet
// starts, but we'd have to also correctly skip the end of any continued packet in
// stb_vorbis_seek_start.
if
(
f
->
next_seg
==
-
1
)
{
f
->
first_audio_page_offset
=
stb_vorbis_get_file_offset
(
f
);
}
else
{
f
->
first_audio_page_offset
=
0
;
}
return
TRUE
;
}
...
...
@@ -4110,6 +4181,13 @@ static int start_decoder(vorb *f)
static
void
vorbis_deinit
(
stb_vorbis
*
p
)
{
int
i
,
j
;
setup_free
(
p
,
p
->
vendor
);
for
(
i
=
0
;
i
<
p
->
comment_list_length
;
++
i
)
{
setup_free
(
p
,
p
->
comment_list
[
i
]);
}
setup_free
(
p
,
p
->
comment_list
);
if
(
p
->
residue_config
)
{
for
(
i
=
0
;
i
<
p
->
residue_count
;
++
i
)
{
Residue
*
r
=
p
->
residue_config
+
i
;
...
...
@@ -4209,6 +4287,15 @@ stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f)
return
d
;
}
stb_vorbis_comment
stb_vorbis_get_comment
(
stb_vorbis
*
f
)
{
stb_vorbis_comment
d
;
d
.
vendor
=
f
->
vendor
;
d
.
comment_list_length
=
f
->
comment_list_length
;
d
.
comment_list
=
f
->
comment_list
;
return
d
;
}
int
stb_vorbis_get_error
(
stb_vorbis
*
f
)
{
int
e
=
f
->
error
;
...
...
@@ -4350,7 +4437,7 @@ int stb_vorbis_decode_frame_pushdata(
f
->
error
=
VORBIS__no_error
;
// check that we have the entire packet in memory
if
(
!
is_whole_packet_present
(
f
,
FALSE
))
{
if
(
!
is_whole_packet_present
(
f
))
{
*
samples
=
0
;
return
0
;
}
...
...
@@ -4555,7 +4642,7 @@ static int get_seek_page_info(stb_vorbis *f, ProbedPage *z)
return
1
;
}
// rarely used function to seek back to the prece
e
ding page while finding the
// rarely used function to seek back to the preceding page while finding the
// start of a packet
static
int
go_to_page_before
(
stb_vorbis
*
f
,
unsigned
int
limit_offset
)
{
...
...
@@ -4586,8 +4673,8 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
{
ProbedPage
left
,
right
,
mid
;
int
i
,
start_seg_with_known_loc
,
end_pos
,
page_start
;
uint32
delta
,
stream_length
,
padding
;
double
offset
,
bytes_per_sample
;
uint32
delta
,
stream_length
,
padding
,
last_sample_limit
;
double
offset
=
0
.
0
,
bytes_per_sample
=
0
.
0
;
int
probe
=
0
;
// find the last page and validate the target sample
...
...
@@ -4600,9 +4687,9 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
// indicates should be the granule position (give or take one)).
padding
=
((
f
->
blocksize_1
-
f
->
blocksize_0
)
>>
2
);
if
(
sample_number
<
padding
)
sample_number
=
0
;
last_sample_limit
=
0
;
else
sample_number
-=
padding
;
last_sample_limit
=
sample_number
-
padding
;
left
=
f
->
p_first
;
while
(
left
.
last_decoded_sample
==
~
0U
)
{
...
...
@@ -4615,9 +4702,12 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
assert
(
right
.
last_decoded_sample
!=
~
0U
);
// starting from the start is handled differently
if
(
sample_number
<=
left
.
last_decoded_sample
)
{
if
(
stb_vorbis_seek_start
(
f
))
if
(
last_sample_limit
<=
left
.
last_decoded_sample
)
{
if
(
stb_vorbis_seek_start
(
f
))
{
if
(
f
->
current_loc
>
sample_number
)
return
error
(
f
,
VORBIS_seek_failed
);
return
1
;
}
return
0
;
}
...
...
@@ -4634,10 +4724,10 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
// first probe (interpolate)
double
data_bytes
=
right
.
page_end
-
left
.
page_start
;
bytes_per_sample
=
data_bytes
/
right
.
last_decoded_sample
;
offset
=
left
.
page_start
+
bytes_per_sample
*
(
sample_number
-
left
.
last_decoded_sample
);
offset
=
left
.
page_start
+
bytes_per_sample
*
(
last_sample_limit
-
left
.
last_decoded_sample
);
}
else
{
// second probe (try to bound the other side)
double
error
=
((
double
)
sample_number
-
mid
.
last_decoded_sample
)
*
bytes_per_sample
;
double
error
=
((
double
)
last_sample_limit
-
mid
.
last_decoded_sample
)
*
bytes_per_sample
;
if
(
error
>=
0
&&
error
<
8000
)
error
=
8000
;
if
(
error
<
0
&&
error
>
-
8000
)
error
=
-
8000
;
offset
+=
error
*
2
;
...
...
@@ -4668,14 +4758,16 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
}
// if we've just found the last page again then we're in a tricky file,
// and we're close enough.
if
(
mid
.
page_start
==
right
.
page_start
)
break
;
if
(
sample_number
<
mid
.
last_decoded_sample
)
right
=
mid
;
else
left
=
mid
;
// and we're close enough (if it wasn't an interpolation probe).
if
(
mid
.
page_start
==
right
.
page_start
)
{
if
(
probe
>=
2
||
delta
<=
65536
)
break
;
}
else
{
if
(
last_sample_limit
<
mid
.
last_decoded_sample
)
right
=
mid
;
else
left
=
mid
;
}
++
probe
;
}
...
...
@@ -4791,8 +4883,8 @@ int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number)
flush_packet
(
f
);
}
}
// the next frame
will
start with the sample
assert
(
f
->
current_loc
==
sample_number
);
// the next frame
should
start with the sample
if
(
f
->
current_loc
!=
sample_number
)
return
error
(
f
,
VORBIS_seek_failed
);
return
1
;
}
...
...
@@ -4962,8 +5054,14 @@ stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, con
stb_vorbis
*
stb_vorbis_open_filename
(
const
char
*
filename
,
int
*
error
,
const
stb_vorbis_alloc
*
alloc
)
{
FILE
*
f
=
fopen
(
filename
,
"rb"
);
if
(
f
)
FILE
*
f
;
#if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__)
if
(
0
!=
fopen_s
(
&
f
,
filename
,
"rb"
))
f
=
NULL
;
#else
f
=
fopen
(
filename
,
"rb"
);
#endif
if
(
f
)
return
stb_vorbis_open_file
(
f
,
TRUE
,
error
,
alloc
);
if
(
error
)
*
error
=
VORBIS_file_open_failure
;
return
NULL
;
...
...
@@ -5026,7 +5124,7 @@ static int8 channel_position[7][6] =
#define MAGIC(SHIFT) (1.5f * (1 << (23-SHIFT)) + 0.5f/(1 << SHIFT))
#define ADDEND(SHIFT) (((150-SHIFT) << 23) + (1 << 22))
#define FAST_SCALED_FLOAT_TO_INT(temp,x,s) (temp.f = (x) + MAGIC(s), temp.i - ADDEND(s))
#define check_endianness()
#define check_endianness()
#else
#define FAST_SCALED_FLOAT_TO_INT(temp,x,s) ((int) ((x) * (1 << (s))))
#define check_endianness()
...
...
@@ -5128,7 +5226,7 @@ static void convert_samples_short(int buf_c, short **buffer, int b_offset, int d
int
stb_vorbis_get_frame_short
(
stb_vorbis
*
f
,
int
num_c
,
short
**
buffer
,
int
num_samples
)
{
float
**
output
;
float
**
output
=
NULL
;
int
len
=
stb_vorbis_get_frame_float
(
f
,
NULL
,
&
output
);
if
(
len
>
num_samples
)
len
=
num_samples
;
if
(
len
)
...
...
@@ -5351,20 +5449,28 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in
#endif // STB_VORBIS_NO_PULLDATA_API
/* Version history
1.10 - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory
1.09 - 2016/04/04 - back out 'avoid discarding last frame' fix from previous version
1.08 - 2016/04/02 - fixed multiple warnings; fix setup memory leaks;
1.17 - 2019-07-08 - fix CVE-2019-13217, -13218, -13219, -13220, -13221, -13222, -13223
found with Mayhem by ForAllSecure
1.16 - 2019-03-04 - fix warnings
1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found
1.14 - 2018-02-11 - delete bogus dealloca usage
1.13 - 2018-01-29 - fix truncation of last frame (hopefully)
1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
1.11 - 2017-07-23 - fix MinGW compilation
1.10 - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory
1.09 - 2016-04-04 - back out 'avoid discarding last frame' fix from previous version
1.08 - 2016-04-02 - fixed multiple warnings; fix setup memory leaks;
avoid discarding last frame of audio data
1.07 - 2015
/01/
16 - fixed some warnings, fix mingw, const-correct API
some more crash fixes when out of memory or with corrupt files
1.06 - 2015
/08/
31 - full, correct support for seeking API (Dougall Johnson)
1.07 - 2015
-01-
16 - fixed some warnings, fix mingw, const-correct API
some more crash fixes when out of memory or with corrupt files
1.06 - 2015
-08-
31 - full, correct support for seeking API (Dougall Johnson)
some crash fixes when out of memory or with corrupt files
1.05 - 2015
/04/
19 - don't define __forceinline if it's redundant
1.04 - 2014
/08/
27 - fix missing const-correct case in API
1.03 - 2014
/08/
07 - Warning fixes
1.02 - 2014
/07/
09 - Declare qsort compare function _cdecl on windows
1.01 - 2014
/06/
18 - fix stb_vorbis_get_samples_float
1.0 - 2014
/05/
26 - fix memory leaks; fix warnings; fix bugs in multichannel
1.05 - 2015
-04-
19 - don't define __forceinline if it's redundant
1.04 - 2014
-08-
27 - fix missing const-correct case in API
1.03 - 2014
-08-
07 - Warning fixes
1.02 - 2014
-07-
09 - Declare qsort compare function _cdecl on windows
1.01 - 2014
-06-
18 - fix stb_vorbis_get_samples_float
1.0 - 2014
-05-
26 - fix memory leaks; fix warnings; fix bugs in multichannel
(API change) report sample rate for decode-full-file funcs
0.99996 - bracket #include <malloc.h> for macintosh compilation by Laurent Gomila
0.99995 - use union instead of pointer-cast for fast-float-to-int to avoid alias-optimization problem
...
...
@@ -5412,38 +5518,38 @@ This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment