Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Libretro
tyrquake
Commits
2d81f6a8
Commit
2d81f6a8
authored
Dec 09, 2016
by
Libretro-Admin
Browse files
Bake in libflac
parent
5ab98d55
Changes
97
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
2d81f6a8
...
...
@@ -314,10 +314,9 @@ CODECLIBS :=
ifeq
($(USE_CODEC_WAVE),1)
CFLAGS
+=
-DUSE_CODEC_WAVE
endif
ifeq
($(USE_CODEC_FLAC),1)
CFLAGS
+=
-DUSE_CODEC_FLAC
CODECLIBS
+=
-lFLAC
endif
ifeq
($(USE_CODEC_OPUS),1)
# opus and opusfile put their *.h under <includedir>/opus,
# but they include the headers without the opus directory
...
...
Makefile.common
View file @
2d81f6a8
LIBFLAC_DIR
=
$(CORE_DIR)
/deps/libFLAC
INCFLAGS
:=
\
-I
$(CORE_DIR)
\
-I
$(CORE_DIR)
/libretro-common/include
\
-I
$(CORE_DIR)
/include
-I
$(CORE_DIR)
/include
\
-I
$(LIBFLAC_DIR)
/include
SOURCES_C
:=
\
$(CORE_DIR)
/common/cl_input.c
\
...
...
@@ -93,3 +95,24 @@ ifneq ($(STATIC_LINKING),1)
endif
SOURCES_C
+=
$(CORE_DIR)
/common/net_none.c
SOURCES_C
+=
$(LIBFLAC_DIR)
/bitmath.c
\
$(LIBFLAC_DIR)
/bitreader.c
\
$(LIBFLAC_DIR)
/cpu.c
\
$(LIBFLAC_DIR)
/crc.c
\
$(LIBFLAC_DIR)
/fixed.c
\
$(LIBFLAC_DIR)
/float.c
\
$(LIBFLAC_DIR)
/format.c
\
$(LIBFLAC_DIR)
/lpc.c
\
$(LIBFLAC_DIR)
/md5.c
\
$(LIBFLAC_DIR)
/memory.c
\
$(LIBFLAC_DIR)
/metadata_iterators.c
\
$(LIBFLAC_DIR)
/metadata_object.c
\
$(LIBFLAC_DIR)
/ogg_decoder_aspect.c
\
$(LIBFLAC_DIR)
/ogg_encoder_aspect.c
\
$(LIBFLAC_DIR)
/ogg_helper.c
\
$(LIBFLAC_DIR)
/ogg_mapping.c
\
$(LIBFLAC_DIR)
/stream_decoder.c
\
$(LIBFLAC_DIR)
/stream_encoder.c
\
$(LIBFLAC_DIR)
/stream_encoder_framing.c
\
$(LIBFLAC_DIR)
/window.c
deps/libFLAC/bitmath.c
0 → 100644
View file @
2d81f6a8
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Xiph.org Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "private/bitmath.h"
#include "FLAC/assert.h"
/* An example of what FLAC__bitmath_silog2() computes:
*
* silog2(-10) = 5
* silog2(- 9) = 5
* silog2(- 8) = 4
* silog2(- 7) = 4
* silog2(- 6) = 4
* silog2(- 5) = 4
* silog2(- 4) = 3
* silog2(- 3) = 3
* silog2(- 2) = 2
* silog2(- 1) = 2
* silog2( 0) = 0
* silog2( 1) = 2
* silog2( 2) = 3
* silog2( 3) = 3
* silog2( 4) = 4
* silog2( 5) = 4
* silog2( 6) = 4
* silog2( 7) = 4
* silog2( 8) = 5
* silog2( 9) = 5
* silog2( 10) = 5
*/
unsigned
FLAC__bitmath_silog2
(
int
v
)
{
while
(
1
)
{
if
(
v
==
0
)
{
return
0
;
}
else
if
(
v
>
0
)
{
unsigned
l
=
0
;
while
(
v
)
{
l
++
;
v
>>=
1
;
}
return
l
+
1
;
}
else
if
(
v
==
-
1
)
{
return
2
;
}
else
{
v
++
;
v
=
-
v
;
}
}
}
unsigned
FLAC__bitmath_silog2_wide
(
FLAC__int64
v
)
{
while
(
1
)
{
if
(
v
==
0
)
{
return
0
;
}
else
if
(
v
>
0
)
{
unsigned
l
=
0
;
while
(
v
)
{
l
++
;
v
>>=
1
;
}
return
l
+
1
;
}
else
if
(
v
==
-
1
)
{
return
2
;
}
else
{
v
++
;
v
=
-
v
;
}
}
}
deps/libFLAC/bitreader.c
0 → 100644
View file @
2d81f6a8
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson
* Copyright (C) 2011-2013 Xiph.Org Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Xiph.org Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <retro_inline.h>
#include "private/bitmath.h"
#include "private/bitreader.h"
#include "private/crc.h"
#include "private/macros.h"
#include "FLAC/assert.h"
#include "share/compat.h"
#include "share/endswap.h"
#include <retro_miscellaneous.h>
/* Things should be fastest when this matches the machine word size */
/* WATCHOUT: if you change this you must also change the following #defines down to FLAC__clz_uint32 below to match */
/* WATCHOUT: there are a few places where the code will not work unless uint32_t is >= 32 bits wide */
/* also, some sections currently only have fast versions for 4 or 8 bytes per word */
#define FLAC__BYTES_PER_WORD 4
/* sizeof uint32_t */
#define FLAC__BITS_PER_WORD (8 * FLAC__BYTES_PER_WORD)
#define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff)
/* SWAP_BE_WORD_TO_HOST swaps bytes in a uint32_t (which is always big-endian) if necessary to match host byte order */
#ifdef MSB_FIRST
#define SWAP_BE_WORD_TO_HOST(x) (x)
#else
#define SWAP_BE_WORD_TO_HOST(x) ENDSWAP_32(x)
#endif
/*
* This should be at least twice as large as the largest number of words
* required to represent any 'number' (in any encoding) you are going to
* read. With FLAC this is on the order of maybe a few hundred bits.
* If the buffer is smaller than that, the decoder won't be able to read
* in a whole number that is in a variable length encoding (e.g. Rice).
* But to be practical it should be at least 1K bytes.
*
* Increase this number to decrease the number of read callbacks, at the
* expense of using more memory. Or decrease for the reverse effect,
* keeping in mind the limit from the first paragraph. The optimal size
* also depends on the CPU cache size and other factors; some twiddling
* may be necessary to squeeze out the best performance.
*/
static
const
unsigned
FLAC__BITREADER_DEFAULT_CAPACITY
=
65536u
/
FLAC__BITS_PER_WORD
;
/* in words */
/* WATCHOUT: assembly routines rely on the order in which these fields are declared */
struct
FLAC__BitReader
{
/* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */
/* any incomplete word at the tail will be left-justified, and bytes from the read callback are added on the right */
uint32_t
*
buffer
;
unsigned
capacity
;
/* in words */
unsigned
words
;
/* # of completed words in buffer */
unsigned
bytes
;
/* # of bytes in incomplete word at buffer[words] */
unsigned
consumed_words
;
/* #words ... */
unsigned
consumed_bits
;
/* ... + (#bits of head word) already consumed from the front of buffer */
unsigned
read_crc16
;
/* the running frame CRC */
unsigned
crc16_align
;
/* the number of bits in the current consumed word that should not be CRC'd */
FLAC__BitReaderReadCallback
read_callback
;
void
*
client_data
;
FLAC__CPUInfo
cpu_info
;
};
static
INLINE
void
crc16_update_word_
(
FLAC__BitReader
*
br
,
uint32_t
word
)
{
register
unsigned
crc
=
br
->
read_crc16
;
#if FLAC__BYTES_PER_WORD == 4
switch
(
br
->
crc16_align
)
{
case
0
:
crc
=
FLAC__CRC16_UPDATE
((
unsigned
)(
word
>>
24
),
crc
);
case
8
:
crc
=
FLAC__CRC16_UPDATE
((
unsigned
)((
word
>>
16
)
&
0xff
),
crc
);
case
16
:
crc
=
FLAC__CRC16_UPDATE
((
unsigned
)((
word
>>
8
)
&
0xff
),
crc
);
case
24
:
br
->
read_crc16
=
FLAC__CRC16_UPDATE
((
unsigned
)(
word
&
0xff
),
crc
);
}
#elif FLAC__BYTES_PER_WORD == 8
switch
(
br
->
crc16_align
)
{
case
0
:
crc
=
FLAC__CRC16_UPDATE
((
unsigned
)(
word
>>
56
),
crc
);
case
8
:
crc
=
FLAC__CRC16_UPDATE
((
unsigned
)((
word
>>
48
)
&
0xff
),
crc
);
case
16
:
crc
=
FLAC__CRC16_UPDATE
((
unsigned
)((
word
>>
40
)
&
0xff
),
crc
);
case
24
:
crc
=
FLAC__CRC16_UPDATE
((
unsigned
)((
word
>>
32
)
&
0xff
),
crc
);
case
32
:
crc
=
FLAC__CRC16_UPDATE
((
unsigned
)((
word
>>
24
)
&
0xff
),
crc
);
case
40
:
crc
=
FLAC__CRC16_UPDATE
((
unsigned
)((
word
>>
16
)
&
0xff
),
crc
);
case
48
:
crc
=
FLAC__CRC16_UPDATE
((
unsigned
)((
word
>>
8
)
&
0xff
),
crc
);
case
56
:
br
->
read_crc16
=
FLAC__CRC16_UPDATE
((
unsigned
)(
word
&
0xff
),
crc
);
}
#else
for
(
;
br
->
crc16_align
<
FLAC__BITS_PER_WORD
;
br
->
crc16_align
+=
8
)
crc
=
FLAC__CRC16_UPDATE
((
unsigned
)((
word
>>
(
FLAC__BITS_PER_WORD
-
8
-
br
->
crc16_align
))
&
0xff
),
crc
);
br
->
read_crc16
=
crc
;
#endif
br
->
crc16_align
=
0
;
}
/* would be static except it needs to be called by asm routines */
FLAC__bool
bitreader_read_from_client_
(
FLAC__BitReader
*
br
)
{
unsigned
start
,
end
;
size_t
bytes
;
FLAC__byte
*
target
;
/* first shift the unconsumed buffer data toward the front as much as possible */
if
(
br
->
consumed_words
>
0
)
{
start
=
br
->
consumed_words
;
end
=
br
->
words
+
(
br
->
bytes
?
1
:
0
);
memmove
(
br
->
buffer
,
br
->
buffer
+
start
,
FLAC__BYTES_PER_WORD
*
(
end
-
start
));
br
->
words
-=
start
;
br
->
consumed_words
=
0
;
}
/*
* set the target for reading, taking into account word alignment and endianness
*/
bytes
=
(
br
->
capacity
-
br
->
words
)
*
FLAC__BYTES_PER_WORD
-
br
->
bytes
;
if
(
bytes
==
0
)
return
false
;
/* no space left, buffer is too small; see note for FLAC__BITREADER_DEFAULT_CAPACITY */
target
=
((
FLAC__byte
*
)(
br
->
buffer
+
br
->
words
))
+
br
->
bytes
;
/* before reading, if the existing reader looks like this (say uint32_t is 32 bits wide)
* bitstream : 11 22 33 44 55 br->words=1 br->bytes=1 (partial tail word is left-justified)
* buffer[BE]: 11 22 33 44 55 ?? ?? ?? (shown layed out as bytes sequentially in memory)
* buffer[LE]: 44 33 22 11 ?? ?? ?? 55 (?? being don't-care)
* ^^-------target, bytes=3
* on LE machines, have to byteswap the odd tail word so nothing is
* overwritten:
*/
#ifndef MSB_FIRST
if
(
br
->
bytes
)
br
->
buffer
[
br
->
words
]
=
SWAP_BE_WORD_TO_HOST
(
br
->
buffer
[
br
->
words
]);
#endif
/* now it looks like:
* bitstream : 11 22 33 44 55 br->words=1 br->bytes=1
* buffer[BE]: 11 22 33 44 55 ?? ?? ??
* buffer[LE]: 44 33 22 11 55 ?? ?? ??
* ^^-------target, bytes=3
*/
/* read in the data; note that the callback may return a smaller number of bytes */
if
(
!
br
->
read_callback
(
target
,
&
bytes
,
br
->
client_data
))
return
false
;
/* after reading bytes 66 77 88 99 AA BB CC DD EE FF from the client:
* bitstream : 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
* buffer[BE]: 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF ??
* buffer[LE]: 44 33 22 11 55 66 77 88 99 AA BB CC DD EE FF ??
* now have to byteswap on LE machines:
*/
#ifndef MSB_FIRST
end
=
(
br
->
words
*
FLAC__BYTES_PER_WORD
+
br
->
bytes
+
bytes
+
(
FLAC__BYTES_PER_WORD
-
1
))
/
FLAC__BYTES_PER_WORD
;
for
(
start
=
br
->
words
;
start
<
end
;
start
++
)
br
->
buffer
[
start
]
=
SWAP_BE_WORD_TO_HOST
(
br
->
buffer
[
start
]);
#endif
/* now it looks like:
* bitstream : 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
* buffer[BE]: 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF ??
* buffer[LE]: 44 33 22 11 88 77 66 55 CC BB AA 99 ?? FF EE DD
* finally we'll update the reader values:
*/
end
=
br
->
words
*
FLAC__BYTES_PER_WORD
+
br
->
bytes
+
bytes
;
br
->
words
=
end
/
FLAC__BYTES_PER_WORD
;
br
->
bytes
=
end
%
FLAC__BYTES_PER_WORD
;
return
true
;
}
/***********************************************************************
*
* Class constructor/destructor
*
***********************************************************************/
FLAC__BitReader
*
FLAC__bitreader_new
(
void
)
{
FLAC__BitReader
*
br
=
(
FLAC__BitReader
*
)
calloc
(
1
,
sizeof
(
FLAC__BitReader
));
/* calloc() implies:
memset(br, 0, sizeof(FLAC__BitReader));
br->buffer = 0;
br->capacity = 0;
br->words = br->bytes = 0;
br->consumed_words = br->consumed_bits = 0;
br->read_callback = 0;
br->client_data = 0;
*/
return
br
;
}
void
FLAC__bitreader_delete
(
FLAC__BitReader
*
br
)
{
FLAC__ASSERT
(
0
!=
br
);
FLAC__bitreader_free
(
br
);
free
(
br
);
}
/***********************************************************************
*
* Public class methods
*
***********************************************************************/
FLAC__bool
FLAC__bitreader_init
(
FLAC__BitReader
*
br
,
FLAC__CPUInfo
cpu
,
FLAC__BitReaderReadCallback
rcb
,
void
*
cd
)
{
FLAC__ASSERT
(
0
!=
br
);
br
->
words
=
br
->
bytes
=
0
;
br
->
consumed_words
=
br
->
consumed_bits
=
0
;
br
->
capacity
=
FLAC__BITREADER_DEFAULT_CAPACITY
;
br
->
buffer
=
(
uint32_t
*
)
malloc
(
sizeof
(
uint32_t
)
*
br
->
capacity
);
if
(
br
->
buffer
==
0
)
return
false
;
br
->
read_callback
=
rcb
;
br
->
client_data
=
cd
;
br
->
cpu_info
=
cpu
;
return
true
;
}
void
FLAC__bitreader_free
(
FLAC__BitReader
*
br
)
{
FLAC__ASSERT
(
0
!=
br
);
if
(
0
!=
br
->
buffer
)
free
(
br
->
buffer
);
br
->
buffer
=
0
;
br
->
capacity
=
0
;
br
->
words
=
br
->
bytes
=
0
;
br
->
consumed_words
=
br
->
consumed_bits
=
0
;
br
->
read_callback
=
0
;
br
->
client_data
=
0
;
}
FLAC__bool
FLAC__bitreader_clear
(
FLAC__BitReader
*
br
)
{
br
->
words
=
br
->
bytes
=
0
;
br
->
consumed_words
=
br
->
consumed_bits
=
0
;
return
true
;
}
void
FLAC__bitreader_dump
(
const
FLAC__BitReader
*
br
,
FILE
*
out
)
{
unsigned
i
,
j
;
if
(
br
==
0
)
{
fprintf
(
out
,
"bitreader is NULL
\n
"
);
}
else
{
fprintf
(
out
,
"bitreader: capacity=%u words=%u bytes=%u consumed: words=%u, bits=%u
\n
"
,
br
->
capacity
,
br
->
words
,
br
->
bytes
,
br
->
consumed_words
,
br
->
consumed_bits
);
for
(
i
=
0
;
i
<
br
->
words
;
i
++
)
{
fprintf
(
out
,
"%08X: "
,
i
);
for
(
j
=
0
;
j
<
FLAC__BITS_PER_WORD
;
j
++
)
if
(
i
<
br
->
consumed_words
||
(
i
==
br
->
consumed_words
&&
j
<
br
->
consumed_bits
))
fprintf
(
out
,
"."
);
else
fprintf
(
out
,
"%01u"
,
br
->
buffer
[
i
]
&
(
1
<<
(
FLAC__BITS_PER_WORD
-
j
-
1
))
?
1
:
0
);
fprintf
(
out
,
"
\n
"
);
}
if
(
br
->
bytes
>
0
)
{
fprintf
(
out
,
"%08X: "
,
i
);
for
(
j
=
0
;
j
<
br
->
bytes
*
8
;
j
++
)
if
(
i
<
br
->
consumed_words
||
(
i
==
br
->
consumed_words
&&
j
<
br
->
consumed_bits
))
fprintf
(
out
,
"."
);
else
fprintf
(
out
,
"%01u"
,
br
->
buffer
[
i
]
&
(
1
<<
(
br
->
bytes
*
8
-
j
-
1
))
?
1
:
0
);
fprintf
(
out
,
"
\n
"
);
}
}
}
void
FLAC__bitreader_reset_read_crc16
(
FLAC__BitReader
*
br
,
FLAC__uint16
seed
)
{
FLAC__ASSERT
(
0
!=
br
);
FLAC__ASSERT
(
0
!=
br
->
buffer
);
FLAC__ASSERT
((
br
->
consumed_bits
&
7
)
==
0
);
br
->
read_crc16
=
(
unsigned
)
seed
;
br
->
crc16_align
=
br
->
consumed_bits
;
}
FLAC__uint16
FLAC__bitreader_get_read_crc16
(
FLAC__BitReader
*
br
)
{
FLAC__ASSERT
(
0
!=
br
);
FLAC__ASSERT
(
0
!=
br
->
buffer
);
FLAC__ASSERT
((
br
->
consumed_bits
&
7
)
==
0
);
FLAC__ASSERT
(
br
->
crc16_align
<=
br
->
consumed_bits
);
/* CRC any tail bytes in a partially-consumed word */
if
(
br
->
consumed_bits
)
{
const
uint32_t
tail
=
br
->
buffer
[
br
->
consumed_words
];
for
(
;
br
->
crc16_align
<
br
->
consumed_bits
;
br
->
crc16_align
+=
8
)
br
->
read_crc16
=
FLAC__CRC16_UPDATE
((
unsigned
)((
tail
>>
(
FLAC__BITS_PER_WORD
-
8
-
br
->
crc16_align
))
&
0xff
),
br
->
read_crc16
);
}
return
br
->
read_crc16
;
}
FLAC__bool
FLAC__bitreader_is_consumed_byte_aligned
(
const
FLAC__BitReader
*
br
)
{
return
((
br
->
consumed_bits
&
7
)
==
0
);
}
unsigned
FLAC__bitreader_bits_left_for_byte_alignment
(
const
FLAC__BitReader
*
br
)
{
return
8
-
(
br
->
consumed_bits
&
7
);
}
unsigned
FLAC__bitreader_get_input_bits_unconsumed
(
const
FLAC__BitReader
*
br
)
{
return
(
br
->
words
-
br
->
consumed_words
)
*
FLAC__BITS_PER_WORD
+
br
->
bytes
*
8
-
br
->
consumed_bits
;
}
FLAC__bool
FLAC__bitreader_read_raw_uint32
(
FLAC__BitReader
*
br
,
FLAC__uint32
*
val
,
unsigned
bits
)
{
FLAC__ASSERT
(
0
!=
br
);
FLAC__ASSERT
(
0
!=
br
->
buffer
);
FLAC__ASSERT
(
bits
<=
32
);
FLAC__ASSERT
((
br
->
capacity
*
FLAC__BITS_PER_WORD
)
*
2
>=
bits
);
FLAC__ASSERT
(
br
->
consumed_words
<=
br
->
words
);
/* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */
FLAC__ASSERT
(
FLAC__BITS_PER_WORD
>=
32
);
if
(
bits
==
0
)
{
/* OPT: investigate if this can ever happen, maybe change to assertion */
*
val
=
0
;
return
true
;
}
while
((
br
->
words
-
br
->
consumed_words
)
*
FLAC__BITS_PER_WORD
+
br
->
bytes
*
8
-
br
->
consumed_bits
<
bits
)
{
if
(
!
bitreader_read_from_client_
(
br
))
return
false
;
}
if
(
br
->
consumed_words
<
br
->
words
)
{
/* if we've not consumed up to a partial tail word... */
/* OPT: taking out the consumed_bits==0 "else" case below might make things faster if less code allows the compiler to inline this function */
if
(
br
->
consumed_bits
)
{
/* this also works when consumed_bits==0, it's just a little slower than necessary for that case */
const
unsigned
n
=
FLAC__BITS_PER_WORD
-
br
->
consumed_bits
;
const
uint32_t
word
=
br
->
buffer
[
br
->
consumed_words
];
if
(
bits
<
n
)
{
*
val
=
(
word
&
(
FLAC__WORD_ALL_ONES
>>
br
->
consumed_bits
))
>>
(
n
-
bits
);
br
->
consumed_bits
+=
bits
;
return
true
;
}
*
val
=
word
&
(
FLAC__WORD_ALL_ONES
>>
br
->
consumed_bits
);
bits
-=
n
;
crc16_update_word_
(
br
,
word
);
br
->
consumed_words
++
;
br
->
consumed_bits
=
0
;
if
(
bits
)
{
/* if there are still bits left to read, there have to be less than 32 so they will all be in the next word */
*
val
<<=
bits
;
*
val
|=
(
br
->
buffer
[
br
->
consumed_words
]
>>
(
FLAC__BITS_PER_WORD
-
bits
));
br
->
consumed_bits
=
bits
;
}
return
true
;
}
else
{
const
uint32_t
word
=
br
->
buffer
[
br
->
consumed_words
];
if
(
bits
<
FLAC__BITS_PER_WORD
)
{
*
val
=
word
>>
(
FLAC__BITS_PER_WORD
-
bits
);
br
->
consumed_bits
=
bits
;
return
true
;
}
/* at this point 'bits' must be == FLAC__BITS_PER_WORD; because of previous assertions, it can't be larger */
*
val
=
word
;
crc16_update_word_
(
br
,
word
);
br
->
consumed_words
++
;
return
true
;
}
}
else
{
/* in this case we're starting our read at a partial tail word;
* the reader has guaranteed that we have at least 'bits' bits
* available to read, which makes this case simpler.
*/
/* OPT: taking out the consumed_bits==0 "else" case below might make things faster if less code allows the compiler to inline this function */
if
(
br
->
consumed_bits
)
{
/* this also works when consumed_bits==0, it's just a little slower than necessary for that case */
FLAC__ASSERT
(
br
->
consumed_bits
+
bits
<=
br
->
bytes
*
8
);
*
val
=
(
br
->
buffer
[
br
->
consumed_words
]
&
(
FLAC__WORD_ALL_ONES
>>
br
->
consumed_bits
))
>>
(
FLAC__BITS_PER_WORD
-
br
->
consumed_bits
-
bits
);
br
->
consumed_bits
+=
bits
;
return
true
;
}
else
{
*
val
=
br
->
buffer
[
br
->
consumed_words
]
>>
(
FLAC__BITS_PER_WORD
-
bits
);
br
->
consumed_bits
+=
bits
;
return
true
;
}
}
}
FLAC__bool
FLAC__bitreader_read_raw_int32
(
FLAC__BitReader
*
br
,
FLAC__int32
*
val
,
unsigned
bits
)
{
/* OPT: inline raw uint32 code here, or make into a macro if possible in the .h file */
if
(
!
FLAC__bitreader_read_raw_uint32
(
br
,
(
FLAC__uint32
*
)
val
,
bits
))
return
false
;
/* sign-extend: */
*
val
<<=
(
32
-
bits
);
*
val
>>=
(
32
-
bits
);
return
true
;
}
FLAC__bool
FLAC__bitreader_read_raw_uint64
(
FLAC__BitReader
*
br
,
FLAC__uint64
*
val
,
unsigned
bits
)
{
FLAC__uint32
hi
,
lo
;
if
(
bits
>
32
)
{
if
(
!
FLAC__bitreader_read_raw_uint32
(
br
,
&
hi
,
bits
-
32
))
return
false
;
if
(
!
FLAC__bitreader_read_raw_uint32
(
br
,
&
lo
,
32
))
return
false
;
*
val
=
hi
;
*
val
<<=
32
;
*
val
|=
lo
;
}
else
{
if
(
!
FLAC__bitreader_read_raw_uint32
(
br
,
&
lo
,
bits
))
return
false
;
*
val
=
lo
;
}
return
true
;
}